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.
- package/AGENTS.md +15 -2
- package/AGENTS_BACKEND.md +144 -20
- package/AGENTS_FRONTEND.md +161 -67
- package/README.md +47 -26
- package/dist/bin/generate-schema.js +9 -26
- package/dist/bin/generate-tables.js +7 -30
- package/dist/bin/utils.d.ts +28 -0
- package/dist/bin/utils.d.ts.map +1 -1
- package/dist/bin/utils.js +69 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/cli/load-dependency.d.ts +8 -0
- package/dist/lib/cli/load-dependency.d.ts.map +1 -0
- package/dist/lib/cli/load-dependency.js +21 -0
- package/dist/lib/cli/mysql-introspect.d.ts.map +1 -1
- package/dist/lib/cli/mysql-introspect.js +2 -18
- package/dist/lib/cli/pg-introspect.d.ts.map +1 -1
- package/dist/lib/cli/pg-introspect.js +2 -17
- package/dist/lib/db.d.ts +1 -0
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +33 -55
- package/dist/lib/dialect.d.ts +17 -0
- package/dist/lib/dialect.d.ts.map +1 -1
- package/dist/lib/dialect.js +32 -0
- package/dist/lib/engine/bulk/bulk-delete.d.ts.map +1 -1
- package/dist/lib/engine/bulk/bulk-delete.js +8 -2
- package/dist/lib/engine/bulk/bulk-upsert.d.ts.map +1 -1
- package/dist/lib/engine/bulk/bulk-upsert.js +15 -43
- package/dist/lib/engine/rest/delete.d.ts.map +1 -1
- package/dist/lib/engine/rest/delete.js +14 -12
- package/dist/lib/engine/rest/get.d.ts.map +1 -1
- package/dist/lib/engine/rest/get.js +3 -5
- package/dist/lib/engine/rest/insert.d.ts.map +1 -1
- package/dist/lib/engine/rest/insert.js +11 -31
- package/dist/lib/engine/rest/update.d.ts.map +1 -1
- package/dist/lib/engine/rest/update.js +13 -46
- package/dist/lib/engine/search/search.d.ts.map +1 -1
- package/dist/lib/engine/search/search.js +553 -229
- package/dist/lib/engine/write-helpers.d.ts +39 -2
- package/dist/lib/engine/write-helpers.d.ts.map +1 -1
- package/dist/lib/engine/write-helpers.js +55 -12
- package/dist/lib/errors.d.ts +11 -0
- package/dist/lib/errors.d.ts.map +1 -0
- package/dist/lib/errors.js +12 -0
- package/dist/lib/schema/bulk-upsert.d.ts.map +1 -1
- package/dist/lib/schema/bulk-upsert.js +9 -25
- package/dist/lib/schema/helpers.d.ts +28 -1
- package/dist/lib/schema/helpers.d.ts.map +1 -1
- package/dist/lib/schema/helpers.js +38 -0
- package/dist/lib/schema/insert.d.ts.map +1 -1
- package/dist/lib/schema/insert.js +9 -19
- package/dist/lib/schema/search.d.ts.map +1 -1
- package/dist/lib/schema/search.js +138 -50
- package/dist/lib/schema/update.d.ts.map +1 -1
- package/dist/lib/schema/update.js +9 -25
- package/dist/lib/sql-api.d.ts +6 -6
- package/dist/lib/sql-api.d.ts.map +1 -1
- package/dist/lib/sql-api.js +10 -10
- package/dist/lib/table-helpers.d.ts +6 -1
- package/dist/lib/table-helpers.d.ts.map +1 -1
- package/dist/lib/table-helpers.js +42 -2
- package/dist/lib/tenant.d.ts +30 -0
- package/dist/lib/tenant.d.ts.map +1 -1
- package/dist/lib/tenant.js +78 -9
- package/dist/routes/auto/bulk-delete.routes.d.ts.map +1 -1
- package/dist/routes/auto/bulk-delete.routes.js +17 -23
- package/dist/routes/auto/bulk-upsert.routes.d.ts.map +1 -1
- package/dist/routes/auto/bulk-upsert.routes.js +16 -22
- package/dist/routes/auto/delete.routes.d.ts.map +1 -1
- package/dist/routes/auto/delete.routes.js +18 -24
- package/dist/routes/auto/get.routes.d.ts.map +1 -1
- package/dist/routes/auto/get.routes.js +16 -23
- package/dist/routes/auto/insert.routes.d.ts.map +1 -1
- package/dist/routes/auto/insert.routes.js +19 -26
- package/dist/routes/auto/plugin.d.ts.map +1 -1
- package/dist/routes/auto/plugin.js +40 -5
- package/dist/routes/auto/route-helpers.d.ts +27 -2
- package/dist/routes/auto/route-helpers.d.ts.map +1 -1
- package/dist/routes/auto/route-helpers.js +39 -1
- package/dist/routes/auto/search.routes.d.ts.map +1 -1
- package/dist/routes/auto/search.routes.js +47 -47
- package/dist/routes/auto/update.routes.d.ts.map +1 -1
- package/dist/routes/auto/update.routes.js +20 -27
- package/dist/types/cli.d.ts +22 -0
- package/dist/types/cli.d.ts.map +1 -0
- package/dist/types/cli.js +1 -0
- package/dist/types/computed.d.ts +29 -0
- package/dist/types/computed.d.ts.map +1 -0
- package/dist/types/computed.js +1 -0
- package/dist/types/conditions.d.ts +16 -0
- package/dist/types/conditions.d.ts.map +1 -0
- package/dist/types/conditions.js +1 -0
- package/dist/types/db.d.ts +22 -0
- package/dist/types/db.d.ts.map +1 -0
- package/dist/types/db.js +1 -0
- package/dist/types/dml.d.ts +66 -0
- package/dist/types/dml.d.ts.map +1 -0
- package/dist/types/dml.js +1 -0
- package/dist/types/join.d.ts +44 -0
- package/dist/types/join.d.ts.map +1 -0
- package/dist/types/join.js +1 -0
- package/dist/types/plugin.d.ts +20 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/plugin.js +1 -0
- package/dist/types/schema.d.ts +10 -0
- package/dist/types/schema.d.ts.map +1 -0
- package/dist/types/schema.js +1 -0
- package/dist/types/search.d.ts +45 -0
- package/dist/types/search.d.ts.map +1 -0
- package/dist/types/search.js +1 -0
- package/dist/types/table.d.ts +76 -0
- package/dist/types/table.d.ts.map +1 -0
- package/dist/types/table.js +7 -0
- package/dist/types/tenant.d.ts +19 -0
- package/dist/types/tenant.d.ts.map +1 -0
- package/dist/types/tenant.js +1 -0
- package/dist/types/validation.d.ts +21 -0
- package/dist/types/validation.d.ts.map +1 -0
- package/dist/types/validation.js +1 -0
- package/dist/types.d.ts +12 -277
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +12 -7
- package/package.json +3 -3
|
@@ -1,50 +1,50 @@
|
|
|
1
1
|
import { SearchTableBodyPost, SearchTableQueryString, SearchTableResponse } from '../../lib/schema/search.js';
|
|
2
|
-
import {
|
|
2
|
+
import { registerForAllTables } from './route-helpers.js';
|
|
3
3
|
export default async function searchRoutes(fastify, options) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
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,
|
|
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 {
|
|
2
|
+
import { registerForAllTables, buildWriteDescription } from './route-helpers.js';
|
|
3
3
|
export default async function updateRoutes(fastify, options) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
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"}
|
package/dist/types/db.js
ADDED
|
@@ -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":"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"}
|
|
@@ -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,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
|