gedcom-ts 2.1.0 → 2026.5.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +83 -0
  2. package/README.md +99 -8
  3. package/dist/commons/Act.d.ts +9 -2
  4. package/dist/commons/Person.d.ts +6 -1
  5. package/dist/commons/clonePrimitives.d.ts +17 -0
  6. package/dist/commons/gedcomEventTags.d.ts +7 -0
  7. package/dist/dataset/ReadGedEdit.d.ts +27 -0
  8. package/dist/dataset/cloneModels.d.ts +8 -0
  9. package/dist/dataset/graphOps.d.ts +29 -0
  10. package/dist/dataset/index.d.ts +9 -0
  11. package/dist/dataset/readGedCommands.d.ts +46 -0
  12. package/dist/dataset/readGedMutations.d.ts +12 -0
  13. package/dist/dataset/validation.d.ts +36 -0
  14. package/dist/edit/ActEdit.d.ts +8 -0
  15. package/dist/edit/ActMediaEdit.d.ts +21 -0
  16. package/dist/edit/ActsEdit.d.ts +18 -1
  17. package/dist/edit/GedcomExportOptionsEdit.d.ts +20 -0
  18. package/dist/edit/IndiAttributesEdit.d.ts +38 -0
  19. package/dist/edit/MultimediaFileEdit.d.ts +17 -0
  20. package/dist/edit/NameVariantsEdit.d.ts +43 -0
  21. package/dist/edit/NoteEdit.d.ts +18 -0
  22. package/dist/edit/NotesEdit.d.ts +11 -0
  23. package/dist/edit/PersonEdit.d.ts +20 -0
  24. package/dist/edit/PersonMediaEdit.d.ts +27 -0
  25. package/dist/edit/factories.d.ts +35 -0
  26. package/dist/edit/index.d.ts +14 -0
  27. package/dist/import/PreservedRecordsBuffer.d.ts +21 -0
  28. package/dist/import/ReadGed.d.ts +6 -0
  29. package/dist/import/SplitedInformations.d.ts +7 -1
  30. package/dist/index.cjs +1 -1
  31. package/dist/index.d.ts +3 -3
  32. package/dist/index.mjs +1 -1
  33. package/dist/utils/gedcom/importGedcomNote.d.ts +17 -0
  34. package/dist/utils/gedcom/uriBasename.d.ts +2 -0
  35. package/dist/utils/multimedia/registerTrackedMedia.d.ts +10 -0
  36. package/dist/version.d.ts +1 -1
  37. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -4,6 +4,89 @@ All notable changes of gedcom-ts
4
4
 
5
5
  ## [Unreleased]
6
6
 
