prostgles-server 2.0.189 → 2.0.192
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/DboBuilder/insertDataParse.d.ts.map +1 -1
- package/dist/DboBuilder/insertDataParse.js +12 -3
- package/dist/DboBuilder/insertDataParse.js.map +1 -1
- package/dist/DboBuilder.d.ts +5 -4
- package/dist/DboBuilder.d.ts.map +1 -1
- package/dist/DboBuilder.js +54 -153
- package/dist/DboBuilder.js.map +1 -1
- package/dist/FileManager.d.ts +20 -72
- package/dist/FileManager.d.ts.map +1 -1
- package/dist/FileManager.js +233 -164
- package/dist/FileManager.js.map +1 -1
- package/dist/PostgresNotifListenManager.d.ts.map +1 -1
- package/dist/PostgresNotifListenManager.js +3 -1
- package/dist/PostgresNotifListenManager.js.map +1 -1
- package/dist/Prostgles.d.ts +13 -2
- package/dist/Prostgles.d.ts.map +1 -1
- package/dist/Prostgles.js +8 -4
- package/dist/Prostgles.js.map +1 -1
- package/dist/TableConfig.d.ts +1 -2
- package/dist/TableConfig.d.ts.map +1 -1
- package/dist/TableConfig.js.map +1 -1
- package/lib/DboBuilder/insertDataParse.d.ts.map +1 -1
- package/lib/DboBuilder/insertDataParse.js +12 -3
- package/lib/DboBuilder/insertDataParse.ts +12 -3
- package/lib/DboBuilder.d.ts +5 -4
- package/lib/DboBuilder.d.ts.map +1 -1
- package/lib/DboBuilder.js +54 -153
- package/lib/DboBuilder.ts +67 -181
- package/lib/FileManager.d.ts +19 -71
- package/lib/FileManager.d.ts.map +1 -1
- package/lib/FileManager.js +233 -164
- package/lib/FileManager.ts +274 -191
- package/lib/PostgresNotifListenManager.d.ts.map +1 -1
- package/lib/PostgresNotifListenManager.js +3 -1
- package/lib/PostgresNotifListenManager.ts +4 -1
- package/lib/Prostgles.d.ts +13 -2
- package/lib/Prostgles.d.ts.map +1 -1
- package/lib/Prostgles.js +8 -4
- package/lib/Prostgles.ts +9 -5
- package/lib/TableConfig.d.ts +1 -2
- package/lib/TableConfig.d.ts.map +1 -1
- package/lib/TableConfig.ts +2 -4
- package/lib/fileType/core.js +1527 -0
- package/lib/fileType/supported.js +278 -0
- package/package.json +3 -3
- package/tests/client/PID.txt +1 -1
- package/tests/server/DBoGenerated.d.ts +1 -1
- package/tests/server/package-lock.json +5 -5
package/lib/FileManager.js
CHANGED
|
@@ -23,12 +23,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.asSQLIdentifier = void 0;
|
|
26
|
+
exports.getFileType = exports.getFileTypeFromFilename = exports.asSQLIdentifier = void 0;
|
|
27
27
|
const aws_sdk_1 = require("aws-sdk");
|
|
28
28
|
const fs = __importStar(require("fs"));
|
|
29
|
-
const FileType = __importStar(require("file-type"));
|
|
30
29
|
const sharp = __importStar(require("sharp"));
|
|
31
30
|
const prostgles_types_1 = require("prostgles-types");
|
|
31
|
+
const DboBuilder_1 = require("./DboBuilder");
|
|
32
32
|
const HOUR = 3600 * 1000;
|
|
33
33
|
const asSQLIdentifier = async (name, db) => {
|
|
34
34
|
return (await db.one("select format('%I', $1) as name", [name]))?.name;
|
|
@@ -81,6 +81,18 @@ class FileManager {
|
|
|
81
81
|
return res;
|
|
82
82
|
};
|
|
83
83
|
this.parseSQLIdentifier = async (name) => (0, exports.asSQLIdentifier)(name, this.prostgles.db); // this.prostgles.dbo.sql<"value">("select format('%I', $1)", [name], { returnType: "value" } )
|
|
84
|
+
this.getColInfo = (args) => {
|
|
85
|
+
const { colName, tableName } = args;
|
|
86
|
+
const tableConfig = this.prostgles?.opts.fileTable?.referencedTables?.[tableName];
|
|
87
|
+
const isReferencingFileTable = this.dbo[tableName]?.columns?.some(c => c.name === colName && c.references && c.references?.ftable === this.tableName);
|
|
88
|
+
if (isReferencingFileTable) {
|
|
89
|
+
if (tableConfig && typeof tableConfig !== "string") {
|
|
90
|
+
return tableConfig.referenceColumns[colName];
|
|
91
|
+
}
|
|
92
|
+
return { acceptedContent: "*" };
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
};
|
|
84
96
|
this.init = async (prg) => {
|
|
85
97
|
this.prostgles = prg;
|
|
86
98
|
// const { dbo, db, opts } = prg;
|
|
@@ -91,6 +103,7 @@ class FileManager {
|
|
|
91
103
|
this.tableName = tableName;
|
|
92
104
|
const maxBfSizeMB = (prg.opts.io?.engine?.opts?.maxHttpBufferSize || 1e6) / 1e6;
|
|
93
105
|
console.log(`Prostgles: Initiated file manager. Max allowed file size: ${maxBfSizeMB}MB (maxHttpBufferSize = 1e6). To increase this set maxHttpBufferSize in socket.io server init options`);
|
|
106
|
+
// throw `this.db.tx(d => do everything in a transaction pls!!!!`;
|
|
94
107
|
// throw "Why are constraints dissapearing?"
|
|
95
108
|
/**
|
|
96
109
|
* 1. Create media table
|
|
@@ -121,56 +134,96 @@ class FileManager {
|
|
|
121
134
|
/**
|
|
122
135
|
* 2. Create media lookup tables
|
|
123
136
|
*/
|
|
124
|
-
await Promise.all(
|
|
137
|
+
await Promise.all((0, prostgles_types_1.getKeys)(referencedTables).map(async (refTable) => {
|
|
125
138
|
if (!this.dbo[refTable])
|
|
126
|
-
throw `Referenced table (${refTable}) from fileTable.referencedTables
|
|
127
|
-
|
|
128
|
-
const
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
` This may have been caused by a DROP TABLE ... CASCADE.`);
|
|
153
|
-
let q = `
|
|
154
|
-
ALTER TABLE ${(0, prostgles_types_1.asName)(lookupTableName)}
|
|
155
|
-
ADD CONSTRAINT ${(lookupTableName + "_" + badCol.name + "_r")} FOREIGN KEY (${badCol.name})
|
|
156
|
-
`;
|
|
157
|
-
console.log("Trying to add the missing constraint back");
|
|
158
|
-
if (badCol.name === "foreign_id") {
|
|
159
|
-
q += `REFERENCES ${(0, prostgles_types_1.asName)(refTable)}(${(0, prostgles_types_1.asName)(pkField.name)}) `;
|
|
160
|
-
}
|
|
161
|
-
else if (badCol.name === "media_id") {
|
|
162
|
-
q += `REFERENCES ${(0, prostgles_types_1.asName)(tableName)}(id) `;
|
|
139
|
+
throw `Referenced table (${refTable}) from fileTable.referencedTables prostgles init config is missing`;
|
|
140
|
+
const cols = await this.dbo[refTable].getColumns();
|
|
141
|
+
const tableConfig = referencedTables[refTable];
|
|
142
|
+
if (typeof tableConfig !== "string") {
|
|
143
|
+
for await (const colName of (0, prostgles_types_1.getKeys)(tableConfig.referenceColumns)) {
|
|
144
|
+
const existingCol = cols.find(c => c.name === colName);
|
|
145
|
+
if (existingCol) {
|
|
146
|
+
if (existingCol.references?.ftable === tableName) {
|
|
147
|
+
// All ok
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
if (existingCol.udt_name === "uuid") {
|
|
151
|
+
try {
|
|
152
|
+
const query = `ALTER TABLE ${(0, prostgles_types_1.asName)(tableName)} ADD CONSTRAINT FOREIGN KEY (${(0, prostgles_types_1.asName)(colName)}) REFERENCES ${(0, prostgles_types_1.asName)(tableName)} (id);`;
|
|
153
|
+
console.log(`Referenced file column ${refTable} (${colName}) exists but is not referencing file table. Trying to add REFERENCE constraing...\n${query}`);
|
|
154
|
+
await this.db.any(query);
|
|
155
|
+
console.log("SUCCESS: " + query);
|
|
156
|
+
}
|
|
157
|
+
catch (e) {
|
|
158
|
+
throw new Error(`Could not add constraing. Err: ${e instanceof Error ? e.message : JSON.stringify(e)}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
throw new Error(`Referenced file column ${refTable} (${colName}) exists but is not of required type (UUID). Choose a different column name or ALTER the existing column to match the type and the data found in file table ${tableName}(id)`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
163
165
|
}
|
|
164
|
-
|
|
166
|
+
else {
|
|
165
167
|
try {
|
|
166
|
-
|
|
167
|
-
console.log(
|
|
168
|
+
const query = `ALTER TABLE ${(0, prostgles_types_1.asName)(tableName)} ADD COLUMN ${(0, prostgles_types_1.asName)(colName)} UUID REFERENCES ${(0, prostgles_types_1.asName)(tableName)} (id);`;
|
|
169
|
+
console.log(`Creating referenced file column ${refTable} (${colName})...\n${query}`);
|
|
170
|
+
await this.db.any(query);
|
|
171
|
+
console.log("SUCCESS: " + query);
|
|
168
172
|
}
|
|
169
173
|
catch (e) {
|
|
170
|
-
|
|
174
|
+
throw new Error(`FAILED. Err: ${e instanceof Error ? e.message : JSON.stringify(e)}`);
|
|
171
175
|
}
|
|
172
176
|
}
|
|
173
|
-
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
else {
|
|
180
|
+
const lookupTableName = await this.parseSQLIdentifier(`prostgles_lookup_${tableName}_${refTable}`);
|
|
181
|
+
const pKeyFields = cols.filter(f => f.is_pkey);
|
|
182
|
+
if (pKeyFields.length !== 1)
|
|
183
|
+
throw `Could not make link table for ${refTable}. ${pKeyFields} must have exactly one primary key column. Current pkeys: ${pKeyFields.map(f => f.name)}`;
|
|
184
|
+
const pkField = pKeyFields[0];
|
|
185
|
+
const refType = referencedTables[refTable];
|
|
186
|
+
if (!this.dbo[lookupTableName]) {
|
|
187
|
+
// if(!(await dbo[lookupTableName].count())) await db.any(`DROP TABLE IF EXISTS ${lookupTableName};`);
|
|
188
|
+
const action = ` (${tableName} <-> ${refTable}) join table ${lookupTableName}`; // PRIMARY KEY
|
|
189
|
+
const query = `
|
|
190
|
+
CREATE TABLE ${lookupTableName} (
|
|
191
|
+
foreign_id ${pkField.udt_name} ${refType === "one" ? " PRIMARY KEY " : ""} REFERENCES ${(0, prostgles_types_1.asName)(refTable)}(${(0, prostgles_types_1.asName)(pkField.name)}),
|
|
192
|
+
media_id UUID NOT NULL REFERENCES ${(0, prostgles_types_1.asName)(tableName)}(id)
|
|
193
|
+
)
|
|
194
|
+
`;
|
|
195
|
+
console.log(`Creating ${action} ...`, lookupTableName);
|
|
196
|
+
await this.db.any(query);
|
|
197
|
+
console.log(`Created ${action}`);
|
|
198
|
+
}
|
|
199
|
+
else {
|
|
200
|
+
const cols = await this.dbo[lookupTableName].getColumns();
|
|
201
|
+
const badCols = cols.filter(c => !c.references);
|
|
202
|
+
await Promise.all(badCols.map(async (badCol) => {
|
|
203
|
+
console.error(`Prostgles: media ${lookupTableName} joining table has lost a reference constraint for column ${badCol.name}.` +
|
|
204
|
+
` This may have been caused by a DROP TABLE ... CASCADE.`);
|
|
205
|
+
let q = `
|
|
206
|
+
ALTER TABLE ${(0, prostgles_types_1.asName)(lookupTableName)}
|
|
207
|
+
ADD CONSTRAINT ${(lookupTableName + "_" + badCol.name + "_r")} FOREIGN KEY (${badCol.name})
|
|
208
|
+
`;
|
|
209
|
+
console.log("Trying to add the missing constraint back");
|
|
210
|
+
if (badCol.name === "foreign_id") {
|
|
211
|
+
q += `REFERENCES ${(0, prostgles_types_1.asName)(refTable)}(${(0, prostgles_types_1.asName)(pkField.name)}) `;
|
|
212
|
+
}
|
|
213
|
+
else if (badCol.name === "media_id") {
|
|
214
|
+
q += `REFERENCES ${(0, prostgles_types_1.asName)(tableName)}(id) `;
|
|
215
|
+
}
|
|
216
|
+
if (q) {
|
|
217
|
+
try {
|
|
218
|
+
await this.db.any(q);
|
|
219
|
+
console.log("Added missing constraint back");
|
|
220
|
+
}
|
|
221
|
+
catch (e) {
|
|
222
|
+
console.error("Failed to add missing constraint", e);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}));
|
|
226
|
+
}
|
|
174
227
|
}
|
|
175
228
|
await prg.refreshDBO();
|
|
176
229
|
return true;
|
|
@@ -251,63 +304,108 @@ class FileManager {
|
|
|
251
304
|
return this.prostgles.db;
|
|
252
305
|
}
|
|
253
306
|
;
|
|
254
|
-
async
|
|
255
|
-
const
|
|
256
|
-
const
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
307
|
+
async parseFile(args) {
|
|
308
|
+
const { file, fileName, tableName, colName } = args;
|
|
309
|
+
const config = this.prostgles?.opts.fileTable;
|
|
310
|
+
if (!config)
|
|
311
|
+
throw new Error("File table config missing");
|
|
312
|
+
const buffer = typeof file === "string" ? Buffer.from(file, 'utf8') : file;
|
|
313
|
+
const mime = await (0, exports.getFileType)(buffer, fileName);
|
|
314
|
+
if (tableName && colName) {
|
|
315
|
+
const tableConfig = config.referencedTables?.[tableName];
|
|
316
|
+
if (tableConfig && (0, prostgles_types_1.isObject)(tableConfig) && tableConfig.referenceColumns[colName]) {
|
|
317
|
+
const colConfig = tableConfig.referenceColumns[colName];
|
|
318
|
+
if (colConfig.maxFileSizeMB) {
|
|
319
|
+
const actualBufferSize = Buffer.byteLength(buffer);
|
|
320
|
+
if ((actualBufferSize / 1e6) > colConfig.maxFileSizeMB) {
|
|
321
|
+
throw new Error(`Provided file is larger than the ${colConfig.maxFileSizeMB}MB limit`);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
if ("acceptedContent" in colConfig && colConfig.acceptedContent) {
|
|
325
|
+
const CONTENTS = [
|
|
326
|
+
"image",
|
|
327
|
+
"audio",
|
|
328
|
+
"video",
|
|
329
|
+
"text",
|
|
330
|
+
"application",
|
|
331
|
+
];
|
|
332
|
+
const allowedContent = DboBuilder_1.ViewHandler._parseFieldFilter(colConfig.acceptedContent, false, CONTENTS);
|
|
333
|
+
if (!allowedContent.some(c => mime.mime.startsWith(c))) {
|
|
334
|
+
throw new Error(`Dissallowed content type provided: ${mime.mime.split("/")[0]}. Allowed content types: ${allowedContent} `);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
else if ("acceptedContentType" in colConfig && colConfig.acceptedContentType) {
|
|
338
|
+
const allowedContentTypes = DboBuilder_1.ViewHandler._parseFieldFilter(colConfig.acceptedContentType, false, (0, prostgles_types_1.getKeys)(prostgles_types_1.CONTENT_TYPE_TO_EXT));
|
|
339
|
+
if (!allowedContentTypes.some(c => c === mime.mime)) {
|
|
340
|
+
throw new Error(`Dissallowed MIME provided: ${mime.mime}. Allowed MIME values: ${allowedContentTypes} `);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
else if ("acceptedFileTypes" in colConfig && colConfig.acceptedFileTypes) {
|
|
344
|
+
const allowedExtensions = DboBuilder_1.ViewHandler._parseFieldFilter(colConfig.acceptedFileTypes, false, Object.values(prostgles_types_1.CONTENT_TYPE_TO_EXT).flat());
|
|
345
|
+
if (!allowedExtensions.some(c => c === mime.ext)) {
|
|
346
|
+
throw new Error(`Dissallowed extension provided: ${mime.ext}. Allowed extension values: ${allowedExtensions} `);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
288
349
|
}
|
|
289
350
|
}
|
|
290
|
-
|
|
291
|
-
!allowedExtensions.map(v => v.toLowerCase())?.includes(type.ext)) {
|
|
292
|
-
throw fileName + " -> File type ( " + type.ext + " ) not allowed. Expecting one of: " + allowedExtensions.map(v => v.toLowerCase()).join(", ");
|
|
293
|
-
}
|
|
294
|
-
else if (dissallowedExtensions &&
|
|
295
|
-
dissallowedExtensions.map(v => v.toLowerCase())?.includes(type.ext)) {
|
|
296
|
-
throw fileName + " -> File type ( " + type.ext + " ) not allowed";
|
|
297
|
-
}
|
|
298
|
-
if (!onlyFromName) {
|
|
299
|
-
let { ext } = type;
|
|
300
|
-
if (nameExt !== ext)
|
|
301
|
-
fileName = nameParts.slice(0, -1).join('') + "." + ext;
|
|
302
|
-
}
|
|
303
|
-
const res = {
|
|
304
|
-
...type,
|
|
305
|
-
fileName
|
|
306
|
-
};
|
|
307
|
-
if (!res.mime)
|
|
308
|
-
throw "Could not find mime";
|
|
309
|
-
return res;
|
|
351
|
+
return mime;
|
|
310
352
|
}
|
|
353
|
+
// private async getMIME(
|
|
354
|
+
// file: Buffer | string,
|
|
355
|
+
// fileName: string,
|
|
356
|
+
// allowedExtensions?: Array<ALLOWED_EXTENSION>,
|
|
357
|
+
// dissallowedExtensions?: Array<ALLOWED_EXTENSION>,
|
|
358
|
+
// onlyFromName = true
|
|
359
|
+
// ): Promise<{
|
|
360
|
+
// mime: string;
|
|
361
|
+
// ext: string | ALLOWED_EXTENSION;
|
|
362
|
+
// fileName: string;
|
|
363
|
+
// }> {
|
|
364
|
+
// const nameParts = fileName.split(".");
|
|
365
|
+
// const nameExt = nameParts[nameParts.length - 1].toLowerCase(),
|
|
366
|
+
// mime = getKeys(CONTENT_TYPE_TO_EXT).find(k => (CONTENT_TYPE_TO_EXT[k] as readonly string[]).includes(nameExt));
|
|
367
|
+
// let type = {
|
|
368
|
+
// fileName,
|
|
369
|
+
// mime,
|
|
370
|
+
// ext: nameExt,
|
|
371
|
+
// }
|
|
372
|
+
// if(onlyFromName && !mime) throw `Invalid file extension: content_type could not be found for extension(${nameExt})`;
|
|
373
|
+
// if(!mime){
|
|
374
|
+
// /* Set correct/missing extension */
|
|
375
|
+
// if(["xml", "txt", "csv", "tsv"].includes(nameExt)){
|
|
376
|
+
// type = { ...type, mime: ("text/" + nameExt) as any, ext: nameExt };
|
|
377
|
+
// } else if(["svg"].includes(nameExt)){
|
|
378
|
+
// type = { ...type, mime: "image/svg+xml", ext: nameExt };
|
|
379
|
+
// } else {
|
|
380
|
+
// const res = await getFileTypeFromBuffer(file);
|
|
381
|
+
// type = {
|
|
382
|
+
// ...(res as any),
|
|
383
|
+
// fileName,
|
|
384
|
+
// }
|
|
385
|
+
// }
|
|
386
|
+
// }
|
|
387
|
+
// if(
|
|
388
|
+
// allowedExtensions &&
|
|
389
|
+
// !allowedExtensions.map(v => v.toLowerCase())?.includes(type.ext)
|
|
390
|
+
// ){
|
|
391
|
+
// throw fileName + " -> File type ( " + type.ext + " ) not allowed. Expecting one of: " + allowedExtensions.map(v => v.toLowerCase()).join(", ");
|
|
392
|
+
// } else if(
|
|
393
|
+
// dissallowedExtensions &&
|
|
394
|
+
// dissallowedExtensions.map(v => v.toLowerCase())?.includes(type.ext)
|
|
395
|
+
// ){
|
|
396
|
+
// throw fileName + " -> File type ( " + type.ext + " ) not allowed";
|
|
397
|
+
// }
|
|
398
|
+
// if(!onlyFromName){
|
|
399
|
+
// let { ext } = type;
|
|
400
|
+
// if(nameExt !== ext) fileName = nameParts.slice(0, -1).join('') + "." + ext;
|
|
401
|
+
// }
|
|
402
|
+
// const res = {
|
|
403
|
+
// ...type,
|
|
404
|
+
// fileName
|
|
405
|
+
// }
|
|
406
|
+
// if(!res.mime) throw "Could not find mime"
|
|
407
|
+
// return res as any;
|
|
408
|
+
// }
|
|
311
409
|
// async getUploadURL(fileName: string): Promise<string> {
|
|
312
410
|
// const thisHour = new Date();
|
|
313
411
|
// thisHour.setMilliseconds(0);
|
|
@@ -391,72 +489,43 @@ class FileManager {
|
|
|
391
489
|
}
|
|
392
490
|
}
|
|
393
491
|
exports.default = FileManager;
|
|
394
|
-
const
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
"
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
"
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
"application/x-java-archive-diff": ["jardiff"],
|
|
430
|
-
"application/x-java-jnlp-file": ["jnlp"],
|
|
431
|
-
"application/x-makeself": ["run"],
|
|
432
|
-
"application/x-perl": ["pl", "pm"],
|
|
433
|
-
"application/x-pilot": ["prc", "pdb"],
|
|
434
|
-
"application/x-rar-compressed": ["rar"],
|
|
435
|
-
"application/x-redhat-package-manager": ["rpm"],
|
|
436
|
-
"application/x-sea": ["sea"],
|
|
437
|
-
"application/x-shockwave-flash": ["swf"],
|
|
438
|
-
"application/x-stuffit": ["sit"],
|
|
439
|
-
"application/x-tcl": ["tcl", "tk"],
|
|
440
|
-
"application/x-x509-ca-cert": ["der", "pem", "crt"],
|
|
441
|
-
"application/x-xpinstall": ["xpi"],
|
|
442
|
-
"application/xhtml+xml": ["xhtml"],
|
|
443
|
-
"application/zip": ["zip"],
|
|
444
|
-
"application/octet-stream": ["bin", "exe", "dll", "deb", "dmg", "eot", "iso", "img", "msi", "msp", "msm"],
|
|
445
|
-
"audio/midi": ["mid", "midi", "kar"],
|
|
446
|
-
"audio/mpeg": ["mp3"],
|
|
447
|
-
"audio/ogg": ["ogg"],
|
|
448
|
-
"audio/x-realaudio": ["ra"],
|
|
449
|
-
"video/3gpp": ["3gpp", "3gp"],
|
|
450
|
-
"video/mpeg": ["mpeg", "mpg"],
|
|
451
|
-
"video/quicktime": ["mov"],
|
|
452
|
-
"video/x-flv": ["flv"],
|
|
453
|
-
"video/x-mng": ["mng"],
|
|
454
|
-
"video/x-ms-asf": ["asx", "asf"],
|
|
455
|
-
"video/x-ms-wmv": ["wmv"],
|
|
456
|
-
"video/x-msvideo": ["avi"],
|
|
457
|
-
"video/mp4": ["m4v", "mp4"],
|
|
458
|
-
"video/webm": ["webm"],
|
|
492
|
+
const getFileTypeFromFilename = (fileName) => {
|
|
493
|
+
const nameParts = fileName.split(".");
|
|
494
|
+
if (!nameParts.length)
|
|
495
|
+
return undefined;
|
|
496
|
+
const nameExt = nameParts[nameParts.length - 1].toLowerCase(), mime = (0, prostgles_types_1.getKeys)(prostgles_types_1.CONTENT_TYPE_TO_EXT).find(k => prostgles_types_1.CONTENT_TYPE_TO_EXT[k].includes(nameExt));
|
|
497
|
+
if (!mime)
|
|
498
|
+
return undefined;
|
|
499
|
+
return {
|
|
500
|
+
mime,
|
|
501
|
+
ext: nameExt,
|
|
502
|
+
};
|
|
503
|
+
};
|
|
504
|
+
exports.getFileTypeFromFilename = getFileTypeFromFilename;
|
|
505
|
+
// const fileType = require("file-type");
|
|
506
|
+
// const res = await fileType.fromBuffer(typeof file === "string"? Buffer.from(file, 'utf8') : file);
|
|
507
|
+
const getFileType = async (file, fileName) => {
|
|
508
|
+
const { fileTypeFromBuffer } = await eval('import("file-type")');
|
|
509
|
+
const fileNameMime = (0, exports.getFileTypeFromFilename)(fileName);
|
|
510
|
+
if (!fileNameMime?.ext)
|
|
511
|
+
throw new Error("File name must contain extenions");
|
|
512
|
+
const res = await fileTypeFromBuffer(typeof file === "string" ? Buffer.from(file, 'utf8') : file);
|
|
513
|
+
if (!res) {
|
|
514
|
+
/* Set correct/missing extension */
|
|
515
|
+
const nameExt = fileNameMime?.ext;
|
|
516
|
+
if (["xml", "txt", "csv", "tsv", "svg"].includes(nameExt)) {
|
|
517
|
+
return fileNameMime;
|
|
518
|
+
}
|
|
519
|
+
throw new Error("Could not get the file type from file buffer");
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
if (!res.ext || fileNameMime?.ext.toLowerCase() !== res.ext.toLowerCase()) {
|
|
523
|
+
throw new Error(`There is a mismatch between file name extension and actual buffer extension: ${fileNameMime?.ext} vs ${res.ext}`);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return res;
|
|
459
527
|
};
|
|
528
|
+
exports.getFileType = getFileType;
|
|
460
529
|
/**
|
|
461
530
|
*
|
|
462
531
|
|