@singi-labs/sifa-sdk 0.12.59 → 0.12.61

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.
@@ -78,6 +78,13 @@ interface JsonLdOptions {
78
78
  readonly baseUrl?: string;
79
79
  /** Applied to every user-authored string. Defaults to identity. */
80
80
  readonly sanitize?: Sanitizer;
81
+ /**
82
+ * Absolute URL of the page this graph describes, used for `url` and `@id`.
83
+ * Defaults to `${baseUrl}/p/${handle}`. Personal sites can be served from an
84
+ * arbitrary host, including a self-hosted custom domain, where that default
85
+ * path is not where the page lives.
86
+ */
87
+ readonly canonicalUrl?: string;
81
88
  }
82
89
  /**
83
90
  * Structural input for the emitters.
@@ -117,6 +124,16 @@ interface JsonLdProfileInput {
117
124
  readonly publications?: readonly unknown[];
118
125
  readonly courses?: readonly unknown[];
119
126
  readonly externalAccounts?: readonly unknown[];
127
+ /**
128
+ * Dual-facet accounts: one DID presenting as both a person and a company.
129
+ * Only the opted-in case is emitted, see `buildPersonJsonLd`.
130
+ */
131
+ readonly org?: {
132
+ readonly personalProfileVisible?: boolean;
133
+ readonly orgProfile?: {
134
+ readonly name?: string;
135
+ } | null;
136
+ } | null;
120
137
  }
