@natlibfi/melinda-rest-api-commons 4.2.5-alpha.1 → 5.0.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. package/.github/workflows/melinda-node-tests.yml +9 -6
  2. package/dist/conversion.js +70 -0
  3. package/dist/conversion.js.map +7 -0
  4. package/dist/fix-constants.js +63 -0
  5. package/dist/fix-constants.js.map +7 -0
  6. package/dist/fix-handle-tempurns.js +83 -0
  7. package/dist/fix-handle-tempurns.js.map +7 -0
  8. package/dist/fix-strip-f884s.js +160 -0
  9. package/dist/fix-strip-f884s.js.map +7 -0
  10. package/dist/fix-utils.js +39 -0
  11. package/dist/fix-utils.js.map +7 -0
  12. package/dist/fix.js +142 -0
  13. package/dist/fix.js.map +7 -0
  14. package/dist/validation.js +19 -0
  15. package/dist/validation.js.map +7 -0
  16. package/eslint.config.js +53 -0
  17. package/package.json +23 -96
  18. package/tests/{amqp.health.spec.js → amqp.healthtest.js} +2 -2
  19. package/tests/{amqp.tests.spec.js → amqp.tests.localtest.js} +46 -46
  20. package/tests/helpers/{conversion.spec.js → conversion.test.js} +38 -25
  21. package/tests/helpers/{fix.spec.js → fix.test.js} +6 -6
  22. package/tests/helpers/{validation.spec.js → validation.test.js} +12 -9
  23. package/tests/{mongo-add-blob-size.spec.js → mongo-add-blob-size.test.js} +6 -6
  24. package/tests/{mongo-check-and-check-state.spec.js → mongo-check-and-check-state.test.js} +7 -7
  25. package/tests/{mongo-check-and-set-import-job-state.spec.js → mongo-check-and-set-import-job-state.test.js} +7 -7
  26. package/tests/{mongo-check-timeout.spec.js → mongo-check-timeout.test.js} +7 -7
  27. package/tests/{mongo-create-bulk.spec.js → mongo-create-bulk.test.js} +5 -5
  28. package/tests/{mongo-create-prio.spec.js → mongo-create-prio.test.js} +6 -6
  29. package/tests/{mongo-get-one.spec.js → mongo-get-one.test.js} +7 -7
  30. package/tests/{mongo-get-stream.spec.js → mongo-get-stream.test.js} +7 -7
  31. package/tests/{mongo-push-ids.spec.js → mongo-push-ids.test.js} +5 -5
  32. package/tests/{mongo-push-messages.spec.js → mongo-push-messages.test.js} +6 -6
  33. package/tests/{mongo-query-by-id.spec.js → mongo-query-by-id.test.js} +7 -7
  34. package/tests/{mongo-query.spec.js → mongo-query.test.js} +7 -7
  35. package/tests/{mongo-read-content.spec.js → mongo-read-content.test.js} +8 -8
  36. package/tests/{mongo-remove.spec.js → mongo-remove.test.js} +6 -6
  37. package/tests/{mongo-set-blob-size.spec.js → mongo-set-blob-size.test.js} +6 -6
  38. package/tests/{mongo-set-import-job-state.spec.js → mongo-set-import-job-state.test.js} +6 -6
  39. package/tests/{mongo-set-operation.spec.js → mongo-set-operation.test.js} +6 -6
  40. package/tests/{mongo-set-operations.spec.js → mongo-set-operations.test.js} +6 -6
  41. package/tests/{mongo-set-state.spec.js → mongo-set-state.test.js} +7 -7
  42. package/tests/{mongoLog.spec.js → mongoLog.test.js} +10 -11
  43. package/tests/testUtils.js +9 -8
  44. package/dist/amqp.js +0 -326
  45. package/dist/amqp.js.map +0 -1
  46. package/dist/constants.js +0 -60
  47. package/dist/constants.js.map +0 -1
  48. package/dist/helpers/conversion.js +0 -88
  49. package/dist/helpers/conversion.js.map +0 -1
  50. package/dist/helpers/fix-constants.js +0 -70
  51. package/dist/helpers/fix-constants.js.map +0 -1
  52. package/dist/helpers/fix-handle-tempurns.js +0 -133
  53. package/dist/helpers/fix-handle-tempurns.js.map +0 -1
  54. package/dist/helpers/fix-strip-f884s.js +0 -210
  55. package/dist/helpers/fix-strip-f884s.js.map +0 -1
  56. package/dist/helpers/fix-utils.js +0 -54
  57. package/dist/helpers/fix-utils.js.map +0 -1
  58. package/dist/helpers/fix.js +0 -202
  59. package/dist/helpers/fix.js.map +0 -1
  60. package/dist/helpers/validation.js +0 -37
  61. package/dist/helpers/validation.js.map +0 -1
  62. package/dist/index.js +0 -109
  63. package/dist/index.js.map +0 -1
  64. package/dist/mongo.js +0 -822
  65. package/dist/mongo.js.map +0 -1
  66. package/dist/mongoLog.js +0 -409
  67. package/dist/mongoLog.js.map +0 -1
  68. package/dist/utils.js +0 -211
  69. package/dist/utils.js.map +0 -1