7
+ ## [2026.5.0] - 2026-05-15
8
+
9
+ ### Versioning
10
+
11
+ À partir de cette release, le numéro de version du paquet npm et de **`GEDCOM_LIBRARY_VERSION`** (`src/version.ts`, exporté dans `HEAD`.`SOUR`.`VERS`) suit un schéma **CalVer** :
12
+
13
+ - format **`AAAA.M.micro`** (ex. **`2026.5.0`** = mai 2026, première publication de la série) ;
14
+ - remplace l’ancien **semver** (`2.1.0`, `2.0.x`, …) pour les releases applicatives ;
15
+ - la propriété `version` de `package.json` et `GEDCOM_LIBRARY_VERSION` doivent rester **identiques** (vérifié par `tests/version-package-sync.spec.ts`) ;
16
+ - les branches de release peuvent porter le même libellé (ex. `2026.5.0`).
17
+
18
+ Les entrées historiques du changelog conservent leurs numéros semver d’origine.
19
+
20
+ ### Highlights
21
+
22
+ - Nouvelle couche **`src/dataset/`** : mutations du graphe `ReadGed`, opérations famille, validation typée, commandes sûres (`try*` / `CommandResult`) et clones.
23
+ - Extension majeure de la **couche d’édition** (`*Edit`, factories, médias, variants de nom, attributs, options d’export).
24
+ - **Round-trip des notes sous actes** corrigé (import `2 NOTE` / `3 CONT` après `DATE`, ordre d’export `ActLine`).
25
+ - Refactor interne : médias centralisés, buffer des enregistrements préservés, `Person.clone` / `Act.clone`.
26
+
27
+ ### Added
28
+
29
+ #### Dataset (`src/dataset/`)
30
+
31
+ - **`readGedMutations`** : `addPersonToReadGed`, `removePersonFromReadGedByIndi` (mise à jour `mapPersons`, `persons`, lieux, `groupPartners`).
32
+ - **`ReadGedEdit`** / `editReadGed` : `addPerson`, `removePersonByIndi`, `preserved()` → `PreservedTopLevelEdit` (`append`, `insertAt`, `replaceAt`, `removeAt`, `clear`).
33
+ - **`graphOps`** : `nextFamilyId`, `createMarriageFamily`, `linkChildToFamily`, `unlinkChildFromFamily`, `removeFamilyReferencesFromDataset`.
34
+ - **`CreateUnionFamilyOptions`** : `eventTag` sur `createMarriageFamily` / `tryCreateMarriageFamily` (défaut `MARR` ; aussi `ENGA`, `MARB`, `MARC`, `MARL`, `MARS`, `EVEN` + `CreateActInit`, etc.) ; constante **`GEDCOM_7_PAIR_UNION_EVENT_TAGS`**.
35
+ - **`readGedCommands`** : `tryAddPersonToReadGed`, `tryRemovePersonFromReadGedByIndi`, `tryLinkChildToFamily`, `tryUnlinkChildFromFamily`, `tryCreateMarriageFamily` ; `validate*Command` ; **`CommandResult`** / `commandBlockingIssues`.
36
+ - **`validation`** : `ModelConsistencyIssue` avec `code`, `severity` (`error` | `warn`), `validatePerson` / `validateReadGed` ; options `checkMarrParticipants`, `checkDuplicateIndis`, `checkFamcWithoutSpouses`, `checkFamsWithoutSpouses`, `checkDuplicateFamsEntries`, `checkAncestorCycles` ; `assertPersonConsistent` / `assertReadGedConsistent` avec `failOn`.
37
+ - **`cloneModels`** : `clonePerson`, `cloneAct` (délèguent à `Person.clone` / `Act.clone`).
38
+
39
+ #### Import / modèle
40
+
41
+ - **`PreservedRecordsBuffer`** : encapsulation des blocs `0 …` préservés (`SplitGedcom` / `ReadGed.preservedTopLevelRecords`).
42
+ - **`ReadGed.rehydratePlacesFromActs()`** : reconstruction de `placesMap` après édition manuelle du graphe.
43
+ - **`importGedcomNote`** : `createNoteFromGedcomPayload`, `appendGedcomNoteSubline`, `isPersonLevelGedcomLine`, `isActLevelGedcomNoteLine`, `isGedcomNoteContinuationTag`.
44
+ - **`registerTrackedMedia`** : chemins relatifs uniques pour médias personne / acte.
45
+ - **`uriBasename`** : nom de fichier logique depuis une URI média.
46
+ - **`clonePrimitives`** : briques de copie profonde partagées (dates, lieux, notes, médias, variants, attributs).
47
+ - **`Person.clone(newIndi)`**, **`Act.clone()`** sur les classes domaine.
48
+
49
+ #### Fluent edit layer (extensions)
50
+
51
+ - **`factories`** : `createAct`, `createNote`, `createPersonStub`, `createPersonNameVariant`, `createIndiAttribute` (+ types `CreateActInit`, `CreatePersonStubInit`).
52
+ - **`NoteEdit`** / `editNote` ; **`NotesEdit`** : `addNew`, `insertNewAt`, `removeNote`, `indexOfNote`.
53
+ - **`ActMediaEdit`** / **`PersonMediaEdit`** / **`MultimediaFileEdit`** ; **`NameVariantsEdit`** / **`PersonNameVariantEdit`** ; **`IndiAttributesEdit`**.
54
+ - **`ActsEdit`** : `addNew`, `insertNewAt`, `removeAct`, `indexOfAct`.
55
+ - **`ActEdit`** : `notes()`, `multimedia()`, `clearNotes`, `clearMultimedia`.
56
+ - **`PersonEdit`** : `multimedia()`, `nameVariants()`, `attributes()`, `appendFams`, `removeFamsAt`, `removeFamsById`, etc.
57
+ - **`GedcomExportOptionsEdit`** / `editGedcomExportOptions` : `setExtraTopLevelRecords`, `setHeadCopyright`, `setHeadDestination`, `setHeadLanguageTag`, `setHeadSchemaTagDefs`, `clear*`.
58
+
59
+ #### Public API (`src/index.ts`)
60
+
61
+ - Réexport de tout le dataset, des commandes `try*`, des types de validation, `GEDCOM_7_PAIR_UNION_EVENT_TAGS`, `Gedcom7PairUnionEventTag`, `CreateUnionFamilyOptions`, `CommandResult`, etc.
62
+
63
+ #### Tests
64
+
65
+ - `tests/dataset/readGedCommands.spec.ts` : commandes et validations FAM optionnelles.
66
+ - `tests/edit/extendedLayer.spec.ts` : ReadGed, graphe, export options, clones, validation, `removeFamilyReferencesFromDataset`.
67
+ - `tests/edit/editApi.spec.ts` : facades étendues.
68
+ - `tests/commons/Person.spec.ts` / `Act.spec.ts` : notes d’acte (`2 NOTE` / `3 CONT`, ordre après `DATE`).
69
+ - `tests/export/GEDCOM.spec.ts` : round-trip ZIP avec note multi-lignes sous acte.
70
+ - `tests/utils/uriBasename.spec.ts`.
71
+
72
+ #### Documentation
73
+
74
+ - README : section **Dataset editing** (ReadGed, graphe, clones, validation, commandes) ; table `ReadGed` mise à jour (`rehydratePlacesFromActs`, plus de `addPerson` direct sur `ReadGed`).
75
+
76
+ ### Changed
77
+
78
+ - **`ReadGed`** : `addPerson` / `removePersonByIndi` retirés de la classe ; préférer `editReadGed` ou `addPersonToReadGed` / `removePersonFromReadGedByIndi`.
79
+ - **`Person.addMultimedia` / `addMultimediaFromUri`** et **`Act.addMultimedia` / `addMultimediaFromUri`** : délégation à `registerTrackedMedia`.
80
+ - **`SplitGedcom`** : liste préservée via `PreservedRecordsBuffer` au lieu d’un tableau interne brut.
81
+ - **`package.json`** / **`package-lock.json`** : version **`2026.5.0`** (CalVer).
82
+ - CI (`.gitlab-ci.yml`) : ajustements mineurs liés à la release.
83
+
84
+ ### Fixed
85
+
86
+ - **Notes d’acte au réimport** : `parsePersonLine` n’attache plus les `NOTE` de niveau 2 au individu ; `convertToActs` traite `2 NOTE` et `3 CONC`/`CONT` **avant** les blocs `pendingAfterDate` / `Plac` / `Sdate`, ce qui évite de perdre les `3 CONT` lorsque l’export place la note après `DATE` (`ActLine`).
87
+ - **`ReadGedEdit.addPerson`** : discrimination TypeScript correcte sur `CommandResult` (`r.ok === false`).
88
+ - Alignement **`GEDCOM_LIBRARY_VERSION`** ↔ **`package.json`** pour la série `2026.5.0`.
89
+
7
90
  ## [2.1.0] - 2026-05-13
8
91
 
9
92
  ### Highlights
