@drax/crud-back 0.31.0 → 0.33.1

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 (52) hide show
  1. package/dist/controllers/AbstractFastifyController.js +2 -0
  2. package/dist/exports/AbstractExport.js +3 -0
  3. package/dist/exports/ExportCsv.js +15 -6
  4. package/dist/exports/ExportJson.js +0 -0
  5. package/dist/index.js +0 -0
  6. package/dist/regexs/QueryFilterRegex.js +1 -1
  7. package/dist/repository/AbstractMongoRepository.js +0 -0
  8. package/dist/repository/AbstractSqliteRepository.js +0 -0
  9. package/dist/services/AbstractService.js +2 -2
  10. package/dist/workers/ExportCsvWorker.js +0 -0
  11. package/package.json +6 -6
  12. package/src/controllers/AbstractFastifyController.ts +3 -0
  13. package/src/exports/AbstractExport.ts +5 -0
  14. package/src/exports/ExportCsv.ts +19 -8
  15. package/src/regexs/QueryFilterRegex.ts +1 -1
  16. package/src/services/AbstractService.ts +2 -1
  17. package/tsconfig.tsbuildinfo +1 -1
  18. package/types/controllers/AbstractFastifyController.d.ts +1 -0
  19. package/types/controllers/AbstractFastifyController.d.ts.map +1 -1
  20. package/types/exports/AbstractExport.d.ts +2 -0
  21. package/types/exports/AbstractExport.d.ts.map +1 -1
  22. package/types/exports/ExportCsv.d.ts +0 -0
  23. package/types/exports/ExportCsv.d.ts.map +1 -1
  24. package/types/exports/ExportJson.d.ts +0 -0
  25. package/types/exports/ExportJson.d.ts.map +0 -0
  26. package/types/index.d.ts +0 -0
  27. package/types/index.d.ts.map +0 -0
  28. package/types/regexs/QueryFilterRegex.d.ts.map +1 -1
  29. package/types/repository/AbstractMongoRepository.d.ts +0 -0
  30. package/types/repository/AbstractMongoRepository.d.ts.map +0 -0
  31. package/types/repository/AbstractSqliteRepository.d.ts +0 -0
  32. package/types/repository/AbstractSqliteRepository.d.ts.map +0 -0
  33. package/types/schemas/ExportBodyResponseSchema.d.ts +2 -2
  34. package/types/services/AbstractService.d.ts +1 -1
  35. package/types/services/AbstractService.d.ts.map +1 -1
  36. package/types/workers/ExportCsvWorker.d.ts +0 -0
  37. package/types/workers/ExportCsvWorker.d.ts.map +0 -0
  38. package/dist/schemas/PaginateBodySchema.js +0 -20
  39. package/dist/zod/DeleteBodySchema.js +0 -6
  40. package/dist/zod/IdParamSchema.js +0 -6
  41. package/dist/zod/PaginateBodySchema.js +0 -20
  42. package/src/workers/ExportCsvWorker.js +0 -12
  43. package/test/exports/output_base_test.csv/export_50969507-e285-464e-bdd3-3ed1b1854b2e.csv +0 -2
  44. package/test/exports/output_object_test.csv/export_ac96f27e-4fb4-44ed-a025-bf03392d761a.csv +0 -2
  45. package/types/schemas/PaginateBodySchema.d.ts +0 -61
  46. package/types/schemas/PaginateBodySchema.d.ts.map +0 -1
  47. package/types/zod/DeleteBodySchema.d.ts +0 -11
  48. package/types/zod/DeleteBodySchema.d.ts.map +0 -1
  49. package/types/zod/IdParamSchema.d.ts +0 -11
  50. package/types/zod/IdParamSchema.d.ts.map +0 -1
  51. package/types/zod/PaginateBodySchema.d.ts +0 -61
  52. package/types/zod/PaginateBodySchema.d.ts.map +0 -1