package/dist/fix.js ADDED
@@ -0,0 +1,142 @@
1
+ import createDebugLogger from "debug";
2
+ import { MarcRecord } from "@natlibfi/marc-record";
3
+ import { createLogger } from "@natlibfi/melinda-backend-commons";
4
+ import { FieldExclusion, SubfieldExclusion } from "@natlibfi/marc-record-validators-melinda";
5
+ import { handleTempUrns } from "./fix-handle-tempurns.js";
6
+ import { stripF884s } from "./fix-strip-f884s.js";
7
+ export * from "./fix-constants.js";
8
+ const logger = createLogger();
9
+ const debug = createDebugLogger("@natlibfi/melinda-rest-api-commons:fixRecord");
10
+ const debugData = debug.extend("data");
11
+ export function fixRecord(record, settings = {}) {
12
+ logger.verbose(`We will apply formatting to the record according to settings: ${JSON.stringify(settings)}`);
13
+ const newRecord = MarcRecord.clone(record, { subfieldValues: false });
14
+ debugData(`settings: ${JSON.stringify(settings)}`);
15
+ const generateMissingSIDsOptions = settings.generateMissingSIDs || void 0;
16
+ const newRecord1 = generateMissingSIDs(newRecord, generateMissingSIDsOptions);
17
+ const replacePrefixesOptions = settings.replacePrefixes || [];
18
+ const newRecord2 = replaceAllPrefixes(newRecord1, replacePrefixesOptions);
19
+ const newRecord3 = handleTempUrns(newRecord2, settings.handleTempUrns);
20
+ const newRecord4 = stripF884s(newRecord3, settings.stripF884s);
21
+ const newRecord5 = stripF984s(newRecord4, settings.stripF984s || false);
22
+ const newRecord6 = stripMelindaTempSubfields(newRecord5, settings.stripMelindaTempSubfields || false);
23
+ debugData(newRecord6);
24
+ return newRecord6.toObject();
25
+ }
26
+ function replaceAllPrefixes(record, replacePrefixesOptions) {
27
+ if (replacePrefixesOptions.length < 1) {
28
+ debug(`NOT running replacePrefixes, no options`);
29
+ return record;
30
+ }
31
+ debug(`Running replacePrefixes fixer`);
32
+ debugData(`replacePrefixesOptions: ${JSON.stringify(replacePrefixesOptions)}`);
33
+ replacePrefixesOptions.forEach((options) => {
34
+ replacePrefix(record, options);
35
+ });
36
+ return record;
37
+ }
38
+ function replacePrefix(record, options) {
39
+ const { oldPrefix, newPrefix, prefixReplaceCodes } = options;
40
+ debug(`Replacing ${oldPrefix} with ${newPrefix} in subfields ${prefixReplaceCodes}`);
41
+ const pattern = `(${oldPrefix})`;
42
+ const replacement = `(${newPrefix})`;
43
+ record.getDatafields().forEach((field) => {
44
+ field.subfields.filter(({ code }) => prefixReplaceCodes.includes(code)).forEach((subfield) => {
45
+ subfield.value = subfield.value.replace(pattern, replacement);
46
+ });
47
+ });
48
+ return record;
49
+ }
50
+ function generateMissingSIDs(record, options) {
51
+ const f035Filters = options && options.f035Filters ? options.f035Filters : [];
52
+ const fSIDFilters = options && options.fSIDFilters ? options.fSIDFilters : [];
53
+ if (f035Filters.length !== fSIDFilters.length || f035Filters.length < 1 || fSIDFilters.length < 1) {
54
+ debug(`NOT running generateMissingsSIDs, no options`);
55
+ return record;
56
+ }
57
+ debug(`Running generateMissingSIDs fixer`);
58
+ debugData(`generateMissingSIDs options: ${JSON.stringify(options)}`);
59
+ const f035s = f035ToSidInfo(record.get(/^035$/u));
60
+ const fSIDs = sidsToSidInfo(record.get(/^SID$/u));
61
+ const sidsToBeAdded = genNewSids(fSIDs.length === 0 ? f035s : f035s.filter((f035SidInfo) => !fSIDs.some((fSIDInfo) => f035SidInfo.SID === fSIDInfo.SID && f035SidInfo.value === fSIDInfo.value)));
62
+ debugData(`Adding (${sidsToBeAdded.length}) SIDs: ${JSON.stringify(sidsToBeAdded)}`);
63
+ sidsToBeAdded.forEach((sidField) => record.insertField(sidField));
64
+ return record;
65
+ function genNewSids(sidsToBeAdded2) {
66
+ return sidsToBeAdded2.map((sidInfo) => ({ tag: "SID", ind1: " ", ind2: " ", subfields: [{ code: "c", value: sidInfo.value }, { code: "b", value: sidInfo.SID }] }));
67
+ }
68
+ function sidsToSidInfo(SIDs) {
69
+ return SIDs.flatMap(({ subfields }) => {
70
+ const [SID] = subfields.filter((sub) => sub.code === "b" && fSIDFilters.includes(sub.value)).map((sub) => sub.value);
71
+ const [value] = subfields.filter((sub) => sub.code === "c" && sub.value !== void 0).map((sub) => sub.value);
72
+ if (SID && value) {
73
+ return {
74
+ SID,
75
+ value
76
+ };
77
+ }
78
+ return void 0;
79
+ }).filter((value) => value !== void 0);
80
+ }
81
+ function f035ToSidInfo(f035s2) {
82
+ return f035s2.flatMap(({ subfields }) => {
83
+ const [wantedSub] = subfields.filter((sub) => sub.code === "a" && f035Filters.some((regexp) => regexp.test(sub.value)));
84
+ if (wantedSub) {
85
+ return {
86
+ SID: fSIDFilters[f035Filters.findIndex((regexp) => regexp.test(wantedSub.value))],
87
+ value: wantedSub.value.slice(wantedSub.value.indexOf(")") + 1)
88
+ };
89
+ }
90
+ return void 0;
91
+ }).filter((value) => value !== void 0);
92
+ }
93
+ }
94
+ function stripF984s(record, stripF984sSettings) {
95
+ const F984A_PATTERN = /^(?:ALWAYS|NEVER)-PREFER-IN-MERGE$/u;
96
+ const config = [
97
+ {
98
+ tag: /^984$/u,
99
+ subfields: [
100
+ {
101
+ code: /a/u,
102
+ value: F984A_PATTERN
103
+ }
104
+ ]
105
+ }
106
+ ];
107
+ debug(`Running removeF984AFields`);
108
+ debugData(`removeF984AFieldsSettings: ${JSON.stringify(stripF984sSettings)}`);
109
+ if (!stripF984sSettings || !F984A_PATTERN || record.get("984").length < 1) {
110
+ debug(`No settings or pattern for removeF984AFields or f984 in record`);
111
+ return record;
112
+ }
113
+ debug(`Removing f984 fields with subfield $a consisting values ${F984A_PATTERN.toString()}`);
114
+ const validator = FieldExclusion(config);
115
+ validator.fix(record);
116
+ return record;
117
+ }
118
+ function stripMelindaTempSubfields(record, stripMelindaTempSubfieldsSettings) {
119
+ if (!stripMelindaTempSubfieldsSettings) {
120
+ debug(`No settings for stripMelindaTempSubfields`);
121
+ return record;
122
+ }
123
+ const tagPattern = /856/u;
124
+ const subfieldCodePattern = /9/u;
125
+ const subfieldValuePattern = /^MELINDA<TEMP>$/u;
126
+ const config = [
127
+ {
128
+ tag: tagPattern,
129
+ subfields: [
130
+ {
131
+ code: subfieldCodePattern,
132
+ value: subfieldValuePattern
133
+ }
134
+ ]
135
+ }
136
+ ];
137
+ debug(`Running stripMelindaTempSubfields`);
138
+ const validator = SubfieldExclusion(config);
139
+ validator.fix(record);
140
+ return record;
141
+ }
142
+ //# sourceMappingURL=fix.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/helpers/fix.js"],
4
+ "sourcesContent": ["import createDebugLogger from 'debug';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\n\nimport {FieldExclusion, SubfieldExclusion} from '@natlibfi/marc-record-validators-melinda';\n\nimport {handleTempUrns} from './fix-handle-tempurns.js';\nimport {stripF884s} from './fix-strip-f884s.js';\n\nexport * from './fix-constants.js';\n\nconst logger = createLogger();\nconst debug = createDebugLogger('@natlibfi/melinda-rest-api-commons:fixRecord');\nconst debugData = debug.extend('data');\n\nexport function fixRecord(record, settings = {}) {\n\n logger.verbose(`We will apply formatting to the record according to settings: ${JSON.stringify(settings)}`);\n const newRecord = MarcRecord.clone(record, {subfieldValues: false});\n debugData(`settings: ${JSON.stringify(settings)}`);\n\n // We should handle these in some prettier way ...\n\n // Fix 1, generate SIDs\n const generateMissingSIDsOptions = settings.generateMissingSIDs || undefined;\n const newRecord1 = generateMissingSIDs(newRecord, generateMissingSIDsOptions);\n\n // Fix 2, replace identifier prefixes\n const replacePrefixesOptions = settings.replacePrefixes || [];\n const newRecord2 = replaceAllPrefixes(newRecord1, replacePrefixesOptions);\n\n // Fix 3, handle temporary URNs from legal deposit record import\n const newRecord3 = handleTempUrns(newRecord2, settings.handleTempUrns);\n\n // Fix 4, strip extra field 884s\n const newRecord4 = stripF884s(newRecord3, settings.stripF884s);\n\n // Fix 5, strip extra field 984s\n const newRecord5 = stripF984s(newRecord4, settings.stripF984s || false);\n\n // Fix 6, strip $9 MELINDA<TEMP> subfields\n const newRecord6 = stripMelindaTempSubfields(newRecord5, settings.stripMelindaTempSubfields || false);\n\n debugData(newRecord6);\n\n return newRecord6.toObject();\n\n}\n\n\nfunction replaceAllPrefixes(record, replacePrefixesOptions) {\n if (replacePrefixesOptions.length < 1) {\n debug(`NOT running replacePrefixes, no options`);\n return record;\n }\n\n debug(`Running replacePrefixes fixer`);\n debugData(`replacePrefixesOptions: ${JSON.stringify(replacePrefixesOptions)}`);\n\n replacePrefixesOptions.forEach(options => {\n replacePrefix(record, options);\n });\n return record;\n}\n\n\n// Replace prefix in all specified subfields\nfunction replacePrefix(record, options) {\n const {oldPrefix, newPrefix, prefixReplaceCodes} = options;\n debug(`Replacing ${oldPrefix} with ${newPrefix} in subfields ${prefixReplaceCodes}`);\n const pattern = `(${oldPrefix})`;\n const replacement = `(${newPrefix})`;\n record.getDatafields()\n .forEach(field => {\n field.subfields\n .filter(({code}) => prefixReplaceCodes.includes(code))\n .forEach(subfield => {\n subfield.value = subfield.value.replace(pattern, replacement);\n });\n });\n return record;\n}\n\n\nfunction generateMissingSIDs(record, options) {\n\n const f035Filters = options && options.f035Filters ? options.f035Filters : [];\n const fSIDFilters = options && options.fSIDFilters ? options.fSIDFilters : [];\n\n if (f035Filters.length !== fSIDFilters.length || f035Filters.length < 1 || fSIDFilters.length < 1) {\n debug(`NOT running generateMissingsSIDs, no options`);\n return record;\n }\n\n debug(`Running generateMissingSIDs fixer`);\n debugData(`generateMissingSIDs options: ${JSON.stringify(options)}`);\n\n const f035s = f035ToSidInfo(record.get(/^035$/u));\n const fSIDs = sidsToSidInfo(record.get(/^SID$/u));\n\n const sidsToBeAdded = genNewSids(fSIDs.length === 0\n ? f035s\n // test that SIDs are not there yet\n : f035s.filter(f035SidInfo => !fSIDs.some(fSIDInfo => f035SidInfo.SID === fSIDInfo.SID && f035SidInfo.value === fSIDInfo.value)));\n\n debugData(`Adding (${sidsToBeAdded.length}) SIDs: ${JSON.stringify(sidsToBeAdded)}`);\n\n // Add new SIDs\n sidsToBeAdded.forEach(sidField => record.insertField(sidField));\n return record;\n\n function genNewSids(sidsToBeAdded) {\n return sidsToBeAdded.map(sidInfo => ({tag: 'SID', ind1: ' ', ind2: ' ', subfields: [{code: 'c', value: sidInfo.value}, {code: 'b', value: sidInfo.SID}]}));\n }\n\n function sidsToSidInfo(SIDs) {\n return SIDs.flatMap(({subfields}) => {\n const [SID] = subfields.filter(sub => sub.code === 'b' && fSIDFilters.includes(sub.value)).map(sub => sub.value);\n const [value] = subfields.filter(sub => sub.code === 'c' && sub.value !== undefined).map(sub => sub.value);\n\n if (SID && value) {\n return {\n SID,\n value\n };\n }\n\n return undefined;\n }).filter(value => value !== undefined);\n }\n\n function f035ToSidInfo(f035s) {\n return f035s.flatMap(({subfields}) => {\n const [wantedSub] = subfields.filter(sub => sub.code === 'a' && f035Filters.some(regexp => regexp.test(sub.value)));\n\n if (wantedSub) {\n return {\n SID: fSIDFilters[f035Filters.findIndex(regexp => regexp.test(wantedSub.value))],\n value: wantedSub.value.slice(wantedSub.value.indexOf(')') + 1)\n };\n }\n\n return undefined;\n }).filter(value => value !== undefined);\n }\n}\n\n\nfunction stripF984s(record, stripF984sSettings) {\n const F984A_PATTERN = /^(?:ALWAYS|NEVER)-PREFER-IN-MERGE$/u;\n const config = [\n {\n tag: /^984$/u,\n subfields: [\n {\n code: /a/u,\n value: F984A_PATTERN\n }\n ]\n }\n ];\n\n debug(`Running removeF984AFields`);\n debugData(`removeF984AFieldsSettings: ${JSON.stringify(stripF984sSettings)}`);\n\n if (!stripF984sSettings || !F984A_PATTERN || record.get('984').length < 1) {\n debug(`No settings or pattern for removeF984AFields or f984 in record`);\n return record;\n }\n\n debug(`Removing f984 fields with subfield $a consisting values ${F984A_PATTERN.toString()}`);\n // eslint-disable-next-line new-cap\n const validator = FieldExclusion(config);\n validator.fix(record);\n return record;\n\n}\n\nfunction stripMelindaTempSubfields(record, stripMelindaTempSubfieldsSettings) {\n if (!stripMelindaTempSubfieldsSettings) {\n debug(`No settings for stripMelindaTempSubfields`);\n return record;\n }\n // NOTE: we remove $9 MELINDA<TEMP> subfields only from f856\n const tagPattern = /856/u;\n const subfieldCodePattern = /9/u;\n const subfieldValuePattern = /^MELINDA<TEMP>$/u;\n const config = [\n {\n tag: tagPattern,\n subfields: [\n {\n code: subfieldCodePattern,\n value: subfieldValuePattern\n }\n ]\n }\n ];\n\n debug(`Running stripMelindaTempSubfields`);\n\n // eslint-disable-next-line new-cap\n const validator = SubfieldExclusion(config);\n validator.fix(record);\n return record;\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["sidsToBeAdded", "f035s"]
7
+ }
@@ -0,0 +1,19 @@
1
+ import validateFactory from "@natlibfi/marc-record-validate";
2
+ import {
3
+ FieldStructure as fieldStructure
4
+ } from "@natlibfi/marc-record-validators-melinda";
5
+ import { createLogger } from "@natlibfi/melinda-backend-commons";
6
+ export default async () => {
7
+ const logger = createLogger();
8
+ logger.verbose("Running inbuilt record validations");
9
+ const validate = validateFactory([await fieldStructure([{ tag: /^003$/u, valuePattern: /^FI-MELINDA$/u }])]);
10
+ return async (unvalidRecord) => {
11
+ const { record, valid, report } = await validate(unvalidRecord, { fix: false, validateFixes: false }, { subfieldValues: false });
12
+ return {
13
+ record,
14
+ failed: valid === false,
15
+ messages: report
16
+ };
17
+ };
18
+ };
19
+ //# sourceMappingURL=validation.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/helpers/validation.js"],
4
+ "sourcesContent": ["import validateFactory from '@natlibfi/marc-record-validate';\nimport {\n FieldStructure as fieldStructure\n} from '@natlibfi/marc-record-validators-melinda';\nimport {createLogger} from '@natlibfi/melinda-backend-commons';\n\nexport default async () => {\n const logger = createLogger();\n\n logger.verbose('Running inbuilt record validations');\n const validate = validateFactory([await fieldStructure([{tag: /^003$/u, valuePattern: /^FI-MELINDA$/u}])]);\n\n return async unvalidRecord => {\n const {record, valid, report} = await validate(unvalidRecord, {fix: false, validateFixes: false}, {subfieldValues: false});\n\n return {\n record,\n failed: valid === false,\n messages: report\n };\n };\n};\n"],
5
+ "mappings": "AAAA,OAAO,qBAAqB;AAC5B;AAAA,EACE,kBAAkB;AAAA,OACb;AACP,SAAQ,oBAAmB;AAE3B,eAAe,YAAY;AACzB,QAAM,SAAS,aAAa;AAE5B,SAAO,QAAQ,oCAAoC;AACnD,QAAM,WAAW,gBAAgB,CAAC,MAAM,eAAe,CAAC,EAAC,KAAK,UAAU,cAAc,gBAAe,CAAC,CAAC,CAAC,CAAC;AAEzG,SAAO,OAAM,kBAAiB;AAC5B,UAAM,EAAC,QAAQ,OAAO,OAAM,IAAI,MAAM,SAAS,eAAe,EAAC,KAAK,OAAO,eAAe,MAAK,GAAG,EAAC,gBAAgB,MAAK,CAAC;AAEzH,WAAO;AAAA,MACL;AAAA,MACA,QAAQ,UAAU;AAAA,MAClB,UAAU;AAAA,IACZ;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,53 @@
1
+ // Eslint configuration object for src
2
+ const configSrc = {
3
+ files: [
4
+ "src/*",
5
+ "tests/*"
6
+ ],
7
+ linterOptions: {
8
+ reportUnusedDisableDirectives: true,
9
+ },
10
+ rules: {
11
+ "no-console": "warn",
12
+ "eqeqeq": ["error", "always"],
13
+ "no-const-assign": "error",
14
+ "max-depth": ["warn", 4],
15
+ "max-lines": ["warn", 500],
16
+ "max-lines-per-function": ["warn", {"max": 100}],
17
+ "no-else-return": ["error", {allowElseIf: false}],
18
+ "no-plusplus": [
19
+ "error",
20
+ {
21
+ "allowForLoopAfterthoughts": true
22
+ }
23
+ ],
24
+ "array-callback-return": [
25
+ "error",
26
+ {
27
+ "checkForEach": false
28
+ }
29
+ ],
30
+ "no-unused-vars": [
31
+ "error",
32
+ {
33
+ "argsIgnorePattern": "next"
34
+ }
35
+ ],
36
+ "no-warning-comments": "off"
37
+ }
38
+ };
39
+
40
+ // Eslint configuration object for globally ignoring .js files
41
+ // - ignore all files that start with a dot
42
+ // - ignore all files inside directories named 'dist'
43
+ const configIgnores = {
44
+ ignores: [
45
+ "**/.*",
46
+ "**/dist/"
47
+ ]
48
+ };
49
+
50
+ export default [
51
+ configSrc,
52
+ configIgnores
53
+ ];
package/package.json CHANGED
@@ -14,124 +14,51 @@
14
14
  "url": "git@github.com:natlibfi/melinda-rest-api-commons.git"
