@ejfdelgado/ejflab-back 1.1.0

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.
Files changed (64) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +2 -0
  3. package/package.json +57 -0
  4. package/srv/AudIASrv.mjs +218 -0
  5. package/srv/AuthorizationSrv.mjs +213 -0
  6. package/srv/ComputeEngineSrv.mjs +289 -0
  7. package/srv/EmailHandler.mjs +54 -0
  8. package/srv/Image2MeshSrv.mjs +101 -0
  9. package/srv/ImagiationSrv.mjs +408 -0
  10. package/srv/KeysSrv.mjs +104 -0
  11. package/srv/MainHandler.mjs +140 -0
  12. package/srv/MainReplacer.mjs +77 -0
  13. package/srv/MfaSrv.mjs +266 -0
  14. package/srv/MilvusSrv.mjs +152 -0
  15. package/srv/MinioSrv.mjs +154 -0
  16. package/srv/MongoSrv.mjs +320 -0
  17. package/srv/MyError.mjs +48 -0
  18. package/srv/MyFileService.mjs +392 -0
  19. package/srv/MyFileServiceLocal.mjs +177 -0
  20. package/srv/MyPdf.mjs +37 -0
  21. package/srv/MyShell.mjs +205 -0
  22. package/srv/MySqlSrv.mjs +43 -0
  23. package/srv/Network.mjs +111 -0
  24. package/srv/OpenCVSrv.mjs +27 -0
  25. package/srv/PageSrv.mjs +234 -0
  26. package/srv/PayUSrv.mjs +186 -0
  27. package/srv/PayUSrvConstants.mjs +46 -0
  28. package/srv/PostgresSrv.mjs +109 -0
  29. package/srv/SecretsSrv.mjs +126 -0
  30. package/srv/SocketIOCall.mjs +494 -0
  31. package/srv/TupleSrv.mjs +141 -0
  32. package/srv/UtilesSrv.mjs +8 -0
  33. package/srv/callprocessors/AskIceServersProcessor.mjs +14 -0
  34. package/srv/callprocessors/AskRoomProcessor.mjs +15 -0
  35. package/srv/callprocessors/CallUserProcessor.mjs +17 -0
  36. package/srv/callprocessors/ChatSetSawProcessor.mjs +42 -0
  37. package/srv/callprocessors/CheckSrcResponseProcessor.mjs +28 -0
  38. package/srv/callprocessors/ClientChangeProcessor.mjs +19 -0
  39. package/srv/callprocessors/CloseVideoChatProcessor.mjs +16 -0
  40. package/srv/callprocessors/DestroyModelProcessor.mjs +16 -0
  41. package/srv/callprocessors/DisconnectProcessor.mjs +53 -0
  42. package/srv/callprocessors/GenericProcessor.mjs +7 -0
  43. package/srv/callprocessors/GetModelProcessor.mjs +11 -0
  44. package/srv/callprocessors/IncludeOtherPeersProcessor.mjs +12 -0
  45. package/srv/callprocessors/LoadFlowChartProcessor.mjs +103 -0
  46. package/srv/callprocessors/MakeAnswerProcessor.mjs +17 -0
  47. package/srv/callprocessors/OnIceCandidateProcessor.mjs +13 -0
  48. package/srv/callprocessors/OpenVideoChatProcessor.mjs +17 -0
  49. package/srv/callprocessors/PauseFlowChartProcessor.mjs +16 -0
  50. package/srv/callprocessors/ProcessResponseProcessor.mjs +123 -0
  51. package/srv/callprocessors/ReadSrcResponseProcessor.mjs +30 -0
  52. package/srv/callprocessors/RegisterProcessorProcessor.mjs +23 -0
  53. package/srv/callprocessors/RegisterSourceProcessor.mjs +22 -0
  54. package/srv/callprocessors/SendChatProcessor.mjs +71 -0
  55. package/srv/callprocessors/StartFlowChartProcessor.mjs +48 -0
  56. package/srv/callprocessors/StopFlowChartProcessor.mjs +16 -0
  57. package/srv/callprocessors/SubscribemeProcessor.mjs +13 -0
  58. package/srv/callprocessors/UpdateMyInformationProcessor.mjs +30 -0
  59. package/srv/common/FirebasConfig.mjs +160 -0
  60. package/srv/common/General.mjs +69 -0
  61. package/srv/common/MimeTypeMap.mjs +142 -0
  62. package/srv/common/MyStore.mjs +169 -0
  63. package/srv/common/Usuario.mjs +101 -0
  64. package/srv/common/Utilidades.mjs +43 -0
