@natlibfi/marc-record-merge 6.0.0-beta.8 → 7.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.
- package/.github/CODEOWNERS +2 -9
- package/.github/dependabot.yml +2 -3
- package/.github/workflows/melinda-node-tests.yml +2 -2
- package/README.md +16 -0
- package/dist/index.js +49 -4
- package/dist/index.js.map +1 -1
- package/dist/index.spec.js +59 -0
- package/dist/index.spec.js.map +1 -0
- package/dist/reducers/copy.js +59 -148
- package/dist/reducers/copy.js.map +1 -1
- package/dist/reducers/copy.spec.js +9 -12
- package/dist/reducers/copy.spec.js.map +1 -1
- package/dist/reducers/copy2.spec.js +66 -0
- package/dist/reducers/copy2.spec.js.map +1 -0
- package/dist/reducers/index.js +0 -6
- package/dist/reducers/index.js.map +1 -1
- package/dist/reducers/select.js +43 -40
- package/dist/reducers/select.js.map +1 -1
- package/dist/reducers/select.spec.js +4 -15
- package/dist/reducers/select.spec.js.map +1 -1
- package/dist/reducers/select2.spec.js +58 -0
- package/dist/reducers/select2.spec.js.map +1 -0
- package/package.json +18 -18
- package/src/index.js +51 -1
- package/src/index.spec.js +45 -0
- package/src/reducers/copy.js +42 -103
- package/src/reducers/copy.spec.js +4 -6
- package/src/reducers/copy2.spec.js +55 -0
- package/src/reducers/select.js +31 -10
- package/src/reducers/select2.spec.js +49 -0
- package/test-fixtures/index/01/base.json +24 -0
- package/test-fixtures/index/01/merged.json +24 -0
- package/test-fixtures/index/01/metadata.json +8 -0
- package/test-fixtures/index/01/source.json +40 -0
- package/test-fixtures/index/02/base.json +24 -0
- package/test-fixtures/index/02/merged.json +24 -0
- package/test-fixtures/index/02/metadata.json +7 -0
- package/test-fixtures/index/02/source.json +40 -0
- package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/03/metadata.json +6 -0
- package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/base.json +20 -0
- package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/merged.json +31 -0
- package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/metadata.json +5 -0
- package/test-fixtures/reducers/copy/04 - compareWithoutIndicators/04/source.json +20 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/01/base.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/01/merged.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/01/metadata.json +6 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/01/source.json +20 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/02/base.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/02/merged.json +39 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/02/metadata.json +6 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/02/source.json +31 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/03/base.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/03/merged.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/03/metadata.json +7 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/03/source.json +20 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/base.json +17 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/merged.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/metadata.json +7 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/04/source.json +31 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/base.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/merged.json +28 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/metadata.json +7 -0
- package/test-fixtures/reducers/copy/11 - compareWithoutTag/05/source.json +28 -0
package/.github/CODEOWNERS
CHANGED
|
@@ -1,9 +1,2 @@
|
|
|
1
|
-
# With this line @NatLibFi/melinda-js-lead owns any files in
|
|
2
|
-
|
|
3
|
-
# subdirectories.
|
|
4
|
-
/.github/ @NatLibFi/melinda-js-lead
|
|
5
|
-
|
|
6
|
-
# With this line @NatLibFi/melinda-js-lead owns any files in the /src/
|
|
7
|
-
# directory at the root of the repository and any of its
|
|
8
|
-
# subdirectories.
|
|
9
|
-
/src/ @NatLibFi/melinda-js-lead
|
|
1
|
+
# With this line @NatLibFi/melinda-js-lead owns any files in this repository
|
|
2
|
+
* @NatLibFi/melinda-js-lead
|
package/.github/dependabot.yml
CHANGED
|
@@ -10,7 +10,7 @@ updates:
|
|
|
10
10
|
interval: "daily"
|
|
11
11
|
time: "06:30"
|
|
12
12
|
timezone: "Europe/Helsinki"
|
|
13
|
-
|
|
13
|
+
target-branch: "dependencies"
|
|
14
14
|
|
|
15
15
|
# Minor updates to npm production dependencies daily
|
|
16
16
|
- package-ecosystem: "npm"
|
|
@@ -20,10 +20,9 @@ updates:
|
|
|
20
20
|
time: "06:45"
|
|
21
21
|
timezone: "Europe/Helsinki"
|
|
22
22
|
versioning-strategy: lockfile-only
|
|
23
|
-
labels:
|
|
24
|
-
- "npm minor dependencies"
|
|
25
23
|
allow:
|
|
26
24
|
- dependency-type: "production"
|
|
25
|
+
target-branch: "dependencies"
|
|
27
26
|
|
|
28
27
|
# Major updates to npm dependencies weekly @tuesday
|
|
29
28
|
# Not possible yet https://github.com/dependabot/dependabot-core/issues/1778
|
|
@@ -11,7 +11,7 @@ jobs:
|
|
|
11
11
|
|
|
12
12
|
strategy:
|
|
13
13
|
matrix:
|
|
14
|
-
node-version: [
|
|
14
|
+
node-version: [16.x, 18.x, 19.x]
|
|
15
15
|
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/
|
|
16
16
|
|
|
17
17
|
steps:
|
|
@@ -52,7 +52,7 @@ jobs:
|
|
|
52
52
|
# Setup .npmrc file to publish to npm
|
|
53
53
|
- uses: actions/setup-node@v3
|
|
54
54
|
with:
|
|
55
|
-
node-version: '
|
|
55
|
+
node-version: '18.x'
|
|
56
56
|
registry-url: 'https://registry.npmjs.org'
|
|
57
57
|
- run: npm ci
|
|
58
58
|
- run: npm publish
|
package/README.md
CHANGED
|
@@ -36,6 +36,14 @@ If base has field with that tag 011 source field is ignored
|
|
|
36
36
|
|
|
37
37
|
When base and source fields are compared, indicator differences are ignored
|
|
38
38
|
|
|
39
|
+
### compareWithoutTag (Defaults false)
|
|
40
|
+
```
|
|
41
|
+
{tagPattern: /^(100|700)$/u, compareWithoutTag: false}
|
|
42
|
+
{tagPattern: /^(100|700)$/u, compareWithoutTag: false, swapTag: [{"from": "^100$", "to": "700"}]}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
When base and source fields are compared, tag differences are ignored
|
|
46
|
+
|
|
39
47
|
### subfieldsMustBeIdentical (Defaults true)
|
|
40
48
|
```
|
|
41
49
|
{tagPattern: /010/u, subfieldsMustBeIdentical: true}
|
|
@@ -58,6 +66,14 @@ If source subfields are subset of base subfields this option says if it is copie
|
|
|
58
66
|
|
|
59
67
|
When base and source fields are compared, excluded subfields are ignored
|
|
60
68
|
|
|
69
|
+
### swapTag (Defaults [ ])
|
|
70
|
+
```
|
|
71
|
+
{tagPattern: /^100$/u, swapTag: [{"from": "^100$", "to": "700"}]}
|
|
72
|
+
{tagPattern: /^(100|700)$/u, compareWithoutTag: false, swapTag: [{"from": "^100$", "to": "700"}]}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
When fields are copied, tags are swapped. From is Regexp filter and to is string value.
|
|
76
|
+
|
|
61
77
|
### swapSubfieldCode (Defaults [ ])
|
|
62
78
|
```
|
|
63
79
|
{tagPattern: /010/u, swapSubfieldCode: [{"from": "a", "to": "b"}]}
|
package/dist/index.js
CHANGED
|
@@ -10,16 +10,61 @@ Object.defineProperty(exports, "Reducers", {
|
|
|
10
10
|
}
|
|
11
11
|
});
|
|
12
12
|
exports.default = void 0;
|
|
13
|
-
|
|
14
13
|
var _reducers = _interopRequireDefault(require("./reducers"));
|
|
15
|
-
|
|
14
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
16
15
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
17
|
-
|
|
16
|
+
const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge:index');
|
|
17
|
+
const debugData = debug.extend('data');
|
|
18
|
+
// export default ({base, source, reducers}) => reducers.reduce((base, reducer) => reducer(base, source), base);
|
|
19
|
+
// NV: Modified the reducer loop so, that not only base, but also is carried back.
|
|
20
|
+
// However, we try to be backward-compatible: normally after the reducers, only base is returned.
|
|
18
21
|
var _default = ({
|
|
19
22
|
base,
|
|
20
23
|
source,
|
|
21
24
|
reducers
|
|
22
|
-
}) =>
|
|
25
|
+
}) => {
|
|
26
|
+
const combo = {
|
|
27
|
+
base,
|
|
28
|
+
source
|
|
29
|
+
};
|
|
30
|
+
const resultCombo = reducers.reduce((combo, reducer) => {
|
|
31
|
+
const returnCombo = singleRound(reducer, combo.base, combo.source);
|
|
32
|
+
//debugData(`returnCombo after current reducer: ${JSON.stringify(returnCombo)}`);
|
|
33
|
+
return returnCombo;
|
|
34
|
+
}, combo);
|
|
35
|
+
debugData(`ResultCombo after reducers: ${JSON.stringify(resultCombo)}`);
|
|
23
36
|
|
|
37
|
+
// Hack to make my melinda-marc-record-merge-reducers single tests that expect both
|
|
38
|
+
// base and source to return them both:
|
|
39
|
+
if (reducers.length === 1 && resultCombo.base && resultCombo.source) {
|
|
40
|
+
debug('Single reducer, returning resultCombo');
|
|
41
|
+
debugData(JSON.stringify(resultCombo));
|
|
42
|
+
return resultCombo;
|
|
43
|
+
}
|
|
44
|
+
// All other tests return just base... Backward (compability) it is!
|
|
45
|
+
debug('Multiple reducers, returning just base');
|
|
46
|
+
debugData(JSON.stringify(resultCombo.base));
|
|
47
|
+
return resultCombo.base;
|
|
48
|
+
function singleRound(reducer, base, source) {
|
|
49
|
+
//debug(`SINGLE ROUND INPUT (base, source)`);
|
|
50
|
+
//debugData(base);
|
|
51
|
+
//debugData(base);
|
|
52
|
+
const reducerResult = reducer(base, source);
|
|
53
|
+
//debug(`reducerResult:`);
|
|
54
|
+
//debugData(reducerResult);
|
|
55
|
+
if (reducerResult.base !== undefined && reducerResult.source !== undefined) {
|
|
56
|
+
debug('NEW STYLE REDUCER RESULT v2');
|
|
57
|
+
const combo = reducerResult;
|
|
58
|
+
//debugData(combo);
|
|
59
|
+
return combo;
|
|
60
|
+
}
|
|
61
|
+
debug('OLD SCHOOL REDUCER RESULT v2');
|
|
62
|
+
//debugData({base: reducerResult, source});
|
|
63
|
+
return {
|
|
64
|
+
base: reducerResult,
|
|
65
|
+
source
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
};
|
|
24
69
|
exports.default = _default;
|
|
25
70
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["base","source","reducers","reduce","reducer"],"sources":["../src/index.js"],"sourcesContent":["import Reducers from './reducers';\n\nexport {Reducers};\
|
|
1
|
+
{"version":3,"file":"index.js","names":["_reducers","_interopRequireDefault","require","_debug","obj","__esModule","default","debug","createDebugLogger","debugData","extend","_default","base","source","reducers","combo","resultCombo","reduce","reducer","returnCombo","singleRound","JSON","stringify","length","reducerResult","undefined","exports"],"sources":["../src/index.js"],"sourcesContent":["import Reducers from './reducers';\nimport createDebugLogger from 'debug';\n\nconst debug = createDebugLogger('@natlibfi/melinda-marc-record-merge:index');\nconst debugData = debug.extend('data');\n\nexport {Reducers};\n// export default ({base, source, reducers}) => reducers.reduce((base, reducer) => reducer(base, source), base);\n\n// NV: Modified the reducer loop so, that not only base, but also is carried back.\n// However, we try to be backward-compatible: normally after the reducers, only base is returned.\n\nexport default ({base, source, reducers}) => {\n\n const combo = {base, source};\n const resultCombo = reducers.reduce((combo, reducer) => {\n const returnCombo = singleRound(reducer, combo.base, combo.source);\n //debugData(`returnCombo after current reducer: ${JSON.stringify(returnCombo)}`);\n return returnCombo;\n }, combo);\n\n debugData(`ResultCombo after reducers: ${JSON.stringify(resultCombo)}`);\n\n // Hack to make my melinda-marc-record-merge-reducers single tests that expect both\n // base and source to return them both:\n if (reducers.length === 1 && resultCombo.base && resultCombo.source) {\n debug('Single reducer, returning resultCombo');\n debugData(JSON.stringify(resultCombo));\n\n return resultCombo;\n }\n // All other tests return just base... Backward (compability) it is!\n debug('Multiple reducers, returning just base');\n debugData(JSON.stringify(resultCombo.base));\n return resultCombo.base;\n\n function singleRound(reducer, base, source) {\n //debug(`SINGLE ROUND INPUT (base, source)`);\n //debugData(base);\n //debugData(base);\n const reducerResult = reducer(base, source);\n //debug(`reducerResult:`);\n //debugData(reducerResult);\n if (reducerResult.base !== undefined && reducerResult.source !== undefined) {\n debug('NEW STYLE REDUCER RESULT v2');\n const combo = reducerResult;\n //debugData(combo);\n return combo;\n }\n debug('OLD SCHOOL REDUCER RESULT v2');\n //debugData({base: reducerResult, source});\n return {base: reducerResult, source};\n }\n};\n"],"mappings":";;;;;;;;;;;;AAAA,IAAAA,SAAA,GAAAC,sBAAA,CAAAC,OAAA;AACA,IAAAC,MAAA,GAAAF,sBAAA,CAAAC,OAAA;AAAsC,SAAAD,uBAAAG,GAAA,WAAAA,GAAA,IAAAA,GAAA,CAAAC,UAAA,GAAAD,GAAA,KAAAE,OAAA,EAAAF,GAAA;AAEtC,MAAMG,KAAK,GAAG,IAAAC,cAAiB,EAAC,2CAA2C,CAAC;AAC5E,MAAMC,SAAS,GAAGF,KAAK,CAACG,MAAM,CAAC,MAAM,CAAC;AAGtC;AAEA;AACA;AAAA,IAAAC,QAAA,GAEeA,CAAC;EAACC,IAAI;EAAEC,MAAM;EAAEC;AAAQ,CAAC,KAAK;EAE3C,MAAMC,KAAK,GAAG;IAACH,IAAI;IAAEC;EAAM,CAAC;EAC5B,MAAMG,WAAW,GAAGF,QAAQ,CAACG,MAAM,CAAC,CAACF,KAAK,EAAEG,OAAO,KAAK;IACtD,MAAMC,WAAW,GAAGC,WAAW,CAACF,OAAO,EAAEH,KAAK,CAACH,IAAI,EAAEG,KAAK,CAACF,MAAM,CAAC;IAClE;IACA,OAAOM,WAAW;EACpB,CAAC,EAAEJ,KAAK,CAAC;EAETN,SAAS,CAAE,+BAA8BY,IAAI,CAACC,SAAS,CAACN,WAAW,CAAE,EAAC,CAAC;;EAEvE;EACA;EACA,IAAIF,QAAQ,CAACS,MAAM,KAAK,CAAC,IAAIP,WAAW,CAACJ,IAAI,IAAII,WAAW,CAACH,MAAM,EAAE;IACnEN,KAAK,CAAC,uCAAuC,CAAC;IAC9CE,SAAS,CAACY,IAAI,CAACC,SAAS,CAACN,WAAW,CAAC,CAAC;IAEtC,OAAOA,WAAW;EACpB;EACA;EACAT,KAAK,CAAC,wCAAwC,CAAC;EAC/CE,SAAS,CAACY,IAAI,CAACC,SAAS,CAACN,WAAW,CAACJ,IAAI,CAAC,CAAC;EAC3C,OAAOI,WAAW,CAACJ,IAAI;EAEvB,SAASQ,WAAWA,CAACF,OAAO,EAAEN,IAAI,EAAEC,MAAM,EAAE;IAC1C;IACA;IACA;IACA,MAAMW,aAAa,GAAGN,OAAO,CAACN,IAAI,EAAEC,MAAM,CAAC;IAC3C;IACA;IACA,IAAIW,aAAa,CAACZ,IAAI,KAAKa,SAAS,IAAID,aAAa,CAACX,MAAM,KAAKY,SAAS,EAAE;MAC1ElB,KAAK,CAAC,6BAA6B,CAAC;MACpC,MAAMQ,KAAK,GAAGS,aAAa;MAC3B;MACA,OAAOT,KAAK;IACd;IACAR,KAAK,CAAC,8BAA8B,CAAC;IACrC;IACA,OAAO;MAACK,IAAI,EAAEY,aAAa;MAAEX;IAAM,CAAC;EACtC;AACF,CAAC;AAAAa,OAAA,CAAApB,OAAA,GAAAK,QAAA"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _index = _interopRequireWildcard(require("./index"));
|
|
4
|
+
var _util = require("util");
|
|
5
|
+
var _debug = _interopRequireDefault(require("debug"));
|
|
6
|
+
var _chai = require("chai");
|
|
7
|
+
var _marcRecord = require("@natlibfi/marc-record");
|
|
8
|
+
var _fixura = require("@natlibfi/fixura");
|
|
9
|
+
var _fixugen = _interopRequireDefault(require("@natlibfi/fixugen"));
|
|
10
|
+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
11
|
+
function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function (nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
|
|
12
|
+
function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
|
|
13
|
+
(0, _fixugen.default)({
|
|
14
|
+
callback,
|
|
15
|
+
path: [__dirname, '..', 'test-fixtures', 'index'],
|
|
16
|
+
recurse: false,
|
|
17
|
+
useMetadataFile: true,
|
|
18
|
+
fixura: {
|
|
19
|
+
failWhenNotFound: false,
|
|
20
|
+
reader: _fixura.READERS.JSON
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
function callback({
|
|
24
|
+
getFixture,
|
|
25
|
+
reducerConfigs = []
|
|
26
|
+
}) {
|
|
27
|
+
const base = new _marcRecord.MarcRecord(getFixture('base.json'), {
|
|
28
|
+
subfieldValues: false
|
|
29
|
+
});
|
|
30
|
+
const source = new _marcRecord.MarcRecord(getFixture('source.json'), {
|
|
31
|
+
subfieldValues: false
|
|
32
|
+
});
|
|
33
|
+
const expectedRecord = getFixture('merged.json');
|
|
34
|
+
const debug = (0, _debug.default)('@natlibfi/melinda-marc-record-merge-reducers:index:test');
|
|
35
|
+
const debugData = debug.extend('data');
|
|
36
|
+
const testReducerConfigs = reducerConfigs;
|
|
37
|
+
const reducers = [...testReducerConfigs.map(conf => _index.Reducers.copy(conf))];
|
|
38
|
+
debugData(`Reducers: ${(0, _util.inspect)(reducers, {
|
|
39
|
+
colors: true,
|
|
40
|
+
maxArrayLength: 10,
|
|
41
|
+
depth: 8
|
|
42
|
+
})})}`);
|
|
43
|
+
const result = (0, _index.default)({
|
|
44
|
+
base,
|
|
45
|
+
source,
|
|
46
|
+
reducers
|
|
47
|
+
});
|
|
48
|
+
debug(`Merge result is: ${result.constructor.name}`);
|
|
49
|
+
debugData(`${JSON.stringify(result)}`);
|
|
50
|
+
|
|
51
|
+
// Use either result.base or a plain result as resultRecord
|
|
52
|
+
// It can also be a MarcRecord or a plain object
|
|
53
|
+
const resultRecord = result.base || result;
|
|
54
|
+
const resultRecordToRecord = new _marcRecord.MarcRecord(resultRecord, {
|
|
55
|
+
subfieldValues: false
|
|
56
|
+
});
|
|
57
|
+
(0, _chai.expect)(resultRecordToRecord.toObject()).to.eql(expectedRecord);
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=index.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.spec.js","names":["_index","_interopRequireWildcard","require","_util","_debug","_interopRequireDefault","_chai","_marcRecord","_fixura","_fixugen","obj","__esModule","default","_getRequireWildcardCache","nodeInterop","WeakMap","cacheBabelInterop","cacheNodeInterop","cache","has","get","newObj","hasPropertyDescriptor","Object","defineProperty","getOwnPropertyDescriptor","key","prototype","hasOwnProperty","call","desc","set","generateTests","callback","path","__dirname","recurse","useMetadataFile","fixura","failWhenNotFound","reader","READERS","JSON","getFixture","reducerConfigs","base","MarcRecord","subfieldValues","source","expectedRecord","debug","createDebugLogger","debugData","extend","testReducerConfigs","reducers","map","conf","Reducers","copy","inspect","colors","maxArrayLength","depth","result","merger","constructor","name","stringify","resultRecord","resultRecordToRecord","expect","toObject","to","eql"],"sources":["../src/index.spec.js"],"sourcesContent":["import merger, {Reducers} from './index';\nimport {inspect} from 'util';\nimport createDebugLogger from 'debug';\nimport {expect} from 'chai';\nimport {MarcRecord} from '@natlibfi/marc-record';\nimport {READERS} from '@natlibfi/fixura';\nimport generateTests from '@natlibfi/fixugen';\n\ngenerateTests({\n callback,\n path: [__dirname, '..', 'test-fixtures', 'index'],\n recurse: false,\n useMetadataFile: true,\n fixura: {\n failWhenNotFound: false,\n reader: READERS.JSON\n }\n});\n\nfunction callback({getFixture, reducerConfigs = []}) {\n const base = new MarcRecord(getFixture('base.json'), {subfieldValues: false});\n const source = new MarcRecord(getFixture('source.json'), {subfieldValues: false});\n const expectedRecord = getFixture('merged.json');\n\n const debug = createDebugLogger('@natlibfi/melinda-marc-record-merge-reducers:index:test');\n const debugData = debug.extend('data');\n\n const testReducerConfigs = reducerConfigs;\n const reducers = [...testReducerConfigs.map(conf => Reducers.copy(conf))];\n\n debugData(`Reducers: ${inspect(reducers, {colors: true, maxArrayLength: 10, depth: 8})})}`);\n\n const result = merger({base, source, reducers});\n\n debug(`Merge result is: ${result.constructor.name}`);\n debugData(`${JSON.stringify(result)}`);\n\n // Use either result.base or a plain result as resultRecord\n // It can also be a MarcRecord or a plain object\n const resultRecord = result.base || result;\n const resultRecordToRecord = new MarcRecord(resultRecord, {subfieldValues: false});\n expect(resultRecordToRecord.toObject()).to.eql(expectedRecord);\n\n\n}\n"],"mappings":"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"}
|
package/dist/reducers/copy.js
CHANGED
|
@@ -4,20 +4,18 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _marcRecord = require("@natlibfi/marc-record");
|
|
9
|
-
|
|
10
8
|
var _debug = _interopRequireDefault(require("debug"));
|
|
11
|
-
|
|
12
9
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
13
|
-
|
|
14
10
|
/* eslint-disable max-statements */
|
|
15
|
-
|
|
16
11
|
/* eslint-disable no-unused-vars */
|
|
17
12
|
var _default = ({
|
|
18
13
|
tagPattern,
|
|
19
14
|
compareTagsOnly = false,
|
|
15
|
+
compareWithoutTag = false,
|
|
20
16
|
compareWithoutIndicators = false,
|
|
17
|
+
compareWithoutIndicator1 = false,
|
|
18
|
+
compareWithoutIndicator2 = false,
|
|
21
19
|
subfieldsMustBeIdentical = true,
|
|
22
20
|
excludeSubfields = [],
|
|
23
21
|
dropSubfields = [],
|
|
@@ -32,14 +30,40 @@ var _default = ({
|
|
|
32
30
|
swapSubfieldCode = [],
|
|
33
31
|
doNotCopyIfFieldPresent = false
|
|
34
32
|
}) => (base, source) => {
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const debug = (0, _debug.default)('@natlibfi/marc-record-merge');
|
|
33
|
+
const debug = (0, _debug.default)('@natlibfi/marc-record-merge:copy');
|
|
34
|
+
const debugData = debug.extend('data');
|
|
38
35
|
const debugOptions = (0, _debug.default)('@natlibfi/marc-record-merge:compare-options');
|
|
39
36
|
const debugCompare = (0, _debug.default)('@natlibfi/marc-record-merge:compare');
|
|
37
|
+
debugData(`base: ${JSON.stringify(base)}`);
|
|
38
|
+
debugData(`source: ${JSON.stringify(source)}`);
|
|
39
|
+
const {
|
|
40
|
+
baseRecord,
|
|
41
|
+
sourceRecord
|
|
42
|
+
} = getRecordsFromParameters(base, source, baseValidators, sourceValidators);
|
|
43
|
+
function getRecordsFromParameters(base, source, baseValidators, sourceValidators) {
|
|
44
|
+
// records if we got an object ({base, source}) as a parameter
|
|
45
|
+
if (source === undefined && base.base !== undefined && base.source !== undefined) {
|
|
46
|
+
const baseRecord = new _marcRecord.MarcRecord(base.base, baseValidators);
|
|
47
|
+
const sourceRecord = new _marcRecord.MarcRecord(base.source, sourceValidators);
|
|
48
|
+
return {
|
|
49
|
+
baseRecord,
|
|
50
|
+
sourceRecord
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
// records if we got an non-object (base, source) as a parameter
|
|
54
|
+
const baseRecord = new _marcRecord.MarcRecord(base, baseValidators);
|
|
55
|
+
const sourceRecord = new _marcRecord.MarcRecord(source, sourceValidators);
|
|
56
|
+
return {
|
|
57
|
+
baseRecord,
|
|
58
|
+
sourceRecord
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
const ignoreInd1 = compareWithoutIndicators || compareWithoutIndicator1;
|
|
62
|
+
const ignoreInd2 = compareWithoutIndicators || compareWithoutIndicator2;
|
|
40
63
|
debugOptions(`Tag Pattern: ${tagPattern}`);
|
|
41
64
|
debugOptions(`Compare tags only: ${compareTagsOnly}`);
|
|
42
|
-
debugOptions(`
|
|
65
|
+
debugOptions(`Omit indicator 1 from comparison: ${ignoreInd1}`);
|
|
66
|
+
debugOptions(`Omit indicator 2 from comparison: ${ignoreInd2}`);
|
|
43
67
|
debugOptions(`Copy if identical: ${subfieldsMustBeIdentical}`);
|
|
44
68
|
debugOptions(`Exclude subfields: [${excludeSubfields}]`);
|
|
45
69
|
debugOptions(`Drop subfields [${dropSubfields}]`);
|
|
@@ -47,128 +71,117 @@ var _default = ({
|
|
|
47
71
|
const baseFields = baseRecord.get(tagPattern);
|
|
48
72
|
const sourceFields = sourceRecord.get(tagPattern);
|
|
49
73
|
const doNotCopy = doNotCopyIfFieldPresent ? baseRecord.get(doNotCopyIfFieldPresent).length > 0 : false;
|
|
50
|
-
|
|
51
74
|
if (doNotCopy) {
|
|
52
75
|
return baseRecord.toObject();
|
|
53
76
|
}
|
|
54
|
-
|
|
77
|
+
debug(`FFS: ${compareWithoutIndicator1}, ${compareWithoutIndicators}, ${ignoreInd1}`);
|
|
55
78
|
debug(`Base fields: `, baseFields);
|
|
56
79
|
debug(`Source fields: `, sourceFields);
|
|
80
|
+
|
|
81
|
+
// Logic steps
|
|
57
82
|
const baseCompareFields = baseFields.map(baseField => createCompareField(baseField));
|
|
58
83
|
const compareResultFields = compareFields(sourceFields, baseCompareFields);
|
|
59
84
|
const droppedUnwantedSubfield = checkDropSubfields(compareResultFields);
|
|
60
85
|
const droppedUnwantedFields = checkCopyUnlessFields(droppedUnwantedSubfield);
|
|
61
86
|
const swappedSubfields = checkSwapSubfieldCodes(droppedUnwantedFields);
|
|
62
87
|
const swappedTags = checkSwapTag(swappedSubfields);
|
|
88
|
+
const uniqueFields = [...new Set(swappedTags.map(field => JSON.stringify(field)))].map(field => JSON.parse(field));
|
|
63
89
|
debug('Fields to be copied');
|
|
64
|
-
debug(JSON.stringify(
|
|
65
|
-
|
|
66
|
-
swappedTags.forEach(field => baseRecord.insertField(field));
|
|
67
|
-
return baseRecord.toObject(); //return copyFields(baseFields, sourceFields);
|
|
90
|
+
debug(JSON.stringify(uniqueFields));
|
|
68
91
|
|
|
92
|
+
// Add fields to base;
|
|
93
|
+
uniqueFields.forEach(field => baseRecord.insertField(field));
|
|
94
|
+
debugData(`baseRecord before return: ${JSON.stringify(baseRecord)}`);
|
|
95
|
+
//return baseRecord;
|
|
96
|
+
return baseRecord.toObject();
|
|
69
97
|
function compareFields(sourceFields, baseCompareFields, uniqFields = []) {
|
|
70
98
|
const [sourceField, ...rest] = sourceFields;
|
|
71
|
-
|
|
72
99
|
if (sourceField === undefined) {
|
|
73
100
|
return uniqFields;
|
|
74
101
|
}
|
|
75
|
-
|
|
76
102
|
if (baseCompareFields.length === 0) {
|
|
77
103
|
return compareFields(rest, baseCompareFields, [...uniqFields, sourceField]);
|
|
78
|
-
}
|
|
79
|
-
// Non-identical fields are copied from source to base as duplicates
|
|
80
|
-
|
|
104
|
+
}
|
|
81
105
|
|
|
106
|
+
// Source and base are also compared for identicalness
|
|
107
|
+
// Non-identical fields are copied from source to base as duplicates
|
|
82
108
|
const sourceCompareField = createCompareField(sourceField);
|
|
83
109
|
const unique = checkCompareFields(baseCompareFields, sourceCompareField);
|
|
84
110
|
debugCompare(`${JSON.stringify(sourceField)} ${unique ? 'is UNIQUE' : 'not UNIQUE'}`);
|
|
85
|
-
|
|
86
111
|
if (unique) {
|
|
87
112
|
return compareFields(rest, baseCompareFields, [...uniqFields, sourceField]);
|
|
88
113
|
}
|
|
89
|
-
|
|
90
114
|
return compareFields(rest, baseCompareFields, uniqFields);
|
|
91
|
-
|
|
92
115
|
function checkCompareFields(baseCompareFields, sourceCompareField) {
|
|
93
116
|
let unique = true; // eslint-disable-line functional/no-let
|
|
94
117
|
|
|
95
118
|
baseCompareFields.forEach(baseCompareField => {
|
|
96
119
|
debugCompare(`Comparing ${JSON.stringify(sourceCompareField)} to ${JSON.stringify(baseCompareField)}}`);
|
|
97
|
-
|
|
98
120
|
if (sourceCompareField.value !== baseCompareField.value) {
|
|
99
121
|
debugCompare(`Value is different ${sourceCompareField.value} !== ${baseCompareField.value}`);
|
|
100
122
|
return;
|
|
101
123
|
}
|
|
102
|
-
|
|
103
124
|
if (sourceCompareField.ind1 !== baseCompareField.ind1) {
|
|
104
125
|
debugCompare(`Ind1 is different ${sourceCompareField.ind1} !== ${baseCompareField.ind1}`);
|
|
105
126
|
return;
|
|
106
127
|
}
|
|
107
|
-
|
|
108
128
|
if (sourceCompareField.ind2 !== baseCompareField.ind2) {
|
|
109
129
|
debugCompare(`Ind2 is different ${sourceCompareField.ind2} !== ${baseCompareField.ind2}`);
|
|
110
130
|
return;
|
|
111
131
|
}
|
|
112
|
-
|
|
113
132
|
if ('subfields' in sourceCompareField) {
|
|
114
133
|
const allFound = checkSubfields(sourceCompareField.subfields, baseCompareField.subfields);
|
|
115
134
|
debugCompare(`Subfields are different ${!allFound}`);
|
|
116
|
-
|
|
117
135
|
if (!allFound) {
|
|
118
136
|
return;
|
|
119
137
|
}
|
|
120
|
-
|
|
121
138
|
unique = false;
|
|
122
139
|
return;
|
|
123
140
|
}
|
|
124
|
-
|
|
125
141
|
unique = false;
|
|
126
142
|
return;
|
|
127
143
|
});
|
|
128
144
|
return unique;
|
|
129
145
|
}
|
|
130
|
-
|
|
131
146
|
function checkSubfields(sourceSubfields, baseSubfields) {
|
|
132
147
|
const foundSubs = sourceSubfields.filter(sSub => baseSubfields.some(bSub => sSub.code === bSub.code && sSub.value === bSub.value));
|
|
133
|
-
|
|
134
148
|
if (subfieldsMustBeIdentical) {
|
|
135
149
|
return foundSubs.length === sourceSubfields.length && foundSubs.length === baseSubfields.length;
|
|
136
150
|
}
|
|
137
|
-
|
|
138
151
|
return foundSubs.length === sourceSubfields.length;
|
|
139
152
|
}
|
|
140
153
|
}
|
|
141
154
|
|
|
155
|
+
// compare objects have only fields that matter in comparison
|
|
142
156
|
function createCompareField(field) {
|
|
143
157
|
if (compareTagsOnly) {
|
|
144
158
|
return {
|
|
145
159
|
tag: field.tag
|
|
146
160
|
};
|
|
147
161
|
}
|
|
148
|
-
|
|
149
162
|
if ('value' in field) {
|
|
150
163
|
return {
|
|
151
164
|
tag: field.tag,
|
|
152
165
|
value: field.value
|
|
153
166
|
};
|
|
154
167
|
}
|
|
155
|
-
|
|
156
168
|
const [filteredField] = checkDropSubfields([field]);
|
|
169
|
+
const [foundRule] = swapTag.filter(rule => new RegExp(rule.from, 'u').test(field.tag));
|
|
170
|
+
const replacementTag = foundRule ? foundRule.to : undefined;
|
|
157
171
|
const params = [{
|
|
158
172
|
name: 'tag',
|
|
159
|
-
value: field.tag
|
|
173
|
+
value: compareWithoutTag ? replacementTag : field.tag
|
|
160
174
|
}, {
|
|
161
175
|
name: 'ind1',
|
|
162
|
-
value:
|
|
176
|
+
value: ignoreInd1 ? undefined : field.ind1
|
|
163
177
|
}, {
|
|
164
178
|
name: 'ind2',
|
|
165
|
-
value:
|
|
179
|
+
value: ignoreInd2 ? undefined : field.ind2
|
|
166
180
|
}, {
|
|
167
181
|
name: 'subfields',
|
|
168
182
|
value: createCompareSubfields(filteredField.subfields)
|
|
169
183
|
}].map(param => [param.name, param.value]);
|
|
170
184
|
return Object.fromEntries(params);
|
|
171
|
-
|
|
172
185
|
function createCompareSubfields(subfields) {
|
|
173
186
|
const nonExcludedSubfields = subfields.filter(sub => !excludeSubfields.some(code => code === sub.code));
|
|
174
187
|
const normalizedSubfields = nonExcludedSubfields.map(sub => ({
|
|
@@ -176,50 +189,41 @@ var _default = ({
|
|
|
176
189
|
value: normalizeSubfieldValue(sub.value)
|
|
177
190
|
}));
|
|
178
191
|
return normalizedSubfields;
|
|
179
|
-
|
|
180
192
|
function normalizeSubfieldValue(value) {
|
|
181
193
|
return value.toLowerCase().replace(/\s+/ug, '');
|
|
182
194
|
}
|
|
183
195
|
}
|
|
184
196
|
}
|
|
185
|
-
|
|
186
197
|
function checkSwapTag(fields) {
|
|
187
198
|
if (swapTag.length > 0) {
|
|
188
|
-
return fields.map(field => ({
|
|
199
|
+
return fields.map(field => ({
|
|
200
|
+
...field,
|
|
189
201
|
tag: swapTagsFunc(field.tag)
|
|
190
202
|
}));
|
|
191
203
|
}
|
|
192
|
-
|
|
193
204
|
return fields;
|
|
194
|
-
|
|
195
205
|
function swapTagsFunc(tag) {
|
|
196
206
|
const [foundRule] = swapTag.filter(rule => new RegExp(rule.from, 'u').test(tag));
|
|
197
|
-
|
|
198
207
|
if (foundRule === undefined) {
|
|
199
208
|
return tag;
|
|
200
209
|
}
|
|
201
|
-
|
|
202
210
|
return foundRule.to;
|
|
203
211
|
}
|
|
204
212
|
}
|
|
205
|
-
|
|
206
213
|
function checkSwapSubfieldCodes(fields) {
|
|
207
214
|
if (swapSubfieldCode.length > 0) {
|
|
208
|
-
return fields.map(field => ({
|
|
215
|
+
return fields.map(field => ({
|
|
216
|
+
...field,
|
|
209
217
|
subfields: swapSubfieldCodesFunc(field.subfields)
|
|
210
218
|
}));
|
|
211
219
|
}
|
|
212
|
-
|
|
213
220
|
return fields;
|
|
214
|
-
|
|
215
221
|
function swapSubfieldCodesFunc(subfields) {
|
|
216
222
|
return subfields.map(sub => {
|
|
217
223
|
const [foundRule] = swapSubfieldCode.filter(rule => rule.from === sub.code);
|
|
218
|
-
|
|
219
224
|
if (foundRule === undefined) {
|
|
220
225
|
return sub;
|
|
221
226
|
}
|
|
222
|
-
|
|
223
227
|
return {
|
|
224
228
|
code: foundRule.to,
|
|
225
229
|
value: sub.value
|
|
@@ -227,16 +231,14 @@ var _default = ({
|
|
|
227
231
|
});
|
|
228
232
|
}
|
|
229
233
|
}
|
|
230
|
-
|
|
231
234
|
function checkDropSubfields(fields) {
|
|
232
235
|
if (dropSubfields.length > 0) {
|
|
233
|
-
return fields.map(field => ({
|
|
236
|
+
return fields.map(field => ({
|
|
237
|
+
...field,
|
|
234
238
|
subfields: dropSubfieldsFunc(field.subfields)
|
|
235
239
|
})).filter(field => field.subfields.length > 0);
|
|
236
240
|
}
|
|
237
|
-
|
|
238
241
|
return fields;
|
|
239
|
-
|
|
240
242
|
function dropSubfieldsFunc(subfields) {
|
|
241
243
|
return subfields.filter(sub => {
|
|
242
244
|
// eslint-disable-line
|
|
@@ -248,116 +250,25 @@ var _default = ({
|
|
|
248
250
|
if (code !== sub.code) {
|
|
249
251
|
return false;
|
|
250
252
|
}
|
|
251
|
-
|
|
252
253
|
if (!condition && value) {
|
|
253
254
|
return value === sub.value;
|
|
254
255
|
}
|
|
255
|
-
|
|
256
256
|
if (condition === 'unless' && value) {
|
|
257
257
|
return !new RegExp(value, 'u').test(sub.value);
|
|
258
258
|
}
|
|
259
|
-
|
|
260
259
|
return true;
|
|
261
260
|
});
|
|
262
261
|
});
|
|
263
262
|
}
|
|
264
263
|
}
|
|
265
|
-
|
|
266
264
|
function checkCopyUnlessFields(fields) {
|
|
267
265
|
if (copyUnless.length > 0) {
|
|
268
266
|
return fields.filter(({
|
|
269
267
|
subfields
|
|
270
268
|
}) => copyUnless.some(filter => !subfields.some(sub => sub.code === filter.code && new RegExp(filter.value, 'u').test(sub.value))));
|
|
271
269
|
}
|
|
272
|
-
|
|
273
270
|
return fields;
|
|
274
271
|
}
|
|
275
|
-
};
|
|
276
|
-
// const sourceTags = sourceFields.map(field => field.tag);
|
|
277
|
-
// sourceTags.forEach(tag => debug(`Comparing field ${tag}`));
|
|
278
|
-
// /*
|
|
279
|
-
// if (combine.length > 0) {
|
|
280
|
-
// debug(`*** NOW Copy options: ${tagPattern}, ${compareTagsOnly}, ${compareWithoutIndicators}, ${subfieldsMustBeIdentical}, [${combine}], [${excludeSubfields}], [${dropSubfields}]`);
|
|
281
|
-
// combine.forEach(row => debug(` ### combine ${row} <- `));
|
|
282
|
-
// return [];
|
|
283
|
-
// }
|
|
284
|
-
// */
|
|
285
|
-
// // If compareTagsOnly = true, only this part is run
|
|
286
|
-
// // The field is copied from source only if it is missing completely from base
|
|
287
|
-
// if (compareTagsOnly && baseFields.length === 0) {
|
|
288
|
-
// sourceTags.forEach(tag => debug(`Missing field ${tag} copied from source to base`));
|
|
289
|
-
// sourceFields.forEach(f => base.insertField(f));
|
|
290
|
-
// return true;
|
|
291
|
-
// }
|
|
292
|
-
// // If compareTagsOnly = false (default)
|
|
293
|
-
// // Source and base are also compared for identicalness
|
|
294
|
-
// // Non-identical fields are copied from source to base as duplicates
|
|
295
|
-
// if (!compareTagsOnly) {
|
|
296
|
-
// const filterMissing = function (sourceField) {
|
|
297
|
-
// if ('value' in sourceField) {
|
|
298
|
-
// debug(`Checking control field ${sourceField.tag} for identicalness`);
|
|
299
|
-
// return baseFields.some(isIdenticalControlField) === false;
|
|
300
|
-
// }
|
|
301
|
-
// if ('subfields' in sourceField) {
|
|
302
|
-
// debug(`Checking data field ${sourceField.tag} for identicalness`);
|
|
303
|
-
// return baseFields.some(isIdenticalDataField) === false;
|
|
304
|
-
// }
|
|
305
|
-
// function normalizeControlField(field) {
|
|
306
|
-
// return field.value.toLowerCase().replace(/\s+/u, '');
|
|
307
|
-
// }
|
|
308
|
-
// function isIdenticalControlField(baseField) {
|
|
309
|
-
// const normalizedBaseField = normalizeControlField(baseField);
|
|
310
|
-
// const normalizedSourceField = normalizeControlField(sourceField);
|
|
311
|
-
// return normalizedSourceField === normalizedBaseField;
|
|
312
|
-
// }
|
|
313
|
-
// function isIdenticalDataField(baseField) {
|
|
314
|
-
// // If excluded subfields have been defined for this field, they must be ignored first
|
|
315
|
-
// // (i.e. source and base fields are considered identical if all non-excluded subfields are identical)
|
|
316
|
-
// if (excludeSubfields.length > 0 &&
|
|
317
|
-
// sourceField.tag === baseField.tag &&
|
|
318
|
-
// sourceField.ind1 === baseField.ind1 &&
|
|
319
|
-
// sourceField.ind2 === baseField.ind2) {
|
|
320
|
-
// excludeSubfields.forEach(sub => debug(`Subfield ${sub} excluded from identicalness comparison`));
|
|
321
|
-
// // Compare only those subfields that are not excluded
|
|
322
|
-
// const baseSubsToCompare = baseField.subfields.filter(subfield => excludeSubfields.indexOf(subfield.code) === -1);
|
|
323
|
-
// return baseSubsToCompare.every(isIdenticalSubfield);
|
|
324
|
-
// }
|
|
325
|
-
// // If there are no excluded subfields (default case)
|
|
326
|
-
// if (sourceField.tag === baseField.tag &&
|
|
327
|
-
// sourceField.ind1 === baseField.ind1 &&
|
|
328
|
-
// sourceField.ind2 === baseField.ind2 &&
|
|
329
|
-
// sourceField.subfields.length === baseField.subfields.length) {
|
|
330
|
-
// return baseField.subfields.every(isIdenticalSubfield);
|
|
331
|
-
// }
|
|
332
|
-
// function normalizeSubfield(subfield) {
|
|
333
|
-
// return subfield.value.toLowerCase().replace(/\s+/u, '');
|
|
334
|
-
// }
|
|
335
|
-
// function isIdenticalSubfield(baseSub) {
|
|
336
|
-
// const normBaseSub = normalizeSubfield(baseSub);
|
|
337
|
-
// return sourceField.subfields.some(sourceSub => {
|
|
338
|
-
// const normSourceSub = normalizeSubfield(sourceSub);
|
|
339
|
-
// return normSourceSub === normBaseSub;
|
|
340
|
-
// });
|
|
341
|
-
// }
|
|
342
|
-
// }
|
|
343
|
-
// };
|
|
344
|
-
// // Search for fields missing from base
|
|
345
|
-
// const missingFields = sourceFields.filter(filterMissing);
|
|
346
|
-
// missingFields.forEach(f => base.insertField(f));
|
|
347
|
-
// if (missingFields.length > 0) {
|
|
348
|
-
// const missingTags = missingFields.map(field => field.tag);
|
|
349
|
-
// missingTags.forEach(tag => debug(`Field ${tag} copied from source to base`));
|
|
350
|
-
// return base;
|
|
351
|
-
// }
|
|
352
|
-
// if (missingFields.length === 0) {
|
|
353
|
-
// debug(`No missing fields found`);
|
|
354
|
-
// return base;
|
|
355
|
-
// }
|
|
356
|
-
// }
|
|
357
|
-
// debug(`No missing fields found`);
|
|
358
|
-
// return base;
|
|
359
|
-
// }
|
|
360
|
-
|
|
361
|
-
|
|
272
|
+
};
|
|
362
273
|
exports.default = _default;
|
|
363
274
|
//# sourceMappingURL=copy.js.map
|