15
15
  },
16
16
  "license": "MIT",
17
- "version": "4.2.5-alpha.1",
17
+ "version": "5.0.0-alpha.1",
18
18
  "main": "./dist/index.js",
19
+ "type": "module",
19
20
  "engines": {
20
- "node": ">=18"
21
+ "node": ">=22"
21
22
  },
22
23
  "publishConfig": {
23
24
  "access": "public"
24
25
  },
25
26
  "scripts": {
26
27
  "prepare": "npm run build",
27
- "build": "babel src --source-maps --copy-files --delete-dir-on-start --out-dir=dist",
28
+ "build": "esbuild src/**/*.js --sourcemap --platform=node --main-fields=main --outdir=dist --allow-overwrite --analyze",
28
29
  "lint": "eslint ./src",
29
- "lint:dev": "eslint ./src --fix",
30
+ "lint:dev": "eslint --fix ./src",
30
31
  "test": "npm run lint && npm run test:base",
31
- "test:base": "cross-env NODE_ENV=test nyc mocha --package ./package.json --exclude tests/amqp.health.spec.js --exclude tests/amqp.tests.spec.js",
32
- "test:dev": "npm run lint:dev && cross-env NODE_ENV=test nyc mocha --package ./package.json --exclude tests/amqp.health.spec.js --exclude tests/amqp.tests.spec.js",
33
- "test:local": "cross-env NODE_ENV=test nyc mocha --package ./package.json -- tests/amqp.*.spec.js",
34
- "test:healthcheck": "cross-env NODE_ENV=test nyc mocha --require @babel/register -- tests/amqp.health.spec.js",
35
- "dev": "nodemon",
36
- "dev:debug": "cross-env LOG_LEVEL=debug DEBUG=@natlibfi/* NODE_ENV=test nodemon"
32
+ "test:base": "node --test --test-force-exit --experimental-test-coverage --test-reporter=spec './tests/**/*.test.js'",
33
+ "test:local": "cross-env NODE_ENV=test node --test --test-force-exit --experimental-test-coverage --test-reporter=spec './tests/amqp.*.localtest.js'",
34
+ "test:healthcheck": "cross-env NODE_ENV=test node --test --test-force-exit --experimental-test-coverage --test-reporter=spec './tests/amqp.healthtest.js'",
35
+ "watch:test": "cross-env DEBUG=@natlibfi/* NODE_ENV=test node --watch --test --experimental-test-coverage --test-reporter=spec './src/*.test.js' './src/**/*.test.js'",
36
+ "dev": "npm run watch:test",
37
+ "dev:debug": "cross-env LOG_LEVEL=debug DEBUG=@natlibfi/* NODE_ENV=test npm run watch:test"
37
38
  },
