@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
|
@@ -1,16 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
"use strict";
|
|
3
|
-
var __assign = (this && this.__assign) || function () {
|
|
4
|
-
__assign = Object.assign || function(t) {
|
|
5
|
-
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
6
|
-
s = arguments[i];
|
|
7
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
8
|
-
t[p] = s[p];
|
|
9
|
-
}
|
|
10
|
-
return t;
|
|
11
|
-
};
|
|
12
|
-
return __assign.apply(this, arguments);
|
|
13
|
-
};
|
|
14
3
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
4
|
if (k2 === undefined) k2 = k;
|
|
16
5
|
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
@@ -53,55 +42,19 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
53
42
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
54
43
|
});
|
|
55
44
|
};
|
|
56
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
57
|
-
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);
|
|
58
|
-
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
59
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
60
|
-
function step(op) {
|
|
61
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
62
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
63
|
-
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;
|
|
64
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
65
|
-
switch (op[0]) {
|
|
66
|
-
case 0: case 1: t = op; break;
|
|
67
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
68
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
69
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
70
|
-
default:
|
|
71
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
72
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
73
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
74
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
75
|
-
if (t[2]) _.ops.pop();
|
|
76
|
-
_.trys.pop(); continue;
|
|
77
|
-
}
|
|
78
|
-
op = body.call(thisArg, _);
|
|
79
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
80
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
84
|
-
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
85
|
-
if (ar || !(i in from)) {
|
|
86
|
-
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
87
|
-
ar[i] = from[i];
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return to.concat(ar || Array.prototype.slice.call(from));
|
|
91
|
-
};
|
|
92
45
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
46
|
+
const fs_1 = require("fs");
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const util = __importStar(require("util"));
|
|
49
|
+
const jsonld = __importStar(require("jsonld"));
|
|
50
|
+
const N3 = __importStar(require("n3"));
|
|
51
|
+
const index_1 = require("../index");
|
|
52
|
+
const resource_1 = require("../resources/resource");
|
|
53
|
+
const csv_1 = require("../csv");
|
|
54
|
+
const SHEETS = ['catalog', 'authors', 'places', 'publishers', 'taxa'];
|
|
55
|
+
const PREFIX = 'https://purl.org/identification-resources/';
|
|
56
|
+
const HANDLE_PREFIX = 'https://hdl.handle.net/';
|
|
57
|
+
const SCOPES = {
|
|
105
58
|
// animal life stage
|
|
106
59
|
'adults': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/adult'],
|
|
107
60
|
'pupae': ['dwciri:lifeStage', 'http://rs.gbif.org/vocabulary/gbif/life_stage/pupa'],
|
|
@@ -126,6 +79,7 @@ var SCOPES = {
|
|
|
126
79
|
// sex
|
|
127
80
|
'females': ['dwciri:sex', 'http://rs.gbif.org/vocabulary/gbif/sex/female'],
|
|
128
81
|
'males': ['dwciri:sex', 'http://rs.gbif.org/vocabulary/gbif/sex/male'],
|
|
82
|
+
'male': ['dwciri:sex', 'http://rs.gbif.org/vocabulary/gbif/sex/male'],
|
|
129
83
|
// caste
|
|
130
84
|
'queens': ['dwc:caste', 'queen'],
|
|
131
85
|
'workers': ['dwc:caste', 'worker'],
|
|
@@ -143,7 +97,7 @@ var SCOPES = {
|
|
|
143
97
|
'bones (upper jaws)': ['ac:subjectPart', 'http://rs.tdwg.org/acpart/values/p0028'],
|
|
144
98
|
'bones (lower jaws)': ['ac:subjectPart', 'http://rs.tdwg.org/acpart/values/p0029'],
|
|
145
99
|
};
|
|
146
|
-
|
|
100
|
+
const PREFIXES = {
|
|
147
101
|
'ac': 'http://rs.tdwg.org/ac/terms/',
|
|
148
102
|
'bibo': 'http://purl.org/ontology/bibo/',
|
|
149
103
|
'dcterms': 'http://purl.org/dc/terms/',
|
|
@@ -155,7 +109,7 @@ var PREFIXES = {
|
|
|
155
109
|
'schema': 'https://schema.org/',
|
|
156
110
|
'xsd': 'http://www.w3.org/2001/XMLSchema#',
|
|
157
111
|
};
|
|
158
|
-
|
|
112
|
+
const DWC_FIELDS = {
|
|
159
113
|
scientificName: 'dwc:scientificName',
|
|
160
114
|
scientificNameAuthorship: 'dwc:scientificNameAuthorship',
|
|
161
115
|
genericName: 'dwc:genericName',
|
|
@@ -167,30 +121,29 @@ var DWC_FIELDS = {
|
|
|
167
121
|
taxonomicStatus: 'dwc:taxonomicStatus',
|
|
168
122
|
verbatimIdentification: 'dwc:verbatimIdentification',
|
|
169
123
|
};
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
124
|
+
const GBIF_RANKS = ['kingdom', 'phylum', 'class', 'order', 'family', 'genus', 'species', 'subspecies'];
|
|
125
|
+
const GBIF_VOCAB_RANKS = ['domain', 'kingdom', 'subkingdom', 'superphylum', 'phylum', 'subphylum', 'superclass', 'class', 'subclass', 'supercohort', 'cohort', 'subcohort', 'superorder', 'order', 'suborder', 'infraorder', 'superfamily', 'family', 'subfamily', 'tribe', 'subtribe', 'genus', 'subgenus', 'section', 'subsection', 'series', 'subseries', 'speciesAggregate', 'species', 'subspecificAggregate', 'subspecies', 'variety', 'subvariety', 'form', 'subform', 'cultivarGroup', 'cultivar', 'strain'];
|
|
126
|
+
const STATUSES = {
|
|
173
127
|
'accepted': 'http://rs.gbif.org/vocabulary/gbif/taxonomicStatus/accepted',
|
|
174
128
|
'heterotypic synonym': 'http://rs.gbif.org/vocabulary/gbif/taxonomicStatus/heterotypicSynonym',
|
|
175
129
|
'synonym': 'http://rs.gbif.org/vocabulary/gbif/taxonomicStatus/synonym',
|
|
176
130
|
};
|
|
177
131
|
function getCoveringTaxon(taxa) {
|
|
178
132
|
if (taxa.length === 1 && !taxa[0].has('gbif')) {
|
|
179
|
-
return
|
|
133
|
+
return `${PREFIX}taxon/${taxa[0].get('id')}`;
|
|
180
134
|
}
|
|
181
135
|
function getAncestors(taxon) {
|
|
182
136
|
var _a;
|
|
183
|
-
|
|
137
|
+
const [...parents] = ((_a = taxon.get('parent_taxa')) !== null && _a !== void 0 ? _a : []);
|
|
184
138
|
if (taxon.has('gbif')) {
|
|
185
139
|
parents.push(taxon.get('gbif'));
|
|
186
140
|
}
|
|
187
141
|
return parents;
|
|
188
142
|
}
|
|
189
|
-
|
|
190
|
-
for (
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
for (var i = 0; i < ancestors.length; i++) {
|
|
143
|
+
const ancestors = getAncestors(taxa[0]);
|
|
144
|
+
for (const taxon of taxa.slice(1)) {
|
|
145
|
+
const otherAncestors = getAncestors(taxon);
|
|
146
|
+
for (let i = 0; i < ancestors.length; i++) {
|
|
194
147
|
if (ancestors[i] !== otherAncestors[i]) {
|
|
195
148
|
ancestors.splice(i);
|
|
196
149
|
}
|
|
@@ -199,40 +152,36 @@ function getCoveringTaxon(taxa) {
|
|
|
199
152
|
return ancestors.length ? makeGbifUri(ancestors[ancestors.length - 1])['@id'] : null;
|
|
200
153
|
}
|
|
201
154
|
function mapEntities(names, entities) {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
return Array.isArray(values) ? values.includes(
|
|
155
|
+
const result = [];
|
|
156
|
+
for (const name of names) {
|
|
157
|
+
const entity = entities.find(entity => {
|
|
158
|
+
const values = entity.get('name');
|
|
159
|
+
return Array.isArray(values) ? values.includes(name) : values === name;
|
|
207
160
|
});
|
|
208
161
|
if (!entity) {
|
|
209
|
-
console.error('Unmapped entity:',
|
|
210
|
-
|
|
162
|
+
console.error('Unmapped entity:', name);
|
|
163
|
+
continue;
|
|
211
164
|
}
|
|
212
165
|
result.push(entity);
|
|
213
|
-
};
|
|
214
|
-
for (var _i = 0, names_1 = names; _i < names_1.length; _i++) {
|
|
215
|
-
var name_1 = names_1[_i];
|
|
216
|
-
_loop_1(name_1);
|
|
217
166
|
}
|
|
218
167
|
return result;
|
|
219
168
|
}
|
|
220
169
|
function makeWikidataUri(qid) {
|
|
221
|
-
return { '@id':
|
|
170
|
+
return { '@id': `http://www.wikidata.org/entity/${qid}` };
|
|
222
171
|
}
|
|
223
172
|
function makeGbifUri(id) {
|
|
224
|
-
return { '@id':
|
|
173
|
+
return { '@id': `https://gbif.org/species/${id}` };
|
|
225
174
|
}
|
|
226
175
|
function makeWorkUri(id) {
|
|
227
|
-
return { '@id':
|
|
176
|
+
return { '@id': `${PREFIX}catalog/${id}` };
|
|
228
177
|
}
|
|
229
178
|
function makeScientificNameUri(id) {
|
|
230
|
-
|
|
231
|
-
return { '@id':
|
|
179
|
+
const resource = id.split(':').slice(0, -1).join(':');
|
|
180
|
+
return { '@id': `${PREFIX}resource/${resource}#${id}` };
|
|
232
181
|
}
|
|
233
182
|
function makeTaxonRankUri(rank) {
|
|
234
183
|
if (GBIF_VOCAB_RANKS.includes(rank)) {
|
|
235
|
-
return { '@id':
|
|
184
|
+
return { '@id': `http://rs.gbif.org/vocabulary/gbif/rank/${rank}` };
|
|
236
185
|
}
|
|
237
186
|
else {
|
|
238
187
|
return rank;
|
|
@@ -242,8 +191,8 @@ function makeTaxonomicStatusUri(status) {
|
|
|
242
191
|
return { '@id': STATUSES[status] };
|
|
243
192
|
}
|
|
244
193
|
function makeLinkedDataForAuthor(author) {
|
|
245
|
-
|
|
246
|
-
'@id':
|
|
194
|
+
const node = {
|
|
195
|
+
'@id': `${PREFIX}author/${author.get('id')}`,
|
|
247
196
|
'@type': 'foaf:Person',
|
|
248
197
|
'foaf:name': author.get('display_name')
|
|
249
198
|
};
|
|
@@ -253,8 +202,8 @@ function makeLinkedDataForAuthor(author) {
|
|
|
253
202
|
return node;
|
|
254
203
|
}
|
|
255
204
|
function makeLinkedDataForPlace(place) {
|
|
256
|
-
|
|
257
|
-
'@id':
|
|
205
|
+
const node = {
|
|
206
|
+
'@id': `${PREFIX}place/${place.get('id')}`,
|
|
258
207
|
'@type': 'dcterms:Location',
|
|
259
208
|
'dcterms:title': place.get('display_name'),
|
|
260
209
|
};
|
|
@@ -264,8 +213,8 @@ function makeLinkedDataForPlace(place) {
|
|
|
264
213
|
return node;
|
|
265
214
|
}
|
|
266
215
|
function makeLinkedDataForPublisher(publisher) {
|
|
267
|
-
|
|
268
|
-
'@id':
|
|
216
|
+
const node = {
|
|
217
|
+
'@id': `${PREFIX}publisher/${publisher.get('id')}`,
|
|
269
218
|
'@type': 'foaf:Organization',
|
|
270
219
|
'foaf:name': publisher.get('display_name')
|
|
271
220
|
};
|
|
@@ -275,15 +224,15 @@ function makeLinkedDataForPublisher(publisher) {
|
|
|
275
224
|
return node;
|
|
276
225
|
}
|
|
277
226
|
function makeLinkedDataForTaxon(taxon) {
|
|
278
|
-
|
|
279
|
-
'@id':
|
|
227
|
+
const node = {
|
|
228
|
+
'@id': `${PREFIX}taxon/${taxon.get('id')}`,
|
|
280
229
|
'@type': 'dwc:Taxon',
|
|
281
|
-
'dwc:scientificName': taxon.get('
|
|
230
|
+
'dwc:scientificName': taxon.get('name'),
|
|
282
231
|
};
|
|
283
232
|
if (taxon.has('rank')) {
|
|
284
233
|
node['dwc:taxonRank'] = makeTaxonRankUri(taxon.get('rank'));
|
|
285
234
|
}
|
|
286
|
-
|
|
235
|
+
const ids = [];
|
|
287
236
|
if (taxon.has('qid')) {
|
|
288
237
|
ids.push(makeWikidataUri(taxon.get('qid')));
|
|
289
238
|
}
|
|
@@ -297,39 +246,37 @@ function makeLinkedDataForTaxon(taxon) {
|
|
|
297
246
|
}
|
|
298
247
|
function makeLinkedDataForTaxa(files) {
|
|
299
248
|
var _a;
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
for (
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
var ancestors = (_a = taxon.get('ancestors_gbif')) !== null && _a !== void 0 ? _a : [];
|
|
249
|
+
const nodes = [];
|
|
250
|
+
const gbifTaxa = {};
|
|
251
|
+
for (const taxon of files.taxa.entities) {
|
|
252
|
+
const node = makeLinkedDataForTaxon(taxon);
|
|
253
|
+
const ancestors = (_a = taxon.get('ancestors_gbif')) !== null && _a !== void 0 ? _a : [];
|
|
306
254
|
if (ancestors.length) {
|
|
307
255
|
node['dwc:parentNameUsageID'] = makeGbifUri(ancestors[ancestors.length - 1]);
|
|
308
256
|
}
|
|
309
257
|
else if (taxon.get('id') !== 'T141') {
|
|
310
|
-
node['dwc:parentNameUsageID'] = { '@id':
|
|
258
|
+
node['dwc:parentNameUsageID'] = { '@id': `${PREFIX}taxon/T141` };
|
|
311
259
|
}
|
|
312
|
-
for (
|
|
313
|
-
gbifTaxa[ancestors[i]] =
|
|
260
|
+
for (let i = 0; i < ancestors.length; i++) {
|
|
261
|
+
gbifTaxa[ancestors[i]] = Object.assign(Object.assign({}, makeGbifUri(ancestors[i])), { 'dwc:taxonRank': makeTaxonRankUri(GBIF_RANKS[i]), 'dwc:parentNameUsageID': i ? makeGbifUri(ancestors[i - 1]) : { '@id': `${PREFIX}taxon/T141` } });
|
|
314
262
|
}
|
|
315
263
|
if (taxon.has('children_gbif')) {
|
|
316
|
-
|
|
264
|
+
const children = taxon.get('children_gbif');
|
|
317
265
|
node['@reverse'] = { 'dwc:parentNameUsageID': children.map(makeGbifUri) };
|
|
318
|
-
|
|
319
|
-
for (
|
|
320
|
-
|
|
321
|
-
gbifTaxa[child] = __assign(__assign({}, makeGbifUri(child)), { 'dwc:taxonRank': makeTaxonRankUri(childRank) });
|
|
266
|
+
const childRank = GBIF_RANKS[ancestors.length];
|
|
267
|
+
for (const child of children) {
|
|
268
|
+
gbifTaxa[child] = Object.assign(Object.assign({}, makeGbifUri(child)), { 'dwc:taxonRank': makeTaxonRankUri(childRank) });
|
|
322
269
|
}
|
|
323
270
|
}
|
|
324
271
|
nodes.push(node);
|
|
325
272
|
}
|
|
326
|
-
nodes.push
|
|
273
|
+
nodes.push(...Object.values(gbifTaxa));
|
|
327
274
|
return nodes;
|
|
328
275
|
}
|
|
329
276
|
function makeLinkedDataForScientificName(name) {
|
|
330
|
-
|
|
331
|
-
for (
|
|
332
|
-
|
|
277
|
+
const node = Object.assign(Object.assign({}, makeScientificNameUri(name.scientificNameID)), { '@type': 'dwc:Taxon' });
|
|
278
|
+
for (const field in DWC_FIELDS) {
|
|
279
|
+
const value = name[field];
|
|
333
280
|
if (value) {
|
|
334
281
|
node[DWC_FIELDS[field]] = value;
|
|
335
282
|
}
|
|
@@ -346,12 +293,12 @@ function makeLinkedDataForScientificName(name) {
|
|
|
346
293
|
if (name.parentNameUsageID) {
|
|
347
294
|
node['dwc:parentNameUsageID'] = makeScientificNameUri(name.parentNameUsageID);
|
|
348
295
|
}
|
|
349
|
-
|
|
296
|
+
const identifiers = [];
|
|
350
297
|
if (name.gbifTaxonID) {
|
|
351
298
|
identifiers.push(makeGbifUri(name.gbifTaxonID));
|
|
352
299
|
}
|
|
353
300
|
if (name.colTaxonID) {
|
|
354
|
-
identifiers.push({ '@id':
|
|
301
|
+
identifiers.push({ '@id': `https://www.checklistbank.org/dataset/309120/taxon/${name.colTaxonID}` });
|
|
355
302
|
}
|
|
356
303
|
if (identifiers.length) {
|
|
357
304
|
node['dwc:taxonID'] = identifiers;
|
|
@@ -360,9 +307,9 @@ function makeLinkedDataForScientificName(name) {
|
|
|
360
307
|
}
|
|
361
308
|
function makeLinkedDataForResource(work, files, resourceId) {
|
|
362
309
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
363
|
-
|
|
310
|
+
const resource = new resource_1.WorkResource({});
|
|
364
311
|
if (!resourceId) {
|
|
365
|
-
resourceId =
|
|
312
|
+
resourceId = `${work.get('id')}:0`;
|
|
366
313
|
}
|
|
367
314
|
if (files.resources[resourceId] && files.resources[resourceId].metadata.catalog) {
|
|
368
315
|
resource.fields = files.resources[resourceId].metadata.catalog;
|
|
@@ -370,9 +317,9 @@ function makeLinkedDataForResource(work, files, resourceId) {
|
|
|
370
317
|
if (!resource.has('language')) {
|
|
371
318
|
resource.fields.language = work.get('language');
|
|
372
319
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
if (types.includes('matrix')) {
|
|
320
|
+
const node = Object.assign(Object.assign({}, makeLinkedDataForWork(resource, files)), { '@id': `${PREFIX}resource/${resourceId}`, '@type': 'bibo:DocumentPart' });
|
|
321
|
+
const types = (_b = (_a = resource.get('key_type')) !== null && _a !== void 0 ? _a : work.get('key_type')) !== null && _b !== void 0 ? _b : [];
|
|
322
|
+
if (types.includes('matrix') || types.includes('algorithm')) {
|
|
376
323
|
node['dcterms:type'] = { '@id': 'http://purl.org/dc/dcmitype/Software' };
|
|
377
324
|
}
|
|
378
325
|
else if (types.includes('key') || types.includes('reference') || types.includes('supplement')) {
|
|
@@ -381,32 +328,33 @@ function makeLinkedDataForResource(work, files, resourceId) {
|
|
|
381
328
|
else if (types.includes('gallery') || types.includes('collection')) {
|
|
382
329
|
node['dcterms:type'] = { '@id': 'http://purl.org/dc/dcmitype/Collection' };
|
|
383
330
|
}
|
|
331
|
+
else if (types.includes('checklist')) {
|
|
332
|
+
node['dcterms:type'] = { '@id': 'http://purl.org/dc/dcmitype/Dataset' };
|
|
333
|
+
}
|
|
384
334
|
if (types.includes('key') || types.includes('matrix')) {
|
|
385
335
|
node['ac:subtype'] = { '@id': 'http://rs.tdwg.org/acsubtype/values/IdentificationKey' };
|
|
386
336
|
}
|
|
387
|
-
|
|
337
|
+
const taxonNames = (_c = resource.get('taxon')) !== null && _c !== void 0 ? _c : work.get('taxon');
|
|
388
338
|
if (taxonNames) {
|
|
389
|
-
|
|
390
|
-
|
|
339
|
+
const taxa = mapEntities(taxonNames, files.taxa.entities);
|
|
340
|
+
const coveringTaxon = taxa.length ? getCoveringTaxon(taxa) : null;
|
|
391
341
|
if (coveringTaxon !== null) {
|
|
392
342
|
node['ac:taxonCoverage'] = { '@id': coveringTaxon };
|
|
393
343
|
}
|
|
394
|
-
node['dwc:taxonID'] = taxa.map(
|
|
344
|
+
node['dwc:taxonID'] = taxa.map(taxon => ({ '@id': `${PREFIX}taxon/${taxon.get('id')}` }));
|
|
395
345
|
}
|
|
396
|
-
|
|
346
|
+
const scopes = (_d = resource.get('scope')) !== null && _d !== void 0 ? _d : work.get('scope');
|
|
397
347
|
if (scopes) {
|
|
398
|
-
for (
|
|
399
|
-
var scope = _j[_i];
|
|
348
|
+
for (const scope of scopes) {
|
|
400
349
|
if (!SCOPES[scope]) {
|
|
401
350
|
console.error('Unmapped scope:', scope);
|
|
402
351
|
continue;
|
|
403
352
|
}
|
|
404
|
-
|
|
353
|
+
const [property, ...values] = SCOPES[scope];
|
|
405
354
|
if (!Array.isArray(node[property])) {
|
|
406
355
|
node[property] = [];
|
|
407
356
|
}
|
|
408
|
-
for (
|
|
409
|
-
var value = values_1[_l];
|
|
357
|
+
for (const value of values) {
|
|
410
358
|
if (value.startsWith('http')) {
|
|
411
359
|
node[property].push({ '@id': value });
|
|
412
360
|
}
|
|
@@ -416,34 +364,33 @@ function makeLinkedDataForResource(work, files, resourceId) {
|
|
|
416
364
|
}
|
|
417
365
|
}
|
|
418
366
|
}
|
|
419
|
-
|
|
367
|
+
const region = (_e = resource.get('region')) !== null && _e !== void 0 ? _e : work.get('region');
|
|
420
368
|
if (region) {
|
|
421
|
-
|
|
369
|
+
const places = mapEntities(region, files.places.entities).map(place => ({ '@id': `${PREFIX}place/${place.get('id')}` }));
|
|
422
370
|
node['dcterms:spatial'] = places;
|
|
423
371
|
}
|
|
424
|
-
|
|
425
|
-
|
|
372
|
+
const tags = [];
|
|
373
|
+
const taxonScopes = (_f = resource.get('taxon_scope')) !== null && _f !== void 0 ? _f : work.get('taxon_scope');
|
|
426
374
|
if (taxonScopes) {
|
|
427
|
-
tags.push
|
|
375
|
+
tags.push(...taxonScopes);
|
|
428
376
|
}
|
|
429
377
|
else if (((_g = resource.get('complete')) !== null && _g !== void 0 ? _g : work.get('complete')) === 'FALSE') {
|
|
430
378
|
tags.push('not intended to be complete');
|
|
431
379
|
}
|
|
432
|
-
|
|
380
|
+
const targetTaxa = (_h = resource.get('target_taxa')) !== null && _h !== void 0 ? _h : work.get('target_taxa');
|
|
433
381
|
if (targetTaxa) {
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
tags.push(
|
|
382
|
+
const first = targetTaxa.slice(0, -1).map(rank => rank + ',');
|
|
383
|
+
const last = targetTaxa[targetTaxa.length - 1];
|
|
384
|
+
const list = first.length ? first.join('') + ' or ' + last : last;
|
|
385
|
+
tags.push(`for identification to ${list}`);
|
|
438
386
|
}
|
|
439
387
|
if (tags.length) {
|
|
440
388
|
node['ac:tag'] = tags;
|
|
441
389
|
}
|
|
442
390
|
if (files.resources[resourceId].taxa) {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
for (
|
|
446
|
-
var taxon = _o[_m];
|
|
391
|
+
const leafs = new Set(files.resources[resourceId].taxa.map(taxon => taxon.scientificNameID));
|
|
392
|
+
const taxa = [];
|
|
393
|
+
for (const taxon of files.resources[resourceId].taxa) {
|
|
447
394
|
taxa.push(makeLinkedDataForScientificName(taxon));
|
|
448
395
|
if (taxon.parentNameUsageID) {
|
|
449
396
|
leafs.delete(taxon.parentNameUsageID);
|
|
@@ -455,20 +402,20 @@ function makeLinkedDataForResource(work, files, resourceId) {
|
|
|
455
402
|
return node;
|
|
456
403
|
}
|
|
457
404
|
function makeLinkedDataForWork(work, files) {
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
node['dcterms:language'] = languages.map(
|
|
405
|
+
const id = work.get('id');
|
|
406
|
+
const node = makeWorkUri(id);
|
|
407
|
+
const languages = work.get('language');
|
|
408
|
+
node['dcterms:language'] = languages.map(language => ({ '@id': `http://id.loc.gov/vocabulary/iso639-1/${language}` }));
|
|
462
409
|
if (work.has('title')) {
|
|
463
|
-
|
|
410
|
+
const title = work.get('title');
|
|
464
411
|
if (title.length > languages.length) {
|
|
465
412
|
title.splice(0, title.length, title.join('; '));
|
|
466
413
|
}
|
|
467
|
-
node['dcterms:title'] = title.map(
|
|
414
|
+
node['dcterms:title'] = title.map((value, i) => ({ '@value': value, '@language': languages[i] }));
|
|
468
415
|
}
|
|
469
416
|
if (work.has('pages') && work.get('pages').includes('-')) {
|
|
470
|
-
|
|
471
|
-
if (containers.find(
|
|
417
|
+
const containers = work.has('part_of') ? work.get('part_of').map(id => files.catalog.get(id)) : [];
|
|
418
|
+
if (containers.find(container => container.get('entry_type') === 'online')) {
|
|
472
419
|
node['@type'] = 'bibo:BookSection';
|
|
473
420
|
}
|
|
474
421
|
else {
|
|
@@ -482,28 +429,28 @@ function makeLinkedDataForWork(work, files) {
|
|
|
482
429
|
node['@type'] = 'bibo:Book';
|
|
483
430
|
}
|
|
484
431
|
if (work.has('author')) {
|
|
485
|
-
|
|
432
|
+
const authors = mapEntities(work.get('author'), files.authors.entities).map(author => ({ '@id': `${PREFIX}author/${author.get('id')}` }));
|
|
486
433
|
node['bibo:authorList'] = { '@list': authors };
|
|
487
434
|
node['dcterms:creator'] = authors;
|
|
488
435
|
}
|
|
489
436
|
if (work.has('url')) {
|
|
490
|
-
|
|
491
|
-
|
|
437
|
+
const urls = work.get('url');
|
|
438
|
+
const handle = urls.find(url => url.startsWith(HANDLE_PREFIX));
|
|
492
439
|
if (handle) {
|
|
493
440
|
node['bibo:handle'] = { '@id': handle.slice(HANDLE_PREFIX.length) };
|
|
494
441
|
}
|
|
495
|
-
node['schema:url'] = urls.map(
|
|
442
|
+
node['schema:url'] = urls.map(url => ({ '@id': url }));
|
|
496
443
|
}
|
|
497
444
|
if (work.has('fulltext_url')) {
|
|
498
|
-
|
|
499
|
-
node['schema:encoding'] = urls.map(
|
|
445
|
+
const urls = work.get('fulltext_url');
|
|
446
|
+
node['schema:encoding'] = urls.map(url => ({ '@type': 'schema:MediaObject', 'schema:contentUrl': { '@id': url } }));
|
|
500
447
|
}
|
|
501
448
|
if (work.has('archive_url')) {
|
|
502
|
-
node['schema:archivedAt'] = work.get('archive_url').map(
|
|
449
|
+
node['schema:archivedAt'] = work.get('archive_url').map(url => ({ '@id': url }));
|
|
503
450
|
}
|
|
504
451
|
if (work.has('date')) {
|
|
505
|
-
|
|
506
|
-
|
|
452
|
+
const date = work.get('date');
|
|
453
|
+
let dateType = 'rdfs:Literal';
|
|
507
454
|
if (date.match(/^\d{4}-\d{2}-\d{2}$/)) {
|
|
508
455
|
dateType = 'xsd:date';
|
|
509
456
|
}
|
|
@@ -516,16 +463,15 @@ function makeLinkedDataForWork(work, files) {
|
|
|
516
463
|
node['dcterms:issued'] = { '@value': work.get('date'), '@type': dateType };
|
|
517
464
|
}
|
|
518
465
|
if (work.has('publisher')) {
|
|
519
|
-
|
|
466
|
+
const publishers = mapEntities(work.get('publisher'), files.publishers.entities).map(publisher => ({ '@id': `${PREFIX}publisher/${publisher.get('id')}` }));
|
|
520
467
|
node['dcterms:publisher'] = publishers;
|
|
521
468
|
}
|
|
522
469
|
if (work.has('ISSN')) {
|
|
523
470
|
node['bibo:issn'] = work.get('ISSN');
|
|
524
471
|
}
|
|
525
472
|
if (work.has('ISBN')) {
|
|
526
|
-
|
|
527
|
-
for (
|
|
528
|
-
var isbn = isbns_1[_i];
|
|
473
|
+
const isbns = work.get('ISBN');
|
|
474
|
+
for (const isbn of isbns) {
|
|
529
475
|
if (isbn.length === 13) {
|
|
530
476
|
node['bibo:isbn13'] = isbn;
|
|
531
477
|
}
|
|
@@ -550,14 +496,14 @@ function makeLinkedDataForWork(work, files) {
|
|
|
550
496
|
node['bibo:issue'] = work.get('issue');
|
|
551
497
|
}
|
|
552
498
|
if (work.has('pages')) {
|
|
553
|
-
|
|
554
|
-
|
|
499
|
+
const pages = work.get('pages');
|
|
500
|
+
const range = pages.split('-');
|
|
555
501
|
if (pages.match(/^\d+$/)) {
|
|
556
502
|
node['bibo:numPages'] = parseInt(pages);
|
|
557
503
|
}
|
|
558
504
|
else if (range.length === 2) {
|
|
559
505
|
node['bibo:pages'] = pages;
|
|
560
|
-
|
|
506
|
+
const [start, end] = range.map(part => parseInt(part));
|
|
561
507
|
if (!isNaN(start)) {
|
|
562
508
|
node['bibo:pageStart'] = start;
|
|
563
509
|
}
|
|
@@ -576,38 +522,36 @@ function makeLinkedDataForWork(work, files) {
|
|
|
576
522
|
node['bibo:edition'] = work.get('edition');
|
|
577
523
|
}
|
|
578
524
|
if (work.has('license')) {
|
|
579
|
-
|
|
580
|
-
node['dcterms:rights'] = licenses.map(
|
|
525
|
+
const licenses = work.get('license');
|
|
526
|
+
node['dcterms:rights'] = licenses.map(license => {
|
|
581
527
|
if (license === '<public domain>' || license.match(/^<.+\?>$/)) {
|
|
582
528
|
return license.slice(1, -1);
|
|
583
529
|
}
|
|
584
530
|
else {
|
|
585
|
-
return { '@id':
|
|
531
|
+
return { '@id': `https://spdx.org/licenses/${license}.html` };
|
|
586
532
|
}
|
|
587
533
|
});
|
|
588
534
|
}
|
|
589
535
|
return node;
|
|
590
536
|
}
|
|
591
537
|
function makeLinkedDataForWorks(files) {
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
for (
|
|
595
|
-
var work = _a[_i];
|
|
538
|
+
const nodes = {};
|
|
539
|
+
const works = files.catalog;
|
|
540
|
+
for (const work of works.entities) {
|
|
596
541
|
nodes[work.get('id')] = makeLinkedDataForWork(work, files);
|
|
597
542
|
}
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
543
|
+
for (const work of works.entities) {
|
|
544
|
+
const id = work.get('id');
|
|
545
|
+
const node = nodes[id];
|
|
546
|
+
const language = work.get('language');
|
|
602
547
|
if (work.has('part_of')) {
|
|
603
|
-
|
|
548
|
+
const containers = work.get('part_of');
|
|
604
549
|
if (work.get('key_type').includes('supplement')) {
|
|
605
550
|
node['bibo:annotates'] = containers.map(makeWorkUri);
|
|
606
551
|
}
|
|
607
552
|
else {
|
|
608
553
|
node['dcterms:isPartOf'] = containers.map(makeWorkUri);
|
|
609
|
-
for (
|
|
610
|
-
var container = containers_1[_d];
|
|
554
|
+
for (const container of containers) {
|
|
611
555
|
if (!Array.isArray(nodes[container]['dcterms:hasPart'])) {
|
|
612
556
|
nodes[container]['dcterms:hasPart'] = [];
|
|
613
557
|
}
|
|
@@ -616,170 +560,107 @@ function makeLinkedDataForWorks(files) {
|
|
|
616
560
|
}
|
|
617
561
|
}
|
|
618
562
|
if (work.has('listed_in')) {
|
|
619
|
-
|
|
563
|
+
const referers = work.get('listed_in');
|
|
620
564
|
node['bibo:citedBy'] = node['dcterms:isReferencedBy'] = referers.map(makeWorkUri);
|
|
621
|
-
for (
|
|
622
|
-
var referer = referers_1[_e];
|
|
565
|
+
for (const referer of referers) {
|
|
623
566
|
nodes[referer]['bibo:cites'] = nodes[referer]['dcterms:references'] = makeWorkUri(id);
|
|
624
567
|
}
|
|
625
568
|
}
|
|
626
569
|
if (work.has('version_of')) {
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
node['bibo:translationOf'] = originals.filter(
|
|
630
|
-
node['dcterms:isVersionOf'] = originals.filter(
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
while ((resourceId =
|
|
635
|
-
|
|
570
|
+
const originals = work.get('version_of');
|
|
571
|
+
const originalLanguages = originals.map(id => works.get(id).get('language').join());
|
|
572
|
+
node['bibo:translationOf'] = originals.filter((_, i) => originalLanguages[i] !== language.join()).map(makeWorkUri);
|
|
573
|
+
node['dcterms:isVersionOf'] = originals.filter(id => work.get('id') !== id).map(makeWorkUri);
|
|
574
|
+
}
|
|
575
|
+
let resourceIndex = 1;
|
|
576
|
+
let resourceId;
|
|
577
|
+
while ((resourceId = `${id}:${resourceIndex++}`) in files.resources) {
|
|
578
|
+
const resource = makeLinkedDataForResource(work, files, resourceId);
|
|
636
579
|
if (!Array.isArray(node['dcterms:hasPart'])) {
|
|
637
580
|
node['dcterms:hasPart'] = [];
|
|
638
581
|
}
|
|
639
582
|
node['dcterms:hasPart'].push(resource);
|
|
640
|
-
if (!Array.isArray(resource['dcterms:
|
|
641
|
-
resource['dcterms:
|
|
583
|
+
if (!Array.isArray(resource['dcterms:isPartOf'])) {
|
|
584
|
+
resource['dcterms:isPartOf'] = [];
|
|
642
585
|
}
|
|
643
|
-
resource['dcterms:
|
|
586
|
+
resource['dcterms:isPartOf'].push({ '@id': node['@id'] });
|
|
644
587
|
}
|
|
645
|
-
};
|
|
646
|
-
for (var _b = 0, _c = works.entities; _b < _c.length; _b++) {
|
|
647
|
-
var work = _c[_b];
|
|
648
|
-
_loop_2(work);
|
|
649
588
|
}
|
|
650
589
|
return Object.values(nodes);
|
|
651
590
|
}
|
|
652
591
|
function writeOutput(document_1) {
|
|
653
|
-
return __awaiter(this, arguments, void 0, function (document, format) {
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
return [2 /*return*/];
|
|
669
|
-
}
|
|
670
|
-
parser = new N3.StreamParser();
|
|
671
|
-
writer = new N3.StreamWriter({ prefixes: PREFIXES });
|
|
672
|
-
parser.write(nquads);
|
|
673
|
-
parser.pipe(writer);
|
|
674
|
-
writer.pipe(process.stdout);
|
|
675
|
-
return [2 /*return*/];
|
|
676
|
-
}
|
|
677
|
-
});
|
|
592
|
+
return __awaiter(this, arguments, void 0, function* (document, format = 'jsonld') {
|
|
593
|
+
if (format === 'jsonld') {
|
|
594
|
+
process.stdout.write(JSON.stringify(document, null, 2));
|
|
595
|
+
return;
|
|
596
|
+
}
|
|
597
|
+
const nquads = yield jsonld.toRDF(document, { format: 'application/n-quads' });
|
|
598
|
+
if (format === 'nquads') {
|
|
599
|
+
process.stdout.write(nquads);
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
const parser = new N3.StreamParser();
|
|
603
|
+
const writer = new N3.StreamWriter({ prefixes: PREFIXES });
|
|
604
|
+
parser.write(nquads);
|
|
605
|
+
parser.pipe(writer);
|
|
606
|
+
writer.pipe(process.stdout);
|
|
678
607
|
});
|
|
679
608
|
}
|
|
680
609
|
function main() {
|
|
681
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
short: 'f',
|
|
692
|
-
default: 'jsonld',
|
|
693
|
-
}
|
|
694
|
-
},
|
|
695
|
-
});
|
|
696
|
-
directory = path.resolve(args.positionals[0]);
|
|
697
|
-
files = {};
|
|
698
|
-
_i = 0, SHEETS_1 = SHEETS;
|
|
699
|
-
_o.label = 1;
|
|
700
|
-
case 1:
|
|
701
|
-
if (!(_i < SHEETS_1.length)) return [3 /*break*/, 4];
|
|
702
|
-
sheet = SHEETS_1[_i];
|
|
703
|
-
filePath = path.join(directory, "".concat(sheet, ".csv"));
|
|
704
|
-
if (!(0, fs_1.existsSync)(filePath)) {
|
|
705
|
-
throw new Error("File \"".concat(sheet, ".csv\" must be provided"));
|
|
706
|
-
}
|
|
707
|
-
return [4 /*yield*/, fs_1.promises.readFile(filePath, 'utf8')];
|
|
708
|
-
case 2:
|
|
709
|
-
file = _o.sent();
|
|
710
|
-
files[sheet] = index_1.catalog.loadData(file, sheet);
|
|
711
|
-
_o.label = 3;
|
|
712
|
-
case 3:
|
|
713
|
-
_i++;
|
|
714
|
-
return [3 /*break*/, 1];
|
|
715
|
-
case 4:
|
|
716
|
-
files.resources = {};
|
|
717
|
-
_b = (_a = JSON).parse;
|
|
718
|
-
return [4 /*yield*/, fs_1.promises.readFile(path.join(directory, 'resources', 'index.json'), 'utf8')];
|
|
719
|
-
case 5:
|
|
720
|
-
resources = _b.apply(_a, [_o.sent()]);
|
|
721
|
-
_loop_3 = function (id) {
|
|
722
|
-
var filePath, file, _p, header, rows, taxa;
|
|
723
|
-
return __generator(this, function (_q) {
|
|
724
|
-
switch (_q.label) {
|
|
725
|
-
case 0:
|
|
726
|
-
filePath = path.join(directory, 'resources', 'dwc', id.split(':').join('-') + '.csv');
|
|
727
|
-
return [4 /*yield*/, fs_1.promises.readFile(filePath, 'utf8')];
|
|
728
|
-
case 1:
|
|
729
|
-
file = _q.sent();
|
|
730
|
-
_p = (0, csv_1.parseCsv)(file), header = _p[0], rows = _p.slice(1);
|
|
731
|
-
taxa = rows.map(function (row) { return row.reduce(function (object, value, index) {
|
|
732
|
-
object[header[index]] = value;
|
|
733
|
-
return object;
|
|
734
|
-
}, {}); });
|
|
735
|
-
files.resources[id] = { metadata: resources[id], taxa: taxa };
|
|
736
|
-
return [2 /*return*/];
|
|
737
|
-
}
|
|
738
|
-
});
|
|
739
|
-
};
|
|
740
|
-
_c = resources;
|
|
741
|
-
_d = [];
|
|
742
|
-
for (_e in _c)
|
|
743
|
-
_d.push(_e);
|
|
744
|
-
_f = 0;
|
|
745
|
-
_o.label = 6;
|
|
746
|
-
case 6:
|
|
747
|
-
if (!(_f < _d.length)) return [3 /*break*/, 9];
|
|
748
|
-
_e = _d[_f];
|
|
749
|
-
if (!(_e in _c)) return [3 /*break*/, 8];
|
|
750
|
-
id = _e;
|
|
751
|
-
return [5 /*yield**/, _loop_3(id)];
|
|
752
|
-
case 7:
|
|
753
|
-
_o.sent();
|
|
754
|
-
_o.label = 8;
|
|
755
|
-
case 8:
|
|
756
|
-
_f++;
|
|
757
|
-
return [3 /*break*/, 6];
|
|
758
|
-
case 9:
|
|
759
|
-
graph = __spreadArray(__spreadArray([], makeLinkedDataForWorks(files), true), makeLinkedDataForTaxa(files), true);
|
|
760
|
-
for (_g = 0, _h = files.authors.entities; _g < _h.length; _g++) {
|
|
761
|
-
entity = _h[_g];
|
|
762
|
-
graph.push(makeLinkedDataForAuthor(entity));
|
|
763
|
-
}
|
|
764
|
-
for (_j = 0, _k = files.places.entities; _j < _k.length; _j++) {
|
|
765
|
-
entity = _k[_j];
|
|
766
|
-
graph.push(makeLinkedDataForPlace(entity));
|
|
767
|
-
}
|
|
768
|
-
for (_l = 0, _m = files.publishers.entities; _l < _m.length; _l++) {
|
|
769
|
-
entity = _m[_l];
|
|
770
|
-
graph.push(makeLinkedDataForPublisher(entity));
|
|
771
|
-
}
|
|
772
|
-
document = {
|
|
773
|
-
'@context': PREFIXES,
|
|
774
|
-
'@graph': graph
|
|
775
|
-
};
|
|
776
|
-
writeOutput(document, args.values.format);
|
|
777
|
-
return [2 /*return*/];
|
|
778
|
-
}
|
|
610
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
611
|
+
const args = util.parseArgs({
|
|
612
|
+
allowPositionals: true,
|
|
613
|
+
options: {
|
|
614
|
+
format: {
|
|
615
|
+
type: 'string',
|
|
616
|
+
short: 'f',
|
|
617
|
+
default: 'jsonld',
|
|
618
|
+
}
|
|
619
|
+
},
|
|
779
620
|
});
|
|
621
|
+
const directory = path.resolve(args.positionals[0]);
|
|
622
|
+
const files = {};
|
|
623
|
+
for (const sheet of SHEETS) {
|
|
624
|
+
const filePath = path.join(directory, `${sheet}.csv`);
|
|
625
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
626
|
+
throw new Error(`File "${sheet}.csv" must be provided`);
|
|
627
|
+
}
|
|
628
|
+
const file = yield fs_1.promises.readFile(filePath, 'utf8');
|
|
629
|
+
files[sheet] = index_1.catalog.loadData(file, sheet);
|
|
630
|
+
}
|
|
631
|
+
files.resources = {};
|
|
632
|
+
const resources = JSON.parse(yield fs_1.promises.readFile(path.join(directory, 'resources', 'index.json'), 'utf8'));
|
|
633
|
+
for (const id in resources) {
|
|
634
|
+
const filePath = path.join(directory, 'resources', 'dwc', id.split(':').join('-') + '.csv');
|
|
635
|
+
const file = yield fs_1.promises.readFile(filePath, 'utf8');
|
|
636
|
+
const [header, ...rows] = (0, csv_1.parseCsv)(file);
|
|
637
|
+
const taxa = rows.map(row => row.reduce((object, value, index) => {
|
|
638
|
+
object[header[index]] = value;
|
|
639
|
+
return object;
|
|
640
|
+
}, {}));
|
|
641
|
+
files.resources[id] = { metadata: resources[id], taxa };
|
|
642
|
+
}
|
|
643
|
+
const graph = [
|
|
644
|
+
...makeLinkedDataForWorks(files),
|
|
645
|
+
...makeLinkedDataForTaxa(files),
|
|
646
|
+
];
|
|
647
|
+
for (const entity of files.authors.entities) {
|
|
648
|
+
graph.push(makeLinkedDataForAuthor(entity));
|
|
649
|
+
}
|
|
650
|
+
for (const entity of files.places.entities) {
|
|
651
|
+
graph.push(makeLinkedDataForPlace(entity));
|
|
652
|
+
}
|
|
653
|
+
for (const entity of files.publishers.entities) {
|
|
654
|
+
graph.push(makeLinkedDataForPublisher(entity));
|
|
655
|
+
}
|
|
656
|
+
const document = {
|
|
657
|
+
'@context': PREFIXES,
|
|
658
|
+
'@graph': graph
|
|
659
|
+
};
|
|
660
|
+
writeOutput(document, args.values.format);
|
|
780
661
|
});
|
|
781
662
|
}
|
|
782
|
-
main().catch(
|
|
663
|
+
main().catch((error) => {
|
|
783
664
|
console.error(error);
|
|
784
665
|
process.exit(1);
|
|
785
666
|
});
|