@tablecraft/engine 0.1.0-beta.1

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 (237) hide show
  1. package/dist/src/__tests__/inputValidator.test.d.ts +2 -0
  2. package/dist/src/__tests__/inputValidator.test.d.ts.map +1 -0
  3. package/dist/src/__tests__/inputValidator.test.js +205 -0
  4. package/dist/src/__tests__/inputValidator.test.js.map +1 -0
  5. package/dist/src/__tests__/metadataBuilder.test.d.ts +2 -0
  6. package/dist/src/__tests__/metadataBuilder.test.d.ts.map +1 -0
  7. package/dist/src/__tests__/metadataBuilder.test.js +221 -0
  8. package/dist/src/__tests__/metadataBuilder.test.js.map +1 -0
  9. package/dist/src/core/aggregationBuilder.d.ts +17 -0
  10. package/dist/src/core/aggregationBuilder.d.ts.map +1 -0
  11. package/dist/src/core/aggregationBuilder.js +81 -0
  12. package/dist/src/core/aggregationBuilder.js.map +1 -0
  13. package/dist/src/core/cursorPagination.d.ts +36 -0
  14. package/dist/src/core/cursorPagination.d.ts.map +1 -0
  15. package/dist/src/core/cursorPagination.js +88 -0
  16. package/dist/src/core/cursorPagination.js.map +1 -0
  17. package/dist/src/core/datePresets.d.ts +19 -0
  18. package/dist/src/core/datePresets.d.ts.map +1 -0
  19. package/dist/src/core/datePresets.js +96 -0
  20. package/dist/src/core/datePresets.js.map +1 -0
  21. package/dist/src/core/dialect.d.ts +17 -0
  22. package/dist/src/core/dialect.d.ts.map +1 -0
  23. package/dist/src/core/dialect.js +60 -0
  24. package/dist/src/core/dialect.js.map +1 -0
  25. package/dist/src/core/fieldSelector.d.ts +19 -0
  26. package/dist/src/core/fieldSelector.d.ts.map +1 -0
  27. package/dist/src/core/fieldSelector.js +49 -0
  28. package/dist/src/core/fieldSelector.js.map +1 -0
  29. package/dist/src/core/filterBuilder.d.ts +22 -0
  30. package/dist/src/core/filterBuilder.d.ts.map +1 -0
  31. package/dist/src/core/filterBuilder.js +112 -0
  32. package/dist/src/core/filterBuilder.js.map +1 -0
  33. package/dist/src/core/filterGroupBuilder.d.ts +28 -0
  34. package/dist/src/core/filterGroupBuilder.d.ts.map +1 -0
  35. package/dist/src/core/filterGroupBuilder.js +73 -0
  36. package/dist/src/core/filterGroupBuilder.js.map +1 -0
  37. package/dist/src/core/groupByBuilder.d.ts +23 -0
  38. package/dist/src/core/groupByBuilder.d.ts.map +1 -0
  39. package/dist/src/core/groupByBuilder.js +127 -0
  40. package/dist/src/core/groupByBuilder.js.map +1 -0
  41. package/dist/src/core/inputValidator.d.ts +8 -0
  42. package/dist/src/core/inputValidator.d.ts.map +1 -0
  43. package/dist/src/core/inputValidator.js +117 -0
  44. package/dist/src/core/inputValidator.js.map +1 -0
  45. package/dist/src/core/metadataBuilder.d.ts +91 -0
  46. package/dist/src/core/metadataBuilder.d.ts.map +1 -0
  47. package/dist/src/core/metadataBuilder.js +220 -0
  48. package/dist/src/core/metadataBuilder.js.map +1 -0
  49. package/dist/src/core/paginationBuilder.d.ts +20 -0
  50. package/dist/src/core/paginationBuilder.d.ts.map +1 -0
  51. package/dist/src/core/paginationBuilder.js +42 -0
  52. package/dist/src/core/paginationBuilder.js.map +1 -0
  53. package/dist/src/core/queryBuilder.d.ts +20 -0
  54. package/dist/src/core/queryBuilder.d.ts.map +1 -0
  55. package/dist/src/core/queryBuilder.js +163 -0
  56. package/dist/src/core/queryBuilder.js.map +1 -0
  57. package/dist/src/core/recursiveBuilder.d.ts +25 -0
  58. package/dist/src/core/recursiveBuilder.d.ts.map +1 -0
  59. package/dist/src/core/recursiveBuilder.js +86 -0
  60. package/dist/src/core/recursiveBuilder.js.map +1 -0
  61. package/dist/src/core/relationBuilder.d.ts +19 -0
  62. package/dist/src/core/relationBuilder.d.ts.map +1 -0
  63. package/dist/src/core/relationBuilder.js +118 -0
  64. package/dist/src/core/relationBuilder.js.map +1 -0
  65. package/dist/src/core/roleFilter.d.ts +11 -0
  66. package/dist/src/core/roleFilter.d.ts.map +1 -0
  67. package/dist/src/core/roleFilter.js +24 -0
  68. package/dist/src/core/roleFilter.js.map +1 -0
  69. package/dist/src/core/searchBuilder.d.ts +17 -0
  70. package/dist/src/core/searchBuilder.d.ts.map +1 -0
  71. package/dist/src/core/searchBuilder.js +71 -0
  72. package/dist/src/core/searchBuilder.js.map +1 -0
  73. package/dist/src/core/softDelete.d.ts +12 -0
  74. package/dist/src/core/softDelete.d.ts.map +1 -0
  75. package/dist/src/core/softDelete.js +29 -0
  76. package/dist/src/core/softDelete.js.map +1 -0
  77. package/dist/src/core/sortBuilder.d.ts +14 -0
  78. package/dist/src/core/sortBuilder.d.ts.map +1 -0
  79. package/dist/src/core/sortBuilder.js +58 -0
  80. package/dist/src/core/sortBuilder.js.map +1 -0
  81. package/dist/src/core/subqueryBuilder.d.ts +13 -0
  82. package/dist/src/core/subqueryBuilder.d.ts.map +1 -0
  83. package/dist/src/core/subqueryBuilder.js +47 -0
  84. package/dist/src/core/subqueryBuilder.js.map +1 -0
  85. package/dist/src/core/validator.d.ts +18 -0
  86. package/dist/src/core/validator.d.ts.map +1 -0
  87. package/dist/src/core/validator.js +88 -0
  88. package/dist/src/core/validator.js.map +1 -0
  89. package/dist/src/define.d.ts +274 -0
  90. package/dist/src/define.d.ts.map +1 -0
  91. package/dist/src/define.js +690 -0
  92. package/dist/src/define.js.map +1 -0
  93. package/dist/src/engine.d.ts +17 -0
  94. package/dist/src/engine.d.ts.map +1 -0
  95. package/dist/src/engine.js +429 -0
  96. package/dist/src/engine.js.map +1 -0
  97. package/dist/src/errors.d.ts +53 -0
  98. package/dist/src/errors.d.ts.map +1 -0
  99. package/dist/src/errors.js +80 -0
  100. package/dist/src/errors.js.map +1 -0
  101. package/dist/src/index.d.ts +37 -0
  102. package/dist/src/index.d.ts.map +1 -0
  103. package/dist/src/index.js +41 -0
  104. package/dist/src/index.js.map +1 -0
  105. package/dist/src/types/engine.d.ts +92 -0
  106. package/dist/src/types/engine.d.ts.map +1 -0
  107. package/dist/src/types/engine.js +2 -0
  108. package/dist/src/types/engine.js.map +1 -0
  109. package/dist/src/types/table.d.ts +867 -0
  110. package/dist/src/types/table.d.ts.map +1 -0
  111. package/dist/src/types/table.js +198 -0
  112. package/dist/src/types/table.js.map +1 -0
  113. package/dist/src/utils/adapterUtils.d.ts +16 -0
  114. package/dist/src/utils/adapterUtils.d.ts.map +1 -0
  115. package/dist/src/utils/adapterUtils.js +28 -0
  116. package/dist/src/utils/adapterUtils.js.map +1 -0
  117. package/dist/src/utils/codegen.d.ts +7 -0
  118. package/dist/src/utils/codegen.d.ts.map +1 -0
  119. package/dist/src/utils/codegen.js +126 -0
  120. package/dist/src/utils/codegen.js.map +1 -0
  121. package/dist/src/utils/export.d.ts +15 -0
  122. package/dist/src/utils/export.d.ts.map +1 -0
  123. package/dist/src/utils/export.js +42 -0
  124. package/dist/src/utils/export.js.map +1 -0
  125. package/dist/src/utils/introspect.d.ts +32 -0
  126. package/dist/src/utils/introspect.d.ts.map +1 -0
  127. package/dist/src/utils/introspect.js +174 -0
  128. package/dist/src/utils/introspect.js.map +1 -0
  129. package/dist/src/utils/openapi.d.ts +6 -0
  130. package/dist/src/utils/openapi.d.ts.map +1 -0
  131. package/dist/src/utils/openapi.js +138 -0
  132. package/dist/src/utils/openapi.js.map +1 -0
  133. package/dist/src/utils/operators.d.ts +8 -0
  134. package/dist/src/utils/operators.d.ts.map +1 -0
  135. package/dist/src/utils/operators.js +70 -0
  136. package/dist/src/utils/operators.js.map +1 -0
  137. package/dist/src/utils/requestParser.d.ts +18 -0
  138. package/dist/src/utils/requestParser.d.ts.map +1 -0
  139. package/dist/src/utils/requestParser.js +126 -0
  140. package/dist/src/utils/requestParser.js.map +1 -0
  141. package/dist/src/utils/responseFormatter.d.ts +12 -0
  142. package/dist/src/utils/responseFormatter.d.ts.map +1 -0
  143. package/dist/src/utils/responseFormatter.js +106 -0
  144. package/dist/src/utils/responseFormatter.js.map +1 -0
  145. package/dist/src/utils/typedSql.d.ts +70 -0
  146. package/dist/src/utils/typedSql.d.ts.map +1 -0
  147. package/dist/src/utils/typedSql.js +102 -0
  148. package/dist/src/utils/typedSql.js.map +1 -0
  149. package/dist/test/columnMeta.test.d.ts +2 -0
  150. package/dist/test/columnMeta.test.d.ts.map +1 -0
  151. package/dist/test/columnMeta.test.js +92 -0
  152. package/dist/test/columnMeta.test.js.map +1 -0
  153. package/dist/test/core/aggregationBuilder.test.d.ts +2 -0
  154. package/dist/test/core/aggregationBuilder.test.d.ts.map +1 -0
  155. package/dist/test/core/aggregationBuilder.test.js +64 -0
  156. package/dist/test/core/aggregationBuilder.test.js.map +1 -0
  157. package/dist/test/core/filterBuilder.test.d.ts +2 -0
  158. package/dist/test/core/filterBuilder.test.d.ts.map +1 -0
  159. package/dist/test/core/filterBuilder.test.js +80 -0
  160. package/dist/test/core/filterBuilder.test.js.map +1 -0
  161. package/dist/test/core/paginationBuilder.test.d.ts +2 -0
  162. package/dist/test/core/paginationBuilder.test.d.ts.map +1 -0
  163. package/dist/test/core/paginationBuilder.test.js +63 -0
  164. package/dist/test/core/paginationBuilder.test.js.map +1 -0
  165. package/dist/test/core/queryBuilder.test.d.ts +2 -0
  166. package/dist/test/core/queryBuilder.test.d.ts.map +1 -0
  167. package/dist/test/core/queryBuilder.test.js +92 -0
  168. package/dist/test/core/queryBuilder.test.js.map +1 -0
  169. package/dist/test/core/searchBuilder.test.d.ts +2 -0
  170. package/dist/test/core/searchBuilder.test.d.ts.map +1 -0
  171. package/dist/test/core/searchBuilder.test.js +68 -0
  172. package/dist/test/core/searchBuilder.test.js.map +1 -0
  173. package/dist/test/core/softDelete.test.d.ts +2 -0
  174. package/dist/test/core/softDelete.test.d.ts.map +1 -0
  175. package/dist/test/core/softDelete.test.js +60 -0
  176. package/dist/test/core/softDelete.test.js.map +1 -0
  177. package/dist/test/core/sortBuilder.test.d.ts +2 -0
  178. package/dist/test/core/sortBuilder.test.d.ts.map +1 -0
  179. package/dist/test/core/sortBuilder.test.js +59 -0
  180. package/dist/test/core/sortBuilder.test.js.map +1 -0
  181. package/dist/test/core/subqueryBuilder.test.d.ts +2 -0
  182. package/dist/test/core/subqueryBuilder.test.d.ts.map +1 -0
  183. package/dist/test/core/subqueryBuilder.test.js +48 -0
  184. package/dist/test/core/subqueryBuilder.test.js.map +1 -0
  185. package/dist/test/core/validator.test.d.ts +2 -0
  186. package/dist/test/core/validator.test.d.ts.map +1 -0
  187. package/dist/test/core/validator.test.js +81 -0
  188. package/dist/test/core/validator.test.js.map +1 -0
  189. package/dist/test/datePresets.test.d.ts +2 -0
  190. package/dist/test/datePresets.test.d.ts.map +1 -0
  191. package/dist/test/datePresets.test.js +57 -0
  192. package/dist/test/datePresets.test.js.map +1 -0
  193. package/dist/test/errors.test.d.ts +2 -0
  194. package/dist/test/errors.test.d.ts.map +1 -0
  195. package/dist/test/errors.test.js +62 -0
  196. package/dist/test/errors.test.js.map +1 -0
  197. package/dist/test/inputValidator.test.d.ts +2 -0
  198. package/dist/test/inputValidator.test.d.ts.map +1 -0
  199. package/dist/test/inputValidator.test.js +60 -0
  200. package/dist/test/inputValidator.test.js.map +1 -0
  201. package/dist/test/metadata.test.d.ts +2 -0
  202. package/dist/test/metadata.test.d.ts.map +1 -0
  203. package/dist/test/metadata.test.js +285 -0
  204. package/dist/test/metadata.test.js.map +1 -0
  205. package/dist/test/metadataComplete.test.d.ts +2 -0
  206. package/dist/test/metadataComplete.test.d.ts.map +1 -0
  207. package/dist/test/metadataComplete.test.js +113 -0
  208. package/dist/test/metadataComplete.test.js.map +1 -0
  209. package/dist/test/roleFilter.test.d.ts +2 -0
  210. package/dist/test/roleFilter.test.d.ts.map +1 -0
  211. package/dist/test/roleFilter.test.js +53 -0
  212. package/dist/test/roleFilter.test.js.map +1 -0
  213. package/dist/test/typedSql.test.d.ts +2 -0
  214. package/dist/test/typedSql.test.d.ts.map +1 -0
  215. package/dist/test/typedSql.test.js +63 -0
  216. package/dist/test/typedSql.test.js.map +1 -0
  217. package/dist/test/utils/codegen.test.d.ts +2 -0
  218. package/dist/test/utils/codegen.test.d.ts.map +1 -0
  219. package/dist/test/utils/codegen.test.js +65 -0
  220. package/dist/test/utils/codegen.test.js.map +1 -0
  221. package/dist/test/utils/export.test.d.ts +2 -0
  222. package/dist/test/utils/export.test.d.ts.map +1 -0
  223. package/dist/test/utils/export.test.js +54 -0
  224. package/dist/test/utils/export.test.js.map +1 -0
  225. package/dist/test/utils/openapi.test.d.ts +2 -0
  226. package/dist/test/utils/openapi.test.d.ts.map +1 -0
  227. package/dist/test/utils/openapi.test.js +65 -0
  228. package/dist/test/utils/openapi.test.js.map +1 -0
  229. package/dist/test/utils/requestParser.test.d.ts +2 -0
  230. package/dist/test/utils/requestParser.test.d.ts.map +1 -0
  231. package/dist/test/utils/requestParser.test.js +89 -0
  232. package/dist/test/utils/requestParser.test.js.map +1 -0
  233. package/dist/test/utils/responseFormatter.test.d.ts +2 -0
  234. package/dist/test/utils/responseFormatter.test.d.ts.map +1 -0
  235. package/dist/test/utils/responseFormatter.test.js +79 -0
  236. package/dist/test/utils/responseFormatter.test.js.map +1 -0
  237. package/package.json +42 -0