38
39
  "dependencies": {
39
- "@natlibfi/marc-record": "^9.1.5",
40
- "@natlibfi/marc-record-serializers": "^10.1.6",
41
- "@natlibfi/marc-record-validate": "^8.0.14",
40
+ "@natlibfi/marc-record": "^10.0.0-alpha.1",
41
+ "@natlibfi/marc-record-serializers": "^11.0.0-alpha.2",
42
+ "@natlibfi/marc-record-validate": "^9.0.0-alpha.1",
42
43
  "@natlibfi/marc-record-validators-melinda": "^11.6.2",
43
- "@natlibfi/melinda-backend-commons": "^2.3.8",
44
- "@natlibfi/melinda-commons": "^13.0.20",
44
+ "@natlibfi/melinda-backend-commons": "^3.0.0-alpha.3",
45
+ "@natlibfi/melinda-commons": "^14.0.0-alpha.3",
45
46
  "amqplib": "^0.10.8",
46
47
  "debug": "^4.4.0",
47
48
  "http-status": "^2.1.0",
48
49
  "moment": "^2.30.1",
49
50
  "mongo-sanitize": "^1.1.0",
50
- "mongodb": "^6.16.0"
51
+ "mongodb": "^6.18.0"
51
52
  },
52
53
  "devDependencies": {
53
- "@babel/cli": "^7.27.1",
54
- "@babel/core": "^7.27.1",
55
- "@babel/plugin-transform-runtime": "^7.27.1",
56
- "@babel/preset-env": "^7.27.1",
57
- "@babel/register": "^7.27.1",
58
- "@natlibfi/eslint-config-melinda-backend": "^3.0.5",
59
- "@natlibfi/fixugen": "^2.0.14",
60
- "@natlibfi/fixura": "^3.0.13",
61
- "@natlibfi/fixura-mongo": "^2.0.24",
62
- "babel-plugin-istanbul": "^7.0.0",
63
- "babel-plugin-rewire": "^1.2.0",
64
- "chai": "^4.5.0",
65
- "cross-env": "^7.0.3",
66
- "eslint": "^8.57.1",
67
- "mocha": "^11.2.2",
68
- "nodemon": "^3.1.10",
69
- "nyc": "^17.1.0"
54
+ "@natlibfi/fixugen": "^3.0.0-alpha.5",
55
+ "@natlibfi/fixura": "^4.0.0-alpha.12",
56
+ "@natlibfi/fixura-mongo": "^3.0.0-alpha.5",
57
+ "cross-env": "^10.0.0",
58
+ "esbuild": "^0.25.9",
59
+ "eslint": "^9.33.0"
70
60
  },
