@galadrim/galadmin 0.1.226 → 0.1.227
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/README.md +25 -0
- package/dist/api.js +354 -170
- package/dist/api.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/config.d.ts +6 -0
- package/package.json +2 -1
- package/src/api.ts +1227 -916
- package/src/front/yarn.lock +10795 -0
- package/src/types/config.ts +6 -0
package/dist/api.js
CHANGED
|
@@ -18,6 +18,7 @@ const path = require("path");
|
|
|
18
18
|
const crypto = require("crypto");
|
|
19
19
|
const mime = require("mime");
|
|
20
20
|
const aws_sdk_1 = require("aws-sdk");
|
|
21
|
+
const storage_1 = require("@google-cloud/storage");
|
|
21
22
|
const image_size_1 = require("image-size");
|
|
22
23
|
const serializeJs = require("serialize-javascript");
|
|
23
24
|
const SftpClient = require("ssh2-sftp-client");
|
|
@@ -28,7 +29,7 @@ const axios_1 = require("axios");
|
|
|
28
29
|
const uuid_1 = require("uuid");
|
|
29
30
|
function generateUniqueIdForObject(obj) {
|
|
30
31
|
const str = JSON.stringify(obj);
|
|
31
|
-
const hash = crypto.createHash(
|
|
32
|
+
const hash = crypto.createHash("sha256").update(str).digest("hex");
|
|
32
33
|
return hash;
|
|
33
34
|
}
|
|
34
35
|
exports.default = (db, config, user) => {
|
|
@@ -49,7 +50,8 @@ exports.default = (db, config, user) => {
|
|
|
49
50
|
const columns = params.columns;
|
|
50
51
|
let isNewCondition = true;
|
|
51
52
|
for (let i in columns) {
|
|
52
|
-
if (columns[i].searchable !== false &&
|
|
53
|
+
if (columns[i].searchable !== false &&
|
|
54
|
+
(columns[i].searchableName || columns[i].name)) {
|
|
53
55
|
if (queryString.length == 0) {
|
|
54
56
|
queryString += " WHERE (";
|
|
55
57
|
}
|
|
@@ -63,7 +65,10 @@ exports.default = (db, config, user) => {
|
|
|
63
65
|
queryString += columns[i].searchableName;
|
|
64
66
|
}
|
|
65
67
|
else if (columns[i].name) {
|
|
66
|
-
queryString += columns[i].name
|
|
68
|
+
queryString += columns[i].name
|
|
69
|
+
.split(".")
|
|
70
|
+
.map((x) => (db.dbType === "POSTGRESQL" ? x : "`" + x + "`"))
|
|
71
|
+
.join(".");
|
|
67
72
|
}
|
|
68
73
|
queryString += " LIKE '%" + params.query.replace(/'/g, "\\'") + "%'";
|
|
69
74
|
isNewCondition = false;
|
|
@@ -72,7 +77,8 @@ exports.default = (db, config, user) => {
|
|
|
72
77
|
queryString += ")";
|
|
73
78
|
}
|
|
74
79
|
const limit = params.allRecords ? 999999 : parseInt(params.limit);
|
|
75
|
-
const query = params.customQuery ||
|
|
80
|
+
const query = params.customQuery ||
|
|
81
|
+
`SELECT
|
|
76
82
|
${params.selectExpression || "*"}
|
|
77
83
|
FROM ${params.table}
|
|
78
84
|
${params.join || ""}
|
|
@@ -84,7 +90,7 @@ exports.default = (db, config, user) => {
|
|
|
84
90
|
if (err) {
|
|
85
91
|
console.error(err);
|
|
86
92
|
return {
|
|
87
|
-
error: err
|
|
93
|
+
error: err,
|
|
88
94
|
};
|
|
89
95
|
}
|
|
90
96
|
let count = undefined;
|
|
@@ -103,22 +109,22 @@ exports.default = (db, config, user) => {
|
|
|
103
109
|
queryString,
|
|
104
110
|
input: {
|
|
105
111
|
query,
|
|
106
|
-
params
|
|
112
|
+
params,
|
|
107
113
|
},
|
|
108
|
-
count
|
|
114
|
+
count,
|
|
109
115
|
};
|
|
110
116
|
}
|
|
111
117
|
async function findRecordByPosition(params) {
|
|
112
118
|
return await getRecords(Object.assign(params, {
|
|
113
119
|
page: parseInt(params.position) + parseInt(params.offset),
|
|
114
|
-
limit: 1
|
|
120
|
+
limit: 1,
|
|
115
121
|
}));
|
|
116
122
|
}
|
|
117
|
-
app.get(
|
|
123
|
+
app.get("/config", async (req, res) => {
|
|
118
124
|
try {
|
|
119
125
|
const { mysql, auth, sessionSecret } = config, safeConfig = __rest(config, ["mysql", "auth", "sessionSecret"]);
|
|
120
126
|
res.send({
|
|
121
|
-
config: serializeJs(safeConfig)
|
|
127
|
+
config: serializeJs(safeConfig),
|
|
122
128
|
});
|
|
123
129
|
}
|
|
124
130
|
catch (e) {
|
|
@@ -128,7 +134,7 @@ exports.default = (db, config, user) => {
|
|
|
128
134
|
});
|
|
129
135
|
app.get("/customComponent", async (req, res) => {
|
|
130
136
|
try {
|
|
131
|
-
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname,
|
|
137
|
+
const pkg = JSON.parse(fs.readFileSync(path.join(__dirname, "../src/front/package.json"), "utf-8"));
|
|
132
138
|
const external = Object.keys(pkg.dependencies || {});
|
|
133
139
|
const bundle = await rollup.rollup({
|
|
134
140
|
input: path.join(__dirname, "../../", req.query.componentPath),
|
|
@@ -136,26 +142,29 @@ exports.default = (db, config, user) => {
|
|
|
136
142
|
(0, plugin_node_resolve_1.default)(),
|
|
137
143
|
(0, plugin_babel_1.default)({
|
|
138
144
|
configFile: path.join(__dirname, "../babel.config"),
|
|
139
|
-
babelHelpers: "bundled"
|
|
140
|
-
})
|
|
145
|
+
babelHelpers: "bundled",
|
|
146
|
+
}),
|
|
141
147
|
],
|
|
142
|
-
external
|
|
148
|
+
external,
|
|
149
|
+
});
|
|
150
|
+
const { output } = await bundle.generate({
|
|
151
|
+
format: "cjs",
|
|
152
|
+
exports: "auto",
|
|
143
153
|
});
|
|
144
|
-
const { output } = await bundle.generate({ format: 'cjs', exports: 'auto' });
|
|
145
154
|
res.send(output[0].code);
|
|
146
155
|
}
|
|
147
156
|
catch (err) {
|
|
148
157
|
console.error(err);
|
|
149
158
|
}
|
|
150
159
|
});
|
|
151
|
-
app.post(
|
|
160
|
+
app.post("/adjacentRecordId", async function (req, res, next) {
|
|
152
161
|
const { rows, error } = await findRecordByPosition(req.body);
|
|
153
162
|
if (error) {
|
|
154
163
|
return res.status(500).send(error);
|
|
155
164
|
}
|
|
156
165
|
const recordId = rows[0] ? rows[0][req.body.primaryId] : null;
|
|
157
166
|
res.send({
|
|
158
|
-
recordId: recordId
|
|
167
|
+
recordId: recordId,
|
|
159
168
|
});
|
|
160
169
|
});
|
|
161
170
|
const sqlAnd = (conditions) => {
|
|
@@ -179,26 +188,32 @@ exports.default = (db, config, user) => {
|
|
|
179
188
|
return result;
|
|
180
189
|
}
|
|
181
190
|
};
|
|
182
|
-
app.post(
|
|
191
|
+
app.post("/foreignSelectRecords", async (req, res, next) => {
|
|
183
192
|
var _a, _b, _c, _d, _e;
|
|
184
193
|
const view = config.views[req.body.viewIndex];
|
|
185
194
|
const column = [
|
|
186
195
|
...view.columns,
|
|
187
|
-
...(((_c = (_b = (_a = view.recordViewPanels) === null || _a === void 0 ? void 0 : _a.map(x => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.createConfig) === null || _a === void 0 ? void 0 : _a.columns; })) === null || _b === void 0 ? void 0 : _b.filter(x => x)) === null || _c === void 0 ? void 0 : _c.flat()) || [])
|
|
188
|
-
].find(x => x.__id__ === req.body.columnId);
|
|
189
|
-
const queryEscaped = db.dbType === "POSTGRESQL"
|
|
196
|
+
...(((_c = (_b = (_a = view.recordViewPanels) === null || _a === void 0 ? void 0 : _a.map((x) => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.createConfig) === null || _a === void 0 ? void 0 : _a.columns; })) === null || _b === void 0 ? void 0 : _b.filter((x) => x)) === null || _c === void 0 ? void 0 : _c.flat()) || []),
|
|
197
|
+
].find((x) => x.__id__ === req.body.columnId);
|
|
198
|
+
const queryEscaped = db.dbType === "POSTGRESQL"
|
|
199
|
+
? (_d = req.body.query) === null || _d === void 0 ? void 0 : _d.replace(/'/g, "''")
|
|
200
|
+
: (_e = req.body.query) === null || _e === void 0 ? void 0 : _e.replace(/'/g, "\\'");
|
|
190
201
|
const { rows: records, error } = await getRecords({
|
|
191
202
|
table: column.table,
|
|
192
203
|
page: 1,
|
|
193
204
|
filters: sqlAnd([
|
|
194
205
|
column.filters,
|
|
195
|
-
req.body.query
|
|
196
|
-
|
|
206
|
+
req.body.query
|
|
207
|
+
? `${column.searchableName} LIKE '${column.wholeSearch ? "%" : ""}${queryEscaped}%'`
|
|
208
|
+
: null,
|
|
209
|
+
column.filtersFromUser
|
|
210
|
+
? column.filtersFromUser(user.userId, user.role)
|
|
211
|
+
: null,
|
|
197
212
|
]),
|
|
198
213
|
join: column.join,
|
|
199
214
|
selectExpression: column.selectExpression,
|
|
200
215
|
orderBy: column.orderBy,
|
|
201
|
-
limit: column.limit || 1000
|
|
216
|
+
limit: column.limit || 1000,
|
|
202
217
|
});
|
|
203
218
|
if (error) {
|
|
204
219
|
return res.status(500).send(error);
|
|
@@ -218,32 +233,41 @@ exports.default = (db, config, user) => {
|
|
|
218
233
|
label = record[column.name];
|
|
219
234
|
}
|
|
220
235
|
const value = record[column.foreignName] || record[column.name];
|
|
221
|
-
return
|
|
236
|
+
return {
|
|
222
237
|
value,
|
|
223
|
-
label
|
|
224
|
-
}
|
|
238
|
+
label,
|
|
239
|
+
};
|
|
225
240
|
}));
|
|
226
241
|
res.send(options);
|
|
227
242
|
});
|
|
228
|
-
app.post(
|
|
243
|
+
app.post("/records", async function (req, res, next) {
|
|
229
244
|
const view = config.views[req.body.viewIndex];
|
|
230
245
|
const isDesc = req.body.isDesc === null ? view.isDesc : req.body.isDesc;
|
|
231
|
-
const subview = view.subviews && req.body.subviewIndex !== undefined
|
|
246
|
+
const subview = view.subviews && req.body.subviewIndex !== undefined
|
|
247
|
+
? view.subviews[req.body.subviewIndex]
|
|
248
|
+
: null;
|
|
232
249
|
const orderBy = req.body.orderBy || (subview === null || subview === void 0 ? void 0 : subview.orderBy) || view.orderBy;
|
|
233
|
-
const { rows: records, input, error, count } = await getRecords({
|
|
250
|
+
const { rows: records, input, error, count, } = await getRecords({
|
|
234
251
|
table: view.tableName,
|
|
235
252
|
page: req.body.page,
|
|
236
253
|
filters: sqlAnd([
|
|
237
254
|
view.filters,
|
|
238
255
|
subview === null || subview === void 0 ? void 0 : subview.filters,
|
|
239
256
|
...req.body.filters,
|
|
240
|
-
view.filtersFromUser
|
|
257
|
+
view.filtersFromUser
|
|
258
|
+
? view.filtersFromUser(user.userId, user.role)
|
|
259
|
+
: null,
|
|
241
260
|
]),
|
|
242
261
|
having: subview === null || subview === void 0 ? void 0 : subview.having,
|
|
243
262
|
customQuery: view.customQuery,
|
|
244
263
|
join: view.join,
|
|
245
264
|
selectExpression: view.selectExpression,
|
|
246
|
-
orderBy: [
|
|
265
|
+
orderBy: [
|
|
266
|
+
orderBy ? `${orderBy} ${isDesc ? "DESC" : "ASC"}` : null,
|
|
267
|
+
view.primaryId,
|
|
268
|
+
]
|
|
269
|
+
.filter((x) => x)
|
|
270
|
+
.join(", "),
|
|
247
271
|
primaryId: view.primaryId,
|
|
248
272
|
query: req.body.query,
|
|
249
273
|
groupBy: view.groupBy,
|
|
@@ -256,14 +280,15 @@ exports.default = (db, config, user) => {
|
|
|
256
280
|
for (const column of view.columns) {
|
|
257
281
|
if (column.formatValue) {
|
|
258
282
|
for (const record of records) {
|
|
259
|
-
record[`__formatValue-${column.__id__}__`] =
|
|
283
|
+
record[`__formatValue-${column.__id__}__`] =
|
|
284
|
+
await column.formatValue(record);
|
|
260
285
|
}
|
|
261
286
|
}
|
|
262
287
|
}
|
|
263
288
|
res.send({
|
|
264
289
|
records,
|
|
265
290
|
input,
|
|
266
|
-
count
|
|
291
|
+
count,
|
|
267
292
|
});
|
|
268
293
|
});
|
|
269
294
|
const formattedValueToFunction = {};
|
|
@@ -293,11 +318,25 @@ exports.default = (db, config, user) => {
|
|
|
293
318
|
}
|
|
294
319
|
}
|
|
295
320
|
function evalExpression(expression, data) {
|
|
296
|
-
let varString =
|
|
297
|
-
let statement =
|
|
321
|
+
let varString = "";
|
|
322
|
+
let statement = "";
|
|
298
323
|
try {
|
|
299
324
|
for (let key in data) {
|
|
300
|
-
statement =
|
|
325
|
+
statement =
|
|
326
|
+
"var " +
|
|
327
|
+
key +
|
|
328
|
+
" = " +
|
|
329
|
+
(typeof data[key] === "string"
|
|
330
|
+
? "'" +
|
|
331
|
+
data[key]
|
|
332
|
+
.replace(/'/g, "\\'")
|
|
333
|
+
.replace(/\n/g, "")
|
|
334
|
+
.replace(/\r/g, "") +
|
|
335
|
+
"'"
|
|
336
|
+
: typeof data[key] === "object"
|
|
337
|
+
? JSON.stringify(data[key])
|
|
338
|
+
: data[key]) +
|
|
339
|
+
";";
|
|
301
340
|
varString += statement;
|
|
302
341
|
}
|
|
303
342
|
const result = eval(varString + expression);
|
|
@@ -335,11 +374,13 @@ exports.default = (db, config, user) => {
|
|
|
335
374
|
}
|
|
336
375
|
return value;
|
|
337
376
|
}
|
|
338
|
-
app.post(
|
|
377
|
+
app.post("/recordsExport", async function (req, res) {
|
|
339
378
|
const view = config.views[req.body.viewIndex];
|
|
340
379
|
const orderBy = req.body.orderBy || view.orderBy;
|
|
341
380
|
const isDesc = req.body.isDesc === null ? view.isDesc : req.body.isDesc;
|
|
342
|
-
const subview = view.subviews && req.body.subviewIndex !== undefined
|
|
381
|
+
const subview = view.subviews && req.body.subviewIndex !== undefined
|
|
382
|
+
? view.subviews[req.body.subviewIndex]
|
|
383
|
+
: null;
|
|
343
384
|
const { rows: records, error } = await getRecords({
|
|
344
385
|
table: view.tableName,
|
|
345
386
|
page: 1,
|
|
@@ -375,21 +416,21 @@ exports.default = (db, config, user) => {
|
|
|
375
416
|
if (!columns[j].hideInTable || columns[j].includeInExport) {
|
|
376
417
|
if (j > 0)
|
|
377
418
|
output += ";";
|
|
378
|
-
if (columns[j].dataType ==
|
|
419
|
+
if (columns[j].dataType == "textarea") {
|
|
379
420
|
output += '"';
|
|
380
421
|
}
|
|
381
422
|
output += await getFormattedValue(columns[j], el);
|
|
382
|
-
if (columns[j].dataType ==
|
|
423
|
+
if (columns[j].dataType == "textarea") {
|
|
383
424
|
output += '"';
|
|
384
425
|
}
|
|
385
426
|
}
|
|
386
427
|
}
|
|
387
428
|
}
|
|
388
429
|
res.send({
|
|
389
|
-
content: output
|
|
430
|
+
content: output,
|
|
390
431
|
});
|
|
391
432
|
});
|
|
392
|
-
app.post(
|
|
433
|
+
app.post("/recordsImport", async function (req, res) {
|
|
393
434
|
const form = new multiparty.Form();
|
|
394
435
|
form.parse(req, async function (err, fields, files) {
|
|
395
436
|
if (err) {
|
|
@@ -397,13 +438,15 @@ exports.default = (db, config, user) => {
|
|
|
397
438
|
}
|
|
398
439
|
const view = config.views[fields.viewIndex[0]];
|
|
399
440
|
if (typeof view.parseImportFile !== "function") {
|
|
400
|
-
return res
|
|
441
|
+
return res
|
|
442
|
+
.status(500)
|
|
443
|
+
.send('"parseImportFile" doit être défini dans la configuration de la vue.');
|
|
401
444
|
}
|
|
402
445
|
const records = await view.parseImportFile(files.data[0]);
|
|
403
446
|
const columns = [];
|
|
404
447
|
if (records.length === 0) {
|
|
405
448
|
return res.send({
|
|
406
|
-
affectedRows: 0
|
|
449
|
+
affectedRows: 0,
|
|
407
450
|
});
|
|
408
451
|
}
|
|
409
452
|
try {
|
|
@@ -416,20 +459,32 @@ exports.default = (db, config, user) => {
|
|
|
416
459
|
}
|
|
417
460
|
let queryString;
|
|
418
461
|
if (db.dbType === "POSTGRESQL") {
|
|
419
|
-
queryString = `INSERT INTO ?? (${columns.map(x => `"${x}"`).join(", ")}) VALUES`;
|
|
462
|
+
queryString = `INSERT INTO ?? (${columns.map((x) => `"${x}"`).join(", ")}) VALUES`;
|
|
420
463
|
for (let record of records) {
|
|
421
|
-
const valuesList = columns
|
|
464
|
+
const valuesList = columns
|
|
465
|
+
.map((x) => formatValueForInsertion(record[x], db.dbType))
|
|
466
|
+
.join(", ");
|
|
422
467
|
queryString += ` (${valuesList}),`;
|
|
423
468
|
}
|
|
424
|
-
queryString =
|
|
469
|
+
queryString =
|
|
470
|
+
queryString.slice(0, -1) +
|
|
471
|
+
` ON CONFLICT (${view.importFileUniqueField}) DO UPDATE SET `;
|
|
425
472
|
for (let column of columns) {
|
|
426
473
|
queryString += `"${column}" = EXCLUDED."${column}",`;
|
|
427
474
|
}
|
|
428
475
|
}
|
|
429
476
|
else {
|
|
430
|
-
queryString =
|
|
477
|
+
queryString =
|
|
478
|
+
"INSERT INTO ?? (" +
|
|
479
|
+
columns.map((x) => "`" + x + "`").join(", ") +
|
|
480
|
+
") VALUES";
|
|
431
481
|
for (let record of records) {
|
|
432
|
-
queryString +=
|
|
482
|
+
queryString +=
|
|
483
|
+
" (" +
|
|
484
|
+
columns
|
|
485
|
+
.map((x) => formatValueForInsertion(record[x], db.dbType))
|
|
486
|
+
.join(", ") +
|
|
487
|
+
"),";
|
|
433
488
|
}
|
|
434
489
|
queryString = queryString.slice(0, -1) + " ON DUPLICATE KEY UPDATE";
|
|
435
490
|
for (let column of columns) {
|
|
@@ -442,23 +497,23 @@ exports.default = (db, config, user) => {
|
|
|
442
497
|
console.error(err);
|
|
443
498
|
return res.status(500).send({
|
|
444
499
|
err,
|
|
445
|
-
message: "Une erreur est survenue."
|
|
500
|
+
message: "Une erreur est survenue.",
|
|
446
501
|
});
|
|
447
502
|
}
|
|
448
503
|
res.send({
|
|
449
|
-
affectedRows: r.affectedRows
|
|
504
|
+
affectedRows: r.affectedRows,
|
|
450
505
|
});
|
|
451
506
|
}
|
|
452
507
|
catch (err) {
|
|
453
508
|
console.error(err);
|
|
454
509
|
res.status(500).send({
|
|
455
510
|
err,
|
|
456
|
-
message: "Une erreur est survenue."
|
|
511
|
+
message: "Une erreur est survenue.",
|
|
457
512
|
});
|
|
458
513
|
}
|
|
459
514
|
});
|
|
460
515
|
});
|
|
461
|
-
app.post(
|
|
516
|
+
app.post("/subrecordsImport", async function (req, res) {
|
|
462
517
|
const form = new multiparty.Form();
|
|
463
518
|
form.parse(req, async function (err, fields, files) {
|
|
464
519
|
if (err) {
|
|
@@ -467,16 +522,20 @@ exports.default = (db, config, user) => {
|
|
|
467
522
|
const view = config.views[fields.viewIndex[0]];
|
|
468
523
|
const panel = view.recordViewPanels[fields.panelIndex[0]];
|
|
469
524
|
if (typeof panel.parseImportFile !== "function") {
|
|
470
|
-
return res
|
|
525
|
+
return res
|
|
526
|
+
.status(500)
|
|
527
|
+
.send('"parseImportFile" doit être défini dans la configuration du panneau.');
|
|
471
528
|
}
|
|
472
529
|
if (!Boolean(panel.createConfig)) {
|
|
473
|
-
return res
|
|
530
|
+
return res
|
|
531
|
+
.status(500)
|
|
532
|
+
.send('"createConfig" doit être défini dans la configuration du panneau.');
|
|
474
533
|
}
|
|
475
534
|
const records = await panel.parseImportFile(files.data[0], fields.recordId[0]);
|
|
476
535
|
const columns = [];
|
|
477
536
|
if (records.length === 0) {
|
|
478
537
|
return res.send({
|
|
479
|
-
affectedRows: 0
|
|
538
|
+
affectedRows: 0,
|
|
480
539
|
});
|
|
481
540
|
}
|
|
482
541
|
try {
|
|
@@ -487,38 +546,59 @@ exports.default = (db, config, user) => {
|
|
|
487
546
|
}
|
|
488
547
|
}
|
|
489
548
|
}
|
|
490
|
-
let queryString = "INSERT IGNORE INTO ?? (`" +
|
|
549
|
+
let queryString = "INSERT IGNORE INTO ?? (`" +
|
|
550
|
+
panel.createConfig.recordIdKey +
|
|
551
|
+
"`, " +
|
|
552
|
+
columns.map((x) => "`" + x + "`").join(", ") +
|
|
553
|
+
") VALUES";
|
|
491
554
|
for (let record of records) {
|
|
492
|
-
queryString +=
|
|
555
|
+
queryString +=
|
|
556
|
+
" (" +
|
|
557
|
+
fields.recordId[0] +
|
|
558
|
+
", " +
|
|
559
|
+
columns
|
|
560
|
+
.map((x) => formatValueForInsertion(record[x], db.dbType))
|
|
561
|
+
.join(", ") +
|
|
562
|
+
"),";
|
|
493
563
|
}
|
|
494
564
|
queryString = queryString.slice(0, -1) + " ON DUPLICATE KEY UPDATE";
|
|
495
565
|
for (let column of columns) {
|
|
496
566
|
queryString += " `" + column + "` = VALUES(`" + column + "`),";
|
|
497
567
|
}
|
|
498
|
-
const { err, rows: r } = await db.query(queryString.slice(0, -1), [
|
|
568
|
+
const { err, rows: r } = await db.query(queryString.slice(0, -1), [
|
|
569
|
+
panel.tableName,
|
|
570
|
+
]);
|
|
499
571
|
if (err) {
|
|
500
572
|
console.error(err);
|
|
501
573
|
return res.status(500).send({
|
|
502
574
|
err,
|
|
503
|
-
message: "Une erreur est survenue."
|
|
575
|
+
message: "Une erreur est survenue.",
|
|
504
576
|
});
|
|
505
577
|
}
|
|
506
578
|
res.send({
|
|
507
|
-
affectedRows: r.affectedRows
|
|
579
|
+
affectedRows: r.affectedRows,
|
|
508
580
|
});
|
|
509
581
|
}
|
|
510
582
|
catch (err) {
|
|
511
583
|
console.error(err);
|
|
512
584
|
res.status(500).send({
|
|
513
585
|
err,
|
|
514
|
-
message: "Une erreur est survenue."
|
|
586
|
+
message: "Une erreur est survenue.",
|
|
515
587
|
});
|
|
516
588
|
}
|
|
517
589
|
});
|
|
518
590
|
});
|
|
519
|
-
app.get(
|
|
591
|
+
app.get("/record", async function (req, res) {
|
|
520
592
|
const view = config.views[req.query.viewIndex];
|
|
521
|
-
const { err, rows } = await db.query("SELECT " +
|
|
593
|
+
const { err, rows } = await db.query("SELECT " +
|
|
594
|
+
(view.selectExpression || "*") +
|
|
595
|
+
" FROM ?? " +
|
|
596
|
+
(view.join || "") +
|
|
597
|
+
" WHERE ?? = ?", [
|
|
598
|
+
view.tableName,
|
|
599
|
+
view.tableName + "." + view.primaryId,
|
|
600
|
+
req.query.recordId,
|
|
601
|
+
]);
|
|
522
602
|
if (err) {
|
|
523
603
|
return res.status(500).send(err);
|
|
524
604
|
}
|
|
@@ -526,7 +606,8 @@ exports.default = (db, config, user) => {
|
|
|
526
606
|
const record = rows[0];
|
|
527
607
|
for (const column of view.columns) {
|
|
528
608
|
if (column.formatValue) {
|
|
529
|
-
record[`__formatValue-${column.__id__}__`] =
|
|
609
|
+
record[`__formatValue-${column.__id__}__`] =
|
|
610
|
+
await column.formatValue(record);
|
|
530
611
|
}
|
|
531
612
|
}
|
|
532
613
|
res.send(record);
|
|
@@ -535,19 +616,28 @@ exports.default = (db, config, user) => {
|
|
|
535
616
|
res.sendStatus(404);
|
|
536
617
|
}
|
|
537
618
|
});
|
|
538
|
-
app.post(
|
|
619
|
+
app.post("/updateRecord", async function (req, res, next) {
|
|
539
620
|
const view = config.views[req.body.viewIndex];
|
|
540
621
|
for (let key in req.body.data) {
|
|
541
|
-
if (req.body.data[key] == "NULL" ||
|
|
622
|
+
if (req.body.data[key] == "NULL" ||
|
|
623
|
+
req.body.data[key] === "" ||
|
|
624
|
+
req.body.data[key] === "Invalid date") {
|
|
542
625
|
req.body.data[key] = null;
|
|
543
626
|
}
|
|
544
627
|
}
|
|
545
628
|
if (Object.keys(req.body.data).length === 0) {
|
|
546
629
|
return res.sendStatus(200);
|
|
547
630
|
}
|
|
548
|
-
const queryExpression = Object.keys(req.body.data)
|
|
549
|
-
|
|
550
|
-
|
|
631
|
+
const queryExpression = Object.keys(req.body.data)
|
|
632
|
+
.map((x) => `${x} = ?`)
|
|
633
|
+
.join(", ");
|
|
634
|
+
const queryParameters = Object.keys(req.body.data).map((x) => req.body.data[x]);
|
|
635
|
+
const { err } = await db.query(`UPDATE ?? SET ${queryExpression} WHERE ?? = ?`, [
|
|
636
|
+
view.tableName,
|
|
637
|
+
...queryParameters,
|
|
638
|
+
view.primaryId,
|
|
639
|
+
req.body.primaryValue,
|
|
640
|
+
]);
|
|
551
641
|
if (err) {
|
|
552
642
|
return res.status(500).send(err);
|
|
553
643
|
}
|
|
@@ -556,7 +646,7 @@ exports.default = (db, config, user) => {
|
|
|
556
646
|
await axios_1.default.post(view.editCallback, {
|
|
557
647
|
id: req.body.primaryValue,
|
|
558
648
|
data: req.body.data,
|
|
559
|
-
previousData: req.body.previousData
|
|
649
|
+
previousData: req.body.previousData,
|
|
560
650
|
});
|
|
561
651
|
}
|
|
562
652
|
catch (e) { }
|
|
@@ -564,23 +654,27 @@ exports.default = (db, config, user) => {
|
|
|
564
654
|
if (view.editCallbackFunction) {
|
|
565
655
|
await view.editCallbackFunction({
|
|
566
656
|
id: req.body.primaryValue,
|
|
567
|
-
data: req.body.data
|
|
657
|
+
data: req.body.data,
|
|
568
658
|
});
|
|
569
659
|
}
|
|
570
660
|
res.sendStatus(200);
|
|
571
661
|
});
|
|
572
|
-
app.post(
|
|
662
|
+
app.post("/customAction", async function (req, res, next) {
|
|
573
663
|
const view = config.views[req.body.viewIndex];
|
|
574
664
|
const action = view.customActions[req.body.actionIndex];
|
|
575
665
|
for (const recordId of req.body.selectedRecordIds) {
|
|
576
666
|
try {
|
|
577
|
-
const { rows } = await db.query("SELECT " +
|
|
667
|
+
const { rows } = await db.query("SELECT " +
|
|
668
|
+
(view.selectExpression || "*") +
|
|
669
|
+
" FROM ?? " +
|
|
670
|
+
(view.join || "") +
|
|
671
|
+
" WHERE ?? = ?", [view.tableName, view.tableName + "." + view.primaryId, recordId]);
|
|
578
672
|
const record = rows[0];
|
|
579
673
|
const actionResult = await action.action(record, user.userId);
|
|
580
674
|
if (actionResult) {
|
|
581
675
|
return res.send({
|
|
582
676
|
success: true,
|
|
583
|
-
message: actionResult
|
|
677
|
+
message: actionResult,
|
|
584
678
|
});
|
|
585
679
|
}
|
|
586
680
|
}
|
|
@@ -588,18 +682,26 @@ exports.default = (db, config, user) => {
|
|
|
588
682
|
console.error(err);
|
|
589
683
|
return res.send({
|
|
590
684
|
success: false,
|
|
591
|
-
error: err
|
|
685
|
+
error: err,
|
|
592
686
|
});
|
|
593
687
|
}
|
|
594
688
|
}
|
|
595
689
|
res.send({
|
|
596
690
|
success: true,
|
|
597
|
-
message: action.successMessage
|
|
691
|
+
message: action.successMessage,
|
|
598
692
|
});
|
|
599
693
|
});
|
|
600
|
-
app.post(
|
|
694
|
+
app.post("/deleteRecord", async function (req, res) {
|
|
601
695
|
const view = config.views[req.body.viewIndex];
|
|
602
|
-
const { rows, err: err2 } = await db.query("SELECT " +
|
|
696
|
+
const { rows, err: err2 } = await db.query("SELECT " +
|
|
697
|
+
(view.selectExpression || "*") +
|
|
698
|
+
" FROM ?? " +
|
|
699
|
+
(view.join || "") +
|
|
700
|
+
" WHERE ?? = ?", [
|
|
701
|
+
view.tableName,
|
|
702
|
+
view.tableName + "." + view.primaryId,
|
|
703
|
+
req.body.primaryValue,
|
|
704
|
+
]);
|
|
603
705
|
if (err2) {
|
|
604
706
|
return res.status(500).send(err2);
|
|
605
707
|
}
|
|
@@ -607,14 +709,18 @@ exports.default = (db, config, user) => {
|
|
|
607
709
|
if (!deletedRecord) {
|
|
608
710
|
return res.status(404).send("Record not found");
|
|
609
711
|
}
|
|
610
|
-
const { err } = await db.query("DELETE FROM ?? WHERE ?? = ?", [
|
|
712
|
+
const { err } = await db.query("DELETE FROM ?? WHERE ?? = ?", [
|
|
713
|
+
view.tableName,
|
|
714
|
+
view.primaryId,
|
|
715
|
+
req.body.primaryValue,
|
|
716
|
+
]);
|
|
611
717
|
if (err) {
|
|
612
718
|
return res.status(500).send(err);
|
|
613
719
|
}
|
|
614
720
|
if (view.deleteCallback) {
|
|
615
721
|
try {
|
|
616
722
|
await axios_1.default.post(view.deleteCallback, {
|
|
617
|
-
id: req.body.primaryValue
|
|
723
|
+
id: req.body.primaryValue,
|
|
618
724
|
});
|
|
619
725
|
}
|
|
620
726
|
catch (e) { }
|
|
@@ -622,27 +728,31 @@ exports.default = (db, config, user) => {
|
|
|
622
728
|
if (view.deleteCallbackFunction) {
|
|
623
729
|
await view.deleteCallbackFunction({
|
|
624
730
|
id: req.body.primaryValue,
|
|
625
|
-
deletedRecord
|
|
731
|
+
deletedRecord,
|
|
626
732
|
});
|
|
627
733
|
}
|
|
628
734
|
res.sendStatus(200);
|
|
629
735
|
});
|
|
630
|
-
app.post(
|
|
736
|
+
app.post("/deleteRecordFromPanel", async function (req, res) {
|
|
631
737
|
const view = config.views[req.body.viewIndex];
|
|
632
|
-
const panel = view.recordViewPanels.find(x => x.__id__ === req.body.panelId);
|
|
738
|
+
const panel = view.recordViewPanels.find((x) => x.__id__ === req.body.panelId);
|
|
633
739
|
const { rows, err: err2 } = await db.query("SELECT * FROM ?? WHERE ?? = ?", [panel.tableName, panel.primaryId, req.body.primaryValue]);
|
|
634
740
|
if (err2) {
|
|
635
741
|
return res.status(500).send(err2);
|
|
636
742
|
}
|
|
637
743
|
const deletedRecord = rows[0];
|
|
638
|
-
const { err } = await db.query("DELETE FROM ?? WHERE ?? = ?", [
|
|
744
|
+
const { err } = await db.query("DELETE FROM ?? WHERE ?? = ?", [
|
|
745
|
+
panel.tableName,
|
|
746
|
+
panel.primaryId,
|
|
747
|
+
req.body.primaryValue,
|
|
748
|
+
]);
|
|
639
749
|
if (err) {
|
|
640
750
|
return res.status(500).send(err);
|
|
641
751
|
}
|
|
642
752
|
if (panel.deleteCallback) {
|
|
643
753
|
try {
|
|
644
754
|
await axios_1.default.post(panel.deleteCallback, {
|
|
645
|
-
id: req.body.primaryValue
|
|
755
|
+
id: req.body.primaryValue,
|
|
646
756
|
});
|
|
647
757
|
}
|
|
648
758
|
catch (e) { }
|
|
@@ -650,20 +760,20 @@ exports.default = (db, config, user) => {
|
|
|
650
760
|
if (panel.deleteCallbackFunction) {
|
|
651
761
|
await panel.deleteCallbackFunction({
|
|
652
762
|
id: req.body.primaryValue,
|
|
653
|
-
deletedRecord
|
|
763
|
+
deletedRecord,
|
|
654
764
|
});
|
|
655
765
|
}
|
|
656
766
|
res.sendStatus(200);
|
|
657
767
|
});
|
|
658
|
-
app.post(
|
|
768
|
+
app.post("/deleteRecords", async function (req, res, next) {
|
|
659
769
|
const view = config.views[req.body.viewIndex];
|
|
660
|
-
const { err } = await db.query(`DELETE FROM ?? WHERE ?? IN(${req.body.primaryValues.map(x => "'" + x + "'").join(",")})`, [view.tableName, view.primaryId]);
|
|
770
|
+
const { err } = await db.query(`DELETE FROM ?? WHERE ?? IN(${req.body.primaryValues.map((x) => "'" + x + "'").join(",")})`, [view.tableName, view.primaryId]);
|
|
661
771
|
if (err) {
|
|
662
772
|
return res.status(500).send(err);
|
|
663
773
|
}
|
|
664
774
|
res.sendStatus(200);
|
|
665
775
|
});
|
|
666
|
-
app.get(
|
|
776
|
+
app.get("/notificationBadges", async function (req, res) {
|
|
667
777
|
const notificationBadges = {};
|
|
668
778
|
async function checkAndGetNotificationBadge(obj) {
|
|
669
779
|
if (obj.notificationBadge) {
|
|
@@ -671,9 +781,11 @@ exports.default = (db, config, user) => {
|
|
|
671
781
|
if (err) {
|
|
672
782
|
console.error(err);
|
|
673
783
|
}
|
|
674
|
-
else if (rows.length > 0 &&
|
|
784
|
+
else if (rows.length > 0 &&
|
|
785
|
+
rows[0][obj.notificationBadge.attribute]) {
|
|
675
786
|
const notificationBadge = rows[0][obj.notificationBadge.attribute];
|
|
676
|
-
if (!obj.notificationBadge.displayCondition ||
|
|
787
|
+
if (!obj.notificationBadge.displayCondition ||
|
|
788
|
+
obj.notificationBadge.displayCondition(notificationBadge)) {
|
|
677
789
|
notificationBadges[obj.__id__] = notificationBadge;
|
|
678
790
|
}
|
|
679
791
|
}
|
|
@@ -689,9 +801,13 @@ exports.default = (db, config, user) => {
|
|
|
689
801
|
}
|
|
690
802
|
res.send(notificationBadges);
|
|
691
803
|
});
|
|
692
|
-
app.post(
|
|
804
|
+
app.post("/duplicateRecord", async function (req, res, next) {
|
|
693
805
|
const primaryId = req.body.duplicateConfig.primaryId;
|
|
694
|
-
const { err, rows } = await db.query("SELECT * FROM ?? WHERE ?? = ?", [
|
|
806
|
+
const { err, rows } = await db.query("SELECT * FROM ?? WHERE ?? = ?", [
|
|
807
|
+
req.body.table,
|
|
808
|
+
primaryId,
|
|
809
|
+
req.body.primaryValue,
|
|
810
|
+
]);
|
|
695
811
|
if (err) {
|
|
696
812
|
return res.status(500).send(err);
|
|
697
813
|
}
|
|
@@ -706,7 +822,11 @@ exports.default = (db, config, user) => {
|
|
|
706
822
|
}
|
|
707
823
|
const newRecordId = r.insertId;
|
|
708
824
|
for (let foreignTable of req.body.duplicateConfig.foreignTables) {
|
|
709
|
-
const { err, rows } = await db.query("SELECT * FROM ?? WHERE ?? = ?", [
|
|
825
|
+
const { err, rows } = await db.query("SELECT * FROM ?? WHERE ?? = ?", [
|
|
826
|
+
foreignTable.table,
|
|
827
|
+
primaryId,
|
|
828
|
+
req.body.primaryValue,
|
|
829
|
+
]);
|
|
710
830
|
if (err)
|
|
711
831
|
console.log(err);
|
|
712
832
|
for (let record of rows) {
|
|
@@ -715,51 +835,62 @@ exports.default = (db, config, user) => {
|
|
|
715
835
|
for (let field of foreignTable.fields) {
|
|
716
836
|
data[field] = record[field];
|
|
717
837
|
}
|
|
718
|
-
await db.query("INSERT IGNORE INTO ?? SET ?", [
|
|
838
|
+
await db.query("INSERT IGNORE INTO ?? SET ?", [
|
|
839
|
+
foreignTable.table,
|
|
840
|
+
data,
|
|
841
|
+
]);
|
|
719
842
|
}
|
|
720
843
|
}
|
|
721
844
|
res.sendStatus(200);
|
|
722
845
|
});
|
|
723
|
-
app.post(
|
|
846
|
+
app.post("/createRecord", async function (req, res, next) {
|
|
724
847
|
var _a, _b, _c;
|
|
725
848
|
const view = config.views[req.body.viewIndex];
|
|
726
|
-
const panel = req.body.panelIndex
|
|
849
|
+
const panel = req.body.panelIndex
|
|
850
|
+
? view.recordViewPanels[req.body.panelIndex]
|
|
851
|
+
: null;
|
|
727
852
|
try {
|
|
728
853
|
for (let key in req.body.data) {
|
|
729
|
-
if (req.body.data[key] == "NULL" ||
|
|
854
|
+
if (req.body.data[key] == "NULL" ||
|
|
855
|
+
req.body.data[key] === "Invalid date") {
|
|
730
856
|
req.body.data[key] = null;
|
|
731
857
|
}
|
|
732
858
|
}
|
|
733
859
|
if (panel) {
|
|
734
860
|
req.body.data[panel.createConfig.recordIdKey] = req.body.recordId;
|
|
735
861
|
}
|
|
736
|
-
const primaryColumn = (_b = (_a = (view || panel)) === null || _a === void 0 ? void 0 : _a.columns) === null || _b === void 0 ? void 0 : _b.find(x => x.name === (view || panel).primaryId);
|
|
862
|
+
const primaryColumn = (_b = (_a = (view || panel)) === null || _a === void 0 ? void 0 : _a.columns) === null || _b === void 0 ? void 0 : _b.find((x) => x.name === (view || panel).primaryId);
|
|
737
863
|
if ((primaryColumn === null || primaryColumn === void 0 ? void 0 : primaryColumn.dataType) == "uuid") {
|
|
738
864
|
req.body.data[primaryColumn.name] = (0, uuid_1.v4)();
|
|
739
865
|
}
|
|
740
866
|
const createPayload = JSON.parse(JSON.stringify(req.body.data));
|
|
741
867
|
const columns = panel ? panel.createConfig.columns : view.columns;
|
|
742
868
|
for (let key in createPayload) {
|
|
743
|
-
if (((_c = columns === null || columns === void 0 ? void 0 : columns.find(x => x.name === key)) === null || _c === void 0 ? void 0 : _c.includedInCreatePayload) ===
|
|
869
|
+
if (((_c = columns === null || columns === void 0 ? void 0 : columns.find((x) => x.name === key)) === null || _c === void 0 ? void 0 : _c.includedInCreatePayload) ===
|
|
870
|
+
false) {
|
|
744
871
|
delete createPayload[key];
|
|
745
872
|
}
|
|
746
873
|
}
|
|
747
874
|
const queryExpression = Object.keys(createPayload).join(", ");
|
|
748
|
-
const queryPlaceholders = Object.keys(createPayload)
|
|
749
|
-
|
|
875
|
+
const queryPlaceholders = Object.keys(createPayload)
|
|
876
|
+
.map((x) => "?")
|
|
877
|
+
.join(", ");
|
|
878
|
+
const queryParameters = Object.keys(createPayload).map((x) => createPayload[x]);
|
|
750
879
|
const { err, rows: r } = await db.query(`INSERT INTO ?? (${queryExpression}) VALUES(${queryPlaceholders})`, [panel ? panel.tableName : view.tableName, ...queryParameters]);
|
|
751
880
|
if (err) {
|
|
752
881
|
console.error(err);
|
|
753
882
|
return res.status(500).send({
|
|
754
883
|
err,
|
|
755
|
-
message: err.code ===
|
|
884
|
+
message: err.code === "ER_DUP_ENTRY"
|
|
885
|
+
? "Cet élément existe déjà."
|
|
886
|
+
: "Une erreur est survenue.",
|
|
756
887
|
});
|
|
757
888
|
}
|
|
758
889
|
if (panel ? panel.createCallback : view.createCallback) {
|
|
759
890
|
try {
|
|
760
891
|
await axios_1.default.post(panel ? panel.createCallback : view.createCallback, {
|
|
761
892
|
id: r.insertId,
|
|
762
|
-
data: req.body.data
|
|
893
|
+
data: req.body.data,
|
|
763
894
|
});
|
|
764
895
|
}
|
|
765
896
|
catch (e) { }
|
|
@@ -767,22 +898,22 @@ exports.default = (db, config, user) => {
|
|
|
767
898
|
if (panel ? panel.createCallbackFunction : view.createCallbackFunction) {
|
|
768
899
|
await (panel ? panel.createCallbackFunction : view.createCallbackFunction)({
|
|
769
900
|
id: r.insertId,
|
|
770
|
-
data: req.body.data
|
|
901
|
+
data: req.body.data,
|
|
771
902
|
});
|
|
772
903
|
}
|
|
773
904
|
res.send({
|
|
774
|
-
id: r.insertId
|
|
905
|
+
id: r.insertId,
|
|
775
906
|
});
|
|
776
907
|
}
|
|
777
908
|
catch (err) {
|
|
778
909
|
console.error(err);
|
|
779
910
|
res.status(500).send({
|
|
780
911
|
err,
|
|
781
|
-
message: "Une erreur est survenue."
|
|
912
|
+
message: "Une erreur est survenue.",
|
|
782
913
|
});
|
|
783
914
|
}
|
|
784
915
|
});
|
|
785
|
-
app.get(
|
|
916
|
+
app.get("/customQuery", async function (req, res, next) {
|
|
786
917
|
const query = req.query.query.replace(/\?/g, req.query.primaryValue);
|
|
787
918
|
const { err, rows } = await db.query(query);
|
|
788
919
|
if (err) {
|
|
@@ -801,22 +932,14 @@ exports.default = (db, config, user) => {
|
|
|
801
932
|
res.send(rows);
|
|
802
933
|
});
|
|
803
934
|
function uploadFile(column, fileParamName, req, res) {
|
|
804
|
-
if (column.s3Config) {
|
|
805
|
-
const s3Config = column.s3Config;
|
|
935
|
+
if (column.s3Config || column.gcpConfig) {
|
|
806
936
|
const form = new multiparty.Form();
|
|
807
|
-
const s3 = new aws_sdk_1.S3({
|
|
808
|
-
endpoint: new aws_sdk_1.Endpoint(s3Config.host),
|
|
809
|
-
accessKeyId: s3Config.accessKeyId,
|
|
810
|
-
secretAccessKey: s3Config.secretAccessKey,
|
|
811
|
-
region: s3Config.region,
|
|
812
|
-
signatureVersion: "v4",
|
|
813
|
-
});
|
|
814
937
|
form.parse(req, function (err, fields, files) {
|
|
815
938
|
if (err) {
|
|
816
939
|
return res.status(500).send(err);
|
|
817
940
|
}
|
|
818
941
|
const originalFilename = files[fileParamName][0].originalFilename;
|
|
819
|
-
const contentType = mime.getType(originalFilename) ||
|
|
942
|
+
const contentType = mime.getType(originalFilename) || "application/octet-stream";
|
|
820
943
|
const extension = originalFilename.match(/(?:\.([^.]+))?$/)[1];
|
|
821
944
|
let aspectRatio = null;
|
|
822
945
|
if (["png", "jpeg", "jpg", "gif"].includes(extension)) {
|
|
@@ -824,55 +947,105 @@ exports.default = (db, config, user) => {
|
|
|
824
947
|
aspectRatio = dimensions.height / dimensions.width;
|
|
825
948
|
}
|
|
826
949
|
const originalFilenameWithoutExtension = originalFilename.replace("." + extension, "");
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
950
|
+
if (column.gcpConfig) {
|
|
951
|
+
const gcpConfig = column.gcpConfig;
|
|
952
|
+
const path = (gcpConfig.subfolder ? gcpConfig.subfolder + "/" : "") +
|
|
953
|
+
originalFilenameWithoutExtension +
|
|
954
|
+
"-" +
|
|
955
|
+
Math.random().toString().substr(2) +
|
|
956
|
+
"." +
|
|
957
|
+
extension;
|
|
958
|
+
const storage = new storage_1.Storage();
|
|
959
|
+
const bucketName = gcpConfig.bucket;
|
|
960
|
+
storage
|
|
961
|
+
.bucket(bucketName)
|
|
962
|
+
.upload(files[fileParamName][0].path, {
|
|
963
|
+
destination: path,
|
|
841
964
|
})
|
|
842
965
|
.then(() => {
|
|
843
966
|
res.status(200).send({
|
|
844
|
-
path:
|
|
967
|
+
path: gcpConfig.pathTransform
|
|
968
|
+
? gcpConfig.pathTransform(path)
|
|
969
|
+
: path,
|
|
845
970
|
aspectRatio,
|
|
846
971
|
originalFilename,
|
|
847
972
|
});
|
|
848
973
|
})
|
|
849
|
-
.catch(e => {
|
|
974
|
+
.catch((e) => {
|
|
850
975
|
res.status(500).send(e);
|
|
851
976
|
});
|
|
852
977
|
}
|
|
853
978
|
else {
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
originalFilename
|
|
868
|
-
});
|
|
979
|
+
const s3Config = column.s3Config;
|
|
980
|
+
const path = (s3Config.subfolder ? s3Config.subfolder + "/" : "") +
|
|
981
|
+
originalFilenameWithoutExtension +
|
|
982
|
+
"-" +
|
|
983
|
+
Math.random().toString().substr(2) +
|
|
984
|
+
"." +
|
|
985
|
+
extension;
|
|
986
|
+
const s3 = new aws_sdk_1.S3({
|
|
987
|
+
endpoint: new aws_sdk_1.Endpoint(s3Config.host),
|
|
988
|
+
accessKeyId: s3Config.accessKeyId,
|
|
989
|
+
secretAccessKey: s3Config.secretAccessKey,
|
|
990
|
+
region: s3Config.region,
|
|
991
|
+
signatureVersion: "v4",
|
|
869
992
|
});
|
|
993
|
+
if (s3Config.signedUrlNeeded) {
|
|
994
|
+
const signedUrl = s3.getSignedUrl("putObject", {
|
|
995
|
+
Bucket: s3Config.bucket,
|
|
996
|
+
Key: path,
|
|
997
|
+
ContentType: contentType,
|
|
998
|
+
Expires: 150,
|
|
999
|
+
});
|
|
1000
|
+
axios_1.default
|
|
1001
|
+
.put(signedUrl, fs.readFileSync(files[fileParamName][0].path), {
|
|
1002
|
+
maxContentLength: 100000000000,
|
|
1003
|
+
maxBodyLength: 100000000000,
|
|
1004
|
+
headers: {
|
|
1005
|
+
"Content-Type": contentType,
|
|
1006
|
+
},
|
|
1007
|
+
})
|
|
1008
|
+
.then(() => {
|
|
1009
|
+
res.status(200).send({
|
|
1010
|
+
path: s3Config.pathTransform
|
|
1011
|
+
? s3Config.pathTransform(path)
|
|
1012
|
+
: path,
|
|
1013
|
+
aspectRatio,
|
|
1014
|
+
originalFilename,
|
|
1015
|
+
});
|
|
1016
|
+
})
|
|
1017
|
+
.catch((e) => {
|
|
1018
|
+
res.status(500).send(e);
|
|
1019
|
+
});
|
|
1020
|
+
}
|
|
1021
|
+
else {
|
|
1022
|
+
s3.putObject({
|
|
1023
|
+
Body: fs.readFileSync(files[fileParamName][0].path),
|
|
1024
|
+
Bucket: s3Config.bucket,
|
|
1025
|
+
ContentType: contentType,
|
|
1026
|
+
ACL: "public-read",
|
|
1027
|
+
Key: path,
|
|
1028
|
+
}, function (err, data) {
|
|
1029
|
+
if (err)
|
|
1030
|
+
return res.status(500).send(err);
|
|
1031
|
+
res.send({
|
|
1032
|
+
url: `https://${s3Config.host}/${s3Config.bucket}/${path}`,
|
|
1033
|
+
path: s3Config.pathTransform
|
|
1034
|
+
? s3Config.pathTransform(path)
|
|
1035
|
+
: path,
|
|
1036
|
+
aspectRatio,
|
|
1037
|
+
originalFilename,
|
|
1038
|
+
});
|
|
1039
|
+
});
|
|
1040
|
+
}
|
|
870
1041
|
}
|
|
871
1042
|
});
|
|
872
1043
|
}
|
|
873
1044
|
else if (column.sftpConfig) {
|
|
874
1045
|
if (!column.publicPath) {
|
|
875
|
-
return res
|
|
1046
|
+
return res
|
|
1047
|
+
.status(500)
|
|
1048
|
+
.send("You need to pass publicPath parameter when using sftpConfig");
|
|
876
1049
|
}
|
|
877
1050
|
const form = new multiparty.Form();
|
|
878
1051
|
form.parse(req, function (err, fields, files) {
|
|
@@ -887,13 +1060,16 @@ exports.default = (db, config, user) => {
|
|
|
887
1060
|
host: column.sftpConfig.host,
|
|
888
1061
|
port: 22,
|
|
889
1062
|
username: column.sftpConfig.user,
|
|
890
|
-
password: column.sftpConfig.password
|
|
1063
|
+
password: column.sftpConfig.password,
|
|
891
1064
|
});
|
|
892
|
-
await sftp.fastPut(files[fileParamName][0].path, column.publicPath +
|
|
1065
|
+
await sftp.fastPut(files[fileParamName][0].path, column.publicPath +
|
|
1066
|
+
(column.subdirectory ? "/" + column.subdirectory : "") +
|
|
1067
|
+
"/" +
|
|
1068
|
+
filename);
|
|
893
1069
|
await sftp.end();
|
|
894
1070
|
res.send({
|
|
895
1071
|
path: filename,
|
|
896
|
-
originalFilename: files[fileParamName][0].originalFilename
|
|
1072
|
+
originalFilename: files[fileParamName][0].originalFilename,
|
|
897
1073
|
});
|
|
898
1074
|
fs.unlinkSync(files[fileParamName][0].path);
|
|
899
1075
|
})();
|
|
@@ -901,7 +1077,7 @@ exports.default = (db, config, user) => {
|
|
|
901
1077
|
}
|
|
902
1078
|
else {
|
|
903
1079
|
const form = new multiparty.Form({
|
|
904
|
-
uploadDir: column.publicPath + column.subdirectory
|
|
1080
|
+
uploadDir: column.publicPath + column.subdirectory,
|
|
905
1081
|
});
|
|
906
1082
|
form.parse(req, function (err, fields, files) {
|
|
907
1083
|
if (err) {
|
|
@@ -909,32 +1085,32 @@ exports.default = (db, config, user) => {
|
|
|
909
1085
|
}
|
|
910
1086
|
res.send({
|
|
911
1087
|
path: files[fileParamName][0].path.replace(column.publicPath, ""),
|
|
912
|
-
originalFilename: files[fileParamName][0].originalFilename
|
|
1088
|
+
originalFilename: files[fileParamName][0].originalFilename,
|
|
913
1089
|
});
|
|
914
1090
|
});
|
|
915
1091
|
}
|
|
916
1092
|
}
|
|
917
|
-
app.post(
|
|
918
|
-
const fileUploadProperties = JSON.parse(req.headers[
|
|
1093
|
+
app.post("/uploadFileFromBetterRichTextInput", async function (req, res, next) {
|
|
1094
|
+
const fileUploadProperties = JSON.parse(req.headers["file-upload-properties"]);
|
|
919
1095
|
uploadFile(fileUploadProperties, "upload", req, res);
|
|
920
1096
|
});
|
|
921
|
-
app.post(
|
|
1097
|
+
app.post("/uploadFile", async function (req, res, next) {
|
|
922
1098
|
var _a, _b, _c;
|
|
923
1099
|
const view = config.views[req.query.viewIndex];
|
|
924
1100
|
const column = [
|
|
925
1101
|
...view.columns,
|
|
926
|
-
...(((_c = (_b = (_a = view.recordViewPanels) === null || _a === void 0 ? void 0 : _a.map(x => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.createConfig) === null || _a === void 0 ? void 0 : _a.columns; })) === null || _b === void 0 ? void 0 : _b.filter(x => x)) === null || _c === void 0 ? void 0 : _c.flat()) || [])
|
|
927
|
-
].find(x => x.__id__ == req.query.columnId);
|
|
1102
|
+
...(((_c = (_b = (_a = view.recordViewPanels) === null || _a === void 0 ? void 0 : _a.map((x) => { var _a; return (_a = x === null || x === void 0 ? void 0 : x.createConfig) === null || _a === void 0 ? void 0 : _a.columns; })) === null || _b === void 0 ? void 0 : _b.filter((x) => x)) === null || _c === void 0 ? void 0 : _c.flat()) || []),
|
|
1103
|
+
].find((x) => x.__id__ == req.query.columnId);
|
|
928
1104
|
uploadFile(column, "file", req, res);
|
|
929
1105
|
});
|
|
930
|
-
app.get(
|
|
1106
|
+
app.get("/searchCompanies", async (req, res) => {
|
|
931
1107
|
const processedQuery = req.query.query.replaceAll(" ", "-");
|
|
932
1108
|
try {
|
|
933
1109
|
const response = await axios_1.default.get(`https://public.opendatasoft.com/api/explore/v2.1/catalog/datasets/economicref-france-sirene-v3/records`, {
|
|
934
1110
|
params: {
|
|
935
1111
|
where: `denominationunitelegale LIKE '${processedQuery}*' OR siret LIKE '${processedQuery}*'`,
|
|
936
|
-
limit: 100
|
|
937
|
-
}
|
|
1112
|
+
limit: 100,
|
|
1113
|
+
},
|
|
938
1114
|
});
|
|
939
1115
|
const results = response.data.results
|
|
940
1116
|
.filter((etablissement) => etablissement.etatadministratifetablissement === "Actif")
|
|
@@ -1002,25 +1178,33 @@ async function enrichConfig(config, db) {
|
|
|
1002
1178
|
config.enriched = true;
|
|
1003
1179
|
}
|
|
1004
1180
|
function enrichColumn(column, tableName, info) {
|
|
1181
|
+
var _a, _b, _c, _d;
|
|
1005
1182
|
if (!column.__id__) {
|
|
1006
1183
|
column.__id__ = generateUniqueIdForObject(column);
|
|
1007
1184
|
}
|
|
1008
|
-
const infoEl = info.find(x => x.TABLE_NAME == tableName && x.COLUMN_NAME == column.name);
|
|
1009
|
-
if ((infoEl === null || infoEl === void 0 ? void 0 : infoEl.IS_NULLABLE) == "NO" &&
|
|
1185
|
+
const infoEl = info.find((x) => x.TABLE_NAME == tableName && x.COLUMN_NAME == column.name);
|
|
1186
|
+
if ((infoEl === null || infoEl === void 0 ? void 0 : infoEl.IS_NULLABLE) == "NO" &&
|
|
1187
|
+
(infoEl === null || infoEl === void 0 ? void 0 : infoEl.DATA_TYPE) != "text" &&
|
|
1188
|
+
column.required !== true &&
|
|
1189
|
+
column.required !== false) {
|
|
1010
1190
|
column.required = true;
|
|
1011
1191
|
}
|
|
1012
1192
|
if (!column.dataType && infoEl) {
|
|
1013
1193
|
column.dataType = infoEl.DATA_TYPE;
|
|
1014
1194
|
if (column.dataType == "enum") {
|
|
1015
1195
|
column.dataType = "select";
|
|
1016
|
-
column.options = JSON.parse(infoEl.COLUMN_TYPE.replace("enum(", "[")
|
|
1196
|
+
column.options = JSON.parse(infoEl.COLUMN_TYPE.replace("enum(", "[")
|
|
1197
|
+
.replace(")", "]")
|
|
1198
|
+
.replace(/'/g, '"'));
|
|
1017
1199
|
}
|
|
1018
1200
|
}
|
|
1019
1201
|
if (column.dataType == "richText") {
|
|
1020
1202
|
column.name = column.contentField;
|
|
1021
1203
|
}
|
|
1022
|
-
if (column.dataType == "file" && column.s3Config) {
|
|
1023
|
-
|
|
1204
|
+
if (column.dataType == "file" && (column.s3Config || column.gcpConfig)) {
|
|
1205
|
+
const host = ((_a = column.s3Config) === null || _a === void 0 ? void 0 : _a.host) || ((_b = column.gcpConfig) === null || _b === void 0 ? void 0 : _b.host);
|
|
1206
|
+
const bucket = ((_c = column.s3Config) === null || _c === void 0 ? void 0 : _c.bucket) || ((_d = column.gcpConfig) === null || _d === void 0 ? void 0 : _d.bucket);
|
|
1207
|
+
column.baseUrl = `https://${host}/${bucket}/`;
|
|
1024
1208
|
}
|
|
1025
1209
|
}
|
|
1026
1210
|
//# sourceMappingURL=api.js.map
|