@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/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 = 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 = b(e);
1302
- if (!r) {
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 i = Je.find(({ version: e }) => r.startsWith(e));
1313
- return i ? {
1314
- ...i,
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: r,
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
- }, $e = [
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
- ], et = ["FROM", "TO"], tt = {
1350
+ ], tt = ["FROM", "TO"], nt = {
1339
1351
  BET: "AND",
1340
1352
  FROM: "TO"
1341
- }, nt = [
1353
+ }, rt = [
1342
1354
  "GREGORIAN",
1343
1355
  "JULIAN",
1344
1356
  "HEBREW",
1345
1357
  "FRENCH_R"
1346
- ], Q = "GREGORIAN", $ = /^\d+$/u, rt = ["BCE", "B.C."];
1347
- function it(e) {
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 at(e) {
1363
+ function ot(e) {
1352
1364
  let t = 0, n = Q;
1353
- e[0] !== void 0 && nt.includes(e[0]) && (n = e[0], t = 1);
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) => rt.includes(e))) return {
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 ot(e, t) {
1386
- let n = it(e);
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" ? et : $e;
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 : tt[i], s = o === void 0 ? -1 : a.indexOf(o), c = at(s === -1 ? a : a.slice(s + 1));
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 st = /^(\d+)\s+(?:@[^\s@]+@\s+)?([A-Z0-9_]*)$/, ct = /^(\d+)\s+(?:@[^\s@]+@\s+)?([A-Z0-9_]+)\s+(.*)$/;
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 dt(e, t) {
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 ft(e, t) {
1436
+ function pt(e, t) {
1425
1437
  if (t === 0) return {
1426
1438
  parentType: _(""),
1427
1439
  siblings: e.nodes
1428
1440
  };
1429
- let n = lt(e.nodes).filter((t) => t.range.start.line <= e.position.line), r = n.find((t) => t.range.start.line === e.position.line), i;
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 || !dt(i, t - 1)) return null;
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 pt(e, t) {
1452
- let n = ft(e, t);
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 = ut(r.cardinality);
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 mt = {
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 ht(e, t, n) {
1477
- let r = ot(n, t), i = (t) => t === null ? void 0 : e.scheme.calendar[g(t)];
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 gt(e, t, n, r) {
1489
- let i = ft(e, t);
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 : mt[s.type];
1494
- if (c) return ht(e, c, r);
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 _t(e) {
1509
- let t = e.lineText.slice(0, e.position.character), n = st.exec(t);
1510
- if (n) return pt(e, Number(n[1]));
1511
- let r = ct.exec(t);
1512
- return r ? gt(e, Number(r[1]), r[2], r[3]) : [];
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 vt = /* @__PURE__ */ new Set([p.UnresolvedXref, p.UndocumentedTag]), yt = class {
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 = Qe(n);
1558
- return this.resolution = a, t.fragment && t.dialect && a.kind === "undetermined" ? (this.applyScheme(n, Ze(t.dialect), t), this) : a.kind === "undetermined" ? (this.scheme = a.scheme, this.requiresSchmaDeclaration = a.requiresSchmaDeclaration, this.errors.push({
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) : a.kind === "unsupported" ? (this.errors.push({
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) => !vt.has(e.code)));
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 ? _t({
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 { yt as GedcomDocument, p as GedcomErrorCode, r as TokenNames };
1670
+ export { bt as GedcomDocument, p as GedcomErrorCode, r as TokenNames };
@@ -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.7.0",
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.1"
64
+ "tsx": "^4.23.12"
65
65
  }
66
66
  }