71
61
  "overrides": {
72
62
  "nanoid": "^3.3.8"
73
- },
74
- "eslintConfig": {
75
- "extends": "@natlibfi/melinda-backend"
76
- },
77
- "babel": {
78
- "presets": [
79
- [
80
- "@babel/preset-env",
81
- {
82
- "targets": "maintained node versions"
83
- }
84
- ]
85
- ],
86
- "plugins": [
87
- [
88
- "@babel/transform-runtime"
89
- ]
90
- ],
91
- "env": {
92
- "test": {
93
- "plugins": [
94
- "istanbul",
95
- "rewire"
96
- ]
97
- }
98
- }
99
- },
100
- "mocha": {
101
- "spec": [
102
- "tests/*.spec.js",
103
- "tests/**/*.spec.js"
104
- ],
105
- "require": [
106
- "@babel/register"
107
- ],
108
- "inline-diffs": true,
109
- "maxDiffSize": 25000,
110
- "bail": true,
111
- "exit": true,
112
- "timeout": 10000
113
- },
114
- "nodemonConfig": {
115
- "exec": "npm run test:dev",
116
- "watch": [
117
- "tests/*",
118
- "src/*",
119
- "test-fixtures/*"
120
- ]
121
- },
122
- "nyc": {
123
- "exclude": [
124
- "tests/*.spec.js",
125
- "tests/**/*.spec.js"
126
- ],
127
- "reporter": [
128
- "text"
129
- ],
130
- "sourceMap": false,
131
- "instrument": false,
132
- "lines": 80,
133
- "statements": 80,
134
- "functions": 80,
135
- "branches": 80
136
63
  }