@@ -343,6 +343,7 @@ class AbstractFastifyController extends CommonController {
343
343
  request.rbac.assertPermission(this.permission.View);
344
344
  const format = request.query.format || 'JSON';
345
345
  const headers = request.query.headers ? request.query.headers.split(",") : [];
346
+ const headersTranslate = request.query.headersTranslate ? request.query.headersTranslate.split(",") : [];
346
347
  const separator = request.query.separator || ";";
347
348
  const fileName = request.query.fileName || "export";
348
349
  const limit = request.query.limit;
@@ -360,6 +361,7 @@ class AbstractFastifyController extends CommonController {
360
361
  fileName,
361
362
  format,
362
363
  headers,
364
+ headersTranslate,
363
365
  limit,
364
366
  orderBy,
365
367
  order,
@@ -6,6 +6,9 @@ class AbstractExport {
6
6
  this.destinationPath = options.destinationPath;
7
7
  this.headers = Array.isArray(options.headers) ? options.headers : options.headers.split(',');
8
8
  this.fileName = options.fileName;
9
+ if (options.headersTranslate) {
10
+ this.headersTranslate = Array.isArray(options.headersTranslate) ? options.headersTranslate : options.headersTranslate.split(',');
11
+ }
9
12
  }
10
13
  createDirIfNotExist() {
11
14
  createDirIfNotExist(this.destinationPath);
@@ -25,7 +25,9 @@ class ExportCsv extends AbstractExport {
25
25
  time: Date.now() - start,
26
26
  message: 'Export successful',
27
27
  }));
28
- const csvHeaders = this.headers.join(this.separator);
28
+ let csvHeaders = this.headers.join(this.separator);
29
+ if (this.headersTranslate && this.headersTranslate.length)
30
+ csvHeaders = this.headersTranslate.join(this.separator);
29
31
  writableStream.write(csvHeaders + '\n');
30
32
  if (this.isIterableAsync(this.cursor)) {
31
33
  for await (const record of this.cursor) {
@@ -61,24 +63,31 @@ class ExportCsv extends AbstractExport {
61
63
  else {
62
64
  value = record[header];
63
65
  }
64
- if (value === undefined) {
66
+ if (value === undefined || value === null) {
65
67
  fields.push('');
66
68
  continue;
67
69
  }
68
70
  if (Array.isArray(value)) {
69
71
  if (value.length > 0 && typeof value[0] === 'object') {
70
- fields.push(JSON.stringify(value));
72
+ value = JSON.stringify(value);
71
73
  }
72
74
  else {
73
- fields.push(value.join(','));
75
+ value = value.join(',');
74
76
  }
75
77
  }
76
78
  else if (typeof value === 'object') {
77
- fields.push(JSON.stringify(value));
79
+ value = JSON.stringify(value);
78
80
  }
79
81
  else {
80
- fields.push(value.toString());
82
+ value = value.toString();
81
83
  }
84
+ if (value.includes(this.separator) ||
85
+ value.includes('"') ||
86
+ value.includes('\n') ||
87
+ value.includes('\r')) {
88
+ value = '"' + value.replace(/"/g, '""') + '"';
89
+ }
90
+ fields.push(value);
82
91
  }
83
92
  return fields.join(this.separator);
84
93
  }
File without changes
package/dist/index.js CHANGED
File without changes
@@ -1,3 +1,3 @@
1
- const QueryFilterRegex = /^(?:[a-zA-Z0-9_\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_\-:\., áéíóúÁÉÍÓÚ]+)(?:\|[a-zA-Z0-9_\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_\-:\., áéíóúÁÉÍÓÚ]+)*$/;
1
+ const QueryFilterRegex = /^(?:[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]+)(?:\|[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]+)*$/;
2
2
  export default QueryFilterRegex;
3
3
  export { QueryFilterRegex };
File without changes
File without changes
@@ -200,7 +200,7 @@ class AbstractService {
200
200
  throw e;
201
201
  }
202
202
  }
203
- async export({ format = 'JSON', headers = [], separator = ';', fileName = 'export', orderBy = '', order = false, search = '', filters = [] }, destinationPath) {
203
+ async export({ format = 'JSON', headers = [], headersTranslate = [], separator = ';', fileName = 'export', orderBy = '', order = false, search = '', filters = [] }, destinationPath) {
204
204
  try {
205
205
  let cursor;
206
206
  let exporter;
@@ -215,7 +215,7 @@ class AbstractService {
215
215
  exporter = new ExportJson({ cursor, destinationPath: destinationPath, headers, fileName });
216
216
  return await exporter.process();
217
217
  case 'CSV':
218
- exporter = new ExportCsv({ cursor, destinationPath: destinationPath, headers, fileName, separator });
218
+ exporter = new ExportCsv({ cursor, destinationPath: destinationPath, headers, headersTranslate, fileName, separator });
219
219
  return await exporter.process();
220
220
  default:
221
221
  throw new Error(`Unsupported export format: ${format}`);
File without changes
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.31.0",
6
+ "version": "0.33.1",
7
7
  "description": "Crud utils across modules",
8
8
  "main": "dist/index.js",
9
9
  "types": "types/index.d.ts",
@@ -22,10 +22,10 @@
22
22
  "author": "Cristian Incarnato & Drax Team",
23
23
  "license": "ISC",
24
24
  "dependencies": {
25
- "@drax/common-back": "^0.31.0",
26
- "@drax/common-share": "^0.31.0",
27
- "@drax/identity-share": "^0.31.0",
28
- "@drax/media-back": "^0.31.0",
25
+ "@drax/common-back": "^0.33.0",
26
+ "@drax/common-share": "^0.33.0",
27
+ "@drax/identity-share": "^0.33.0",
28
+ "@drax/media-back": "^0.33.1",
29
29
  "@graphql-tools/load-files": "^7.0.0",
30
30
  "@graphql-tools/merge": "^9.0.4",
31
31
  "mongoose": "^8.6.3",
@@ -45,5 +45,5 @@
45
45
  "tsc-alias": "^1.8.10",
46
46
  "typescript": "^5.6.2"
47
47
  },
48
- "gitHead": "01589f8197801c0b8ad13a10d398e41d6cb2a25a"
48
+ "gitHead": "bb0468049ef3388a464c991fa170226739a6f2d2"
49
49
  }
@@ -36,6 +36,7 @@ type CustomRequest = FastifyRequest<{
36
36
  search?: string
37
37
  filters?: string
38
38
  headers?: string
39
+ headersTranslate?: string
39
40
  separator?: string
40
41
  fileName?: string
41
42
  }
@@ -464,6 +465,7 @@ class AbstractFastifyController<T, C, U> extends CommonController {
464
465
 
465
466
  const format = request.query.format as 'CSV' | 'JSON' || 'JSON'
466
467
  const headers = request.query.headers ? request.query.headers.split(",") : []
468
+ const headersTranslate = request.query.headersTranslate ? request.query.headersTranslate.split(",") : []
467
469
  const separator = request.query.separator || ";"
468
470
  const fileName = request.query.fileName || "export"
469
471
  const limit = request.query.limit
@@ -485,6 +487,7 @@ class AbstractFastifyController<T, C, U> extends CommonController {
485
487
  fileName,
486
488
  format,
487
489
  headers,
490
+ headersTranslate,
488
491
  limit,
489
492
  orderBy,
490
493
  order,
@@ -6,6 +6,7 @@ interface ExportOptions {
6
6
  cursor: any
7
7
  destinationPath: string
8
8
  headers: string[] | string
9
+ headersTranslate?: string[] | string
9
10
  fileName: string
10
11
  }
11
12
 
@@ -16,6 +17,7 @@ class AbstractExport {
16
17
  protected cursor: any
17
18
  protected destinationPath: string
18
19
  protected headers: string[]
20
+ protected headersTranslate?: string[]
19
21
 
20
22
  protected fileName: string
21
23
  protected relativeFilePath: string
@@ -25,6 +27,9 @@ class AbstractExport {
25
27
  this.destinationPath = options.destinationPath;
26
28
  this.headers = Array.isArray(options.headers) ? options.headers : options.headers.split(',');
27
29
  this.fileName = options.fileName;
30
+ if(options.headersTranslate){
31
+ this.headersTranslate = Array.isArray(options.headersTranslate) ? options.headersTranslate : options.headersTranslate.split(',');
32
+ }
28
33
  }
29
34
 
30
35
 
@@ -40,8 +40,9 @@ class ExportCsv extends AbstractExport {
40
40
  message: 'Export successful',
41
41
  }))
42
42
 
43
+ let csvHeaders = this.headers.join(this.separator);
44
+ if(this.headersTranslate && this.headersTranslate.length) csvHeaders = this.headersTranslate.join(this.separator)
43
45
 
44
- const csvHeaders = this.headers.join(this.separator);
45
46
  writableStream.write(csvHeaders + '\n');
46
47
 
47
48
  if (this.isIterableAsync(this.cursor)) {
@@ -81,27 +82,37 @@ class ExportCsv extends AbstractExport {
81
82
  value = record[header];
82
83
  }
83
84
 
84
- if (value === undefined) {
85
+ if (value === undefined || value === null) {
85
86
  fields.push('');
86
87
  continue;
87
88
  }
88
89
 
89
90
  if (Array.isArray(value)) {
90
91
  if (value.length > 0 && typeof value[0] === 'object') {
91
- fields.push(JSON.stringify(value));
92
+ value = JSON.stringify(value);
92
93
  } else {
93
- fields.push(value.join(','));
94
+ value = value.join(',');
94
95
  }
95
96
  } else if (typeof value === 'object') {
96
- fields.push(JSON.stringify(value));
97
-
97
+ value = JSON.stringify(value);
98
98
  } else {
99
- fields.push(value.toString());
99
+ value = value.toString();
100
+ }
101
+
102
+ if (
103
+ value.includes(this.separator) ||
104
+ value.includes('"') ||
105
+ value.includes('\n') ||
106
+ value.includes('\r')
107
+ ) {
108
+ value = '"' + value.replace(/"/g, '""') + '"';
100
109
  }
110
+
111
+ fields.push(value);
101
112
  }
102
113
  return fields.join(this.separator);
103
114
  }
104
115
 
105
116
  }
106
117
 
107
- export default ExportCsv;
118
+ export default ExportCsv;
@@ -1,4 +1,4 @@
1
- const QueryFilterRegex = /^(?:[a-zA-Z0-9_\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_\-:\., áéíóúÁÉÍÓÚ]+)(?:\|[a-zA-Z0-9_\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_\-:\., áéíóúÁÉÍÓÚ]+)*$/
1
+ const QueryFilterRegex = /^(?:[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]+)(?:\|[a-zA-Z0-9_.\-]+;(?:eq|like|ne|in|nin|gt|gte|lt|lte);[a-zA-Z0-9_.\-:\., áéíóúÁÉÍÓÚ]+)*$/
2
2
 
3
3
  export default QueryFilterRegex
4
4
  export {QueryFilterRegex}
@@ -265,6 +265,7 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
265
265
  async export({
266
266
  format = 'JSON',
267
267
  headers = [],
268
+ headersTranslate = [],
268
269
  separator = ';',
269
270
  fileName = 'export',
270
271
  orderBy = '',
@@ -289,7 +290,7 @@ abstract class AbstractService<T, C, U> implements IDraxCrudService<T, C, U> {
289
290
  exporter = new ExportJson({cursor, destinationPath: destinationPath, headers, fileName});
290
291
  return await exporter.process()
291
292
  case 'CSV':
292
- exporter = new ExportCsv({cursor, destinationPath: destinationPath, headers, fileName, separator});
293
+ exporter = new ExportCsv({cursor, destinationPath: destinationPath, headers, headersTranslate, fileName, separator});
293
294
  return await exporter.process()
294
295
  default:
295
296
  throw new Error(`Unsupported export format: ${format}`);