121
138
  interface Hideable {
122
139
  readonly hidden?: boolean;
@@ -192,7 +209,11 @@ declare function buildPersonJsonLd(profile: JsonLdProfileInput, options?: JsonLd
192
209
  '@type': "EducationalOrganization";
193
210
  name: string;
194
211
  }[] | undefined;
195
- worksFor?: {
212
+ worksFor?: ({
213
+ '@type': "Organization";
214
+ '@id': string;
215
+ name: string;
216
+ } | {
196
217
  member?: {
197
218
  endDate?: string | undefined;
198
219
  startDate?: string | undefined;
@@ -201,7 +222,7 @@ declare function buildPersonJsonLd(profile: JsonLdProfileInput, options?: JsonLd
201
222
  } | undefined;
202
223
  '@type': "Organization";
203
224
  name: string;
204
- }[] | undefined;
225
+ })[] | undefined;
205
226
  homeLocation?: {
206
227
  address?: {
207
228
  addressCountry?: string | undefined;
@@ -213,12 +234,14 @@ declare function buildPersonJsonLd(profile: JsonLdProfileInput, options?: JsonLd
213
234
  } | undefined;
214
235
  jobTitle: string | undefined;
215
236
  description: string | undefined;
237
+ alternateName: string;
216
238
  url: string;
217
239
  image: string | undefined;
218
240
  familyName?: string | undefined;
219
241
  givenName?: string | undefined;
220
242
  '@context': string;
221
243
  '@type': string;
244
+ '@id': string;
222
245
  name: string;
223
246
  };
224
247
  declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: JsonLdOptions): {
@@ -263,7 +286,11 @@ declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: J
263
286
  '@type': "EducationalOrganization";
264
287
  name: string;
265
288
  }[] | undefined;
266
- worksFor?: {
289
+ worksFor?: ({
290
+ '@type': "Organization";
291
+ '@id': string;
292
+ name: string;
293
+ } | {
267
294
  member?: {
268
295
  endDate?: string | undefined;
269
296
  startDate?: string | undefined;
@@ -272,7 +299,7 @@ declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: J
272
299
  } | undefined;
273
300
  '@type': "Organization";
274
301
  name: string;
275
- }[] | undefined;
302
+ })[] | undefined;
276
303
  homeLocation?: {
277
304
  address?: {
278
305
  addressCountry?: string | undefined;
@@ -284,11 +311,13 @@ declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: J
284
311
  } | undefined;
285
312
  jobTitle: string | undefined;
286
313
  description: string | undefined;
314
+ alternateName: string;
287
315
  url: string;
288
316
  image: string | undefined;
289
317
  familyName?: string | undefined;
290
318
  givenName?: string | undefined;
291
319
  '@type': string;
320
+ '@id': string;
292
321
  name: string;
293
322
  };
294
323
  dateModified?: string | undefined;
@@ -78,6 +78,13 @@ interface JsonLdOptions {
78
78
  readonly baseUrl?: string;
79
79
  /** Applied to every user-authored string. Defaults to identity. */
80
80
  readonly sanitize?: Sanitizer;
81
+ /**
82
+ * Absolute URL of the page this graph describes, used for `url` and `@id`.
83
+ * Defaults to `${baseUrl}/p/${handle}`. Personal sites can be served from an
84
+ * arbitrary host, including a self-hosted custom domain, where that default
85
+ * path is not where the page lives.
86
+ */
87
+ readonly canonicalUrl?: string;
81
88
  }
82
89
  /**
83
90
  * Structural input for the emitters.
@@ -117,6 +124,16 @@ interface JsonLdProfileInput {
117
124
  readonly publications?: readonly unknown[];
118
125
  readonly courses?: readonly unknown[];
119
126
  readonly externalAccounts?: readonly unknown[];
127
+ /**
128
+ * Dual-facet accounts: one DID presenting as both a person and a company.
129
+ * Only the opted-in case is emitted, see `buildPersonJsonLd`.
130
+ */
131
+ readonly org?: {
132
+ readonly personalProfileVisible?: boolean;
133
+ readonly orgProfile?: {
134
+ readonly name?: string;
135
+ } | null;
136
+ } | null;
120
137
  }
121
138
  interface Hideable {
122
139
  readonly hidden?: boolean;
@@ -192,7 +209,11 @@ declare function buildPersonJsonLd(profile: JsonLdProfileInput, options?: JsonLd
192
209
  '@type': "EducationalOrganization";
193
210
  name: string;
194
211
  }[] | undefined;
195
- worksFor?: {
212
+ worksFor?: ({
213
+ '@type': "Organization";
214
+ '@id': string;
215
+ name: string;
216
+ } | {
196
217
  member?: {
197
218
  endDate?: string | undefined;
198
219
  startDate?: string | undefined;
@@ -201,7 +222,7 @@ declare function buildPersonJsonLd(profile: JsonLdProfileInput, options?: JsonLd
201
222
  } | undefined;
202
223
  '@type': "Organization";
203
224
  name: string;
204
- }[] | undefined;
225
+ })[] | undefined;
205
226
  homeLocation?: {
206
227
  address?: {
207
228
  addressCountry?: string | undefined;
@@ -213,12 +234,14 @@ declare function buildPersonJsonLd(profile: JsonLdProfileInput, options?: JsonLd
213
234
  } | undefined;
214
235
  jobTitle: string | undefined;
215
236
  description: string | undefined;
237
+ alternateName: string;
216
238
  url: string;
217
239
  image: string | undefined;
218
240
  familyName?: string | undefined;
219
241
  givenName?: string | undefined;
220
242
  '@context': string;
221
243
  '@type': string;
244
+ '@id': string;
222
245
  name: string;
223
246
  };
224
247
  declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: JsonLdOptions): {
@@ -263,7 +286,11 @@ declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: J
263
286
  '@type': "EducationalOrganization";
264
287
  name: string;
265
288
  }[] | undefined;
266
- worksFor?: {
289
+ worksFor?: ({
290
+ '@type': "Organization";
291
+ '@id': string;
292
+ name: string;
293
+ } | {
267
294
  member?: {
268
295
  endDate?: string | undefined;
269
296
  startDate?: string | undefined;
@@ -272,7 +299,7 @@ declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: J
272
299
  } | undefined;
273
300
  '@type': "Organization";
274
301
  name: string;
275
- }[] | undefined;
302
+ })[] | undefined;
276
303
  homeLocation?: {
277
304
  address?: {
278
305
  addressCountry?: string | undefined;
@@ -284,11 +311,13 @@ declare function buildProfilePageJsonLd(profile: JsonLdProfileInput, options?: J
284
311
  } | undefined;
285
312
  jobTitle: string | undefined;
286
313
  description: string | undefined;
314
+ alternateName: string;
287
315
  url: string;
288
316
  image: string | undefined;
289
317
  familyName?: string | undefined;
290
318
  givenName?: string | undefined;
291
319
  '@type': string;
320
+ '@id': string;
292
321
  name: string;
293
322
  };
294
323
  dateModified?: string | undefined;
@@ -561,6 +561,7 @@ function buildHomeLocation(location, s) {
561
561
  function buildPersonJsonLd(profile, options = {}) {
562
562
  const s = options.sanitize ?? identity;
563
563
  const baseUrl = normaliseBaseUrl(options.baseUrl);
564
+ const canonical = options.canonicalUrl ?? `${baseUrl}/p/${profile.handle}`;
564
565
  const positions = visible(profile.positions);
565
566
  const currentPosition = pickPrimaryPosition(positions);
566
567
  const knowsAbout = rankKnowsAbout(profile.skills, s);
@@ -589,33 +590,43 @@ function buildPersonJsonLd(profile, options = {}) {
589
590
  const givenTrimmed = profile.givenName?.trim();
590
591
  const familyTrimmed = profile.familyName?.trim();
591
592
  const structuredName = givenTrimmed && familyTrimmed ? `${givenTrimmed} ${familyTrimmed}` : void 0;
593
+ const ownCompany = profile.org?.personalProfileVisible && profile.org.orgProfile ? {
594
+ "@type": "Organization",
595
+ "@id": `${baseUrl}/c/${profile.handle}`,
596
+ name: s(profile.org.orgProfile.name ?? profile.handle)
597
+ } : null;
598
+ const worksFor = [
599
+ ...ownCompany ? [ownCompany] : [],
600
+ ...positions.filter((p) => p.company).map((p) => ({
601
+ "@type": "Organization",
602
+ name: s(p.company),
603
+ ...p.title && {
604
+ member: {
605
+ "@type": "OrganizationRole",
606
+ roleName: s(p.title),
607
+ ...p.startedAt && { startDate: p.startedAt },
608
+ ...p.endedAt && { endDate: p.endedAt }
609
+ }
610
+ }
611
+ }))
612
+ ];
592
613
  const awards = visible(profile.honors).filter((h) => h.title).map((h) => s(h.title));
593
614
  const languages = visible(profile.languages).filter((l) => l.language).map((l) => l.language);
594
615
  return {
595
616
  "@context": "https://schema.org",
596
617
  "@type": "Person",
618
+ // Stable identifier so a /c/ Organization's `founder` can point back here.
619
+ "@id": canonical,
597
620
  name: s(structuredName ?? profile.displayName ?? profile.handle),
598
621
  ...givenTrimmed && { givenName: s(givenTrimmed) },
599
622
  ...familyTrimmed && { familyName: s(familyTrimmed) },
600
623
  jobTitle: hasMeaningfulText(profile.headline) ? s(profile.headline) : currentPosition?.title ? s(currentPosition.title) : void 0,
601
624
  description: hasMeaningfulText(profile.about) ? s(profile.about) : void 0,
602
- url: `${baseUrl}/p/${profile.handle}`,
625
+ alternateName: `@${profile.handle}`,
626
+ url: canonical,
603
627
  image: profile.avatar ?? void 0,
604
628
  ...profile.location && { homeLocation: buildHomeLocation(profile.location, s) },
605
- ...positions.length > 0 && {
606
- worksFor: positions.filter((p) => p.company).map((p) => ({
607
- "@type": "Organization",
608
- name: s(p.company),
609
- ...p.title && {
610
- member: {
611
- "@type": "OrganizationRole",
612
- roleName: s(p.title),
613
- ...p.startedAt && { startDate: p.startedAt },
614
- ...p.endedAt && { endDate: p.endedAt }
615
- }
616
- }
617
- }))
618
- },
629
+ ...worksFor.length > 0 && { worksFor },
619
630
  ...visible(profile.education).length > 0 && {
620
631
  alumniOf: visible(profile.education).filter((e) => e.institution).map((e) => ({ "@type": "EducationalOrganization", name: s(e.institution) }))
621
632
  },
@@ -667,7 +678,7 @@ var PROFILE_SECTION_HAS_PART = [
667
678
  function buildProfilePageJsonLd(profile, options = {}) {
668
679
  const person = buildPersonJsonLd(profile, options);
669
680
  const { "@context": _context, ...personWithoutContext } = person;
670
- const url = `${normaliseBaseUrl(options.baseUrl)}/p/${profile.handle}`;
681
+ const url = options.canonicalUrl ?? `${normaliseBaseUrl(options.baseUrl)}/p/${profile.handle}`;
671
682
  const hasPart = PROFILE_SECTION_HAS_PART.filter((section) => section.populated(profile)).map(
672
683
  (section) => ({
673
684
  "@type": "WebPageElement",