fastify-auto-sqlapi 0.0.5 → 0.1.2

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 (123) hide show
  1. package/AGENTS.md +15 -2
  2. package/AGENTS_BACKEND.md +144 -20
  3. package/AGENTS_FRONTEND.md +161 -67
  4. package/README.md +47 -26
  5. package/dist/bin/generate-schema.js +9 -26
  6. package/dist/bin/generate-tables.js +7 -30
  7. package/dist/bin/utils.d.ts +28 -0
  8. package/dist/bin/utils.d.ts.map +1 -1
  9. package/dist/bin/utils.js +69 -0
  10. package/dist/index.d.ts +1 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/lib/cli/load-dependency.d.ts +8 -0
  13. package/dist/lib/cli/load-dependency.d.ts.map +1 -0
  14. package/dist/lib/cli/load-dependency.js +21 -0
  15. package/dist/lib/cli/mysql-introspect.d.ts.map +1 -1
  16. package/dist/lib/cli/mysql-introspect.js +2 -18
  17. package/dist/lib/cli/pg-introspect.d.ts.map +1 -1
  18. package/dist/lib/cli/pg-introspect.js +2 -17
  19. package/dist/lib/db.d.ts +1 -0
  20. package/dist/lib/db.d.ts.map +1 -1
  21. package/dist/lib/db.js +33 -55
  22. package/dist/lib/dialect.d.ts +17 -0
  23. package/dist/lib/dialect.d.ts.map +1 -1
  24. package/dist/lib/dialect.js +32 -0
  25. package/dist/lib/engine/bulk/bulk-delete.d.ts.map +1 -1
  26. package/dist/lib/engine/bulk/bulk-delete.js +8 -2
  27. package/dist/lib/engine/bulk/bulk-upsert.d.ts.map +1 -1
  28. package/dist/lib/engine/bulk/bulk-upsert.js +15 -43
  29. package/dist/lib/engine/rest/delete.d.ts.map +1 -1
  30. package/dist/lib/engine/rest/delete.js +14 -12
  31. package/dist/lib/engine/rest/get.d.ts.map +1 -1
  32. package/dist/lib/engine/rest/get.js +3 -5
  33. package/dist/lib/engine/rest/insert.d.ts.map +1 -1
  34. package/dist/lib/engine/rest/insert.js +11 -31
  35. package/dist/lib/engine/rest/update.d.ts.map +1 -1
  36. package/dist/lib/engine/rest/update.js +13 -46
  37. package/dist/lib/engine/search/search.d.ts.map +1 -1
  38. package/dist/lib/engine/search/search.js +553 -229
  39. package/dist/lib/engine/write-helpers.d.ts +39 -2
  40. package/dist/lib/engine/write-helpers.d.ts.map +1 -1
  41. package/dist/lib/engine/write-helpers.js +55 -12
  42. package/dist/lib/errors.d.ts +11 -0
  43. package/dist/lib/errors.d.ts.map +1 -0
  44. package/dist/lib/errors.js +12 -0
  45. package/dist/lib/schema/bulk-upsert.d.ts.map +1 -1
  46. package/dist/lib/schema/bulk-upsert.js +9 -25
  47. package/dist/lib/schema/helpers.d.ts +28 -1
  48. package/dist/lib/schema/helpers.d.ts.map +1 -1
  49. package/dist/lib/schema/helpers.js +38 -0
  50. package/dist/lib/schema/insert.d.ts.map +1 -1
  51. package/dist/lib/schema/insert.js +9 -19
  52. package/dist/lib/schema/search.d.ts.map +1 -1
  53. package/dist/lib/schema/search.js +138 -50
  54. package/dist/lib/schema/update.d.ts.map +1 -1
  55. package/dist/lib/schema/update.js +9 -25
  56. package/dist/lib/sql-api.d.ts +6 -6
  57. package/dist/lib/sql-api.d.ts.map +1 -1
  58. package/dist/lib/sql-api.js +10 -10
  59. package/dist/lib/table-helpers.d.ts +6 -1
  60. package/dist/lib/table-helpers.d.ts.map +1 -1
  61. package/dist/lib/table-helpers.js +42 -2
  62. package/dist/lib/tenant.d.ts +30 -0
  63. package/dist/lib/tenant.d.ts.map +1 -1
  64. package/dist/lib/tenant.js +78 -9
  65. package/dist/routes/auto/bulk-delete.routes.d.ts.map +1 -1
  66. package/dist/routes/auto/bulk-delete.routes.js +17 -23
  67. package/dist/routes/auto/bulk-upsert.routes.d.ts.map +1 -1
  68. package/dist/routes/auto/bulk-upsert.routes.js +16 -22
  69. package/dist/routes/auto/delete.routes.d.ts.map +1 -1
  70. package/dist/routes/auto/delete.routes.js +18 -24
  71. package/dist/routes/auto/get.routes.d.ts.map +1 -1
  72. package/dist/routes/auto/get.routes.js +16 -23
  73. package/dist/routes/auto/insert.routes.d.ts.map +1 -1
  74. package/dist/routes/auto/insert.routes.js +19 -26
  75. package/dist/routes/auto/plugin.d.ts.map +1 -1
  76. package/dist/routes/auto/plugin.js +40 -5
  77. package/dist/routes/auto/route-helpers.d.ts +27 -2
  78. package/dist/routes/auto/route-helpers.d.ts.map +1 -1
  79. package/dist/routes/auto/route-helpers.js +39 -1
  80. package/dist/routes/auto/search.routes.d.ts.map +1 -1
  81. package/dist/routes/auto/search.routes.js +47 -47
  82. package/dist/routes/auto/update.routes.d.ts.map +1 -1
  83. package/dist/routes/auto/update.routes.js +20 -27
  84. package/dist/types/cli.d.ts +22 -0
  85. package/dist/types/cli.d.ts.map +1 -0
  86. package/dist/types/cli.js +1 -0
  87. package/dist/types/computed.d.ts +29 -0
  88. package/dist/types/computed.d.ts.map +1 -0
  89. package/dist/types/computed.js +1 -0
  90. package/dist/types/conditions.d.ts +16 -0
  91. package/dist/types/conditions.d.ts.map +1 -0
  92. package/dist/types/conditions.js +1 -0
  93. package/dist/types/db.d.ts +22 -0
  94. package/dist/types/db.d.ts.map +1 -0
  95. package/dist/types/db.js +1 -0
  96. package/dist/types/dml.d.ts +66 -0
  97. package/dist/types/dml.d.ts.map +1 -0
  98. package/dist/types/dml.js +1 -0
  99. package/dist/types/join.d.ts +44 -0
  100. package/dist/types/join.d.ts.map +1 -0
  101. package/dist/types/join.js +1 -0
  102. package/dist/types/plugin.d.ts +20 -0
  103. package/dist/types/plugin.d.ts.map +1 -0
  104. package/dist/types/plugin.js +1 -0
  105. package/dist/types/schema.d.ts +10 -0
  106. package/dist/types/schema.d.ts.map +1 -0
  107. package/dist/types/schema.js +1 -0
  108. package/dist/types/search.d.ts +45 -0
  109. package/dist/types/search.d.ts.map +1 -0
  110. package/dist/types/search.js +1 -0
  111. package/dist/types/table.d.ts +76 -0
  112. package/dist/types/table.d.ts.map +1 -0
  113. package/dist/types/table.js +7 -0
  114. package/dist/types/tenant.d.ts +19 -0
  115. package/dist/types/tenant.d.ts.map +1 -0
  116. package/dist/types/tenant.js +1 -0
  117. package/dist/types/validation.d.ts +21 -0
  118. package/dist/types/validation.d.ts.map +1 -0
  119. package/dist/types/validation.js +1 -0
  120. package/dist/types.d.ts +12 -277
  121. package/dist/types.d.ts.map +1 -1
  122. package/dist/types.js +12 -7
  123. package/package.json +3 -3
