prostgles-server 4.2.566 → 4.2.569
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/dist/Auth/AuthTypes.d.ts +5 -5
- package/dist/Auth/AuthTypes.d.ts.map +1 -1
- package/dist/Auth/AuthTypes.js.map +1 -1
- package/dist/Auth/endpoints/setCatchAllRequestHandler.d.ts.map +1 -1
- package/dist/Auth/endpoints/setCatchAllRequestHandler.js +2 -2
- package/dist/Auth/endpoints/setCatchAllRequestHandler.js.map +1 -1
- package/dist/DBSchemaBuilder/getColumnTypescriptDefinition.d.ts +1 -1
- package/dist/DBSchemaBuilder/getColumnTypescriptDefinition.d.ts.map +1 -1
- package/dist/DBSchemaBuilder/getDBGeneratedSchema.d.ts +1 -1
- package/dist/DBSchemaBuilder/getDBGeneratedSchema.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilder.js +4 -4
- package/dist/DboBuilder/DboBuilder.js.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.d.ts +2 -18
- package/dist/DboBuilder/DboBuilderTypes.d.ts.map +1 -1
- package/dist/DboBuilder/DboBuilderTypes.js.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts +15 -5
- package/dist/DboBuilder/TableHandler/TableHandler.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/TableHandler.js +4 -3
- package/dist/DboBuilder/TableHandler/TableHandler.js.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/delete.js +17 -14
- package/dist/DboBuilder/TableHandler/delete.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insert.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insert.js +3 -12
- package/dist/DboBuilder/TableHandler/insert/insert.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.js +10 -15
- package/dist/DboBuilder/TableHandler/insert/insertNestedRecords.js.map +1 -1
- package/dist/DboBuilder/TableHandler/insert/insertRowWithNestedRecords.js +1 -1
- package/dist/DboBuilder/TableHandler/insert/insertRowWithNestedRecords.js.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts +8 -6
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js +30 -48
- package/dist/DboBuilder/TableHandler/onDeleteFromFileTable.js.map +1 -1
- package/dist/DboBuilder/TableHandler/update.d.ts +1 -1
- package/dist/DboBuilder/TableHandler/update.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/update.js +8 -18
- package/dist/DboBuilder/TableHandler/update.js.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.d.ts +2 -3
- package/dist/DboBuilder/TableHandler/updateFile.d.ts.map +1 -1
- package/dist/DboBuilder/TableHandler/updateFile.js +8 -28
- package/dist/DboBuilder/TableHandler/updateFile.js.map +1 -1
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts +2 -2
- package/dist/DboBuilder/ViewHandler/ViewHandler.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/getInfo.d.ts +1 -1
- package/dist/DboBuilder/ViewHandler/getInfo.d.ts.map +1 -1
- package/dist/DboBuilder/ViewHandler/getInfo.js +12 -1
- package/dist/DboBuilder/ViewHandler/getInfo.js.map +1 -1
- package/dist/DboBuilder/getColumns.d.ts.map +1 -1
- package/dist/DboBuilder/getColumns.js +29 -4
- package/dist/DboBuilder/getColumns.js.map +1 -1
- package/dist/DboBuilder/schema/getTablesForSchemaPostgresSQL.d.ts +2 -2
- package/dist/DboBuilder/uploadFile.d.ts +5 -6
- package/dist/DboBuilder/uploadFile.d.ts.map +1 -1
- package/dist/DboBuilder/uploadFile.js +28 -42
- package/dist/DboBuilder/uploadFile.js.map +1 -1
- package/dist/FileManager/FileManager.d.ts +22 -78
- package/dist/FileManager/FileManager.d.ts.map +1 -1
- package/dist/FileManager/FileManager.js +1 -219
- package/dist/FileManager/FileManager.js.map +1 -1
- package/dist/FileManager/getFileTableConfig.d.ts +26 -0
- package/dist/FileManager/getFileTableConfig.d.ts.map +1 -0
- package/dist/FileManager/getFileTableConfig.js +115 -0
- package/dist/FileManager/getFileTableConfig.js.map +1 -0
- package/dist/FileManager/getLocalStorageClient.d.ts +3 -0
- package/dist/FileManager/getLocalStorageClient.d.ts.map +1 -0
- package/dist/FileManager/getLocalStorageClient.js +105 -0
- package/dist/FileManager/getLocalStorageClient.js.map +1 -0
- package/dist/FileManager/getValidatedFileType.d.ts +2 -2
- package/dist/FileManager/getValidatedFileType.d.ts.map +1 -1
- package/dist/FileManager/getValidatedFileType.js +7 -9
- package/dist/FileManager/getValidatedFileType.js.map +1 -1
- package/dist/FileManager/setupFileServeHandler.d.ts +9 -0
- package/dist/FileManager/setupFileServeHandler.d.ts.map +1 -0
- package/dist/FileManager/setupFileServeHandler.js +114 -0
- package/dist/FileManager/setupFileServeHandler.js.map +1 -0
- package/dist/Filtering/Filtering.d.ts +1 -1
- package/dist/JSONBSchemaValidation/validateJSONBSchemaSQL.d.ts.map +1 -1
- package/dist/JSONBSchemaValidation/validateJSONBSchemaSQL.js +39 -0
- package/dist/JSONBSchemaValidation/validateJSONBSchemaSQL.js.map +1 -1
- package/dist/Logging.d.ts +1 -1
- package/dist/Logging.d.ts.map +1 -1
- package/dist/Prostgles.d.ts +52 -6
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +8 -47
- package/dist/Prostgles.js.map +1 -1
- package/dist/ProstglesTypes.d.ts +23 -21
- package/dist/ProstglesTypes.d.ts.map +1 -1
- package/dist/ProstglesTypes.js.map +1 -1
- package/dist/PubSubManager/notifListener.d.ts.map +1 -1
- package/dist/PubSubManager/notifListener.js +0 -1
- package/dist/PubSubManager/notifListener.js.map +1 -1
- package/dist/PublishParser/getDBSchemaTable.d.ts +2 -2
- package/dist/PublishParser/getDBSchemaTable.d.ts.map +1 -1
- package/dist/PublishParser/getDBSchemaTable.js +5 -3
- package/dist/PublishParser/getDBSchemaTable.js.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.d.ts.map +1 -1
- package/dist/PublishParser/getSchemaFromPublish.js +2 -2
- package/dist/PublishParser/getSchemaFromPublish.js.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.d.ts +1 -0
- package/dist/PublishParser/publishTypesAndUtils.d.ts.map +1 -1
- package/dist/PublishParser/publishTypesAndUtils.js.map +1 -1
- package/dist/RestApi.d.ts +1 -5
- package/dist/RestApi.d.ts.map +1 -1
- package/dist/RestApi.js +10 -5
- package/dist/RestApi.js.map +1 -1
- package/dist/TableConfig/{TableConfig.d.ts → TableConfigTypes.d.ts} +19 -64
- package/dist/TableConfig/TableConfigTypes.d.ts.map +1 -0
- package/dist/TableConfig/TableConfigTypes.js +3 -0
- package/dist/TableConfig/TableConfigTypes.js.map +1 -0
- package/dist/TableConfig/TableConfigurator.d.ts +104 -0
- package/dist/TableConfig/TableConfigurator.d.ts.map +1 -0
- package/dist/TableConfig/{TableConfig.js → TableConfigurator.js} +31 -44
- package/dist/TableConfig/TableConfigurator.js.map +1 -0
- package/dist/TableConfig/applyTableConfig.d.ts.map +1 -1
- package/dist/TableConfig/applyTableConfig.js +0 -1
- package/dist/TableConfig/applyTableConfig.js.map +1 -1
- package/dist/TableConfig/getColumnConfig.d.ts +1 -1
- package/dist/TableConfig/getColumnConfig.d.ts.map +1 -1
- package/dist/TableConfig/getColumnSQLDefinitionQuery.d.ts +1 -1
- package/dist/TableConfig/getColumnSQLDefinitionQuery.d.ts.map +1 -1
- package/dist/TableConfig/getColumnSQLDefinitionQuery.js +1 -1
- package/dist/TableConfig/getColumnSQLDefinitionQuery.js.map +1 -1
- package/dist/TableConfig/getConstraintDefinitionQueries.d.ts +1 -1
- package/dist/TableConfig/getConstraintDefinitionQueries.d.ts.map +1 -1
- package/dist/TableConfig/getCreateSchemaQueries.d.ts +26 -8
- package/dist/TableConfig/getCreateSchemaQueries.d.ts.map +1 -1
- package/dist/TableConfig/getSchemaDiffQueries.d.ts.map +1 -1
- package/dist/TableConfig/getSchemaDiffQueries.js +12 -8
- package/dist/TableConfig/getSchemaDiffQueries.js.map +1 -1
- package/dist/TableConfig/getTableColumnQueries.d.ts +1 -1
- package/dist/TableConfig/getTableColumnQueries.d.ts.map +1 -1
- package/dist/TableConfig/getTableColumnQueries.js +19 -19
- package/dist/TableConfig/getTableColumnQueries.js.map +1 -1
- package/dist/TableConfig/getTableConfigSchemaQueries.d.ts +26 -10
- package/dist/TableConfig/getTableConfigSchemaQueries.d.ts.map +1 -1
- package/dist/TableConfig/getTableConfigSchemaQueries.js +8 -10
- package/dist/TableConfig/getTableConfigSchemaQueries.js.map +1 -1
- package/dist/TableConfig/indexes/getIndexesQueries.d.ts +1 -1
- package/dist/TableConfig/indexes/getIndexesQueries.d.ts.map +1 -1
- package/dist/TableConfig/initTableConfig.d.ts +1 -1
- package/dist/TableConfig/initTableConfig.d.ts.map +1 -1
- package/dist/TableConfig/initTableConfig.js +6 -3
- package/dist/TableConfig/initTableConfig.js.map +1 -1
- package/dist/WebsocketAPI/getClientSchema.d.ts.map +1 -1
- package/dist/WebsocketAPI/getClientSchema.js +6 -1
- package/dist/WebsocketAPI/getClientSchema.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/initProstgles.d.ts.map +1 -1
- package/dist/initProstgles.js +2 -5
- package/dist/initProstgles.js.map +1 -1
- package/dist/runClientRequest.js +1 -1
- package/dist/runClientRequest.js.map +1 -1
- package/dist/updateConfiguration.d.ts.map +1 -1
- package/dist/updateConfiguration.js +0 -3
- package/dist/updateConfiguration.js.map +1 -1
- package/eslint.config.mjs +0 -3
- package/lib/Auth/AuthTypes.ts +6 -7
- package/lib/Auth/endpoints/setCatchAllRequestHandler.ts +6 -2
- package/lib/DBSchemaBuilder/getColumnTypescriptDefinition.ts +1 -1
- package/lib/DBSchemaBuilder/getDBGeneratedSchema.ts +1 -1
- package/lib/DboBuilder/DboBuilder.ts +4 -4
- package/lib/DboBuilder/DboBuilderTypes.ts +7 -20
- package/lib/DboBuilder/TableHandler/TableHandler.ts +7 -4
- package/lib/DboBuilder/TableHandler/delete.ts +23 -17
- package/lib/DboBuilder/TableHandler/insert/insert.ts +3 -12
- package/lib/DboBuilder/TableHandler/insert/insertNestedRecords.ts +13 -17
- package/lib/DboBuilder/TableHandler/insert/insertRowWithNestedRecords.ts +1 -1
- package/lib/DboBuilder/TableHandler/onDeleteFromFileTable.ts +41 -54
- package/lib/DboBuilder/TableHandler/update.ts +8 -19
- package/lib/DboBuilder/TableHandler/updateFile.ts +20 -42
- package/lib/DboBuilder/ViewHandler/ViewHandler.ts +1 -1
- package/lib/DboBuilder/ViewHandler/getInfo.ts +19 -2
- package/lib/DboBuilder/getColumns.ts +40 -4
- package/lib/DboBuilder/uploadFile.ts +34 -50
- package/lib/FileManager/FileManager.ts +23 -249
- package/lib/FileManager/getFileTableConfig.ts +142 -0
- package/lib/FileManager/getLocalStorageClient.ts +118 -0
- package/lib/FileManager/getValidatedFileType.ts +14 -22
- package/lib/FileManager/setupFileServeHandler.ts +102 -0
- package/lib/JSONBSchemaValidation/validateJSONBSchemaSQL.ts +39 -0
- package/lib/Logging.ts +0 -3
- package/lib/Prostgles.ts +9 -44
- package/lib/ProstglesTypes.ts +34 -23
- package/lib/PubSubManager/notifListener.ts +0 -2
- package/lib/PublishParser/getDBSchemaTable.ts +6 -3
- package/lib/PublishParser/getSchemaFromPublish.ts +2 -1
- package/lib/PublishParser/publishTypesAndUtils.ts +1 -0
- package/lib/RestApi.ts +12 -12
- package/lib/TableConfig/{TableConfig.ts → TableConfigTypes.ts} +18 -217
- package/lib/TableConfig/TableConfigurator.ts +191 -0
- package/lib/TableConfig/applyTableConfig.ts +2 -3
- package/lib/TableConfig/getColumnConfig.ts +2 -2
- package/lib/TableConfig/getColumnSQLDefinitionQuery.ts +2 -2
- package/lib/TableConfig/getConstraintDefinitionQueries.ts +1 -1
- package/lib/TableConfig/getCreateSchemaQueries.ts +1 -1
- package/lib/TableConfig/getSchemaDiffQueries.ts +14 -11
- package/lib/TableConfig/getTableColumnQueries.ts +22 -20
- package/lib/TableConfig/getTableConfigSchemaQueries.ts +20 -22
- package/lib/TableConfig/indexes/getIndexesQueries.ts +1 -1
- package/lib/TableConfig/initTableConfig.ts +7 -6
- package/lib/WebsocketAPI/getClientSchema.ts +7 -1
- package/lib/index.ts +3 -2
- package/lib/initProstgles.ts +2 -6
- package/lib/runClientRequest.ts +1 -1
- package/lib/updateConfiguration.ts +0 -3
- package/package.json +2 -3
- package/dist/FileManager/initFileManager.d.ts +0 -18
- package/dist/FileManager/initFileManager.d.ts.map +0 -1
- package/dist/FileManager/initFileManager.js +0 -257
- package/dist/FileManager/initFileManager.js.map +0 -1
- package/dist/FileManager/upload.d.ts +0 -4
- package/dist/FileManager/upload.d.ts.map +0 -1
- package/dist/FileManager/upload.js +0 -90
- package/dist/FileManager/upload.js.map +0 -1
- package/dist/FileManager/uploadStream.d.ts +0 -4
- package/dist/FileManager/uploadStream.d.ts.map +0 -1
- package/dist/FileManager/uploadStream.js +0 -100
- package/dist/FileManager/uploadStream.js.map +0 -1
- package/dist/TableConfig/TableConfig.d.ts.map +0 -1
- package/dist/TableConfig/TableConfig.js.map +0 -1
- package/lib/FileManager/initFileManager.ts +0 -254
- package/lib/FileManager/upload.ts +0 -59
- package/lib/FileManager/uploadStream.ts +0 -76
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import crypto from "crypto";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import stream from "stream";
|
|
5
|
+
import type {
|
|
6
|
+
FileUploadArgs,
|
|
7
|
+
LocalConfig,
|
|
8
|
+
LocalStorageClient,
|
|
9
|
+
UploadedCloudFile,
|
|
10
|
+
} from "./FileManager";
|
|
11
|
+
|
|
12
|
+
export const getLocalStorageClient = (localConfig: LocalConfig): LocalStorageClient => {
|
|
13
|
+
const { localFolderPath, minFreeBytes = 100 * 1024 * 1024 } = localConfig; // Default 100MB
|
|
14
|
+
|
|
15
|
+
// Helper to ensure we have enough free disk space (Requires Node >= 18.17.0)
|
|
16
|
+
const checkFreeSpace = async () => {
|
|
17
|
+
try {
|
|
18
|
+
const stats = await fs.promises.statfs(localFolderPath);
|
|
19
|
+
const freeSpace = stats.bavail * stats.bsize;
|
|
20
|
+
|
|
21
|
+
if (freeSpace < minFreeBytes) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Insufficient disk space. Required: ${minFreeBytes} bytes, Available: ${freeSpace} bytes`,
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
} catch (error: any) {
|
|
27
|
+
// If the directory doesn't exist yet, statfs will throw. We'll ignore and let mkdir handle it.
|
|
28
|
+
if (error.code !== "ENOENT") {
|
|
29
|
+
throw error;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
type: "local",
|
|
36
|
+
localFolderPath: localConfig.localFolderPath,
|
|
37
|
+
upload: async (args: FileUploadArgs): Promise<UploadedCloudFile> => {
|
|
38
|
+
// Ensure the target directory exists
|
|
39
|
+
await fs.promises.mkdir(localFolderPath, { recursive: true });
|
|
40
|
+
await checkFreeSpace();
|
|
41
|
+
|
|
42
|
+
const filePath = path.join(localFolderPath, args.fileName);
|
|
43
|
+
const hash = crypto.createHash("md5");
|
|
44
|
+
let contentLength = 0;
|
|
45
|
+
|
|
46
|
+
return new Promise((resolve, reject) => {
|
|
47
|
+
const writeStream = fs.createWriteStream(filePath);
|
|
48
|
+
|
|
49
|
+
writeStream.on("error", reject);
|
|
50
|
+
writeStream.on("finish", () => {
|
|
51
|
+
resolve({
|
|
52
|
+
cloud_url: filePath,
|
|
53
|
+
etag: hash.digest("hex"),
|
|
54
|
+
content_length: contentLength,
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// Handle raw string or Buffer
|
|
59
|
+
if (typeof args.file === "string" || Buffer.isBuffer(args.file)) {
|
|
60
|
+
const buffer = Buffer.isBuffer(args.file) ? args.file : Buffer.from(args.file);
|
|
61
|
+
|
|
62
|
+
contentLength = buffer.length;
|
|
63
|
+
hash.update(buffer);
|
|
64
|
+
|
|
65
|
+
if (args.onProgress) {
|
|
66
|
+
args.onProgress(contentLength);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
writeStream.write(buffer);
|
|
70
|
+
writeStream.end();
|
|
71
|
+
} else if (
|
|
72
|
+
args.file instanceof stream.Readable ||
|
|
73
|
+
(args.file as unknown) instanceof stream.PassThrough
|
|
74
|
+
) {
|
|
75
|
+
let lastProgress = Date.now();
|
|
76
|
+
const throttle = 1000; // 1 second
|
|
77
|
+
args.file.on("data", (chunk: Buffer) => {
|
|
78
|
+
contentLength += chunk.length;
|
|
79
|
+
hash.update(chunk);
|
|
80
|
+
if (args.onProgress && Date.now() - lastProgress > throttle) {
|
|
81
|
+
lastProgress = Date.now();
|
|
82
|
+
args.onProgress(contentLength);
|
|
83
|
+
}
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
args.file.on("error", reject);
|
|
87
|
+
args.file.pipe(writeStream);
|
|
88
|
+
} else {
|
|
89
|
+
reject(new Error("Unsupported file type provided to upload."));
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
},
|
|
93
|
+
|
|
94
|
+
downloadAsStream: async (name: string) => {
|
|
95
|
+
const filePath = path.join(localFolderPath, name);
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
await fs.promises.access(filePath, fs.constants.R_OK);
|
|
99
|
+
} catch (err) {
|
|
100
|
+
throw new Error(`File not found or unreadable: ${name}`);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return fs.createReadStream(filePath);
|
|
104
|
+
},
|
|
105
|
+
|
|
106
|
+
delete: async (fileName: string) => {
|
|
107
|
+
const filePath = path.join(localFolderPath, fileName);
|
|
108
|
+
try {
|
|
109
|
+
await fs.promises.unlink(filePath);
|
|
110
|
+
} catch (err: any) {
|
|
111
|
+
// Ignore error if file doesn't exist
|
|
112
|
+
if (err.code !== "ENOENT") {
|
|
113
|
+
throw err;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
},
|
|
117
|
+
};
|
|
118
|
+
};
|
|
@@ -1,13 +1,7 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
ALLOWED_EXTENSION,
|
|
5
|
-
CONTENT_TYPE_TO_EXT,
|
|
6
|
-
getKeys,
|
|
7
|
-
isObject,
|
|
8
|
-
} from "prostgles-types";
|
|
1
|
+
import type { ALLOWED_CONTENT_TYPE } from "prostgles-types";
|
|
2
|
+
import { CONTENT_TYPE_TO_EXT, getKeys, isObject } from "prostgles-types";
|
|
9
3
|
import { parseFieldFilter } from "../DboBuilder/ViewHandler/parseFieldFilter";
|
|
10
|
-
import type {
|
|
4
|
+
import type { FileTableConfig } from "../ProstglesTypes";
|
|
11
5
|
import { getFileType, getFileTypeFromFilename } from "./FileManager";
|
|
12
6
|
|
|
13
7
|
type Args = {
|
|
@@ -16,19 +10,17 @@ type Args = {
|
|
|
16
10
|
colName?: string;
|
|
17
11
|
tableName?: string;
|
|
18
12
|
};
|
|
19
|
-
export async
|
|
20
|
-
|
|
21
|
-
args: Args
|
|
13
|
+
export const getValidatedFileType = async (
|
|
14
|
+
config: FileTableConfig,
|
|
15
|
+
args: Args,
|
|
22
16
|
): Promise<{
|
|
23
17
|
mime: ALLOWED_CONTENT_TYPE;
|
|
24
|
-
ext: string;
|
|
18
|
+
ext: string;
|
|
25
19
|
|
|
26
20
|
/** File name is not returned because we fail if the extensions do not match */
|
|
27
21
|
// fileName: string;
|
|
28
|
-
}> {
|
|
22
|
+
}> => {
|
|
29
23
|
const { file, fileName, tableName, colName } = args;
|
|
30
|
-
const config = this.prostgles?.opts.fileTable;
|
|
31
|
-
if (!config) throw new Error("File table config missing");
|
|
32
24
|
|
|
33
25
|
const buffer = typeof file === "string" ? Buffer.from(file, "utf8") : file;
|
|
34
26
|
|
|
@@ -55,7 +47,7 @@ export async function getValidatedFileType(
|
|
|
55
47
|
const allowedContent = parseFieldFilter(colConfig.acceptedContent, false, CONTENTS);
|
|
56
48
|
if (!allowedContent.some((c) => mime.mime.startsWith(c))) {
|
|
57
49
|
throw new Error(
|
|
58
|
-
`
|
|
50
|
+
`Disallowed content type provided: ${mime.mime.split("/")[0]}. Allowed content types: ${allowedContent} `,
|
|
59
51
|
);
|
|
60
52
|
}
|
|
61
53
|
} else if (
|
|
@@ -67,12 +59,12 @@ export async function getValidatedFileType(
|
|
|
67
59
|
const allowedContentTypes = parseFieldFilter(
|
|
68
60
|
colConfig.acceptedContentType,
|
|
69
61
|
false,
|
|
70
|
-
getKeys(CONTENT_TYPE_TO_EXT)
|
|
62
|
+
getKeys(CONTENT_TYPE_TO_EXT),
|
|
71
63
|
);
|
|
72
64
|
|
|
73
65
|
if (!allowedContentTypes.some((c) => c === mime.mime)) {
|
|
74
66
|
throw new Error(
|
|
75
|
-
`
|
|
67
|
+
`Disallowed MIME provided: ${mime.mime}. Allowed MIME values: ${allowedContentTypes} `,
|
|
76
68
|
);
|
|
77
69
|
}
|
|
78
70
|
} else if (
|
|
@@ -84,12 +76,12 @@ export async function getValidatedFileType(
|
|
|
84
76
|
const allowedExtensions = parseFieldFilter(
|
|
85
77
|
colConfig.acceptedFileTypes,
|
|
86
78
|
false,
|
|
87
|
-
Object.values(CONTENT_TYPE_TO_EXT).flat()
|
|
79
|
+
Object.values(CONTENT_TYPE_TO_EXT).flat(),
|
|
88
80
|
);
|
|
89
81
|
|
|
90
82
|
if (!allowedExtensions.some((c) => c === mime.ext)) {
|
|
91
83
|
throw new Error(
|
|
92
|
-
`
|
|
84
|
+
`Disallowed extension provided: ${mime.ext}. Allowed extension values: ${allowedExtensions} `,
|
|
93
85
|
);
|
|
94
86
|
}
|
|
95
87
|
}
|
|
@@ -97,4 +89,4 @@ export async function getValidatedFileType(
|
|
|
97
89
|
}
|
|
98
90
|
if (!result?.mime) throw `File MIME type not found for the provided extension: ${result?.ext}`;
|
|
99
91
|
return result;
|
|
100
|
-
}
|
|
92
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import { join } from "path";
|
|
3
|
+
import { HTTP_FAIL_CODES, removeExpressRoute } from "../Auth/AuthHandler";
|
|
4
|
+
import type { DB } from "../initProstgles";
|
|
5
|
+
import type { Prostgles } from "../Prostgles";
|
|
6
|
+
import type { FileTableConfig } from "../ProstglesTypes";
|
|
7
|
+
import type { ExpressApp } from "../RestApi";
|
|
8
|
+
import { runClientRequest } from "../runClientRequest";
|
|
9
|
+
import type { StorageClient } from "./FileManager";
|
|
10
|
+
import { HOUR } from "./FileManager";
|
|
11
|
+
import type { FileTableRow } from "./getFileTableConfig";
|
|
12
|
+
|
|
13
|
+
export const setupFileServeHandler = (
|
|
14
|
+
db: DB,
|
|
15
|
+
config: FileTableConfig,
|
|
16
|
+
storageClient: StorageClient,
|
|
17
|
+
app: ExpressApp,
|
|
18
|
+
prg: Prostgles,
|
|
19
|
+
) => {
|
|
20
|
+
const fileTableName = config.tableName;
|
|
21
|
+
const fileServeRoute = config.fileServePath ?? `/${fileTableName}`;
|
|
22
|
+
if (fileServeRoute.endsWith("/")) {
|
|
23
|
+
throw `fileServeRoute must not end with a '/'`;
|
|
24
|
+
}
|
|
25
|
+
const fileRouteExpress = fileServeRoute + "/:name";
|
|
26
|
+
|
|
27
|
+
app.get(fileRouteExpress, async (req, res) => {
|
|
28
|
+
try {
|
|
29
|
+
const { name } = req.params;
|
|
30
|
+
if (typeof name !== "string" || !name) {
|
|
31
|
+
throw "Invalid media name";
|
|
32
|
+
}
|
|
33
|
+
const id = name.slice(0, 36);
|
|
34
|
+
const selectParams = {
|
|
35
|
+
select: {
|
|
36
|
+
id: 1,
|
|
37
|
+
name: 1,
|
|
38
|
+
signed_url: 1,
|
|
39
|
+
signed_url_expires: 1,
|
|
40
|
+
content_type: 1,
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
const file = (await runClientRequest.bind(prg)(
|
|
44
|
+
{
|
|
45
|
+
command: "findOne",
|
|
46
|
+
tableName: fileTableName,
|
|
47
|
+
param1: { id },
|
|
48
|
+
param2: selectParams,
|
|
49
|
+
param3: undefined,
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
res,
|
|
53
|
+
httpReq: req,
|
|
54
|
+
},
|
|
55
|
+
undefined,
|
|
56
|
+
)) as FileTableRow | undefined;
|
|
57
|
+
|
|
58
|
+
if (!file) {
|
|
59
|
+
res.status(HTTP_FAIL_CODES.NOT_FOUND).send("File not found or not allowed");
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (storageClient.type === "cloud") {
|
|
64
|
+
let url = file.signed_url;
|
|
65
|
+
const expires = +(file.signed_url_expires || 0);
|
|
66
|
+
|
|
67
|
+
const EXPIRES = Date.now() + HOUR;
|
|
68
|
+
if (!url || expires < EXPIRES) {
|
|
69
|
+
url = await storageClient.getSignedUrlForDownload(file.name, 60 * 60);
|
|
70
|
+
|
|
71
|
+
await db.any(
|
|
72
|
+
"UPDATE ${fileTableName:name} SET signed_url = ${signed_url}, signed_url_expires = ${signed_url_expires} WHERE id = ${id}",
|
|
73
|
+
{
|
|
74
|
+
fileTableName,
|
|
75
|
+
id: file.id,
|
|
76
|
+
signed_url: url,
|
|
77
|
+
signed_url_expires: EXPIRES,
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
res.redirect(url);
|
|
83
|
+
} else {
|
|
84
|
+
const localFilePath = join(storageClient.localFolderPath, file.name);
|
|
85
|
+
if (!fs.existsSync(localFilePath)) {
|
|
86
|
+
throw new Error("File not found");
|
|
87
|
+
}
|
|
88
|
+
res.contentType(file.content_type);
|
|
89
|
+
res.sendFile(localFilePath);
|
|
90
|
+
}
|
|
91
|
+
} catch (e) {
|
|
92
|
+
console.log(e);
|
|
93
|
+
res.status(HTTP_FAIL_CODES.BAD_REQUEST).send("Invalid/disallowed file");
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
const destroy = () => {
|
|
98
|
+
removeExpressRoute(app, [fileRouteExpress]);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return { destroy };
|
|
102
|
+
};
|
|
@@ -329,7 +329,46 @@ BEGIN
|
|
|
329
329
|
END LOOP;
|
|
330
330
|
|
|
331
331
|
${raiseException(`E'No oneOf schemas matching:\n % ), %', v_one_of_errors, path`)}
|
|
332
|
+
|
|
333
|
+
/* tuple: [FieldType, FieldType, ...] */
|
|
334
|
+
ELSIF schema ? 'tuple' THEN
|
|
335
|
+
|
|
336
|
+
IF jsonb_typeof(schema->'tuple') != 'array' THEN
|
|
337
|
+
${raiseException(`'Invalid tuple schema. Expected tuple to be an array, got: %. %', jsonb_typeof(schema->'tuple'), path`)}
|
|
338
|
+
END IF;
|
|
332
339
|
|
|
340
|
+
IF jsonb_typeof(data) != 'array' THEN
|
|
341
|
+
${raiseException(`'Tuple data is not an array. %', path`)}
|
|
342
|
+
END IF;
|
|
343
|
+
|
|
344
|
+
IF jsonb_array_length(data) != jsonb_array_length(schema->'tuple') THEN
|
|
345
|
+
${raiseException(`'Tuple length does not match schema. Expected %, got %. %',
|
|
346
|
+
jsonb_array_length(schema->'tuple'),
|
|
347
|
+
jsonb_array_length(data),
|
|
348
|
+
path`)}
|
|
349
|
+
END IF;
|
|
350
|
+
|
|
351
|
+
FOR array_element IN
|
|
352
|
+
SELECT
|
|
353
|
+
data_item.value AS data_value,
|
|
354
|
+
tuple_item.value AS schema_value,
|
|
355
|
+
data_item.ordinality - 1 AS idx
|
|
356
|
+
FROM jsonb_array_elements(data) WITH ORDINALITY AS data_item(value, ordinality)
|
|
357
|
+
INNER JOIN jsonb_array_elements(schema->'tuple') WITH ORDINALITY AS tuple_item(value, ordinality)
|
|
358
|
+
ON data_item.ordinality = tuple_item.ordinality
|
|
359
|
+
LOOP
|
|
360
|
+
IF NOT ${VALIDATE_SCHEMA_FUNCNAME}(
|
|
361
|
+
array_element.schema_value::TEXT,
|
|
362
|
+
array_element.data_value,
|
|
363
|
+
context,
|
|
364
|
+
checked_path || array_element.idx::TEXT
|
|
365
|
+
) THEN
|
|
366
|
+
RETURN FALSE;
|
|
367
|
+
END IF;
|
|
368
|
+
END LOOP;
|
|
369
|
+
|
|
370
|
+
RETURN TRUE;
|
|
371
|
+
|
|
333
372
|
/* arrayOfType: { key_name: { type: "string" } } */
|
|
334
373
|
ELSIF (schema ? 'arrayOf' OR schema ? 'arrayOfType') THEN
|
|
335
374
|
|
package/lib/Logging.ts
CHANGED
|
@@ -164,7 +164,6 @@ export namespace EventTypes {
|
|
|
164
164
|
type: "debug";
|
|
165
165
|
command:
|
|
166
166
|
| "applyTableConfig"
|
|
167
|
-
| "initFileTable"
|
|
168
167
|
| "initTableConfig"
|
|
169
168
|
| "runSQLFile"
|
|
170
169
|
| "schemaChangeNotif"
|
|
@@ -174,8 +173,6 @@ export namespace EventTypes {
|
|
|
174
173
|
| "refreshDBO.end"
|
|
175
174
|
| "tableConfigurator.init.start"
|
|
176
175
|
| "tableConfigurator.init.end"
|
|
177
|
-
| "initFileTable.start"
|
|
178
|
-
| "initFileTable.end"
|
|
179
176
|
| "initFileManager.runQuery"
|
|
180
177
|
| "DboBuilder.getTablesForSchemaPostgresSQL"
|
|
181
178
|
| "PubSubManager.create";
|
package/lib/Prostgles.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type pgPromise from "pg-promise";
|
|
2
2
|
import { AuthHandler } from "./Auth/AuthHandler";
|
|
3
|
-
import { FileManager } from "./FileManager/FileManager";
|
|
4
3
|
import type { OnInitReason } from "./initProstgles";
|
|
5
4
|
import { initProstgles } from "./initProstgles";
|
|
6
5
|
import type { SchemaWatch } from "./SchemaWatch/SchemaWatch";
|
|
@@ -10,7 +9,7 @@ import pg = require("pg-promise/typescript/pg-subset");
|
|
|
10
9
|
|
|
11
10
|
import type { ProstglesInitOptions } from "./ProstglesTypes";
|
|
12
11
|
import { RestApi } from "./RestApi";
|
|
13
|
-
import TableConfigurator from "./TableConfig/
|
|
12
|
+
import { TableConfigurator } from "./TableConfig/TableConfigurator";
|
|
14
13
|
|
|
15
14
|
import type { PRGLIOSocket } from "./DboBuilder/DboBuilder";
|
|
16
15
|
import { DBHandlerServer, DboBuilder } from "./DboBuilder/DboBuilder";
|
|
@@ -59,8 +58,9 @@ const DEFAULT_KEYWORDS = {
|
|
|
59
58
|
|
|
60
59
|
import { randomUUID } from "crypto";
|
|
61
60
|
import * as fs from "fs";
|
|
62
|
-
import type { TableHandler } from "./DboBuilder/TableHandler/TableHandler";
|
|
63
61
|
import type { getAdminClient } from "./DboBuilder/runSql/getAdminClient";
|
|
62
|
+
import type { TableHandler } from "./DboBuilder/TableHandler/TableHandler";
|
|
63
|
+
import { getFileTableConfig } from "./FileManager/getFileTableConfig";
|
|
64
64
|
|
|
65
65
|
export class Prostgles {
|
|
66
66
|
/**
|
|
@@ -108,11 +108,14 @@ export class Prostgles {
|
|
|
108
108
|
dbEventsManager?: DBEventsManager;
|
|
109
109
|
schemaAge = "0";
|
|
110
110
|
|
|
111
|
-
fileManager?: FileManager;
|
|
112
111
|
restApi?: RestApi;
|
|
113
112
|
|
|
114
113
|
tableConfigurator?: TableConfigurator;
|
|
115
114
|
|
|
115
|
+
get mergedTableConfig() {
|
|
116
|
+
return getFileTableConfig(this);
|
|
117
|
+
}
|
|
118
|
+
|
|
116
119
|
isMedia(tableName: string) {
|
|
117
120
|
return this.opts.fileTable?.tableName === tableName;
|
|
118
121
|
}
|
|
@@ -147,6 +150,8 @@ export class Prostgles {
|
|
|
147
150
|
onLog: 1,
|
|
148
151
|
restApi: 1,
|
|
149
152
|
testRulesOnConnect: 1,
|
|
153
|
+
modifyClientSchema: 1,
|
|
154
|
+
expressApp: 1,
|
|
150
155
|
};
|
|
151
156
|
const unknownParams = Object.keys(params).filter(
|
|
152
157
|
(key: string) => !Object.keys(config).includes(key),
|
|
@@ -157,10 +162,6 @@ export class Prostgles {
|
|
|
157
162
|
|
|
158
163
|
this.opts = { ...this.opts, ...params };
|
|
159
164
|
|
|
160
|
-
/* set defaults */
|
|
161
|
-
if (this.opts.fileTable) {
|
|
162
|
-
this.opts.fileTable.tableName ??= "media";
|
|
163
|
-
}
|
|
164
165
|
this.opts.schemaFilter ??= { public: 1 };
|
|
165
166
|
|
|
166
167
|
this.keywords = {
|
|
@@ -195,10 +196,8 @@ export class Prostgles {
|
|
|
195
196
|
if (this.opts.tsGeneratedTypesDir) {
|
|
196
197
|
const { fullPath, fileName } = this.getTSFileName();
|
|
197
198
|
const { tsSchema: fileContent } = this.dboBuilder.getTsDefinitions();
|
|
198
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
199
199
|
fs.readFile(fullPath, "utf8", function (err, data) {
|
|
200
200
|
if (err || force || data !== fileContent) {
|
|
201
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
202
201
|
fs.writeFileSync(fullPath, fileContent);
|
|
203
202
|
console.log("Prostgles: Created typescript schema definition file: \n " + fileName);
|
|
204
203
|
}
|
|
@@ -285,39 +284,6 @@ export class Prostgles {
|
|
|
285
284
|
return res.data;
|
|
286
285
|
};
|
|
287
286
|
|
|
288
|
-
/* Create media table if required */
|
|
289
|
-
initFileTable = async () => {
|
|
290
|
-
const res = await tryCatchV2(async () => {
|
|
291
|
-
if (this.opts.fileTable) {
|
|
292
|
-
const { cloudClient, localConfig, imageOptions } = this.opts.fileTable;
|
|
293
|
-
await this.refreshDBO();
|
|
294
|
-
if (!cloudClient && !localConfig)
|
|
295
|
-
throw "fileTable missing param: Must provide awsS3Config OR localConfig";
|
|
296
|
-
|
|
297
|
-
this.fileManager = new FileManager(cloudClient || localConfig!, imageOptions);
|
|
298
|
-
|
|
299
|
-
try {
|
|
300
|
-
await this.fileManager.init(this);
|
|
301
|
-
} catch (e) {
|
|
302
|
-
console.error("FileManager: ", e);
|
|
303
|
-
this.fileManager = undefined;
|
|
304
|
-
}
|
|
305
|
-
} else {
|
|
306
|
-
this.fileManager?.destroy();
|
|
307
|
-
this.fileManager = undefined;
|
|
308
|
-
}
|
|
309
|
-
await this.refreshDBO();
|
|
310
|
-
return { data: {} };
|
|
311
|
-
});
|
|
312
|
-
await this.opts.onLog?.({
|
|
313
|
-
type: "debug",
|
|
314
|
-
command: "initFileTable",
|
|
315
|
-
...res,
|
|
316
|
-
});
|
|
317
|
-
if (res.error !== undefined) throw res.error;
|
|
318
|
-
return res.data;
|
|
319
|
-
};
|
|
320
|
-
|
|
321
287
|
isSuperUser = false;
|
|
322
288
|
|
|
323
289
|
init = initProstgles.bind(this);
|
|
@@ -365,7 +331,6 @@ export async function getIsSuperUser(db: DBorTx): Promise<boolean> {
|
|
|
365
331
|
|
|
366
332
|
export const getFileText = (fullPath: string, _format = "utf8"): Promise<string> => {
|
|
367
333
|
return new Promise((resolve, reject) => {
|
|
368
|
-
// eslint-disable-next-line security/detect-non-literal-fs-filename
|
|
369
334
|
fs.readFile(fullPath, "utf8", function (err, data) {
|
|
370
335
|
if (err) reject(err);
|
|
371
336
|
else resolve(data);
|
package/lib/ProstglesTypes.ts
CHANGED
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import type { FileColumnConfig } from "prostgles-types";
|
|
2
|
-
import type {
|
|
1
|
+
import type { DBSchemaTable, FileColumnConfig, MaybePromise } from "prostgles-types";
|
|
2
|
+
import type {
|
|
3
|
+
AuthConfig,
|
|
4
|
+
AuthRequestParams,
|
|
5
|
+
AuthResultWithSID,
|
|
6
|
+
SessionUser,
|
|
7
|
+
} from "./Auth/AuthTypes";
|
|
3
8
|
import type { EventTriggerTagFilter } from "./Event_Trigger_Tags";
|
|
4
|
-
import type {
|
|
9
|
+
import type { StorageClient } from "./FileManager/FileManager";
|
|
5
10
|
import type { DbConnection, OnReadyCallback } from "./initProstgles";
|
|
6
11
|
import type { EventInfo } from "./Logging";
|
|
7
12
|
import type { ExpressApp, RestApiConfig } from "./RestApi";
|
|
8
13
|
import type { OnSchemaChangeCallback } from "./SchemaWatch/SchemaWatch";
|
|
9
14
|
import type { PGConstraint } from "./TableConfig/fetchTableConstraints";
|
|
10
|
-
import type { TableConfig } from "./TableConfig/
|
|
11
|
-
import type { Express } from "express";
|
|
15
|
+
import type { TableConfig } from "./TableConfig/TableConfigTypes";
|
|
12
16
|
|
|
13
17
|
import type { PRGLIOSocket } from "./DboBuilder/DboBuilder";
|
|
14
18
|
|
|
@@ -16,8 +20,8 @@ import type pgPromise from "pg-promise";
|
|
|
16
20
|
import type pg from "pg-promise/typescript/pg-subset";
|
|
17
21
|
import type { AnyObject } from "prostgles-types";
|
|
18
22
|
import type { Server } from "socket.io";
|
|
19
|
-
import type { Awaitable, Publish, PublishParams } from "./PublishParser/PublishParser";
|
|
20
23
|
import type { ServerFunctionDefinitions } from "./PublishParser/defineServerFunction";
|
|
24
|
+
import type { Awaitable, Publish, PublishParams } from "./PublishParser/PublishParser";
|
|
21
25
|
|
|
22
26
|
/**
|
|
23
27
|
* Allows uploading and downloading files.
|
|
@@ -37,9 +41,8 @@ import type { ServerFunctionDefinitions } from "./PublishParser/defineServerFunc
|
|
|
37
41
|
export type FileTableConfig = {
|
|
38
42
|
/**
|
|
39
43
|
* Name of the table that will contain the file metadata.
|
|
40
|
-
* Defaults to "files"
|
|
41
44
|
*/
|
|
42
|
-
tableName
|
|
45
|
+
tableName: string;
|
|
43
46
|
|
|
44
47
|
/**
|
|
45
48
|
* GET path used in serving media. defaults to /${tableName}
|
|
@@ -57,16 +60,11 @@ export type FileTableConfig = {
|
|
|
57
60
|
*/
|
|
58
61
|
deleteAfterNDays: number;
|
|
59
62
|
/**
|
|
60
|
-
* How
|
|
63
|
+
* How frequently the files will be checked for deletion delay
|
|
61
64
|
*/
|
|
62
65
|
checkIntervalHours?: number;
|
|
63
66
|
};
|
|
64
67
|
|
|
65
|
-
/**
|
|
66
|
-
* Express server instance
|
|
67
|
-
*/
|
|
68
|
-
expressApp: ExpressApp | Express;
|
|
69
|
-
|
|
70
68
|
/**
|
|
71
69
|
* Specifying referencedTables with referenceColumns allows restricting the
|
|
72
70
|
* allowed file types that can be inserted and referenced in the specified tables.
|
|
@@ -78,18 +76,12 @@ export type FileTableConfig = {
|
|
|
78
76
|
* */
|
|
79
77
|
{ type: "column"; referenceColumns: Record<string, FileColumnConfig> };
|
|
80
78
|
};
|
|
81
|
-
imageOptions?: ImageOptions;
|
|
82
79
|
|
|
83
80
|
/**
|
|
84
81
|
* Callbacks for file upload and download.
|
|
85
82
|
* Used for custom file handling.
|
|
86
83
|
*/
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
/**
|
|
90
|
-
* Local file storage configuration.
|
|
91
|
-
*/
|
|
92
|
-
localConfig?: LocalConfig;
|
|
84
|
+
storageClient: StorageClient;
|
|
93
85
|
};
|
|
94
86
|
|
|
95
87
|
export const JOIN_TYPES = ["one-many", "many-one", "one-one", "many-many"] as const;
|
|
@@ -100,6 +92,11 @@ export type Join = {
|
|
|
100
92
|
};
|
|
101
93
|
type Joins = Join[] | "inferred";
|
|
102
94
|
|
|
95
|
+
type ModifyClientSchema<SUser extends SessionUser = SessionUser> = (
|
|
96
|
+
tables: DBSchemaTable,
|
|
97
|
+
userData: AuthResultWithSID<SUser> | undefined,
|
|
98
|
+
) => MaybePromise<DBSchemaTable>;
|
|
99
|
+
|
|
103
100
|
export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUser> = {
|
|
104
101
|
/**
|
|
105
102
|
* Database connection details and options
|
|
@@ -129,6 +126,14 @@ export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUs
|
|
|
129
126
|
*/
|
|
130
127
|
io?: Server;
|
|
131
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Express server instance used for:
|
|
131
|
+
* - Auth
|
|
132
|
+
* - REST API
|
|
133
|
+
* - Serving files through the file manager
|
|
134
|
+
*/
|
|
135
|
+
expressApp?: ExpressApp;
|
|
136
|
+
|
|
132
137
|
/**
|
|
133
138
|
* Rest API configuration.
|
|
134
139
|
* The REST API allows interacting with the database similarly to the websocket connection.
|
|
@@ -189,7 +194,7 @@ export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUs
|
|
|
189
194
|
|
|
190
195
|
/**
|
|
191
196
|
* Allows defining table relationships that can then be used in filters and data inserts:
|
|
192
|
-
* - `
|
|
197
|
+
* - `inferred` - uses the foreign keys to infer the joins
|
|
193
198
|
* - `Join[]` - specifies the joins manually
|
|
194
199
|
*/
|
|
195
200
|
joins?: Joins;
|
|
@@ -307,9 +312,15 @@ export type ProstglesInitOptions<S = void, SUser extends SessionUser = SessionUs
|
|
|
307
312
|
tableConfigMigrations?: TableConfigMigrations;
|
|
308
313
|
|
|
309
314
|
/**
|
|
310
|
-
*
|
|
315
|
+
* Useful for logging or debugging
|
|
311
316
|
*/
|
|
312
317
|
onLog?: (evt: EventInfo) => Promise<void> | void;
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Used to add custom metadata to the table and column schemas.
|
|
321
|
+
* This metadata is then available in the client schema and can be used for custom logic on the client side.
|
|
322
|
+
*/
|
|
323
|
+
modifyClientSchema?: ModifyClientSchema<SUser>;
|
|
313
324
|
};
|
|
314
325
|
|
|
315
326
|
export type TableConfigMigrations = {
|
|
@@ -15,8 +15,6 @@ export async function notifListener(this: PubSubManager, data: { payload: string
|
|
|
15
15
|
const dataArr = str.split(DELIMITER);
|
|
16
16
|
const notifType = dataArr[0] as NotifTypeName;
|
|
17
17
|
|
|
18
|
-
log(str);
|
|
19
|
-
|
|
20
18
|
const commonLog = {
|
|
21
19
|
triggers: this._triggers,
|
|
22
20
|
sid: undefined,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getObjectEntries, includes, type DBSchemaTable } from "prostgles-types";
|
|
2
|
-
import type { AuthClientRequest } from "../Auth/AuthTypes";
|
|
2
|
+
import type { AuthClientRequest, AuthResultWithSID } from "../Auth/AuthTypes";
|
|
3
3
|
import { getErrorAsObject } from "../DboBuilder/dboBuilderUtils";
|
|
4
4
|
import type { TableHandler } from "../DboBuilder/TableHandler/TableHandler";
|
|
5
5
|
import { TABLE_METHODS } from "../Prostgles";
|
|
@@ -11,6 +11,7 @@ export const getDBSchemaTable = async (
|
|
|
11
11
|
tableHandler: TableHandler,
|
|
12
12
|
parsedTableRule: ParsedTableRule,
|
|
13
13
|
clientReq: AuthClientRequest,
|
|
14
|
+
clientInfo: AuthResultWithSID | undefined,
|
|
14
15
|
scope: PermissionScope | undefined,
|
|
15
16
|
): Promise<DBSchemaTable> => {
|
|
16
17
|
const tableName = tableHandler.name;
|
|
@@ -20,11 +21,13 @@ export const getDBSchemaTable = async (
|
|
|
20
21
|
}
|
|
21
22
|
const info = await tableHandler.getInfo(undefined, undefined, undefined, parsedTableRule, {
|
|
22
23
|
...clientReq,
|
|
23
|
-
isRemoteRequest: {
|
|
24
|
+
isRemoteRequest: {
|
|
25
|
+
clientInfo,
|
|
26
|
+
},
|
|
24
27
|
});
|
|
25
28
|
const columns = await tableHandler.getColumns(undefined, undefined, undefined, parsedTableRule, {
|
|
26
29
|
...clientReq,
|
|
27
|
-
isRemoteRequest: {},
|
|
30
|
+
isRemoteRequest: { clientInfo },
|
|
28
31
|
});
|
|
29
32
|
const allowedCommands = getAllowedTableMethods(info);
|
|
30
33
|
for (const method of allowedCommands) {
|
|
@@ -45,7 +45,7 @@ export async function getSchemaFromPublish(
|
|
|
45
45
|
* Add file table to the list of published tables if it's referenced by other published tables.
|
|
46
46
|
* Access to the file table is controlled through the publish rules of the tables referencing it.
|
|
47
47
|
*/
|
|
48
|
-
const fileTableName = this.prostgles.
|
|
48
|
+
const fileTableName = this.prostgles.opts.fileTable?.tableName;
|
|
49
49
|
if (fileTableName && this.dbo[fileTableName]?.is_media && !tableNames.includes(fileTableName)) {
|
|
50
50
|
const isReferenced = this.prostgles.dboBuilder.tablesOrViews?.some((t) =>
|
|
51
51
|
t.columns.some((c) => c.references?.some((r) => r.ftable === fileTableName)),
|
|
@@ -83,6 +83,7 @@ export async function getSchemaFromPublish(
|
|
|
83
83
|
tableHandler,
|
|
84
84
|
parsedTableRule,
|
|
85
85
|
clientReq,
|
|
86
|
+
clientInfo,
|
|
86
87
|
scope,
|
|
87
88
|
);
|
|
88
89
|
tables.push(tableSchema);
|