@singi-labs/sifa-sdk 0.11.4 → 0.11.6

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.
@@ -406,4 +406,4 @@ declare function hasAdultContent(item: {
406
406
  labels?: ActivityLabel[];
407
407
  }): boolean;
408
408
 
409
- export { type AdultContentLabel as A, hasAdultContent as B, type ExternalAccount as E, type FeedItem as F, type LocationValue as L, type ProfileSkill as P, type SkillSuggestion as S, type TrustStat as T, type VerifiedAccount as V, type ActivityLabel as a, type PdsProviderInfo as b, type Profile as c, ADULT_CONTENT_LABELS as d, type ActiveApp as e, type Endorsement as f, type EndorsementData as g, type ExternalAccountKeytraceClaim as h, type LanguageProficiency as i, type PresentationLinkView as j, type ProfileCertification as k, type ProfileCourse as l, type ProfileEducation as m, type ProfileHonor as n, type ProfileIndustry as o, type ProfileLanguage as p, type ProfileLocation as q, type ProfileOverrideSource as r, type ProfilePosition as s, type ProfilePresentation as t, type ProfilePresentationDelivery as u, type ProfileProject as v, type ProfilePublication as w, type ProfileVolunteering as x, type PublicationContributor as y, type SkillRef as z };
409
+ export { type AdultContentLabel as A, hasAdultContent as B, type ExternalAccount as E, type FeedItem as F, type LocationValue as L, type ProfileSkill as P, type SkillSuggestion as S, type TrustStat as T, type VerifiedAccount as V, type ActivityLabel as a, type ProfilePresentationDelivery as b, type PdsProviderInfo as c, type Profile as d, ADULT_CONTENT_LABELS as e, type ActiveApp as f, type Endorsement as g, type EndorsementData as h, type ExternalAccountKeytraceClaim as i, type LanguageProficiency as j, type PresentationLinkView as k, type ProfileCertification as l, type ProfileCourse as m, type ProfileEducation as n, type ProfileHonor as o, type ProfileIndustry as p, type ProfileLanguage as q, type ProfileLocation as r, type ProfileOverrideSource as s, type ProfilePosition as t, type ProfilePresentation as u, type ProfileProject as v, type ProfilePublication as w, type ProfileVolunteering as x, type PublicationContributor as y, type SkillRef as z };
@@ -406,4 +406,4 @@ declare function hasAdultContent(item: {
406
406
  labels?: ActivityLabel[];
407
407
  }): boolean;
408
408
 
409
- export { type AdultContentLabel as A, hasAdultContent as B, type ExternalAccount as E, type FeedItem as F, type LocationValue as L, type ProfileSkill as P, type SkillSuggestion as S, type TrustStat as T, type VerifiedAccount as V, type ActivityLabel as a, type PdsProviderInfo as b, type Profile as c, ADULT_CONTENT_LABELS as d, type ActiveApp as e, type Endorsement as f, type EndorsementData as g, type ExternalAccountKeytraceClaim as h, type LanguageProficiency as i, type PresentationLinkView as j, type ProfileCertification as k, type ProfileCourse as l, type ProfileEducation as m, type ProfileHonor as n, type ProfileIndustry as o, type ProfileLanguage as p, type ProfileLocation as q, type ProfileOverrideSource as r, type ProfilePosition as s, type ProfilePresentation as t, type ProfilePresentationDelivery as u, type ProfileProject as v, type ProfilePublication as w, type ProfileVolunteering as x, type PublicationContributor as y, type SkillRef as z };
409
+ export { type AdultContentLabel as A, hasAdultContent as B, type ExternalAccount as E, type FeedItem as F, type LocationValue as L, type ProfileSkill as P, type SkillSuggestion as S, type TrustStat as T, type VerifiedAccount as V, type ActivityLabel as a, type ProfilePresentationDelivery as b, type PdsProviderInfo as c, type Profile as d, ADULT_CONTENT_LABELS as e, type ActiveApp as f, type Endorsement as g, type EndorsementData as h, type ExternalAccountKeytraceClaim as i, type LanguageProficiency as j, type PresentationLinkView as k, type ProfileCertification as l, type ProfileCourse as m, type ProfileEducation as n, type ProfileHonor as o, type ProfileIndustry as p, type ProfileLanguage as q, type ProfileLocation as r, type ProfileOverrideSource as s, type ProfilePosition as t, type ProfilePresentation as u, type ProfileProject as v, type ProfilePublication as w, type ProfileVolunteering as x, type PublicationContributor as y, type SkillRef as z };
package/dist/index.cjs CHANGED
@@ -1404,6 +1404,50 @@ function formatRelativeTime(dateString) {
1404
1404
  return `${years}y ago`;
1405
1405
  }
