@natlibfi/melinda-rest-api-commons 2.2.0-alpha.1 → 2.2.0-alpha.12

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 CHANGED
@@ -10,27 +10,30 @@ Shared modules for microservices of Melinda rest api import system
10
10
 
11
11
  #### QueueItemState flow for bulk jobs (multiple records, no validations):
12
12
 
13
- |microservice | states |
14
- |-------------| -------------------------------------------------------------------------|
15
- |`http` | -> VALIDATOR.UPLOADING -> VALIDATOR.PENDING_QUEUING -> |
16
- |`validator` | VALIDATOR.QUEUING_IN_PROGRESS -> IMPORTER.IN_QUEUE -> |
17
- |`importer` | IMPORTER.IMPORTING -> IMPORTER.IN_PROCESS -> IMPORTER.IMPORTING -> DONE |
18
- | | |
19
- |any | any -> ERROR if errored
13
+ | microservice | states |
14
+ |--------------|--------------------------------------------------------|
15
+ | `http` | -> VALIDATOR.UPLOADING -> VALIDATOR.PENDING_QUEUING -> |
16
+ | `validator` | VALIDATOR.QUEUING_IN_PROGRESS -> IMPORTER.IN_QUEUE -> |
17
+ | `importer` | IMPORTER.IMPORTING -> IMPORT_JOB_STATEs* -> DONE |
18
+ | | |
19
+ | any | any -> ERROR if errored |
20
20
 
21
+ *IMPORT_JOB_STATEs: EMPTY or IN_QUEUE, PROCESSING -> final: DONE, ERROR, ABORT
21
22
 
22
23
  #### QueueItemState flow for prio jobs (single record):
23
24
 
24
- |microservice | states |
25
- |-------------| -------------------------------------------------------------------------|
26
- |`http` | -> VALIDATOR.PENDING_VALIDATION -> |
27
- |`validator` | VALIDATOR.VALIDATING -> IMPORTER.IN_QUEUE -> |
28
- |`importer` | IMPORTER.IMPORTING -> IMPORTER.IN_PROCESS -> DONE |
29
- | | |
30
- |`http` | any -> ABORT if job has stayed in an active state too long |
31
- |`validator` | VALIDATOR.VALIDATING -> DONE for noop (no-operation) jobs |
32
- | | |
33
- | any | any -> ERROR if errored |
25
+ | microservice | states |
26
+ |--------------|------------------------------------------------------------|
27
+ | `http` | -> VALIDATOR.PENDING_VALIDATION -> |
28
+ | `validator` | VALIDATOR.VALIDATING -> IMPORTER.IN_QUEUE -> |
29
+ | `importer` | IMPORTER.IMPORTING -> IMPORT_JOB_STATEs* -> DONE |
30
+ | | |
31
+ | `http` | any -> ABORT if job has stayed in an active state too long |
32
+ | `validator` | VALIDATOR.VALIDATING -> DONE for noop (no-operation) jobs |
33
+ | | |
34
+ | any | any -> ERROR if errored |
35
+
36
+ *IMPORT_JOB_STATEs: EMPTY or IN_QUEUE, PROCESSING -> final: DONE, ERROR, ABORT
34
37
 
35
38
  ### CHUNK_SIZE
36
39
  Chunck size to execution time ratio (From file to queue: ~450 records in 15sec)
package/dist/constants.js CHANGED
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.conversionFormats = exports.QUEUE_ITEM_STATE = exports.OPERATIONS = exports.CHUNK_SIZE = void 0;
6
+ exports.QUEUE_ITEM_STATE = exports.OPERATIONS = exports.IMPORT_JOB_STATE = exports.CONVERSION_FORMATS = exports.CHUNK_SIZE = void 0;
7
7
 