@@ -0,0 +1,71 @@
1
+ import { sql, getTableColumns, or, ilike, } from 'drizzle-orm';
2
+ import { escapeLikePattern } from '../utils/operators';
3
+ export class SearchBuilder {
4
+ schema;
5
+ constructor(schema) {
6
+ this.schema = schema;
7
+ }
8
+ /**
9
+ * Builds a search condition across multiple columns using OR + ILIKE.
10
+ */
11
+ buildSearch(config, searchTerm) {
12
+ if (!searchTerm || searchTerm.trim().length === 0) {
13
+ return undefined;
14
+ }
15
+ if (!config.search || !config.search.enabled) {
16
+ return undefined;
17
+ }
18
+ const searchFields = config.search.fields;
19
+ if (!searchFields || searchFields.length === 0) {
20
+ return undefined;
21
+ }
22
+ const table = this.schema[config.base];
23
+ if (!table)
24
+ return undefined;
25
+ const baseColumns = getTableColumns(table);
26
+ const escaped = escapeLikePattern(searchTerm.trim());
27
+ const conditions = [];
28
+ for (const fieldName of searchFields) {
29
+ const col = this.resolveColumn(baseColumns, fieldName);
30
+ if (!col)
31
+ continue;
32
+ conditions.push(ilike(col, `%${escaped}%`));
33
+ }
34
+ if (conditions.length === 0)
35
+ return undefined;
36
+ // Combine with OR — matching any field is a hit
37
+ return or(...conditions);
38
+ }
39
+ /**
40
+ * Builds a PostgreSQL full-text search condition (tsvector/tsquery).
41
+ * This is an optional enhanced mode — only works on PostgreSQL.
42
+ */
43
+ buildFullTextSearch(config, searchTerm, language = 'english') {
44
+ if (!searchTerm || searchTerm.trim().length === 0)
45
+ return undefined;
46
+ if (!config.search?.enabled)
47
+ return undefined;
48
+ const fields = config.search.fields;
49
+ if (!fields || fields.length === 0)
50
+ return undefined;
51
+ // Concatenate all search fields into a single tsvector
52
+ const concatParts = fields.map((f) => sql `coalesce(${sql.identifier(f)}::text, '')`);
53
+ const concatenated = sql.join(concatParts, sql ` || ' ' || `);
54
+ return sql `to_tsvector(${sql.raw(`'${language}'`)}, ${concatenated}) @@ plainto_tsquery(${sql.raw(`'${language}'`)}, ${searchTerm.trim()})`;
55
+ }
56
+ resolveColumn(baseColumns, fieldName) {
57
+ if (baseColumns[fieldName])
58
+ return baseColumns[fieldName];
59
+ // Joined table column: "table.column"
60
+ if (fieldName.includes('.')) {
61
+ const [tableName, colName] = fieldName.split('.');
62
+ const joinedTable = this.schema[tableName];
63
+ if (!joinedTable)
64
+ return undefined;
65
+ const cols = getTableColumns(joinedTable);
66
+ return cols[colName];
67
+ }
68
+ return undefined;
69
+ }
70
+ }
71
+ //# sourceMappingURL=searchBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"searchBuilder.js","sourceRoot":"","sources":["../../../src/core/searchBuilder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { SQL } from 'drizzle-orm';
2
+ import { TableConfig } from '../types/table';
3
+ export declare class SoftDeleteHandler {
4
+ private schema;
5
+ constructor(schema: Record<string, unknown>);
6
+ /**
7
+ * Returns a WHERE condition that excludes soft-deleted rows.
8
+ * Returns undefined when soft delete is disabled or overridden.
9
+ */
10
+ buildSoftDeleteCondition(config: TableConfig, includeDeleted?: boolean): SQL | undefined;
11
+ }
12
+ //# sourceMappingURL=softDelete.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"softDelete.d.ts","sourceRoot":"","sources":["../../../src/core/softDelete.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,GAAG,EAGJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAE7C,qBAAa,iBAAiB;IAChB,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;;OAGG;IACH,wBAAwB,CACtB,MAAM,EAAE,WAAW,EACnB,cAAc,GAAE,OAAe,GAC9B,GAAG,GAAG,SAAS;CAoBnB"}
@@ -0,0 +1,29 @@
1
+ import { getTableColumns, isNull, } from 'drizzle-orm';
2
+ export class SoftDeleteHandler {
3
+ schema;
4
+ constructor(schema) {
5
+ this.schema = schema;
6
+ }
7
+ /**
8
+ * Returns a WHERE condition that excludes soft-deleted rows.
9
+ * Returns undefined when soft delete is disabled or overridden.
10
+ */
11
+ buildSoftDeleteCondition(config, includeDeleted = false) {
12
+ if (!config.softDelete?.enabled)
13
+ return undefined;
14
+ if (includeDeleted)
15
+ return undefined;
16
+ const table = this.schema[config.base];
17
+ if (!table)
18
+ return undefined;
19
+ const columns = getTableColumns(table);
20
+ const field = config.softDelete.field ?? 'deletedAt';
21
+ const col = columns[field];
22
+ if (!col) {
23
+ console.warn(`[tablecraft] Soft-delete field '${field}' not found in table '${config.base}'`);
24
+ return undefined;
25
+ }
26
+ return isNull(col);
27
+ }
28
+ }
29
+ //# sourceMappingURL=softDelete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"softDelete.js","sourceRoot":"","sources":["../../../src/core/softDelete.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EACf,MAAM,GACP,MAAM,aAAa,CAAC;AAGrB,MAAM,OAAO,iBAAiB;IACR;IAApB,YAAoB,MAA+B;QAA/B,WAAM,GAAN,MAAM,CAAyB;IAAG,CAAC;IAEvD;;;OAGG;IACH,wBAAwB,CACtB,MAAmB,EACnB,iBAA0B,KAAK;QAE/B,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,OAAO;YAAE,OAAO,SAAS,CAAC;QAClD,IAAI,cAAc;YAAE,OAAO,SAAS,CAAC;QAErC,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAU,CAAC;QAChD,IAAI,CAAC,KAAK;YAAE,OAAO,SAAS,CAAC;QAE7B,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QACvC,MAAM,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,IAAI,WAAW,CAAC;QACrD,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAE3B,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,OAAO,CAAC,IAAI,CACV,mCAAmC,KAAK,yBAAyB,MAAM,CAAC,IAAI,GAAG,CAChF,CAAC;YACF,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ import { SQL } from 'drizzle-orm';
2
+ import { TableConfig } from '../types/table';
3
+ import { SortParam } from '../types/engine';
4
+ export declare class SortBuilder {
5
+ private schema;
6
+ constructor(schema: Record<string, unknown>);
7
+ /**
8
+ * Builds ORDER BY clauses from request params, falling back to defaults.
9
+ * Only allows sorting on columns marked sortable in the config.
10
+ */
11
+ buildSort(config: TableConfig, params?: SortParam[]): SQL[];
12
+ private getDefaultSort;
13
+ }
14
+ //# sourceMappingURL=sortBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sortBuilder.d.ts","sourceRoot":"","sources":["../../../src/core/sortBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,GAAG,EAKJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,qBAAa,WAAW;IACV,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,MAAM,CAAC,EAAE,SAAS,EAAE,GAAG,GAAG,EAAE;IA+C3D,OAAO,CAAC,cAAc;CAQvB"}
@@ -0,0 +1,58 @@
1
+ import { getTableColumns, asc, desc, } from 'drizzle-orm';
2
+ export class SortBuilder {
3
+ schema;
4
+ constructor(schema) {
5
+ this.schema = schema;
6
+ }
7
+ /**
8
+ * Builds ORDER BY clauses from request params, falling back to defaults.
9
+ * Only allows sorting on columns marked sortable in the config.
10
+ */
11
+ buildSort(config, params) {
12
+ const sortParams = params && params.length > 0 ? params : this.getDefaultSort(config);
13
+ if (!sortParams || sortParams.length === 0)
14
+ return [];
15
+ const table = this.schema[config.base];
16
+ if (!table)
17
+ return [];
18
+ const columns = getTableColumns(table);
19
+ // Build a whitelist of sortable fields
20
+ const sortableFields = new Set();
21
+ for (const col of config.columns) {
22
+ if (col.sortable !== false) {
23
+ sortableFields.add(col.name);
24
+ }
25
+ }
26
+ const clauses = [];
27
+ for (const sp of sortParams) {
28
+ if (!sortableFields.has(sp.field))
29
+ continue;
30
+ const colConfig = config.columns.find(c => c.name === sp.field);
31
+ const dbFieldName = colConfig?.field ?? sp.field;
32
+ let col;
33
+ if (dbFieldName.includes('.')) {
34
+ const [tableName, colName] = dbFieldName.split('.');
35
+ const joinedTable = this.schema[tableName];
36
+ if (joinedTable) {
37
+ col = getTableColumns(joinedTable)[colName];
38
+ }
39
+ }
40
+ else {
41
+ col = columns[dbFieldName];
42
+ }
43
+ if (!col)
44
+ continue;
45
+ clauses.push(sp.order === 'desc' ? desc(col) : asc(col));
46
+ }
47
+ return clauses;
48
+ }
49
+ getDefaultSort(config) {
50
+ if (!config.defaultSort || config.defaultSort.length === 0)
51
+ return undefined;
52
+ return config.defaultSort.map((s) => ({
53
+ field: s.field,
54
+ order: s.order ?? 'asc',
55
+ }));
56
+ }
57
+ }
58
+ //# sourceMappingURL=sortBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sortBuilder.js","sourceRoot":"","sources":["../../../src/core/sortBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,eAAe,EACf,GAAG,EACH,IAAI,GAEL,MAAM,aAAa,CAAC;AAIrB,MAAM,OAAO,WAAW;IACF;IAApB,YAAoB,MAA+B;QAA/B,WAAM,GAAN,MAAM,CAAyB;IAAG,CAAC;IAEvD;;;OAGG;IACH,SAAS,CAAC,MAAmB,EAAE,MAAoB;QACjD,MAAM,UAAU,GACd,MAAM,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAErE,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QAEtD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAU,CAAC;QAChD,IAAI,CAAC,KAAK;YAAE,OAAO,EAAE,CAAC;QAEtB,MAAM,OAAO,GAAG,eAAe,CAAC,KAAK,CAAC,CAAC;QAEvC,uCAAuC;QACvC,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;QACzC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;gBAC3B,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,MAAM,OAAO,GAAU,EAAE,CAAC;QAE1B,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;YAC5B,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;gBAAE,SAAS;YAE5C,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC;YAChE,MAAM,WAAW,GAAG,SAAS,EAAE,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC;YAEjD,IAAI,GAAuB,CAAC;YAE5B,IAAI,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACpD,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAU,CAAC;gBACpD,IAAI,WAAW,EAAE,CAAC;oBACd,GAAG,GAAG,eAAe,CAAC,WAAW,CAAC,CAAC,OAAO,CAAC,CAAC;gBAChD,CAAC;YACJ,CAAC;iBAAM,CAAC;gBACL,GAAG,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;YAC9B,CAAC;YAED,IAAI,CAAC,GAAG;gBAAE,SAAS;YAEnB,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3D,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,cAAc,CAAC,MAAmB;QACxC,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC,WAAW,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,SAAS,CAAC;QAE7E,OAAO,MAAM,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACpC,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,KAAK,EAAE,CAAC,CAAC,KAAK,IAAI,KAAK;SACxB,CAAC,CAAC,CAAC;IACN,CAAC;CACF"}
@@ -0,0 +1,13 @@
1
+ import { SQL } from 'drizzle-orm';
2
+ import { TableConfig } from '../types/table';
3
+ export declare class SubqueryBuilder {
4
+ private schema;
5
+ constructor(schema: Record<string, unknown>);
6
+ /**
7
+ * Builds correlated subquery select expressions.
8
+ * Supports count, exists, and first subquery types.
9
+ */
10
+ buildSubqueries(config: TableConfig): Record<string, SQL> | undefined;
11
+ private buildSingle;
12
+ }
13
+ //# sourceMappingURL=subqueryBuilder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subqueryBuilder.d.ts","sourceRoot":"","sources":["../../../src/core/subqueryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,GAAG,EAEJ,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AAE7D,qBAAa,eAAe;IACd,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAEnD;;;OAGG;IACH,eAAe,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,SAAS;IAuBrE,OAAO,CAAC,WAAW;CAiBpB"}
@@ -0,0 +1,47 @@
1
+ import { sql, } from 'drizzle-orm';
2
+ export class SubqueryBuilder {
3
+ schema;
4
+ constructor(schema) {
5
+ this.schema = schema;
6
+ }
7
+ /**
8
+ * Builds correlated subquery select expressions.
9
+ * Supports count, exists, and first subquery types.
10
+ */
11
+ buildSubqueries(config) {
12
+ if (!config.subqueries || config.subqueries.length === 0) {
13
+ return undefined;
14
+ }
15
+ const baseTable = this.schema[config.base];
16
+ if (!baseTable)
17
+ return undefined;
18
+ const result = {};
19
+ for (const sub of config.subqueries) {
20
+ const subTable = this.schema[sub.table];
21
+ if (!subTable)
22
+ continue;
23
+ const subQuery = this.buildSingle(sub, subTable);
24
+ if (subQuery) {
25
+ result[sub.alias] = subQuery;
26
+ }
27
+ }
28
+ return Object.keys(result).length > 0 ? result : undefined;
29
+ }
30
+ buildSingle(sub, subTable) {
31
+ // The filter string is a raw SQL correlation condition
32
+ // e.g. "orders.user_id = users.id"
33
+ // TODO: replace with a structured, parameterised representation
34
+ const filterSql = sub.filter ? sql.raw(sub.filter) : sql `true`;
35
+ switch (sub.type) {
36
+ case 'count':
37
+ return sql `(SELECT count(*) FROM ${subTable} WHERE ${filterSql})`;
38
+ case 'exists':
39
+ return sql `EXISTS (SELECT 1 FROM ${subTable} WHERE ${filterSql})`;
40
+ case 'first':
41
+ return sql `(SELECT row_to_json(t) FROM (SELECT * FROM ${subTable} WHERE ${filterSql} LIMIT 1) t)`;
42
+ default:
43
+ return undefined;
44
+ }
45
+ }
46
+ }
47
+ //# sourceMappingURL=subqueryBuilder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subqueryBuilder.js","sourceRoot":"","sources":["../../../src/core/subqueryBuilder.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,GAAG,GACJ,MAAM,aAAa,CAAC;AAGrB,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,MAA+B;QAA/B,WAAM,GAAN,MAAM,CAAyB;IAAG,CAAC;IAEvD;;;OAGG;IACH,eAAe,CAAC,MAAmB;QACjC,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACzD,OAAO,SAAS,CAAC;QACnB,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAU,CAAC;QACpD,IAAI,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QAEjC,MAAM,MAAM,GAAwB,EAAE,CAAC;QAEvC,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAU,CAAC;YACjD,IAAI,CAAC,QAAQ;gBAAE,SAAS;YAExB,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;YACjD,IAAI,QAAQ,EAAE,CAAC;gBACb,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,QAAQ,CAAC;YAC/B,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;IAC7D,CAAC;IAEO,WAAW,CAAC,GAAmB,EAAE,QAAe;QACtD,uDAAuD;QACvD,mCAAmC;QACnC,gEAAgE;QAChE,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,CAAA,MAAM,CAAC;QAE/D,QAAQ,GAAG,CAAC,IAAI,EAAE,CAAC;YACjB,KAAK,OAAO;gBACV,OAAO,GAAG,CAAA,yBAAyB,QAAQ,UAAU,SAAS,GAAG,CAAC;YACpE,KAAK,QAAQ;gBACX,OAAO,GAAG,CAAA,yBAAyB,QAAQ,UAAU,SAAS,GAAG,CAAC;YACpE,KAAK,OAAO;gBACV,OAAO,GAAG,CAAA,8CAA8C,QAAQ,UAAU,SAAS,cAAc,CAAC;YACpG;gBACE,OAAO,SAAS,CAAC;QACrB,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,18 @@
1
+ import { TableConfig } from '../types/table';
2
+ /**
3
+ * Validates a raw configuration object against the Zod schema.
4
+ * @param config The raw configuration object.
5
+ * @returns The validated TableConfig object.
6
+ * @throws ZodError if validation fails.
7
+ */
8
+ export declare function validateConfig(config: unknown): TableConfig;
9
+ /**
10
+ * Validates the configuration against the actual Drizzle schema.
11
+ * Ensures that the base table and columns exist.
12
+ * @param config The validated TableConfig object.
13
+ * @param drizzleSchema An object containing Drizzle table definitions.
14
+ * @returns True if valid.
15
+ * @throws Error if validation fails.
16
+ */
17
+ export declare function validateAgainstSchema(config: TableConfig, drizzleSchema: Record<string, unknown>): boolean;
18
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../../src/core/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAqB,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAGhE;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,OAAO,GAAG,WAAW,CAE3D;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,WAAW,EACnB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACrC,OAAO,CA+ET"}
@@ -0,0 +1,88 @@
1
+ import { TableConfigSchema } from '../types/table';
2
+ import { getTableColumns } from 'drizzle-orm';
3
+ /**
4
+ * Validates a raw configuration object against the Zod schema.
5
+ * @param config The raw configuration object.
6
+ * @returns The validated TableConfig object.
7
+ * @throws ZodError if validation fails.
8
+ */
9
+ export function validateConfig(config) {
10
+ return TableConfigSchema.parse(config);
11
+ }
12
+ /**
13
+ * Validates the configuration against the actual Drizzle schema.
14
+ * Ensures that the base table and columns exist.
15
+ * @param config The validated TableConfig object.
16
+ * @param drizzleSchema An object containing Drizzle table definitions.
17
+ * @returns True if valid.
18
+ * @throws Error if validation fails.
19
+ */
20
+ export function validateAgainstSchema(config, drizzleSchema // Using unknown here as we'll cast to Drizzle Table
21
+ ) {
22
+ // 1. Verify base table exists
23
+ const baseTable = drizzleSchema[config.base];
24
+ if (!baseTable) {
25
+ throw new Error(`Base table '${config.base}' not found in Drizzle schema.`);
26
+ }
27
+ // Check if it's a valid Drizzle table (simplistic check)
28
+ // In a real app, we might check for specific Drizzle symbols or properties
29
+ if (typeof baseTable !== 'object' || baseTable === null) {
30
+ throw new Error(`Schema entry '${config.base}' is not a valid table object.`);
31
+ }
32
+ // Cast to Table to use getTableColumns
33
+ const table = baseTable;
34
+ try {
35
+ // 2. Verify columns exist in table
36
+ const tableColumns = getTableColumns(table);
37
+ const tableColumnNames = new Set(Object.keys(tableColumns));
38
+ for (const col of config.columns) {
39
+ // Resolve database field name (default to col.name)
40
+ const dbField = col.field ?? col.name;
41
+ // Handle joined columns "table.column"
42
+ if (dbField.includes('.')) {
43
+ const [tableName, colName] = dbField.split('.');
44
+ const joinedTable = drizzleSchema[tableName];
45
+ if (!joinedTable) {
46
+ throw new Error(`Table '${tableName}' referenced in column '${col.name}' not found in schema.`);
47
+ }
48
+ const joinedColumns = getTableColumns(joinedTable);
49
+ if (!joinedColumns[colName]) {
50
+ throw new Error(`Column '${colName}' referenced in '${col.name}' does not exist in table '${tableName}'.`);
51
+ }
52
+ continue; // Validated
53
+ }
54
+ // Check if column is computed (virtual)
55
+ if (col.computed) {
56
+ continue;
57
+ }
58
+ // Check if column is a subquery alias
59
+ if (config.subqueries?.some(s => s.alias === col.name)) {
60
+ continue;
61
+ }
62
+ // Check if column is an aggregation alias
63
+ if (config.aggregations?.some(a => a.alias === col.name)) {
64
+ continue;
65
+ }
66
+ // Validate against base table
67
+ if (!tableColumnNames.has(dbField)) {
68
+ throw new Error(`Column '${dbField}' configured in '${config.name}' does not exist in table '${config.base}'.`);
69
+ }
70
+ }
71
+ // 3. Verify join tables (if any)
72
+ if (config.joins) {
73
+ for (const join of config.joins) {
74
+ const joinTable = drizzleSchema[join.table];
75
+ if (!joinTable) {
76
+ throw new Error(`Joined table '${join.table}' not found in Drizzle schema.`);
77
+ }
78
+ // Recursive validation could happen here if we wanted to validate join columns too
79
+ }
80
+ }
81
+ }
82
+ catch (e) {
83
+ // getTableColumns throws if it's not a valid table, catch that too
84
+ throw new Error(`Failed to validate against Drizzle schema: ${e.message}`);
85
+ }
86
+ return true;
87
+ }
88
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../../src/core/validator.ts"],"names":[],"mappings":"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"}