1406
1406
 
1407
+ // src/format/format-duration.ts
1408
+ function formatPresentationDuration(duration) {
1409
+ if (!duration) return void 0;
1410
+ const { minMinutes, maxMinutes } = duration;
1411
+ if (maxMinutes != null && maxMinutes !== minMinutes) {
1412
+ return `${minMinutes}-${maxMinutes} min`;
1413
+ }
1414
+ return `${minMinutes} min`;
1415
+ }
1416
+
1417
+ // src/format/summarize-deliveries.ts
1418
+ var CANCELLED_STATUS = "community.lexicon.calendar.event#cancelled";
1419
+ var KEYNOTE_ROLE = "id.sifa.defs#keynote";
1420
+ function summarizePresentationDeliveries(deliveries, options = {}) {
1421
+ const venueLimit = options.venueLimit ?? 3;
1422
+ const counted = (deliveries ?? []).filter((delivery) => delivery.status !== CANCELLED_STATUS);
1423
+ const sorted = [...counted].sort((a, b) => (b.date ?? "").localeCompare(a.date ?? ""));
1424
+ let recentYear;
1425
+ for (const delivery of counted) {
1426
+ if (!delivery.date) continue;
1427
+ const year = Number(delivery.date.slice(0, 4));
1428
+ if (!Number.isNaN(year) && (recentYear === void 0 || year > recentYear)) {
1429
+ recentYear = year;
1430
+ }
1431
+ }
1432
+ const seen = /* @__PURE__ */ new Set();
1433
+ const distinctVenues = [];
1434
+ for (const delivery of sorted) {
1435
+ const name = delivery.eventName?.trim();
1436
+ if (name && !seen.has(name)) {
1437
+ seen.add(name);
1438
+ distinctVenues.push(name);
1439
+ }
1440
+ }
1441
+ const venues = distinctVenues.slice(0, venueLimit);
1442
+ return {
1443
+ count: counted.length,
1444
+ recentYear,
1445
+ keynoteCount: counted.filter((delivery) => delivery.role === KEYNOTE_ROLE).length,
1446
+ venues,
1447
+ moreVenues: distinctVenues.length - venues.length
1448
+ };
1449
+ }
1450
+
1407
1451
  // src/format/sort-by-date.ts
1408
1452
  var FAR_FUTURE = "9999-12-31";
1409
1453
  var FAR_PAST = "0000-01-01";
@@ -1627,6 +1671,102 @@ function meetsContrastAA(foreground, background) {
1627
1671
  return contrastRatio(foreground, background) >= 4.5;
1628
1672
  }
1629
1673
 
