@treeviz/familysearch-sdk 2.0.7 → 2.0.9

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.
@@ -1,4 +1,4 @@
1
- import { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from './index-CKi9wd-C.js';
1
+ import { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from './tree-changes-e0UMhVha.cjs';
2
2
 
3
3
  /**
4
4
  * FamilySearch Tree API
@@ -1,4 +1,4 @@
1
- import { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from './index-CLkFtjZD.cjs';
1
+ import { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from './tree-changes-CFwJtBcK.js';
2
2
 
3
3
  /**
4
4
  * FamilySearch Tree API
package/dist/index.cjs CHANGED
@@ -1668,6 +1668,10 @@ __export(tree_exports, {
1668
1668
  });
1669
1669
 
1670
1670
  // src/api/tree/persons.ts
1671
+ var PERSON_WRITE_HEADERS = {
1672
+ "Content-Type": "application/x-fs-v1+json",
1673
+ Accept: "application/x-fs-v1+json"
1674
+ };
1671
1675
  async function readPerson(sdk, personId) {
1672
1676
  try {
1673
1677
  const response = await sdk.get(
@@ -1700,7 +1704,7 @@ async function readPersonWithDetails(sdk, personId, options = {}) {
1700
1704
  }
1701
1705
  async function createPerson(sdk, person, reason) {
1702
1706
  try {
1703
- const headers = {};
1707
+ const headers = { ...PERSON_WRITE_HEADERS };
1704
1708
  if (reason) {
1705
1709
  headers["X-Reason"] = reason;
1706
1710
  }
@@ -1717,7 +1721,7 @@ async function createPerson(sdk, person, reason) {
1717
1721
  }
1718
1722
  async function updatePerson(sdk, personId, person, reason) {
1719
1723
  try {
1720
- const headers = {};
1724
+ const headers = { ...PERSON_WRITE_HEADERS };
1721
1725
  if (reason) {
1722
1726
  headers["X-Reason"] = reason;
1723
1727
  }
@@ -6064,6 +6068,16 @@ var PedigreeAPI = class {
6064
6068
  }
6065
6069
  };
6066
6070
 
6071
+ // src/utils/headers.ts
6072
+ var isLatin1 = (value) => [...value].every((char) => char.charCodeAt(0) <= 255);
6073
+ var toLatin1HeaderValue = (value) => [...value].map((char) => {
6074
+ if (char.charCodeAt(0) <= 255) {
6075
+ return char;
6076
+ }
6077
+ const stripped = char.normalize("NFKD").replace(/\p{M}/gu, "");
6078
+ return stripped && isLatin1(stripped) ? stripped : "?";
6079
+ }).join("");
6080
+
6067
6081
  // src/client.ts
6068
6082
  var ENVIRONMENT_CONFIGS = {
6069
6083
  production: {
@@ -6204,6 +6218,9 @@ var FamilySearchSDK = class {
6204
6218
  if (this.appKey) {
6205
6219
  headers["X-FS-App-Key"] = this.appKey;
6206
6220
  }
6221
+ for (const key of Object.keys(headers)) {
6222
+ headers[key] = toLatin1HeaderValue(headers[key]);
6223
+ }
6207
6224
  this.logger.log(
6208
6225
  `[FamilySearch SDK] ${options.method || "GET"} ${fullUrl}`
6209
6226
  );
@@ -6218,7 +6235,7 @@ var FamilySearchSDK = class {
6218
6235
  });
6219
6236
  let data;
6220
6237
  const contentType = response.headers.get("content-type");
6221
- if (contentType && contentType.includes("application/json")) {
6238
+ if (contentType && contentType.includes("json")) {
6222
6239
  try {
6223
6240
  data = await response.json();
6224
6241
  } catch (error) {
@@ -6374,6 +6391,40 @@ function resetFamilySearchSDK() {
6374
6391
  sdkInstance = null;
6375
6392
  }
6376
6393
 
6394
+ // src/places/gazetteer-id.ts
6395
+ var numericPlaceIdFromRef = (ref) => {
6396
+ if (!ref) {
6397
+ return void 0;
6398
+ }
6399
+ if (ref.includes("/places/description/") || ref.includes("ark:/")) {
6400
+ return void 0;
6401
+ }
6402
+ const match = ref.match(/\/places\/(\d+)/);
6403
+ return match?.[1];
6404
+ };
6405
+ var extractGazetteerPlaceId = (place) => {
6406
+ const persistent = place.identifiers?.["http://gedcomx.org/Persistent"]?.[0];
6407
+ const fromPersistent = numericPlaceIdFromRef(persistent);
6408
+ if (fromPersistent) {
6409
+ return fromPersistent;
6410
+ }
6411
+ return numericPlaceIdFromRef(place.place?.description);
6412
+ };
6413
+ var familySearchResearchPlaceUrl = (placeId, baseUrl = "https://www.familysearch.org") => `${baseUrl}/en/research/places/?focusedId=${placeId}`;
6414
+ var pickBestPlaceSearchResult = (results, query) => {
6415
+ if (results.length === 0) {
6416
+ return void 0;
6417
+ }
6418
+ const town = query.split(",")[0]?.trim().toLowerCase();
6419
+ if (!town) {
6420
+ return results[0];
6421
+ }
6422
+ const label = (result) => (result.fullName || result.name || result.title || "").toLowerCase();
6423
+ return results.find(
6424
+ (result) => label(result) === town || label(result).startsWith(`${town},`)
6425
+ ) || results.find((result) => label(result).includes(town)) || results[0];
6426
+ };
6427
+
6377
6428
  // src/utils/gedcom-converter.ts
6378
6429
  function transformFamilySearchUrl(url) {
6379
6430
  if (url.includes("/platform/tree/persons/https://")) {
@@ -7341,6 +7392,8 @@ exports.createErrorFromResponse = createErrorFromResponse;
7341
7392
  exports.createFamilySearchSDK = createFamilySearchSDK;
7342
7393
  exports.createNetworkError = createNetworkError;
7343
7394
  exports.exchangeCodeForToken = exchangeCodeForToken;
7395
+ exports.extractGazetteerPlaceId = extractGazetteerPlaceId;
7396
+ exports.familySearchResearchPlaceUrl = familySearchResearchPlaceUrl;
7344
7397
  exports.fetchMultiplePersons = fetchMultiplePersons;
7345
7398
  exports.fetchPedigree = fetchPedigree;
7346
7399
  exports.generateOAuthState = generateOAuthState;
@@ -7352,8 +7405,10 @@ exports.getTokenStorageKey = getTokenStorageKey;
7352
7405
  exports.getUserInfo = getUserInfo;
7353
7406
  exports.initFamilySearchSDK = initFamilySearchSDK;
7354
7407
  exports.isRetryableError = isRetryableError;
7408
+ exports.numericPlaceIdFromRef = numericPlaceIdFromRef;
7355
7409
  exports.openOAuthPopup = openOAuthPopup;
7356
7410
  exports.parseCallbackParams = parseCallbackParams;
7411
+ exports.pickBestPlaceSearchResult = pickBestPlaceSearchResult;
7357
7412
  exports.readCurrentUser = readCurrentUser2;
7358
7413
  exports.readPlaceAttributes = readPlaceAttributes;
7359
7414
  exports.readPlaceChildren = readPlaceChildren;
@@ -7372,6 +7427,7 @@ exports.searchParentPlaces = searchParentPlaces;
7372
7427
  exports.searchPlaces = searchPlaces;
7373
7428
  exports.storeOAuthState = storeOAuthState;
7374
7429
  exports.storeTokens = storeTokens;
7430
+ exports.toLatin1HeaderValue = toLatin1HeaderValue;
7375
7431
  exports.transformFamilySearchUrl = transformFamilySearchUrl;
7376
7432
  exports.validateAccessToken = validateAccessToken;
7377
7433
  exports.validateOAuthState = validateOAuthState;
package/dist/index.d.cts CHANGED
@@ -1,10 +1,11 @@
1
- import { bt as GenealogyOtherAPI, bu as GenealogyPersonsAPI, bv as GenealogyRelationshipsAPI, bw as GenealogySourcesAPI, bx as TreesAPI, by as createGenealogyPerson, bz as createGenealogySourceDescription, bA as createGenealogyTree, bB as deleteGenealogyConclusion, bC as deleteGenealogyPerson, bD as deleteGenealogyRelationship, bE as deleteGenealogySourceDescription, bF as deleteGenealogyTree, bG as readGenealogyBulkMatch, bH as readGenealogyNote, bI as readGenealogyPerson, bJ as readGenealogyPersonMatches, bK as readGenealogyPersons, bL as readGenealogySourceDescription, bM as readGenealogyTree, bN as readGenealogyTrees, bO as restoreGenealogyPerson, bP as updateGenealogyPerson, bQ as updateGenealogyRelationship, bR as updateGenealogySourceDescription, bS as updateGenealogyTree, bT as DatesAPI, bU as NamesAPI, bV as PlaceSearchQuery, bW as PlacesAPI, bX as VocabulariesAPI, bY as checkPlaceIsChild, bZ as getNameScript, b_ as normalizeDate, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, ca as readVocabularies, cb as readVocabularyConcept, cc as readVocabularyConcepts, cd as searchParentPlaces, ce as searchPlaces, cf as segmentAName } from './index-CLkFtjZD.cjs';
2
- export { cg as DateStandardizationResponse, ch as ENVIRONMENT_CONFIGS, ci as FamilySearchPlace, cj as FamilySearchSDK, ck as FamilySearchUser, cl as MemoriesAPI, cm as MemoryArtifact, cn as MemoryComment, co as MemoryPersona, cp as MemoryPersonaResponse, cq as MemoryPersonasResponse, cr as MemoryWithCommentsResponse, cs as NameScriptResponse, ct as NameSegment, cu as NameSegmentsResponse, cv as PedigreeAPI, cw as PersonMemoriesResponse, cx as PlaceDescription, cy as PlaceDetailsResponse, cz as PlaceSearchResponse, cA as PlaceSearchResult, cB as StandardizedDate, cC as UserAPI, cD as UserMemoriesResponse, cE as VocabAPI, cF as VocabulariesResponse, cG as VocabularyConceptDetail, cH as VocabularyConceptResponse, cI as VocabularyConceptsResponse, cJ as VocabularyMetadata, cK as createFamilySearchSDK, cL as fetchMultiplePersons, cM as fetchPedigree, cN as getFamilySearchSDK, cO as initFamilySearchSDK, cP as readCurrentUser, cQ as resetFamilySearchSDK } from './index-CLkFtjZD.cjs';
1
+ import { bt as GenealogyOtherAPI, bu as GenealogyPersonsAPI, bv as GenealogyRelationshipsAPI, bw as GenealogySourcesAPI, bx as TreesAPI, by as createGenealogyPerson, bz as createGenealogySourceDescription, bA as createGenealogyTree, bB as deleteGenealogyConclusion, bC as deleteGenealogyPerson, bD as deleteGenealogyRelationship, bE as deleteGenealogySourceDescription, bF as deleteGenealogyTree, bG as readGenealogyBulkMatch, bH as readGenealogyNote, bI as readGenealogyPerson, bJ as readGenealogyPersonMatches, bK as readGenealogyPersons, bL as readGenealogySourceDescription, bM as readGenealogyTree, bN as readGenealogyTrees, bO as restoreGenealogyPerson, bP as updateGenealogyPerson, bQ as updateGenealogyRelationship, bR as updateGenealogySourceDescription, bS as updateGenealogyTree, bT as DatesAPI, bU as NamesAPI, bV as PlaceSearchQuery, bW as PlacesAPI, bX as VocabulariesAPI, bY as checkPlaceIsChild, bZ as getNameScript, b_ as normalizeDate, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, ca as readVocabularies, cb as readVocabularyConcept, cc as readVocabularyConcepts, cd as searchParentPlaces, ce as searchPlaces, cf as segmentAName } from './tree-changes-e0UMhVha.cjs';
2
+ export { cg as DateStandardizationResponse, ch as ENVIRONMENT_CONFIGS, ci as FamilySearchPlace, cj as FamilySearchSDK, ck as FamilySearchUser, cl as MemoriesAPI, cm as MemoryArtifact, cn as MemoryComment, co as MemoryPersona, cp as MemoryPersonaResponse, cq as MemoryPersonasResponse, cr as MemoryWithCommentsResponse, cs as NameScriptResponse, ct as NameSegment, cu as NameSegmentsResponse, cv as PedigreeAPI, cw as PersonMemoriesResponse, cx as PlaceDescription, cy as PlaceDetailsResponse, cz as PlaceSearchResponse, cA as PlaceSearchResult, cB as StandardizedDate, cC as UserAPI, cD as UserMemoriesResponse, cE as VocabAPI, cF as VocabulariesResponse, cG as VocabularyConceptDetail, cH as VocabularyConceptResponse, cI as VocabularyConceptsResponse, cJ as VocabularyMetadata, cK as createFamilySearchSDK, cL as fetchMultiplePersons, cM as fetchPedigree, cN as getFamilySearchSDK, cO as initFamilySearchSDK, cP as readCurrentUser, cQ as resetFamilySearchSDK } from './tree-changes-e0UMhVha.cjs';
3
3
  import { F as FamilySearchApiResponse } from './index-0PpnEPuZ.cjs';
4
4
  export { E as EnvironmentConfig, a as FamilySearchApiError, b as FamilySearchEnvironment, c as FamilySearchSDKConfig, O as OAUTH_ENDPOINTS, d as OAUTH_STORAGE_KEYS, e as OAuthAPI, f as OAuthConfig, g as OAuthEndpoints, h as OAuthStateValidation, i as OAuthTokenResponse, P as ProgressCallback, R as RateLimiterConfig, S as SDKLogger, j as buildAuthorizationUrl, k as clearAllTokens, l as clearStoredTokens, m as exchangeCodeForToken, n as generateOAuthState, o as getOAuthEndpoints, p as getStoredAccessToken, q as getStoredRefreshToken, r as getTokenStorageKey, s as getUserInfo, t as openOAuthPopup, u as parseCallbackParams, v as refreshAccessToken, w as storeOAuthState, x as storeTokens, y as validateAccessToken, z as validateOAuthState } from './index-0PpnEPuZ.cjs';
5
5
  export { A as AttachSourceInput, a as AttachSourceResponse, C as ChangeEntry, b as ChildAndParentsRelationship, c as CreateChildAndParentsRelationshipInput, d as CreateCoupleRelationshipInput, e as CreatePersonResponse, f as CreateRelationshipResponse, D as DeletePersonResponse, g as Discussion, h as DiscussionComment, E as EnhancedPedigreeData, i as EnhancedPerson, F as FamilySearchPerson, M as MatchesResponse, N as NameForm, j as Note, k as NoteInput, l as NoteResponse, P as PedigreeData, m as PedigreeResponse, n as PersonChangeHistoryResponse, o as PersonData, p as PersonDiscussionsResponse, q as PersonDisplay, r as PersonFact, s as PersonInput, t as PersonMatchInput, u as PersonMatchOptions, v as PersonMergeAnalysis, w as PersonMergeInput, x as PersonMergeResponse, y as PersonNotesResponse, z as PersonPortrait, B as PersonPortraitsResponse, G as PersonSearchResponse, H as PersonSearchResult, I as PersonSourcesResponse, J as PersonWithRelationships, R as Relationship, K as RelationshipDetails, S as SourceDescription, L as SourceDescriptionDetail, O as SourceDescriptionResponse, Q as SourceDescriptionsResponse, T as SourceReference, U as TreePersonMatchEntry, V as TreePersonMatchesOptions, W as TreePersonMatchesResponse, X as UpdatePersonResponse, Y as UpdateRelationshipResponse } from './tree-D7X-beAQ.cjs';
6
- export { GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, transformFamilySearchUrl } from './utils/index.cjs';
7
- export { i as TreeAPI } from './index-BMAcJBZJ.cjs';
6
+ export { FamilySearchPlacePayload, extractGazetteerPlaceId, familySearchResearchPlaceUrl, numericPlaceIdFromRef, pickBestPlaceSearchResult } from './places/index.cjs';
7
+ export { GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, toLatin1HeaderValue, transformFamilySearchUrl } from './utils/index.cjs';
8
+ export { i as TreeAPI } from './index-BfeojAOm.cjs';
8
9
 
9
10
  /**
10
11
  * FamilySearch Genealogies API
package/dist/index.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- import { bt as GenealogyOtherAPI, bu as GenealogyPersonsAPI, bv as GenealogyRelationshipsAPI, bw as GenealogySourcesAPI, bx as TreesAPI, by as createGenealogyPerson, bz as createGenealogySourceDescription, bA as createGenealogyTree, bB as deleteGenealogyConclusion, bC as deleteGenealogyPerson, bD as deleteGenealogyRelationship, bE as deleteGenealogySourceDescription, bF as deleteGenealogyTree, bG as readGenealogyBulkMatch, bH as readGenealogyNote, bI as readGenealogyPerson, bJ as readGenealogyPersonMatches, bK as readGenealogyPersons, bL as readGenealogySourceDescription, bM as readGenealogyTree, bN as readGenealogyTrees, bO as restoreGenealogyPerson, bP as updateGenealogyPerson, bQ as updateGenealogyRelationship, bR as updateGenealogySourceDescription, bS as updateGenealogyTree, bT as DatesAPI, bU as NamesAPI, bV as PlaceSearchQuery, bW as PlacesAPI, bX as VocabulariesAPI, bY as checkPlaceIsChild, bZ as getNameScript, b_ as normalizeDate, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, ca as readVocabularies, cb as readVocabularyConcept, cc as readVocabularyConcepts, cd as searchParentPlaces, ce as searchPlaces, cf as segmentAName } from './index-CKi9wd-C.js';
2
- export { cg as DateStandardizationResponse, ch as ENVIRONMENT_CONFIGS, ci as FamilySearchPlace, cj as FamilySearchSDK, ck as FamilySearchUser, cl as MemoriesAPI, cm as MemoryArtifact, cn as MemoryComment, co as MemoryPersona, cp as MemoryPersonaResponse, cq as MemoryPersonasResponse, cr as MemoryWithCommentsResponse, cs as NameScriptResponse, ct as NameSegment, cu as NameSegmentsResponse, cv as PedigreeAPI, cw as PersonMemoriesResponse, cx as PlaceDescription, cy as PlaceDetailsResponse, cz as PlaceSearchResponse, cA as PlaceSearchResult, cB as StandardizedDate, cC as UserAPI, cD as UserMemoriesResponse, cE as VocabAPI, cF as VocabulariesResponse, cG as VocabularyConceptDetail, cH as VocabularyConceptResponse, cI as VocabularyConceptsResponse, cJ as VocabularyMetadata, cK as createFamilySearchSDK, cL as fetchMultiplePersons, cM as fetchPedigree, cN as getFamilySearchSDK, cO as initFamilySearchSDK, cP as readCurrentUser, cQ as resetFamilySearchSDK } from './index-CKi9wd-C.js';
1
+ import { bt as GenealogyOtherAPI, bu as GenealogyPersonsAPI, bv as GenealogyRelationshipsAPI, bw as GenealogySourcesAPI, bx as TreesAPI, by as createGenealogyPerson, bz as createGenealogySourceDescription, bA as createGenealogyTree, bB as deleteGenealogyConclusion, bC as deleteGenealogyPerson, bD as deleteGenealogyRelationship, bE as deleteGenealogySourceDescription, bF as deleteGenealogyTree, bG as readGenealogyBulkMatch, bH as readGenealogyNote, bI as readGenealogyPerson, bJ as readGenealogyPersonMatches, bK as readGenealogyPersons, bL as readGenealogySourceDescription, bM as readGenealogyTree, bN as readGenealogyTrees, bO as restoreGenealogyPerson, bP as updateGenealogyPerson, bQ as updateGenealogyRelationship, bR as updateGenealogySourceDescription, bS as updateGenealogyTree, bT as DatesAPI, bU as NamesAPI, bV as PlaceSearchQuery, bW as PlacesAPI, bX as VocabulariesAPI, bY as checkPlaceIsChild, bZ as getNameScript, b_ as normalizeDate, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, ca as readVocabularies, cb as readVocabularyConcept, cc as readVocabularyConcepts, cd as searchParentPlaces, ce as searchPlaces, cf as segmentAName } from './tree-changes-CFwJtBcK.js';
2
+ export { cg as DateStandardizationResponse, ch as ENVIRONMENT_CONFIGS, ci as FamilySearchPlace, cj as FamilySearchSDK, ck as FamilySearchUser, cl as MemoriesAPI, cm as MemoryArtifact, cn as MemoryComment, co as MemoryPersona, cp as MemoryPersonaResponse, cq as MemoryPersonasResponse, cr as MemoryWithCommentsResponse, cs as NameScriptResponse, ct as NameSegment, cu as NameSegmentsResponse, cv as PedigreeAPI, cw as PersonMemoriesResponse, cx as PlaceDescription, cy as PlaceDetailsResponse, cz as PlaceSearchResponse, cA as PlaceSearchResult, cB as StandardizedDate, cC as UserAPI, cD as UserMemoriesResponse, cE as VocabAPI, cF as VocabulariesResponse, cG as VocabularyConceptDetail, cH as VocabularyConceptResponse, cI as VocabularyConceptsResponse, cJ as VocabularyMetadata, cK as createFamilySearchSDK, cL as fetchMultiplePersons, cM as fetchPedigree, cN as getFamilySearchSDK, cO as initFamilySearchSDK, cP as readCurrentUser, cQ as resetFamilySearchSDK } from './tree-changes-CFwJtBcK.js';
3
3
  import { F as FamilySearchApiResponse } from './index-0PpnEPuZ.js';
4
4
  export { E as EnvironmentConfig, a as FamilySearchApiError, b as FamilySearchEnvironment, c as FamilySearchSDKConfig, O as OAUTH_ENDPOINTS, d as OAUTH_STORAGE_KEYS, e as OAuthAPI, f as OAuthConfig, g as OAuthEndpoints, h as OAuthStateValidation, i as OAuthTokenResponse, P as ProgressCallback, R as RateLimiterConfig, S as SDKLogger, j as buildAuthorizationUrl, k as clearAllTokens, l as clearStoredTokens, m as exchangeCodeForToken, n as generateOAuthState, o as getOAuthEndpoints, p as getStoredAccessToken, q as getStoredRefreshToken, r as getTokenStorageKey, s as getUserInfo, t as openOAuthPopup, u as parseCallbackParams, v as refreshAccessToken, w as storeOAuthState, x as storeTokens, y as validateAccessToken, z as validateOAuthState } from './index-0PpnEPuZ.js';
5
5
  export { A as AttachSourceInput, a as AttachSourceResponse, C as ChangeEntry, b as ChildAndParentsRelationship, c as CreateChildAndParentsRelationshipInput, d as CreateCoupleRelationshipInput, e as CreatePersonResponse, f as CreateRelationshipResponse, D as DeletePersonResponse, g as Discussion, h as DiscussionComment, E as EnhancedPedigreeData, i as EnhancedPerson, F as FamilySearchPerson, M as MatchesResponse, N as NameForm, j as Note, k as NoteInput, l as NoteResponse, P as PedigreeData, m as PedigreeResponse, n as PersonChangeHistoryResponse, o as PersonData, p as PersonDiscussionsResponse, q as PersonDisplay, r as PersonFact, s as PersonInput, t as PersonMatchInput, u as PersonMatchOptions, v as PersonMergeAnalysis, w as PersonMergeInput, x as PersonMergeResponse, y as PersonNotesResponse, z as PersonPortrait, B as PersonPortraitsResponse, G as PersonSearchResponse, H as PersonSearchResult, I as PersonSourcesResponse, J as PersonWithRelationships, R as Relationship, K as RelationshipDetails, S as SourceDescription, L as SourceDescriptionDetail, O as SourceDescriptionResponse, Q as SourceDescriptionsResponse, T as SourceReference, U as TreePersonMatchEntry, V as TreePersonMatchesOptions, W as TreePersonMatchesResponse, X as UpdatePersonResponse, Y as UpdateRelationshipResponse } from './tree-D7X-beAQ.js';
6
- export { GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, transformFamilySearchUrl } from './utils/index.js';
7
- export { i as TreeAPI } from './index-CcZ9bR5K.js';
6
+ export { FamilySearchPlacePayload, extractGazetteerPlaceId, familySearchResearchPlaceUrl, numericPlaceIdFromRef, pickBestPlaceSearchResult } from './places/index.js';
7
+ export { GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, toLatin1HeaderValue, transformFamilySearchUrl } from './utils/index.js';
8
+ export { i as TreeAPI } from './index-CgIsZu6a.js';
8
9
 
9
10
  /**
10
11
  * FamilySearch Genealogies API
package/dist/index.js CHANGED
@@ -1666,6 +1666,10 @@ __export(tree_exports, {
1666
1666
  });
1667
1667
 
1668
1668
  // src/api/tree/persons.ts
1669
+ var PERSON_WRITE_HEADERS = {
1670
+ "Content-Type": "application/x-fs-v1+json",
1671
+ Accept: "application/x-fs-v1+json"
1672
+ };
1669
1673
  async function readPerson(sdk, personId) {
1670
1674
  try {
1671
1675
  const response = await sdk.get(
@@ -1698,7 +1702,7 @@ async function readPersonWithDetails(sdk, personId, options = {}) {
1698
1702
  }
1699
1703
  async function createPerson(sdk, person, reason) {
1700
1704
  try {
1701
- const headers = {};
1705
+ const headers = { ...PERSON_WRITE_HEADERS };
1702
1706
  if (reason) {
1703
1707
  headers["X-Reason"] = reason;
1704
1708
  }
@@ -1715,7 +1719,7 @@ async function createPerson(sdk, person, reason) {
1715
1719
  }
1716
1720
  async function updatePerson(sdk, personId, person, reason) {
1717
1721
  try {
1718
- const headers = {};
1722
+ const headers = { ...PERSON_WRITE_HEADERS };
1719
1723
  if (reason) {
1720
1724
  headers["X-Reason"] = reason;
1721
1725
  }
@@ -6062,6 +6066,16 @@ var PedigreeAPI = class {
6062
6066
  }
6063
6067
  };
6064
6068
 
6069
+ // src/utils/headers.ts
6070
+ var isLatin1 = (value) => [...value].every((char) => char.charCodeAt(0) <= 255);
6071
+ var toLatin1HeaderValue = (value) => [...value].map((char) => {
6072
+ if (char.charCodeAt(0) <= 255) {
6073
+ return char;
6074
+ }
6075
+ const stripped = char.normalize("NFKD").replace(/\p{M}/gu, "");
6076
+ return stripped && isLatin1(stripped) ? stripped : "?";
6077
+ }).join("");
6078
+
6065
6079
  // src/client.ts
6066
6080
  var ENVIRONMENT_CONFIGS = {
6067
6081
  production: {
@@ -6202,6 +6216,9 @@ var FamilySearchSDK = class {
6202
6216
  if (this.appKey) {
6203
6217
  headers["X-FS-App-Key"] = this.appKey;
6204
6218
  }
6219
+ for (const key of Object.keys(headers)) {
6220
+ headers[key] = toLatin1HeaderValue(headers[key]);
6221
+ }
6205
6222
  this.logger.log(
6206
6223
  `[FamilySearch SDK] ${options.method || "GET"} ${fullUrl}`
6207
6224
  );
@@ -6216,7 +6233,7 @@ var FamilySearchSDK = class {
6216
6233
  });
6217
6234
  let data;
6218
6235
  const contentType = response.headers.get("content-type");
6219
- if (contentType && contentType.includes("application/json")) {
6236
+ if (contentType && contentType.includes("json")) {
6220
6237
  try {
6221
6238
  data = await response.json();
6222
6239
  } catch (error) {
@@ -6372,6 +6389,40 @@ function resetFamilySearchSDK() {
6372
6389
  sdkInstance = null;
6373
6390
  }
6374
6391
 
6392
+ // src/places/gazetteer-id.ts
6393
+ var numericPlaceIdFromRef = (ref) => {
6394
+ if (!ref) {
6395
+ return void 0;
6396
+ }
6397
+ if (ref.includes("/places/description/") || ref.includes("ark:/")) {
6398
+ return void 0;
6399
+ }
6400
+ const match = ref.match(/\/places\/(\d+)/);
6401
+ return match?.[1];
6402
+ };
6403
+ var extractGazetteerPlaceId = (place) => {
6404
+ const persistent = place.identifiers?.["http://gedcomx.org/Persistent"]?.[0];
6405
+ const fromPersistent = numericPlaceIdFromRef(persistent);
6406
+ if (fromPersistent) {
6407
+ return fromPersistent;
6408
+ }
6409
+ return numericPlaceIdFromRef(place.place?.description);
6410
+ };
6411
+ var familySearchResearchPlaceUrl = (placeId, baseUrl = "https://www.familysearch.org") => `${baseUrl}/en/research/places/?focusedId=${placeId}`;
6412
+ var pickBestPlaceSearchResult = (results, query) => {
6413
+ if (results.length === 0) {
6414
+ return void 0;
6415
+ }
6416
+ const town = query.split(",")[0]?.trim().toLowerCase();
6417
+ if (!town) {
6418
+ return results[0];
6419
+ }
6420
+ const label = (result) => (result.fullName || result.name || result.title || "").toLowerCase();
6421
+ return results.find(
6422
+ (result) => label(result) === town || label(result).startsWith(`${town},`)
6423
+ ) || results.find((result) => label(result).includes(town)) || results[0];
6424
+ };
6425
+
6375
6426
  // src/utils/gedcom-converter.ts
6376
6427
  function transformFamilySearchUrl(url) {
6377
6428
  if (url.includes("/platform/tree/persons/https://")) {
@@ -7309,4 +7360,4 @@ function addMarriageFacts(lines, relationships, person1, person2) {
7309
7360
  }
7310
7361
  var convertFamilySearchToGedcom = convertToGedcom;
7311
7362
 
7312
- export { AuthenticationError, ENVIRONMENT_CONFIGS, FamilySearchError, FamilySearchSDK, genealogies_exports as GenealogiesAPI, memories_exports as MemoriesAPI, NetworkError, NotFoundError, OAUTH_ENDPOINTS, OAUTH_STORAGE_KEYS, OAuthAPI, PedigreeAPI, PlacesAPI, RateLimitError, ServerError, standards_exports as StandardsAPI, tree_exports as TreeAPI, user_exports as UserAPI, ValidationError, vocab_exports as VocabAPI, buildAuthorizationUrl, checkPlaceIsChild, clearAllTokens, clearStoredTokens, convertFamilySearchToGedcom, convertToGedcom, createErrorFromResponse, createFamilySearchSDK, createNetworkError, exchangeCodeForToken, fetchMultiplePersons, fetchPedigree, generateOAuthState, getFamilySearchSDK, getOAuthEndpoints, getStoredAccessToken, getStoredRefreshToken, getTokenStorageKey, getUserInfo, initFamilySearchSDK, isRetryableError, openOAuthPopup, parseCallbackParams, readCurrentUser2 as readCurrentUser, readPlaceAttributes, readPlaceChildren, readPlaceDescription, readPlaceDescriptionWithRelated, readPlaceDescriptions, readPlaceDescriptionsGroup, readPlaceDetails, readPlaceType, readPlaceTypeGroup, readPlaceTypeGroups, readPlaceTypes, refreshAccessToken, resetFamilySearchSDK, searchParentPlaces, searchPlaces, storeOAuthState, storeTokens, transformFamilySearchUrl, validateAccessToken, validateOAuthState };
7363
+ export { AuthenticationError, ENVIRONMENT_CONFIGS, FamilySearchError, FamilySearchSDK, genealogies_exports as GenealogiesAPI, memories_exports as MemoriesAPI, NetworkError, NotFoundError, OAUTH_ENDPOINTS, OAUTH_STORAGE_KEYS, OAuthAPI, PedigreeAPI, PlacesAPI, RateLimitError, ServerError, standards_exports as StandardsAPI, tree_exports as TreeAPI, user_exports as UserAPI, ValidationError, vocab_exports as VocabAPI, buildAuthorizationUrl, checkPlaceIsChild, clearAllTokens, clearStoredTokens, convertFamilySearchToGedcom, convertToGedcom, createErrorFromResponse, createFamilySearchSDK, createNetworkError, exchangeCodeForToken, extractGazetteerPlaceId, familySearchResearchPlaceUrl, fetchMultiplePersons, fetchPedigree, generateOAuthState, getFamilySearchSDK, getOAuthEndpoints, getStoredAccessToken, getStoredRefreshToken, getTokenStorageKey, getUserInfo, initFamilySearchSDK, isRetryableError, numericPlaceIdFromRef, openOAuthPopup, parseCallbackParams, pickBestPlaceSearchResult, readCurrentUser2 as readCurrentUser, readPlaceAttributes, readPlaceChildren, readPlaceDescription, readPlaceDescriptionWithRelated, readPlaceDescriptions, readPlaceDescriptionsGroup, readPlaceDetails, readPlaceType, readPlaceTypeGroup, readPlaceTypeGroups, readPlaceTypes, refreshAccessToken, resetFamilySearchSDK, searchParentPlaces, searchPlaces, storeOAuthState, storeTokens, toLatin1HeaderValue, transformFamilySearchUrl, validateAccessToken, validateOAuthState };
@@ -298,8 +298,46 @@ var PlacesAPI = class {
298
298
  }
299
299
  };
300
300
 
301
+ // src/places/gazetteer-id.ts
302
+ var numericPlaceIdFromRef = (ref) => {
303
+ if (!ref) {
304
+ return void 0;
305
+ }
306
+ if (ref.includes("/places/description/") || ref.includes("ark:/")) {
307
+ return void 0;
308
+ }
309
+ const match = ref.match(/\/places\/(\d+)/);
310
+ return match?.[1];
311
+ };
312
+ var extractGazetteerPlaceId = (place) => {
313
+ const persistent = place.identifiers?.["http://gedcomx.org/Persistent"]?.[0];
314
+ const fromPersistent = numericPlaceIdFromRef(persistent);
315
+ if (fromPersistent) {
316
+ return fromPersistent;
317
+ }
318
+ return numericPlaceIdFromRef(place.place?.description);
319
+ };
320
+ var familySearchResearchPlaceUrl = (placeId, baseUrl = "https://www.familysearch.org") => `${baseUrl}/en/research/places/?focusedId=${placeId}`;
321
+ var pickBestPlaceSearchResult = (results, query) => {
322
+ if (results.length === 0) {
323
+ return void 0;
324
+ }
325
+ const town = query.split(",")[0]?.trim().toLowerCase();
326
+ if (!town) {
327
+ return results[0];
328
+ }
329
+ const label = (result) => (result.fullName || result.name || result.title || "").toLowerCase();
330
+ return results.find(
331
+ (result) => label(result) === town || label(result).startsWith(`${town},`)
332
+ ) || results.find((result) => label(result).includes(town)) || results[0];
333
+ };
334
+
301
335
  exports.PlacesAPI = PlacesAPI;
302
336
  exports.checkPlaceIsChild = checkPlaceIsChild;
337
+ exports.extractGazetteerPlaceId = extractGazetteerPlaceId;
338
+ exports.familySearchResearchPlaceUrl = familySearchResearchPlaceUrl;
339
+ exports.numericPlaceIdFromRef = numericPlaceIdFromRef;
340
+ exports.pickBestPlaceSearchResult = pickBestPlaceSearchResult;
303
341
  exports.readPlaceAttributes = readPlaceAttributes;
304
342
  exports.readPlaceChildren = readPlaceChildren;
305
343
  exports.readPlaceDescription = readPlaceDescription;
@@ -1,3 +1,42 @@
1
- export { bW as PlacesAPI, bY as checkPlaceIsChild, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, cd as searchParentPlaces, ce as searchPlaces } from '../index-CLkFtjZD.cjs';
1
+ export { bW as PlacesAPI, bY as checkPlaceIsChild, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, cd as searchParentPlaces, ce as searchPlaces } from '../tree-changes-e0UMhVha.cjs';
2
2
  import '../tree-D7X-beAQ.cjs';
3
3
  import '../index-0PpnEPuZ.cjs';
4
+
5
+ /**
6
+ * FamilySearch Places search returns Place Descriptions.
7
+ * `place.id` is a Description ID. The Places web UI `focusedId` is a
8
+ * gazetteer Place ID (different namespace). The Place ID lives on
9
+ * `identifiers["http://gedcomx.org/Persistent"]` or `place.place`.
10
+ *
11
+ * @see https://developers.familysearch.org/main/docs/places
12
+ */
13
+ type FamilySearchPlacePayload = {
14
+ id?: string;
15
+ identifiers?: Record<string, string[]>;
16
+ place?: {
17
+ original?: string;
18
+ description?: string;
19
+ };
20
+ display?: {
21
+ name?: string;
22
+ fullName?: string;
23
+ type?: string;
24
+ };
25
+ names?: Array<{
26
+ value?: string;
27
+ }>;
28
+ type?: string;
29
+ latitude?: number;
30
+ longitude?: number;
31
+ };
32
+ /** Numeric ID from a Place authority URL, never from /places/description/. */
33
+ declare const numericPlaceIdFromRef: (ref?: string) => string | undefined;
34
+ declare const extractGazetteerPlaceId: (place: FamilySearchPlacePayload) => string | undefined;
35
+ declare const familySearchResearchPlaceUrl: (placeId: string, baseUrl?: string) => string;
36
+ declare const pickBestPlaceSearchResult: <T extends {
37
+ name?: string;
38
+ fullName?: string;
39
+ title?: string;
40
+ }>(results: T[], query: string) => T | undefined;
41
+
42
+ export { type FamilySearchPlacePayload, extractGazetteerPlaceId, familySearchResearchPlaceUrl, numericPlaceIdFromRef, pickBestPlaceSearchResult };
@@ -1,3 +1,42 @@
1
- export { bW as PlacesAPI, bY as checkPlaceIsChild, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, cd as searchParentPlaces, ce as searchPlaces } from '../index-CKi9wd-C.js';
1
+ export { bW as PlacesAPI, bY as checkPlaceIsChild, b$ as readPlaceAttributes, c0 as readPlaceChildren, c1 as readPlaceDescription, c2 as readPlaceDescriptionWithRelated, c3 as readPlaceDescriptions, c4 as readPlaceDescriptionsGroup, c5 as readPlaceDetails, c6 as readPlaceType, c7 as readPlaceTypeGroup, c8 as readPlaceTypeGroups, c9 as readPlaceTypes, cd as searchParentPlaces, ce as searchPlaces } from '../tree-changes-CFwJtBcK.js';
2
2
  import '../tree-D7X-beAQ.js';
3
3
  import '../index-0PpnEPuZ.js';
4
+
5
+ /**
6
+ * FamilySearch Places search returns Place Descriptions.
7
+ * `place.id` is a Description ID. The Places web UI `focusedId` is a
8
+ * gazetteer Place ID (different namespace). The Place ID lives on
9
+ * `identifiers["http://gedcomx.org/Persistent"]` or `place.place`.
10
+ *
11
+ * @see https://developers.familysearch.org/main/docs/places
12
+ */
13
+ type FamilySearchPlacePayload = {
14
+ id?: string;
15
+ identifiers?: Record<string, string[]>;
16
+ place?: {
17
+ original?: string;
18
+ description?: string;
19
+ };
20
+ display?: {
21
+ name?: string;
22
+ fullName?: string;
23
+ type?: string;
24
+ };
25
+ names?: Array<{
26
+ value?: string;
27
+ }>;
28
+ type?: string;
29
+ latitude?: number;
30
+ longitude?: number;
31
+ };
32
+ /** Numeric ID from a Place authority URL, never from /places/description/. */
33
+ declare const numericPlaceIdFromRef: (ref?: string) => string | undefined;
34
+ declare const extractGazetteerPlaceId: (place: FamilySearchPlacePayload) => string | undefined;
35
+ declare const familySearchResearchPlaceUrl: (placeId: string, baseUrl?: string) => string;
36
+ declare const pickBestPlaceSearchResult: <T extends {
37
+ name?: string;
38
+ fullName?: string;
39
+ title?: string;
40
+ }>(results: T[], query: string) => T | undefined;
41
+
42
+ export { type FamilySearchPlacePayload, extractGazetteerPlaceId, familySearchResearchPlaceUrl, numericPlaceIdFromRef, pickBestPlaceSearchResult };
@@ -296,4 +296,38 @@ var PlacesAPI = class {
296
296
  }
297
297
  };
298
298
 
299
- export { PlacesAPI, checkPlaceIsChild, readPlaceAttributes, readPlaceChildren, readPlaceDescription, readPlaceDescriptionWithRelated, readPlaceDescriptions, readPlaceDescriptionsGroup, readPlaceDetails, readPlaceType, readPlaceTypeGroup, readPlaceTypeGroups, readPlaceTypes, searchParentPlaces, searchPlaces };
299
+ // src/places/gazetteer-id.ts
300
+ var numericPlaceIdFromRef = (ref) => {
301
+ if (!ref) {
302
+ return void 0;
303
+ }
304
+ if (ref.includes("/places/description/") || ref.includes("ark:/")) {
305
+ return void 0;
306
+ }
307
+ const match = ref.match(/\/places\/(\d+)/);
308
+ return match?.[1];
309
+ };
310
+ var extractGazetteerPlaceId = (place) => {
311
+ const persistent = place.identifiers?.["http://gedcomx.org/Persistent"]?.[0];
312
+ const fromPersistent = numericPlaceIdFromRef(persistent);
313
+ if (fromPersistent) {
314
+ return fromPersistent;
315
+ }
316
+ return numericPlaceIdFromRef(place.place?.description);
317
+ };
318
+ var familySearchResearchPlaceUrl = (placeId, baseUrl = "https://www.familysearch.org") => `${baseUrl}/en/research/places/?focusedId=${placeId}`;
319
+ var pickBestPlaceSearchResult = (results, query) => {
320
+ if (results.length === 0) {
321
+ return void 0;
322
+ }
323
+ const town = query.split(",")[0]?.trim().toLowerCase();
324
+ if (!town) {
325
+ return results[0];
326
+ }
327
+ const label = (result) => (result.fullName || result.name || result.title || "").toLowerCase();
328
+ return results.find(
329
+ (result) => label(result) === town || label(result).startsWith(`${town},`)
330
+ ) || results.find((result) => label(result).includes(town)) || results[0];
331
+ };
332
+
333
+ export { PlacesAPI, checkPlaceIsChild, extractGazetteerPlaceId, familySearchResearchPlaceUrl, numericPlaceIdFromRef, pickBestPlaceSearchResult, readPlaceAttributes, readPlaceChildren, readPlaceDescription, readPlaceDescriptionWithRelated, readPlaceDescriptions, readPlaceDescriptionsGroup, readPlaceDetails, readPlaceType, readPlaceTypeGroup, readPlaceTypeGroups, readPlaceTypes, searchParentPlaces, searchPlaces };
@@ -1,6 +1,10 @@
1
1
  'use strict';
2
2
 
3
3
  // src/api/tree/persons.ts
4
+ var PERSON_WRITE_HEADERS = {
5
+ "Content-Type": "application/x-fs-v1+json",
6
+ Accept: "application/x-fs-v1+json"
7
+ };
4
8
  async function readPerson(sdk, personId) {
5
9
  try {
6
10
  const response = await sdk.get(
@@ -33,7 +37,7 @@ async function readPersonWithDetails(sdk, personId, options = {}) {
33
37
  }
34
38
  async function createPerson(sdk, person, reason) {
35
39
  try {
36
- const headers = {};
40
+ const headers = { ...PERSON_WRITE_HEADERS };
37
41
  if (reason) {
38
42
  headers["X-Reason"] = reason;
39
43
  }
@@ -50,7 +54,7 @@ async function createPerson(sdk, person, reason) {
50
54
  }
51
55
  async function updatePerson(sdk, personId, person, reason) {
52
56
  try {
53
- const headers = {};
57
+ const headers = { ...PERSON_WRITE_HEADERS };
54
58
  if (reason) {
55
59
  headers["X-Reason"] = reason;
56
60
  }
@@ -1,3 +1,3 @@
1
- export { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from '../index-CLkFtjZD.cjs';
1
+ export { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from '../tree-changes-e0UMhVha.cjs';
2
2
  import '../tree-D7X-beAQ.cjs';
3
3
  import '../index-0PpnEPuZ.cjs';
@@ -1,3 +1,3 @@
1
- export { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from '../index-CKi9wd-C.js';
1
+ export { A as AgentAPI, C as ConclusionsAPI, G as GroupsAPI, M as MatchesAPI, a as MergesAPI, N as NotesAPI, P as PedigreesAPI, b as PendingModificationsAPI, c as PersonsAPI, d as PreferencesAPI, R as RelationshipsAPI, S as SearchAPI, e as SourceAttachmentsAPI, f as SourceBoxAPI, g as SourcesAPI, T as TreeChangesAPI, h as TreesManagementAPI, i as addSourcesToCollection, j as allowPersonMerge, k as attachSourceToChildAndParentsRelationship, l as attachSourceToCoupleRelationship, m as attachSourceToPerson, n as canMergePersons, o as createChildAndParentsRelationship, p as createChildAndParentsRelationshipNote, q as createChildAndParentsRelationshipSourceReference, r as createCoupleRelationship, s as createCoupleRelationshipNote, t as createCoupleRelationshipSourceReference, u as createGroup, v as createNotAMatchDeclaration, w as createPerson, x as createPersonMemory, y as createPersonNote, z as createRelationshipGedcomx, B as createSourceDescription, D as createSourceFolder, E as createTree, F as deleteAllNotAMatchDeclarations, H as deleteChildAndParentsRelationship, I as deleteChildAndParentsRelationshipConclusion, J as deleteChildAndParentsRelationshipNote, K as deleteChildAndParentsRelationshipParent, L as deleteChildAndParentsRelationshipSourceReference, O as deleteCoupleRelationship, Q as deleteCoupleRelationshipConclusion, U as deleteCoupleRelationshipNote, V as deleteCoupleRelationshipSourceReference, W as deleteGroup, X as deleteNotAMatchDeclaration, Y as deletePerson, Z as deletePersonConclusion, _ as deletePersonDiscussionReference, $ as deletePersonMemoriesPersonaReference, a0 as deletePersonNotAMatch, a1 as deletePersonNotAMatches, a2 as deletePersonNote, a3 as deletePersonPortrait, a4 as deletePersonSourceReference, a5 as deletePreferredParentRelationship, a6 as deletePreferredSpouseRelationship, a7 as deleteSourceDescription, a8 as deleteTree, a9 as deleteTreePersonReference, aa as deleteUserDefinedCollection, ab as detachSourceFromChildAndParentsRelationship, ac as detachSourceFromCoupleRelationship, ad as detachSourceFromPerson, ae as exportGEDCOM, af as matchPerson, ag as mergePerson, ah as performPersonMatchesByExample, ai as readAgent, aj as readAncestry, ak as readChildAndParentRelationshipNote, al as readChildAndParentsRelationship, am as readChildAndParentsRelationshipChangeHistory, an as readChildAndParentsRelationshipNote, ao as readChildAndParentsRelationshipNotes, ap as readChildAndParentsRelationshipSourceReferences, aq as readChildAndParentsRelationshipSources, ar as readCollectionSourceDescriptions, as as readCoupleRelationship, at as readCoupleRelationshipChangeHistory, au as readCoupleRelationshipNote, av as readCoupleRelationshipNotes, aw as readCoupleRelationshipSourceReferences, ax as readCoupleRelationshipSources, ay as readDescendancy, az as readGroup, aA as readGroups, aB as readNotAMatchDeclarations, aC as readPendingModifications, aD as readPerson, aE as readPersonChangeHistory, aF as readPersonChildren, aG as readPersonDiscussions, aH as readPersonFamilies, aI as readPersonMatches, aJ as readPersonMemories, aK as readPersonMergeAnalysis, aL as readPersonNonMatches, aM as readPersonNotAMatches, aN as readPersonNote, aO as readPersonNotes, aP as readPersonParents, aQ as readPersonPortraits, aR as readPersonSources, aS as readPersonSpouses, aT as readPersonWithDetails, aU as readPreferredParentRelationship, aV as readPreferredSpouseRelationship, aW as readResearchTreePersons, aX as readSourceDescription, aY as readSourceDescriptionChanges, aZ as readSourceDescriptionHead, a_ as readSourceDescriptions, a$ as readSourceFolders, b0 as readTree, b1 as readTreeChanges, b2 as readTreeMatches, b3 as readUserDefinedCollection, b4 as readUserSourceDescriptions, b5 as readUserSourceFolders, b6 as removeSourcesFromCollection, b7 as restoreChange, b8 as restoreChildAndParentsRelationship, b9 as restoreCoupleRelationship, ba as restorePerson, bb as searchPersonByData, bc as searchPersons, bd as setParentOrder, be as setPreferredParentRelationship, bf as setPreferredSpouseRelationship, bg as setSpouseOrder, bh as updateChildAndParentsRelationship, bi as updateChildAndParentsRelationshipNote, bj as updateCoupleRelationship, bk as updateCoupleRelationshipNote, bl as updateGroup, bm as updateMatchResolution, bn as updatePerson, bo as updatePersonNotAMatches, bp as updatePersonNote, bq as updatePersonPortraits, br as updateSourceDescription, bs as updateUserDefinedCollection } from '../tree-changes-CFwJtBcK.js';
2
2
  import '../tree-D7X-beAQ.js';
3
3
  import '../index-0PpnEPuZ.js';
@@ -1,4 +1,8 @@
1
1
  // src/api/tree/persons.ts
2
+ var PERSON_WRITE_HEADERS = {
3
+ "Content-Type": "application/x-fs-v1+json",
4
+ Accept: "application/x-fs-v1+json"
5
+ };
2
6
  async function readPerson(sdk, personId) {
3
7
  try {
4
8
  const response = await sdk.get(
@@ -31,7 +35,7 @@ async function readPersonWithDetails(sdk, personId, options = {}) {
31
35
  }
32
36
  async function createPerson(sdk, person, reason) {
33
37
  try {
34
- const headers = {};
38
+ const headers = { ...PERSON_WRITE_HEADERS };
35
39
  if (reason) {
36
40
  headers["X-Reason"] = reason;
37
41
  }
@@ -48,7 +52,7 @@ async function createPerson(sdk, person, reason) {
48
52
  }
49
53
  async function updatePerson(sdk, personId, person, reason) {
50
54
  try {
51
- const headers = {};
55
+ const headers = { ...PERSON_WRITE_HEADERS };
52
56
  if (reason) {
53
57
  headers["X-Reason"] = reason;
54
58
  }
@@ -390,6 +390,8 @@ interface PlaceDescription {
390
390
  };
391
391
  latitude?: number;
392
392
  longitude?: number;
393
+ /** Persistent Place authority URLs (gazetteer Place IDs), not Description IDs */
394
+ identifiers?: Record<string, string[]>;
393
395
  place?: {
394
396
  original?: string;
395
397
  description?: string;
@@ -398,6 +400,11 @@ interface PlaceDescription {
398
400
  id?: string;
399
401
  name?: string;
400
402
  };
403
+ display?: {
404
+ name?: string;
405
+ fullName?: string;
406
+ type?: string;
407
+ };
401
408
  spatialDescription?: {
402
409
  type?: string;
403
410
  geojson?: unknown;
@@ -474,6 +481,8 @@ interface PlaceDescriptionsResponse {
474
481
  * Single place description response
475
482
  */
476
483
  interface PlaceDescriptionResponse {
484
+ /** Top-level places array returned by /platform/places/description/{id} */
485
+ places?: PlaceDescription[];
477
486
  sourceDescriptions?: Array<{
478
487
  id?: string;
479
488
  resourceType?: string;
@@ -390,6 +390,8 @@ interface PlaceDescription {
390
390
  };
391
391
  latitude?: number;
392
392
  longitude?: number;
393
+ /** Persistent Place authority URLs (gazetteer Place IDs), not Description IDs */
394
+ identifiers?: Record<string, string[]>;
393
395
  place?: {
394
396
  original?: string;
395
397
  description?: string;
@@ -398,6 +400,11 @@ interface PlaceDescription {
398
400
  id?: string;
399
401
  name?: string;
400
402
  };
403
+ display?: {
404
+ name?: string;
405
+ fullName?: string;
406
+ type?: string;
407
+ };
401
408
  spatialDescription?: {
402
409
  type?: string;
403
410
  geojson?: unknown;
@@ -474,6 +481,8 @@ interface PlaceDescriptionsResponse {
474
481
  * Single place description response
475
482
  */
476
483
  interface PlaceDescriptionResponse {
484
+ /** Top-level places array returned by /platform/places/description/{id} */
485
+ places?: PlaceDescription[];
477
486
  sourceDescriptions?: Array<{
478
487
  id?: string;
479
488
  resourceType?: string;
@@ -937,6 +937,17 @@ function addMarriageFacts(lines, relationships, person1, person2) {
937
937
  }
938
938
  var convertFamilySearchToGedcom = convertToGedcom;
939
939
 
940
+ // src/utils/headers.ts
941
+ var isLatin1 = (value) => [...value].every((char) => char.charCodeAt(0) <= 255);
942
+ var toLatin1HeaderValue = (value) => [...value].map((char) => {
943
+ if (char.charCodeAt(0) <= 255) {
944
+ return char;
945
+ }
946
+ const stripped = char.normalize("NFKD").replace(/\p{M}/gu, "");
947
+ return stripped && isLatin1(stripped) ? stripped : "?";
948
+ }).join("");
949
+
940
950
  exports.convertFamilySearchToGedcom = convertFamilySearchToGedcom;
941
951
  exports.convertToGedcom = convertToGedcom;
952
+ exports.toLatin1HeaderValue = toLatin1HeaderValue;
942
953
  exports.transformFamilySearchUrl = transformFamilySearchUrl;
@@ -49,4 +49,6 @@ interface GedcomConversionOptions {
49
49
  declare function convertToGedcom(pedigreeData: EnhancedPedigreeData, options?: GedcomConversionOptions): string;
50
50
  declare const convertFamilySearchToGedcom: typeof convertToGedcom;
51
51
 
52
- export { type GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, transformFamilySearchUrl };
52
+ declare const toLatin1HeaderValue: (value: string) => string;
53
+
54
+ export { type GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, toLatin1HeaderValue, transformFamilySearchUrl };
@@ -49,4 +49,6 @@ interface GedcomConversionOptions {
49
49
  declare function convertToGedcom(pedigreeData: EnhancedPedigreeData, options?: GedcomConversionOptions): string;
50
50
  declare const convertFamilySearchToGedcom: typeof convertToGedcom;
51
51
 
52
- export { type GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, transformFamilySearchUrl };
52
+ declare const toLatin1HeaderValue: (value: string) => string;
53
+
54
+ export { type GedcomConversionOptions, convertFamilySearchToGedcom, convertToGedcom, toLatin1HeaderValue, transformFamilySearchUrl };
@@ -935,4 +935,14 @@ function addMarriageFacts(lines, relationships, person1, person2) {
935
935
  }
936
936
  var convertFamilySearchToGedcom = convertToGedcom;
937
937
 
938
- export { convertFamilySearchToGedcom, convertToGedcom, transformFamilySearchUrl };
938
+ // src/utils/headers.ts
939
+ var isLatin1 = (value) => [...value].every((char) => char.charCodeAt(0) <= 255);
940
+ var toLatin1HeaderValue = (value) => [...value].map((char) => {
941
+ if (char.charCodeAt(0) <= 255) {
942
+ return char;
943
+ }
944
+ const stripped = char.normalize("NFKD").replace(/\p{M}/gu, "");
945
+ return stripped && isLatin1(stripped) ? stripped : "?";
946
+ }).join("");
947
+
948
+ export { convertFamilySearchToGedcom, convertToGedcom, toLatin1HeaderValue, transformFamilySearchUrl };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeviz/familysearch-sdk",
3
- "version": "2.0.7",
3
+ "version": "2.0.9",
4
4
  "description": "Modern TypeScript SDK for FamilySearch API v3 - OAuth, Places API, Tree API, and GEDCOM utilities",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",