@domorium/validator 1.5.0 → 1.7.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 CHANGED
@@ -2,6 +2,52 @@
2
2
 
3
3
  All notable changes to `@domorium/validator` are documented here.
4
4
 
5
+ ## 1.7.0 - 2026-08-13
6
+
7
+ - **A date payload offers completions, and they depend on where the cursor is.**
8
+ Typing one got no help at all, in a format where the help is most needed. The
9
+ start of a value offers the calendars, the modifiers and the months; after a
10
+ number, the months it could still take and the epoch it could already be;
11
+ after `BET`'s first date, `AND`; after `FROM`'s, `TO`. An exact date is offered
12
+ months alone, since its grammar admits no calendar and no epoch.
13
+ - **The months offered are the ones the calendar in force actually has.**
14
+ a cursor after `HEBREW 1` offers `TSH` through `ELL`, one after `FRENCH_R`
15
+ offers `VEND` through `COMP`, and the twelve a user knows by heart are not among them. This is the
16
+ case the feature is for.
17
+ - GEDCOM 7 only. 5.5.1 keeps its months in a regular expression and its
18
+ `calendar` section is empty, so there is nothing there to offer from.
19
+
20
+ - **A date naming a day the calendar does not have is reported.** `31 FEB 1900`,
21
+ `31 APR 1880`, `0 JAN` and `99 JAN` were all accepted: the grammar gives a day
22
+ as one or two digits, and nothing looked at the month it belongs to. Each now
23
+ carries `VAL014` saying which day was named and how many the month has. So does
24
+ `29 FEB 1900` — a year divisible by 100 and not by 400 has no 29th — while
25
+ `29 FEB 2000` and `29 FEB 2024` stay quiet.
26
+ - The check is separate from the grammar and reported with a code of its own,
27
+ because `31 FEB 1900` _is_ a date: telling its author it is not one would say
28
+ the wrong thing about a value they can see is a date.
29
+ - **A Julian date is judged by the Julian rule**, which keeps every fourth year
30
+ leap with no exception for centuries, so `JULIAN 29 FEB 1700` is accepted where
31
+ the same day in the Gregorian calendar is not. `HEBREW` and `FRENCH_R` have
32
+ months of their own and are not judged by anyone else's calendar. Both dialects
33
+ are covered, including 5.5.1's `@#DJULIAN@` escape.
34
+ - A phrase is removed before a value is read as a date, so
35
+ `INT 1900 (born 31 FEB by the old reckoning)` reports nothing.
36
+
37
+ ## 1.6.0 - 2026-08-12
38
+
39
+ - **A fragment can be checked without being told it is not a file.** Text that is
40
+ part of a document rather than one of its own — a block pasted into a note, an
41
+ example in documentation, a selection — was judged as a whole file, so the one
42
+ thing certainly not the author's mistake was the first thing reported, and
43
+ nothing after it was read at all. `createDocument(text, { fragment: true,
44
+ dialect })` reads the lines and goes quiet only about what the boundary caused:
45
+ the missing header and trailer, a pointer leaving the text, an extension tag
46
+ with no `HEAD.SCHMA` to declare it in. An unknown tag, a payload of the wrong
47
+ type and a level that cannot follow the line above are still reported.
48
+ - `dialect` is named by the caller because a fragment carries no
49
+ `HEAD.GEDC.VERS`; without one there are still no rules to read it by.
50
+
5
51
  ## 1.5.0 - 2026-08-10
6
52
 
7
53
  - **The GEDCOM version is resolved against a table by longest match, and a
package/README.md CHANGED
@@ -25,6 +25,23 @@ const document = new GedcomDocument().createDocument(gedcomString);
25
25
  const errors = document.getErrors();
26
26
  ```
27
27
 
28
+ ## Fragments
29
+
30
+ A fenced block in a note, an example in documentation, a selection: text that is
31
+ part of a document rather than one of its own.
32
+
33
+ ```typescript
34
+ const block = new GedcomDocument().createDocument(text, {
35
+ fragment: true,
36
+ dialect: "7.0",
37
+ });
38
+ ```
39
+
40
+ What goes quiet is what the boundary caused — the header and trailer, a pointer
41
+ leaving the text, an extension tag with no `HEAD.SCHMA` to declare it in.
42
+ Everything else is still read. `dialect` is needed because a fragment carries no
43
+ `HEAD.GEDC.VERS`.
44
+
28
45
  ## Diagnostics
29
46
 
30
47
  `getErrors()` returns `GedcomError[]`:
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Which part of a date the cursor is in. A flat list would be worse than
3
+ * nothing here: the months worth offering depend on the calendar named a few
4
+ * tokens earlier, and the keywords depend on what the value opened with.
5
+ */
6
+ export type DateGrammar = "value" | "period" | "exact";
7
+ export interface DateSlot {
8
+ /** A calendar may be named here. */
9
+ calendars: boolean;
10
+ /** Whose months may be named here, or null where none may. */
11
+ months: string | null;
12
+ /** Whose epochs may be named here, or null where none may. */
13
+ epochs: string | null;
14
+ /** Bare words the grammar allows here. */
15
+ keywords: string[];
16
+ }
17
+ export declare function dateSlot(typed: string, grammar: DateGrammar): DateSlot;
@@ -3,6 +3,12 @@ import { ASTNode, ASTToken } from "../parser";
3
3
  import { type GedcomDialect, type VersionResolution } from "../validator/versionRegistry";
4
4
  import { type GedcomCompletion } from "../completion/completion";
5
5
  import type { Position } from "../types/position";
6
+ export interface CreateDocumentOptions {
7
+ /** Text that is part of a document rather than one of its own. */
8
+ fragment?: boolean;
9
+ /** A fragment carries no header, so the rules are named rather than read. */
10
+ dialect?: GedcomDialect;
11
+ }
6
12
  export declare class GedcomDocument {
7
13
  private nodes;
8
14
  pointers: Map<string, ASTNode[]>;
@@ -13,7 +19,8 @@ export declare class GedcomDocument {
13
19
  private requiresSchmaDeclaration;
14
20
  private extensions;
15
21
  private parseGedcom;
16
- createDocument(text: string): GedcomDocument;
22
+ createDocument(text: string, options?: CreateDocumentOptions): GedcomDocument;
23
+ private applyScheme;
17
24
  private validateLevels;
18
25
  getLabel(node: ASTNode): string | undefined;
19
26
  getPointerTargetTag(node: ASTNode): string | undefined;