@forgebase/database 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +470 -0
- package/dist/cjs/adapters/base.d.ts +20 -0
- package/dist/cjs/adapters/base.d.ts.map +1 -0
- package/dist/cjs/adapters/base.js +13 -0
- package/dist/cjs/adapters/base.js.map +1 -0
- package/dist/cjs/adapters/index.d.ts +6 -0
- package/dist/cjs/adapters/index.d.ts.map +1 -0
- package/dist/cjs/adapters/index.js +24 -0
- package/dist/cjs/adapters/index.js.map +1 -0
- package/dist/cjs/adapters/postgres.d.ts +13 -0
- package/dist/cjs/adapters/postgres.d.ts.map +1 -0
- package/dist/cjs/adapters/postgres.js +51 -0
- package/dist/cjs/adapters/postgres.js.map +1 -0
- package/dist/cjs/adapters/sqlite.d.ts +13 -0
- package/dist/cjs/adapters/sqlite.d.ts.map +1 -0
- package/dist/cjs/adapters/sqlite.js +47 -0
- package/dist/cjs/adapters/sqlite.js.map +1 -0
- package/dist/cjs/adapters/types.d.ts +8 -0
- package/dist/cjs/adapters/types.d.ts.map +1 -0
- package/dist/cjs/adapters/types.js +3 -0
- package/dist/cjs/adapters/types.js.map +1 -0
- package/dist/cjs/database.d.ts +73 -0
- package/dist/cjs/database.d.ts.map +1 -0
- package/dist/cjs/database.js +673 -0
- package/dist/cjs/database.js.map +1 -0
- package/dist/cjs/errors.d.ts +37 -0
- package/dist/cjs/errors.d.ts.map +1 -0
- package/dist/cjs/errors.js +64 -0
- package/dist/cjs/errors.js.map +1 -0
- package/dist/cjs/index.d.ts +16 -0
- package/dist/cjs/index.d.ts.map +1 -0
- package/dist/cjs/index.js +31 -0
- package/dist/cjs/index.js.map +1 -0
- package/dist/cjs/kysely-hooks.d.ts +45 -0
- package/dist/cjs/kysely-hooks.d.ts.map +1 -0
- package/dist/cjs/kysely-hooks.js +93 -0
- package/dist/cjs/kysely-hooks.js.map +1 -0
- package/dist/cjs/libsql/example.d.ts +2 -0
- package/dist/cjs/libsql/example.d.ts.map +1 -0
- package/dist/cjs/libsql/example.js +44 -0
- package/dist/cjs/libsql/example.js.map +1 -0
- package/dist/cjs/libsql/index.d.ts +36 -0
- package/dist/cjs/libsql/index.d.ts.map +1 -0
- package/dist/cjs/libsql/index.js +155 -0
- package/dist/cjs/libsql/index.js.map +1 -0
- package/dist/cjs/permissionService.d.ts +20 -0
- package/dist/cjs/permissionService.d.ts.map +1 -0
- package/dist/cjs/permissionService.js +107 -0
- package/dist/cjs/permissionService.js.map +1 -0
- package/dist/cjs/rlsFunctionRegistry.d.ts +43 -0
- package/dist/cjs/rlsFunctionRegistry.d.ts.map +1 -0
- package/dist/cjs/rlsFunctionRegistry.js +63 -0
- package/dist/cjs/rlsFunctionRegistry.js.map +1 -0
- package/dist/cjs/rlsManager.d.ts +23 -0
- package/dist/cjs/rlsManager.d.ts.map +1 -0
- package/dist/cjs/rlsManager.js +371 -0
- package/dist/cjs/rlsManager.js.map +1 -0
- package/dist/cjs/schema.d.ts +15 -0
- package/dist/cjs/schema.d.ts.map +1 -0
- package/dist/cjs/schema.js +119 -0
- package/dist/cjs/schema.js.map +1 -0
- package/dist/cjs/sdk/client.d.ts +324 -0
- package/dist/cjs/sdk/client.d.ts.map +1 -0
- package/dist/cjs/sdk/client.js +554 -0
- package/dist/cjs/sdk/client.js.map +1 -0
- package/dist/cjs/sdk/examples.d.ts +68 -0
- package/dist/cjs/sdk/examples.d.ts.map +1 -0
- package/dist/cjs/sdk/examples.js +232 -0
- package/dist/cjs/sdk/examples.js.map +1 -0
- package/dist/cjs/sdk/server.d.ts +115 -0
- package/dist/cjs/sdk/server.d.ts.map +1 -0
- package/dist/cjs/sdk/server.js +140 -0
- package/dist/cjs/sdk/server.js.map +1 -0
- package/dist/cjs/types.d.ts +217 -0
- package/dist/cjs/types.d.ts.map +1 -0
- package/dist/cjs/types.js +5 -0
- package/dist/cjs/types.js.map +1 -0
- package/dist/cjs/utils/column-utils.d.ts +8 -0
- package/dist/cjs/utils/column-utils.d.ts.map +1 -0
- package/dist/cjs/utils/column-utils.js +131 -0
- package/dist/cjs/utils/column-utils.js.map +1 -0
- package/dist/cjs/utils/db.d.ts +2 -0
- package/dist/cjs/utils/db.d.ts.map +1 -0
- package/dist/cjs/utils/db.js +6 -0
- package/dist/cjs/utils/db.js.map +1 -0
- package/dist/cjs/utils/inspector.d.ts +39 -0
- package/dist/cjs/utils/inspector.d.ts.map +1 -0
- package/dist/cjs/utils/inspector.js +164 -0
- package/dist/cjs/utils/inspector.js.map +1 -0
- package/dist/cjs/utils/permission-initializer.d.ts +15 -0
- package/dist/cjs/utils/permission-initializer.d.ts.map +1 -0
- package/dist/cjs/utils/permission-initializer.js +173 -0
- package/dist/cjs/utils/permission-initializer.js.map +1 -0
- package/dist/cjs/websocket/RealtimeAdapter.d.ts +22 -0
- package/dist/cjs/websocket/RealtimeAdapter.d.ts.map +1 -0
- package/dist/cjs/websocket/RealtimeAdapter.js +3 -0
- package/dist/cjs/websocket/RealtimeAdapter.js.map +1 -0
- package/dist/cjs/websocket/SSEManager.d.ts +40 -0
- package/dist/cjs/websocket/SSEManager.d.ts.map +1 -0
- package/dist/cjs/websocket/SSEManager.js +268 -0
- package/dist/cjs/websocket/SSEManager.js.map +1 -0
- package/dist/cjs/websocket/WebSocketManager.d.ts +28 -0
- package/dist/cjs/websocket/WebSocketManager.d.ts.map +1 -0
- package/dist/cjs/websocket/WebSocketManager.js +156 -0
- package/dist/cjs/websocket/WebSocketManager.js.map +1 -0
- package/dist/cjs/websocket/index.d.ts +4 -0
- package/dist/cjs/websocket/index.d.ts.map +1 -0
- package/dist/cjs/websocket/index.js +20 -0
- package/dist/cjs/websocket/index.js.map +1 -0
- package/dist/esm/adapters/base.d.ts +20 -0
- package/dist/esm/adapters/base.d.ts.map +1 -0
- package/dist/esm/adapters/base.js +10 -0
- package/dist/esm/adapters/base.js.map +1 -0
- package/dist/esm/adapters/index.d.ts +6 -0
- package/dist/esm/adapters/index.d.ts.map +1 -0
- package/dist/esm/adapters/index.js +19 -0
- package/dist/esm/adapters/index.js.map +1 -0
- package/dist/esm/adapters/postgres.d.ts +13 -0
- package/dist/esm/adapters/postgres.d.ts.map +1 -0
- package/dist/esm/adapters/postgres.js +47 -0
- package/dist/esm/adapters/postgres.js.map +1 -0
- package/dist/esm/adapters/sqlite.d.ts +13 -0
- package/dist/esm/adapters/sqlite.d.ts.map +1 -0
- package/dist/esm/adapters/sqlite.js +43 -0
- package/dist/esm/adapters/sqlite.js.map +1 -0
- package/dist/esm/adapters/types.d.ts +8 -0
- package/dist/esm/adapters/types.d.ts.map +1 -0
- package/dist/esm/adapters/types.js +2 -0
- package/dist/esm/adapters/types.js.map +1 -0
- package/dist/esm/database.d.ts +73 -0
- package/dist/esm/database.d.ts.map +1 -0
- package/dist/esm/database.js +668 -0
- package/dist/esm/database.js.map +1 -0
- package/dist/esm/errors.d.ts +37 -0
- package/dist/esm/errors.d.ts.map +1 -0
- package/dist/esm/errors.js +55 -0
- package/dist/esm/errors.js.map +1 -0
- package/dist/esm/index.d.ts +16 -0
- package/dist/esm/index.d.ts.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/kysely-hooks.d.ts +45 -0
- package/dist/esm/kysely-hooks.d.ts.map +1 -0
- package/dist/esm/kysely-hooks.js +86 -0
- package/dist/esm/kysely-hooks.js.map +1 -0
- package/dist/esm/libsql/example.d.ts +2 -0
- package/dist/esm/libsql/example.d.ts.map +1 -0
- package/dist/esm/libsql/example.js +42 -0
- package/dist/esm/libsql/example.js.map +1 -0
- package/dist/esm/libsql/index.d.ts +36 -0
- package/dist/esm/libsql/index.d.ts.map +1 -0
- package/dist/esm/libsql/index.js +116 -0
- package/dist/esm/libsql/index.js.map +1 -0
- package/dist/esm/permissionService.d.ts +20 -0
- package/dist/esm/permissionService.d.ts.map +1 -0
- package/dist/esm/permissionService.js +103 -0
- package/dist/esm/permissionService.js.map +1 -0
- package/dist/esm/rlsFunctionRegistry.d.ts +43 -0
- package/dist/esm/rlsFunctionRegistry.d.ts.map +1 -0
- package/dist/esm/rlsFunctionRegistry.js +60 -0
- package/dist/esm/rlsFunctionRegistry.js.map +1 -0
- package/dist/esm/rlsManager.d.ts +23 -0
- package/dist/esm/rlsManager.d.ts.map +1 -0
- package/dist/esm/rlsManager.js +366 -0
- package/dist/esm/rlsManager.js.map +1 -0
- package/dist/esm/schema.d.ts +15 -0
- package/dist/esm/schema.d.ts.map +1 -0
- package/dist/esm/schema.js +113 -0
- package/dist/esm/schema.js.map +1 -0
- package/dist/esm/sdk/client.d.ts +324 -0
- package/dist/esm/sdk/client.d.ts.map +1 -0
- package/dist/esm/sdk/client.js +550 -0
- package/dist/esm/sdk/client.js.map +1 -0
- package/dist/esm/sdk/examples.d.ts +68 -0
- package/dist/esm/sdk/examples.d.ts.map +1 -0
- package/dist/esm/sdk/examples.js +229 -0
- package/dist/esm/sdk/examples.js.map +1 -0
- package/dist/esm/sdk/server.d.ts +115 -0
- package/dist/esm/sdk/server.d.ts.map +1 -0
- package/dist/esm/sdk/server.js +136 -0
- package/dist/esm/sdk/server.js.map +1 -0
- package/dist/esm/types.d.ts +217 -0
- package/dist/esm/types.d.ts.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/utils/column-utils.d.ts +8 -0
- package/dist/esm/utils/column-utils.d.ts.map +1 -0
- package/dist/esm/utils/column-utils.js +127 -0
- package/dist/esm/utils/column-utils.js.map +1 -0
- package/dist/esm/utils/db.d.ts +2 -0
- package/dist/esm/utils/db.d.ts.map +1 -0
- package/dist/esm/utils/db.js +3 -0
- package/dist/esm/utils/db.js.map +1 -0
- package/dist/esm/utils/inspector.d.ts +39 -0
- package/dist/esm/utils/inspector.d.ts.map +1 -0
- package/dist/esm/utils/inspector.js +160 -0
- package/dist/esm/utils/inspector.js.map +1 -0
- package/dist/esm/utils/permission-initializer.d.ts +15 -0
- package/dist/esm/utils/permission-initializer.d.ts.map +1 -0
- package/dist/esm/utils/permission-initializer.js +137 -0
- package/dist/esm/utils/permission-initializer.js.map +1 -0
- package/dist/esm/websocket/RealtimeAdapter.d.ts +22 -0
- package/dist/esm/websocket/RealtimeAdapter.d.ts.map +1 -0
- package/dist/esm/websocket/RealtimeAdapter.js +2 -0
- package/dist/esm/websocket/RealtimeAdapter.js.map +1 -0
- package/dist/esm/websocket/SSEManager.d.ts +40 -0
- package/dist/esm/websocket/SSEManager.d.ts.map +1 -0
- package/dist/esm/websocket/SSEManager.js +231 -0
- package/dist/esm/websocket/SSEManager.js.map +1 -0
- package/dist/esm/websocket/WebSocketManager.d.ts +28 -0
- package/dist/esm/websocket/WebSocketManager.d.ts.map +1 -0
- package/dist/esm/websocket/WebSocketManager.js +152 -0
- package/dist/esm/websocket/WebSocketManager.js.map +1 -0
- package/dist/esm/websocket/index.d.ts +4 -0
- package/dist/esm/websocket/index.d.ts.map +1 -0
- package/dist/esm/websocket/index.js +4 -0
- package/dist/esm/websocket/index.js.map +1 -0
- package/package.json +67 -0
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createForgeDatabase = exports.ForgeDatabase = void 0;
|
|
4
|
+
const kysely_1 = require("kysely");
|
|
5
|
+
const permissionService_1 = require("./permissionService");
|
|
6
|
+
const rlsManager_1 = require("./rlsManager");
|
|
7
|
+
const inspector_1 = require("./utils/inspector");
|
|
8
|
+
const kysely_hooks_1 = require("./kysely-hooks");
|
|
9
|
+
const errors_1 = require("./errors");
|
|
10
|
+
const types_1 = require("./types");
|
|
11
|
+
const column_utils_1 = require("./utils/column-utils");
|
|
12
|
+
const schema_1 = require("./schema");
|
|
13
|
+
const server_1 = require("./sdk/server");
|
|
14
|
+
const WebSocketManager_1 = require("./websocket/WebSocketManager");
|
|
15
|
+
const SSEManager_1 = require("./websocket/SSEManager");
|
|
16
|
+
const permission_initializer_1 = require("./utils/permission-initializer");
|
|
17
|
+
const libsql_1 = require("./libsql");
|
|
18
|
+
class ForgeDatabase {
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
this.config = config;
|
|
21
|
+
this.defaultPermissions = {
|
|
22
|
+
operations: {
|
|
23
|
+
SELECT: [
|
|
24
|
+
{
|
|
25
|
+
allow: 'private',
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
INSERT: [
|
|
29
|
+
{
|
|
30
|
+
allow: 'private',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
UPDATE: [
|
|
34
|
+
{
|
|
35
|
+
allow: 'private',
|
|
36
|
+
},
|
|
37
|
+
],
|
|
38
|
+
DELETE: [
|
|
39
|
+
{
|
|
40
|
+
allow: 'private',
|
|
41
|
+
},
|
|
42
|
+
],
|
|
43
|
+
},
|
|
44
|
+
};
|
|
45
|
+
this.excludedTables = [types_1.FG_PERMISSION_TABLE];
|
|
46
|
+
/**
|
|
47
|
+
* Get the endpoints for the database
|
|
48
|
+
* @returns Endpoints for the database
|
|
49
|
+
*/
|
|
50
|
+
this.endpoints = {
|
|
51
|
+
/**
|
|
52
|
+
* Work with the database schema
|
|
53
|
+
* @returns Schema endpoints
|
|
54
|
+
*/
|
|
55
|
+
schema: {
|
|
56
|
+
get: async (trx) => {
|
|
57
|
+
return await this.dbInspector.getDatabaseSchema(this.excludedTables);
|
|
58
|
+
},
|
|
59
|
+
create: async (payload, trx) => {
|
|
60
|
+
const { tableName, columns } = payload;
|
|
61
|
+
if (!tableName) {
|
|
62
|
+
throw new Error('Invalid request body');
|
|
63
|
+
}
|
|
64
|
+
// Efficiently check if table exists
|
|
65
|
+
const hasTable = await this.dbInspector.hasTable(tableName);
|
|
66
|
+
if (hasTable) {
|
|
67
|
+
console.log('Table already exists');
|
|
68
|
+
throw new Error('Table already exists');
|
|
69
|
+
}
|
|
70
|
+
// Use transaction if provided, otherwise use the db instance
|
|
71
|
+
const builder = trx || this.hooks.getDbInstance();
|
|
72
|
+
// Start creating the table
|
|
73
|
+
// Start creating the table
|
|
74
|
+
let tableBuilder = builder.schema.createTable(tableName);
|
|
75
|
+
// Add columns using strict createColumn util
|
|
76
|
+
columns.forEach((col) => {
|
|
77
|
+
tableBuilder = (0, column_utils_1.createColumn)(tableBuilder, col, this.hooks.getDbInstance());
|
|
78
|
+
});
|
|
79
|
+
await tableBuilder.execute();
|
|
80
|
+
await this.permissionService.setPermissionsForTable(tableName, this.defaultPermissions, builder);
|
|
81
|
+
return {
|
|
82
|
+
message: 'Table created successfully',
|
|
83
|
+
tablename: tableName,
|
|
84
|
+
action: 'create',
|
|
85
|
+
};
|
|
86
|
+
},
|
|
87
|
+
delete: async (tableName, trx) => {
|
|
88
|
+
if (this.excludedTables.includes(tableName)) {
|
|
89
|
+
throw new errors_1.ExcludedTableError(tableName);
|
|
90
|
+
}
|
|
91
|
+
// Use transaction if provided, otherwise use the db instance
|
|
92
|
+
const builder = trx || this.hooks.getDbInstance();
|
|
93
|
+
await builder.schema.dropTable(tableName).ifExists().execute();
|
|
94
|
+
await this.permissionService.deletePermissionsForTable(tableName, builder);
|
|
95
|
+
return {
|
|
96
|
+
message: 'Table deleted successfully',
|
|
97
|
+
tablename: tableName,
|
|
98
|
+
action: 'delete',
|
|
99
|
+
};
|
|
100
|
+
},
|
|
101
|
+
modify: async (payload, trx) => {
|
|
102
|
+
if (this.excludedTables.includes(payload.tableName)) {
|
|
103
|
+
throw new errors_1.ExcludedTableError(payload.tableName);
|
|
104
|
+
}
|
|
105
|
+
const builder = this.hooks.getDbInstance();
|
|
106
|
+
return await (0, schema_1.modifySchema)(builder, payload, trx);
|
|
107
|
+
},
|
|
108
|
+
addForeingKey: async (payload, trx) => {
|
|
109
|
+
if (this.excludedTables.includes(payload.tableName)) {
|
|
110
|
+
throw new errors_1.ExcludedTableError(payload.tableName);
|
|
111
|
+
}
|
|
112
|
+
if (this.excludedTables.includes(payload.foreignTableName)) {
|
|
113
|
+
throw new errors_1.ExcludedTableError(payload.foreignTableName);
|
|
114
|
+
}
|
|
115
|
+
return await (0, schema_1.addForeignKey)(payload, this.hooks.getDbInstance(), trx);
|
|
116
|
+
},
|
|
117
|
+
dropForeignKey: async (payload, trx) => {
|
|
118
|
+
if (this.excludedTables.includes(payload.tableName)) {
|
|
119
|
+
throw new errors_1.ExcludedTableError(payload.tableName);
|
|
120
|
+
}
|
|
121
|
+
return await (0, schema_1.dropForeignKey)(payload, this.hooks.getDbInstance(), trx);
|
|
122
|
+
},
|
|
123
|
+
truncateTable: async (tableName, trx) => {
|
|
124
|
+
if (this.excludedTables.includes(tableName)) {
|
|
125
|
+
throw new errors_1.ExcludedTableError(tableName);
|
|
126
|
+
}
|
|
127
|
+
return await (0, schema_1.truncateTable)(tableName, this.hooks.getDbInstance(), trx);
|
|
128
|
+
},
|
|
129
|
+
getTableSchema: async (tableName, trx) => {
|
|
130
|
+
if (this.excludedTables.includes(tableName)) {
|
|
131
|
+
throw new errors_1.ExcludedTableError(tableName);
|
|
132
|
+
}
|
|
133
|
+
const tableInfo = await this.dbInspector.getTableInfo(tableName);
|
|
134
|
+
return {
|
|
135
|
+
name: tableName,
|
|
136
|
+
info: tableInfo,
|
|
137
|
+
};
|
|
138
|
+
},
|
|
139
|
+
getTables: async (trx) => {
|
|
140
|
+
let tables = await this.dbInspector.getTables();
|
|
141
|
+
tables = tables.filter((t) => !this.excludedTables.includes(t));
|
|
142
|
+
return tables;
|
|
143
|
+
},
|
|
144
|
+
getTablePermissions: async (tableName, trx) => {
|
|
145
|
+
if (this.excludedTables.includes(tableName)) {
|
|
146
|
+
throw new errors_1.ExcludedTableError(tableName);
|
|
147
|
+
}
|
|
148
|
+
return await this.permissionService.getPermissionsForTable(tableName, trx);
|
|
149
|
+
},
|
|
150
|
+
getTableSchemaWithPermissions: async (tableName, trx) => {
|
|
151
|
+
if (this.excludedTables.includes(tableName)) {
|
|
152
|
+
throw new errors_1.ExcludedTableError(tableName);
|
|
153
|
+
}
|
|
154
|
+
const tableInfo = await this.dbInspector.getTableInfo(tableName);
|
|
155
|
+
const permissions = await this.permissionService.getPermissionsForTable(tableName, trx);
|
|
156
|
+
return {
|
|
157
|
+
name: tableName,
|
|
158
|
+
info: tableInfo,
|
|
159
|
+
permissions,
|
|
160
|
+
};
|
|
161
|
+
},
|
|
162
|
+
},
|
|
163
|
+
/**
|
|
164
|
+
* Work with the database data
|
|
165
|
+
* @returns Data endpoints
|
|
166
|
+
*/
|
|
167
|
+
data: {
|
|
168
|
+
query: async (tableName, params, user, isSystem = false, trx) => {
|
|
169
|
+
if (this.excludedTables.includes(tableName)) {
|
|
170
|
+
throw new errors_1.ExcludedTableError(tableName);
|
|
171
|
+
}
|
|
172
|
+
// const queryParams = this.parseQueryParams(params);
|
|
173
|
+
const queryParams = params; // KyselyQueryHandler handles params object directly
|
|
174
|
+
if (!this.config.enforceRls || isSystem) {
|
|
175
|
+
return this.hooks.query(tableName, (db) => this.queryHandler
|
|
176
|
+
.buildQuery(queryParams, db.selectFrom(tableName))
|
|
177
|
+
.execute(), queryParams, trx);
|
|
178
|
+
}
|
|
179
|
+
if (!user && !isSystem && this.config.enforceRls) {
|
|
180
|
+
throw new errors_1.AuthenticationRequiredError('Authentication required to query records');
|
|
181
|
+
}
|
|
182
|
+
const { status: initialStatus, hasFieldCheck: initialHasFieldCheck, hasCustomFunction: initialHasCustomFunction, fieldCheckRules: extractedFieldCheckRules, } = await (0, rlsManager_1.enforcePermissions)(tableName, 'SELECT', user, this.permissionService, undefined, this.hooks.getDbInstance());
|
|
183
|
+
if (!initialStatus &&
|
|
184
|
+
!initialHasFieldCheck &&
|
|
185
|
+
!initialHasCustomFunction) {
|
|
186
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to query table "${tableName}"`);
|
|
187
|
+
}
|
|
188
|
+
const records = (await this.hooks.query(tableName, (db) => this.queryHandler
|
|
189
|
+
.buildQuery(queryParams, db.selectFrom(tableName))
|
|
190
|
+
.execute(), queryParams, trx));
|
|
191
|
+
if (initialStatus) {
|
|
192
|
+
// Simple rule matched — return all records
|
|
193
|
+
return records;
|
|
194
|
+
}
|
|
195
|
+
// Fast path: filter rows using pre-extracted fieldCheck rules
|
|
196
|
+
if (extractedFieldCheckRules?.length) {
|
|
197
|
+
const filtered = [];
|
|
198
|
+
for (const record of records) {
|
|
199
|
+
const allowed = await (0, rlsManager_1.evaluateFieldCheckForRow)(extractedFieldCheckRules, user, record, this.hooks.getDbInstance());
|
|
200
|
+
if (allowed) {
|
|
201
|
+
filtered.push(record);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (filtered.length === 0) {
|
|
205
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to query table "${tableName}"`);
|
|
206
|
+
}
|
|
207
|
+
return filtered;
|
|
208
|
+
}
|
|
209
|
+
// Fallback for customFunction rules
|
|
210
|
+
const { status, row } = await (0, rlsManager_1.enforcePermissions)(tableName, 'SELECT', user, this.permissionService, records, this.hooks.getDbInstance());
|
|
211
|
+
if (!status) {
|
|
212
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to query table "${tableName}"`);
|
|
213
|
+
}
|
|
214
|
+
return row;
|
|
215
|
+
},
|
|
216
|
+
create: async (params, user, isSystem = false, trx) => {
|
|
217
|
+
if (this.excludedTables.includes(params.tableName)) {
|
|
218
|
+
throw new errors_1.ExcludedTableError(params.tableName);
|
|
219
|
+
}
|
|
220
|
+
const { data, tableName } = params;
|
|
221
|
+
// console.log('data-db', data, tableName);
|
|
222
|
+
// Handle both single record and array of records
|
|
223
|
+
const isArray = Array.isArray(data);
|
|
224
|
+
const records = isArray ? data : [data];
|
|
225
|
+
// Validate records
|
|
226
|
+
if (!records.length ||
|
|
227
|
+
!records.every((record) => typeof record === 'object' && Object.keys(record).length > 0)) {
|
|
228
|
+
console.log('Invalid request body', records);
|
|
229
|
+
throw new Error('Invalid request body');
|
|
230
|
+
}
|
|
231
|
+
if (!this.config.enforceRls || isSystem) {
|
|
232
|
+
return this.hooks.mutate(tableName, 'create', async (db) => db.insertInto(tableName).values(records).returningAll().execute(), records, undefined, trx);
|
|
233
|
+
}
|
|
234
|
+
if (!user && !isSystem && this.config.enforceRls) {
|
|
235
|
+
throw new errors_1.AuthenticationRequiredError('Authentication required to create records');
|
|
236
|
+
}
|
|
237
|
+
const { status: initialStatus, hasFieldCheck: initialHasFieldCheck, hasCustomFunction: initialHasCustomFunction, } = await (0, rlsManager_1.enforcePermissions)(tableName, 'INSERT', user, this.permissionService, undefined, this.hooks.getDbInstance());
|
|
238
|
+
if (!initialStatus &&
|
|
239
|
+
!initialHasFieldCheck &&
|
|
240
|
+
!initialHasCustomFunction) {
|
|
241
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to create record in table "${tableName}"`);
|
|
242
|
+
}
|
|
243
|
+
if (initialStatus) {
|
|
244
|
+
// If the user has permission to create, proceed with the creation
|
|
245
|
+
return this.hooks.mutate(tableName, 'create', async (db) => db.insertInto(tableName).values(records).returningAll().execute(), records, undefined, trx);
|
|
246
|
+
}
|
|
247
|
+
const { status, row } = await (0, rlsManager_1.enforcePermissions)(tableName, 'INSERT', user, this.permissionService, records, this.hooks.getDbInstance());
|
|
248
|
+
if (!status) {
|
|
249
|
+
throw new Error(`User does not have permission to create record in table "${tableName}"`);
|
|
250
|
+
}
|
|
251
|
+
if (!row || (Array.isArray(row) && row.length === 0)) {
|
|
252
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to create this record in table "${tableName}"`);
|
|
253
|
+
}
|
|
254
|
+
const result = this.hooks.mutate(tableName, 'create', async (db) => db.insertInto(tableName).values(row).returningAll().execute(), row, undefined, trx);
|
|
255
|
+
return result;
|
|
256
|
+
},
|
|
257
|
+
update: async (params, user, isSystem = false, trx) => {
|
|
258
|
+
if (this.excludedTables.includes(params.tableName)) {
|
|
259
|
+
throw new errors_1.ExcludedTableError(params.tableName);
|
|
260
|
+
}
|
|
261
|
+
const { id, tableName, data } = params;
|
|
262
|
+
if (!this.config.enforceRls || isSystem) {
|
|
263
|
+
const result = this.hooks.mutate(tableName, 'update', async (db) => db
|
|
264
|
+
.updateTable(tableName)
|
|
265
|
+
.set(data)
|
|
266
|
+
.where('id', '=', id)
|
|
267
|
+
.returningAll()
|
|
268
|
+
.execute(), { id, ...data }, undefined, trx);
|
|
269
|
+
return result;
|
|
270
|
+
}
|
|
271
|
+
if (!user && !isSystem && this.config.enforceRls) {
|
|
272
|
+
throw new errors_1.AuthenticationRequiredError('Authentication required to update records');
|
|
273
|
+
}
|
|
274
|
+
const { status: initialStatus, hasFieldCheck: initialHasFieldCheck, hasCustomFunction: initialHasCustomFunction, fieldCheckRules: extractedFieldCheckRules, } = await (0, rlsManager_1.enforcePermissions)(tableName, 'UPDATE', user, this.permissionService, undefined, this.hooks.getDbInstance());
|
|
275
|
+
if (!initialStatus &&
|
|
276
|
+
!initialHasFieldCheck &&
|
|
277
|
+
!initialHasCustomFunction) {
|
|
278
|
+
throw new Error(`User does not have permission to update record with id ${id}`);
|
|
279
|
+
}
|
|
280
|
+
if (initialStatus) {
|
|
281
|
+
// Simple rule matched — proceed directly
|
|
282
|
+
const result = this.hooks.mutate(tableName, 'update', async (db) => db
|
|
283
|
+
.updateTable(tableName)
|
|
284
|
+
.set(data)
|
|
285
|
+
.where('id', '=', id)
|
|
286
|
+
.returningAll()
|
|
287
|
+
.execute(), { id, ...data }, undefined, trx);
|
|
288
|
+
return result;
|
|
289
|
+
}
|
|
290
|
+
// fieldCheck/customFunction path — fetch the row then evaluate
|
|
291
|
+
const record = await this.hooks.query(tableName, (db) => {
|
|
292
|
+
return db
|
|
293
|
+
.selectFrom(tableName)
|
|
294
|
+
.where('id', '=', id)
|
|
295
|
+
.selectAll()
|
|
296
|
+
.execute();
|
|
297
|
+
}, { id }, trx);
|
|
298
|
+
// Fast path: use pre-extracted rules instead of full enforcePermissions
|
|
299
|
+
if (extractedFieldCheckRules?.length) {
|
|
300
|
+
const allowed = await (0, rlsManager_1.evaluateFieldCheckForRow)(extractedFieldCheckRules, user, record[0], this.hooks.getDbInstance());
|
|
301
|
+
if (!allowed) {
|
|
302
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to update record with id ${id}`);
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
else {
|
|
306
|
+
// Fallback for customFunction rules
|
|
307
|
+
const { status } = await (0, rlsManager_1.enforcePermissions)(tableName, 'UPDATE', user, this.permissionService, record[0], this.hooks.getDbInstance());
|
|
308
|
+
if (!status) {
|
|
309
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to update record with id ${id}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
const result = this.hooks.mutate(tableName, 'update', async (db) => db
|
|
313
|
+
.updateTable(tableName)
|
|
314
|
+
.set(data)
|
|
315
|
+
.where('id', '=', id)
|
|
316
|
+
.returningAll()
|
|
317
|
+
.execute(), { id, ...data }, undefined, trx);
|
|
318
|
+
return result;
|
|
319
|
+
},
|
|
320
|
+
advanceUpdate: async (params, user, isSystem = false, trx) => {
|
|
321
|
+
if (this.excludedTables.includes(params.tableName)) {
|
|
322
|
+
throw new errors_1.ExcludedTableError(params.tableName);
|
|
323
|
+
}
|
|
324
|
+
const { query, tableName, data } = params;
|
|
325
|
+
// const queryParams = this.parseQueryParams(query);
|
|
326
|
+
const queryParams = query;
|
|
327
|
+
if (!this.config.enforceRls || isSystem) {
|
|
328
|
+
const result = this.hooks.mutate(tableName, 'update', async (db) => this.queryHandler
|
|
329
|
+
.buildQuery(queryParams, db.updateTable(tableName))
|
|
330
|
+
.set(data)
|
|
331
|
+
.returningAll()
|
|
332
|
+
.execute(), { ...data }, undefined, trx);
|
|
333
|
+
return result;
|
|
334
|
+
}
|
|
335
|
+
if (!user && !isSystem && this.config.enforceRls) {
|
|
336
|
+
throw new errors_1.AuthenticationRequiredError('Authentication required to update records');
|
|
337
|
+
}
|
|
338
|
+
const { status: initialStatus, hasFieldCheck: initialHasFieldCheck, hasCustomFunction: initialHasCustomFunction, fieldCheckRules: extractedFieldCheckRules, } = await (0, rlsManager_1.enforcePermissions)(tableName, 'UPDATE', user, this.permissionService, undefined, this.hooks.getDbInstance());
|
|
339
|
+
if (!initialStatus &&
|
|
340
|
+
!initialHasFieldCheck &&
|
|
341
|
+
!initialHasCustomFunction) {
|
|
342
|
+
throw new Error(`User does not have permission to update this records`);
|
|
343
|
+
}
|
|
344
|
+
if (initialStatus) {
|
|
345
|
+
// Simple rule matched — proceed directly
|
|
346
|
+
const result = this.hooks.mutate(tableName, 'update', async (db) => this.queryHandler
|
|
347
|
+
.buildQuery(queryParams, db.updateTable(tableName))
|
|
348
|
+
.set(data)
|
|
349
|
+
.returningAll()
|
|
350
|
+
.execute(), { ...data }, queryParams, trx);
|
|
351
|
+
return result;
|
|
352
|
+
}
|
|
353
|
+
// fieldCheck/customFunction path — fetch matching rows then evaluate
|
|
354
|
+
const records = (await this.hooks.query(tableName, (db) => this.queryHandler
|
|
355
|
+
.buildQuery(queryParams, db.selectFrom(tableName))
|
|
356
|
+
.selectAll()
|
|
357
|
+
.execute(), queryParams, trx));
|
|
358
|
+
// Fast path: use pre-extracted rules instead of full enforcePermissions
|
|
359
|
+
if (extractedFieldCheckRules?.length) {
|
|
360
|
+
for (const record of records) {
|
|
361
|
+
const allowed = await (0, rlsManager_1.evaluateFieldCheckForRow)(extractedFieldCheckRules, user, record, this.hooks.getDbInstance());
|
|
362
|
+
if (!allowed) {
|
|
363
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to update this records`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
else {
|
|
368
|
+
// Fallback for customFunction rules
|
|
369
|
+
const { status } = await (0, rlsManager_1.enforcePermissions)(tableName, 'UPDATE', user, this.permissionService, records, this.hooks.getDbInstance());
|
|
370
|
+
if (!status) {
|
|
371
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to update this records`);
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
const result = this.hooks.mutate(tableName, 'update', async (db) => this.queryHandler
|
|
375
|
+
.buildQuery(queryParams, db.updateTable(tableName))
|
|
376
|
+
.set(data)
|
|
377
|
+
.returningAll()
|
|
378
|
+
.execute(), { ...data }, queryParams, trx);
|
|
379
|
+
return result;
|
|
380
|
+
},
|
|
381
|
+
delete: async (params, user, isSystem = false, trx) => {
|
|
382
|
+
if (this.excludedTables.includes(params.tableName)) {
|
|
383
|
+
throw new errors_1.ExcludedTableError(params.tableName);
|
|
384
|
+
}
|
|
385
|
+
const { id, tableName } = params;
|
|
386
|
+
if (!this.config.enforceRls || isSystem) {
|
|
387
|
+
return this.hooks.mutate(tableName, 'delete', async (db) => db
|
|
388
|
+
.deleteFrom(tableName)
|
|
389
|
+
.where('id', '=', id)
|
|
390
|
+
.returning('id')
|
|
391
|
+
.execute(), { id }, undefined, trx);
|
|
392
|
+
}
|
|
393
|
+
if (!user && !isSystem && this.config.enforceRls) {
|
|
394
|
+
throw new errors_1.AuthenticationRequiredError('Authentication required to delete records');
|
|
395
|
+
}
|
|
396
|
+
const { status: initialStatus, hasFieldCheck: initialHasFieldCheck, hasCustomFunction: initialHasCustomFunction, fieldCheckRules: extractedFieldCheckRules, } = await (0, rlsManager_1.enforcePermissions)(tableName, 'DELETE', user, this.permissionService, undefined, this.hooks.getDbInstance());
|
|
397
|
+
if (!initialStatus &&
|
|
398
|
+
!initialHasFieldCheck &&
|
|
399
|
+
!initialHasCustomFunction) {
|
|
400
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to delete record with id ${id}`);
|
|
401
|
+
}
|
|
402
|
+
if (initialStatus) {
|
|
403
|
+
// If the user has permission to delete, proceed with the deletion
|
|
404
|
+
return this.hooks.mutate(tableName, 'delete', async (db) => db.deleteFrom(tableName).where('id', '=', id).execute(), { id }, undefined, trx);
|
|
405
|
+
}
|
|
406
|
+
// fieldCheck/customFunction path — fetch the record then evaluate
|
|
407
|
+
const record = (await this.hooks.query(tableName, (db) => {
|
|
408
|
+
return db
|
|
409
|
+
.selectFrom(tableName)
|
|
410
|
+
.where('id', '=', id)
|
|
411
|
+
.selectAll()
|
|
412
|
+
.execute();
|
|
413
|
+
}, { id }, trx));
|
|
414
|
+
// Fast path: use pre-extracted rules instead of full enforcePermissions
|
|
415
|
+
if (extractedFieldCheckRules?.length) {
|
|
416
|
+
const allowed = await (0, rlsManager_1.evaluateFieldCheckForRow)(extractedFieldCheckRules, user, record[0], this.hooks.getDbInstance());
|
|
417
|
+
if (!allowed) {
|
|
418
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to delete record with id ${id}`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
else {
|
|
422
|
+
// Fallback for customFunction rules
|
|
423
|
+
const { status } = await (0, rlsManager_1.enforcePermissions)(tableName, 'DELETE', user, this.permissionService, record, this.hooks.getDbInstance());
|
|
424
|
+
if (!status) {
|
|
425
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to delete record with id ${id}`);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
return this.hooks.mutate(tableName, 'delete', async (db) => db.deleteFrom(tableName).where('id', '=', id).execute(), { id }, undefined, trx);
|
|
429
|
+
},
|
|
430
|
+
advanceDelete: async (params, user, isSystem = false, trx) => {
|
|
431
|
+
if (this.excludedTables.includes(params.tableName)) {
|
|
432
|
+
throw new errors_1.ExcludedTableError(params.tableName);
|
|
433
|
+
}
|
|
434
|
+
const { query, tableName } = params;
|
|
435
|
+
// const queryParams = this.parseQueryParams(query);
|
|
436
|
+
const queryParams = query;
|
|
437
|
+
if (!this.config.enforceRls || isSystem) {
|
|
438
|
+
return this.hooks.mutate(tableName, 'delete', async (db) => this.queryHandler
|
|
439
|
+
.buildQuery(queryParams, db.deleteFrom(tableName))
|
|
440
|
+
.returningAll()
|
|
441
|
+
.execute(), undefined, queryParams, trx);
|
|
442
|
+
}
|
|
443
|
+
if (!user && !isSystem && this.config.enforceRls) {
|
|
444
|
+
throw new errors_1.AuthenticationRequiredError('Authentication required to delete records');
|
|
445
|
+
}
|
|
446
|
+
const { status: initialStatus, hasFieldCheck: initialHasFieldCheck, hasCustomFunction: initialHasCustomFunction, fieldCheckRules: extractedFieldCheckRules, } = await (0, rlsManager_1.enforcePermissions)(tableName, 'DELETE', user, this.permissionService, undefined, this.hooks.getDbInstance());
|
|
447
|
+
if (!initialStatus &&
|
|
448
|
+
!initialHasFieldCheck &&
|
|
449
|
+
!initialHasCustomFunction) {
|
|
450
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to delete this records`);
|
|
451
|
+
}
|
|
452
|
+
if (initialStatus) {
|
|
453
|
+
// Simple rule matched — proceed directly
|
|
454
|
+
return this.hooks.mutate(tableName, 'delete', async (db) => this.queryHandler
|
|
455
|
+
.buildQuery(queryParams, db.deleteFrom(tableName))
|
|
456
|
+
.returningAll()
|
|
457
|
+
.execute(), undefined, queryParams, trx);
|
|
458
|
+
}
|
|
459
|
+
// fieldCheck/customFunction path — fetch matching rows then evaluate
|
|
460
|
+
const records = (await this.hooks.query(tableName, async (db) => this.queryHandler
|
|
461
|
+
.buildQuery(queryParams, db.selectFrom(tableName))
|
|
462
|
+
.execute(), queryParams, trx));
|
|
463
|
+
// Fast path: use pre-extracted rules instead of full enforcePermissions
|
|
464
|
+
if (extractedFieldCheckRules?.length) {
|
|
465
|
+
for (const record of records) {
|
|
466
|
+
const allowed = await (0, rlsManager_1.evaluateFieldCheckForRow)(extractedFieldCheckRules, user, record, this.hooks.getDbInstance());
|
|
467
|
+
if (!allowed) {
|
|
468
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to delete this records`);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
else {
|
|
473
|
+
// Fallback for customFunction rules
|
|
474
|
+
const { status } = await (0, rlsManager_1.enforcePermissions)(tableName, 'DELETE', user, this.permissionService, records, this.hooks.getDbInstance());
|
|
475
|
+
if (!status) {
|
|
476
|
+
throw new errors_1.PermissionDeniedError(`User does not have permission to delete this records`);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
return this.hooks.mutate(tableName, 'delete', async (db) => this.queryHandler
|
|
480
|
+
.buildQuery(queryParams, db.deleteFrom(tableName))
|
|
481
|
+
.returningAll()
|
|
482
|
+
.execute(), undefined, queryParams, trx);
|
|
483
|
+
},
|
|
484
|
+
},
|
|
485
|
+
/**
|
|
486
|
+
* Work with the database permissions
|
|
487
|
+
* @returns Permissions endpoints
|
|
488
|
+
*/
|
|
489
|
+
permissions: {
|
|
490
|
+
get: async (params, trx) => {
|
|
491
|
+
if (this.excludedTables.includes(params.tableName)) {
|
|
492
|
+
throw new errors_1.ExcludedTableError(params.tableName);
|
|
493
|
+
}
|
|
494
|
+
// If no transaction is provided, create one internally
|
|
495
|
+
if (!trx) {
|
|
496
|
+
return this.transaction(async (newTrx) => {
|
|
497
|
+
return await this.endpoints.permissions.get(params, newTrx);
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
const { tableName } = params;
|
|
501
|
+
return this.permissionService.getPermissionsForTable(tableName, trx);
|
|
502
|
+
},
|
|
503
|
+
set: async (params, trx) => {
|
|
504
|
+
if (this.excludedTables.includes(params.tableName)) {
|
|
505
|
+
throw new errors_1.ExcludedTableError(params.tableName);
|
|
506
|
+
}
|
|
507
|
+
// If no transaction is provided, create one internally and manage it
|
|
508
|
+
if (!trx) {
|
|
509
|
+
return this.transaction(async (newTrx) => {
|
|
510
|
+
return await this.endpoints.permissions.set(params, newTrx);
|
|
511
|
+
});
|
|
512
|
+
}
|
|
513
|
+
const { tableName, permissions } = params;
|
|
514
|
+
if (!permissions) {
|
|
515
|
+
throw new Error('Permissions object is required');
|
|
516
|
+
}
|
|
517
|
+
return this.permissionService.setPermissionsForTable(tableName, permissions, trx);
|
|
518
|
+
},
|
|
519
|
+
},
|
|
520
|
+
};
|
|
521
|
+
if (!config.db && !config.libsql) {
|
|
522
|
+
throw new Error('Either database instance (db) or libsql config is required');
|
|
523
|
+
}
|
|
524
|
+
if (!config.db && config.libsql) {
|
|
525
|
+
this.config.db = new kysely_1.Kysely({
|
|
526
|
+
dialect: new libsql_1.LibsqlDialect(config.libsql),
|
|
527
|
+
});
|
|
528
|
+
}
|
|
529
|
+
if (config.excludedTables) {
|
|
530
|
+
this.excludedTables = [...this.excludedTables, ...config.excludedTables];
|
|
531
|
+
}
|
|
532
|
+
this.permissionService =
|
|
533
|
+
config.permissionsService || new permissionService_1.PermissionService(config.db);
|
|
534
|
+
this.dbInspector = new inspector_1.DBInspector(config.db);
|
|
535
|
+
// Initialize realtime adapter if realtime is enabled
|
|
536
|
+
if (config.realtime) {
|
|
537
|
+
const adapterType = config.realtimeAdapter || 'sse';
|
|
538
|
+
const port = config.websocketPort || 9001;
|
|
539
|
+
if (adapterType === 'websocket') {
|
|
540
|
+
this.realtimeAdapter = new WebSocketManager_1.WebSocketManager(port, this.permissionService);
|
|
541
|
+
}
|
|
542
|
+
else if (adapterType === 'sse') {
|
|
543
|
+
this.realtimeAdapter = new SSEManager_1.SSEManager(port, this.permissionService);
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
this.hooks =
|
|
547
|
+
config.hooks || new kysely_hooks_1.KyselyHooks(config.db, this.realtimeAdapter);
|
|
548
|
+
this.queryHandler = new server_1.KyselyQueryHandler(this.hooks.getDbInstance());
|
|
549
|
+
// Set default permissions for all tables
|
|
550
|
+
if (config.defaultPermissions) {
|
|
551
|
+
this.defaultPermissions = config.defaultPermissions;
|
|
552
|
+
}
|
|
553
|
+
// Initialize permissions for all tables if enabled
|
|
554
|
+
if (config.initializePermissions) {
|
|
555
|
+
this.initializeTablePermissions();
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
getDbInspector() {
|
|
559
|
+
return this.dbInspector;
|
|
560
|
+
}
|
|
561
|
+
async ready() {
|
|
562
|
+
await this.permissionService.ready();
|
|
563
|
+
}
|
|
564
|
+
getExcludedTables() {
|
|
565
|
+
return this.excludedTables;
|
|
566
|
+
}
|
|
567
|
+
getDefaultPermissions() {
|
|
568
|
+
return this.defaultPermissions;
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Initialize permissions for all tables in the database
|
|
572
|
+
* This is a non-blocking operation that runs in the background
|
|
573
|
+
*/
|
|
574
|
+
initializeTablePermissions() {
|
|
575
|
+
const { permissionReportPath, onPermissionInitComplete } = this.config;
|
|
576
|
+
// Use the public method to avoid code duplication
|
|
577
|
+
this.initializePermissions(permissionReportPath, onPermissionInitComplete);
|
|
578
|
+
}
|
|
579
|
+
/**
|
|
580
|
+
* Add a table to the excluded tables list
|
|
581
|
+
* @param tables List of tables to exclude
|
|
582
|
+
*/
|
|
583
|
+
addExcludedTables(tables) {
|
|
584
|
+
this.excludedTables = [...this.excludedTables, ...tables];
|
|
585
|
+
}
|
|
586
|
+
/**
|
|
587
|
+
* Remove a table from the excluded tables list
|
|
588
|
+
* @param tables List of tables to include
|
|
589
|
+
*/
|
|
590
|
+
removeExcludedTables(tables) {
|
|
591
|
+
this.excludedTables = this.excludedTables.filter((table) => !tables.includes(table));
|
|
592
|
+
}
|
|
593
|
+
/**
|
|
594
|
+
* Manually trigger permission initialization for all tables
|
|
595
|
+
* @param reportPath Optional path to save the report file
|
|
596
|
+
* @param onComplete Optional callback function to call when initialization is complete
|
|
597
|
+
*/
|
|
598
|
+
initializePermissions(reportPath, onComplete) {
|
|
599
|
+
// Use provided parameters or fall back to config values
|
|
600
|
+
const finalReportPath = reportPath || this.config.permissionReportPath;
|
|
601
|
+
const finalCallback = onComplete || this.config.onPermissionInitComplete;
|
|
602
|
+
// Start the initialization process
|
|
603
|
+
(0, permission_initializer_1.initializePermissions)(this.hooks.getDbInstance(), this.permissionService, this.dbInspector, this.excludedTables, this.defaultPermissions, finalReportPath, finalCallback);
|
|
604
|
+
console.log('Permission initialization started in the background');
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* Get the database schema
|
|
608
|
+
* @returns Database schema
|
|
609
|
+
*/
|
|
610
|
+
getEndpoints() {
|
|
611
|
+
return this.endpoints;
|
|
612
|
+
}
|
|
613
|
+
/**
|
|
614
|
+
* Get the knex instance
|
|
615
|
+
* @returns Knex instance
|
|
616
|
+
*/
|
|
617
|
+
getDbInstance() {
|
|
618
|
+
return this.hooks.getDbInstance();
|
|
619
|
+
}
|
|
620
|
+
getHooksDb() {
|
|
621
|
+
return this.hooks;
|
|
622
|
+
}
|
|
623
|
+
getPermissionService() {
|
|
624
|
+
return this.permissionService;
|
|
625
|
+
}
|
|
626
|
+
/**
|
|
627
|
+
* Execute a function within a transaction
|
|
628
|
+
* @param callback Function to execute within the transaction
|
|
629
|
+
* @returns Result of the callback function
|
|
630
|
+
*/
|
|
631
|
+
async transaction(callback) {
|
|
632
|
+
try {
|
|
633
|
+
return await this.hooks.getDbInstance().transaction().execute(callback);
|
|
634
|
+
}
|
|
635
|
+
catch (error) {
|
|
636
|
+
console.error('Transaction error:', error);
|
|
637
|
+
throw error;
|
|
638
|
+
}
|
|
639
|
+
}
|
|
640
|
+
parseQueryParams(params) {
|
|
641
|
+
const queryParams = {};
|
|
642
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
643
|
+
if (typeof value === 'string') {
|
|
644
|
+
try {
|
|
645
|
+
queryParams[key] = JSON.parse(value);
|
|
646
|
+
}
|
|
647
|
+
catch {
|
|
648
|
+
if (key === 'limit' || key === 'offset') {
|
|
649
|
+
queryParams[key] = parseInt(value, 10) || 10;
|
|
650
|
+
}
|
|
651
|
+
else {
|
|
652
|
+
queryParams[key] = value;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
else {
|
|
657
|
+
queryParams[key] = value;
|
|
658
|
+
}
|
|
659
|
+
});
|
|
660
|
+
return queryParams;
|
|
661
|
+
}
|
|
662
|
+
}
|
|
663
|
+
exports.ForgeDatabase = ForgeDatabase;
|
|
664
|
+
/**
|
|
665
|
+
* Create a new instance of the ForgeDatabase class
|
|
666
|
+
* @param config Configuration object for the ForgeDatabase instance
|
|
667
|
+
* @returns A new instance of the ForgeDatabase class
|
|
668
|
+
*/
|
|
669
|
+
const createForgeDatabase = (config) => {
|
|
670
|
+
return new ForgeDatabase(config);
|
|
671
|
+
};
|
|
672
|
+
exports.createForgeDatabase = createForgeDatabase;
|
|
673
|
+
//# sourceMappingURL=database.js.map
|