package/README.md CHANGED
@@ -14,6 +14,7 @@ A graphical demo showcasing the public API (import a `.ged` / `.zip`, browse the
14
14
  ## Project
15
15
 
16
16
  - NPM package: [gedcom-ts](https://www.npmjs.com/package/gedcom-ts)
17
+ - **Versioning (CalVer)** : releases use **`AAAA.M.micro`** (e.g. `2026.5.0` = May 2026). The npm `version`, `GEDCOM_LIBRARY_VERSION` (export `HEAD`.`SOUR`.`VERS`), and release branches share the same label. Older changelog entries still refer to semver (`2.1.0`, …). See [CHANGELOG.md](CHANGELOG.md).
17
18
  - **GEDCOM 7 roadmap** (spec gedcom.io, coverage matrix, prioritized gaps): [docs/GEDCOM7-roadmap.md](docs/GEDCOM7-roadmap.md)
18
19
 
19
20
  ## Installation
@@ -118,6 +119,7 @@ Notable members:
118
119
  | `getChildrenOfFamily(familyId)` | Children of a single family. |
119
120
  | `groupPartners()` | Rebuilds `partnersMap` / `childsMap` after editing links. |
120
121
  | `generateUniqueIndi()` | Next free `INDI` number for new persons. |
122
+ | `rehydratePlacesFromActs()` | Rebuilds `placesMap` from act places (e.g. after manual graph edits). Use `editReadGed(readGed).addPerson(...)` to register persons so maps stay coherent. |
121
123
 
122
124
  ```ts
123
125
  import { ReadGed } from "gedcom-ts";
@@ -232,7 +234,7 @@ const occ = new IndiAttribute("OCCU", "Blacksmith", [
232
234
 
233
235
  #### `Act`, `Acts`, `TypeAct`, `ActConstructionOptions`
234
236
 
235
- `Act` models an individual or family event (BIRT, MARR, etc.). `Acts` is the ordered collection on a `Person`. `TypeAct` is the union of every supported GEDCOM 7 event tag (= `Gedcom7EventTag`).
237
+ `Act` models an individual or family event (BIRT, MARR, etc.). `Acts` is the ordered collection on a `Person`. `TypeAct` is the union of every supported GEDCOM 7 event tag (= `Gedcom7EventTag`). Event-level notes live on `act.notes` (`2 NOTE` / `3 CONT` in GEDCOM); they are distinct from `person.notes` (`1 NOTE` on `INDI`) and round-trip through ZIP export/import.
236
238
 
237
239
  ```ts
238
240
  import { Act, Acts, Identifier, type TypeAct } from "gedcom-ts";
@@ -267,9 +269,9 @@ const act = new Act(
267
269
  );
268
270
  ```
269
271
 
270
- #### `GEDCOM_7_ALL_EVENT_TAGS`, `GEDCOM_7_EVENT_SORT_ORDER`, `GEDCOM_7_EVENT_TAG_SET`, `Gedcom7EventTag`
272
+ #### `GEDCOM_7_ALL_EVENT_TAGS`, `GEDCOM_7_EVENT_SORT_ORDER`, `GEDCOM_7_EVENT_TAG_SET`, `GEDCOM_7_PAIR_UNION_EVENT_TAGS`, `Gedcom7EventTag`, `Gedcom7PairUnionEventTag`
271
273
 
272
- Canonical lists of GEDCOM 7 event tags (`INDIVIDUAL_EVENT_STRUCTURE` ∪ `FAMILY_EVENT_STRUCTURE`, LDS ordinances excluded). Use them to build UI selects or guard custom logic.
274
+ Canonical lists of GEDCOM 7 event tags (`INDIVIDUAL_EVENT_STRUCTURE` ∪ `FAMILY_EVENT_STRUCTURE`, LDS ordinances excluded). Use them to build UI selects or guard custom logic. `GEDCOM_7_PAIR_UNION_EVENT_TAGS` lists tags commonly used when creating a family union via `createMarriageFamily` (`ENGA`, `MARB`, `MARC`, `MARL`, `MARR`, `MARS`).
273
275
 
274
276
  ```ts
275
277
  import {
@@ -394,12 +396,78 @@ editDateAct(person.acts.list[0].dateAct!).setExactDate(1900, "JAN", 1);
394
396
 
395
397
  | Helper / class | Purpose |
396
398
  | --- | --- |
397
- | `editPerson(person)` / `PersonEdit` | identity (`setLastname`, `setFirstnames`, `setSex`, `setSosa`), links (`setFamc`, `setFams`, `clearFams`, `appendFams`), name variants (`setNameVariants`), attributes (`setAttributes`), entry points to `acts()` and `notes()`. |
398
- | `editActs(acts)` / `ActsEdit` | `add`, `replaceAt`, `removeAt`, `clear`, `sortByDate`, `at(index)`. |
399
- | `editAct(act)` / `ActEdit` | `setType`, `setIndis`, `setDateAct`, `setSdateAct`, `setPlace`, `setEvenDescription`, `setEvenTypeLabel`, `setEventPhrases` / `appendEventPhrase` / `clearEventPhrases`, plus `setPreservedPrefix` / `Suffix` helpers. |
399
+ | `editPerson(person)` / `PersonEdit` | Identity, `FAMS` / `FAMC` / `removeFams*`, `nameVariants()` / `attributes()` / `multimedia()`, bulk `clear*`, entry points to `acts()` and `notes()`. |
400
+ | `editActs(acts)` / `ActsEdit` | `add`, `addNew`, `insertAt`, `insertNewAt`, `replaceAt`, `removeAt`, `removeAct`, `removeLast`, `clear`, `sortByDate`, `at`, `indexOfAct`. |
401
+ | `editAct(act)` / `ActEdit` | `setType`, `setIndis`, dates, place, EVEN fields, preserved lines, `notes()`, `multimedia()`, `clearNotes`, `clearMultimedia`. |
400
402
  | `editDateAct(dateAct)` / `DateActEdit` | `clear`, `applyGedcomPayload`, `setExactDate`, `setQualified`, `setBetween`, `setFromTo`, `setTime`, `setDatePhrase` / `appendDatePhrase`, `setVerbatimPayload`. |
401
403
  | `editPlace(place)` / `PlaceEdit` | `setFromGedcom7Payload`, `setCity`, `setCounty`, `setState`, `setCountry`, `setPlacPhrase` / `appendPlacPhrase` / `clearPlacPhrase`, `setCoordinates` / `clearCoordinates` / `replaceCoordinateModel`, `clearStructured`. |
402
- | `editNotes(notes)` / `NotesEdit` | `add`, `replaceAt`, `removeAt`, `clear`. |
404
+ | `editNotes(notes)` / `NotesEdit` | `add`, `addNew`, `insertAt`, `insertNewAt`, `replaceAt`, `removeAt`, `removeNote`, `removeLast`, `clear`, `at`, `indexOfNote`. |
405
+
406
+ ### Dataset editing: `ReadGed`, graph, clone, export options, validation
407
+
408
+ Higher-level helpers complement the per-object edit facades:
409
+
410
+ ```ts
411
+ import type { GedcomExportOptions } from "gedcom-ts";
412
+ import {
413
+ createEmptyReadGed,
414
+ createPersonStub,
415
+ DateAct,
416
+ Sex,
417
+ editReadGed,
418
+ editGedcomExportOptions,
419
+ clonePerson,
420
+ cloneAct,
421
+ createMarriageFamily,
422
+ linkChildToFamily,
423
+ removeFamilyReferencesFromDataset,
424
+ addPersonToReadGed,
425
+ validateReadGed,
426
+ Identifier,
427
+ Act,
428
+ } from "gedcom-ts";
429
+
430
+ const readGed = createEmptyReadGed();
431
+ const p = createPersonStub(readGed.generateUniqueIndi(), { sex: Sex.M, firstnames: ["Jean"], lastname: "Dupont" });
432
+ editReadGed(readGed).addPerson(p);
433
+ p.acts.add(new Act(Identifier.BIRT, new DateAct("1900")));
434
+
435
+ editReadGed(readGed).preserved().append("0 @S42@ SOUR Custom");
436
+
437
+ const opts: GedcomExportOptions = {};
438
+ editGedcomExportOptions(opts)
439
+ .setHeadCopyright("© 2026")
440
+ .setExtraTopLevelRecords([...readGed.preservedTopLevelRecords]);
441
+
442
+ const twin = clonePerson(p, readGed.generateUniqueIndi());
443
+ const birthCopy = cloneAct(p.acts.list[0]!);
444
+
445
+ // const fam = createMarriageFamily(readGed, spouseA, spouseB, { dateAct: new DateAct("1 JAN 2000") }, { eventTag: Identifier.ENGA });
446
+ // linkChildToFamily(readGed, child, fam);
447
+ // removeFamilyReferencesFromDataset(readGed, fam);
448
+
449
+ validateReadGed(readGed, {
450
+ checkMarrParticipants: true,
451
+ checkFamcWithoutSpouses: true,
452
+ checkFamsWithoutSpouses: true,
453
+ checkDuplicateFamsEntries: true,
454
+ checkAncestorCycles: true,
455
+ });
456
+ ```
457
+
458
+ #### Commands (invariants before mutation)
459
+
460
+ `tryAddPersonToReadGed`, `tryRemovePersonFromReadGedByIndi`, `tryLinkChildToFamily`, `tryUnlinkChildFromFamily`, and `tryCreateMarriageFamily` return a `CommandResult` (`ok` + `issues` or `value` + optional `warnings`). `editReadGed(...).addPerson` uses these checks internally (throws on blocking errors). For UI or transactional flows, prefer the `try*` APIs and inspect `commandBlockingIssues`.
461
+
462
+ | Export | Role |
463
+ | --- | --- |
464
+ | `editReadGed(readGed)` / `ReadGedEdit` | `addPerson`, `removePersonByIndi`, `preserved()` → `PreservedTopLevelEdit` (`append`, `insertAt`, `replaceAt`, `removeAt`, `clear`) on `preservedTopLevelRecords`. Low-level helpers: `addPersonToReadGed`, `removePersonFromReadGedByIndi`. |
465
+ | `editGedcomExportOptions(opts)` / `GedcomExportOptionsEdit` | Fluent setters for `extraTopLevelRecords`, `headLanguageTag`, `headCopyright`, `headDestination`, `headSchemaTagDefs`. |
466
+ | `clonePerson(person, newIndi)` / `cloneAct(act)` / `person.clone` / `act.clone` | Deep copies for templates or undo stacks. |
467
+ | `nextFamilyId(persons)` | Next internal family id `F`. |
468
+ | `createMarriageFamily`, `linkChildToFamily`, `unlinkChildFromFamily`, `removeFamilyReferencesFromDataset` | Crée une `F` et des actes sur les deux conjoints. 5ᵉ argument : `{ eventTag }` (défaut `MARR`) pour `ENGA`, bans, contrat, `EVEN`+`CreateActInit`, etc. Voir `GEDCOM_7_PAIR_UNION_EVENT_TAGS`. |
469
+ | `validateReadGed`, `assertReadGedConsistent`, `validatePerson`, `assertPersonConsistent` | Typed `code` / `severity` (`error` \| `warn`). Options: `checkMarrParticipants`, `checkDuplicateIndis`, `checkFamcWithoutSpouses`, `checkFamsWithoutSpouses`, `checkDuplicateFamsEntries`, `checkAncestorCycles`. Assertions: `failOn` (default: `error`). |
470
+ | `tryAddPersonToReadGed`, `tryRemovePersonFromReadGedByIndi`, `tryLinkChildToFamily`, `tryUnlinkChildFromFamily`, `tryCreateMarriageFamily`, `commandBlockingIssues` | Command layer with `CommandResult` / `validate*Command` prechecks. |
403
471
 
404
472
  ### Utilities
405
473
 
@@ -479,7 +547,7 @@ const primary = selectPrimaryNameVariant(person.nameVariants);
479
547
 
480
548
  #### `GEDCOM_LIBRARY_VERSION`
481
549
 
482
- The library version embedded in the exported `HEAD`.`SOUR`.`VERS`. Kept aligned with the `version` field of `package.json` (a test enforces it).
550
+ CalVer string embedded in the exported `HEAD`.`SOUR`.`VERS` (same value as `package.json` `version`, e.g. `2026.5.0`). A test (`version-package-sync`) enforces the match on every CI run.
483
551
 
484
552
  ```ts
485
553
  import { GEDCOM_LIBRARY_VERSION } from "gedcom-ts";
@@ -514,6 +582,29 @@ async function importModifyExport(file: File) {
514
582
  }
515
583
  ```
516
584
 
585
+ ## Development
586
+
587
+ ### Local scripts
588
+
589
+ | Script | Role |
590
+ | --- | --- |
591
+ | `npm run lint` | ESLint on the codebase |
592
+ | `npm run test` | Vitest test suite |
593
+ | `npm run build` | Production bundle + `.d.ts` |
594
+ | `npm run tgz` | `build` then `npm pack` (local `.tgz`) |
595
+
596
+ ### GitLab CI (`.gitlab-ci.yml`)
597
+
598
+ Every pipeline runs **`InstallDependencies`** (`npm ci`, `node_modules` artifact) — required by all other jobs.
599
+
600
+ | Job | When it runs |
601
+ | --- | --- |
602
+ | `InstallDependencies` | Always |
603
+ | `Lint`, `Test` | Merge requests and branch pushes (not on `master` after a merge commit titled `Merge…`) |
604
+ | `BuildTgz`, `PublishNpm` | Push to `master` after merge only (`Merge…` commit title) |
605
+
606
+ Typical flow: open an MR from a release branch (e.g. `2026.5.0`) → lint + test run there → after merge to `master`, only package build and npm publish run (quality checks are not repeated).
607
+
517
608
  ## Error handling
518
609
 
519
610
  ```ts
@@ -46,8 +46,13 @@ export declare class Act {
46
46
  * Suffixe `_1`, `_2`, … avant l’extension si le chemin est déjà pris sur cet acte.
47
47
  */
48
48
  addMultimedia(multimediaFile: MultimediaFile, ownerIndi?: number): void;
49
+ /**
50
+ * Média distant (URI) sans fichier local ; `ownerIndi` requis si {@link INDIS} est vide.
51
+ */
52
+ addMultimediaFromUri(sourceUri: string, ownerIndi?: number, objeXrefId?: number | null): void;
49
53
  removeMultimedia(index: number): void;
50
- private mediaRelativePathsInUse;
54
+ /** Copie profonde de l’acte (nouvelle instance, mêmes valeurs). */
55
+ clone(): Act;
51
56
  updateType(typeAct: TypeAct): void;
52
57
  addIndis(INDIS: number[]): void;
53
58
  updatePlace(place: Place | null): void;
@@ -72,7 +77,9 @@ export declare class Acts {
72
77
  export declare class ActsByExtraction extends Acts {
73
78
  extractActsInfo(lines: string[], INDIS: number[], mapFiles: Map<string, File>, objePayloadById?: ReadonlyMap<number, {
74
79
  sourceUri: string;
75
- }>, textualIndiXrefToIndi?: ReadonlyMap<string, number>): void;
80
+ }>, textualIndiXrefToIndi?: ReadonlyMap<string, number>, globalNotes?: Map<number, string[]>, importOptions?: {
81
+ notePointerToId?: ReadonlyMap<string, number>;
82
+ }): void;
76
83
  private convertToActs;
77
84
  private resolveTypeAct;
78
85
  }
@@ -51,8 +51,13 @@ export declare class Person {
51
51
  * Si le même nom existe déjà pour cet individu, suffixe `_1`, `_2`, etc. avant l’extension.
52
52
  */
53
53
  addMultimedia(multimediaFile: MultimediaFile): void;
54
+ /**
55
+ * Média distant (`FILE` / OBJE avec URI) sans fichier local : chemins relatifs uniques comme {@link addMultimedia}.
56
+ */
57
+ addMultimediaFromUri(sourceUri: string, objeXrefId?: number | null): void;
54
58
  deleteMultimedia(path: string): void;
55
- private mediaRelativePathsInUse;
59
+ /** Copie profonde avec un nouvel `INDI` (actes via {@link Act.clone}, notes, médias, variants, attributs). */
60
+ clone(newIndi: number): Person;
56
61
  private createFirstnamesAndLastnameJson;
57
62
  }
58
63
  export declare class TreePerson extends Person {
@@ -0,0 +1,17 @@
1
+ import { DateAct } from "./DateAct";
2
+ import { IndiAttribute } from "./IndiAttribute";
3
+ import { MultimediaFile, MultimediaFiles } from "./MultimediaFile";
4
+ import { Note, Notes } from "./Note";
5
+ import { PersonNameVariant } from "./PersonNameVariant";
6
+ import { Place } from "./Place";
7
+ export declare function cloneDateAct(d: DateAct): DateAct;
8
+ export declare function clonePlace(p: Place): Place;
9
+ export declare function cloneNote(note: Note): Note;
10
+ export declare function cloneNotesColl(notes: Notes): Notes;
11
+ export declare function cloneMultimediaFile(m: MultimediaFile): MultimediaFile;
12
+ export declare function cloneMultimediaBundle(files: readonly MultimediaFile[], relativePathRoot: string): {
13
+ files: MultimediaFiles;
14
+ map: Map<string, MultimediaFile>;
15
+ };
16
+ export declare function cloneNameVariant(v: PersonNameVariant): PersonNameVariant;
17
+ export declare function cloneAttribute(a: IndiAttribute): IndiAttribute;
@@ -5,6 +5,13 @@ import { Identifier } from "./Identifier.enum";
5
5
  */
6
6
  export declare const GEDCOM_7_ALL_EVENT_TAGS: readonly [Identifier.ADOP, Identifier.BAPM, Identifier.BARM, Identifier.BASM, Identifier.BIRT, Identifier.BLES, Identifier.BURI, Identifier.CENS, Identifier.CHR, Identifier.CHRA, Identifier.CONF, Identifier.CREM, Identifier.DEAT, Identifier.EMIG, Identifier.EVEN, Identifier.FCOM, Identifier.GRAD, Identifier.IMMI, Identifier.NATU, Identifier.ORDN, Identifier.PROB, Identifier.RETI, Identifier.WILL, Identifier.ANUL, Identifier.DIV, Identifier.DIVF, Identifier.ENGA, Identifier.MARB, Identifier.MARC, Identifier.MARL, Identifier.MARR, Identifier.MARS];
7
7
  export type Gedcom7EventTag = (typeof GEDCOM_7_ALL_EVENT_TAGS)[number];
8
+ /**
9
+ * Sous-ensemble des tags GEDCOM 7 typiquement utilisés pour lier deux personnes à une même famille `F`
10
+ * (fiançailles, bans, contrat, mariage, etc.). D’autres tags (`EVEN`, …) restent utilisables via
11
+ * {@link CreateUnionFamilyOptions.eventTag} s’ils figurent dans {@link GEDCOM_7_ALL_EVENT_TAGS}.
12
+ */
13
+ export declare const GEDCOM_7_PAIR_UNION_EVENT_TAGS: readonly [Identifier.ENGA, Identifier.MARB, Identifier.MARC, Identifier.MARL, Identifier.MARR, Identifier.MARS];
14
+ export type Gedcom7PairUnionEventTag = (typeof GEDCOM_7_PAIR_UNION_EVENT_TAGS)[number];
8
15
  /** Document order when two acts have no usable sortable date (`Acts.sortByDate`). */
9
16
  export declare const GEDCOM_7_EVENT_SORT_ORDER: readonly Gedcom7EventTag[];
10
17
  export declare const GEDCOM_7_EVENT_TAG_SET: ReadonlySet<string>;
@@ -0,0 +1,27 @@
1
+ import type { ReadGed } from "../import/ReadGed";
2
+ import type { Person } from "../commons/Person";
3
+ /**
4
+ * Édition des blocs `0 …` conservés pour round-trip (voir {@link ReadGed.preservedTopLevelRecords}).
5
+ */
6
+ export declare class PreservedTopLevelEdit {
7
+ private readonly target;
8
+ constructor(target: ReadGed);
9
+ get value(): ReadonlyArray<string>;
10
+ append(block: string): this;
11
+ insertAt(index: number, block: string): this;
12
+ replaceAt(index: number, block: string): this;
13
+ removeAt(index: number): this;
14
+ clear(): this;
15
+ }
16
+ /**
17
+ * Facade d’édition sur un {@link ReadGed} (personnes + enregistrements préservés).
18
+ */
19
+ export declare class ReadGedEdit {
20
+ private readonly target;
21
+ constructor(target: ReadGed);
22
+ get value(): ReadGed;
23
+ addPerson(person: Person): this;
24
+ removePersonByIndi(indi: number): boolean;
25
+ preserved(): PreservedTopLevelEdit;
26
+ }
27
+ export declare function editReadGed(readGed: ReadGed): ReadGedEdit;
@@ -0,0 +1,8 @@
1
+ import type { Act } from "../commons/Act";
2
+ import type { Person } from "../commons/Person";
3
+ /** Copie profonde d’un {@link Act} (nouvelle instance, mêmes valeurs). */
4
+ export declare function cloneAct(act: Act): Act;
5
+ /**
6
+ * Copie profonde d’une {@link Person} avec un nouvel `INDI` (identité, actes, notes, médias, variants, attributs).
7
+ */
8
+ export declare function clonePerson(person: Person, newIndi: number): Person;
@@ -0,0 +1,29 @@
1
+ import type { ReadGed } from "../import/ReadGed";
2
+ import type { TypeAct } from "../commons/Act";
3
+ import { Person } from "../commons/Person";
4
+ import type { CreateActInit } from "../edit/factories";
5
+ /** Prochain identifiant de famille `F` libre d'après les `FAMC` / `FAMS` du jeu. */
6
+ export declare function nextFamilyId(persons: readonly Person[]): number;
7
+ /** Rattache un enfant à une famille (`FAMC`). */
8
+ export declare function linkChildToFamily(readGed: ReadGed, child: Person, familyId: number): void;
9
+ /** Retire le rattachement `FAMC` d'un enfant. */
10
+ export declare function unlinkChildFromFamily(readGed: ReadGed, child: Person): void;
11
+ /**
12
+ * Retire toutes les références à une famille `familyId` : `FAMS` (toutes occurrences) et `FAMC` si égal.
13
+ * Puis {@link ReadGed.groupPartners}.
14
+ */
15
+ export declare function removeFamilyReferencesFromDataset(readGed: ReadGed, familyId: number): void;
16
+ export type CreateUnionFamilyOptions = {
17
+ /**
18
+ * Type d’acte créé sur chaque conjoint pour matérialiser l’union (défaut : {@link Identifier.MARR}).
19
+ * Doit appartenir à {@link GEDCOM_7_EVENT_TAG_SET} (ex. {@link Identifier.ENGA}, ou `EVEN` avec
20
+ * `CreateActInit.construction` pour une union civile / custom).
21
+ */
22
+ eventTag?: TypeAct;
23
+ };
24
+ /**
25
+ * Crée une famille `F` (nouvel id), rattache les deux conjoints en `FAMS` et ajoute le même type d’acte
26
+ * sur chacun (par défaut `MARR`). Voir {@link CreateUnionFamilyOptions} pour fiançailles, bans, etc.
27
+ * @returns l'identifiant interne de famille créé.
28
+ */
29
+ export declare function createMarriageFamily(readGed: ReadGed, spouseA: Person, spouseB: Person, init?: CreateActInit | null, unionOptions?: CreateUnionFamilyOptions | null): number;
@@ -0,0 +1,9 @@
1
+ export { addPersonToReadGed, removePersonFromReadGedByIndi } from "./readGedMutations";
2
+ export { commandBlockingIssues, tryAddPersonToReadGed, tryCreateMarriageFamily, tryLinkChildToFamily, tryRemovePersonFromReadGedByIndi, tryUnlinkChildFromFamily, validateAddPersonCommand, validateCreateMarriageCommand, validateLinkChildCommand, validateUnlinkChildCommand, } from "./readGedCommands";
3
+ export type { CommandFail, CommandOk, CommandResult } from "./readGedCommands";
4
+ export { createMarriageFamily, linkChildToFamily, nextFamilyId, removeFamilyReferencesFromDataset, unlinkChildFromFamily, } from "./graphOps";
5
+ export type { CreateUnionFamilyOptions } from "./graphOps";
6
+ export { PreservedTopLevelEdit, ReadGedEdit, editReadGed } from "./ReadGedEdit";
7
+ export { cloneAct, clonePerson } from "./cloneModels";
8
+ export { assertPersonConsistent, assertReadGedConsistent, validatePerson, validateReadGed, } from "./validation";
9
+ export type { AssertConsistencyOptions, ConsistencySeverity, ModelConsistencyIssue, ModelConsistencyIssueCode, ValidatePersonContext, ValidateReadGedOptions, } from "./validation";
@@ -0,0 +1,46 @@
1
+ import type { ReadGed } from "../import/ReadGed";
2
+ import type { Person } from "../commons/Person";
3
+ import type { CreateActInit } from "../edit/factories";
4
+ import { type CreateUnionFamilyOptions } from "./graphOps";
5
+ import type { ModelConsistencyIssue } from "./validation";
6
+ export type CommandOk<T = void> = {
7
+ ok: true;
8
+ value: T;
9
+ warnings?: ModelConsistencyIssue[];
10
+ };
11
+ export type CommandFail = {
12
+ ok: false;
13
+ issues: ModelConsistencyIssue[];
14
+ };
15
+ export type CommandResult<T = void> = CommandOk<T> | CommandFail;
16
+ /** Filtre les problèmes qui bloquent une commande (`severity === "error"`). */
17
+ export declare function commandBlockingIssues(issues: readonly ModelConsistencyIssue[]): ModelConsistencyIssue[];
18
+ /** Préconditions pour {@link tryAddPersonToReadGed} (sans effet de bord). */
19
+ export declare function validateAddPersonCommand(readGed: ReadGed, person: Person): ModelConsistencyIssue[];
20
+ /**
21
+ * Ajoute une personne au graphe après validation des préconditions.
22
+ * Effets en cas de succès : `mapPersons`, `persons`, lieux, `groupPartners()` (voir {@link addPersonToReadGed}).
23
+ */
24
+ export declare function tryAddPersonToReadGed(readGed: ReadGed, person: Person): CommandResult;
25
+ /**
26
+ * Retire une personne par `INDI`. Si absent, `ok: false` et aucune mutation.
27
+ */
28
+ export declare function tryRemovePersonFromReadGedByIndi(readGed: ReadGed, indi: number): CommandResult;
29
+ /** Préconditions pour rattacher un enfant à une famille. */
30
+ export declare function validateLinkChildCommand(readGed: ReadGed, child: Person, familyId: number): ModelConsistencyIssue[];
31
+ /**
32
+ * Rattache `child.FAMC = familyId` puis `groupPartners()`.
33
+ * Les avertissements (famille sans conjoints) n’empêchent pas la mutation ; ils sont renvoyés dans `warnings`.
34
+ */
35
+ export declare function tryLinkChildToFamily(readGed: ReadGed, child: Person, familyId: number): CommandResult;
36
+ /** Préconditions pour {@link tryUnlinkChildFromFamily}. */
37
+ export declare function validateUnlinkChildCommand(readGed: ReadGed, child: Person): ModelConsistencyIssue[];
38
+ /** Retire `FAMC` sur l’enfant puis `groupPartners()`. */
39
+ export declare function tryUnlinkChildFromFamily(readGed: ReadGed, child: Person): CommandResult;
40
+ /** Préconditions pour {@link tryCreateMarriageFamily}. */
41
+ export declare function validateCreateMarriageCommand(readGed: ReadGed, spouseA: Person, spouseB: Person): ModelConsistencyIssue[];
42
+ /**
43
+ * Crée une union (nouvel id `F`, actes MARR) après validation.
44
+ * @returns l’identifiant de famille en cas de succès.
45
+ */
46
+ export declare function tryCreateMarriageFamily(readGed: ReadGed, spouseA: Person, spouseB: Person, init?: CreateActInit | null, unionOptions?: CreateUnionFamilyOptions | null): CommandResult<number>;
@@ -0,0 +1,12 @@
1
+ import type { ReadGed } from "../import/ReadGed";
2
+ import { Person } from "../commons/Person";
3
+ /**
4
+ * Ajoute une personne au graphe (met à jour `mapPersons`, `persons`, lieux, `groupPartners`).
5
+ * Si `person.INDI` n’est pas défini, un nouvel identifiant unique est attribué.
6
+ */
7
+ export declare function addPersonToReadGed(readGed: ReadGed, person: Person): void;
8
+ /**
9
+ * Retire une personne par `INDI` et purge les références à cet `INDI` dans les actes et notes du jeu.
10
+ * @returns `false` si aucune personne ne correspond.
11
+ */
12
+ export declare function removePersonFromReadGedByIndi(readGed: ReadGed, indi: number): boolean;
@@ -0,0 +1,36 @@
1
+ import type { ReadGed } from "../import/ReadGed";
2
+ import { Person } from "../commons/Person";
3
+ export type ConsistencySeverity = "error" | "warn";
4
+ export type ModelConsistencyIssueCode = "person_missing_indi" | "act_unknown_indi" | "note_unknown_indi" | "marr_missing_spouse_indi" | "duplicate_indi_in_dataset" | "add_person_already_registered" | "add_person_indi_conflict" | "remove_person_not_found" | "link_child_indi_missing" | "link_child_not_bound_to_readged" | "link_child_family_has_no_spouses" | "unlink_child_indi_missing" | "unlink_child_not_bound_to_readged" | "marriage_spouses_same_person" | "marriage_spouses_same_indi" | "marriage_spouse_indi_missing" | "marriage_spouse_not_in_readged" | "famc_family_without_spouses" | "fams_family_without_spouses" | "fams_duplicate_family_id" | "famc_ancestor_cycle";
5
+ export type ModelConsistencyIssue = {
6
+ code: ModelConsistencyIssueCode;
7
+ severity: ConsistencySeverity;
8
+ message: string;
9
+ detail?: unknown;
10
+ };
11
+ export type ValidatePersonContext = {
12
+ knownIndis?: ReadonlySet<number>;
13
+ checkMarrParticipants?: boolean;
14
+ };
15
+ export type ValidateReadGedOptions = ValidatePersonContext & {
16
+ checkDuplicateIndis?: boolean;
17
+ /** `FAMC` pointant vers une famille sans entrée dans `partnersMap` ou liste vide. */
18
+ checkFamcWithoutSpouses?: boolean;
19
+ /** Chaque `FAMS` sans conjoints dans `partnersMap` (souvent import incomplet). */
20
+ checkFamsWithoutSpouses?: boolean;
21
+ /** Même identifiant de famille plusieurs fois dans `FAMS` d’une même personne. */
22
+ checkDuplicateFamsEntries?: boolean;
23
+ /** Cycle dans la remontée `FAMC` → parents (données impossibles biologiquement). */
24
+ checkAncestorCycles?: boolean;
25
+ };
26
+ export type AssertConsistencyOptions = {
27
+ failOn?: ConsistencySeverity;
28
+ };
29
+ /** Contrôles de base sur une personne (INDI, références d’actes). */
30
+ export declare function validatePerson(person: Person, context?: ValidatePersonContext): ModelConsistencyIssue[];
31
+ /** Agrège {@link validatePerson} pour toutes les personnes du graphe, plus les contrôles optionnels sur FAM. */
32
+ export declare function validateReadGed(readGed: ReadGed, options?: ValidateReadGedOptions): ModelConsistencyIssue[];
33
+ /** Lève une erreur si {@link validatePerson} retourne des problèmes selon `failOn` (défaut : seulement `error`). */
34
+ export declare function assertPersonConsistent(person: Person, context?: ValidatePersonContext & AssertConsistencyOptions): void;
35
+ /** Lève une erreur si {@link validateReadGed} retourne des problèmes selon `failOn` (défaut : seulement `error`). */
36
+ export declare function assertReadGedConsistent(readGed: ReadGed, options?: ValidateReadGedOptions & AssertConsistencyOptions): void;
@@ -1,6 +1,8 @@
1
1
  import { Act, type TypeAct } from "../commons/Act";
2
2
  import { DateAct } from "../commons/DateAct";
3
3
  import { Place } from "../commons/Place";
4
+ import { ActMediaEdit } from "./ActMediaEdit";
5
+ import { NotesEdit } from "./NotesEdit";
4
6
  /**
5
7
  * API d’édition cohérente autour d’un {@link Act} existant (mutation in-place).
6
8
  */
@@ -25,5 +27,11 @@ export declare class ActEdit {
25
27
  setPreservedSuffix(lines: readonly string[]): this;
26
28
  appendPreservedSuffixLine(line: string): this;
27
29
  clearPreservedSuffix(): this;
30
+ notes(): NotesEdit;
31
+ multimedia(): ActMediaEdit;
32
+ /** Supprime toutes les notes rattachées à l’acte. */
33
+ clearNotes(): this;
34
+ /** Supprime tous les médias rattachés à l’acte. */
35
+ clearMultimedia(): this;
28
36
  }
29
37
  export declare function editAct(act: Act): ActEdit;
@@ -0,0 +1,21 @@
1
+ import { MultimediaFile } from "../commons/MultimediaFile";
2
+ import type { Act } from "../commons/Act";
3
+ import { MultimediaFileEdit } from "./MultimediaFileEdit";
4
+ /**
5
+ * Médias rattachés à un {@link Act} : délègue à {@link Act.addMultimedia} / {@link Act.removeMultimedia}.
6
+ */
7
+ export declare class ActMediaEdit {
8
+ private readonly target;
9
+ constructor(target: Act);
10
+ get value(): Act;
11
+ /**
12
+ * Crée un {@link MultimediaFile} à partir d'un fichier local, l'ajoute et renvoie sa facade.
13
+ */
14
+ addNewFromFile(file: File, ownerIndi?: number): MultimediaFileEdit;
15
+ addNewFromUri(uri: string, ownerIndi?: number, objeXrefId?: number | null): MultimediaFileEdit;
16
+ add(multimediaFile: MultimediaFile, ownerIndi?: number): this;
17
+ removeAt(index: number): this;
18
+ clear(): this;
19
+ at(index: number): MultimediaFileEdit;
20
+ }
21
+ export declare function editActMedia(act: Act): ActMediaEdit;
@@ -1,5 +1,6 @@
1
- import { Acts } from "../commons/Act";
1
+ import { Act, Acts, type TypeAct } from "../commons/Act";
2
2
  import { ActEdit } from "./ActEdit";
3
+ import { type CreateActInit } from "./factories";
3
4
  /**
4
5
  * API d’édition cohérente autour d’un {@link Acts}.
5
6
  */
@@ -7,7 +8,23 @@ export declare class ActsEdit {
7
8
  private readonly target;
8
9
  constructor(target: Acts);
9
10
  get value(): Acts;
11
+ /**
12
+ * Crée un {@link Act}, l’ajoute en fin de liste et renvoie sa facade d’édition.
13
+ */
14
+ addNew(type: TypeAct, init?: CreateActInit | null): ActEdit;
10
15
  add(act: Parameters<Acts["add"]>[0]): this;
16
+ /** Insère un acte existant à la position donnée (0 = début). */
17
+ insertAt(index: number, act: Act): this;
18
+ /**
19
+ * Crée un acte et l’insère à la position donnée.
20
+ */
21
+ insertNewAt(index: number, type: TypeAct, init?: CreateActInit | null): ActEdit;
22
+ /** Supprime le dernier acte s’il en existe au moins un. */
23
+ removeLast(): this;
24
+ /** Index de l’acte par identité de référence, ou `-1`. */
25
+ indexOfAct(act: Act): number;
26
+ /** Retire l’acte s’il appartient à la liste ; @returns si une entrée a été supprimée. */
27
+ removeAct(act: Act): boolean;
11
28
  replaceAt(index: number, act: Parameters<Acts["updateFromIndex"]>[0]): this;
12
29
  removeAt(index: number): this;
13
30
  clear(): this;
@@ -0,0 +1,20 @@
1
+ import type { GedcomExportOptions } from "../export/GEDCOM";
2
+ /**
3
+ * Mutation in-place des {@link GedcomExportOptions} (export `.ged` / `.zip`).
4
+ */
5
+ export declare class GedcomExportOptionsEdit {
6
+ private readonly target;
7
+ constructor(target: GedcomExportOptions);
8
+ get value(): GedcomExportOptions;
9
+ setExtraTopLevelRecords(lines: readonly string[] | null | undefined): this;
10
+ clearExtraTopLevelRecords(): this;
11
+ setHeadLanguageTag(tag: string | null | undefined): this;
12
+ setHeadCopyright(text: string | null | undefined): this;
13
+ setHeadDestination(dest: string | null | undefined): this;
14
+ setHeadSchemaTagDefs(defs: readonly {
15
+ readonly tag: string;
16
+ readonly uri: string;
17
+ }[] | null | undefined): this;
18
+ clearHeadSchemaTagDefs(): this;
19
+ }
20
+ export declare function editGedcomExportOptions(options: GedcomExportOptions): GedcomExportOptionsEdit;
@@ -0,0 +1,38 @@
1
+ import type { IndiGedcomSubLine } from "../commons/IndiGedcomSubLine";
2
+ import type { IndiAttribute } from "../commons/IndiAttribute";
3
+ /**
4
+ * API d’édition cohérente autour d’un {@link IndiAttribute} existant.
5
+ */
6
+ export declare class IndiAttributeEdit {
7
+ private readonly target;
8
+ constructor(target: IndiAttribute);
9
+ get value(): IndiAttribute;
10
+ setTag(tag: string): this;
11
+ setValue(value: string): this;
12
+ setChildren(children: readonly IndiGedcomSubLine[]): this;
13
+ appendChild(child: IndiGedcomSubLine): this;
14
+ clearChildren(): this;
15
+ }
16
+ export declare function editIndiAttribute(attr: IndiAttribute): IndiAttributeEdit;
17
+ /**
18
+ * Liste d’attributs individuels (`FACT`, `DSCR`, …) sur une {@link Person}.
19
+ */
20
+ export declare class IndiAttributesEdit {
21
+ private readonly target;
22
+ constructor(target: {
23
+ attributes: IndiAttribute[];
24
+ });
25
+ get value(): IndiAttribute[];
26
+ add(attr: IndiAttribute): this;
27
+ addNew(tag: string, value?: string, children?: readonly IndiGedcomSubLine[]): IndiAttributeEdit;
28
+ insertAt(index: number, attr: IndiAttribute): this;
29
+ insertNewAt(index: number, tag: string, value?: string, children?: readonly IndiGedcomSubLine[]): IndiAttributeEdit;
30
+ removeLast(): this;
31
+ replaceAt(index: number, attr: IndiAttribute): this;
32
+ removeAt(index: number): this;
33
+ clear(): this;
34
+ at(index: number): IndiAttributeEdit;
35
+ }
36
+ export declare function editIndiAttributes(person: {
37
+ attributes: IndiAttribute[];
38
+ }): IndiAttributesEdit;