137
64
  }
@@ -1,6 +1,6 @@
1
- //import {expect} from 'chai';
1
+ //import assert from 'node:assert';
2
2
  import createDebugLogger from 'debug';
3
- import {amqpFactory} from '../src/index';
3
+ import {amqpFactory} from '../src/index.js';
4
4
 
5
5
 
6
6
  const debug = createDebugLogger('@natlibfi/melinda-rest-api-commons:amqp:test');
@@ -1,10 +1,10 @@
1
- import {expect} from 'chai';
2
- import {READERS} from '@natlibfi/fixura';
1
+ import assert from 'node:assert';
3
2
  import createDebugLogger from 'debug';
3
+ import {promisify} from 'util';
4
+ import {READERS} from '@natlibfi/fixura';
4
5
  import generateTests from '@natlibfi/fixugen';
5
- import {amqpFactory} from '../src/index';
6
6
  import {Error as ApiError} from '@natlibfi/melinda-commons';
7
- import {promisify} from 'util';
7
+ import {amqpFactory} from '../src/index.js';
8
8
 
9
9
  const setTimeoutPromise = promisify(setTimeout);
10
10
  const debug = createDebugLogger('@natlibfi/melinda-rest-api-commons:amqp:test');
@@ -23,14 +23,14 @@ let amqpOperator;
23
23
 
