fastify-auto-sqlapi 0.1.2 → 0.1.4
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_BACKEND.md +41 -2
- package/AGENTS_FRONTEND.md +7 -5
- package/README.md +105 -5
- package/dist/bin/generate-schema.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/lib/adapters/mysql-adapter.d.ts +4 -0
- package/dist/lib/adapters/mysql-adapter.d.ts.map +1 -1
- package/dist/lib/adapters/mysql-adapter.js +28 -17
- package/dist/lib/adapters/pg-adapter.d.ts +4 -0
- package/dist/lib/adapters/pg-adapter.d.ts.map +1 -1
- package/dist/lib/adapters/pg-adapter.js +18 -7
- package/dist/lib/cli/mysql-introspect.d.ts.map +1 -1
- package/dist/lib/cli/mysql-introspect.js +3 -1
- package/dist/lib/cli/pg-introspect.d.ts.map +1 -1
- package/dist/lib/cli/pg-introspect.js +13 -4
- package/dist/lib/cli/schema-codegen.d.ts +2 -1
- package/dist/lib/cli/schema-codegen.d.ts.map +1 -1
- package/dist/lib/cli/schema-codegen.js +17 -3
- package/dist/lib/cli/tables-codegen.d.ts +2 -0
- package/dist/lib/cli/tables-codegen.d.ts.map +1 -1
- package/dist/lib/cli/tables-codegen.js +43 -12
- package/dist/lib/db.d.ts +17 -0
- package/dist/lib/db.d.ts.map +1 -1
- package/dist/lib/db.js +47 -0
- package/dist/lib/engine/bulk/bulk-delete.d.ts.map +1 -1
- package/dist/lib/engine/bulk/bulk-delete.js +25 -8
- package/dist/lib/engine/bulk/bulk-upsert.d.ts.map +1 -1
- package/dist/lib/engine/bulk/bulk-upsert.js +12 -9
- package/dist/lib/engine/rest/delete.d.ts.map +1 -1
- package/dist/lib/engine/rest/delete.js +9 -5
- package/dist/lib/engine/rest/get.js +1 -1
- package/dist/lib/engine/rest/insert.d.ts.map +1 -1
- package/dist/lib/engine/rest/insert.js +41 -34
- package/dist/lib/engine/rest/update.d.ts.map +1 -1
- package/dist/lib/engine/rest/update.js +74 -57
- package/dist/lib/engine/search/search.d.ts.map +1 -1
- package/dist/lib/engine/search/search.js +94 -34
- package/dist/lib/schema/bulk-delete.d.ts +1 -1
- package/dist/lib/schema/bulk-delete.d.ts.map +1 -1
- package/dist/lib/schema/bulk-delete.js +2 -2
- package/dist/lib/schema/bulk-upsert.d.ts +1 -1
- package/dist/lib/schema/bulk-upsert.d.ts.map +1 -1
- package/dist/lib/schema/bulk-upsert.js +5 -3
- package/dist/lib/schema/helpers.d.ts +2 -0
- package/dist/lib/schema/helpers.d.ts.map +1 -1
- package/dist/lib/schema/helpers.js +3 -2
- package/dist/lib/schema/insert.d.ts.map +1 -1
- package/dist/lib/schema/insert.js +4 -1
- package/dist/lib/schema/update.d.ts.map +1 -1
- package/dist/lib/schema/update.js +4 -1
- package/dist/lib/sql-api.d.ts +2 -0
- package/dist/lib/sql-api.d.ts.map +1 -1
- package/dist/lib/sql-api.js +1 -0
- package/dist/lib/table-helpers.d.ts.map +1 -1
- package/dist/lib/table-helpers.js +10 -9
- package/dist/lib/tenant.d.ts +24 -2
- package/dist/lib/tenant.d.ts.map +1 -1
- package/dist/lib/tenant.js +0 -0
- package/dist/routes/auto/bulk-delete.routes.d.ts.map +1 -1
- package/dist/routes/auto/bulk-delete.routes.js +3 -1
- package/dist/routes/auto/bulk-upsert.routes.d.ts.map +1 -1
- package/dist/routes/auto/bulk-upsert.routes.js +3 -1
- package/dist/routes/auto/delete.routes.d.ts.map +1 -1
- package/dist/routes/auto/delete.routes.js +1 -0
- package/dist/routes/auto/get.routes.d.ts.map +1 -1
- package/dist/routes/auto/get.routes.js +1 -0
- package/dist/routes/auto/insert.routes.d.ts.map +1 -1
- package/dist/routes/auto/insert.routes.js +1 -0
- package/dist/routes/auto/route-helpers.d.ts +3 -1
- package/dist/routes/auto/route-helpers.d.ts.map +1 -1
- package/dist/routes/auto/route-helpers.js +3 -0
- package/dist/routes/auto/search.routes.d.ts.map +1 -1
- package/dist/routes/auto/search.routes.js +9 -0
- package/dist/routes/auto/update.routes.d.ts.map +1 -1
- package/dist/routes/auto/update.routes.js +1 -0
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/cli.d.ts.map +1 -1
- package/dist/types/db.d.ts +11 -0
- package/dist/types/db.d.ts.map +1 -1
- package/dist/types/plugin.d.ts +16 -0
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/plugin.js +4 -1
- package/dist/types/schema.d.ts +2 -0
- package/dist/types/schema.d.ts.map +1 -1
- package/dist/types/search.d.ts +7 -0
- package/dist/types/search.d.ts.map +1 -1
- package/dist/types/table.d.ts +40 -2
- package/dist/types/table.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -11,11 +11,14 @@ export function UpdateTableBody(dbTables, tableName) {
|
|
|
11
11
|
mainFields[key] = key === primaryAsString(tableConf.primary) ? value : Type.Optional(value);
|
|
12
12
|
}
|
|
13
13
|
const bodyProperties = {
|
|
14
|
-
|
|
14
|
+
// additionalProperties:false makes the schema the real write whitelist — unknown keys are
|
|
15
|
+
// rejected (400) instead of silently reaching the UPDATE as columns (mass assignment).
|
|
16
|
+
main: Type.Object(mainFields, { additionalProperties: false }),
|
|
15
17
|
};
|
|
16
18
|
attachWriteJoinSections(bodyProperties, tableConf, dbTables, {
|
|
17
19
|
withDeletions: true,
|
|
18
20
|
secondaryFields: writeJoinBodyFields,
|
|
21
|
+
strictItems: true,
|
|
19
22
|
});
|
|
20
23
|
return Type.Object(bodyProperties);
|
|
21
24
|
}
|
package/dist/lib/sql-api.d.ts
CHANGED
|
@@ -16,6 +16,8 @@ export interface SqlApiSearchParams {
|
|
|
16
16
|
computeSum?: string;
|
|
17
17
|
computeAvg?: string;
|
|
18
18
|
selectComputed?: string[];
|
|
19
|
+
/** Row cap for the main query when no paginator is provided (see SearchParams.maxRows). */
|
|
20
|
+
maxRows?: number;
|
|
19
21
|
}
|
|
20
22
|
export interface SqlApiInsertParams {
|
|
21
23
|
record: Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sql-api.d.ts","sourceRoot":"","sources":["../../src/lib/sql-api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAE9C,OAAO,EAAqB,WAAW,EAAE,MAAM,SAAS,CAAC;AACzD,OAAO,EAAc,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAU5D,OAAO,KAAK,EACV,QAAQ,EACR,SAAS,EACT,YAAY,EACZ,eAAe,EACf,SAAS,EACT,gBAAgB,EAChB,aAAa,EACb,gBAAgB,EAChB,YAAY,EACZ,SAAS,EACT,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EAGT,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,kBAAkB;IACjC,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,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"sql-api.d.ts","sourceRoot":"","sources":["../../src/lib/sql-api.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/sql-api.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/table-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,yBAAyB,
|
|
1
|
+
{"version":3,"file":"table-helpers.d.ts","sourceRoot":"","sources":["../../src/lib/table-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,KAAK,yBAAyB,EAAiC,MAAM,wBAAwB,CAAC;AACzH,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAC1D,OAAO,KAAK,EACV,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,MAAM,EACP,MAAM,aAAa,CAAC;AAarB,KAAK,UAAU,CAAC,EAAE,IAAI,EAAE,SAAS,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AAExH,wBAAgB,eAAe,CAC7B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,EAAE,SAAS,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,EAErE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,YAAY,GAAE,EAAa,EAC3B,iBAAiB,CAAC,EAAE,CAClB,SAAS,EAAE,gBAAgB,EAC3B,OAAO,EAAE;KAAG,CAAC,IAAI,MAAM,CAAC,GAAG,MAAM,UAAU,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,yBAAyB;CAAE,KAC3E,IAAI,GACR;IAAE,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;IAAC,OAAO,EAAE,aAAa,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CA0BhG;AAED,wBAAgB,WAAW,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC3D,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,GAChB,MAAM,CAAC,CAAC,CAAC,CAKX;AA2CD,MAAM,WAAW,oBAAoB;IACnC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,wBAAgB,aAAa,CAC3B,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAEjC,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,EAClD,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC/B,SAAS,EAAE,MAAM,GAAG,MAAM,CAAC,EAC3B,OAAO,CAAC,EAAE,oBAAoB,GAC7B,cAAc,CAShB;AAED,wBAAgB,eAAe,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/D,MAAM,EAAE,gBAAgB,CAAC,CAAC,CAAC,EAC3B,OAAO,EAAE,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC,EAAE,GAC5B,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAE9B;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,KAAK,EAAE,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,EAAE,GACvC,GAAG,CAAC,gBAAgB,EAAE,MAAM,EAAE,CAAC,CAEjC"}
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { ConditionBuilder } from 'node-condition-builder';
|
|
2
2
|
import { getDialect } from './dialect.js';
|
|
3
|
-
// Quote an identifier using the
|
|
4
|
-
// Needed so that DB columns with uppercase letters
|
|
5
|
-
// are preserved on PostgreSQL (which folds unquoted
|
|
6
|
-
// and on MySQL (which is case-sensitive on Linux
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
// Quote an identifier using the given ConditionBuilder dialect (or the global
|
|
4
|
+
// default when not provided). Needed so that DB columns with uppercase letters
|
|
5
|
+
// (e.g. betterauth "userId") are preserved on PostgreSQL (which folds unquoted
|
|
6
|
+
// identifiers to lowercase) and on MySQL (which is case-sensitive on Linux
|
|
7
|
+
// filesystems).
|
|
8
|
+
function qi(field, dialect) {
|
|
9
|
+
return getDialect(dialect ?? ConditionBuilder.DIALECT).qi(field);
|
|
9
10
|
}
|
|
10
11
|
export function exportTableInfo(Schema, extraFilters = {}, extendedCondition) {
|
|
11
|
-
const filters = (filterValues) => {
|
|
12
|
-
const condition = new ConditionBuilder('AND');
|
|
12
|
+
const filters = (filterValues, dialect) => {
|
|
13
|
+
const condition = new ConditionBuilder('AND', dialect);
|
|
13
14
|
// Only auto-match real schema fields (DB columns)
|
|
14
15
|
for (const field of Object.keys(Schema.fields)) {
|
|
15
16
|
if (field in filterValues && filterValues[field] !== null && filterValues[field] !== undefined) {
|
|
16
|
-
condition.isEqual(qi(Schema.col(field)), filterValues[field]);
|
|
17
|
+
condition.isEqual(qi(Schema.col(field), dialect), filterValues[field]);
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
// extraFilters are handled exclusively by extendedCondition
|
package/dist/lib/tenant.d.ts
CHANGED
|
@@ -15,6 +15,28 @@ export declare function buildTenantDeleteWhere(db: QueryClient, tableName: strin
|
|
|
15
15
|
where: string;
|
|
16
16
|
values: unknown[];
|
|
17
17
|
};
|
|
18
|
+
/**
|
|
19
|
+
* Guard the conflict target of an UPSERT (INSERT … ON CONFLICT / ON DUPLICATE KEY) on a
|
|
20
|
+
* tenant-scoped table. Without this, an upsert whose conflict key matches a row owned by
|
|
21
|
+
* ANOTHER tenant would silently UPDATE (and, for direct scopes, re-assign) that row, because
|
|
22
|
+
* the conflict is matched by the unique key alone — the tenant is never part of the ON CONFLICT
|
|
23
|
+
* predicate. This pre-checks that no existing row matching the incoming conflict keys belongs to
|
|
24
|
+
* a different tenant, throwing 403 if one does. No-op when `tenant` is undefined.
|
|
25
|
+
*
|
|
26
|
+
* `conflictCols` and the keys of each record are DB column names (snake_case). Records missing
|
|
27
|
+
* any conflict column are skipped (they can only INSERT, never hit a conflict).
|
|
28
|
+
*/
|
|
29
|
+
export declare function assertTenantOwnsConflicts(db: QueryClient, tenant: TenantContext | undefined, tableName: string, conflictCols: string[], records: Record<string, unknown>[]): Promise<void>;
|
|
30
|
+
/**
|
|
31
|
+
* For an UPDATE on an indirect-tenant table: the record's ownership is verified against its
|
|
32
|
+
* CURRENT through-FK (`assertTenantOwnership`), but if the payload also changes that FK
|
|
33
|
+
* (`through.localField`), the NEW value must be re-validated — otherwise a caller could move
|
|
34
|
+
* their own record into another tenant's scope. Validates the new FK value against the tenant,
|
|
35
|
+
* throwing 403 on mismatch. No-op for direct/no-tenant or when the FK is not being changed.
|
|
36
|
+
*
|
|
37
|
+
* `updateFields` keys are DB column names (snake_case), matching `through.localField`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function enforceTenantFKOnUpdate(db: QueryClient, tenant: TenantContext | undefined, updateFields: Record<string, unknown>): Promise<void>;
|
|
18
40
|
/**
|
|
19
41
|
* Mutates `fields` in-place: removes the tenant column from a SET payload (direct scopes only).
|
|
20
42
|
* No-op for indirect or no scope.
|
|
@@ -32,13 +54,13 @@ export declare function enforceTenantOnWrites(db: QueryClient, tenant: TenantCon
|
|
|
32
54
|
* Returns undefined for indirect or no-tenant scenarios — those are handled separately
|
|
33
55
|
* (indirect uses pre-check via `assertTenantOwnership`).
|
|
34
56
|
*/
|
|
35
|
-
export declare function buildTenantUpdateExtra(tenant: TenantContext | undefined): ConditionBuilder | undefined;
|
|
57
|
+
export declare function buildTenantUpdateExtra(db: QueryClient, tenant: TenantContext | undefined): ConditionBuilder | undefined;
|
|
36
58
|
/**
|
|
37
59
|
* For update with indirect tenant: pre-check ownership via `SELECT 1 ... INNER JOIN ... LIMIT 1`.
|
|
38
60
|
* Throws 404 if the record either does not exist or does not belong to the tenant.
|
|
39
61
|
* No-op for direct or no-tenant — those are enforced via `extraCondition` in the UPDATE itself.
|
|
40
62
|
*/
|
|
41
|
-
export declare function assertTenantOwnership(db: QueryClient, tenant: TenantContext | undefined, tableName: string, pkCol: string, pkValue: ConditionValue): Promise<void>;
|
|
63
|
+
export declare function assertTenantOwnership(db: QueryClient, tenant: TenantContext | undefined, tableName: string, pkCol: string | string[], pkValue: ConditionValue | ConditionValue[]): Promise<void>;
|
|
42
64
|
/**
|
|
43
65
|
* Assert that EVERY pk in `ids` exists and belongs to the tenant, for both direct and indirect
|
|
44
66
|
* scopes. Throws 404 if any id is missing or not owned. No-op when `tenant` is undefined or `ids`
|
package/dist/lib/tenant.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/lib/tenant.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAC3C,OAAO,EAAE,gBAAgB,EAAE,KAAK,cAAc,EAAE,KAAK,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;AAE/G,OAAO,KAAK,EACV,MAAM,EACN,mBAAmB,EACnB,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,aAAa,EACd,MAAM,aAAa,CAAC;AAMrB,wBAAsB,aAAa,CACjC,OAAO,EAAE,mBAAmB,EAC5B,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CASpC;AAED,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,QAAQ,EAAE,GACpB,gBAAgB,CAclB;AAED,wBAAgB,eAAe,CAC7B,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,mBAAmB,EAC1B,aAAa,EAAE,MAAM,GACpB,MAAM,CAMR;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,WAAW,EAClB,SAAS,EAAE,QAAQ,EAAE,GACpB,IAAI,CAiBN;AAED,wBAAsB,gBAAgB,CACpC,EAAE,EAAE,WAAW,EACf,KAAK,EAAE,mBAAmB,EAC1B,SAAS,EAAE,QAAQ,EAAE,EACrB,QAAQ,EAAE,OAAO,EAAE,GAClB,OAAO,CAAC,IAAI,CAAC,CAyBf;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CACpC,EAAE,EAAE,WAAW,EACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,yBAAyB,GAAG,cAAc,EAAE,EACrD,MAAM,EAAE,aAAa,GACpB;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,EAAE,CAAA;CAAE,CAsBtC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,KAAK,EAAE,WAAW,GACjB,IAAI,CAGN;AAED;;;;;GAKG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,WAAW,EACf,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC,CAQf;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,aAAa,GAAG,SAAS,GAChC,gBAAgB,GAAG,SAAS,CAM9B;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,EAAE,EAAE,WAAW,EACf,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../../src/lib/tenant.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/tenant.js
CHANGED
|
Binary file
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk-delete.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/bulk-delete.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"bulk-delete.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/bulk-delete.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,gBAAgB,CAC5C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAkBf"}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { BulkDeleteTableBody, BulkDeleteTableResponse } from '../../lib/schema/bulk-delete.js';
|
|
2
2
|
import { primaryAsString } from '../../types.js';
|
|
3
3
|
import { registerForAllTables } from './route-helpers.js';
|
|
4
|
+
import { DEFAULT_MAX_BULK_ITEMS } from '../../types.js';
|
|
4
5
|
export default async function bulkDeleteRoutes(fastify, options) {
|
|
5
6
|
await registerForAllTables(fastify, options, {
|
|
7
|
+
operation: 'bulkDelete',
|
|
6
8
|
method: 'POST',
|
|
7
9
|
url: (tc) => `/bulk/${tc.Schema.tableName}/delete`,
|
|
8
10
|
successStatus: 200,
|
|
9
11
|
schemas: (db, table) => ({
|
|
10
|
-
body: BulkDeleteTableBody(db, table),
|
|
12
|
+
body: BulkDeleteTableBody(db, table, options.maxBulkItems ?? DEFAULT_MAX_BULK_ITEMS),
|
|
11
13
|
response: BulkDeleteTableResponse(db, table),
|
|
12
14
|
}),
|
|
13
15
|
summary: 'Bulk delete',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bulk-upsert.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/bulk-upsert.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"bulk-upsert.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/bulk-upsert.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/C,OAAO,KAAK,EAAE,mBAAmB,EAAkB,MAAM,gBAAgB,CAAC;AAE1E,wBAA8B,gBAAgB,CAC5C,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { BulkUpsertTableBody, BulkUpsertTableResponse } from '../../lib/schema/bulk-upsert.js';
|
|
2
2
|
import { registerForAllTables, buildWriteDescription } from './route-helpers.js';
|
|
3
|
+
import { DEFAULT_MAX_BULK_ITEMS } from '../../types.js';
|
|
3
4
|
export default async function bulkUpsertRoutes(fastify, options) {
|
|
4
5
|
await registerForAllTables(fastify, options, {
|
|
6
|
+
operation: 'bulkUpsert',
|
|
5
7
|
method: 'PUT',
|
|
6
8
|
url: (tc) => `/bulk/${tc.Schema.tableName}`,
|
|
7
9
|
successStatus: 200,
|
|
8
10
|
schemas: (db, table) => ({
|
|
9
|
-
body: BulkUpsertTableBody(db, table),
|
|
11
|
+
body: BulkUpsertTableBody(db, table, options.maxBulkItems ?? DEFAULT_MAX_BULK_ITEMS),
|
|
10
12
|
response: BulkUpsertTableResponse(db, table),
|
|
11
13
|
}),
|
|
12
14
|
summary: 'Bulk upsert',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delete.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/delete.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/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":"delete.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/delete.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/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,CAoBf"}
|
|
@@ -3,6 +3,7 @@ import { primaryAsString } from '../../types.js';
|
|
|
3
3
|
import { registerForAllTables } from './route-helpers.js';
|
|
4
4
|
export default async function deleteRoutes(fastify, options) {
|
|
5
5
|
await registerForAllTables(fastify, options, {
|
|
6
|
+
operation: 'delete',
|
|
6
7
|
method: 'DELETE',
|
|
7
8
|
url: (tc) => `/rest/${tc.Schema.tableName}/:id`,
|
|
8
9
|
successStatus: 200,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/get.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,SAAS,CACrC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"get.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/get.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,SAAS,CACrC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAiBf"}
|
|
@@ -2,6 +2,7 @@ import { Type } from '@sinclair/typebox';
|
|
|
2
2
|
import { registerForAllTables } from './route-helpers.js';
|
|
3
3
|
export default async function getRoutes(fastify, options) {
|
|
4
4
|
await registerForAllTables(fastify, options, {
|
|
5
|
+
operation: 'get',
|
|
5
6
|
method: 'GET',
|
|
6
7
|
url: (tc) => `/rest/${tc.Schema.tableName}/:id`,
|
|
7
8
|
successStatus: 200,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insert.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/insert.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":"insert.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/insert.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,CAuBf"}
|
|
@@ -2,6 +2,7 @@ import { InsertTableBody, InsertTableResponse } from '../../lib/schema/insert.js
|
|
|
2
2
|
import { registerForAllTables, buildWriteDescription } from './route-helpers.js';
|
|
3
3
|
export default async function insertRoutes(fastify, options) {
|
|
4
4
|
await registerForAllTables(fastify, options, {
|
|
5
|
+
operation: 'insert',
|
|
5
6
|
method: 'POST',
|
|
6
7
|
url: (tc) => `/rest/${tc.Schema.tableName}`,
|
|
7
8
|
successStatus: 201,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FastifyInstance, FastifyRequest, FastifyReply } from 'fastify';
|
|
2
|
-
import type { ITable, SqlApiPluginOptions, DbTables } from '../../types.js';
|
|
2
|
+
import type { ITable, SqlApiPluginOptions, DbTables, TableOperation } from '../../types.js';
|
|
3
3
|
type RequestHook = (request: FastifyRequest, reply: FastifyReply) => Promise<void | FastifyReply>;
|
|
4
4
|
export declare function mergeOnRequests(options: SqlApiPluginOptions, tableConf: ITable): RequestHook[];
|
|
5
5
|
export declare function buildWriteDescription(action: string, tableName: string, tableConf: ITable): string;
|
|
@@ -10,6 +10,8 @@ interface RouteSchema {
|
|
|
10
10
|
response?: any;
|
|
11
11
|
}
|
|
12
12
|
export interface AutoRouteSpec {
|
|
13
|
+
/** Operation key matched against `ITable.operations` to decide whether to register the route. */
|
|
14
|
+
operation: TableOperation;
|
|
13
15
|
method: 'GET' | 'POST' | 'PUT' | 'DELETE';
|
|
14
16
|
/** URL builder receiving the table configuration to read `Schema.tableName`. */
|
|
15
17
|
url: (tableConf: ITable) => string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/route-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/route-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAE5F,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;AAElG,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAE9F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAQlG;AAED,UAAU,WAAW;IAEnB,IAAI,CAAC,EAAE,GAAG,CAAC;IAEX,MAAM,CAAC,EAAE,GAAG,CAAC;IAEb,WAAW,CAAC,EAAE,GAAG,CAAC;IAElB,QAAQ,CAAC,EAAE,GAAG,CAAC;CAChB;AAED,MAAM,WAAW,aAAa;IAC5B,iGAAiG;IACjG,SAAS,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;IAC1C,gFAAgF;IAChF,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,CAAC;IACnC,aAAa,EAAE,GAAG,GAAG,GAAG,CAAC;IACzB,wIAAwI;IACxI,OAAO,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,WAAW,CAAC;IACnF,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,KAAK,MAAM,CAAC;IACpF;2EACuE;IACvE,MAAM,EAAE,CACN,OAAO,EAAE,eAAe,EACxB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,YAAY,KAChB,OAAO,CAAC,OAAO,CAAC,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,EAC5B,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC,IAAI,CAAC,CAiCf"}
|
|
@@ -18,6 +18,9 @@ export function buildWriteDescription(action, tableName, tableConf) {
|
|
|
18
18
|
export async function registerForAllTables(fastify, options, spec) {
|
|
19
19
|
const { DbTables } = options;
|
|
20
20
|
for (const [tableName, tableConf] of Object.entries(DbTables)) {
|
|
21
|
+
// operations acts as a whitelist; when omitted every operation is exposed.
|
|
22
|
+
if (tableConf.operations && !tableConf.operations.includes(spec.operation))
|
|
23
|
+
continue;
|
|
21
24
|
const schemas = spec.schemas(DbTables, tableName, tableConf);
|
|
22
25
|
// Only include schema keys that are actually defined: Fastify checks for key
|
|
23
26
|
// *presence* (not undefined value) to decide whether to emit FSTWRN001.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/search.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"search.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/search.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK/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,CAyDf"}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
import { SearchTableBodyPost, SearchTableQueryString, SearchTableResponse } from '../../lib/schema/search.js';
|
|
2
2
|
import { registerForAllTables } from './route-helpers.js';
|
|
3
|
+
import { httpError } from '../../lib/errors.js';
|
|
4
|
+
import { DEFAULT_MAX_ITEMS_PER_PAGE } from '../../types.js';
|
|
3
5
|
export default async function searchRoutes(fastify, options) {
|
|
4
6
|
await registerForAllTables(fastify, options, {
|
|
7
|
+
operation: 'search',
|
|
5
8
|
method: 'POST',
|
|
6
9
|
url: (tc) => `/search/${tc.Schema.tableName}`,
|
|
7
10
|
successStatus: 200,
|
|
@@ -27,6 +30,11 @@ export default async function searchRoutes(fastify, options) {
|
|
|
27
30
|
const body = request.body;
|
|
28
31
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
29
32
|
const query = request.query;
|
|
33
|
+
// DoS guard: bound the page size and the no-paginator LIMIT.
|
|
34
|
+
const maxRows = options.maxItemsPerPage ?? DEFAULT_MAX_ITEMS_PER_PAGE;
|
|
35
|
+
if (query.itemsPerPage != null && query.itemsPerPage > maxRows) {
|
|
36
|
+
throw httpError(400, `itemsPerPage exceeds the maximum of ${maxRows}`);
|
|
37
|
+
}
|
|
30
38
|
const result = await fastify.sqlApi.search(tableName, {
|
|
31
39
|
filters: body.filters,
|
|
32
40
|
conditions: body.conditions,
|
|
@@ -43,6 +51,7 @@ export default async function searchRoutes(fastify, options) {
|
|
|
43
51
|
computeMax: query.computeMax,
|
|
44
52
|
computeSum: query.computeSum,
|
|
45
53
|
computeAvg: query.computeAvg,
|
|
54
|
+
maxRows,
|
|
46
55
|
}, request);
|
|
47
56
|
return { table: tc.Schema.tableName, ...result };
|
|
48
57
|
},
|
|
@@ -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,CAyBf"}
|
|
@@ -2,6 +2,7 @@ import { UpdateTableBody, UpdateTableResponse } from '../../lib/schema/update.js
|
|
|
2
2
|
import { registerForAllTables, buildWriteDescription } from './route-helpers.js';
|
|
3
3
|
export default async function updateRoutes(fastify, options) {
|
|
4
4
|
await registerForAllTables(fastify, options, {
|
|
5
|
+
operation: 'update',
|
|
5
6
|
method: 'PUT',
|
|
6
7
|
url: (tc) => `/rest/${tc.Schema.tableName}`,
|
|
7
8
|
successStatus: 200,
|
package/dist/types/cli.d.ts
CHANGED
|
@@ -11,12 +11,18 @@ export interface ColumnInfo {
|
|
|
11
11
|
udt_name: string;
|
|
12
12
|
column_default: string | null;
|
|
13
13
|
is_nullable: string;
|
|
14
|
+
/** True when the column is part of the table's PRIMARY KEY (from information_schema). */
|
|
15
|
+
is_primary?: boolean;
|
|
16
|
+
/** True for auto-generated columns without a visible default (mysql AUTO_INCREMENT). */
|
|
17
|
+
is_auto_increment?: boolean;
|
|
14
18
|
}
|
|
15
19
|
export interface TableMap {
|
|
16
20
|
[schemaName: string]: {
|
|
17
21
|
name: string;
|
|
18
22
|
fields: Record<string, string>;
|
|
19
23
|
colMap: Record<string, string>;
|
|
24
|
+
/** PRIMARY KEY fields (camelCase), in table column order. Empty when unknown. */
|
|
25
|
+
primary: string[];
|
|
20
26
|
};
|
|
21
27
|
}
|
|
22
28
|
//# sourceMappingURL=cli.d.ts.map
|
package/dist/types/cli.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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;IACpB,yFAAyF;IACzF,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,wFAAwF;IACxF,iBAAiB,CAAC,EAAE,OAAO,CAAC;CAC7B;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;QAC/B,iFAAiF;QACjF,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,CAAC;CACH"}
|
package/dist/types/db.d.ts
CHANGED
|
@@ -4,8 +4,19 @@ export interface SqlResult<T = Record<string, unknown>> {
|
|
|
4
4
|
affectedRows: number;
|
|
5
5
|
insertId?: number;
|
|
6
6
|
}
|
|
7
|
+
/** A dedicated connection checked out from a pool, used to run a transaction. */
|
|
8
|
+
export interface TransactionQueryable extends Queryable {
|
|
9
|
+
/** Return the connection to the pool. Always called, even on error. */
|
|
10
|
+
release(): void | Promise<void>;
|
|
11
|
+
}
|
|
7
12
|
export interface Queryable {
|
|
8
13
|
query<T = Record<string, unknown>>(text: string, values?: unknown[]): Promise<SqlResult<T>>;
|
|
14
|
+
/**
|
|
15
|
+
* Optional: check out a dedicated connection for `QueryClient.withTransaction`.
|
|
16
|
+
* When absent, `withTransaction` degrades to running its callback without
|
|
17
|
+
* transactional guarantees (legacy custom adapters keep working unchanged).
|
|
18
|
+
*/
|
|
19
|
+
connect?(): Promise<TransactionQueryable>;
|
|
9
20
|
}
|
|
10
21
|
export type DbRecordValue = string | number | boolean | null | Expression;
|
|
11
22
|
export type DbRecord = Record<string, DbRecordValue>;
|
package/dist/types/db.d.ts.map
CHANGED
|
@@ -1 +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;
|
|
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,iFAAiF;AACjF,MAAM,WAAW,oBAAqB,SAAQ,SAAS;IACrD,uEAAuE;IACvE,OAAO,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjC;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;IACzB;;;;OAIG;IACH,OAAO,CAAC,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;CAC3C;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/plugin.d.ts
CHANGED
|
@@ -16,5 +16,21 @@ export interface SqlApiPluginOptions {
|
|
|
16
16
|
dialect?: DialectName;
|
|
17
17
|
getTenantId?: (request: FastifyRequest) => TenantId | TenantId[] | null | undefined | Promise<TenantId | TenantId[] | null | undefined>;
|
|
18
18
|
debug?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Hard cap on the search page size (the `itemsPerPage` query param), and the row LIMIT applied
|
|
21
|
+
* even when no paginator is supplied — so an unbounded `POST /search/:table` cannot dump an
|
|
22
|
+
* entire table. Requests exceeding it get a 400. Defaults to {@link DEFAULT_MAX_ITEMS_PER_PAGE}.
|
|
23
|
+
*/
|
|
24
|
+
maxItemsPerPage?: number;
|
|
25
|
+
/**
|
|
26
|
+
* Hard cap on the number of items accepted by the bulk endpoints (`PUT /bulk/:table`,
|
|
27
|
+
* `POST /bulk/:table/delete`). Larger arrays are rejected at schema validation (400).
|
|
28
|
+
* Defaults to {@link DEFAULT_MAX_BULK_ITEMS}.
|
|
29
|
+
*/
|
|
30
|
+
maxBulkItems?: number;
|
|
19
31
|
}
|
|
32
|
+
/** Default row cap for search (page size and no-paginator LIMIT). Override via `maxItemsPerPage`. */
|
|
33
|
+
export declare const DEFAULT_MAX_ITEMS_PER_PAGE = 1000;
|
|
34
|
+
/** Default cap on bulk endpoint array length. Override via `maxBulkItems`. */
|
|
35
|
+
export declare const DEFAULT_MAX_BULK_ITEMS = 1000;
|
|
20
36
|
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -1 +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;
|
|
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;IAChB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qGAAqG;AACrG,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAE/C,8EAA8E;AAC9E,eAAO,MAAM,sBAAsB,OAAO,CAAC"}
|
package/dist/types/plugin.js
CHANGED
|
@@ -1 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
/** Default row cap for search (page size and no-paginator LIMIT). Override via `maxItemsPerPage`. */
|
|
2
|
+
export const DEFAULT_MAX_ITEMS_PER_PAGE = 1000;
|
|
3
|
+
/** Default cap on bulk endpoint array length. Override via `maxBulkItems`. */
|
|
4
|
+
export const DEFAULT_MAX_BULK_ITEMS = 1000;
|
package/dist/types/schema.d.ts
CHANGED
|
@@ -6,5 +6,7 @@ export interface SchemaDefinition<T = Record<string, TSchema>> {
|
|
|
6
6
|
validation: TObject;
|
|
7
7
|
tableName: string;
|
|
8
8
|
partialValidation: TObject;
|
|
9
|
+
/** PRIMARY KEY fields (camelCase) as introspected from the DB. Set by generated schemas. */
|
|
10
|
+
primaryKey?: string[];
|
|
9
11
|
}
|
|
10
12
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +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;
|
|
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;IAC3B,4FAA4F;IAC5F,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB"}
|
package/dist/types/search.d.ts
CHANGED
|
@@ -28,6 +28,13 @@ export interface SearchParams {
|
|
|
28
28
|
*/
|
|
29
29
|
selectComputed?: string[];
|
|
30
30
|
tenant?: TenantContext;
|
|
31
|
+
/**
|
|
32
|
+
* Row cap applied to the main query when no `paginator` is supplied, bounding an otherwise
|
|
33
|
+
* unbounded "fetch everything" search. Ignored when a paginator is present (the page size
|
|
34
|
+
* governs the LIMIT). Left undefined by programmatic callers (trusted); the HTTP search route
|
|
35
|
+
* sets it from `maxItemsPerPage`.
|
|
36
|
+
*/
|
|
37
|
+
maxRows?: number;
|
|
31
38
|
}
|
|
32
39
|
export interface PaginationResult {
|
|
33
40
|
total: number;
|
|
@@ -1 +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;
|
|
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;IACvB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;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"}
|
package/dist/types/table.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Expression, ConditionBuilder, ConditionValueOrUndefined } from 'node-condition-builder';
|
|
1
|
+
import type { Expression, ConditionBuilder, ConditionValueOrUndefined, DialectName as CbDialect } from 'node-condition-builder';
|
|
2
2
|
import type { TSchema, Static } from '@sinclair/typebox';
|
|
3
3
|
import type { FastifyRequest, FastifyReply } from 'fastify';
|
|
4
4
|
import type { QueryClient } from '../lib/db.js';
|
|
@@ -7,9 +7,17 @@ import type { ComputedFieldFn } from './computed.js';
|
|
|
7
7
|
import type { JoinDefinition } from './join.js';
|
|
8
8
|
import type { TenantScope } from './tenant.js';
|
|
9
9
|
import type { ValidatorFn, BulkValidatorFn } from './validation.js';
|
|
10
|
+
/** Auto-generated HTTP operations that can be enabled per table via `ITable.operations`. */
|
|
11
|
+
export type TableOperation = 'search' | 'get' | 'insert' | 'update' | 'delete' | 'bulkUpsert' | 'bulkDelete';
|
|
10
12
|
export type FilterRecord = Record<string, ConditionValueOrUndefined>;
|
|
11
13
|
export type ExtendedConditionFn = (condition: ConditionBuilder, filters: FilterRecord) => void;
|
|
12
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Builds the WHERE ConditionBuilder for a table from filter values. The optional
|
|
16
|
+
* `dialect` selects identifier quoting and builder behavior per call (the engines pass
|
|
17
|
+
* the dialect of the QueryClient that runs the query); when omitted, the global
|
|
18
|
+
* `ConditionBuilder.DIALECT` is used.
|
|
19
|
+
*/
|
|
20
|
+
export type TableFilterFn = (filters: FilterRecord, dialect?: CbDialect) => ConditionBuilder;
|
|
13
21
|
export interface ITable<F extends Record<string, TSchema> = Record<string, TSchema>> {
|
|
14
22
|
primary: (string & keyof F) | (string & keyof F)[];
|
|
15
23
|
Schema: SchemaDefinition<F>;
|
|
@@ -40,6 +48,15 @@ export interface ITable<F extends Record<string, TSchema> = Record<string, TSche
|
|
|
40
48
|
afterInsert?: (db: QueryClient, req: FastifyRequest, record: {
|
|
41
49
|
[K in keyof F]?: Static<F[K]>;
|
|
42
50
|
}, secondaryRecords?: unknown) => Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Runs after a successful update, inside the same transaction as the UPDATE +
|
|
53
|
+
* secondaries + deletions: throwing here rolls back the whole operation (when the
|
|
54
|
+
* adapter supports transactions). Receives the camelCase input record (including the
|
|
55
|
+
* PK) plus the secondaries/deletions results, mirroring `afterInsert`.
|
|
56
|
+
*/
|
|
57
|
+
afterUpdate?: (db: QueryClient, req: FastifyRequest, record: {
|
|
58
|
+
[K in keyof F]?: Static<F[K]> | Expression | null;
|
|
59
|
+
}, secondaryRecords?: unknown, deletionRecords?: unknown) => void | Promise<void>;
|
|
43
60
|
/**
|
|
44
61
|
* Runs before a single record is deleted (DELETE /rest/:id). Throw to abort the
|
|
45
62
|
* deletion (the thrown error's `statusCode`/`message` are surfaced to the client).
|
|
@@ -54,6 +71,11 @@ export interface ITable<F extends Record<string, TSchema> = Record<string, TSche
|
|
|
54
71
|
* case any hook that reads request context (e.g. `req.user`) must guard for it.
|
|
55
72
|
*/
|
|
56
73
|
beforeDelete?: (db: QueryClient, req: FastifyRequest, id: string | number) => void | Promise<void>;
|
|
74
|
+
/**
|
|
75
|
+
* Runs after a single record has been deleted (DELETE /rest/:id). Not called when the
|
|
76
|
+
* record was not found (404). Same `req` caveat as `beforeDelete`.
|
|
77
|
+
*/
|
|
78
|
+
afterDelete?: (db: QueryClient, req: FastifyRequest, id: string | number) => void | Promise<void>;
|
|
57
79
|
/**
|
|
58
80
|
* Bulk counterpart of `beforeDelete`, invoked ONCE with all ids before a bulk delete
|
|
59
81
|
* (POST /bulk/:table/delete). Called once — not per id — to preserve the single-query
|
|
@@ -64,6 +86,22 @@ export interface ITable<F extends Record<string, TSchema> = Record<string, TSche
|
|
|
64
86
|
* `sqlApi.bulkDelete(table, ids)` is called programmatically without a request.
|
|
65
87
|
*/
|
|
66
88
|
beforeBulkDelete?: (db: QueryClient, req: FastifyRequest, ids: (string | number)[]) => void | Promise<void>;
|
|
89
|
+
/**
|
|
90
|
+
* Bulk counterpart of `afterDelete`, invoked ONCE after a bulk delete with the ids that
|
|
91
|
+
* were ACTUALLY deleted (which may be a subset of the requested ids). Not called when
|
|
92
|
+
* nothing was deleted. Same `req` caveat as `beforeBulkDelete`.
|
|
93
|
+
*/
|
|
94
|
+
afterBulkDelete?: (db: QueryClient, req: FastifyRequest, deletedIds: (string | number)[]) => void | Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* Whitelist of auto-generated HTTP routes for this table. When omitted, ALL operations
|
|
97
|
+
* are exposed (search, get, insert, update, delete, bulkUpsert, bulkDelete) — the
|
|
98
|
+
* default is intentionally open, see the Security section in the README. Listing only
|
|
99
|
+
* some operations skips registering the others entirely (they answer 404).
|
|
100
|
+
*
|
|
101
|
+
* Note: this gates the HTTP routes only; the programmatic `sqlApi.*` methods are not
|
|
102
|
+
* affected.
|
|
103
|
+
*/
|
|
104
|
+
operations?: TableOperation[];
|
|
67
105
|
defaultOrder?: string;
|
|
68
106
|
excludeFromCreation?: (string & keyof F)[];
|
|
69
107
|
distinctResults?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/types/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,yBAAyB,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../src/types/table.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fastify-auto-sqlapi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Fastify plugin for automatic CRUD API generation from PostgreSQL, MySQL and MariaDB tables",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
"@fastify/postgres": ">=5.0.0",
|
|
83
83
|
"@fastify/swagger": ">=9.0.0",
|
|
84
84
|
"@fastify/swagger-ui": ">=5.0.0",
|
|
85
|
-
"fastify": "5.
|
|
85
|
+
"fastify": ">=5.0.0",
|
|
86
86
|
"mysql2": ">=3.0.0",
|
|
87
87
|
"pg": ">=8.0.0"
|
|
88
88
|
},
|