@@ -1,50 +1,50 @@
1
1
  import { SearchTableBodyPost, SearchTableQueryString, SearchTableResponse } from '../../lib/schema/search.js';
2
- import { mergeOnRequests } from './route-helpers.js';
2
+ import { registerForAllTables } from './route-helpers.js';
3
3
  export default async function searchRoutes(fastify, options) {
4
- const { DbTables } = options;
5
- for (const [tableName, tableConf] of Object.entries(DbTables)) {
6
- const bodySchema = SearchTableBodyPost(DbTables, tableName);
7
- const responseSchema = SearchTableResponse(DbTables, tableName);
8
- const joinList = Object.keys(bodySchema.properties.joins?.properties || {}).join(', ');
9
- const description = [
10
- `Search records in ${tableName}`,
11
- joinList && `Available joins: ${joinList}`,
12
- ].filter(Boolean).join('. ');
13
- fastify.route({
14
- method: 'POST',
15
- url: `/search/${tableConf.Schema.tableName}`,
16
- schema: {
17
- body: bodySchema,
18
- querystring: SearchTableQueryString,
19
- response: { 200: responseSchema },
20
- tags: [`SqlAPI-${tableName}`],
21
- summary: `Search ${tableName}`,
22
- description,
23
- },
24
- onRequest: mergeOnRequests(options, tableConf),
25
- handler: async (request, reply) => {
26
- const body = request.body;
27
- const query = request.query;
28
- const result = await fastify.sqlApi.search(tableName, {
29
- filters: body.filters,
30
- conditions: body.conditions,
31
- joinFilters: body.joinFilters,
32
- joins: body.joins,
33
- joinGroups: body.joinGroups,
34
- orderBy: query.orderBy,
35
- paginator: (query.page || query.itemsPerPage)
36
- ? {
37
- page: query.page || 1,
38
- itemsPerPage: query.itemsPerPage || 500,
39
- }
40
- : undefined,
41
- computeMin: query.computeMin,
42
- computeMax: query.computeMax,
43
- computeSum: query.computeSum,
44
- computeAvg: query.computeAvg,
45
- }, request);
46
- reply.send({ table: tableConf.Schema.tableName, ...result });
47
- },
48
- });
49
- }
4
+ await registerForAllTables(fastify, options, {
5
+ method: 'POST',
6
+ url: (tc) => `/search/${tc.Schema.tableName}`,
7
+ successStatus: 200,
8
+ schemas: (db, table) => ({
9
+ body: SearchTableBodyPost(db, table),
10
+ querystring: SearchTableQueryString,
11
+ response: SearchTableResponse(db, table),
12
+ }),
13
+ summary: 'Search',
14
+ description: (name, _tc, schemas) => {
15
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
16
+ const body = schemas.body;
17
+ const multiAliases = Object.keys(body?.properties?.joinMultiple?.properties || {});
18
+ const leftAliases = Object.keys(body?.properties?.joinLeft?.properties || {});
19
+ return [
20
+ `Search records in ${name}`,
21
+ multiAliases.length && `Available joinMultiple/joinMustExist/joinGroup aliases: ${multiAliases.join(', ')}`,
22
+ leftAliases.length && `Available joinLeft aliases: ${leftAliases.join(', ')}`,
23
+ ].filter(Boolean).join('. ');
24
+ },
25
+ handle: async (fastify, tableName, tc, request) => {
26
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
27
+ const body = request.body;
28
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
29
+ const query = request.query;
30
+ const result = await fastify.sqlApi.search(tableName, {
31
+ filters: body.filters,
32
+ conditions: body.conditions,
33
+ joinMustExist: body.joinMustExist,
34
+ joinMultiple: body.joinMultiple,
35
+ joinGroup: body.joinGroup,
36
+ joinLeft: body.joinLeft,
37
+ selectComputed: body.selectComputed,
38
+ orderBy: query.orderBy,
39
+ paginator: (query.page || query.itemsPerPage)
40
+ ? { page: query.page || 1, itemsPerPage: query.itemsPerPage || 500 }
41
+ : undefined,
42
+ computeMin: query.computeMin,
43
+ computeMax: query.computeMax,
44
+ computeSum: query.computeSum,
45
+ computeAvg: query.computeAvg,
46
+ }, request);
47
+ return { table: tc.Schema.tableName, ...result };
48
+ },
49
+ });
50
50
  }