24
24
  generateTests({
25
25
  callback,
26
- path: [__dirname, '..', 'test-fixtures', 'amqp'],
26
+ path: [import.meta.dirname, '..', 'test-fixtures', 'amqp'],
27
27
  recurse: false,
28
28
  useMetadataFile: true,
29
29
  fixura: {
30
30
  failWhenNotFound: true,
31
31
  reader: READERS.JSON
32
32
  },
33
- mocha: {
33
+ hooks: {
34
34
  before: async () => {
35
35
  debug(`Connecting to ${amqpUrl}, with healthCheck running`);
36
36
  amqpOperator = await amqpFactory(amqpUrl, true);
@@ -76,13 +76,13 @@ async function callback({
76
76
 
77
77
  const messageCount = await amqpOperator.checkQueue({queue, style: 'messages'});
78
78
  debug(`MessageCount: ${messageCount}`);
79
- expect(messageCount).to.eql(expectedMessageCount);
79
+ assert.equal(messageCount, expectedMessageCount);
80
80
 
81
81
  if (checkNextMessage) {
82
82
  const {headers, records} = await queueCheckNextMessage();
83
83
  const nextMessage = {headers, records};
84
84
  const expectedNextMessage = getFixture('expectedMessage.json');
85
- expect(nextMessage).to.eql(expectedNextMessage);
85
+ assert.equal(nextMessage, expectedNextMessage);
86
86
  return;
87
87
  }
88
88
 
@@ -90,25 +90,25 @@ async function callback({
90
90
  if (!expectToFail) {
91
91
  throw error;
92
92
  }
93
- expect(expectToFail, 'This is expected to fail').to.equal(true);
93
+ assert.equal(expectToFail, true, 'This is expected to fail');
94
94
  testErrors(error);
95
95
  }
96
96
 
97
97
  function testErrors(error) {
98
-
98
+ const isApiError = error instanceof ApiError;
99
99
  if (expectApiError) {
100
- expect(error).to.be.instanceOf(ApiError);
100
+ assert.equal(isApiError, true);
101
101
  debug(`We expected and got an ApiError`);
102
- expect(error.status).to.equal(expectedErrorStatus);
102
+ assert.equal(error.status, expectedErrorStatus);
103
103
 
104
104
  if (expectedErrorMessage) {
105
- expect(error.payload).to.eql(expectedErrorMessage);
105
+ assert.equal(error.payload, expectedErrorMessage);
106
106
  return;
107
107
  }
108
108
 
109
109
  return;
110
110
  }
111
- expect(error).not.to.be.instanceOf(ApiError);
111
+ assert.equal(isApiError, false);
112
112
  debug(`We expected and got an non-ApiError`);
113
113
  debug(`Error is a ${error.constructor.name}`);
114
114
  }
@@ -141,11 +141,11 @@ async function callback({
141
141
  return;
142
142
  }
143
143
 
144
- expect(result).to.have.property('headers');
145
- expect(result).to.have.property('records');
146
- expect(result).to.have.property('messages');
147
- expect(result.records.length).to.eql(1);
148
- expect(result.messages.length).to.eql(1);
144
+ assert.equal(Object.hasOwn(result, 'headers'), true);
145
+ assert.equal(Object.hasOwn(result, 'records'), true);
146
+ assert.equal(Object.hasOwn(result, 'messages'), true);
147
+ assert.equal(result.records.length, 1);
148
+ assert.equal(result.messages.length, 1);
149
149
 
150
150
  return;
151
151
  }
@@ -159,15 +159,15 @@ async function callback({
159
159
  return;
160
160
  }
161
161
 
162
- expect(fields).to.have.property('deliveryTag');
163
- expect(fields).to.have.property('exchange');
164
- expect(fields).to.have.property('messageCount');
165
- expect(fields).to.have.property('redelivered');
166
- expect(fields).to.have.property('routingKey');
167
- expect(typeof fields.deliveryTag).to.be.eql('number');
168
- expect(typeof fields.messageCount).to.be.eql('number');
169
- expect(typeof fields.redelivered).to.be.eql('boolean');
170
- expect(typeof fields.routingKey).to.be.eql('string');
162
+ assert.equal(Object.hasOwn(result, 'deliveryTag'), true);
163
+ assert.equal(Object.hasOwn(result, 'exchange'), true);
164
+ assert.equal(Object.hasOwn(result, 'messageCount'), true);
165
+ assert.equal(Object.hasOwn(result, 'redelivered'), true);
166
+ assert.equal(Object.hasOwn(result, 'routingKey'), true);
167
+ assert.equal(typeof fields.deliveryTag, 'number');
168
+ assert.equal(typeof fields.messageCount, 'number');
169
+ assert.equal(typeof fields.redelivered, 'boolean');
170
+ assert.equal(typeof fields.routingKey, 'string');
171
171
 
172
172
  return;
173
173
  }
@@ -180,13 +180,13 @@ async function callback({
180
180
  return;
181
181
  }
182
182
 
183
- expect(result).to.have.property('headers');
184
- expect(result).to.have.property('records');
185
- expect(result).to.have.property('messages');
186
- expect(result.records.length).to.eql(3);
187
- expect(result.messages.length).to.eql(3);
183
+ assert.equal(Object.hasOwn(result, 'headers'), true);
184
+ assert.equal(Object.hasOwn(result, 'records'), true);
185
+ assert.equal(Object.hasOwn(result, 'messages'), true);
186
+ assert.equal(result.records.length, 3);
187
+ assert.equal(result.messages.length, 3);
188
188
  const expectedResult = getFixture('expectedResult.json');
189
- expect(result.records).to.eql(expectedResult);
189
+ assert.deepStrictEqual(result.records, expectedResult);
190
190
 
191
191
  return;
192
192
  }
@@ -199,22 +199,22 @@ async function callback({
199
199
  return;
200
200
  }
201
201
 
202
- expect(result).to.have.property('headers');
203
- expect(result).to.have.property('messages');
204
- expect(result.messages.length).to.eql(3);
202
+ assert.equal(Object.hasOwn(result, 'headers'), true);
203
+ assert.equal(Object.hasOwn(result, 'messages'), true);
204
+ assert.equal(result.messages.length, 3);
205
205
 
206
206
  const [{fields}] = result.messages;
207
207
 
208
- expect(fields).to.have.property('deliveryTag');
209
- expect(fields).to.have.property('exchange');
210
- expect(fields).to.have.property('messageCount');
211
- expect(fields).to.have.property('redelivered');
212
- expect(fields).to.have.property('routingKey');
208
+ assert.equal(Object.hasOwn(result, 'deliveryTag'), true);
209
+ assert.equal(Object.hasOwn(result, 'exchange'), true);
210
+ assert.equal(Object.hasOwn(result, 'messageCount'), true);
211
+ assert.equal(Object.hasOwn(result, 'redelivered'), true);
212
+ assert.equal(Object.hasOwn(result, 'routingKey'), true);
213
213
 
214
- expect(typeof fields.deliveryTag).to.be.eql('number');
215
- expect(typeof fields.messageCount).to.be.eql('number');
216
- expect(typeof fields.redelivered).to.be.eql('boolean');
217
- expect(typeof fields.routingKey).to.be.eql('string');
214
+ assert.equal(typeof fields.deliveryTag, 'number');
215
+ assert.equal(typeof fields.messageCount, 'number');
216
+ assert.equal(typeof fields.redelivered, 'boolean');
217
+ assert.equal(typeof fields.routingKey, 'string');
218
218
 
219
219
  return;
220
220
  }