@opengis/fastify-table 2.5.47 → 2.5.49
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/server/plugins/file/uploadMultiPart.d.ts +2 -0
- package/dist/server/plugins/file/uploadMultiPart.d.ts.map +1 -1
- package/dist/server/plugins/file/uploadMultiPart.js +3 -1
- package/dist/server/plugins/file/utils/inspectContent.d.ts +6 -0
- package/dist/server/plugins/file/utils/inspectContent.d.ts.map +1 -1
- package/dist/server/plugins/file/utils/inspectContent.js +52 -2
- package/dist/server/routes/table/schema.js +1 -1
- package/package.json +1 -1
- package/dist/server/plugins/access/funcs/getAdminAccess.d.ts +0 -5
- package/dist/server/plugins/access/funcs/getAdminAccess.d.ts.map +0 -1
- package/dist/server/plugins/access/funcs/getAdminAccess.js +0 -12
- package/dist/server/routes/crud/index.d.ts +0 -3
- package/dist/server/routes/crud/index.d.ts.map +0 -1
- package/dist/server/routes/crud/index.js +0 -55
|
@@ -12,6 +12,8 @@ export interface IFile {
|
|
|
12
12
|
fields?: Record<string, any>;
|
|
13
13
|
error?: string;
|
|
14
14
|
code?: number;
|
|
15
|
+
isValid?: boolean;
|
|
16
|
+
confidence?: string;
|
|
15
17
|
}
|
|
16
18
|
export declare function rotateFilenameFS(filename: string, dirpath: string): Promise<string>;
|
|
17
19
|
export declare function rotateFilenameS3({ Name: filename, Bucket, Prefix, }: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"uploadMultiPart.d.ts","sourceRoot":"","sources":["../../../../server/plugins/file/uploadMultiPart.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,KAAK;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"uploadMultiPart.d.ts","sourceRoot":"","sources":["../../../../server/plugins/file/uploadMultiPart.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,KAAK;IACpB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA2CD,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,mBAkBvE;AAED,wBAAsB,gBAAgB,CACpC,EACE,IAAI,EAAE,QAAQ,EACd,MAA2C,EAC3C,MAAM,GACP,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,EACpD,MAAM,MAAW,mBA+BlB;AAED,wBAAsB,eAAe,CACnC,GAAG,EAAE,GAAG,EACR,EACE,UAAU,EACV,GAAG,EACH,MAAM,EACN,gBAAwB,GACzB,GAAE;IACD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CACvB,GACL,OAAO,CAAC,KAAK,CAAC,CA4HhB;AAED,eAAe,eAAe,CAAC"}
|
|
@@ -112,7 +112,7 @@ export async function uploadMultiPart(req, { extensions, raw, subdir, originalFi
|
|
|
112
112
|
throw new BadRequestError("file buffer is empty");
|
|
113
113
|
}
|
|
114
114
|
const nameExt = ext.substring(1);
|
|
115
|
-
const { isValid } = await inspectContent(fileBuffer, nameExt);
|
|
115
|
+
const { isValid, confidence } = await inspectContent(fileBuffer, nameExt);
|
|
116
116
|
// return buffer for custom upload
|
|
117
117
|
if (raw) {
|
|
118
118
|
return {
|
|
@@ -121,6 +121,8 @@ export async function uploadMultiPart(req, { extensions, raw, subdir, originalFi
|
|
|
121
121
|
extension: ext.substring(1),
|
|
122
122
|
mimetype: value.mimetype,
|
|
123
123
|
fields: value.fields,
|
|
124
|
+
isValid,
|
|
125
|
+
confidence,
|
|
124
126
|
};
|
|
125
127
|
}
|
|
126
128
|
if (!isValid) {
|
|
@@ -2,5 +2,11 @@ export default function inspectContent(input: Buffer | ReadableStream, expectedE
|
|
|
2
2
|
ext: any;
|
|
3
3
|
mime: any;
|
|
4
4
|
isValid: boolean;
|
|
5
|
+
confidence: any;
|
|
6
|
+
} | {
|
|
7
|
+
ext: string | undefined;
|
|
8
|
+
mime: string | undefined;
|
|
9
|
+
isValid: boolean;
|
|
10
|
+
confidence?: undefined;
|
|
5
11
|
}>;
|
|
6
12
|
//# sourceMappingURL=inspectContent.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inspectContent.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/file/utils/inspectContent.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"inspectContent.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/file/utils/inspectContent.ts"],"names":[],"mappings":"AAuGA,wBAA8B,cAAc,CAC1C,KAAK,EAAE,MAAM,GAAG,cAAc,EAC9B,iBAAiB,EAAE,MAAM;;;;;;;;;;GA4E1B"}
|
|
@@ -7,6 +7,25 @@ const cfbOfficeMimes = {
|
|
|
7
7
|
xls: "application/vnd.ms-excel",
|
|
8
8
|
ppt: "application/vnd.ms-powerpoint",
|
|
9
9
|
};
|
|
10
|
+
function countDelimiter(line, delimiter) {
|
|
11
|
+
let count = 0;
|
|
12
|
+
let quoted = false;
|
|
13
|
+
for (let i = 0; i < line.length; i++) {
|
|
14
|
+
const char = line[i];
|
|
15
|
+
if (char === '"') {
|
|
16
|
+
if (quoted && line[i + 1] === '"') {
|
|
17
|
+
i++;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
quoted = !quoted;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
else if (char === delimiter && !quoted) {
|
|
24
|
+
count++;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
return count;
|
|
28
|
+
}
|
|
10
29
|
const handlers = {
|
|
11
30
|
pdf: (buffer) => {
|
|
12
31
|
const head = buffer.subarray(0, 1024).toString("latin1");
|
|
@@ -14,6 +33,7 @@ const handlers = {
|
|
|
14
33
|
return {
|
|
15
34
|
ext: "pdf",
|
|
16
35
|
mime: "application/pdf",
|
|
36
|
+
confidence: "heuristic",
|
|
17
37
|
};
|
|
18
38
|
}
|
|
19
39
|
},
|
|
@@ -23,6 +43,7 @@ const handlers = {
|
|
|
23
43
|
return {
|
|
24
44
|
ext: "json",
|
|
25
45
|
mime: "application/json",
|
|
46
|
+
confidence: "heuristic",
|
|
26
47
|
};
|
|
27
48
|
}
|
|
28
49
|
},
|
|
@@ -34,9 +55,33 @@ const handlers = {
|
|
|
34
55
|
return {
|
|
35
56
|
ext: "geojson",
|
|
36
57
|
mime: "application/geo+json",
|
|
58
|
+
confidence: "heuristic",
|
|
37
59
|
};
|
|
38
60
|
}
|
|
39
61
|
},
|
|
62
|
+
csv: (buffer) => {
|
|
63
|
+
const text = buffer.subarray(0, 16 * 1024).toString("utf8");
|
|
64
|
+
const lines = text.split(/\r?\n/).filter((line) => line.trim());
|
|
65
|
+
if (lines.length < 2) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
const delimiters = [",", ";", "\t"];
|
|
69
|
+
return delimiters.reduce((acc, delimiter) => {
|
|
70
|
+
const counts = lines
|
|
71
|
+
.slice(0, 10)
|
|
72
|
+
.map((line) => countDelimiter(line, delimiter));
|
|
73
|
+
const first = counts[0];
|
|
74
|
+
if (first > 0 && counts.every((count) => count === first)) {
|
|
75
|
+
return {
|
|
76
|
+
...acc,
|
|
77
|
+
ext: "csv",
|
|
78
|
+
mime: "text/csv",
|
|
79
|
+
confidence: "heuristic",
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
return acc;
|
|
83
|
+
}, {});
|
|
84
|
+
},
|
|
40
85
|
};
|
|
41
86
|
const isReadableStream = (stream) => stream && stream instanceof ReadableStream;
|
|
42
87
|
export default async function inspectContent(input, expectedExtension) {
|
|
@@ -72,8 +117,13 @@ export default async function inspectContent(input, expectedExtension) {
|
|
|
72
117
|
const { ext, mime } = inspectResult1 || inspectResult2 || {};
|
|
73
118
|
// ? geojson, signed pdf, kml, svg etc - not recognized - inspecting the content
|
|
74
119
|
if (!ext && handlers[expectedExtension] && buffer) {
|
|
75
|
-
const { ext: ext2, mime: mime2 } = (await handlers[expectedExtension](buffer)) || {};
|
|
76
|
-
return {
|
|
120
|
+
const { ext: ext2, mime: mime2, confidence, } = (await handlers[expectedExtension](buffer)) || {};
|
|
121
|
+
return {
|
|
122
|
+
ext: ext2,
|
|
123
|
+
mime: mime2,
|
|
124
|
+
isValid: ext2 === expectedExtension,
|
|
125
|
+
confidence,
|
|
126
|
+
};
|
|
77
127
|
}
|
|
78
128
|
// ? .doc/.xls/.ppt are CFB containers — file-type returns "cfb", not the office ext
|
|
79
129
|
if (ext === "cfb" && cfbOfficeMimes[expectedExtension]) {
|
package/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getAdminAccess.d.ts","sourceRoot":"","sources":["../../../../../server/plugins/access/funcs/getAdminAccess.ts"],"names":[],"mappings":"AAGA,wBAA8B,cAAc,CAAC,EAC3C,EAAE,EACF,IAAI,GACL,EAAE;IACD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC;CAC3C,iBAYA"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import config from "../../../../config.js";
|
|
2
|
-
import { BadRequestError, ForbiddenError } from "../../../../errors.js";
|
|
3
|
-
export default async function getAdminAccess({ id, user, }) {
|
|
4
|
-
if (!id) {
|
|
5
|
-
throw BadRequestError("not enough params: id");
|
|
6
|
-
}
|
|
7
|
-
if (!config?.local &&
|
|
8
|
-
!["admin"].includes(user?.user_type || user?.type || "")) {
|
|
9
|
-
throw new ForbiddenError("access restricted: admin");
|
|
10
|
-
}
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../server/routes/crud/index.ts"],"names":[],"mappings":"AAmBA,iBAAS,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,GAAE,GAAQ,QAqDtC;AAED,eAAe,MAAM,CAAC"}
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import update from "./controllers/update.js";
|
|
2
|
-
import insert from "./controllers/insert.js";
|
|
3
|
-
import deleteCrud from "./controllers/deleteCrud.js";
|
|
4
|
-
import table from "./controllers/table.js";
|
|
5
|
-
const tableSchema = {
|
|
6
|
-
params: {
|
|
7
|
-
type: "object",
|
|
8
|
-
properties: {
|
|
9
|
-
id: { type: "string", pattern: "^([\\w\\d_.]+)$" },
|
|
10
|
-
table: { type: "string", pattern: "^([\\w\\d_.]+)$" },
|
|
11
|
-
},
|
|
12
|
-
},
|
|
13
|
-
};
|
|
14
|
-
const policy = "L0";
|
|
15
|
-
const tags = ["core", "crud"];
|
|
16
|
-
const packageName = "fastify-table";
|
|
17
|
-
function plugin(app, opt = {}) {
|
|
18
|
-
app.put("/table/:table/:id?", {
|
|
19
|
-
config: {
|
|
20
|
-
tags,
|
|
21
|
-
package: packageName,
|
|
22
|
-
policy,
|
|
23
|
-
summary: "Edit table data",
|
|
24
|
-
},
|
|
25
|
-
schema: tableSchema,
|
|
26
|
-
}, update);
|
|
27
|
-
app.delete("/table/:table/:id?", {
|
|
28
|
-
config: {
|
|
29
|
-
tags,
|
|
30
|
-
package: packageName,
|
|
31
|
-
policy,
|
|
32
|
-
summary: "Delete table data",
|
|
33
|
-
},
|
|
34
|
-
schema: tableSchema,
|
|
35
|
-
}, deleteCrud);
|
|
36
|
-
app.post("/table/:table/:id?", {
|
|
37
|
-
config: {
|
|
38
|
-
tags,
|
|
39
|
-
package: packageName,
|
|
40
|
-
policy,
|
|
41
|
-
summary: "Add table data",
|
|
42
|
-
},
|
|
43
|
-
schema: tableSchema,
|
|
44
|
-
}, insert);
|
|
45
|
-
app.get("/table/:table/:id?", {
|
|
46
|
-
config: {
|
|
47
|
-
tags,
|
|
48
|
-
package: packageName,
|
|
49
|
-
policy,
|
|
50
|
-
summary: "Get table data",
|
|
51
|
-
},
|
|
52
|
-
schema: tableSchema,
|
|
53
|
-
}, table);
|
|
54
|
-
}
|
|
55
|
-
export default plugin;
|