8
8
  /**
9
9
  *
@@ -52,6 +52,17 @@ const QUEUE_ITEM_STATE = {
52
52
  ABORT: 'ABORT'
53
53
  };
54
54
  exports.QUEUE_ITEM_STATE = QUEUE_ITEM_STATE;
55
+ const IMPORT_JOB_STATE = {
56
+ EMPTY: 'EMPTY',
57
+ QUEUING: 'QUEUING',
58
+ IN_QUEUE: 'IN_QUEUE',
59
+ IMPORTING: 'IMPORTING',
60
+ PROCESSING: 'PROCESSING',
61
+ DONE: 'DONE',
62
+ ERROR: 'ERROR',
63
+ ABORT: 'ABORT'
64
+ };
65
+ exports.IMPORT_JOB_STATE = IMPORT_JOB_STATE;
55
66
  const OPERATIONS = {
56
67
  CREATE: 'CREATE',
57
68
  UPDATE: 'UPDATE'
@@ -59,10 +70,11 @@ const OPERATIONS = {
59
70
  exports.OPERATIONS = OPERATIONS;
60
71
  const CHUNK_SIZE = 100;
61
72
  exports.CHUNK_SIZE = CHUNK_SIZE;
62
- const conversionFormats = {
63
- MARCXML: 1,
64
- ISO2709: 2,
65
- JSON: 3
73
+ const CONVERSION_FORMATS = {
74
+ MARCXML: 'MARCXML',
75
+ ISO2709: 'ISO2709',
76
+ JSON: 'JSON',
77
+ ALEPHSEQ: 'ALEPHSEQ'
66
78
  };
67
- exports.conversionFormats = conversionFormats;
79
+ exports.CONVERSION_FORMATS = CONVERSION_FORMATS;
68
80
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.js"],"names":["QUEUE_ITEM_STATE","VALIDATOR","PENDING_QUEUING","PENDING_VALIDATION","QUEUING_IN_PROGRESS","UPLOADING","VALIDATING","WAITING_FOR_RECORDS","IMPORTER","IMPORTING","IN_PROCESS","IN_QUEUE","DONE","ERROR","ABORT","OPERATIONS","CREATE","UPDATE","CHUNK_SIZE","conversionFormats","MARCXML","ISO2709","JSON"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEO,MAAMA,gBAAgB,GAAG;AAC9BC,EAAAA,SAAS,EAAE;AACTC,IAAAA,eAAe,EAAE,iBADR;AAETC,IAAAA,kBAAkB,EAAE,oBAFX;AAGTC,IAAAA,mBAAmB,EAAE,qBAHZ;AAITC,IAAAA,SAAS,EAAE,WAJF;AAKTC,IAAAA,UAAU,EAAE,YALH;AAMTC,IAAAA,mBAAmB,EAAE;AANZ,GADmB;AAS9BC,EAAAA,QAAQ,EAAE;AACRC,IAAAA,SAAS,EAAE,WADH;AAERC,IAAAA,UAAU,EAAE,YAFJ;AAGRC,IAAAA,QAAQ,EAAE;AAHF,GAToB;AAc9BC,EAAAA,IAAI,EAAE,MAdwB;AAe9BC,EAAAA,KAAK,EAAE,OAfuB;AAgB9BC,EAAAA,KAAK,EAAE;AAhBuB,CAAzB;;AAmBA,MAAMC,UAAU,GAAG;AACxBC,EAAAA,MAAM,EAAE,QADgB;AAExBC,EAAAA,MAAM,EAAE;AAFgB,CAAnB;;AAKA,MAAMC,UAAU,GAAG,GAAnB;;AAEA,MAAMC,iBAAiB,GAAG;AAC/BC,EAAAA,OAAO,EAAE,CADsB;AAE/BC,EAAAA,OAAO,EAAE,CAFsB;AAG/BC,EAAAA,IAAI,EAAE;AAHyB,CAA1B","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\n// QueueItemState flows: see README.md\n\nexport const QUEUE_ITEM_STATE = {\n VALIDATOR: {\n PENDING_QUEUING: 'PENDING_QUEUING',\n PENDING_VALIDATION: 'PENDING_VALIDATION',\n QUEUING_IN_PROGRESS: 'QUEUING_IN_PROGRESS',\n UPLOADING: 'UPLOADING',\n VALIDATING: 'VALIDATING',\n WAITING_FOR_RECORDS: 'WAITING_FOR_RECORDS'\n },\n IMPORTER: {\n IMPORTING: 'IMPORTING',\n IN_PROCESS: 'IN_PROCESS',\n IN_QUEUE: 'IN_QUEUE'\n },\n DONE: 'DONE',\n ERROR: 'ERROR',\n ABORT: 'ABORT'\n};\n\nexport const OPERATIONS = {\n CREATE: 'CREATE',\n UPDATE: 'UPDATE'\n};\n\nexport const CHUNK_SIZE = 100;\n\nexport const conversionFormats = {\n MARCXML: 1,\n ISO2709: 2,\n JSON: 3\n};\n"],"file":"constants.js"}
1
+ {"version":3,"sources":["../src/constants.js"],"names":["QUEUE_ITEM_STATE","VALIDATOR","PENDING_QUEUING","PENDING_VALIDATION","QUEUING_IN_PROGRESS","UPLOADING","VALIDATING","WAITING_FOR_RECORDS","IMPORTER","IMPORTING","IN_PROCESS","IN_QUEUE","DONE","ERROR","ABORT","IMPORT_JOB_STATE","EMPTY","QUEUING","PROCESSING","OPERATIONS","CREATE","UPDATE","CHUNK_SIZE","CONVERSION_FORMATS","MARCXML","ISO2709","JSON","ALEPHSEQ"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAEO,MAAMA,gBAAgB,GAAG;AAC9BC,EAAAA,SAAS,EAAE;AACTC,IAAAA,eAAe,EAAE,iBADR;AAETC,IAAAA,kBAAkB,EAAE,oBAFX;AAGTC,IAAAA,mBAAmB,EAAE,qBAHZ;AAITC,IAAAA,SAAS,EAAE,WAJF;AAKTC,IAAAA,UAAU,EAAE,YALH;AAMTC,IAAAA,mBAAmB,EAAE;AANZ,GADmB;AAS9BC,EAAAA,QAAQ,EAAE;AACRC,IAAAA,SAAS,EAAE,WADH;AAERC,IAAAA,UAAU,EAAE,YAFJ;AAGRC,IAAAA,QAAQ,EAAE;AAHF,GAToB;AAc9BC,EAAAA,IAAI,EAAE,MAdwB;AAe9BC,EAAAA,KAAK,EAAE,OAfuB;AAgB9BC,EAAAA,KAAK,EAAE;AAhBuB,CAAzB;;AAmBA,MAAMC,gBAAgB,GAAG;AAC9BC,EAAAA,KAAK,EAAE,OADuB;AAE9BC,EAAAA,OAAO,EAAE,SAFqB;AAG9BN,EAAAA,QAAQ,EAAE,UAHoB;AAI9BF,EAAAA,SAAS,EAAE,WAJmB;AAK9BS,EAAAA,UAAU,EAAE,YALkB;AAM9BN,EAAAA,IAAI,EAAE,MANwB;AAO9BC,EAAAA,KAAK,EAAE,OAPuB;AAQ9BC,EAAAA,KAAK,EAAE;AARuB,CAAzB;;AAWA,MAAMK,UAAU,GAAG;AACxBC,EAAAA,MAAM,EAAE,QADgB;AAExBC,EAAAA,MAAM,EAAE;AAFgB,CAAnB;;AAKA,MAAMC,UAAU,GAAG,GAAnB;;AAEA,MAAMC,kBAAkB,GAAG;AAChCC,EAAAA,OAAO,EAAE,SADuB;AAEhCC,EAAAA,OAAO,EAAE,SAFuB;AAGhCC,EAAAA,IAAI,EAAE,MAH0B;AAIhCC,EAAAA,QAAQ,EAAE;AAJsB,CAA3B","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\n// QueueItemState flows: see README.md\n\nexport const QUEUE_ITEM_STATE = {\n VALIDATOR: {\n PENDING_QUEUING: 'PENDING_QUEUING',\n PENDING_VALIDATION: 'PENDING_VALIDATION',\n QUEUING_IN_PROGRESS: 'QUEUING_IN_PROGRESS',\n UPLOADING: 'UPLOADING',\n VALIDATING: 'VALIDATING',\n WAITING_FOR_RECORDS: 'WAITING_FOR_RECORDS'\n },\n IMPORTER: {\n IMPORTING: 'IMPORTING',\n IN_PROCESS: 'IN_PROCESS',\n IN_QUEUE: 'IN_QUEUE'\n },\n DONE: 'DONE',\n ERROR: 'ERROR',\n ABORT: 'ABORT'\n};\n\nexport const IMPORT_JOB_STATE = {\n EMPTY: 'EMPTY',\n QUEUING: 'QUEUING',\n IN_QUEUE: 'IN_QUEUE',\n IMPORTING: 'IMPORTING',\n PROCESSING: 'PROCESSING',\n DONE: 'DONE',\n ERROR: 'ERROR',\n ABORT: 'ABORT'\n};\n\nexport const OPERATIONS = {\n CREATE: 'CREATE',\n UPDATE: 'UPDATE'\n};\n\nexport const CHUNK_SIZE = 100;\n\nexport const CONVERSION_FORMATS = {\n MARCXML: 'MARCXML',\n ISO2709: 'ISO2709',\n JSON: 'JSON',\n ALEPHSEQ: 'ALEPHSEQ'\n};\n"],"file":"constants.js"}
@@ -51,24 +51,28 @@ function _default() {
51
51
  return {
52
52
  serialize,
53
53
  unserialize
54
- };
54
+ }; // This uses format as a number form contants CONVERSION_FORMATS
55
55
 
56
56
  function serialize(record, format) {
57
57
  logger.verbose(`Serializing record to ${format}`);
58
58
 
59
59
  try {
60
- if (format === _constants.conversionFormats.MARCXML) {
60
+ if (format === _constants.CONVERSION_FORMATS.MARCXML) {
61
61
  return _marcRecordSerializers.MARCXML.to(record);
62
62
  }
63
63
 
64
- if (format === _constants.conversionFormats.ISO2709) {
64
+ if (format === _constants.CONVERSION_FORMATS.ISO2709) {
65
65
  return _marcRecordSerializers.ISO2709.to(record);
66
66
  }
67
67
 
68
- if (format === _constants.conversionFormats.JSON) {
68
+ if (format === _constants.CONVERSION_FORMATS.JSON) {
69
69
  return _marcRecordSerializers.Json.to(record);
70
70
  }
71
71
 
72
+ if (format === _constants.CONVERSION_FORMATS.ALEPHSEQ) {
73
+ return _marcRecordSerializers.AlephSequential.to(record);
74
+ }
75
+
72
76
  throw new _melindaCommons.Error(_httpStatus.default.UNSUPPORTED_MEDIA_TYPE);
73
77
  } catch (err) {
74
78
  (0, _utils.logError)(err);
@@ -80,7 +84,8 @@ function _default() {
80
84
 
81
85
  throw new _melindaCommons.Error(_httpStatus.default.BAD_REQUEST, 'Error while serializing record');
82
86
  }
83
- }
87
+ } // eslint-disable-next-line max-statements
88
+
84
89
 
85
90
  function unserialize(data, format, validationOptions = {
86
91
  subfieldValues: false
@@ -91,21 +96,26 @@ function _default() {
91
96
  logger.silly(`Data: ${JSON.stringify(data)}`);
92
97
 
93
98
  try {
94
- if (format === _constants.conversionFormats.MARCXML) {
99
+ if (format === _constants.CONVERSION_FORMATS.MARCXML) {
95
100
  logger.silly('Unserialize format marcxml');
96
101
  return _marcRecordSerializers.MARCXML.from(data, validationOptions);
97
102
  }
98
103
 
99
- if (format === _constants.conversionFormats.ISO2709) {
104
+ if (format === _constants.CONVERSION_FORMATS.ISO2709) {
100
105
  logger.silly('Unserialize format iso2709');
101
106
  return _marcRecordSerializers.ISO2709.from(data, validationOptions);
102
107
  }
103
108
 
104
- if (format === _constants.conversionFormats.JSON) {
109
+ if (format === _constants.CONVERSION_FORMATS.JSON) {
105
110
  logger.silly('Unserialize format json');
106
111
  return _marcRecordSerializers.Json.from(data, validationOptions);
107
112
  }
108
113
 
114
+ if (format === _constants.CONVERSION_FORMATS.ALEPHSEQ) {
115
+ logger.silly('Unserialize format aleph sequential');
116
+ return _marcRecordSerializers.AlephSequential.from(data, validationOptions);
117
+ }
118
+
109
119
  throw new _melindaCommons.Error(_httpStatus.default.UNSUPPORTED_MEDIA_TYPE);
110
120
  } catch (err) {
111
121
  (0, _utils.logError)(err);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/helpers/conversion.js"],"names":["logger","serialize","unserialize","record","format","verbose","conversionFormats","MARCXML","to","ISO2709","JSON","Json","ConversionError","httpStatus","UNSUPPORTED_MEDIA_TYPE","err","BAD_REQUEST","data","validationOptions","subfieldValues","silly","debug","stringify","from"],"mappings":";;;;;;;AA4BA;;AACA;;AACA;;AACA;;AACA;;AACA;;;;AAjCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AASe,oBAAY;AACzB,QAAMA,MAAM,GAAG,0CAAf;AAEA,SAAO;AAACC,IAAAA,SAAD;AAAYC,IAAAA;AAAZ,GAAP;;AAEA,WAASD,SAAT,CAAmBE,MAAnB,EAA2BC,MAA3B,EAAmC;AACjCJ,IAAAA,MAAM,CAACK,OAAP,CAAgB,yBAAwBD,MAAO,EAA/C;;AACA,QAAI;AACF,UAAIA,MAAM,KAAKE,6BAAkBC,OAAjC,EAA0C;AACxC,eAAOA,+BAAQC,EAAR,CAAWL,MAAX,CAAP;AACD;;AAED,UAAIC,MAAM,KAAKE,6BAAkBG,OAAjC,EAA0C;AACxC,eAAOA,+BAAQD,EAAR,CAAWL,MAAX,CAAP;AACD;;AAED,UAAIC,MAAM,KAAKE,6BAAkBI,IAAjC,EAAuC;AACrC,eAAOC,4BAAKH,EAAL,CAAQL,MAAR,CAAP;AACD;;AAED,YAAM,IAAIS,qBAAJ,CAAoBC,oBAAWC,sBAA/B,CAAN;AACD,KAdD,CAcE,OAAOC,GAAP,EAAY;AACZ,2BAASA,GAAT;;AACA,UAAIA,GAAG,YAAYH,qBAAnB,EAAoC;AAAE;AACpC,cAAMG,GAAN;AACD;;AACD,YAAM,IAAIH,qBAAJ,CAAoBC,oBAAWG,WAA/B,EAA4C,gCAA5C,CAAN;AACD;AACF;;AAED,WAASd,WAAT,CAAqBe,IAArB,EAA2Bb,MAA3B,EAAmCc,iBAAiB,GAAG;AAACC,IAAAA,cAAc,EAAE;AAAjB,GAAvD,EAAgF;AAC9EnB,IAAAA,MAAM,CAACK,OAAP,CAAgB,6BAA4BD,MAAO,EAAnD;AACAJ,IAAAA,MAAM,CAACoB,KAAP,CAAc,WAAUhB,MAAO,EAA/B;AACAJ,IAAAA,MAAM,CAACqB,KAAP,CAAc,uBAAsBX,IAAI,CAACY,SAAL,CAAeJ,iBAAf,CAAkC,EAAtE;AACAlB,IAAAA,MAAM,CAACoB,KAAP,CAAc,SAAQV,IAAI,CAACY,SAAL,CAAeL,IAAf,CAAqB,EAA3C;;AACA,QAAI;AACF,UAAIb,MAAM,KAAKE,6BAAkBC,OAAjC,EAA0C;AACxCP,QAAAA,MAAM,CAACoB,KAAP,CAAa,4BAAb;AACA,eAAOb,+BAAQgB,IAAR,CAAaN,IAAb,EAAmBC,iBAAnB,CAAP;AACD;;AAED,UAAId,MAAM,KAAKE,6BAAkBG,OAAjC,EAA0C;AACxCT,QAAAA,MAAM,CAACoB,KAAP,CAAa,4BAAb;AACA,eAAOX,+BAAQc,IAAR,CAAaN,IAAb,EAAmBC,iBAAnB,CAAP;AACD;;AAED,UAAId,MAAM,KAAKE,6BAAkBI,IAAjC,EAAuC;AACrCV,QAAAA,MAAM,CAACoB,KAAP,CAAa,yBAAb;AACA,eAAOT,4BAAKY,IAAL,CAAUN,IAAV,EAAgBC,iBAAhB,CAAP;AACD;;AAED,YAAM,IAAIN,qBAAJ,CAAoBC,oBAAWC,sBAA/B,CAAN;AACD,KAjBD,CAiBE,OAAOC,GAAP,EAAY;AACZ,2BAASA,GAAT;;AACA,UAAIA,GAAG,YAAYH,qBAAnB,EAAoC;AAAE;AACpC,cAAMG,GAAN;AACD;;AACD,YAAM,IAAIH,qBAAJ,CAAoBC,oBAAWG,WAA/B,EAA4C,kCAA5C,CAAN;AACD;AACF;AACF","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport httpStatus from 'http-status';\nimport {MARCXML, ISO2709, Json} from '@natlibfi/marc-record-serializers';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ConversionError} from '@natlibfi/melinda-commons';\nimport {conversionFormats} from '../constants';\nimport {logError} from '../utils';\n\nexport default function () {\n const logger = createLogger();\n\n return {serialize, unserialize};\n\n function serialize(record, format) {\n logger.verbose(`Serializing record to ${format}`);\n try {\n if (format === conversionFormats.MARCXML) {\n return MARCXML.to(record);\n }\n\n if (format === conversionFormats.ISO2709) {\n return ISO2709.to(record);\n }\n\n if (format === conversionFormats.JSON) {\n return Json.to(record);\n }\n\n throw new ConversionError(httpStatus.UNSUPPORTED_MEDIA_TYPE);\n } catch (err) {\n logError(err);\n if (err instanceof ConversionError) { // eslint-disable-line functional/no-conditional-statement\n throw err;\n }\n throw new ConversionError(httpStatus.BAD_REQUEST, 'Error while serializing record');\n }\n }\n\n function unserialize(data, format, validationOptions = {subfieldValues: false}) {\n logger.verbose(`Unserializing record from ${format}`);\n logger.silly(`Format: ${format}`);\n logger.debug(`Validation options: ${JSON.stringify(validationOptions)}`);\n logger.silly(`Data: ${JSON.stringify(data)}`);\n try {\n if (format === conversionFormats.MARCXML) {\n logger.silly('Unserialize format marcxml');\n return MARCXML.from(data, validationOptions);\n }\n\n if (format === conversionFormats.ISO2709) {\n logger.silly('Unserialize format iso2709');\n return ISO2709.from(data, validationOptions);\n }\n\n if (format === conversionFormats.JSON) {\n logger.silly('Unserialize format json');\n return Json.from(data, validationOptions);\n }\n\n throw new ConversionError(httpStatus.UNSUPPORTED_MEDIA_TYPE);\n } catch (err) {\n logError(err);\n if (err instanceof ConversionError) { // eslint-disable-line functional/no-conditional-statement\n throw err;\n }\n throw new ConversionError(httpStatus.BAD_REQUEST, 'Error while unserializing record');\n }\n }\n}\n"],"file":"conversion.js"}
1
+ {"version":3,"sources":["../../src/helpers/conversion.js"],"names":["logger","serialize","unserialize","record","format","verbose","CONVERSION_FORMATS","MARCXML","to","ISO2709","JSON","Json","ALEPHSEQ","AlephSequential","ConversionError","httpStatus","UNSUPPORTED_MEDIA_TYPE","err","BAD_REQUEST","data","validationOptions","subfieldValues","silly","debug","stringify","from"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport httpStatus from 'http-status';\nimport {MARCXML, ISO2709, Json, AlephSequential} from '@natlibfi/marc-record-serializers';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ConversionError} from '@natlibfi/melinda-commons';\nimport {CONVERSION_FORMATS} from '../constants';\nimport {logError} from '../utils';\n\nexport default function () {\n const logger = createLogger();\n\n return {serialize, unserialize};\n\n // This uses format as a number form contants CONVERSION_FORMATS\n function serialize(record, format) {\n logger.verbose(`Serializing record to ${format}`);\n try {\n if (format === CONVERSION_FORMATS.MARCXML) {\n return MARCXML.to(record);\n }\n\n if (format === CONVERSION_FORMATS.ISO2709) {\n return ISO2709.to(record);\n }\n\n if (format === CONVERSION_FORMATS.JSON) {\n return Json.to(record);\n }\n\n if (format === CONVERSION_FORMATS.ALEPHSEQ) {\n return AlephSequential.to(record);\n }\n\n throw new ConversionError(httpStatus.UNSUPPORTED_MEDIA_TYPE);\n } catch (err) {\n logError(err);\n if (err instanceof ConversionError) { // eslint-disable-line functional/no-conditional-statement\n throw err;\n }\n throw new ConversionError(httpStatus.BAD_REQUEST, 'Error while serializing record');\n }\n }\n\n // eslint-disable-next-line max-statements\n function unserialize(data, format, validationOptions = {subfieldValues: false}) {\n logger.verbose(`Unserializing record from ${format}`);\n logger.silly(`Format: ${format}`);\n logger.debug(`Validation options: ${JSON.stringify(validationOptions)}`);\n logger.silly(`Data: ${JSON.stringify(data)}`);\n try {\n if (format === CONVERSION_FORMATS.MARCXML) {\n logger.silly('Unserialize format marcxml');\n return MARCXML.from(data, validationOptions);\n }\n\n if (format === CONVERSION_FORMATS.ISO2709) {\n logger.silly('Unserialize format iso2709');\n return ISO2709.from(data, validationOptions);\n }\n\n if (format === CONVERSION_FORMATS.JSON) {\n logger.silly('Unserialize format json');\n return Json.from(data, validationOptions);\n }\n\n if (format === CONVERSION_FORMATS.ALEPHSEQ) {\n logger.silly('Unserialize format aleph sequential');\n return AlephSequential.from(data, validationOptions);\n }\n\n throw new ConversionError(httpStatus.UNSUPPORTED_MEDIA_TYPE);\n } catch (err) {\n logError(err);\n if (err instanceof ConversionError) { // eslint-disable-line functional/no-conditional-statement\n throw err;\n }\n throw new ConversionError(httpStatus.BAD_REQUEST, 'Error while unserializing record');\n }\n }\n}\n"],"file":"conversion.js"}
@@ -62,6 +62,9 @@ describe('services/conversion', () => {
62
62
  const json = getFixture({
63
63
  components: ['json1']
64
64
  });
65
+ const alephSeq = getFixture({
66
+ components: ['aleph_sequential']
67
+ });
65
68
  describe('factory', () => {
66
69
  it('Should create the expected object', () => {
67
70
  const service = (0, _conversion.default)();
@@ -73,37 +76,45 @@ describe('services/conversion', () => {
73
76
  (0, _chai.expect)(conversionService.serialize).to.throw();
74
77
  });
75
78
  it('Should serialize to MARCXML', () => {
76
- const data = conversionService.serialize(marcRecord, _constants.conversionFormats.MARCXML);
79
+ const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.MARCXML);
77
80
  (0, _chai.expect)(data).to.equal(marcXml);
78
81
  });
79
82
  it('Should serialize to ISO2709', () => {
80
- const data = conversionService.serialize(marcRecord, _constants.conversionFormats.ISO2709);
83
+ const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.ISO2709);
81
84
  (0, _chai.expect)(data).to.equal(iso2709);
82
85
  });
83
86
  it('Should serialize to JSON', () => {
84
- const data = conversionService.serialize(marcRecord, _constants.conversionFormats.JSON);
87
+ const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.JSON);
85
88
  (0, _chai.expect)(data).to.equal(json);
86
89
  });
90
+ it('Should serialize to aleph sequential', () => {
91
+ const data = conversionService.serialize(marcRecord, _constants.CONVERSION_FORMATS.ALEPHSEQ);
92
+ (0, _chai.expect)(data).to.equal(alephSeq);
93
+ });
87
94
  });
88
95
  describe('#unserialize', () => {
89
96
  it('Should throw because of unsupported format', () => {
90
97
  (0, _chai.expect)(conversionService.unserialize).to.throw();
91
98
  });
92
99
  it('Should unserialize from MARCXML', async () => {
93
- const record = await conversionService.unserialize(marcXml, _constants.conversionFormats.MARCXML);
100
+ const record = await conversionService.unserialize(marcXml, _constants.CONVERSION_FORMATS.MARCXML);
94
101
  (0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
95
102
  });
96
103
  it('Should unserialize from ISO2709', () => {
97
- const record = conversionService.unserialize(iso2709, _constants.conversionFormats.ISO2709);
104
+ const record = conversionService.unserialize(iso2709, _constants.CONVERSION_FORMATS.ISO2709);
98
105
  (0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
99
106
  });
100
107
  it('Should unserialize from JSON', () => {
101
- const record = conversionService.unserialize(json, _constants.conversionFormats.JSON);
108
+ const record = conversionService.unserialize(json, _constants.CONVERSION_FORMATS.JSON);
109
+ (0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
110
+ });
111
+ it('Should unserialize from Aleph sequential', () => {
112
+ const record = conversionService.unserialize(alephSeq, _constants.CONVERSION_FORMATS.ALEPHSEQ);
102
113
  (0, _chai.expect)(record.equalsTo(marcRecord)).to.equal(true);
103
114
  });
104
115
  it('Should throw because the record could not be unserialized', () => {
105
116
  (0, _chai.expect)(() => {
106
- conversionService.unserialize('', _constants.conversionFormats.JSON);
117
+ conversionService.unserialize('', _constants.CONVERSION_FORMATS.JSON);
107
118
  }).to.throw(_melindaCommons.Error);
108
119
  });
109
120
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/helpers/conversion.spec.js"],"names":["describe","getFixture","root","__dirname","conversionService","marcRecord","MarcRecord","JSON","parse","components","subfieldValues","marcXml","iso2709","json","it","service","to","be","an","and","respondTo","serialize","throw","data","conversionFormats","MARCXML","equal","ISO2709","unserialize","record","equalsTo","ConversionError"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {expect} from 'chai';\nimport fixtureFactory from '@natlibfi/fixura';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {Error as ConversionError} from '@natlibfi/melinda-commons';\nimport createConversionService from './conversion';\nimport {conversionFormats} from '../constants';\n\ndescribe('services/conversion', () => {\n const {getFixture} = fixtureFactory({root: [\n __dirname,\n '..',\n '..',\n 'test-fixtures',\n 'conversion'\n ]});\n const conversionService = createConversionService();\n\n const marcRecord = new MarcRecord(JSON.parse(getFixture({components: ['json1']})), {subfieldValues: false});\n const marcXml = getFixture({components: ['marcxml1']});\n const iso2709 = getFixture({components: ['iso2709_1']});\n const json = getFixture({components: ['json1']});\n\n describe('factory', () => {\n it('Should create the expected object', () => {\n const service = createConversionService();\n expect(service).to.be.an('object').and\n .respondTo('serialize')\n .respondTo('unserialize');\n });\n });\n\n describe('#serialize', () => {\n it('Should throw because of unsupported format', () => {\n expect(conversionService.serialize).to.throw();\n });\n\n it('Should serialize to MARCXML', () => {\n const data = conversionService.serialize(marcRecord, conversionFormats.MARCXML);\n expect(data).to.equal(marcXml);\n });\n\n it('Should serialize to ISO2709', () => {\n const data = conversionService.serialize(marcRecord, conversionFormats.ISO2709);\n expect(data).to.equal(iso2709);\n });\n\n it('Should serialize to JSON', () => {\n const data = conversionService.serialize(marcRecord, conversionFormats.JSON);\n expect(data).to.equal(json);\n });\n });\n\n describe('#unserialize', () => {\n it('Should throw because of unsupported format', () => {\n expect(conversionService.unserialize).to.throw();\n });\n\n it('Should unserialize from MARCXML', async () => {\n const record = await conversionService.unserialize(marcXml, conversionFormats.MARCXML);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from ISO2709', () => {\n const record = conversionService.unserialize(iso2709, conversionFormats.ISO2709);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from JSON', () => {\n const record = conversionService.unserialize(json, conversionFormats.JSON);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should throw because the record could not be unserialized', () => {\n expect(() => {\n conversionService.unserialize('', conversionFormats.JSON);\n }).to.throw(ConversionError);\n });\n });\n});\n"],"file":"conversion.spec.js"}
1
+ {"version":3,"sources":["../../src/helpers/conversion.spec.js"],"names":["describe","getFixture","root","__dirname","conversionService","marcRecord","MarcRecord","JSON","parse","components","subfieldValues","marcXml","iso2709","json","alephSeq","it","service","to","be","an","and","respondTo","serialize","throw","data","CONVERSION_FORMATS","MARCXML","equal","ISO2709","ALEPHSEQ","unserialize","record","equalsTo","ConversionError"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {expect} from 'chai';\nimport fixtureFactory from '@natlibfi/fixura';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {Error as ConversionError} from '@natlibfi/melinda-commons';\nimport createConversionService from './conversion';\nimport {CONVERSION_FORMATS} from '../constants';\n\ndescribe('services/conversion', () => {\n const {getFixture} = fixtureFactory({root: [\n __dirname,\n '..',\n '..',\n 'test-fixtures',\n 'conversion'\n ]});\n const conversionService = createConversionService();\n\n const marcRecord = new MarcRecord(JSON.parse(getFixture({components: ['json1']})), {subfieldValues: false});\n const marcXml = getFixture({components: ['marcxml1']});\n const iso2709 = getFixture({components: ['iso2709_1']});\n const json = getFixture({components: ['json1']});\n const alephSeq = getFixture({components: ['aleph_sequential']});\n\n\n describe('factory', () => {\n it('Should create the expected object', () => {\n const service = createConversionService();\n expect(service).to.be.an('object').and\n .respondTo('serialize')\n .respondTo('unserialize');\n });\n });\n\n describe('#serialize', () => {\n it('Should throw because of unsupported format', () => {\n expect(conversionService.serialize).to.throw();\n });\n\n it('Should serialize to MARCXML', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.MARCXML);\n expect(data).to.equal(marcXml);\n });\n\n it('Should serialize to ISO2709', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.ISO2709);\n expect(data).to.equal(iso2709);\n });\n\n it('Should serialize to JSON', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.JSON);\n expect(data).to.equal(json);\n });\n\n it('Should serialize to aleph sequential', () => {\n const data = conversionService.serialize(marcRecord, CONVERSION_FORMATS.ALEPHSEQ);\n expect(data).to.equal(alephSeq);\n });\n\n });\n\n describe('#unserialize', () => {\n it('Should throw because of unsupported format', () => {\n expect(conversionService.unserialize).to.throw();\n });\n\n it('Should unserialize from MARCXML', async () => {\n const record = await conversionService.unserialize(marcXml, CONVERSION_FORMATS.MARCXML);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from ISO2709', () => {\n const record = conversionService.unserialize(iso2709, CONVERSION_FORMATS.ISO2709);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from JSON', () => {\n const record = conversionService.unserialize(json, CONVERSION_FORMATS.JSON);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n it('Should unserialize from Aleph sequential', () => {\n const record = conversionService.unserialize(alephSeq, CONVERSION_FORMATS.ALEPHSEQ);\n expect(record.equalsTo(marcRecord)).to.equal(true);\n });\n\n\n it('Should throw because the record could not be unserialized', () => {\n expect(() => {\n conversionService.unserialize('', CONVERSION_FORMATS.JSON);\n }).to.throw(ConversionError);\n });\n });\n});\n"],"file":"conversion.spec.js"}
package/dist/index.js CHANGED
@@ -9,8 +9,18 @@ var _exportNames = {
9
9
  conversions: true,
10
10
  validations: true,
11
11
  format: true,
12
- logError: true
12
+ logError: true,
13
+ createImportJobState: true,
14
+ createImportJobStateForQuery: true,
15
+ createRecordResponseItem: true,
16
+ addRecordResponseItem: true
13
17
  };
18
+ Object.defineProperty(exports, "addRecordResponseItem", {
19
+ enumerable: true,
20
+ get: function () {
21
+ return _utils.addRecordResponseItem;
22
+ }
23
+ });
14
24
  Object.defineProperty(exports, "amqpFactory", {
15
25
  enumerable: true,
16
26
  get: function () {
@@ -23,6 +33,24 @@ Object.defineProperty(exports, "conversions", {
23
33
  return _conversion.default;
24
34
  }
25
35
  });
36
+ Object.defineProperty(exports, "createImportJobState", {
37
+ enumerable: true,
38
+ get: function () {
39
+ return _utils.createImportJobState;
40
+ }
41
+ });
42
+ Object.defineProperty(exports, "createImportJobStateForQuery", {
43
+ enumerable: true,
44
+ get: function () {
45
+ return _utils.createImportJobStateForQuery;
46
+ }
47
+ });
48
+ Object.defineProperty(exports, "createRecordResponseItem", {
49
+ enumerable: true,
50
+ get: function () {
51
+ return _utils.createRecordResponseItem;
52
+ }
53
+ });
26
54
  exports.format = void 0;
27
55
  Object.defineProperty(exports, "logError", {
28
56
  enumerable: true,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA;;AACA;;AACA;;AACA;;AACA;;;;AACA;;AAGA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport mongoFactory from './mongo';\nimport amqpFactory from './amqp';\nimport conversions from './helpers/conversion';\nimport validations from './helpers/validation';\nimport * as format from './helpers/format';\nimport {logError} from './utils';\n\nexport {mongoFactory, amqpFactory, conversions, validations, format, logError};\nexport * from './constants';\n"],"file":"index.js"}
1
+ {"version":3,"sources":["../src/index.js"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA;;AACA;;AACA;;AACA;;AACA;;;;AACA;;AAGA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport mongoFactory from './mongo';\nimport amqpFactory from './amqp';\nimport conversions from './helpers/conversion';\nimport validations from './helpers/validation';\nimport * as format from './helpers/format';\nimport {logError, createImportJobState, createImportJobStateForQuery, createRecordResponseItem, addRecordResponseItem} from './utils';\n\nexport {mongoFactory, amqpFactory, conversions, validations, format, logError, createImportJobState, createImportJobStateForQuery, createRecordResponseItem, addRecordResponseItem};\nexport * from './constants';\n"],"file":"index.js"}
package/dist/mongo.js CHANGED
@@ -57,6 +57,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
57
57
  "cataloger":"xxx0000",
58
58
  "oCatalogerIn":"xxx0000"
59
59
  "operation":"UPDATE",
60
+ "operations":["UPDATE", "CREATE"]
60
61
  "contentType":"application/json",
61
62
  "recordLoadParams": {
62
63
  "pActiveLibrary": "XXX00",
@@ -66,6 +67,10 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de
66
67
  "pOldNew": "NEW"
67
68
  },
68
69
  "queueItemState":"PENDING_QUEUING",
70
+ "importJobState": {
71
+ "CREATE": "EMPTY",
72
+ "UPDATE": "EMPTY"
73
+ },
69
74
  "creationTime":"2020-01-01T00:00:00.000Z",
70
75
  "modificationTime":"2020-01-01T00:00:01.000Z",
71
76
  "handledIds": []
@@ -86,6 +91,7 @@ async function _default(MONGO_URI, collection) {
86
91
  createPrio,
87
92
  createBulk,
88
93
  checkAndSetState,
94
+ checkAndSetImportJobState,
89
95
  query,
90
96
  queryById,
91
97
  remove,
@@ -94,8 +100,13 @@ async function _default(MONGO_URI, collection) {
94
100
  getOne,
95
101
  getStream,
96
102
  setState,
103
+ setImportJobState,
97
104
  pushIds,
98
- pushMessages
105
+ pushMessages,
106
+ setOperation,
107
+ setOperations,
108
+ addBlobSize,
109
+ setBlobSize
99
110
  };
100
111
 
101
112
  async function createPrio({
@@ -103,22 +114,25 @@ async function _default(MONGO_URI, collection) {
103
114
  cataloger,
104
115
  oCatalogerIn,
105
116
  operation,
106
- noop = undefined,
107
- unique = undefined,
108
- prio = true
117
+ operationSettings
109
118
  }) {
110
119
  const time = (0, _moment.default)().toDate();
111
120
  const newQueueItem = {
112
121
  correlationId,
113
122
  cataloger,
114
123
  operation,
124
+ operations: [operation],
115
125
  oCatalogerIn,
116
126
  operationSettings: {
117
- unique,
118
- noop,
119
- prio
127
+ prio: true,
128
+ ...operationSettings
120
129
  },
121
130
  queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.PENDING_VALIDATION,
131
+ importJobState: {
132
+ CREATE: _constants.IMPORT_JOB_STATE.EMPTY,
133
+ UPDATE: _constants.IMPORT_JOB_STATE.EMPTY
134
+ },
135
+ blobSize: 1,
122
136
  creationTime: time,
123
137
  modificationTime: time,
124
138
  handledIds: [],
@@ -140,7 +154,7 @@ async function _default(MONGO_URI, collection) {
140
154
  }
141
155
  }
142
156
 
143
- function createBulk({
157
+ async function createBulk({
144
158
  correlationId,
145
159
  cataloger,
146
160
  oCatalogerIn,
@@ -148,7 +162,7 @@ async function _default(MONGO_URI, collection) {
148
162
  contentType,
149
163
  recordLoadParams,
150
164
  stream,
151
- prio = false
165
+ operationSettings
152
166
  }) {
153
167
  const time = (0, _moment.default)().toDate();
154
168
  const newQueueItem = {
@@ -156,37 +170,62 @@ async function _default(MONGO_URI, collection) {
156
170
  cataloger,
157
171
  oCatalogerIn,
158
172
  operation,
173
+ operations: [operation],
159
174
  operationSettings: {
160
- prio
175
+ prio: false,
176
+ ...operationSettings
161
177
  },
162
178
  contentType,
163
179
  recordLoadParams,
164
180
  queueItemState: stream ? _constants.QUEUE_ITEM_STATE.VALIDATOR.UPLOADING : _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS,
181
+ blobSize: 0,
182
+ importJobState: {
183
+ CREATE: _constants.IMPORT_JOB_STATE.EMPTY,
184
+ UPDATE: _constants.IMPORT_JOB_STATE.EMPTY
185
+ },
165
186
  creationTime: time,
166
187
  modificationTime: time,
167
188
  handledIds: [],
168
189
  rejectedIds: []
169
- };
170
-
171
- try {
172
- // No await here, promises later
173
- db.collection(collection).insertOne(newQueueItem);
174
- logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);
175
- } catch (error) {
176
- (0, _utils.logError)(error);
177
- throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
190
+ }; // eslint-disable-next-line functional/no-conditional-statement
191
+
192
+ if (stream) {
193
+ try {
194
+ // No await here, promises later
195
+ db.collection(collection).insertOne(newQueueItem);
196
+ logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);
197
+ return new Promise((resolve, reject) => {
198
+ const outputStream = gridFSBucket.openUploadStream(correlationId);
199
+ stream.on('error', reject).on('data', chunk => outputStream.write(chunk)).on('end', () => outputStream.end(undefined, undefined, () => {
200
+ resolve(correlationId);
201
+ }));
202
+ });
203
+ } catch (error) {
204
+ (0, _utils.logError)(error);
205
+ throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
206
+ }
178
207
  }
179
208
 
209
+ logger.debug(`No stream`); // eslint-disable-next-line functional/no-conditional-statement
210
+
180
211
  if (!stream) {
181
- return correlationId;
182
- }
212
+ try {
213
+ const result = await db.collection(collection).insertOne(newQueueItem);
214
+
215
+ if (result.acknowledged) {
216
+ logger.info(`New noStream BULK queue item for ${operation} ${correlationId} has been made in ${collection}`);
217
+ return {
218
+ correlationId,
219
+ queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS
220
+ };
221
+ }
183
222
 
184
- return new Promise((resolve, reject) => {
185
- const outputStream = gridFSBucket.openUploadStream(correlationId);
186
- stream.on('error', reject).on('data', chunk => outputStream.write(chunk)).on('end', () => outputStream.end(undefined, undefined, () => {
187
- resolve(correlationId);
188
- }));
189
- });
223
+ throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
224
+ } catch (error) {
225
+ (0, _utils.logError)(error);
226
+ throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR);
227
+ }
228
+ }
190
229
  } // Check state that the queueItem has not waited too long and set state
191
230
 
192
231
 
@@ -198,7 +237,9 @@ async function _default(MONGO_URI, collection) {
198
237
  }) {
199
238
  // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR
200
239
  // otherwise it sets queueItem to state ABORT (408, 'Timeout')
201
- const timeOut = await checkTimeOut(correlationId);
240
+ const timeOut = await checkTimeOut({
241
+ correlationId
242
+ });
202
243
 
203
244
  if (timeOut) {
204
245
  return setState({
@@ -209,6 +250,36 @@ async function _default(MONGO_URI, collection) {
209
250
  });
210
251
  }
211
252
 
253
+ return false;
254
+ } // Check state that the queueItem has not waited too long and set state
255
+
256
+
257
+ async function checkAndSetImportJobState({
258
+ correlationId,
259
+ operation,
260
+ importJobState,
261
+ errorMessage = '',
262
+ errorStatus = ''
263
+ }) {
264
+ // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR
265
+ // otherwise it sets queueItem to state ABORT (408, 'Timeout')
266
+ logger.debug(`${correlationId}, ${importJobState}, ${operation}`);
267
+ const timeOut = await checkTimeOut({
268
+ correlationId,
269
+ operation,
270
+ importJobState
271
+ });
272
+
273
+ if (timeOut) {
274
+ return setImportJobState({
275
+ correlationId,
276
+ operation,
277
+ importJobState,
278
+ errorMessage,
279
+ errorStatus
280
+ });
281
+ }
282
+
212
283
  return false;
213
284
  }
214
285
 
@@ -222,16 +293,23 @@ async function _default(MONGO_URI, collection) {
222
293
  return result;
223
294
  }
224
295
 
225
- async function queryById(correlationId, checkModTime) {
296
+ async function queryById({
297
+ correlationId,
298
+ checkModTime = false
299
+ }) {
226
300
  const result = await db.collection(collection).findOne({
227
301
  correlationId
228
302
  });
229
303
 
230
304
  if (checkModTime) {
231
- const timeOut = await checkTimeOut(correlationId);
305
+ const timeOut = await checkTimeOut({
306
+ correlationId
307
+ });
232
308
 
233
309
  if (timeOut) {
234
- return queryById(correlationId);
310
+ return queryById({
311
+ correlationId
312
+ });
235
313
  }
236
314
 
237
315
  return result;
@@ -244,15 +322,18 @@ async function _default(MONGO_URI, collection) {
244
322
  // If the state is already ABORT or ERROR return false
245
323
 
246
324
 
247
- async function checkTimeOut(correlationId) {
325
+ async function checkTimeOut({
326
+ correlationId
327
+ }) {
248
328
  const {
249
329
  modificationTime,
250
- queueitemState: oldState
330
+ queueitemState: oldState,
331
+ importJobState
251
332
  } = await db.collection(collection).findOne({
252
333
  correlationId
253
- });
334
+ }); // should we check for DONE too?
254
335
 
255
- if ([_constants.QUEUE_ITEM_STATE.ABORT, _constants.QUEUE_ITEM_STATE.ERROR].includes(oldState)) {
336
+ if ([_constants.QUEUE_ITEM_STATE.ABORT, _constants.QUEUE_ITEM_STATE.ERROR, _constants.QUEUE_ITEM_STATE.DONE].includes(oldState)) {
256
337
  logger.silly(`${correlationId} has already state: ${oldState}`);
257
338
  return false;
258
339
  }
@@ -261,6 +342,26 @@ async function _default(MONGO_URI, collection) {
261
342
  logger.silly(`timeOut @ ${timeoutTime}`);
262
343
 
263
344
  if (timeoutTime.isBefore()) {
345
+ const finalImportJobStates = [_constants.IMPORT_JOB_STATE.ABORT, _constants.IMPORT_JOB_STATE.DONE, _constants.IMPORT_JOB_STATE.EMPTY, _constants.IMPORT_JOB_STATE.ERROR];
346
+
347
+ if (!finalImportJobStates.includes(importJobState.CREATE)) {
348
+ // eslint-disable-line
349
+ await setImportJobState({
350
+ correlationId,
351
+ operation: 'CREATE',
352
+ importJobState: _constants.IMPORT_JOB_STATE.ABORT
353
+ });
354
+ }
355
+
356
+ if (!finalImportJobStates.includes(importJobState.UPDATE)) {
357
+ // eslint-disable-line
358
+ await setImportJobState({
359
+ correlationId,
360
+ operation: 'UPDATE',
361
+ importJobState: _constants.IMPORT_JOB_STATE.ABORT
362
+ });
363
+ }
364
+
264
365
  await setState({
265
366
  correlationId,
266
367
  state: _constants.QUEUE_ITEM_STATE.ABORT,
@@ -340,30 +441,43 @@ async function _default(MONGO_URI, collection) {
340
441
  }
341
442
 
342
443
  return true;
343
- }
444
+ } // eslint-disable-next-line max-statements
445
+
344
446
 
345
447
  function getOne({
346
- operation,
347
- queueItemState
448
+ queueItemState,
449
+ importJobState = undefined
348
450
  }) {
349
- const clean = {
451
+ logger.silly(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);
452
+ const cleanQueueItemState = queueItemState ? {
350
453
  queueItemState: (0, _mongoSanitize.default)(queueItemState)
351
- };
454
+ } : undefined;
352
455
 
353
456
  try {
354
- if (operation === undefined) {
355
- logger.silly(`Checking DB ${collection} for ${JSON.stringify(clean.queueItemState)}`);
356
- return db.collection(collection).findOne({ ...clean
457
+ // Just queueItemState
458
+ if (queueItemState && importJobState === undefined) {
459
+ logger.silly(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);
460
+ return db.collection(collection).findOne({ ...cleanQueueItemState
461
+ });
462
+ } // importJobState
463
+
464
+
465
+ if (importJobState && queueItemState === undefined) {
466
+ logger.silly(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);
467
+ return db.collection(collection).findOne({ ...importJobState
468
+ });
469
+ } // importJobState and queueItemState
470
+
471
+
472
+ if (importJobState && queueItemState) {
473
+ logger.silly(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);
474
+ return db.collection(collection).findOne({ ...cleanQueueItemState,
475
+ ...importJobState
357
476
  });
358
477
  }
359
478
 
360
- const clean2 = {
361
- operation: (0, _mongoSanitize.default)(operation)
362
- };
363
- logger.silly(`Checking DB ${collection} for ${clean.queueItemState} + ${clean2.operation}`);
364
- return db.collection(collection).findOne({ ...clean,
365
- ...clean2
366
- });
479
+ logger.debug(`getOne not working!`);
480
+ throw new _melindaCommons.Error(_httpStatus.default.INTERNAL_SERVER_ERROR, 'Missing parameters, cannot get queueItem');
367
481
  } catch (error) {
368
482
  (0, _utils.logError)(error);
369
483
  }
@@ -466,5 +580,149 @@ async function _default(MONGO_URI, collection) {
466
580
  returnNewDocument: true
467
581
  });
468
582
  }
583
+
584
+ function setImportJobState({
585
+ correlationId,
586
+ operation,
587
+ importJobState
588
+ }) {
589
+ // should this also get importJobState as previously created object? {}
590
+ logger.info(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);
591
+ const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
592
+ const cleanImportJobState = (0, _mongoSanitize.default)(importJobState);
593
+
594
+ if (!(operation in _constants.OPERATIONS)) {
595
+ throw new _melindaCommons.Error('400', 'Invalid operation for import job state');
596
+ }
597
+
598
+ if (!(cleanImportJobState in _constants.IMPORT_JOB_STATE)) {
599
+ throw new _melindaCommons.Error('400', 'Invalid import job state');
600
+ }
601
+
602
+ const newJobState = operation === _constants.OPERATIONS.CREATE ? {
603
+ 'importJobState.CREATE': cleanImportJobState
604
+ } : {
605
+ 'importJobState.UPDATE': cleanImportJobState
606
+ };
607
+ return db.collection(collection).findOneAndUpdate({
608
+ correlationId: cleanCorrelationId
609
+ }, {
610
+ $set: { ...newJobState,
611
+ modificationTime: (0, _moment.default)().toDate()
612
+ }
613
+ }, {
614
+ projection: {
615
+ _id: 0
616
+ },
617
+ returnNewDocument: true
618
+ });
619
+ }
620
+
621
+ async function setOperation({
622
+ correlationId,
623
+ operation
624
+ }) {
625
+ const newOperation = operation;
626
+ const {
627
+ operation: oldOperation
628
+ } = await db.collection(collection).findOne({
629
+ correlationId
630
+ });
631
+ logger.info(`Setting queue-item operation from ${oldOperation} to ${newOperation} for ${correlationId} to ${collection}`);
632
+ const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
633
+ const cleanNewOperation = (0, _mongoSanitize.default)(newOperation);
634
+ const result = await db.collection(collection).findOneAndUpdate({
635
+ correlationId: cleanCorrelationId
636
+ }, {
637
+ $set: {
638
+ operation: cleanNewOperation,
639
+ modificationTime: (0, _moment.default)().toDate()
640
+ }
641
+ }, {
642
+ projection: {
643
+ _id: 0
644
+ },
645
+ returnNewDocument: true
646
+ });
647
+ return result.ok; // logger.debug(JSON.stringify(result));
648
+ }
649
+
650
+ async function setOperations({
651
+ correlationId,
652
+ addOperation,
653
+ removeOperation = undefined
654
+ }) {
655
+ const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId); //logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);
656
+
657
+ const queueItem = await db.collection(collection).findOne({
658
+ correlationId: cleanCorrelationId
659
+ });
660
+ logger.debug(`We fould a queueItem: ${JSON.stringify(queueItem)}`);
661
+ const oldOperations = queueItem.operations;
662
+ logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);
663
+ const operationsAfterRemove = oldOperations.filter(operation => operation !== removeOperation);
664
+ const operationsAfterRemoveAndAdd = [addOperation, ...operationsAfterRemove];
665
+ const result = await db.collection(collection).findOneAndUpdate({
666
+ correlationId: cleanCorrelationId
667
+ }, {
668
+ $set: {
669
+ operations: operationsAfterRemoveAndAdd,
670
+ modificationTime: (0, _moment.default)().toDate()
671
+ }
672
+ }, {
673
+ projection: {
674
+ _id: 0
675
+ },
676
+ returnNewDocument: true
677
+ });
678
+ return result.ok; // logger.debug(JSON.stringify(result));
679
+ }
680
+
681
+ async function addBlobSize({
682
+ correlationId
683
+ }) {
684
+ const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
685
+ const result = await db.collection(collection).findOneAndUpdate({
686
+ correlationId: cleanCorrelationId,
687
+ queueItemState: _constants.QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS
688
+ }, {
689
+ $inc: {
690
+ blobSize: 1
691
+ },
692
+ $set: {
693
+ modificationTime: (0, _moment.default)().toDate()
694
+ }
695
+ }, {
696
+ projection: {
697
+ _id: 0
698
+ },
699
+ returnNewDocument: true
700
+ });
701
+ logger.verbose(`AddBlobSizeResult in mongo: ${JSON.stringify(result)}`);
702
+ return result;
703
+ }
704
+
705
+ async function setBlobSize({
706
+ correlationId,
707
+ blobSize
708
+ }) {
709
+ const cleanCorrelationId = (0, _mongoSanitize.default)(correlationId);
710
+ const cleanBlobSize = (0, _mongoSanitize.default)(blobSize);
711
+ const result = await db.collection(collection).findOneAndUpdate({
712
+ correlationId: cleanCorrelationId
713
+ }, {
714
+ $set: {
715
+ blobSize: cleanBlobSize,
716
+ modificationTime: (0, _moment.default)().toDate()
717
+ }
718
+ }, {
719
+ projection: {
720
+ _id: 0
721
+ },
722
+ returnNewDocument: true
723
+ });
724
+ logger.verbose(`SetBlobSizeResult in mongo: ${JSON.stringify(result)}`);
725
+ return result;
726
+ }
469
727
  }
470
728
  //# sourceMappingURL=mongo.js.map
package/dist/mongo.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mongo.js"],"names":["MONGO_URI","collection","logger","client","MongoClient","connect","useNewUrlParser","useUnifiedTopology","db","gridFSBucket","GridFSBucket","bucketName","createPrio","createBulk","checkAndSetState","query","queryById","remove","readContent","removeContent","getOne","getStream","setState","pushIds","pushMessages","correlationId","cataloger","oCatalogerIn","operation","noop","undefined","unique","prio","time","toDate","newQueueItem","operationSettings","queueItemState","QUEUE_ITEM_STATE","VALIDATOR","PENDING_VALIDATION","creationTime","modificationTime","handledIds","rejectedIds","result","insertOne","acknowledged","info","ApiError","httpStatus","INTERNAL_SERVER_ERROR","error","contentType","recordLoadParams","stream","UPLOADING","WAITING_FOR_RECORDS","Promise","resolve","reject","outputStream","openUploadStream","on","chunk","write","end","state","errorMessage","errorStatus","timeOut","checkTimeOut","params","find","projection","_id","toArray","debug","length","checkModTime","findOne","queueitemState","oldState","ABORT","ERROR","includes","silly","timeoutTime","add","isBefore","REQUEST_TIMEOUT","JSON","stringify","clean","noContent","deleteOne","err","MongoDriverError","message","indexOf","readStream","openDownloadStreamByName","NOT_FOUND","delete","clean2","verbose","updateOne","$set","$push","$each","messages","messageField","cleanMessageField","errorString","stateInQueueItemStates","Object","values","stateInQueueItemStatesValidator","stateInQueueItemStatesImporter","IMPORTER","BAD_REQUEST","updateValues","keys","forEach","key","findOneAndUpdate","returnNewDocument"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {MongoClient, GridFSBucket, MongoDriverError} from 'mongodb';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ApiError} from '@natlibfi/melinda-commons';\nimport {QUEUE_ITEM_STATE} from './constants';\nimport {logError} from './utils.js';\nimport moment from 'moment';\nimport httpStatus from 'http-status';\nimport sanitize from 'mongo-sanitize';\n\n/* QueueItem:\n{\n \"correlationId\":\"FOO\",\n \"cataloger\":\"xxx0000\",\n \"oCatalogerIn\":\"xxx0000\"\n \"operation\":\"UPDATE\",\n \"contentType\":\"application/json\",\n \"recordLoadParams\": {\n \"pActiveLibrary\": \"XXX00\",\n \"pInputFile\": \"filename.seq\",\n \"pRejectFile\": \"filename.rej\",\n \"pLogFile\": \"filename.syslog\",\n \"pOldNew\": \"NEW\"\n },\n \"queueItemState\":\"PENDING_QUEUING\",\n \"creationTime\":\"2020-01-01T00:00:00.000Z\",\n \"modificationTime\":\"2020-01-01T00:00:01.000Z\",\n \"handledIds\": []\n}\n*/\n\nexport default async function (MONGO_URI, collection) {\n const logger = createLogger();\n\n // Connect to mongo (MONGO)\n const client = await MongoClient.connect(MONGO_URI, {useNewUrlParser: true, useUnifiedTopology: true});\n const db = client.db('rest-api');\n const gridFSBucket = new GridFSBucket(db, {bucketName: collection});\n\n return {createPrio, createBulk, checkAndSetState, query, queryById, remove, readContent, removeContent, getOne, getStream, setState, pushIds, pushMessages};\n\n async function createPrio({correlationId, cataloger, oCatalogerIn, operation, noop = undefined, unique = undefined, prio = true}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n operation,\n oCatalogerIn,\n operationSettings: {unique, noop, prio},\n queueItemState: QUEUE_ITEM_STATE.VALIDATOR.PENDING_VALIDATION,\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n try {\n const result = await db.collection(collection).insertOne(newQueueItem);\n if (result.acknowledged) {\n logger.info(`New PRIO queue item for ${operation} ${correlationId} has been made in ${collection}`);\n return;\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n\n function createBulk({correlationId, cataloger, oCatalogerIn, operation, contentType, recordLoadParams, stream, prio = false}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n oCatalogerIn,\n operation,\n operationSettings: {prio},\n contentType,\n recordLoadParams,\n queueItemState: stream ? QUEUE_ITEM_STATE.VALIDATOR.UPLOADING : QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS,\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n try {\n // No await here, promises later\n db.collection(collection).insertOne(newQueueItem);\n logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n\n if (!stream) {\n return correlationId;\n }\n\n return new Promise((resolve, reject) => {\n const outputStream = gridFSBucket.openUploadStream(correlationId);\n\n stream\n .on('error', reject)\n .on('data', chunk => outputStream.write(chunk))\n .on('end', () => outputStream.end(undefined, undefined, () => {\n resolve(correlationId);\n }));\n });\n }\n\n // Check state that the queueItem has not waited too long and set state\n async function checkAndSetState({correlationId, state, errorMessage = undefined, errorStatus = undefined}) {\n // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR\n // otherwise it sets queueItem to state ABORT (408, 'Timeout')\n const timeOut = await checkTimeOut(correlationId);\n if (timeOut) {\n return setState({correlationId, state, errorMessage, errorStatus});\n }\n return false;\n }\n\n async function query(params) {\n const result = await db.collection(collection).find(params, {projection: {_id: 0}})\n .toArray();\n logger.debug(`Query result: ${result.length > 0 ? 'Found!' : 'Not found!'}`);\n return result;\n }\n\n async function queryById(correlationId, checkModTime) {\n const result = await db.collection(collection).findOne({correlationId});\n if (checkModTime) {\n const timeOut = await checkTimeOut(correlationId);\n if (timeOut) {\n return queryById(correlationId);\n }\n return result;\n }\n\n return result;\n }\n\n // Check that if the item has waited too long\n // If the last modification time for the queueItem is older than 1 minute\n // set state to ABORT and return false, otherwise return true\n // If the state is already ABORT or ERROR return false\n\n async function checkTimeOut(correlationId) {\n const {modificationTime, queueitemState: oldState} = await db.collection(collection).findOne({correlationId});\n\n if ([QUEUE_ITEM_STATE.ABORT, QUEUE_ITEM_STATE.ERROR].includes(oldState)) {\n logger.silly(`${correlationId} has already state: ${oldState}`);\n return false;\n }\n\n const timeoutTime = moment(modificationTime).add(1, 'm');\n logger.silly(`timeOut @ ${timeoutTime}`);\n\n if (timeoutTime.isBefore()) {\n await setState({correlationId, state: QUEUE_ITEM_STATE.ABORT, errorStatus: httpStatus.REQUEST_TIMEOUT, errorMessage: `Timeout in ${oldState}`});\n return false;\n }\n\n return true;\n }\n\n async function remove(params) {\n logger.silly(`${JSON.stringify(params)}`);\n logger.info(`Removing from Mongo (${collection}) id: ${params.correlationId}`);\n const clean = sanitize(params.correlationId);\n logger.silly(`mongo/remove: clean: ${JSON.stringify(clean)}`);\n\n try {\n //const metadataResult = await getFileMetadata({filename: clean});\n //logger.debug(`mongo/remove: metadataResult: ${JSON.stringify(metadataResult)}`);\n const noContent = await removeContent(params);\n if (noContent) {\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n } catch (err) {\n if (err instanceof MongoDriverError) {\n if (err.message.indexOf('File not found for id') !== -1) {\n logger.silly(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n logger.error(err.message);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n }\n\n async function readContent(correlationId) {\n logger.info(`Reading content from mongo for id: ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n\n if (result) {\n return {\n contentType: result.contentType,\n readStream: gridFSBucket.openDownloadStreamByName(clean)\n };\n }\n\n throw new ApiError(httpStatus.NOT_FOUND);\n }\n\n async function removeContent(params) {\n logger.info(`Removing content from mongo for id: ${params.correlationId} in ${collection}`);\n const clean = sanitize(params.correlationId);\n\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n logger.silly(`mongo/removeContent: result ${JSON.stringify(result)}`);\n\n if (result) {\n await gridFSBucket.delete(clean);\n return true;\n }\n\n return true;\n }\n\n function getOne({operation, queueItemState}) {\n const clean = {queueItemState: sanitize(queueItemState)};\n try {\n if (operation === undefined) {\n logger.silly(`Checking DB ${collection} for ${JSON.stringify(clean.queueItemState)}`);\n return db.collection(collection).findOne({...clean});\n }\n\n const clean2 = {operation: sanitize(operation)};\n logger.silly(`Checking DB ${collection} for ${clean.queueItemState} + ${clean2.operation}`);\n return db.collection(collection).findOne({...clean, ...clean2});\n } catch (error) {\n logError(error);\n }\n }\n\n function getStream(correlationId) {\n logger.info(`Forming stream from mongo for ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n try {\n // Return content stream\n return gridFSBucket.openDownloadStreamByName(clean);\n } catch (error) {\n logError(error);\n }\n }\n\n async function pushIds({correlationId, handledIds, rejectedIds}) {\n logger.verbose(`Push ids (${handledIds.length}) and rejectedIds (${rejectedIds.length}) ${correlationId} to ${collection}`);\n logger.debug(`ids (${handledIds.length}): ${JSON.stringify(handledIds)}, rejectedIds ${rejectedIds.length}: ${JSON.stringify(rejectedIds)}`);\n const clean = sanitize(correlationId);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n handledIds: {$each: handledIds},\n rejectedIds: {$each: rejectedIds}\n }\n });\n }\n\n async function pushMessages({correlationId, messages, messageField = 'messages'}) {\n logger.verbose(`Push messages (${messages.length}) to ${messageField} ${correlationId} to ${collection}`);\n logger.silly(`Messages (${messages.length}): ${JSON.stringify(messages)}}`);\n const clean = sanitize(correlationId);\n const cleanMessageField = sanitize(messageField);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n [cleanMessageField]: {$each: messages}\n }\n });\n }\n\n function setState({correlationId, state, errorMessage = undefined, errorStatus = undefined}) {\n const errorString = errorMessage || errorStatus ? `, Error message: '${errorMessage || ''}', Error status: '${errorStatus || ''}'` : '';\n logger.info(`Setting queue-item state ${state} for ${correlationId}${errorString} to ${collection}`);\n\n const stateInQueueItemStates = Object.values(QUEUE_ITEM_STATE).indexOf(state) > -1;\n const stateInQueueItemStatesValidator = Object.values(QUEUE_ITEM_STATE.VALIDATOR).indexOf(state) > -1;\n const stateInQueueItemStatesImporter = Object.values(QUEUE_ITEM_STATE.IMPORTER).indexOf(state) > -1;\n if (!stateInQueueItemStates && !stateInQueueItemStatesValidator && !stateInQueueItemStatesImporter) {\n throw new ApiError(httpStatus.BAD_REQUEST, 'Trying to set invalid state');\n }\n\n const clean = sanitize(correlationId);\n const updateValues = {\n queueItemState: state,\n modificationTime: moment().toDate(),\n errorMessage,\n errorStatus\n };\n\n // Do not update value that are undefined\n // eslint-disable-next-line functional/immutable-data\n Object.keys(updateValues).forEach(key => updateValues[key] === undefined && delete updateValues[key]);\n\n return db.collection(collection)\n .findOneAndUpdate(\n {correlationId: clean},\n {$set: updateValues},\n {projection: {_id: 0}, returnNewDocument: true}\n );\n }\n}\n"],"file":"mongo.js"}
1
+ {"version":3,"sources":["../src/mongo.js"],"names":["MONGO_URI","collection","logger","client","MongoClient","connect","useNewUrlParser","useUnifiedTopology","db","gridFSBucket","GridFSBucket","bucketName","createPrio","createBulk","checkAndSetState","checkAndSetImportJobState","query","queryById","remove","readContent","removeContent","getOne","getStream","setState","setImportJobState","pushIds","pushMessages","setOperation","setOperations","addBlobSize","setBlobSize","correlationId","cataloger","oCatalogerIn","operation","operationSettings","time","toDate","newQueueItem","operations","prio","queueItemState","QUEUE_ITEM_STATE","VALIDATOR","PENDING_VALIDATION","importJobState","CREATE","IMPORT_JOB_STATE","EMPTY","UPDATE","blobSize","creationTime","modificationTime","handledIds","rejectedIds","result","insertOne","acknowledged","info","ApiError","httpStatus","INTERNAL_SERVER_ERROR","error","contentType","recordLoadParams","stream","UPLOADING","WAITING_FOR_RECORDS","Promise","resolve","reject","outputStream","openUploadStream","on","chunk","write","end","undefined","debug","state","errorMessage","errorStatus","timeOut","checkTimeOut","params","find","projection","_id","toArray","length","checkModTime","findOne","queueitemState","oldState","ABORT","ERROR","DONE","includes","silly","timeoutTime","add","isBefore","finalImportJobStates","REQUEST_TIMEOUT","JSON","stringify","clean","noContent","deleteOne","err","MongoDriverError","message","indexOf","readStream","openDownloadStreamByName","NOT_FOUND","delete","cleanQueueItemState","verbose","updateOne","$set","$push","$each","messages","messageField","cleanMessageField","errorString","stateInQueueItemStates","Object","values","stateInQueueItemStatesValidator","stateInQueueItemStatesImporter","IMPORTER","BAD_REQUEST","updateValues","keys","forEach","key","findOneAndUpdate","returnNewDocument","cleanCorrelationId","cleanImportJobState","OPERATIONS","newJobState","newOperation","oldOperation","cleanNewOperation","ok","addOperation","removeOperation","queueItem","oldOperations","operationsAfterRemove","filter","operationsAfterRemoveAndAdd","$inc","cleanBlobSize"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {MongoClient, GridFSBucket, MongoDriverError} from 'mongodb';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ApiError} from '@natlibfi/melinda-commons';\nimport {QUEUE_ITEM_STATE, IMPORT_JOB_STATE, OPERATIONS} from './constants';\nimport {logError} from './utils.js';\nimport moment from 'moment';\nimport httpStatus from 'http-status';\nimport sanitize from 'mongo-sanitize';\n\n/* QueueItem:\n{\n \"correlationId\":\"FOO\",\n \"cataloger\":\"xxx0000\",\n \"oCatalogerIn\":\"xxx0000\"\n \"operation\":\"UPDATE\",\n \"operations\":[\"UPDATE\", \"CREATE\"]\n \"contentType\":\"application/json\",\n \"recordLoadParams\": {\n \"pActiveLibrary\": \"XXX00\",\n \"pInputFile\": \"filename.seq\",\n \"pRejectFile\": \"filename.rej\",\n \"pLogFile\": \"filename.syslog\",\n \"pOldNew\": \"NEW\"\n },\n \"queueItemState\":\"PENDING_QUEUING\",\n \"importJobState\": {\n \"CREATE\": \"EMPTY\",\n \"UPDATE\": \"EMPTY\"\n },\n \"creationTime\":\"2020-01-01T00:00:00.000Z\",\n \"modificationTime\":\"2020-01-01T00:00:01.000Z\",\n \"handledIds\": []\n}\n*/\n\nexport default async function (MONGO_URI, collection) {\n const logger = createLogger();\n\n // Connect to mongo (MONGO)\n const client = await MongoClient.connect(MONGO_URI, {useNewUrlParser: true, useUnifiedTopology: true});\n const db = client.db('rest-api');\n const gridFSBucket = new GridFSBucket(db, {bucketName: collection});\n\n return {createPrio, createBulk, checkAndSetState, checkAndSetImportJobState, query, queryById, remove, readContent, removeContent, getOne, getStream, setState, setImportJobState, pushIds, pushMessages, setOperation, setOperations, addBlobSize, setBlobSize};\n\n async function createPrio({correlationId, cataloger, oCatalogerIn, operation, operationSettings}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n operation,\n operations: [operation],\n oCatalogerIn,\n operationSettings: {\n prio: true,\n ...operationSettings\n },\n queueItemState: QUEUE_ITEM_STATE.VALIDATOR.PENDING_VALIDATION,\n importJobState: {\n CREATE: IMPORT_JOB_STATE.EMPTY,\n UPDATE: IMPORT_JOB_STATE.EMPTY\n },\n blobSize: 1,\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n try {\n const result = await db.collection(collection).insertOne(newQueueItem);\n if (result.acknowledged) {\n logger.info(`New PRIO queue item for ${operation} ${correlationId} has been made in ${collection}`);\n return;\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n\n async function createBulk({correlationId, cataloger, oCatalogerIn, operation, contentType, recordLoadParams, stream, operationSettings}) {\n const time = moment().toDate();\n const newQueueItem = {\n correlationId,\n cataloger,\n oCatalogerIn,\n operation,\n operations: [operation],\n operationSettings: {\n prio: false,\n ...operationSettings\n },\n contentType,\n recordLoadParams,\n queueItemState: stream ? QUEUE_ITEM_STATE.VALIDATOR.UPLOADING : QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS,\n blobSize: 0,\n importJobState: {\n CREATE: IMPORT_JOB_STATE.EMPTY,\n UPDATE: IMPORT_JOB_STATE.EMPTY\n },\n creationTime: time,\n modificationTime: time,\n handledIds: [],\n rejectedIds: []\n };\n\n // eslint-disable-next-line functional/no-conditional-statement\n if (stream) {\n try {\n // No await here, promises later\n db.collection(collection).insertOne(newQueueItem);\n logger.info(`New BULK queue item for ${operation} ${correlationId} has been made in ${collection}!`);\n return new Promise((resolve, reject) => {\n const outputStream = gridFSBucket.openUploadStream(correlationId);\n\n stream\n .on('error', reject)\n .on('data', chunk => outputStream.write(chunk))\n .on('end', () => outputStream.end(undefined, undefined, () => {\n resolve(correlationId);\n }));\n });\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n\n logger.debug(`No stream`);\n // eslint-disable-next-line functional/no-conditional-statement\n if (!stream) {\n try {\n const result = await db.collection(collection).insertOne(newQueueItem);\n if (result.acknowledged) {\n logger.info(`New noStream BULK queue item for ${operation} ${correlationId} has been made in ${collection}`);\n return {correlationId, queueItemState: QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS};\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n } catch (error) {\n logError(error);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR);\n }\n }\n }\n\n // Check state that the queueItem has not waited too long and set state\n async function checkAndSetState({correlationId, state, errorMessage = undefined, errorStatus = undefined}) {\n // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR\n // otherwise it sets queueItem to state ABORT (408, 'Timeout')\n const timeOut = await checkTimeOut({correlationId});\n if (timeOut) {\n return setState({correlationId, state, errorMessage, errorStatus});\n }\n return false;\n }\n\n // Check state that the queueItem has not waited too long and set state\n async function checkAndSetImportJobState({correlationId, operation, importJobState, errorMessage = '', errorStatus = ''}) {\n // checkTimeOut returns true, if queueItem is fresher than 1 minute and it's state is not ABORT/ERROR\n // otherwise it sets queueItem to state ABORT (408, 'Timeout')\n logger.debug(`${correlationId}, ${importJobState}, ${operation}`);\n const timeOut = await checkTimeOut({correlationId, operation, importJobState});\n if (timeOut) {\n return setImportJobState({correlationId, operation, importJobState, errorMessage, errorStatus});\n }\n return false;\n }\n\n async function query(params) {\n const result = await db.collection(collection).find(params, {projection: {_id: 0}})\n .toArray();\n logger.debug(`Query result: ${result.length > 0 ? 'Found!' : 'Not found!'}`);\n return result;\n }\n\n async function queryById({correlationId, checkModTime = false}) {\n const result = await db.collection(collection).findOne({correlationId});\n if (checkModTime) {\n const timeOut = await checkTimeOut({correlationId});\n if (timeOut) {\n return queryById({correlationId});\n }\n return result;\n }\n\n return result;\n }\n\n // Check that if the item has waited too long\n // If the last modification time for the queueItem is older than 1 minute\n // set state to ABORT and return false, otherwise return true\n // If the state is already ABORT or ERROR return false\n\n async function checkTimeOut({correlationId}) {\n const {modificationTime, queueitemState: oldState, importJobState} = await db.collection(collection).findOne({correlationId});\n\n // should we check for DONE too?\n if ([QUEUE_ITEM_STATE.ABORT, QUEUE_ITEM_STATE.ERROR, QUEUE_ITEM_STATE.DONE].includes(oldState)) {\n logger.silly(`${correlationId} has already state: ${oldState}`);\n return false;\n }\n\n const timeoutTime = moment(modificationTime).add(1, 'm');\n logger.silly(`timeOut @ ${timeoutTime}`);\n\n if (timeoutTime.isBefore()) {\n const finalImportJobStates = [IMPORT_JOB_STATE.ABORT, IMPORT_JOB_STATE.DONE, IMPORT_JOB_STATE.EMPTY, IMPORT_JOB_STATE.ERROR];\n if (!finalImportJobStates.includes(importJobState.CREATE)) { // eslint-disable-line\n await setImportJobState({correlationId, operation: 'CREATE', importJobState: IMPORT_JOB_STATE.ABORT});\n }\n\n if (!finalImportJobStates.includes(importJobState.UPDATE)) { // eslint-disable-line\n await setImportJobState({correlationId, operation: 'UPDATE', importJobState: IMPORT_JOB_STATE.ABORT});\n }\n\n await setState({correlationId, state: QUEUE_ITEM_STATE.ABORT, errorStatus: httpStatus.REQUEST_TIMEOUT, errorMessage: `Timeout in ${oldState}`});\n\n return false;\n }\n\n return true;\n }\n\n async function remove(params) {\n logger.silly(`${JSON.stringify(params)}`);\n logger.info(`Removing from Mongo (${collection}) id: ${params.correlationId}`);\n const clean = sanitize(params.correlationId);\n logger.silly(`mongo/remove: clean: ${JSON.stringify(clean)}`);\n\n try {\n //const metadataResult = await getFileMetadata({filename: clean});\n //logger.debug(`mongo/remove: metadataResult: ${JSON.stringify(metadataResult)}`);\n const noContent = await removeContent(params);\n if (noContent) {\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n } catch (err) {\n if (err instanceof MongoDriverError) {\n if (err.message.indexOf('File not found for id') !== -1) {\n logger.silly(`mongo/remove: File not found, removing queueItem ${JSON.stringify(clean)} from ${collection}`);\n await db.collection(collection).deleteOne({correlationId: clean});\n return true;\n }\n logger.error(err.message);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, err.message);\n }\n }\n\n async function readContent(correlationId) {\n logger.info(`Reading content from mongo for id: ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n\n if (result) {\n return {\n contentType: result.contentType,\n readStream: gridFSBucket.openDownloadStreamByName(clean)\n };\n }\n\n throw new ApiError(httpStatus.NOT_FOUND);\n }\n\n async function removeContent(params) {\n logger.info(`Removing content from mongo for id: ${params.correlationId} in ${collection}`);\n const clean = sanitize(params.correlationId);\n\n const result = await db.collection(collection).findOne({correlationId: clean}); // njsscan-ignore: node_nosqli_injection\n logger.silly(`mongo/removeContent: result ${JSON.stringify(result)}`);\n\n if (result) {\n await gridFSBucket.delete(clean);\n return true;\n }\n\n return true;\n }\n\n // eslint-disable-next-line max-statements\n function getOne({queueItemState, importJobState = undefined}) {\n\n logger.silly(`queueItemState: ${queueItemState}, importJobState: ${JSON.stringify(importJobState)}`);\n const cleanQueueItemState = queueItemState ? {queueItemState: sanitize(queueItemState)} : undefined;\n\n try {\n\n // Just queueItemState\n if (queueItemState && importJobState === undefined) {\n logger.silly(`Checking DB ${collection} for just ${JSON.stringify(cleanQueueItemState.queueItemState)}`);\n return db.collection(collection).findOne({...cleanQueueItemState});\n }\n\n // importJobState\n if (importJobState && queueItemState === undefined) {\n logger.silly(`Checking DB ${collection} for ${JSON.stringify(importJobState)}`);\n return db.collection(collection).findOne({...importJobState});\n }\n\n // importJobState and queueItemState\n if (importJobState && queueItemState) {\n logger.silly(`Checking DB ${collection} for ${queueItemState} and ${JSON.stringify(importJobState)}`);\n return db.collection(collection).findOne({...cleanQueueItemState, ...importJobState});\n }\n\n logger.debug(`getOne not working!`);\n throw new ApiError(httpStatus.INTERNAL_SERVER_ERROR, 'Missing parameters, cannot get queueItem');\n\n } catch (error) {\n logError(error);\n }\n }\n\n function getStream(correlationId) {\n logger.info(`Forming stream from mongo for ${correlationId} in ${collection}`);\n const clean = sanitize(correlationId);\n try {\n // Return content stream\n return gridFSBucket.openDownloadStreamByName(clean);\n } catch (error) {\n logError(error);\n }\n }\n\n async function pushIds({correlationId, handledIds, rejectedIds}) {\n logger.verbose(`Push ids (${handledIds.length}) and rejectedIds (${rejectedIds.length}) ${correlationId} to ${collection}`);\n logger.debug(`ids (${handledIds.length}): ${JSON.stringify(handledIds)}, rejectedIds ${rejectedIds.length}: ${JSON.stringify(rejectedIds)}`);\n const clean = sanitize(correlationId);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n handledIds: {$each: handledIds},\n rejectedIds: {$each: rejectedIds}\n }\n });\n }\n\n async function pushMessages({correlationId, messages, messageField = 'messages'}) {\n logger.verbose(`Push messages (${messages.length}) to ${messageField} ${correlationId} to ${collection}`);\n logger.silly(`Messages (${messages.length}): ${JSON.stringify(messages)}}`);\n const clean = sanitize(correlationId);\n const cleanMessageField = sanitize(messageField);\n await db.collection(collection).updateOne({\n correlationId: clean\n }, {\n $set: {\n modificationTime: moment().toDate()\n },\n $push: {\n [cleanMessageField]: {$each: messages}\n }\n });\n }\n\n function setState({correlationId, state, errorMessage = undefined, errorStatus = undefined}) {\n const errorString = errorMessage || errorStatus ? `, Error message: '${errorMessage || ''}', Error status: '${errorStatus || ''}'` : '';\n logger.info(`Setting queue-item state ${state} for ${correlationId}${errorString} to ${collection}`);\n\n const stateInQueueItemStates = Object.values(QUEUE_ITEM_STATE).indexOf(state) > -1;\n const stateInQueueItemStatesValidator = Object.values(QUEUE_ITEM_STATE.VALIDATOR).indexOf(state) > -1;\n const stateInQueueItemStatesImporter = Object.values(QUEUE_ITEM_STATE.IMPORTER).indexOf(state) > -1;\n if (!stateInQueueItemStates && !stateInQueueItemStatesValidator && !stateInQueueItemStatesImporter) {\n throw new ApiError(httpStatus.BAD_REQUEST, 'Trying to set invalid state');\n }\n\n const clean = sanitize(correlationId);\n const updateValues = {\n queueItemState: state,\n modificationTime: moment().toDate(),\n errorMessage,\n errorStatus\n };\n\n // Do not update value that are undefined\n // eslint-disable-next-line functional/immutable-data\n Object.keys(updateValues).forEach(key => updateValues[key] === undefined && delete updateValues[key]);\n\n return db.collection(collection)\n .findOneAndUpdate(\n {correlationId: clean},\n {$set: updateValues},\n {projection: {_id: 0}, returnNewDocument: true}\n );\n }\n\n function setImportJobState({correlationId, operation, importJobState}) {\n\n // should this also get importJobState as previously created object? {}\n logger.info(`Setting queue-item importJobState: {${operation}: ${importJobState}} for ${correlationId}`);\n const cleanCorrelationId = sanitize(correlationId);\n const cleanImportJobState = sanitize(importJobState);\n\n if (!(operation in OPERATIONS)) {\n throw new ApiError('400', 'Invalid operation for import job state');\n }\n\n if (!(cleanImportJobState in IMPORT_JOB_STATE)) {\n throw new ApiError('400', 'Invalid import job state');\n }\n\n const newJobState = operation === OPERATIONS.CREATE ? {'importJobState.CREATE': cleanImportJobState} : {'importJobState.UPDATE': cleanImportJobState};\n return db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId\n }, {\n $set: {\n ...newJobState,\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n }\n\n async function setOperation({correlationId, operation}) {\n const newOperation = operation;\n const {operation: oldOperation} = await db.collection(collection).findOne({correlationId});\n logger.info(`Setting queue-item operation from ${oldOperation} to ${newOperation} for ${correlationId} to ${collection}`);\n const cleanCorrelationId = sanitize(correlationId);\n const cleanNewOperation = sanitize(newOperation);\n\n const result = await db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId\n }, {\n $set: {\n operation: cleanNewOperation,\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n\n return result.ok;\n // logger.debug(JSON.stringify(result));\n }\n\n async function setOperations({correlationId, addOperation, removeOperation = undefined}) {\n const cleanCorrelationId = sanitize(correlationId);\n\n //logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);\n\n const queueItem = await db.collection(collection).findOne({correlationId: cleanCorrelationId});\n logger.debug(`We fould a queueItem: ${JSON.stringify(queueItem)}`);\n\n const oldOperations = queueItem.operations;\n\n logger.info(`Setting queue-item operation from ${JSON.stringify(oldOperations)} by adding ${addOperation} and removing ${removeOperation} for ${correlationId} to ${collection}`);\n\n const operationsAfterRemove = oldOperations.filter(operation => operation !== removeOperation);\n const operationsAfterRemoveAndAdd = [addOperation, ...operationsAfterRemove];\n\n const result = await db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId\n }, {\n $set: {\n operations: operationsAfterRemoveAndAdd,\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n\n return result.ok;\n // logger.debug(JSON.stringify(result));\n }\n\n async function addBlobSize({correlationId}) {\n const cleanCorrelationId = sanitize(correlationId);\n\n const result = await db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId,\n queueItemState: QUEUE_ITEM_STATE.VALIDATOR.WAITING_FOR_RECORDS\n }, {\n $inc: {\n blobSize: 1\n },\n $set: {\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n\n logger.verbose(`AddBlobSizeResult in mongo: ${JSON.stringify(result)}`);\n return result;\n }\n\n async function setBlobSize({correlationId, blobSize}) {\n const cleanCorrelationId = sanitize(correlationId);\n const cleanBlobSize = sanitize(blobSize);\n\n const result = await db.collection(collection).findOneAndUpdate({\n correlationId: cleanCorrelationId\n }, {\n $set: {\n blobSize: cleanBlobSize,\n modificationTime: moment().toDate()\n }\n }, {projection: {_id: 0}, returnNewDocument: true});\n\n logger.verbose(`SetBlobSizeResult in mongo: ${JSON.stringify(result)}`);\n return result;\n }\n\n}\n"],"file":"mongo.js"}
package/dist/utils.js CHANGED
@@ -3,12 +3,21 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.addRecordResponseItem = addRecordResponseItem;
7
+ exports.createImportJobState = createImportJobState;
8
+ exports.createRecordResponseItem = createRecordResponseItem;
6
9
  exports.logError = logError;
7
10
 
8
11
  var _melindaBackendCommons = require("@natlibfi/melinda-backend-commons");
9
12
 
10
13
  var _melindaCommons = require("@natlibfi/melinda-commons");
11
14
 
15
+ var _constants = require("./constants");
16
+
17
+ var _httpStatus = _interopRequireDefault(require("http-status"));
18
+
19
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20
+
12
21
  /**
13
22
  *
14
23
  * @licstart The following is the entire license notice for the JavaScript code in this file.
@@ -51,4 +60,127 @@ function logError(err) {
51
60
 
52
61
  logger.error(err.stack === undefined ? err : err.stack);
53
62
  }
63
+
64
+ function createImportJobState(operation, state, queryImportJobState = false) {
65
+ if (!(state in _constants.IMPORT_JOB_STATE)) {
66
+ throw new Error('Invalid IMPORT_JOB_STATE');
67
+ }
68
+
69
+ if (!(operation in _constants.OPERATIONS)) {
70
+ throw new Error('Invalid operation');
71
+ }
72
+
73
+ if (queryImportJobState) {
74
+ const importJobStateWithOperation = `importJobState.${operation}`;
75
+ const importJobStateForQuery = {
76
+ [importJobStateWithOperation]: state
77
+ };
78
+ return importJobStateForQuery;
79
+ }
80
+
81
+ return {
82
+ [operation]: state
83
+ };
84
+ }
85
+
86
+ function createRecordResponseItem({
87
+ responsePayload,
88
+ responseStatus,
89
+ recordMetadata,
90
+ id
91
+ }) {
92
+ const recordResponseStatusAndMessage = getRecordResponseStatusAndMessage(responseStatus, responsePayload);
93
+ const recordResponseItem = {
94
+ databaseId: id || '000000000',
95
+ recordMetadata: responsePayload.recordMetadata || recordMetadata || undefined,
96
+ ...recordResponseStatusAndMessage
97
+ };
98
+ return recordResponseItem;
99
+ }
100
+
101
+ function getRecordResponseStatusAndMessage(responseStatus, responsePayload) {
102
+ logger.debug(`Response status: ${responseStatus} responsePayload: ${JSON.stringify(responsePayload)}`);
103
+ const responseStatusName = _httpStatus.default[`${responseStatus}_NAME`];
104
+ logger.debug(`Response status name: ${responseStatusName}`);
105
+ const message = getMessageFromResponsePayload(responsePayload);
106
+ logger.debug(`Response message: ${message}`); // Non-http statuses
107
+
108
+ if (['UPDATED', 'CREATED', 'INVALID', 'ERROR'].includes(responseStatus)) {
109
+ return {
110
+ status: responseStatus,
111
+ message
112
+ };
113
+ }
114
+
115
+ if (['UNKNOWN'].includes(responseStatus)) {
116
+ const possibleIds = responsePayload.ids || [];
117
+ return {
118
+ status: responseStatus,
119
+ message,
120
+ possibleIds
121
+ };
122
+ } // Duplicates and other CONFLICT statuses
123
+
124
+
125
+ if ([_httpStatus.default.CONFLICT, 'CONFLICT'].includes(responseStatus)) {
126
+ if (/^Duplicates in database/u.test(message)) {
127
+ const duplicateIds = responsePayload.ids || [];
128
+ return {
129
+ status: 'DUPLICATE',
130
+ message,
131
+ duplicateIds
132
+ };
133
+ }
134
+
135
+ return {
136
+ status: 'CONFLICT',
137
+ message
138
+ };
139
+ }
140
+
141
+ if ([_httpStatus.default.UNPROCESSABLE_ENTITY, 'UNPROCESSABLE_ENTITY'].includes(responseStatus)) {
142
+ return {
143
+ status: 'UNPROCESSABLE_ENTITY',
144
+ message
145
+ };
146
+ }
147
+
148
+ if ([_httpStatus.default.NOT_FOUND, 'NOT_FOUND'].includes(responseStatus)) {
149
+ return {
150
+ status: 'NOT_FOUND',
151
+ message
152
+ };
153
+ } // Otherwise
154
+
155
+
156
+ return {
157
+ status: 'ERROR',
158
+ message
159
+ };
160
+ }
161
+
162
+ function getMessageFromResponsePayload(responsePayload) {
163
+ if (responsePayload.message) {
164
+ return responsePayload.message;
165
+ }
166
+
167
+ if (typeof responsePayload === 'string' || responsePayload instanceof String) {
168
+ return responsePayload;
169
+ }
170
+
171
+ return '';
172
+ }
173
+
174
+ async function addRecordResponseItem({
175
+ recordResponseItem,
176
+ correlationId,
177
+ mongoOperator
178
+ }) {
179
+ await mongoOperator.pushMessages({
180
+ correlationId,
181
+ messages: [recordResponseItem],
182
+ messageField: 'records'
183
+ });
184
+ return true;
185
+ }
54
186
  //# sourceMappingURL=utils.js.map
package/dist/utils.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.js"],"names":["logger","logError","err","ApiError","error","JSON","stringify","stack","undefined"],"mappings":";;;;;;;AA4BA;;AACA;;AA7BA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAKA,MAAMA,MAAM,GAAG,0CAAf;;AAEO,SAASC,QAAT,CAAkBC,GAAlB,EAAuB;AAC5B,MAAIA,GAAG,YAAYC,qBAAnB,EAA6B;AAC3BH,IAAAA,MAAM,CAACI,KAAP,CAAaC,IAAI,CAACC,SAAL,CAAeJ,GAAf,CAAb;AACA;AACD;;AAED,MAAIA,GAAG,KAAK,QAAZ,EAAsB;AACpBF,IAAAA,MAAM,CAACI,KAAP,CAAaF,GAAb;AACA;AACD;;AAEDF,EAAAA,MAAM,CAACI,KAAP,CAAaF,GAAG,CAACK,KAAJ,KAAcC,SAAd,GAA0BN,GAA1B,GAAgCA,GAAG,CAACK,KAAjD;AACD","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ApiError} from '@natlibfi/melinda-commons';\n\nconst logger = createLogger();\n\nexport function logError(err) {\n if (err instanceof ApiError) {\n logger.error(JSON.stringify(err));\n return;\n }\n\n if (err === 'SIGINT') {\n logger.error(err);\n return;\n }\n\n logger.error(err.stack === undefined ? err : err.stack);\n}\n"],"file":"utils.js"}
1
+ {"version":3,"sources":["../src/utils.js"],"names":["logger","logError","err","ApiError","error","JSON","stringify","stack","undefined","createImportJobState","operation","state","queryImportJobState","IMPORT_JOB_STATE","Error","OPERATIONS","importJobStateWithOperation","importJobStateForQuery","createRecordResponseItem","responsePayload","responseStatus","recordMetadata","id","recordResponseStatusAndMessage","getRecordResponseStatusAndMessage","recordResponseItem","databaseId","debug","responseStatusName","httpStatus","message","getMessageFromResponsePayload","includes","status","possibleIds","ids","CONFLICT","test","duplicateIds","UNPROCESSABLE_ENTITY","NOT_FOUND","String","addRecordResponseItem","correlationId","mongoOperator","pushMessages","messages","messageField"],"mappings":"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","sourcesContent":["/**\n*\n* @licstart The following is the entire license notice for the JavaScript code in this file.\n*\n* Shared modules for microservices of Melinda rest api batch import system\n*\n* Copyright (C) 2020-2021 University Of Helsinki (The National Library Of Finland)\n*\n* This file is part of melinda-rest-api-commons\n*\n* melinda-rest-api-commons program is free software: you can redistribute it and/or modify\n* it under the terms of the GNU Affero General Public License as\n* published by the Free Software Foundation, either version 3 of the\n* License, or (at your option) any later version.\n*\n* melinda-rest-api-commons is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n* GNU Affero General Public License for more details.\n*\n* You should have received a copy of the GNU Affero General Public License\n* along with this program. If not, see <http://www.gnu.org/licenses/>.\n*\n* @licend The above is the entire license notice\n* for the JavaScript code in this file.\n*\n*/\n\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\nimport {Error as ApiError} from '@natlibfi/melinda-commons';\nimport {IMPORT_JOB_STATE, OPERATIONS} from './constants';\nimport httpStatus from 'http-status';\n\nconst logger = createLogger();\n\nexport function logError(err) {\n if (err instanceof ApiError) {\n logger.error(JSON.stringify(err));\n return;\n }\n\n if (err === 'SIGINT') {\n logger.error(err);\n return;\n }\n\n logger.error(err.stack === undefined ? err : err.stack);\n}\n\nexport function createImportJobState(operation, state, queryImportJobState = false) {\n if (!(state in IMPORT_JOB_STATE)) {\n throw new Error('Invalid IMPORT_JOB_STATE');\n }\n\n if (!(operation in OPERATIONS)) {\n throw new Error('Invalid operation');\n }\n\n if (queryImportJobState) {\n const importJobStateWithOperation = `importJobState.${operation}`;\n const importJobStateForQuery = {[importJobStateWithOperation]: state};\n\n return importJobStateForQuery;\n }\n\n return {[operation]: state};\n}\n\nexport function createRecordResponseItem({responsePayload, responseStatus, recordMetadata, id}) {\n const recordResponseStatusAndMessage = getRecordResponseStatusAndMessage(responseStatus, responsePayload);\n const recordResponseItem = {\n databaseId: id || '000000000',\n recordMetadata: responsePayload.recordMetadata || recordMetadata || undefined,\n ...recordResponseStatusAndMessage\n };\n return recordResponseItem;\n}\n\nfunction getRecordResponseStatusAndMessage(responseStatus, responsePayload) {\n\n logger.debug(`Response status: ${responseStatus} responsePayload: ${JSON.stringify(responsePayload)}`);\n const responseStatusName = httpStatus[`${responseStatus}_NAME`];\n logger.debug(`Response status name: ${responseStatusName}`);\n\n const message = getMessageFromResponsePayload(responsePayload);\n\n logger.debug(`Response message: ${message}`);\n\n // Non-http statuses\n if (['UPDATED', 'CREATED', 'INVALID', 'ERROR'].includes(responseStatus)) {\n return {status: responseStatus, message};\n }\n\n if (['UNKNOWN'].includes(responseStatus)) {\n const possibleIds = responsePayload.ids || [];\n return {status: responseStatus, message, possibleIds};\n }\n\n // Duplicates and other CONFLICT statuses\n if ([httpStatus.CONFLICT, 'CONFLICT'].includes(responseStatus)) {\n if ((/^Duplicates in database/u).test(message)) {\n const duplicateIds = responsePayload.ids || [];\n return {status: 'DUPLICATE', message, duplicateIds};\n }\n return {status: 'CONFLICT', message};\n }\n\n if ([httpStatus.UNPROCESSABLE_ENTITY, 'UNPROCESSABLE_ENTITY'].includes(responseStatus)) {\n return {status: 'UNPROCESSABLE_ENTITY', message};\n }\n\n if ([httpStatus.NOT_FOUND, 'NOT_FOUND'].includes(responseStatus)) {\n return {status: 'NOT_FOUND', message};\n }\n\n // Otherwise\n return {status: 'ERROR', message};\n}\n\nfunction getMessageFromResponsePayload(responsePayload) {\n if (responsePayload.message) {\n return responsePayload.message;\n }\n if (typeof responsePayload === 'string' || responsePayload instanceof String) {\n return responsePayload;\n }\n return '';\n}\n\nexport async function addRecordResponseItem({recordResponseItem, correlationId, mongoOperator}) {\n await mongoOperator.pushMessages({correlationId, messages: [recordResponseItem], messageField: 'records'});\n return true;\n}\n\n"],"file":"utils.js"}
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "url": "git@github.com:natlibfi/melinda-rest-api-commons.git"
15
15
  },
16
16
  "license": "AGPL-3.0+",
17
- "version": "2.2.0-alpha.1",
17
+ "version": "2.2.0-alpha.12",
18
18
  "main": "./dist/index.js",
19
19
  "engines": {
20
20
  "node": ">=14"
@@ -33,7 +33,6 @@
33
33
  "build": "babel src --source-maps --copy-files --delete-dir-on-start --out-dir=dist"
34
34
  },
35
35
  "dependencies": {
36
- "@natlibfi/fixura": "^2.2.1",
37
36
  "@natlibfi/marc-record": "^7.0.0",
38
37
  "@natlibfi/marc-record-serializers": "^8.1.0",
39
38
  "@natlibfi/marc-record-validate": "^7.0.1",
@@ -42,26 +41,26 @@
42
41
  "@natlibfi/melinda-commons": "^12.0.3",
43
42
  "amqplib": ">=0.8.0 <1.0.0",
44
43
  "http-status": "^1.5.0",
45
- "moment": "^2.29.1",
44
+ "moment": "^2.29.2",
46
45
  "mongo-sanitize": "^1.1.0",
47
- "mongodb": "^4.1.3"
46
+ "mongodb": "^4.5.0"
48
47
  },
49
48
  "devDependencies": {
50
- "@babel/cli": "^7.15.7",
51
- "@babel/core": "^7.15.8",
49
+ "@babel/cli": "^7.17.6",
50
+ "@babel/core": "^7.17.8",
51
+ "@babel/eslint-parser": "^7.17.0",
52
52
  "@babel/plugin-syntax-dynamic-import": "^7.8.3",
53
- "@babel/preset-env": "^7.15.8",
53
+ "@babel/preset-env": "^7.16.11",
54
54
  "@natlibfi/eslint-config-melinda-backend": "^2.0.0",
55
- "@babel/eslint-parser": "^7.15.8",
55
+ "@natlibfi/fixura": "^2.2.1",
56
56
  "babel-plugin-dynamic-import-node": "^2.3.3",
57
57
  "babel-plugin-istanbul": "^6.1.1",
58
58
  "babel-plugin-rewire": "^1.2.0",
59
- "chai": "^4.3.4",
59
+ "chai": "^4.3.6",
60
60
  "cross-env": "^7.0.3",
61
- "eslint": "^8.10.0",
62
- "eslint-plugin-import": "^2.25.2",
63
- "mocha": "^9.2.1",
64
- "nodemon": "^2.0.14",
61
+ "eslint": "^8.12.0",
62
+ "mocha": "^9.2.2",
63
+ "nodemon": "^2.0.15",
65
64
  "nyc": "^15.1.0"
66
65
  },
67
66
  "eslintConfig": {