@domorium/validator 1.7.0 → 1.8.0
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/CHANGELOG.md +15 -0
- package/dist/index.cjs.js +2 -2
- package/dist/index.esm.js +72 -49
- package/dist/types/errors.d.ts +2 -0
- package/dist/validator/versionRegistry.d.ts +6 -0
- package/package.json +2 -2
package/dist/index.esm.js
CHANGED
|
@@ -107,7 +107,7 @@ var r = /* @__PURE__ */ function(e) {
|
|
|
107
107
|
})), n;
|
|
108
108
|
}
|
|
109
109
|
}, p = /* @__PURE__ */ function(e) {
|
|
110
|
-
return e.UnknownTag = "VAL001", e.MissingTag = "VAL002", e.MissingValue = "VAL003", e.IncorrectValue = "VAL004", e.ShouldBeSetValue = "VAL005", e.MissingRef = "VAL006", e.ManyOccurrences = "VAL007", e.UndocumentedTag = "VAL008", e.DuplicateDeclaration = "VAL009", e.EmptyEvent = "VAL010", e.UnsupportedVersion = "VAL011", e.UndeterminedVersion = "VAL012", e.SubstitutedVersion = "VAL013", e.ImpossibleDay = "VAL014", e.UnresolvedXref = "unresolved-xref", e.InvalidLevel = "invalid-level", e.Lexer = "LEXER", e.Parser = "PARSER", e;
|
|
110
|
+
return e.UnknownTag = "VAL001", e.MissingTag = "VAL002", e.MissingValue = "VAL003", e.IncorrectValue = "VAL004", e.ShouldBeSetValue = "VAL005", e.MissingRef = "VAL006", e.ManyOccurrences = "VAL007", e.UndocumentedTag = "VAL008", e.DuplicateDeclaration = "VAL009", e.EmptyEvent = "VAL010", e.UnsupportedVersion = "VAL011", e.UndeterminedVersion = "VAL012", e.SubstitutedVersion = "VAL013", e.ImpossibleDay = "VAL014", e.PersonalAncestralFile = "VAL015", e.UnresolvedXref = "unresolved-xref", e.InvalidLevel = "invalid-level", e.Lexer = "LEXER", e.Parser = "PARSER", e;
|
|
111
111
|
}({});
|
|
112
112
|
//#endregion
|
|
113
113
|
//#region src/parser/lineIndex.ts
|
|
@@ -1298,8 +1298,20 @@ function Ze(e) {
|
|
|
1298
1298
|
};
|
|
1299
1299
|
}
|
|
1300
1300
|
function Qe(e) {
|
|
1301
|
-
let t =
|
|
1302
|
-
if (
|
|
1301
|
+
let t = (t) => e?.children.findIndex((e) => e.tokens.TAG?.value === t) ?? -1, n = t("SYST");
|
|
1302
|
+
if (n === -1) return;
|
|
1303
|
+
let r = t("GEDC");
|
|
1304
|
+
return r === -1 || n < r ? e?.children[n] : void 0;
|
|
1305
|
+
}
|
|
1306
|
+
function $e(e) {
|
|
1307
|
+
let t = e.find((e) => e.tokens.TAG?.value === "HEAD"), n = ((t?.children.find((e) => e.tokens.TAG?.value === "GEDC"))?.children.find((e) => e.tokens.TAG?.value === "VERS"))?.tokens.VALUE?.range ?? t?.range ?? Xe, r = Qe(t);
|
|
1308
|
+
if (r) return {
|
|
1309
|
+
kind: "paf",
|
|
1310
|
+
system: r.tokens.VALUE?.value?.trim() ?? "",
|
|
1311
|
+
range: r.tokens.VALUE?.range ?? r.range
|
|
1312
|
+
};
|
|
1313
|
+
let i = b(e);
|
|
1314
|
+
if (!i) {
|
|
1303
1315
|
let { scheme: e, dialect: t, requiresSchmaDeclaration: r } = Ye;
|
|
1304
1316
|
return {
|
|
1305
1317
|
kind: "undetermined",
|
|
@@ -1309,13 +1321,13 @@ function Qe(e) {
|
|
|
1309
1321
|
range: n
|
|
1310
1322
|
};
|
|
1311
1323
|
}
|
|
1312
|
-
let
|
|
1313
|
-
return
|
|
1314
|
-
...
|
|
1324
|
+
let a = Je.find(({ version: e }) => i.startsWith(e));
|
|
1325
|
+
return a ? {
|
|
1326
|
+
...a,
|
|
1315
1327
|
range: n
|
|
1316
1328
|
} : {
|
|
1317
1329
|
kind: "unsupported",
|
|
1318
|
-
version:
|
|
1330
|
+
version: i,
|
|
1319
1331
|
range: n
|
|
1320
1332
|
};
|
|
1321
1333
|
}
|
|
@@ -1326,7 +1338,7 @@ var Z = {
|
|
|
1326
1338
|
months: null,
|
|
1327
1339
|
epochs: null,
|
|
1328
1340
|
keywords: []
|
|
1329
|
-
},
|
|
1341
|
+
}, et = [
|
|
1330
1342
|
"ABT",
|
|
1331
1343
|
"CAL",
|
|
1332
1344
|
"EST",
|
|
@@ -1335,22 +1347,22 @@ var Z = {
|
|
|
1335
1347
|
"BET",
|
|
1336
1348
|
"FROM",
|
|
1337
1349
|
"TO"
|
|
1338
|
-
],
|
|
1350
|
+
], tt = ["FROM", "TO"], nt = {
|
|
1339
1351
|
BET: "AND",
|
|
1340
1352
|
FROM: "TO"
|
|
1341
|
-
},
|
|
1353
|
+
}, rt = [
|
|
1342
1354
|
"GREGORIAN",
|
|
1343
1355
|
"JULIAN",
|
|
1344
1356
|
"HEBREW",
|
|
1345
1357
|
"FRENCH_R"
|
|
1346
|
-
], Q = "GREGORIAN", $ = /^\d+$/u,
|
|
1347
|
-
function
|
|
1358
|
+
], Q = "GREGORIAN", $ = /^\d+$/u, it = ["BCE", "B.C."];
|
|
1359
|
+
function at(e) {
|
|
1348
1360
|
let t = e.split(/\s+/u).filter(Boolean);
|
|
1349
1361
|
return /\s$/u.test(e) ? t : t.slice(0, -1);
|
|
1350
1362
|
}
|
|
1351
|
-
function
|
|
1363
|
+
function ot(e) {
|
|
1352
1364
|
let t = 0, n = Q;
|
|
1353
|
-
e[0] !== void 0 &&
|
|
1365
|
+
e[0] !== void 0 && rt.includes(e[0]) && (n = e[0], t = 1);
|
|
1354
1366
|
let r = e.slice(t);
|
|
1355
1367
|
if (r.length === 0) return {
|
|
1356
1368
|
calendars: t === 0,
|
|
@@ -1359,7 +1371,7 @@ function at(e) {
|
|
|
1359
1371
|
keywords: [],
|
|
1360
1372
|
complete: !1
|
|
1361
1373
|
};
|
|
1362
|
-
if (r.some((e) =>
|
|
1374
|
+
if (r.some((e) => it.includes(e))) return {
|
|
1363
1375
|
...Z,
|
|
1364
1376
|
complete: !0
|
|
1365
1377
|
};
|
|
@@ -1382,20 +1394,20 @@ function at(e) {
|
|
|
1382
1394
|
complete: o
|
|
1383
1395
|
};
|
|
1384
1396
|
}
|
|
1385
|
-
function
|
|
1386
|
-
let n =
|
|
1397
|
+
function st(e, t) {
|
|
1398
|
+
let n = at(e);
|
|
1387
1399
|
if (t === "exact") return n.length === 1 ? {
|
|
1388
1400
|
...Z,
|
|
1389
1401
|
months: Q
|
|
1390
1402
|
} : Z;
|
|
1391
|
-
let r = t === "period" ?
|
|
1403
|
+
let r = t === "period" ? tt : et;
|
|
1392
1404
|
if (n.length === 0) return {
|
|
1393
1405
|
calendars: !0,
|
|
1394
1406
|
months: Q,
|
|
1395
1407
|
epochs: null,
|
|
1396
1408
|
keywords: r
|
|
1397
1409
|
};
|
|
1398
|
-
let i = r.includes(n[0]) ? n[0] : null, a = i === null ? n : n.slice(1), o = i === null ? void 0 :
|
|
1410
|
+
let i = r.includes(n[0]) ? n[0] : null, a = i === null ? n : n.slice(1), o = i === null ? void 0 : nt[i], s = o === void 0 ? -1 : a.indexOf(o), c = ot(s === -1 ? a : a.slice(s + 1));
|
|
1399
1411
|
return {
|
|
1400
1412
|
calendars: c.calendars,
|
|
1401
1413
|
months: c.months,
|
|
@@ -1405,15 +1417,15 @@ function ot(e, t) {
|
|
|
1405
1417
|
}
|
|
1406
1418
|
//#endregion
|
|
1407
1419
|
//#region src/completion/completion.ts
|
|
1408
|
-
var
|
|
1409
|
-
function lt(e) {
|
|
1410
|
-
return e.flatMap((e) => [e, ...lt(e.children)]);
|
|
1411
|
-
}
|
|
1420
|
+
var ct = /^(\d+)\s+(?:@[^\s@]+@\s+)?([A-Z0-9_]*)$/, lt = /^(\d+)\s+(?:@[^\s@]+@\s+)?([A-Z0-9_]+)\s+(.*)$/;
|
|
1412
1421
|
function ut(e) {
|
|
1422
|
+
return e.flatMap((e) => [e, ...ut(e.children)]);
|
|
1423
|
+
}
|
|
1424
|
+
function dt(e) {
|
|
1413
1425
|
let t = /^\{\d+:(\d+|M)\}$/.exec(e);
|
|
1414
1426
|
return t ? t[1] === "M" ? Infinity : Number(t[1]) : null;
|
|
1415
1427
|
}
|
|
1416
|
-
function
|
|
1428
|
+
function ft(e, t) {
|
|
1417
1429
|
let n = e, r = t;
|
|
1418
1430
|
for (; n;) {
|
|
1419
1431
|
if (n.level !== r || !n.tokens.TAG?.value) return !1;
|
|
@@ -1421,12 +1433,12 @@ function dt(e, t) {
|
|
|
1421
1433
|
}
|
|
1422
1434
|
return r === -1;
|
|
1423
1435
|
}
|
|
1424
|
-
function
|
|
1436
|
+
function pt(e, t) {
|
|
1425
1437
|
if (t === 0) return {
|
|
1426
1438
|
parentType: _(""),
|
|
1427
1439
|
siblings: e.nodes
|
|
1428
1440
|
};
|
|
1429
|
-
let n =
|
|
1441
|
+
let n = ut(e.nodes).filter((t) => t.range.start.line <= e.position.line), r = n.find((t) => t.range.start.line === e.position.line), i;
|
|
1430
1442
|
if (r) {
|
|
1431
1443
|
if (r.level !== t || r.parent?.level !== t - 1) return null;
|
|
1432
1444
|
i = r.parent;
|
|
@@ -1441,18 +1453,18 @@ function ft(e, t) {
|
|
|
1441
1453
|
}
|
|
1442
1454
|
}
|
|
1443
1455
|
}
|
|
1444
|
-
if (!i || !
|
|
1456
|
+
if (!i || !ft(i, t - 1)) return null;
|
|
1445
1457
|
let a = new J(e.scheme, e.pointers).getNodeType(i);
|
|
1446
1458
|
return a ? {
|
|
1447
1459
|
parentType: a,
|
|
1448
1460
|
siblings: i.children
|
|
1449
1461
|
} : null;
|
|
1450
1462
|
}
|
|
1451
|
-
function
|
|
1452
|
-
let n =
|
|
1463
|
+
function mt(e, t) {
|
|
1464
|
+
let n = pt(e, t);
|
|
1453
1465
|
if (!n) return [];
|
|
1454
1466
|
let r = Object.entries(e.scheme.substructure[n.parentType] ?? {}).filter(([t, r]) => {
|
|
1455
|
-
let i =
|
|
1467
|
+
let i = dt(r.cardinality);
|
|
1456
1468
|
return i === null || i === Infinity || n.siblings.filter((n) => n.range.start.line !== e.position.line && n.tokens.TAG?.value === t).length < i;
|
|
1457
1469
|
}).map(([t, n]) => ({
|
|
1458
1470
|
label: g(t),
|
|
@@ -1465,7 +1477,7 @@ function pt(e, t) {
|
|
|
1465
1477
|
}));
|
|
1466
1478
|
return [...r, ...i];
|
|
1467
1479
|
}
|
|
1468
|
-
var
|
|
1480
|
+
var ht = {
|
|
1469
1481
|
"date-v7": "value",
|
|
1470
1482
|
date: "value",
|
|
1471
1483
|
"date-period-v7": "period",
|
|
@@ -1473,8 +1485,8 @@ var mt = {
|
|
|
1473
1485
|
"date-exact-v7": "exact",
|
|
1474
1486
|
"date-exact": "exact"
|
|
1475
1487
|
};
|
|
1476
|
-
function
|
|
1477
|
-
let r =
|
|
1488
|
+
function gt(e, t, n) {
|
|
1489
|
+
let r = st(n, t), i = (t) => t === null ? void 0 : e.scheme.calendar[g(t)];
|
|
1478
1490
|
return [
|
|
1479
1491
|
...r.calendars ? Object.keys(e.scheme.calendar) : [],
|
|
1480
1492
|
...Object.keys(i(r.months)?.months ?? {}),
|
|
@@ -1485,13 +1497,13 @@ function ht(e, t, n) {
|
|
|
1485
1497
|
kind: "enum"
|
|
1486
1498
|
}));
|
|
1487
1499
|
}
|
|
1488
|
-
function
|
|
1489
|
-
let i =
|
|
1500
|
+
function _t(e, t, n, r) {
|
|
1501
|
+
let i = pt(e, t);
|
|
1490
1502
|
if (!i) return [];
|
|
1491
1503
|
let a = e.scheme.substructure[i.parentType]?.[g(n)]?.type;
|
|
1492
1504
|
if (!a) return [];
|
|
1493
|
-
let o = new J(e.scheme, e.pointers), s = o.getFieldType(a), c = s.type === null ? void 0 :
|
|
1494
|
-
if (c) return
|
|
1505
|
+
let o = new J(e.scheme, e.pointers), s = o.getFieldType(a), c = s.type === null ? void 0 : ht[s.type];
|
|
1506
|
+
if (c) return gt(e, c, r);
|
|
1495
1507
|
if (s.type === "select" || s.type === "multiselect") return [...new Set(o.getAvailableValues(a) ?? [])].filter(Boolean).map((e) => ({
|
|
1496
1508
|
label: e,
|
|
1497
1509
|
kind: "enum"
|
|
@@ -1505,15 +1517,15 @@ function gt(e, t, n, r) {
|
|
|
1505
1517
|
}
|
|
1506
1518
|
return [];
|
|
1507
1519
|
}
|
|
1508
|
-
function
|
|
1509
|
-
let t = e.lineText.slice(0, e.position.character), n =
|
|
1510
|
-
if (n) return
|
|
1511
|
-
let r =
|
|
1512
|
-
return r ?
|
|
1520
|
+
function vt(e) {
|
|
1521
|
+
let t = e.lineText.slice(0, e.position.character), n = ct.exec(t);
|
|
1522
|
+
if (n) return mt(e, Number(n[1]));
|
|
1523
|
+
let r = lt.exec(t);
|
|
1524
|
+
return r ? _t(e, Number(r[1]), r[2], r[3]) : [];
|
|
1513
1525
|
}
|
|
1514
1526
|
//#endregion
|
|
1515
1527
|
//#region src/document/gedcomDocument.ts
|
|
1516
|
-
var
|
|
1528
|
+
var yt = /* @__PURE__ */ new Set([p.UnresolvedXref, p.UndocumentedTag]), bt = class {
|
|
1517
1529
|
nodes = [];
|
|
1518
1530
|
pointers = /* @__PURE__ */ new Map();
|
|
1519
1531
|
xRefs = /* @__PURE__ */ new Map();
|
|
@@ -1554,13 +1566,24 @@ var vt = /* @__PURE__ */ new Set([p.UnresolvedXref, p.UndocumentedTag]), yt = cl
|
|
|
1554
1566
|
createDocument(e, t = {}) {
|
|
1555
1567
|
let { nodes: n, pointers: r, xrefs: i } = this.parseGedcom(e);
|
|
1556
1568
|
this.nodes = n, this.pointers = r, this.xRefs = i, this.errors.push(...this.validateLevels(n));
|
|
1557
|
-
let a =
|
|
1558
|
-
|
|
1569
|
+
let a = $e(n);
|
|
1570
|
+
if (this.resolution = a, t.fragment && t.dialect && a.kind === "undetermined") return this.applyScheme(n, Ze(t.dialect), t), this;
|
|
1571
|
+
if (a.kind === "undetermined") return this.scheme = a.scheme, this.requiresSchmaDeclaration = a.requiresSchmaDeclaration, this.errors.push({
|
|
1559
1572
|
code: p.UndeterminedVersion,
|
|
1560
1573
|
message: "No GEDCOM version in HEAD.GEDC.VERS, so the file cannot be checked against a specification",
|
|
1561
1574
|
range: a.range,
|
|
1562
1575
|
level: "error"
|
|
1563
|
-
}), this
|
|
1576
|
+
}), this;
|
|
1577
|
+
if (a.kind === "paf") {
|
|
1578
|
+
let e = a.system ? ` (\`1 SYST ${a.system}\`)` : "";
|
|
1579
|
+
return this.errors.push({
|
|
1580
|
+
code: p.PersonalAncestralFile,
|
|
1581
|
+
message: `The header names a system before GEDC${e}, so this is a Personal Ancestral File and is not checked against a GEDCOM specification`,
|
|
1582
|
+
range: a.range,
|
|
1583
|
+
level: "warning"
|
|
1584
|
+
}), this;
|
|
1585
|
+
}
|
|
1586
|
+
return a.kind === "unsupported" ? (this.errors.push({
|
|
1564
1587
|
code: p.UnsupportedVersion,
|
|
1565
1588
|
message: `GEDCOM ${a.version} is not supported, so the file cannot be checked against a specification`,
|
|
1566
1589
|
range: a.range,
|
|
@@ -1577,7 +1600,7 @@ var vt = /* @__PURE__ */ new Set([p.UnresolvedXref, p.UndocumentedTag]), yt = cl
|
|
|
1577
1600
|
let { context: r, errors: i } = le(e, this.requiresSchmaDeclaration, this.scheme);
|
|
1578
1601
|
this.extensions = r, this.errors.push(...i);
|
|
1579
1602
|
let a = new qe(this.pointers, r, n.fragment ?? !1);
|
|
1580
|
-
this.errors.push(...a.validate(this.nodes, _(""), this.scheme)), n.fragment && (this.errors = this.errors.filter((e) => !
|
|
1603
|
+
this.errors.push(...a.validate(this.nodes, _(""), this.scheme)), n.fragment && (this.errors = this.errors.filter((e) => !yt.has(e.code)));
|
|
1581
1604
|
}
|
|
1582
1605
|
validateLevels(e, t = 0) {
|
|
1583
1606
|
let n = [];
|
|
@@ -1623,7 +1646,7 @@ var vt = /* @__PURE__ */ new Set([p.UnresolvedXref, p.UndocumentedTag]), yt = cl
|
|
|
1623
1646
|
return this.resolution && "dialect" in this.resolution ? this.resolution.dialect : void 0;
|
|
1624
1647
|
}
|
|
1625
1648
|
getCompletions(e, t) {
|
|
1626
|
-
return this.scheme ?
|
|
1649
|
+
return this.scheme ? vt({
|
|
1627
1650
|
nodes: this.nodes,
|
|
1628
1651
|
pointers: this.pointers,
|
|
1629
1652
|
scheme: this.scheme,
|
|
@@ -1644,4 +1667,4 @@ var vt = /* @__PURE__ */ new Set([p.UnresolvedXref, p.UndocumentedTag]), yt = cl
|
|
|
1644
1667
|
}
|
|
1645
1668
|
};
|
|
1646
1669
|
//#endregion
|
|
1647
|
-
export {
|
|
1670
|
+
export { bt as GedcomDocument, p as GedcomErrorCode, r as TokenNames };
|
package/dist/types/errors.d.ts
CHANGED
|
@@ -32,6 +32,8 @@ export declare enum GedcomErrorCode {
|
|
|
32
32
|
SubstitutedVersion = "VAL013",
|
|
33
33
|
/** A date naming a day its calendar does not have, such as 31 FEB. */
|
|
34
34
|
ImpossibleDay = "VAL014",
|
|
35
|
+
/** A header naming HEAD.SYST before HEAD.GEDC: the file is PAF. */
|
|
36
|
+
PersonalAncestralFile = "VAL015",
|
|
35
37
|
/** A pointer whose xref names no record of the required type. */
|
|
36
38
|
UnresolvedXref = "unresolved-xref",
|
|
37
39
|
/** A line whose level cannot follow the line above it. */
|
|
@@ -20,6 +20,12 @@ export type VersionResolution = ({
|
|
|
20
20
|
kind: "unsupported";
|
|
21
21
|
version: string;
|
|
22
22
|
range: Range;
|
|
23
|
+
}
|
|
24
|
+
/** The payload of HEAD.SYST, which is the program that wrote the file. */
|
|
25
|
+
| {
|
|
26
|
+
kind: "paf";
|
|
27
|
+
system: string;
|
|
28
|
+
range: Range;
|
|
23
29
|
} | ({
|
|
24
30
|
kind: "undetermined";
|
|
25
31
|
range: Range;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@domorium/validator",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.8.0",
|
|
4
4
|
"description": "GEDCOM 5.5.1 and 7.0 parser and validator",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"gedcom",
|
|
@@ -61,6 +61,6 @@
|
|
|
61
61
|
"ts-brand": "^0.2.0"
|
|
62
62
|
},
|
|
63
63
|
"devDependencies": {
|
|
64
|
-
"tsx": "^4.23.
|
|
64
|
+
"tsx": "^4.23.12"
|
|
65
65
|
}
|
|
66
66
|
}
|