@@ -1 +1 @@
1
- {"version":3,"file":"update.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/update.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,YAAY,CACxC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
1
+ {"version":3,"file":"update.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/update.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,YAAY,CACxC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAwBf"}
@@ -1,30 +1,23 @@
1
1
  import { UpdateTableBody, UpdateTableResponse } from '../../lib/schema/update.js';
2
- import { mergeOnRequests, buildWriteDescription } from './route-helpers.js';
2
+ import { registerForAllTables, buildWriteDescription } from './route-helpers.js';
3
3
  export default async function updateRoutes(fastify, options) {
4
- const { DbTables } = options;
5
- for (const [tableName, tableConf] of Object.entries(DbTables)) {
6
- const bodySchema = UpdateTableBody(DbTables, tableName);
7
- const responseSchema = UpdateTableResponse(DbTables, tableName);
8
- fastify.route({
9
- method: 'PUT',
10
- url: `/rest/${tableConf.Schema.tableName}`,
11
- schema: {
12
- body: bodySchema,
13
- response: { 200: responseSchema },
14
- tags: [`SqlAPI-${tableName}`],
15
- summary: `Update ${tableName}`,
16
- description: buildWriteDescription('Update a record in', tableName, tableConf),
17
- },
18
- onRequest: mergeOnRequests(options, tableConf),
19
- handler: async (request, reply) => {
20
- const body = request.body;
21
- const result = await fastify.sqlApi.update(tableName, {
22
- record: body.main,
23
- secondaries: body.secondaries,
24
- deletions: body.deletions,
25
- }, request);
26
- reply.send(result);
27
- },
28
- });
29
- }
4
+ await registerForAllTables(fastify, options, {
5
+ method: 'PUT',
6
+ url: (tc) => `/rest/${tc.Schema.tableName}`,
7
+ successStatus: 200,
8
+ schemas: (db, table) => ({
9
+ body: UpdateTableBody(db, table),
10
+ response: UpdateTableResponse(db, table),
11
+ }),
12
+ summary: 'Update',
13
+ description: (name, tc) => buildWriteDescription('Update a record in', name, tc),
14
+ handle: (fastify, tableName, _tc, request) => {
15
+ const body = request.body;
16
+ return fastify.sqlApi.update(tableName, {
17
+ record: body.main,
18
+ secondaries: body.secondaries,
19
+ deletions: body.deletions,
20
+ }, request);
21
+ },
22
+ });
30
23
  }
@@ -0,0 +1,22 @@
1
+ import type { DialectName } from '../lib/dialect.js';
2
+ export interface SqlApiConfig {
3
+ outputDir: string;
4
+ schema?: string;
5
+ dialect?: DialectName;
6
+ envFile?: string;
7
+ }
8
+ export interface ColumnInfo {
9
+ table_name: string;
10
+ column_name: string;
11
+ udt_name: string;
12
+ column_default: string | null;
13
+ is_nullable: string;
14
+ }
15
+ export interface TableMap {
16
+ [schemaName: string]: {
17
+ name: string;
18
+ fields: Record<string, string>;
19
+ colMap: Record<string, string>;
20
+ };
21
+ }
22
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../src/types/cli.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,QAAQ;IACvB,CAAC,UAAU,EAAE,MAAM,GAAG;QACpB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KAChC,CAAC;CACH"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,29 @@
1
+ import type { TSchema } from '@sinclair/typebox';
2
+ import type { QueryClient } from '../lib/db.js';
3
+ /**
4
+ * Context passed to ComputedFieldFn when the engine resolves a computed field.
5
+ * - `db` exposes dialect-aware helpers (qi, ph, dialectName, dateTrunc, ...).
6
+ * - `qiCol(field, opts?)` returns a quoted column reference, optionally
7
+ * prefixed by an alias qualifier — needed when the computed is embedded in
8
+ * a `LEFT JOIN <table> AS <alias>` (joinLeft).
9
+ */
10
+ export interface ComputedFieldContext {
11
+ db: QueryClient;
12
+ qiCol(field: string, opts?: {
13
+ qualifier?: string;
14
+ }): string;
15
+ }
16
+ /**
17
+ * Result returned by a ComputedFieldFn.
18
+ * - `expr`: SQL fragment usable as a scalar expression.
19
+ * - `values`: bound parameter values (always parameterized — never interpolate
20
+ * user-derived data into `expr`).
21
+ * - `type`: TypeBox schema for Swagger filters and main response (REQUIRED).
22
+ */
23
+ export interface ComputedFieldExpr {
24
+ expr: string;
25
+ values: unknown[];
26
+ type: TSchema;
27
+ }
28
+ export type ComputedFieldFn = (ctx: ComputedFieldContext) => ComputedFieldExpr;
29
+ //# sourceMappingURL=computed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"computed.d.ts","sourceRoot":"","sources":["../../src/types/computed.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD;;;;;;GAMG;AACH,MAAM,WAAW,oBAAoB;IACnC,EAAE,EAAE,WAAW,CAAC;IAChB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,CAAC;CAC7D;AAED;;;;;;GAMG;AACH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,oBAAoB,KAAK,iBAAiB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,16 @@
1
+ import type { ConditionBuilder as CB } from 'node-condition-builder';
2
+ type SingleValueMethods = 'isEqual' | 'isNotEqual' | 'isGreater' | 'isNotGreater' | 'isGreaterOrEqual' | 'isNotGreaterOrEqual' | 'isLess' | 'isNotLess' | 'isLessOrEqual' | 'isNotLessOrEqual' | 'isLike' | 'isNotLike' | 'isILike' | 'isNotILike';
3
+ type BetweenMethods = 'isBetween' | 'isNotBetween';
4
+ type InMethods = 'isIn' | 'isNotIn';
5
+ type NullMethods = 'isNull' | 'isNotNull';
6
+ export type ConditionMethod = SingleValueMethods | BetweenMethods | InMethods | NullMethods;
7
+ type ConditionParams<M extends ConditionMethod> = M extends SingleValueMethods ? [value: Parameters<CB[M]>[1]] : M extends BetweenMethods ? [from: Parameters<CB[M]>[1], to: Parameters<CB[M]>[2]] : M extends InMethods ? [values: Parameters<CB[M]>[1]] : M extends NullMethods ? [] : never;
8
+ export type SearchCondition<F extends string = string> = {
9
+ [M in ConditionMethod]: {
10
+ field: F;
11
+ method: M;
12
+ params: ConditionParams<M>;
13
+ };
14
+ }[ConditionMethod];
15
+ export {};
16
+ //# sourceMappingURL=conditions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conditions.d.ts","sourceRoot":"","sources":["../../src/types/conditions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,IAAI,EAAE,EAAE,MAAM,wBAAwB,CAAC;AAGrE,KAAK,kBAAkB,GACnB,SAAS,GAAG,YAAY,GACxB,WAAW,GAAG,cAAc,GAAG,kBAAkB,GAAG,qBAAqB,GACzE,QAAQ,GAAG,WAAW,GAAG,eAAe,GAAG,kBAAkB,GAC7D,QAAQ,GAAG,WAAW,GAAG,SAAS,GAAG,YAAY,CAAC;AAGtD,KAAK,cAAc,GAAG,WAAW,GAAG,cAAc,CAAC;AAGnD,KAAK,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAGpC,KAAK,WAAW,GAAG,QAAQ,GAAG,WAAW,CAAC;AAE1C,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG,cAAc,GAAG,SAAS,GAAG,WAAW,CAAC;AAG5F,KAAK,eAAe,CAAC,CAAC,SAAS,eAAe,IAC5C,CAAC,SAAS,kBAAkB,GAAG,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAC5D,CAAC,SAAS,cAAc,GAAG,CAAC,IAAI,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACjF,CAAC,SAAS,SAAS,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GACpD,CAAC,SAAS,WAAW,GAAG,EAAE,GAC1B,KAAK,CAAC;AAER,MAAM,MAAM,eAAe,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;KACtD,CAAC,IAAI,eAAe,GAAG;QAAE,KAAK,EAAE,CAAC,CAAC;QAAC,MAAM,EAAE,CAAC,CAAC;QAAC,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAA;KAAE;CAC5E,CAAC,eAAe,CAAC,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ import type { Expression } from 'node-condition-builder';
2
+ export interface SqlResult<T = Record<string, unknown>> {
3
+ rows: T[];
4
+ affectedRows: number;
5
+ insertId?: number;
6
+ }
7
+ export interface Queryable {
8
+ query<T = Record<string, unknown>>(text: string, values?: unknown[]): Promise<SqlResult<T>>;
9
+ }
10
+ export type DbRecordValue = string | number | boolean | null | Expression;
11
+ export type DbRecord = Record<string, DbRecordValue>;
12
+ export interface SelectOptions {
13
+ tableName: string;
14
+ columns?: string;
15
+ where: string;
16
+ values: unknown[];
17
+ limit?: string | null;
18
+ orderBy?: string;
19
+ joins?: string[];
20
+ distinct?: boolean;
21
+ }
22
+ //# sourceMappingURL=db.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.d.ts","sourceRoot":"","sources":["../../src/types/db.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAEzD,MAAM,WAAW,SAAS,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IACpD,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,IAAI,EAAE,MAAM,EACZ,MAAM,CAAC,EAAE,OAAO,EAAE,GACjB,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;CAC1B;AAED,MAAM,MAAM,aAAa,GACrB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,UAAU,CAAC;AAEf,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;AAErD,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,OAAO,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,66 @@
1
+ import type { FastifyRequest } from 'fastify';
2
+ import type { QueryClient } from '../lib/db.js';
3
+ import type { ITable, DbTables } from './table.js';
4
+ import type { TenantContext } from './tenant.js';
5
+ interface DmlBaseParams {
6
+ db: QueryClient;
7
+ tableConf: ITable;
8
+ tenant?: TenantContext;
9
+ }
10
+ interface DmlWriteBaseParams extends DmlBaseParams {
11
+ dbTables: DbTables;
12
+ request: FastifyRequest;
13
+ }
14
+ export interface InsertParams extends DmlWriteBaseParams {
15
+ record: Record<string, unknown>;
16
+ secondaries?: Record<string, Record<string, unknown>[]>;
17
+ }
18
+ export interface InsertResult {
19
+ main: Record<string, unknown>;
20
+ secondaries?: Record<string, Record<string, unknown>[]>;
21
+ }
22
+ export interface UpdateParams extends DmlWriteBaseParams {
23
+ record: Record<string, unknown>;
24
+ secondaries?: Record<string, Record<string, unknown>[]>;
25
+ deletions?: Record<string, Record<string, unknown>[]>;
26
+ }
27
+ export interface UpdateResult {
28
+ main: Record<string, unknown>;
29
+ secondaries?: Record<string, Record<string, unknown>[]>;
30
+ deletions?: Record<string, Record<string, unknown>[]>;
31
+ }
32
+ export interface GetParams extends DmlBaseParams {
33
+ id: string | number;
34
+ }
35
+ export interface GetResult {
36
+ main: Record<string, unknown>;
37
+ }
38
+ export interface DeleteParams extends DmlBaseParams {
39
+ id: string | number;
40
+ request?: FastifyRequest;
41
+ }
42
+ export interface DeleteResult {
43
+ main: Record<string, unknown>;
44
+ }
45
+ export interface BulkUpsertItem {
46
+ main: Record<string, unknown>;
47
+ secondaries?: Record<string, Record<string, unknown>[]>;
48
+ deletions?: Record<string, Record<string, unknown>[]>;
49
+ }
50
+ export interface BulkUpsertParams extends DmlWriteBaseParams {
51
+ items: BulkUpsertItem[];
52
+ }
53
+ export interface BulkUpsertResult {
54
+ main: Record<string, unknown>;
55
+ secondaries?: Record<string, Record<string, unknown>[]>;
56
+ deletions?: Record<string, Record<string, unknown>[]>;
57
+ }
58
+ export interface BulkDeleteParams extends DmlBaseParams {
59
+ ids: (string | number)[];
60
+ request?: FastifyRequest;
61
+ }
62
+ export interface BulkDeleteResult {
63
+ main: Record<string, unknown>;
64
+ }
65
+ export {};
66
+ //# sourceMappingURL=dml.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dml.d.ts","sourceRoot":"","sources":["../../src/types/dml.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,UAAU,aAAa;IACrB,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,UAAU,kBAAmB,SAAQ,aAAa;IAChD,QAAQ,EAAE,QAAQ,CAAC;IACnB,OAAO,EAAE,cAAc,CAAC;CACzB;AAID,MAAM,WAAW,YAAa,SAAQ,kBAAkB;IACtD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CACzD;AAID,MAAM,WAAW,YAAa,SAAQ,kBAAkB;IACtD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CACvD;AAID,MAAM,WAAW,SAAU,SAAQ,aAAa;IAC9C,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAID,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD,EAAE,EAAE,MAAM,GAAG,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B;AAID,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,KAAK,EAAE,cAAc,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACxD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;CACvD;AAID,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,GAAG,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAC/B"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,44 @@
1
+ import type { SchemaDefinition } from './schema.js';
2
+ import type { FilterRecord } from './table.js';
3
+ import type { SearchCondition } from './conditions.js';
4
+ export interface JoinDefinition {
5
+ joinSchema: SchemaDefinition;
6
+ joinField: string;
7
+ mainField: string | string[];
8
+ alias: string;
9
+ selection: string;
10
+ unique: boolean;
11
+ }
12
+ export interface AggregationRequest {
13
+ /**
14
+ * GROUP BY field. Either a schema field name on the join table or a
15
+ * computed-field name declared on the join table's `computedFields`.
16
+ */
17
+ by?: string;
18
+ distinctCount?: string[];
19
+ min?: string[];
20
+ max?: string[];
21
+ sum?: string[];
22
+ avg?: string[];
23
+ count?: string[];
24
+ }
25
+ export interface JoinGroupRequest {
26
+ aggregations: AggregationRequest;
27
+ filters?: FilterRecord;
28
+ conditions?: SearchCondition[];
29
+ }
30
+ /**
31
+ * Reference filter for join-based existential filtering (joinMustExist),
32
+ * virtual joins data fetching (joinMultiple), and parent inline (joinLeft).
33
+ * Combines equality-based filters with rich ConditionBuilder-powered conditions,
34
+ * both applied to the join schema.
35
+ */
36
+ export interface JoinRefFilter {
37
+ filters?: FilterRecord;
38
+ conditions?: SearchCondition[];
39
+ }
40
+ /** Per-request override of the per-relation default selection. */
41
+ export interface JoinFetchRequest extends JoinRefFilter {
42
+ selection?: string;
43
+ }
44
+ //# sourceMappingURL=join.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"join.d.ts","sourceRoot":"","sources":["../../src/types/join.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,OAAO,CAAC;CACjB;AAED,MAAM,WAAW,kBAAkB;IACjC;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,kBAAkB,CAAC;IACjC,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED;;;;;GAKG;AACH,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;CAChC;AAED,kEAAkE;AAClE,MAAM,WAAW,gBAAiB,SAAQ,aAAa;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,20 @@
1
+ import type { FastifyRequest, FastifyReply } from 'fastify';
2
+ import type { DialectName } from '../lib/dialect.js';
3
+ import type { DbTables } from './table.js';
4
+ import type { TenantId } from './tenant.js';
5
+ export interface SwaggerOptions {
6
+ title?: string;
7
+ description?: string;
8
+ version?: string;
9
+ routePrefix?: string;
10
+ }
11
+ export interface SqlApiPluginOptions {
12
+ DbTables: DbTables;
13
+ onRequests?: ((request: FastifyRequest, reply: FastifyReply) => Promise<void | FastifyReply>)[];
14
+ prefix?: string;
15
+ swagger?: boolean | SwaggerOptions;
16
+ dialect?: DialectName;
17
+ getTenantId?: (request: FastifyRequest) => TenantId | TenantId[] | null | undefined | Promise<TenantId | TenantId[] | null | undefined>;
18
+ debug?: boolean;
19
+ }
20
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/types/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC3C,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,QAAQ,CAAC;IACnB,UAAU,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC,EAAE,CAAC;IAChG,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;IACnC,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,WAAW,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,GAAG,SAAS,GAC/E,OAAO,CAAC,QAAQ,GAAG,QAAQ,EAAE,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACtD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,10 @@
1
+ import type { TSchema, TObject } from '@sinclair/typebox';
2
+ export interface SchemaDefinition<T = Record<string, TSchema>> {
3
+ col(field: string): string;
4
+ colMap?: Record<string, string>;
5
+ fields: T;
6
+ validation: TObject;
7
+ tableName: string;
8
+ partialValidation: TObject;
9
+ }
10
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/types/schema.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE1D,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;IAC3D,GAAG,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAAC;IAC3B,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,MAAM,EAAE,CAAC,CAAC;IACV,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,EAAE,OAAO,CAAC;CAC5B"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,45 @@
1
+ import type { QueryClient } from '../lib/db.js';
2
+ import type { ITable, FilterRecord } from './table.js';
3
+ import type { TenantContext } from './tenant.js';
4
+ import type { JoinFetchRequest, JoinGroupRequest, JoinRefFilter } from './join.js';
5
+ import type { SearchCondition } from './conditions.js';
6
+ export interface Paginator {
7
+ page: number;
8
+ itemsPerPage: number;
9
+ }
10
+ export interface SearchParams {
11
+ db: QueryClient;
12
+ tableConf: ITable;
13
+ filters?: FilterRecord;
14
+ conditions?: SearchCondition[];
15
+ joinMustExist?: Record<string, JoinRefFilter>;
16
+ joinMultiple?: Record<string, JoinFetchRequest>;
17
+ joinGroup?: Record<string, JoinGroupRequest>;
18
+ joinLeft?: Record<string, JoinFetchRequest>;
19
+ orderBy?: string;
20
+ paginator?: Paginator;
21
+ computeMin?: string;
22
+ computeMax?: string;
23
+ computeSum?: string;
24
+ computeAvg?: string;
25
+ /**
26
+ * Names of computed fields (declared on `tableConf.computedFields`) to project
27
+ * into the main response. Each becomes an extra column on each `main[i]` row.
28
+ */
29
+ selectComputed?: string[];
30
+ tenant?: TenantContext;
31
+ }
32
+ export interface PaginationResult {
33
+ total: number;
34
+ pages: number;
35
+ computed?: Record<string, Record<string, unknown>>;
36
+ paginator: Paginator;
37
+ }
38
+ export interface SearchResult {
39
+ main: Record<string, unknown>[];
40
+ joinMultiple?: Record<string, Record<string, unknown>[]>;
41
+ joinLeft?: Record<string, Record<string, unknown>[]>;
42
+ joinGroup?: Record<string, Record<string, unknown>>;
43
+ pagination?: PaginationResult;
44
+ }
45
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/types/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AACnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAEvD,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,WAAW,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,UAAU,CAAC,EAAE,eAAe,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAC9C,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAChD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC7C,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACnD,SAAS,EAAE,SAAS,CAAC;CACtB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACzD,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;IACrD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;IACpD,UAAU,CAAC,EAAE,gBAAgB,CAAC;CAC/B"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,76 @@
1
+ import type { Expression, ConditionBuilder, ConditionValueOrUndefined } from 'node-condition-builder';
2
+ import type { TSchema, Static } from '@sinclair/typebox';
3
+ import type { FastifyRequest, FastifyReply } from 'fastify';
4
+ import type { QueryClient } from '../lib/db.js';
5
+ import type { SchemaDefinition } from './schema.js';
6
+ import type { ComputedFieldFn } from './computed.js';
7
+ import type { JoinDefinition } from './join.js';
8
+ import type { TenantScope } from './tenant.js';
9
+ import type { ValidatorFn, BulkValidatorFn } from './validation.js';
10
+ export type FilterRecord = Record<string, ConditionValueOrUndefined>;
11
+ export type ExtendedConditionFn = (condition: ConditionBuilder, filters: FilterRecord) => void;
12
+ export type TableFilterFn = (filters: FilterRecord) => ConditionBuilder;
13
+ export interface ITable<F extends Record<string, TSchema> = Record<string, TSchema>> {
14
+ primary: (string & keyof F) | (string & keyof F)[];
15
+ Schema: SchemaDefinition<F>;
16
+ filters: TableFilterFn;
17
+ extraFilters: Record<string, TSchema>;
18
+ /**
19
+ * Virtual fields produced by a SQL expression. Usable like schema fields in
20
+ * `filters`, `conditions` (non-dotted), `orderBy` (1-parte),
21
+ * `computeMin/Max/Sum/Avg`, and (opt-in) in `selectComputed` for the main
22
+ * response. Each entry MUST declare `type` for Swagger and validation.
23
+ *
24
+ * Naming clashes with `Schema.fields` or `extraFilters` keys throw at
25
+ * `defineTable` time.
26
+ */
27
+ computedFields?: Record<string, ComputedFieldFn>;
28
+ allowedReadJoins?: JoinDefinition[];
29
+ allowedWriteJoins?: JoinDefinition[];
30
+ upsertMap?: Map<SchemaDefinition, string[]>;
31
+ schemaOverrides?: Partial<Record<string & keyof F, TSchema>>;
32
+ validate?: ValidatorFn<F>;
33
+ validateBulk?: BulkValidatorFn<F>;
34
+ beforeInsert?: (db: QueryClient, req: FastifyRequest, record: {
35
+ [K in keyof F]?: Static<F[K]> | Expression | null;
36
+ }) => Promise<void>;
37
+ beforeUpdate?: (db: QueryClient, req: FastifyRequest, fields: {
38
+ [K in keyof F]?: Static<F[K]> | Expression | null;
39
+ }, secondaryFieldsFetcher?: unknown) => void | Promise<void>;
40
+ afterInsert?: (db: QueryClient, req: FastifyRequest, record: {
41
+ [K in keyof F]?: Static<F[K]>;
42
+ }, secondaryRecords?: unknown) => Promise<void>;
43
+ /**
44
+ * Runs before a single record is deleted (DELETE /rest/:id). Throw to abort the
45
+ * deletion (the thrown error's `statusCode`/`message` are surfaced to the client).
46
+ * Use it to enforce referential or business rules the DB cascade would otherwise hide.
47
+ *
48
+ * For tenant-scoped tables the hook only runs once ownership has been verified, so it
49
+ * never fires for rows the caller cannot access.
50
+ *
51
+ * `req` is the Fastify request that triggered the operation. It is always present when
52
+ * the delete comes through the auto-generated HTTP route. It is `undefined` only if you
53
+ * call `sqlApi.delete(table, id)` programmatically without passing a request — in that
54
+ * case any hook that reads request context (e.g. `req.user`) must guard for it.
55
+ */
56
+ beforeDelete?: (db: QueryClient, req: FastifyRequest, id: string | number) => void | Promise<void>;
57
+ /**
58
+ * Bulk counterpart of `beforeDelete`, invoked ONCE with all ids before a bulk delete
59
+ * (POST /bulk/:table/delete). Called once — not per id — to preserve the single-query
60
+ * optimization. Throw to abort the whole batch. `beforeDelete` is NOT called for bulk
61
+ * deletes; configure this hook if you need a guard there.
62
+ *
63
+ * Same `req` caveat as `beforeDelete`: present via the HTTP route, `undefined` only when
64
+ * `sqlApi.bulkDelete(table, ids)` is called programmatically without a request.
65
+ */
66
+ beforeBulkDelete?: (db: QueryClient, req: FastifyRequest, ids: (string | number)[]) => void | Promise<void>;
67
+ defaultOrder?: string;
68
+ excludeFromCreation?: (string & keyof F)[];
69
+ distinctResults?: boolean;
70
+ onRequests?: ((request: FastifyRequest, reply: FastifyReply) => Promise<void | FastifyReply>)[];
71
+ tenantScope?: TenantScope;
72
+ }
73
+ export type DbTables = Record<string, ITable<any>>;
74
+ export declare function primaryAsString(pk: string | string[]): string;
75
+ export declare function primaryAsCols(pk: string | string[], colFn: (f: string) => string): string | string[];
76
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/types/table.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ // Primary key helpers
2
+ export function primaryAsString(pk) {
3
+ return Array.isArray(pk) ? pk[0] : pk;
4
+ }
5
+ export function primaryAsCols(pk, colFn) {
6
+ return Array.isArray(pk) ? pk.map(colFn) : colFn(pk);
7
+ }
@@ -0,0 +1,19 @@
1
+ import type { SchemaDefinition } from './schema.js';
2
+ export type TenantId = string | number;
3
+ export interface TenantScopeDirect {
4
+ column: string;
5
+ }
6
+ export interface TenantScopeIndirect {
7
+ column: string;
8
+ through: {
9
+ schema: SchemaDefinition;
10
+ localField: string;
11
+ foreignField: string;
12
+ };
13
+ }
14
+ export type TenantScope = TenantScopeDirect | TenantScopeIndirect;
15
+ export interface TenantContext {
16
+ ids: TenantId[];
17
+ scope: TenantScope;
18
+ }
19
+ //# sourceMappingURL=tenant.d.ts.map