@@ -0,0 +1,392 @@
1
+ import axios from "axios";
2
+ import sharp from "sharp";
3
+ import { Buffer } from 'buffer';
4
+ import { Storage } from '@google-cloud/storage';
5
+ import ReadableStreamClone from 'readable-stream-clone'
6
+ import { MyConstants } from "@ejfdelgado/ejflab-common/src/MyConstants.js";
7
+ import { General } from "./common/General.mjs";
8
+ import { PassThrough } from "stream";
9
+ import { Gif } from "@ejfdelgado/ejflab-common/src/gif/index.mjs";
10
+
11
+ const storage = new Storage();
12
+
13
+ const defaultBucket = storage.bucket(MyConstants.BUCKET.PUBLIC);
14
+ const privateBucket = storage.bucket(MyConstants.BUCKET.PRIVATE);
15
+
16
+ export class MyFileService {
17
+
18
+ async setFilePublic(bucketRef, fileName) {
19
+ await bucketRef
20
+ .file(fileName)
21
+ .makePublic();
22
+ }
23
+
24
+ static async makegif(req, res, next) {
25
+ const token = res.locals.token;
26
+ const pageId = req.params['pageId'];
27
+ const peticion = req.body;
28
+
29
+ //console.log(JSON.stringify(peticion, null, 4));
30
+
31
+ //duration, audioUrl, imageUrl
32
+ const frames = peticion.frames;
33
+ const promesasImg = [];
34
+ for (let i = 0; i < frames.length; i++) {
35
+ const frame = frames[i];
36
+ const { imageUrl } = frame;
37
+ promesasImg.push(MyFileService.read(imageUrl));
38
+ }
39
+ const imgBuffers = await Promise.all(promesasImg);
40
+ for (let i = 0; i < frames.length; i++) {
41
+ const frame = frames[i];
42
+ frame.src = new Uint8Array(imgBuffers[i].data);
43
+ }
44
+ const quality = 80;
45
+ const myGif = new Gif(peticion.width, peticion.height, quality);
46
+ myGif.setLoops(1);
47
+ await myGif.setFrames(frames);
48
+ const rendered = await myGif.encode();
49
+
50
+ const bucketKey = MyFileService.getKeyBucketPath(token, "srv/pg/tale/", `${pageId}/${peticion.key}`, "OWN");
51
+ const uri = `${MyConstants.BUCKET.URL_BASE}/${MyConstants.BUCKET.PRIVATE}/${peticion.key}`;
52
+
53
+ const file = privateBucket.file(bucketKey);
54
+
55
+ const stream = new PassThrough();
56
+ stream.end(rendered);
57
+
58
+ await MyFileService.sendFile2Bucket(stream, file);
59
+
60
+ if (peticion.download) {
61
+ res.writeHead(200, {
62
+ "Content-Type": "image/gif",
63
+ "Content-disposition": "attachment;filename=" + peticion.key
64
+ });
65
+ res.end(rendered);
66
+ } else {
67
+ res.status(200).send({ key: bucketKey + "?t=" + new Date().getTime(), uri });
68
+ }
69
+ }
70
+
71
+ static async deleteDonationFiles(bucketRef, keyName) {
72
+ keyName = keyName.replace(/^.*storage.googleapis.com\/[^/]+\//ig, "");
73
+ const keyNameXs = General.getSuffixPath(keyName, "_xs");
74
+ const file = bucketRef.file(keyName);
75
+ const fileXs = bucketRef.file(keyNameXs);
76
+ const reporte = [];
77
+ try {
78
+ const detalle = { url: keyName };
79
+ reporte.push(detalle);
80
+ await file.delete();
81
+ detalle.ok = true;
82
+ } catch (error) { }
83
+ try {
84
+ const detalle = { url: keyNameXs };
85
+ reporte.push(detalle);
86
+ await fileXs.delete();
87
+ detalle.ok = true;
88
+ } catch (error) { }
89
+ return reporte;
90
+ }
91
+
92
+ static async cloneFile(bucketRef, token, orig, dest) {
93
+ const origPath = MyFileService.getKeyBucketPath(token, orig.folder, orig.filename, orig.type);
94
+ const destPath = MyFileService.getKeyBucketPath(token, dest.folder, dest.filename, dest.type);
95
+ const origFile = bucketRef.file(origPath);
96
+ const destFile = bucketRef.file(destPath);
97
+ const copyOptions = {};
98
+ await origFile.copy(destFile, copyOptions);
99
+ await destFile.makePublic();
100
+ }
101
+ static async stream2Buffer(stream) {
102
+ return new Promise((resolve, reject) => {
103
+ const _buf = [];
104
+ stream.on("data", (chunk) => _buf.push(chunk));
105
+ stream.on("end", () => resolve(Buffer.concat(_buf)));
106
+ stream.on("error", (err) => reject(err));
107
+ });
108
+ }
109
+ static async fetchFile2Stream(url) {
110
+ const options = { responseType: 'stream' };
111
+ const response = await new Promise((resolve, reject) => {
112
+ axios.get(url, options)
113
+ .then(res => { resolve(res) })
114
+ .catch(error => { reject(error) });
115
+ });
116
+ const stream = response.data;
117
+ return stream;
118
+ }
119
+ static async fetchUrl2Bucket(url, token, folder, filename, type, isPrivate = false) {
120
+ const keyName = MyFileService.getKeyBucketPath(token, folder, filename, type);
121
+ const stream = await MyFileService.fetchFile2Stream(url);
122
+ let file = defaultBucket.file(keyName);
123
+ let uri = `${MyConstants.BUCKET.URL_BASE}/${MyConstants.BUCKET.PUBLIC}/${keyName}`;
124
+ if (isPrivate) {
125
+ file = privateBucket.file(keyName);
126
+ uri = `${MyConstants.BUCKET.URL_BASE}/${MyConstants.BUCKET.PRIVATE}/${keyName}`;
127
+ }
128
+ await MyFileService.sendFile2Bucket(stream, file);
129
+ if (isPrivate === false) {
130
+ await file.makePublic();
131
+ }
132
+
133
+ return uri;
134
+ }
135
+
136
+ static async sendFile2Bucket(req, file) {
137
+ return new Promise((resolve, reject) => {
138
+ req.pipe(file.createWriteStream()).on('finish', () => {
139
+ resolve();
140
+ }).on('error', (error) => {
141
+ reject(error);
142
+ });
143
+ });
144
+ }
145
+
146
+ static getKeyBucketPath(token, folder = "general", fileName, type) {
147
+ const mp = General.getNameParts();
148
+ let keyName;
149
+ if (type == "FIRST_YEAR_MONTH") {
150
+ keyName = `${folder}/${mp.year}/${mp.month}/${token.email}/${mp.day}/${mp.hours}/${mp.minutes}/${mp.seconds}/${mp.millis}/${fileName}`;
151
+ } else if (type == "FIRST_EMAIL") {
152
+ keyName = `${folder}/${token.email}/${mp.year}/${mp.month}/${mp.day}/${mp.hours}/${mp.minutes}/${mp.seconds}/${mp.millis}/${fileName}`;
153
+ } else {
154
+ keyName = `${folder}/${token.email}/${fileName}`;
155
+ }
156
+ keyName = keyName.replace(/[\/]{2,}/g, "/");
157
+ return keyName;
158
+ }
159
+
160
+ static async readBinary(bucket, filePath) {
161
+ filePath = filePath.replace(/^[/]/, "");
162
+ const file = bucket.file(filePath);
163
+ const contents = (await file.download())[0];
164
+ return contents;
165
+ }
166
+
167
+ static async readString(bucket, filePath, encoding = "utf8") {
168
+ const respuesta = await MyFileService.readBinary(bucket, filePath);
169
+ if (respuesta != null) {
170
+ return respuesta.toString(encoding);
171
+ }
172
+ return null;
173
+ }
174
+
175
+ static async deleteFile(req, res, next) {
176
+ const originalUrl = req.originalUrl;
177
+ const filePath = decodeURIComponent(originalUrl.replace(/^\//, "").replace(/\?.*$/, ""));
178
+ const bucket = privateBucket;
179
+ const oldFileRef = bucket.file(filePath);
180
+ try {
181
+ await oldFileRef.delete();
182
+ } catch (err) {
183
+ //ignore, best effor
184
+ }
185
+ res.status(204).send();
186
+ }
187
+
188
+ static async readFile(req, res, next) {
189
+ const downloadFlag = req.query ? req.query.download : false;
190
+ const encoding = req.query ? req.query.encoding : null;
191
+ const rta = await MyFileService.read(req.originalUrl, encoding);
192
+ const MAPEO_CHARSET = {
193
+ "utf8": "; charset=utf-8",
194
+ };
195
+ let charset = MAPEO_CHARSET[encoding];
196
+ if (!charset) {
197
+ charset = "";
198
+ }
199
+ if (!rta) {
200
+ res.status(204).send();
201
+ return;
202
+ }
203
+ const response = {
204
+ "Content-Type": rta.metadata.contentType + charset,
205
+ "Content-disposition":
206
+ downloadFlag != undefined
207
+ ? "attachment;filename=" + rta.metadata.filename
208
+ : "inline",
209
+ };
210
+ if (req.query.max_age) {
211
+ response["Cache-Control"] = `max-age=${req.query.max_age}`;
212
+ }
213
+ res.writeHead(200, response);
214
+ res.end(rta.data);
215
+ }
216
+
217
+ /**
218
+ * @param encoding ascii, utf8 or null
219
+ */
220
+ static async read(originalUrl, encoding = null) {
221
+ const filePath = decodeURIComponent(originalUrl.replace(/^\//, "").replace(/\?.*$/, ""));
222
+ const fileName = /[^/]+$/.exec(filePath)[0];
223
+ const bucket = privateBucket;
224
+ const file = bucket.file(filePath);
225
+ const metadataPromise = file.getMetadata();
226
+ let contentPromise;
227
+ if (encoding == null) {
228
+ contentPromise = MyFileService.readBinary(bucket, filePath);
229
+ } else {
230
+ contentPromise = MyFileService.readString(bucket, filePath, encoding);
231
+ }
232
+ return new Promise((resolve, reject) => {
233
+ Promise.all([metadataPromise, contentPromise]).then(
234
+ function (respuesta) {
235
+ const metadata = respuesta[0][0];
236
+ metadata.filename = fileName;
237
+ metadata.fullPath = originalUrl;
238
+ const content = respuesta[1];
239
+ resolve({
240
+ metadata: metadata,
241
+ data: content,
242
+ });
243
+ },
244
+ function (err) {
245
+ metadataPromise
246
+ .then(() => {
247
+ reject(err);
248
+ })
249
+ .catch((error) => {
250
+ if (error.code == 404) {
251
+ resolve(null);
252
+ } else {
253
+ reject(err);
254
+ }
255
+ });
256
+ }
257
+ );
258
+ });
259
+ }
260
+
261
+ static async uploadFileResponse(req, res, next) {
262
+ res.status(200).send({ uri: res.locals.uri, key: res.locals.key, bucket: res.locals.bucket });
263
+ }
264
+
265
+ static async setFilePublicSrv(req, res, next) {
266
+ const key = General.readParam(req, "key");
267
+ await privateBucket
268
+ .file(key)
269
+ .makePublic();
270
+ res.status(200).send({ ok: true });
271
+ }
272
+
273
+ static async uploadFile(req, res, next) {
274
+
275
+ if (!req.headers.filename) {
276
+ if (typeof next != "undefined") {
277
+ next();// use await??
278
+ return;
279
+ }
280
+ }
281
+
282
+ const token = res.locals.token;
283
+
284
+ const extra = req.headers.extra;
285
+ if (extra) {
286
+ try {
287
+ const buffer = Buffer.from(extra, 'base64');
288
+ const texto = buffer.toString("utf8");
289
+ if (!req.locals) {
290
+ req.locals = {};
291
+ }
292
+ req.locals.extra = JSON.parse(texto);
293
+ } catch (e) {
294
+ console.log(e);
295
+ console.log("Can't decode extra header, but present.");
296
+ }
297
+ }
298
+
299
+ let folderType = "FIRST_YEAR_MONTH";
300
+
301
+ if (req.headers.foldertype) {
302
+ folderType = req.headers.foldertype;
303
+ }
304
+
305
+ let bucketRef = defaultBucket;
306
+ let bucketName = MyConstants.BUCKET.PUBLIC;
307
+ let isPublic = true;
308
+ if (req.headers.isprivate !== undefined && req.headers.isprivate !== '0') {
309
+ bucketRef = privateBucket;
310
+ bucketName = MyConstants.BUCKET.PRIVATE;
311
+ isPublic = false;
312
+ }
313
+
314
+ let isplainfile = false;
315
+ if ([false, "0", null, undefined].indexOf(req.headers.isplainfile) < 0) {//es undefined si no se manda
316
+ isplainfile = true;
317
+ }
318
+
319
+ const keyName = MyFileService.getKeyBucketPath(
320
+ token,
321
+ req.headers.folder,
322
+ req.headers.filename,
323
+ folderType,
324
+ );
325
+ const file = bucketRef.file(keyName);
326
+
327
+ //check if needs to erase previous file
328
+ if (req.headers.erasefile) {
329
+ const oldFile = decodeURIComponent(req.headers.erasefile.replace(/^\//, "").replace(/\?.*$/, ""));
330
+ const oldFileRef = bucketRef.file(oldFile);
331
+ try {
332
+ await oldFileRef.delete();
333
+ } catch (err) {
334
+ //ignore, best effor
335
+ }
336
+ }
337
+
338
+ if (isplainfile) {
339
+ // Treated as simple blob
340
+ const readClone1 = new ReadableStreamClone(req);
341
+ await MyFileService.sendFile2Bucket(readClone1, file);
342
+ if (isPublic) {
343
+ await file.makePublic();
344
+ }
345
+ } else {
346
+ // Treated as image with thumbnail
347
+ const keyNameXs = General.getSuffixPath(keyName, "_xs");
348
+ const fileXs = bucketRef.file(keyNameXs);
349
+ let sizeBig = 1024;
350
+ let sizeSmall = 256;
351
+ if (req.headers.sizebig) {
352
+ const numero = parseInt(req.headers.sizebig);
353
+ if (!isNaN(numero)) {
354
+ sizeBig = numero;
355
+ }
356
+ }
357
+ if (req.headers.sizesmall) {
358
+ const numero = parseInt(req.headers.sizesmall);
359
+ if (!isNaN(numero)) {
360
+ sizeSmall = numero;
361
+ }
362
+ }
363
+ const bigImage = sharp().resize(null, sizeBig).withMetadata().jpeg({ mozjpeg: true });
364
+ const smallImage = sharp().resize(null, sizeSmall).withMetadata().jpeg({ mozjpeg: true });
365
+
366
+ const readClone1 = new ReadableStreamClone(req);
367
+ const readClone2 = new ReadableStreamClone(req);
368
+
369
+ await Promise.all([
370
+ MyFileService.sendFile2Bucket(readClone1.pipe(bigImage), file),
371
+ MyFileService.sendFile2Bucket(readClone2.pipe(smallImage), fileXs)
372
+ ]);
373
+ if (isPublic) {
374
+ await Promise.all([
375
+ file.makePublic(),
376
+ fileXs.makePublic(),
377
+ ]);
378
+ }
379
+ }
380
+
381
+ res.locals.bucket = bucketName;
382
+ res.locals.key = `${keyName}`;
383
+ const uri = `${MyConstants.BUCKET.URL_BASE}/${bucketName}/${keyName}`;
384
+ res.locals.uri = uri;
385
+
386
+ next();
387
+ }
388
+
389
+ static async listFiles(req, res, next) {
390
+ res.status(200).send({ data: [] });
391
+ }
392
+ }
@@ -0,0 +1,177 @@
1
+ import fs from "fs";
2
+ import { General } from "./common/General.mjs";
3
+ import { NoExisteException, ParametrosIncompletosException } from "./MyError.mjs";
4
+ import { guessMimeType } from "./common/MimeTypeMap.mjs";
5
+
6
+ const FOLDER_LOCALS = "assets/";
7
+ const PATH_LOCALS = `./src/${FOLDER_LOCALS}`;
8
+
9
+ export class MyFileServiceLocal {
10
+
11
+ static async uploadFile(req, res, next) {
12
+ const base64 = General.readParam(req, "base64");
13
+ const fileName = General.readParam(req, "fileName");
14
+ const buffer = Buffer.from(base64, 'base64');
15
+ // Write buffer down to local file
16
+ const filePath = decodeURIComponent(fileName.replace(/^\//, "").replace(/\?.*$/, ""));
17
+ await new Promise((resolve, reject) => {
18
+ fs.open(`${PATH_LOCALS}${filePath}`, 'w', function (err, fd) {
19
+ if (err) {
20
+ reject(err);
21
+ return;
22
+ }
23
+ fs.write(fd, buffer, 0, buffer.length, null, function (err) {
24
+ if (err) {
25
+ reject(err);
26
+ }
27
+ fs.close(fd, function () {
28
+ resolve();
29
+ });
30
+ });
31
+ });
32
+ });
33
+ const response = {
34
+ uri: fileName,
35
+ key: fileName,
36
+ bucket: '',
37
+ };
38
+ res.status(200).send(response);
39
+ }
40
+
41
+ static async readFile(req, res, next) {
42
+ const downloadFlag = req.query ? req.query.download : false;
43
+ const encoding = req.query ? req.query.encoding : null;
44
+ const rta = await MyFileServiceLocal.read(req.originalUrl, encoding);
45
+ const MAPEO_CHARSET = {
46
+ "utf8": "; charset=utf-8",
47
+ };
48
+ let charset = MAPEO_CHARSET[encoding];
49
+ if (!charset) {
50
+ charset = "";
51
+ }
52
+ res.writeHead(200, {
53
+ "Content-Type": rta.metadata.contentType + charset,
54
+ "Content-disposition":
55
+ downloadFlag != undefined
56
+ ? "attachment;filename=" + rta.metadata.filename
57
+ : "inline",
58
+ });
59
+ res.end(rta.data);
60
+ }
61
+
62
+ static async readBinary(filePath) {
63
+ //console.log(`readBinary ${filePath}`);
64
+ filePath = filePath.replace(/^[/]/, "");
65
+ try {
66
+ const contents = fs.readFileSync(`${PATH_LOCALS}${filePath}`);
67
+ return contents;
68
+ } catch (err) {
69
+ if (err.code === 'ENOENT') {
70
+ throw new NoExisteException(`Does not exists ${filePath}`);
71
+ } else {
72
+ throw err;
73
+ }
74
+ }
75
+ }
76
+
77
+ static async readString(filePath, encoding = "utf8") {
78
+ //console.log(`readString ${encoding} ${filePath}`);
79
+ const respuesta = await MyFileServiceLocal.readBinary(filePath);
80
+ if (respuesta != null) {
81
+ return respuesta.toString(encoding);
82
+ }
83
+ return null;
84
+ }
85
+
86
+ static async read(originalUrl, encoding = null) {
87
+ //console.log(`read ${encoding} ${originalUrl}`);
88
+ const filePath = decodeURIComponent(originalUrl.replace(/^\//, "").replace(/\?.*$/, ""));
89
+ const fileName = /[^/]+$/.exec(filePath)[0];
90
+
91
+ const metadataPromise = new Promise((resolve, reject) => {
92
+ fs.stat(`${PATH_LOCALS}${filePath}`, (err, stats) => {
93
+ if (err) {
94
+ reject(err);
95
+ } else {
96
+ resolve(stats);
97
+ }
98
+ });
99
+ });
100
+ let contentPromise;
101
+ if (encoding == null) {
102
+ contentPromise = MyFileServiceLocal.readBinary(filePath);
103
+ } else {
104
+ contentPromise = MyFileServiceLocal.readString(filePath, encoding);
105
+ }
106
+ return new Promise((resolve, reject) => {
107
+ Promise.all([metadataPromise, contentPromise]).then(
108
+ function (respuesta) {
109
+ const metadata = respuesta[0];
110
+ metadata.filename = fileName;
111
+ metadata.fullPath = originalUrl;
112
+ if (!metadata.contentType) {
113
+ metadata.contentType = guessMimeType(fileName);
114
+ }
115
+ const content = respuesta[1];
116
+ resolve({
117
+ metadata: metadata,
118
+ data: content,
119
+ });
120
+ },
121
+ function (err) {
122
+ metadataPromise
123
+ .then(() => {
124
+ reject(err);
125
+ })
126
+ .catch((error) => {
127
+ if (error.code == 404) {
128
+ resolve(null);
129
+ } else {
130
+ reject(err);
131
+ }
132
+ });
133
+ }
134
+ );
135
+ });
136
+ }
137
+
138
+ static async deleteFile(req, res, next) {
139
+ const filePath = decodeURIComponent(req.originalUrl.replace(/^\//, "").replace(/\?.*$/, ""));
140
+ const fullPath = `${PATH_LOCALS}${filePath}`;
141
+ await new Promise((resolve, reject) => {
142
+ fs.stat(fullPath, function (err, stats) {
143
+ if (err) {
144
+ reject(err);
145
+ }
146
+ fs.unlink(fullPath, function (err) {
147
+ if (err) {
148
+ reject(err);
149
+ return;
150
+ }
151
+ resolve();
152
+ });
153
+ });
154
+ });
155
+ res.status(204).send();
156
+ }
157
+
158
+ static async listFiles(req, res, next) {
159
+ let localPath = General.readParam(req, "path");
160
+ if (localPath == null) {
161
+ throw new ParametrosIncompletosException("Falta path");
162
+ }
163
+ // Use only slashes
164
+ localPath = localPath.replace(/\\/g, "/");
165
+ // Avoid end with slash
166
+ localPath = localPath.replace(/\/\s*$/g, "");
167
+ // Avoid starts with slash
168
+ localPath = localPath.replace(/^\//, "");
169
+ //passsing directoryPath and callback function
170
+ const fileObjs = fs.readdirSync(`${PATH_LOCALS}${localPath}`, { withFileTypes: true });
171
+ const response = [];
172
+ fileObjs.forEach(function (file) {
173
+ response.push({ name: file.name, path: `${FOLDER_LOCALS}${localPath}/${file.name}` });
174
+ });
175
+ res.status(200).send({ data: response });
176
+ }
177
+ }
package/srv/MyPdf.mjs ADDED
@@ -0,0 +1,37 @@
1
+ import fs from "fs";
2
+ import puppeteer from 'puppeteer';
3
+ import { General } from "./common/General.mjs";
4
+
5
+ export class MyPdf {
6
+ static async localRender(template) {
7
+ const source = fs.readFileSync(`./src/assets/templates/pdf/${template}`, { encoding: "utf8" });
8
+ const browser = await puppeteer.launch({
9
+ headless: 'new',
10
+ executablePath: '/usr/bin/google-chrome',
11
+ args: [
12
+ "--no-sandbox",
13
+ "--disable-gpu",
14
+ ]
15
+ });
16
+ const page = await browser.newPage();
17
+ await page.setContent(source);
18
+ await page.emulateMediaType('print');
19
+ const pdf = await page.pdf({
20
+ margin: { top: '100px', right: '50px', bottom: '100px', left: '50px' },
21
+ printBackground: true,
22
+ format: 'letter',
23
+ });
24
+ await browser.close();
25
+ return pdf;
26
+ }
27
+
28
+ static async render(req, res, next) {
29
+ const template = General.readParam(req, "template");
30
+ const pdf = await MyPdf.localRender(template);
31
+ res.writeHead(200, {
32
+ "Content-Type": "application/pdf",
33
+ "Content-disposition": "inline"
34
+ });
35
+ res.end(pdf);
36
+ }
37
+ }