@larsgw/formica 0.8.4 → 0.8.6
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/workflows/ci.yml +1 -1
- package/CHANGELOG.md +34 -0
- package/lib/bin/generate-linked-data.js +209 -328
- package/lib/bin/process-resources-index.js +59 -130
- package/lib/bin/process-resources.js +303 -524
- package/lib/bin/util.js +21 -56
- package/lib/bin/validate-catalog.js +26 -70
- package/lib/bin/validate-resources-text.js +17 -61
- package/lib/catalog/entities.js +28 -84
- package/lib/catalog/entity.js +36 -50
- package/lib/catalog/index.js +11 -12
- package/lib/catalog/tables/author.js +7 -24
- package/lib/catalog/tables/index.js +5 -5
- package/lib/catalog/tables/place.js +7 -24
- package/lib/catalog/tables/publisher.js +7 -24
- package/lib/catalog/tables/taxon.js +7 -24
- package/lib/catalog/tables/work.js +13 -30
- package/lib/catalog/value.js +11 -11
- package/lib/csv.js +7 -8
- package/lib/resources/diff-resource.js +52 -55
- package/lib/resources/parse-name.d.ts +6 -0
- package/lib/resources/parse-name.js +354 -0
- package/lib/resources/parse-text.js +185 -475
- package/lib/resources/resource.js +7 -25
- package/lib/taxon-names/index.js +15 -20
- package/package.json +2 -1
- package/src/bin/generate-linked-data.ts +8 -5
- package/src/bin/process-resources.ts +1 -1
- package/src/bin/validate-resources-text.ts +1 -1
- package/src/module.d.ts +4 -2
- package/src/resources/diff-resource.ts +19 -15
- package/src/resources/parse-name.ts +379 -0
- package/src/resources/parse-text.ts +150 -440
- package/test/resources.js +161 -17
- package/tsconfig.json +4 -1
package/lib/bin/util.js
CHANGED
|
@@ -41,49 +41,22 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
41
41
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
42
42
|
});
|
|
43
43
|
};
|
|
44
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
45
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
46
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
47
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
48
|
-
function step(op) {
|
|
49
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
50
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
51
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
52
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
53
|
-
switch (op[0]) {
|
|
54
|
-
case 0: case 1: t = op; break;
|
|
55
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
56
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
57
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
58
|
-
default:
|
|
59
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
60
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
61
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
62
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
63
|
-
if (t[2]) _.ops.pop();
|
|
64
|
-
_.trys.pop(); continue;
|
|
65
|
-
}
|
|
66
|
-
op = body.call(thisArg, _);
|
|
67
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
68
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
44
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
72
45
|
exports.numericSort = numericSort;
|
|
73
46
|
exports.prompt = prompt;
|
|
74
47
|
exports.promptForAnswers = promptForAnswers;
|
|
75
48
|
exports.runCommand = runCommand;
|
|
76
|
-
|
|
77
|
-
|
|
49
|
+
const readline = __importStar(require("readline"));
|
|
50
|
+
const child_process_1 = require("child_process");
|
|
78
51
|
/**
|
|
79
52
|
* Comparison function to sort strings with numerical components.
|
|
80
53
|
*/
|
|
81
54
|
function numericSort(a, b) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
for (
|
|
85
|
-
|
|
86
|
-
|
|
55
|
+
const as = a.split(/(\d+)/);
|
|
56
|
+
const bs = b.split(/(\d+)/);
|
|
57
|
+
for (let i = 0; i < Math.max(as.length, bs.length); i++) {
|
|
58
|
+
const ai = as[i];
|
|
59
|
+
const bi = bs[i];
|
|
87
60
|
if (ai === bi) {
|
|
88
61
|
continue;
|
|
89
62
|
}
|
|
@@ -106,12 +79,12 @@ function numericSort(a, b) {
|
|
|
106
79
|
* Create a CLI prompt and return any answer.
|
|
107
80
|
*/
|
|
108
81
|
function prompt(question) {
|
|
109
|
-
|
|
82
|
+
const rl = readline.createInterface({
|
|
110
83
|
input: process.stdin,
|
|
111
84
|
output: process.stdout
|
|
112
85
|
});
|
|
113
|
-
return new Promise(
|
|
114
|
-
rl.question(question,
|
|
86
|
+
return new Promise(resolve => {
|
|
87
|
+
rl.question(question, (answer) => {
|
|
115
88
|
rl.close();
|
|
116
89
|
resolve(answer);
|
|
117
90
|
});
|
|
@@ -121,31 +94,23 @@ function prompt(question) {
|
|
|
121
94
|
* Create a CLI prompt and only accept certain answers.
|
|
122
95
|
*/
|
|
123
96
|
function promptForAnswers(question, answers) {
|
|
124
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
answer = (_a.sent())[0];
|
|
131
|
-
_a.label = 2;
|
|
132
|
-
case 2:
|
|
133
|
-
if (!answers.includes(answer)) return [3 /*break*/, 0];
|
|
134
|
-
_a.label = 3;
|
|
135
|
-
case 3: return [2 /*return*/, answer];
|
|
136
|
-
}
|
|
137
|
-
});
|
|
97
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98
|
+
let answer;
|
|
99
|
+
do {
|
|
100
|
+
answer = (yield prompt(question))[0];
|
|
101
|
+
} while (!answers.includes(answer));
|
|
102
|
+
return answer;
|
|
138
103
|
});
|
|
139
104
|
}
|
|
140
105
|
/**
|
|
141
106
|
* Run a command and return stdout.
|
|
142
107
|
*/
|
|
143
108
|
function runCommand(command, args, options) {
|
|
144
|
-
return new Promise(
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
proc.stdout.on('data',
|
|
148
|
-
proc.on('close',
|
|
109
|
+
return new Promise((resolve, reject) => {
|
|
110
|
+
const proc = (0, child_process_1.spawn)(command, args, options);
|
|
111
|
+
let stdout = '';
|
|
112
|
+
proc.stdout.on('data', data => { stdout += data; });
|
|
113
|
+
proc.on('close', code => {
|
|
149
114
|
if (code === 0) {
|
|
150
115
|
resolve(stdout);
|
|
151
116
|
}
|
|
@@ -42,82 +42,38 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
42
42
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
46
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
47
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
48
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
49
|
-
function step(op) {
|
|
50
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
51
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
52
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
53
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
54
|
-
switch (op[0]) {
|
|
55
|
-
case 0: case 1: t = op; break;
|
|
56
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
57
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
58
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
59
|
-
default:
|
|
60
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
61
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
62
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
63
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
64
|
-
if (t[2]) _.ops.pop();
|
|
65
|
-
_.trys.pop(); continue;
|
|
66
|
-
}
|
|
67
|
-
op = body.call(thisArg, _);
|
|
68
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
69
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
46
|
+
const fs_1 = require("fs");
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const index_1 = require("../index");
|
|
76
49
|
function validateFile(arg) {
|
|
77
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
filePath = path.resolve(arg);
|
|
83
|
-
return [4 /*yield*/, fs_1.promises.readFile(filePath, 'utf8')];
|
|
84
|
-
case 1:
|
|
85
|
-
file = _a.sent();
|
|
86
|
-
sheet = path.basename(filePath, '.csv');
|
|
87
|
-
return [2 /*return*/, index_1.catalog.loadData(file, sheet).validate()];
|
|
88
|
-
}
|
|
89
|
-
});
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
const filePath = path.resolve(arg);
|
|
52
|
+
const file = yield fs_1.promises.readFile(filePath, 'utf8');
|
|
53
|
+
const sheet = path.basename(filePath, '.csv');
|
|
54
|
+
return index_1.catalog.loadData(file, sheet).validate();
|
|
90
55
|
});
|
|
91
56
|
}
|
|
92
57
|
function main(args) {
|
|
93
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
}
|
|
110
|
-
else if (result.value.length > 0) {
|
|
111
|
-
console.error("".concat(args[i], ":"));
|
|
112
|
-
console.table(result.value);
|
|
113
|
-
console.error();
|
|
114
|
-
exitStatus = 1;
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
process.exit(exitStatus);
|
|
118
|
-
return [2 /*return*/];
|
|
58
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
59
|
+
let exitStatus = 0;
|
|
60
|
+
const results = yield Promise.allSettled(args.map(validateFile));
|
|
61
|
+
for (let i = 0; i < results.length; i++) {
|
|
62
|
+
const result = results[i];
|
|
63
|
+
if (result.status === 'rejected') {
|
|
64
|
+
console.error(`${args[i]}:`);
|
|
65
|
+
console.error(result.reason);
|
|
66
|
+
console.error();
|
|
67
|
+
exitStatus = 1;
|
|
68
|
+
}
|
|
69
|
+
else if (result.value.length > 0) {
|
|
70
|
+
console.error(`${args[i]}:`);
|
|
71
|
+
console.table(result.value);
|
|
72
|
+
console.error();
|
|
73
|
+
exitStatus = 1;
|
|
119
74
|
}
|
|
120
|
-
}
|
|
75
|
+
}
|
|
76
|
+
process.exit(exitStatus);
|
|
121
77
|
});
|
|
122
78
|
}
|
|
123
79
|
main(process.argv.slice(2));
|
|
@@ -42,70 +42,26 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
42
42
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
46
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
47
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
48
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
49
|
-
function step(op) {
|
|
50
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
51
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
52
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
53
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
54
|
-
switch (op[0]) {
|
|
55
|
-
case 0: case 1: t = op; break;
|
|
56
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
57
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
58
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
59
|
-
default:
|
|
60
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
61
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
62
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
63
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
64
|
-
if (t[2]) _.ops.pop();
|
|
65
|
-
_.trys.pop(); continue;
|
|
66
|
-
}
|
|
67
|
-
op = body.call(thisArg, _);
|
|
68
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
69
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
46
|
+
const fs_1 = require("fs");
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const index_1 = require("../index");
|
|
76
49
|
function main(args) {
|
|
77
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
return [4 /*yield*/, fs_1.promises.readFile(filePath, 'utf8')];
|
|
90
|
-
case 2:
|
|
91
|
-
file = _a.sent();
|
|
92
|
-
id = path.basename(filePath, '.txt');
|
|
93
|
-
try {
|
|
94
|
-
index_1.resources.parseTextFile(file, id);
|
|
95
|
-
}
|
|
96
|
-
catch (error) {
|
|
97
|
-
console.error(filePath + '\n ' + error.message + '\n');
|
|
98
|
-
exitStatus = 1;
|
|
99
|
-
}
|
|
100
|
-
_a.label = 3;
|
|
101
|
-
case 3:
|
|
102
|
-
_i++;
|
|
103
|
-
return [3 /*break*/, 1];
|
|
104
|
-
case 4:
|
|
105
|
-
process.exit(exitStatus);
|
|
106
|
-
return [2 /*return*/];
|
|
50
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
51
|
+
let exitStatus = 0;
|
|
52
|
+
for (const arg of args) {
|
|
53
|
+
const filePath = path.resolve(arg);
|
|
54
|
+
const file = yield fs_1.promises.readFile(filePath, 'utf8');
|
|
55
|
+
const id = path.basename(filePath, '.txt');
|
|
56
|
+
try {
|
|
57
|
+
index_1.resources.parseTextFile(file, id);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.error(filePath + '\n' + error.message.replace(/^/gm, ' ') + '\n');
|
|
61
|
+
exitStatus = 1;
|
|
107
62
|
}
|
|
108
|
-
}
|
|
63
|
+
}
|
|
64
|
+
process.exit(exitStatus);
|
|
109
65
|
});
|
|
110
66
|
}
|
|
111
67
|
main(process.argv.slice(2));
|
package/lib/catalog/entities.js
CHANGED
|
@@ -1,111 +1,55 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
3
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
4
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
5
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
6
|
-
function step(op) {
|
|
7
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
8
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
9
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
10
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
11
|
-
switch (op[0]) {
|
|
12
|
-
case 0: case 1: t = op; break;
|
|
13
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
14
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
15
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
16
|
-
default:
|
|
17
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
18
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
19
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
20
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
21
|
-
if (t[2]) _.ops.pop();
|
|
22
|
-
_.trys.pop(); continue;
|
|
23
|
-
}
|
|
24
|
-
op = body.call(thisArg, _);
|
|
25
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
26
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
27
|
-
}
|
|
28
|
-
};
|
|
29
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
30
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
31
|
-
if (ar || !(i in from)) {
|
|
32
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
33
|
-
ar[i] = from[i];
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
37
|
-
};
|
|
38
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
3
|
exports.Entities = void 0;
|
|
40
|
-
|
|
41
|
-
|
|
4
|
+
class Entities {
|
|
5
|
+
constructor(entities, indexField) {
|
|
42
6
|
this.entities = entities;
|
|
43
7
|
this.indexField = indexField;
|
|
44
8
|
this.index = {};
|
|
45
|
-
for (
|
|
46
|
-
|
|
47
|
-
var key = entity.get(indexField);
|
|
9
|
+
for (const entity of this.entities) {
|
|
10
|
+
const key = entity.get(indexField);
|
|
48
11
|
if (typeof key !== 'string') {
|
|
49
12
|
throw new TypeError('Entity missing index field');
|
|
50
13
|
}
|
|
51
14
|
this.index[key] = entity;
|
|
52
15
|
}
|
|
53
16
|
}
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
_b.label = 1;
|
|
61
|
-
case 1:
|
|
62
|
-
if (!(_i < _a.length)) return [3 /*break*/, 4];
|
|
63
|
-
entity = _a[_i];
|
|
64
|
-
return [4 /*yield*/, entity];
|
|
65
|
-
case 2:
|
|
66
|
-
_b.sent();
|
|
67
|
-
_b.label = 3;
|
|
68
|
-
case 3:
|
|
69
|
-
_i++;
|
|
70
|
-
return [3 /*break*/, 1];
|
|
71
|
-
case 4: return [2 /*return*/];
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
};
|
|
75
|
-
Entities.prototype.get = function (key) {
|
|
17
|
+
*[Symbol.iterator]() {
|
|
18
|
+
for (const entity of this.entities) {
|
|
19
|
+
yield entity;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
get(key) {
|
|
76
23
|
return this.index[key];
|
|
77
|
-
}
|
|
78
|
-
|
|
24
|
+
}
|
|
25
|
+
has(key) {
|
|
79
26
|
return key in this.index;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
for (
|
|
84
|
-
|
|
85
|
-
for (var _b = 0, _c = entity.validate(); _b < _c.length; _b++) {
|
|
86
|
-
var _d = _c[_b], field = _d.field, error = _d.error;
|
|
27
|
+
}
|
|
28
|
+
validate() {
|
|
29
|
+
const errors = [];
|
|
30
|
+
for (const entity of this.entities) {
|
|
31
|
+
for (const { field, error } of entity.validate()) {
|
|
87
32
|
errors.push({
|
|
88
33
|
entity: (entity.get(this.indexField) || '[missing]'),
|
|
89
|
-
field
|
|
90
|
-
error
|
|
34
|
+
field,
|
|
35
|
+
error
|
|
91
36
|
});
|
|
92
37
|
}
|
|
93
38
|
}
|
|
94
39
|
return errors;
|
|
95
|
-
}
|
|
96
|
-
|
|
40
|
+
}
|
|
41
|
+
toTable() {
|
|
97
42
|
if (this.entities.length === 0) {
|
|
98
43
|
return [[]];
|
|
99
44
|
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return header.map(
|
|
103
|
-
|
|
45
|
+
const header = Object.keys(this.entities[0].schema);
|
|
46
|
+
const table = this.entities.map((entity) => {
|
|
47
|
+
return header.map((field) => {
|
|
48
|
+
const value = entity.get(field) || '';
|
|
104
49
|
return Array.isArray(value) ? value.join('; ') : value;
|
|
105
50
|
});
|
|
106
51
|
});
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
}());
|
|
52
|
+
return [header, ...table];
|
|
53
|
+
}
|
|
54
|
+
}
|
|
111
55
|
exports.Entities = Entities;
|
package/lib/catalog/entity.js
CHANGED
|
@@ -1,23 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __assign = (this && this.__assign) || function () {
|
|
3
|
-
__assign = Object.assign || function(t) {
|
|
4
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
5
|
-
s = arguments[i];
|
|
6
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
7
|
-
t[p] = s[p];
|
|
8
|
-
}
|
|
9
|
-
return t;
|
|
10
|
-
};
|
|
11
|
-
return __assign.apply(this, arguments);
|
|
12
|
-
};
|
|
13
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
3
|
exports.Entity = void 0;
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
4
|
+
const value_1 = require("./value");
|
|
5
|
+
class Entity {
|
|
6
|
+
constructor(values, schema) {
|
|
18
7
|
this.fields = {};
|
|
19
|
-
for (
|
|
20
|
-
|
|
8
|
+
for (const key in values) {
|
|
9
|
+
const value = (0, value_1.parseValue)(values[key], !!schema[key] && !!schema[key].multiple);
|
|
21
10
|
if (value !== null) {
|
|
22
11
|
this.fields[key] = value;
|
|
23
12
|
}
|
|
@@ -25,31 +14,30 @@ var Entity = /** @class */ (function () {
|
|
|
25
14
|
this.schema = schema;
|
|
26
15
|
this.derivedFields = {};
|
|
27
16
|
}
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
|
|
17
|
+
deriveFields() {
|
|
18
|
+
}
|
|
19
|
+
get(key) {
|
|
31
20
|
if (key in this.fields) {
|
|
32
21
|
return this.fields[key];
|
|
33
22
|
}
|
|
34
23
|
else if (key in this.derivedFields) {
|
|
35
24
|
return this.derivedFields[key];
|
|
36
25
|
}
|
|
37
|
-
}
|
|
38
|
-
|
|
26
|
+
}
|
|
27
|
+
has(key) {
|
|
39
28
|
return key in this.fields || key in this.derivedFields;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
for (
|
|
44
|
-
for (
|
|
45
|
-
|
|
46
|
-
errors.push({ field: field, error: error });
|
|
29
|
+
}
|
|
30
|
+
validate() {
|
|
31
|
+
const errors = [];
|
|
32
|
+
for (const field in Object.assign(Object.assign({}, this.fields), this.schema)) {
|
|
33
|
+
for (const error of this._validateField(field)) {
|
|
34
|
+
errors.push({ field, error });
|
|
47
35
|
}
|
|
48
36
|
}
|
|
49
37
|
return errors;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
38
|
+
}
|
|
39
|
+
_validateField(field) {
|
|
40
|
+
const errors = [];
|
|
53
41
|
if (!(field in this.schema)) {
|
|
54
42
|
errors.push('Field unknown');
|
|
55
43
|
return errors;
|
|
@@ -60,30 +48,29 @@ var Entity = /** @class */ (function () {
|
|
|
60
48
|
}
|
|
61
49
|
return errors;
|
|
62
50
|
}
|
|
63
|
-
|
|
51
|
+
const valueCountError = this._validateValueCount(field, this.fields[field]);
|
|
64
52
|
if (valueCountError !== undefined) {
|
|
65
53
|
errors.push(valueCountError);
|
|
66
54
|
}
|
|
67
|
-
|
|
55
|
+
let values = this.fields[field];
|
|
68
56
|
if (!Array.isArray(values)) {
|
|
69
57
|
values = [values];
|
|
70
58
|
}
|
|
71
|
-
for (
|
|
72
|
-
|
|
73
|
-
var result = this._validateSingleValue(field, value);
|
|
59
|
+
for (const value of values) {
|
|
60
|
+
const result = this._validateSingleValue(field, value);
|
|
74
61
|
if (result !== undefined) {
|
|
75
62
|
errors.push(result);
|
|
76
63
|
}
|
|
77
64
|
}
|
|
78
65
|
return errors;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
66
|
+
}
|
|
67
|
+
_validateValueCount(field, value) {
|
|
68
|
+
const multipleConfig = this.schema[field].multiple;
|
|
69
|
+
const allowMultiple = typeof multipleConfig === 'function'
|
|
83
70
|
? multipleConfig.call(null, this.fields)
|
|
84
71
|
: multipleConfig;
|
|
85
72
|
if (allowMultiple === false) {
|
|
86
|
-
|
|
73
|
+
let multiple = false;
|
|
87
74
|
if (Array.isArray(value) && value.length > 2) {
|
|
88
75
|
multiple = true;
|
|
89
76
|
}
|
|
@@ -95,22 +82,21 @@ var Entity = /** @class */ (function () {
|
|
|
95
82
|
}
|
|
96
83
|
}
|
|
97
84
|
return undefined;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
85
|
+
}
|
|
86
|
+
_validateSingleValue(field, value) {
|
|
87
|
+
const config = this.schema[field].format;
|
|
101
88
|
if (config === undefined) {
|
|
102
89
|
return undefined;
|
|
103
90
|
}
|
|
104
91
|
else if (Array.isArray(config) && (value === null || !config.includes(value))) {
|
|
105
|
-
return
|
|
92
|
+
return `The value "${value}" is not included: ${config.join(', ')}`;
|
|
106
93
|
}
|
|
107
94
|
else if (config instanceof RegExp && !config.test(value)) {
|
|
108
|
-
return
|
|
95
|
+
return `The value "${value}" does not conform to pattern: ${config.source}`;
|
|
109
96
|
}
|
|
110
97
|
else if (typeof config === 'function' && !config.call(null, value)) {
|
|
111
|
-
return
|
|
98
|
+
return `The value "${value}" does not conform to pattern: ${config.name}`;
|
|
112
99
|
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
}());
|
|
100
|
+
}
|
|
101
|
+
}
|
|
116
102
|
exports.Entity = Entity;
|
package/lib/catalog/index.js
CHANGED
|
@@ -3,12 +3,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Entity = exports.Entities = void 0;
|
|
4
4
|
exports.getTypeInfo = getTypeInfo;
|
|
5
5
|
exports.loadData = loadData;
|
|
6
|
-
|
|
6
|
+
const entities_1 = require("./entities");
|
|
7
7
|
Object.defineProperty(exports, "Entities", { enumerable: true, get: function () { return entities_1.Entities; } });
|
|
8
|
-
|
|
8
|
+
const entity_1 = require("./entity");
|
|
9
9
|
Object.defineProperty(exports, "Entity", { enumerable: true, get: function () { return entity_1.Entity; } });
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
const index_1 = require("./tables/index");
|
|
11
|
+
const csv_1 = require("../csv");
|
|
12
12
|
function getTypeInfo(type) {
|
|
13
13
|
switch (type) {
|
|
14
14
|
case 'authors': return index_1.TYPE_INFO.authors;
|
|
@@ -16,17 +16,16 @@ function getTypeInfo(type) {
|
|
|
16
16
|
case 'publishers': return index_1.TYPE_INFO.publishers;
|
|
17
17
|
case 'taxa': return index_1.TYPE_INFO.taxa;
|
|
18
18
|
case 'catalog': return index_1.TYPE_INFO.catalog;
|
|
19
|
-
default: throw new TypeError(
|
|
19
|
+
default: throw new TypeError(`Unknown type "${type}"`);
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
function loadData(file, type) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
for (
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
for (var index = 0; index < header.length && index < row.length; index++) {
|
|
23
|
+
const [subClass, indexField] = getTypeInfo(type);
|
|
24
|
+
const entities = [];
|
|
25
|
+
const [header, ...rows] = (0, csv_1.parseCsv)(file);
|
|
26
|
+
for (const row of rows) {
|
|
27
|
+
const data = {};
|
|
28
|
+
for (let index = 0; index < header.length && index < row.length; index++) {
|
|
30
29
|
data[header[index]] = row[index];
|
|
31
30
|
}
|
|
32
31
|
entities.push(new subClass(data, {}));
|