1674
+ // src/import/presentation-csv.ts
1675
+ function clean(value) {
1676
+ return (value ?? "").trim();
1677
+ }
1678
+ function parsePresentationDuration(input) {
1679
+ const numbers = (clean(input).match(/\d+/g) ?? []).map((n) => Number.parseInt(n, 10)).filter((n) => Number.isInteger(n) && n > 0);
1680
+ const min = numbers.at(0);
1681
+ if (min === void 0) return void 0;
1682
+ const max = numbers.at(1);
1683
+ return max !== void 0 && max >= min ? { minMinutes: min, maxMinutes: max } : { minMinutes: min };
1684
+ }
1685
+ function durationFromMinutes(minRaw, maxRaw) {
1686
+ const min = Number.parseInt(clean(minRaw), 10);
1687
+ if (!Number.isInteger(min) || min < 1) return void 0;
1688
+ const max = Number.parseInt(clean(maxRaw), 10);
1689
+ return Number.isInteger(max) && max >= min ? { minMinutes: min, maxMinutes: max } : { minMinutes: min };
1690
+ }
1691
+ function parseIntendedAudiences(input, delimiter = ";") {
1692
+ return clean(input).split(delimiter).map((s) => s.trim()).filter(Boolean);
1693
+ }
1694
+ function stripHtmlToText(input) {
1695
+ const text = clean(input).replace(/<\s*br\s*\/?>/gi, "\n").replace(/<\/\s*(p|div|li|h[1-6])\s*>/gi, "\n").replace(/<[^>]*>/g, "").replace(/&nbsp;/gi, " ").replace(/&amp;/gi, "&").replace(/&lt;/gi, "<").replace(/&gt;/gi, ">").replace(/&quot;/gi, '"').replace(/&#0*39;|&apos;/gi, "'");
1696
+ return text.replace(/[ \t]+/g, " ").replace(/ *\n */g, "\n").replace(/\n{3,}/g, "\n\n").trim();
1697
+ }
1698
+ var ROLE_TOKENS = {
1699
+ presenter: "id.sifa.defs#presenter",
1700
+ speaker: "id.sifa.defs#presenter",
1701
+ panelist: "id.sifa.defs#panelist",
1702
+ keynote: "id.sifa.defs#keynote",
1703
+ workshop: "id.sifa.defs#workshop",
1704
+ host: "id.sifa.defs#host"
1705
+ };
1706
+ function normalizePresentationRole(value) {
1707
+ const v = clean(value).toLowerCase();
1708
+ if (!v) return void 0;
1709
+ if (v.startsWith("id.sifa.defs#")) return v;
1710
+ return ROLE_TOKENS[v] ?? v;
1711
+ }
1712
+ var MODE_FRAGMENTS = {
1713
+ inperson: "#inperson",
1714
+ "in person": "#inperson",
1715
+ "in-person": "#inperson",
1716
+ virtual: "#virtual",
1717
+ online: "#virtual",
1718
+ remote: "#virtual",
1719
+ hybrid: "#hybrid"
1720
+ };
1721
+ function normalizePresentationMode(value) {
1722
+ const v = clean(value).toLowerCase();
1723
+ if (!v) return void 0;
1724
+ if (v.startsWith("community.lexicon.calendar.event#")) return v;
1725
+ const fragment = MODE_FRAGMENTS[v];
1726
+ return fragment ? `community.lexicon.calendar.event${fragment}` : void 0;
1727
+ }
1728
+ function link(uri, type) {
1729
+ const u = clean(uri);
1730
+ return u ? { uri: u, type } : void 0;
1731
+ }
1732
+ function presentationCsvRowToRecord(row) {
1733
+ const description = stripHtmlToText(row.description);
1734
+ const duration = parsePresentationDuration(row.duration) ?? durationFromMinutes(row.duration_min_minutes, row.duration_max_minutes);
1735
+ const intendedAudiences = parseIntendedAudiences(row.intended_audiences);
1736
+ const links = [
1737
+ link(row.slides_url, "id.sifa.defs#linkSlides"),
1738
+ link(row.recording_url, "id.sifa.defs#linkRecording"),
1739
+ link(row.writeup_url, "id.sifa.defs#linkWriteup")
1740
+ ].filter((l) => l !== void 0);
1741
+ const record = { title: clean(row.title) };
1742
+ if (description) record.description = description;
1743
+ if (duration) record.duration = duration;
1744
+ if (intendedAudiences.length) record.intendedAudiences = intendedAudiences;
1745
+ if (links.length) record.links = links;
1746
+ return { key: clean(row.presentation_key) || void 0, record };
1747
+ }
1748
+ function presentationDeliveryCsvRowToRecord(row) {
1749
+ const links = [
1750
+ link(row.event_url, "id.sifa.defs#linkEvent"),
1751
+ link(row.recording_url, "id.sifa.defs#linkRecording")
1752
+ ].filter((l) => l !== void 0);
1753
+ const record = {};
1754
+ const title = clean(row.title);
1755
+ const eventName = clean(row.event_name);
1756
+ const date = clean(row.date);
1757
+ const location = clean(row.location);
1758
+ const role = normalizePresentationRole(row.role);
1759
+ const mode = normalizePresentationMode(row.mode);
1760
+ if (title) record.title = title;
1761
+ if (role) record.role = role;
1762
+ if (eventName) record.eventName = eventName;
1763
+ if (date) record.date = date;
1764
+ if (location) record.location = location;
1765
+ if (mode) record.mode = mode;
1766
+ if (links.length) record.links = links;
1767
+ return { presentationKey: clean(row.presentation_key) || void 0, record };
1768
+ }
1769
+
1630
1770
  // src/cards/app-url-patterns.ts
1631
1771
  var APP_URL_PATTERNS = Object.freeze({
1632
1772
  bluesky: {
@@ -2444,7 +2584,7 @@ var ProfileVolunteeringRecordSchema = zod.z.object({
2444
2584
  });
2445
2585
 
2446
2586
  // src/index.ts
2447
- var SIFA_SDK_VERSION = "0.11.4";
2587
+ var SIFA_SDK_VERSION = "0.11.6";
2448
2588
 
2449
2589
  exports.ACTIVITY_TIERS = ACTIVITY_TIERS;
2450
2590
  exports.ACTIVITY_VISIBILITY_RULES = ACTIVITY_VISIBILITY_RULES;
@@ -2528,11 +2668,13 @@ exports.dedupeSkills = dedupeSkills;
2528
2668
  exports.detectPdsProvider = detectPdsProvider;
2529
2669
  exports.didSchema = didSchema;
2530
2670
  exports.dimensionsFromInputs = dimensionsFromInputs;
2671
+ exports.durationFromMinutes = durationFromMinutes;
2531
2672
  exports.encodeFeedCursor = encodeFeedCursor;
2532
2673
  exports.externalRecordRefSchema = externalRecordRefSchema;
2533
2674
  exports.findIndustry = findIndustry;
2534
2675
  exports.formatDistanceToNow = formatDistanceToNow;
2535
2676
  exports.formatLocation = formatLocation;
2677
+ exports.formatPresentationDuration = formatPresentationDuration;
2536
2678
  exports.formatRelativeTime = formatRelativeTime;
2537
2679
  exports.getActivityTaxonomyVersion = getActivityTaxonomyVersion;
2538
2680
  exports.getActivityTier = getActivityTier;
@@ -2574,12 +2716,18 @@ exports.maxGraphemes = maxGraphemes;
2574
2716
  exports.meetsContrastAA = meetsContrastAA;
2575
2717
  exports.normalizeOpenTo = normalizeOpenTo;
2576
2718
  exports.normalizePlatformId = normalizePlatformId;
2719
+ exports.normalizePresentationMode = normalizePresentationMode;
2720
+ exports.normalizePresentationRole = normalizePresentationRole;
2577
2721
  exports.normalizeWorkplaceTypes = normalizeWorkplaceTypes;
2578
2722
  exports.openToTokenToValue = openToTokenToValue;
2579
2723
  exports.openToValueToToken = openToValueToToken;
2724
+ exports.parseIntendedAudiences = parseIntendedAudiences;
2580
2725
  exports.parseLocationString = parseLocationString;
2726
+ exports.parsePresentationDuration = parsePresentationDuration;
2581
2727
  exports.pdsProviderFromApi = pdsProviderFromApi;
2582
2728
  exports.pickPrimaryPosition = pickPrimaryPosition;
2729
+ exports.presentationCsvRowToRecord = presentationCsvRowToRecord;
2730
+ exports.presentationDeliveryCsvRowToRecord = presentationDeliveryCsvRowToRecord;
2583
2731
  exports.profileToDimensionInputs = profileToDimensionInputs;
2584
2732
  exports.relativeLuminance = relativeLuminance;
2585
2733
  exports.resolveCardUrl = resolveCardUrl;
@@ -2589,7 +2737,9 @@ exports.sanitizeHandleInput = sanitizeHandleInput;
2589
2737
  exports.selfLabelsSchema = selfLabelsSchema;
2590
2738
  exports.singleDateExtractor = singleDateExtractor;
2591
2739
  exports.sortByDateDesc = sortByDateDesc;
2740
+ exports.stripHtmlToText = stripHtmlToText;
2592
2741
  exports.strongRefSchema = strongRefSchema;
2742
+ exports.summarizePresentationDeliveries = summarizePresentationDeliveries;
2593
2743
  exports.truncateGraphemes = truncateGraphemes;
2594
2744
  exports.uriSchema = uriSchema;
2595
2745
  //# sourceMappingURL=index.cjs.map