@singi-labs/sifa-sdk 0.9.3 → 0.9.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -1
- package/dist/index.cjs +580 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +140 -1
- package/dist/index.d.ts +140 -1
- package/dist/index.js +570 -2
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -35,7 +35,7 @@ Published publicly so third-party developers can build their own AT Protocol cli
|
|
|
35
35
|
| ATproto | Wrapper around `@atproto/api` that accepts an authenticated agent |
|
|
36
36
|
| Format | Pure formatters for dates, locations, profile completeness |
|
|
37
37
|
| Logic | Business-logic predicates (display-only; server-side trust logic lives in `sifa-api`) |
|
|
38
|
-
| Taxonomy | Constants and enums (continents, industries, skill categories,
|
|
38
|
+
| Taxonomy | Constants and enums (continents, industries, skill categories, activity tiers) |
|
|
39
39
|
| Tokens | Sifa-brand design tokens, exported via `@singi-labs/sifa-sdk/tokens` (optional) |
|
|
40
40
|
|
|
41
41
|
---
|
|
@@ -58,6 +58,17 @@ Optional design tokens (skip if you have your own brand):
|
|
|
58
58
|
import { colors, spacing } from '@singi-labs/sifa-sdk/tokens';
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
+
Classify an AT Protocol NSID into one of three activity tiers (`creation`,
|
|
62
|
+
`action`, `filtered`). Unknown NSIDs default to `filtered`:
|
|
63
|
+
|
|
64
|
+
```ts
|
|
65
|
+
import { getActivityTier, getTierMeta } from '@singi-labs/sifa-sdk';
|
|
66
|
+
|
|
67
|
+
getActivityTier('app.bsky.feed.post'); // 'creation'
|
|
68
|
+
getActivityTier('app.bsky.feed.like'); // 'action'
|
|
69
|
+
getTierMeta('creation'); // { label: 'Made', shownOnPublicProfile: true, ... }
|
|
70
|
+
```
|
|
71
|
+
|
|
61
72
|
---
|
|
62
73
|
|
|
63
74
|
## For third-party developers
|
package/dist/index.cjs
CHANGED
|
@@ -693,6 +693,10 @@ function getWorkplaceTypeLabel(value) {
|
|
|
693
693
|
var PLATFORM_LABELS = {
|
|
694
694
|
bluesky: "Bluesky",
|
|
695
695
|
github: "GitHub",
|
|
696
|
+
codeberg: "Codeberg",
|
|
697
|
+
gitlab: "GitLab",
|
|
698
|
+
forgejo: "Forgejo",
|
|
699
|
+
gitea: "Gitea",
|
|
696
700
|
linkedin: "LinkedIn",
|
|
697
701
|
youtube: "YouTube",
|
|
698
702
|
twitter: "X (Twitter)",
|
|
@@ -792,6 +796,350 @@ function groupSkillsByCategory(skills) {
|
|
|
792
796
|
return ordered;
|
|
793
797
|
}
|
|
794
798
|
|
|
799
|
+
// src/taxonomy/activity-tiers.json
|
|
800
|
+
var activity_tiers_default = {
|
|
801
|
+
$schema: "https://sifa.id/schemas/activity-tiers/v1.json",
|
|
802
|
+
version: "1.0.0",
|
|
803
|
+
updated: "2026-05-28",
|
|
804
|
+
tiers: {
|
|
805
|
+
creation: {
|
|
806
|
+
label: "Made",
|
|
807
|
+
description: "Substantive records the actor authored: posts, articles, repos, galleries, livestreams, RSVPs, CV entries. Surfaced on the public profile and in the network timeline.",
|
|
808
|
+
shownOnPublicProfile: true
|
|
809
|
+
},
|
|
810
|
+
action: {
|
|
811
|
+
label: "Did",
|
|
812
|
+
description: "Engagement records (likes, reposts, follows, votes, stars, reactions). Visible to the actor on the 'What is public about me' page and on the originating app, but not surfaced on the Sifa public profile.",
|
|
813
|
+
shownOnPublicProfile: false
|
|
814
|
+
},
|
|
815
|
+
filtered: {
|
|
816
|
+
label: null,
|
|
817
|
+
description: "Configuration, infrastructure, moderation, game state, ephemeral consumption signals (bookmarks, highlights), and other records Sifa does not display anywhere. The records remain public on the actor's PDS regardless.",
|
|
818
|
+
shownOnPublicProfile: false
|
|
819
|
+
}
|
|
820
|
+
},
|
|
821
|
+
lexicons: {
|
|
822
|
+
"app.bsky.feed.post": {
|
|
823
|
+
tier: "creation",
|
|
824
|
+
app: "bluesky",
|
|
825
|
+
notes: "Ambiguous: many posts are casual, but the lexicon also carries long-form posts and threads. Treated as creation; empty quote-posts (no text + record embed) are filtered at the consumer layer, not here."
|
|
826
|
+
},
|
|
827
|
+
"app.bsky.feed.like": { tier: "action", app: "bluesky" },
|
|
828
|
+
"app.bsky.feed.repost": { tier: "action", app: "bluesky" },
|
|
829
|
+
"app.bsky.feed.generator": {
|
|
830
|
+
tier: "filtered",
|
|
831
|
+
app: "bluesky",
|
|
832
|
+
notes: "Feed generator definition record, not personal activity."
|
|
833
|
+
},
|
|
834
|
+
"app.bsky.graph.follow": { tier: "action", app: "bluesky" },
|
|
835
|
+
"app.bsky.graph.block": { tier: "filtered", app: "bluesky", notes: "Moderation record." },
|
|
836
|
+
"app.bsky.graph.mute": { tier: "filtered", app: "bluesky", notes: "Moderation record." },
|
|
837
|
+
"app.bsky.graph.listblock": {
|
|
838
|
+
tier: "filtered",
|
|
839
|
+
app: "bluesky",
|
|
840
|
+
notes: "Moderation record."
|
|
841
|
+
},
|
|
842
|
+
"app.bsky.graph.listitem": {
|
|
843
|
+
tier: "filtered",
|
|
844
|
+
app: "bluesky",
|
|
845
|
+
notes: "List membership; rendered via the parent list, not as standalone activity."
|
|
846
|
+
},
|
|
847
|
+
"app.bsky.graph.list": {
|
|
848
|
+
tier: "filtered",
|
|
849
|
+
app: "bluesky",
|
|
850
|
+
notes: "User-curated list metadata; not surfaced as profile activity."
|
|
851
|
+
},
|
|
852
|
+
"app.bsky.graph.starterpack": { tier: "filtered", app: "bluesky" },
|
|
853
|
+
"app.bsky.actor.profile": {
|
|
854
|
+
tier: "filtered",
|
|
855
|
+
app: "bluesky",
|
|
856
|
+
notes: "Profile metadata record."
|
|
857
|
+
},
|
|
858
|
+
"sh.tangled.repo": { tier: "creation", app: "tangled" },
|
|
859
|
+
"sh.tangled.repo.issue": { tier: "creation", app: "tangled" },
|
|
860
|
+
"sh.tangled.repo.pull": { tier: "creation", app: "tangled" },
|
|
861
|
+
"sh.tangled.feed.star": { tier: "action", app: "tangled" },
|
|
862
|
+
"sh.tangled.graph.follow": { tier: "action", app: "tangled" },
|
|
863
|
+
"sh.tangled.actor.profile": {
|
|
864
|
+
tier: "filtered",
|
|
865
|
+
app: "tangled",
|
|
866
|
+
notes: "Profile metadata record."
|
|
867
|
+
},
|
|
868
|
+
"community.lexicon.calendar.rsvp": {
|
|
869
|
+
tier: "creation",
|
|
870
|
+
app: "smokesignal",
|
|
871
|
+
notes: "Ambiguous: RSVPs are reactions to events, but they are public commitments and the only Smoke Signal record Sifa scans today. Classified as creation."
|
|
872
|
+
},
|
|
873
|
+
"events.smokesignal.profile": {
|
|
874
|
+
tier: "filtered",
|
|
875
|
+
app: "smokesignal",
|
|
876
|
+
notes: "Profile metadata record."
|
|
877
|
+
},
|
|
878
|
+
"blue.flashes.feed.post": { tier: "creation", app: "flashes" },
|
|
879
|
+
"social.grain.gallery": { tier: "creation", app: "grain" },
|
|
880
|
+
"social.grain.gallery.item": {
|
|
881
|
+
tier: "filtered",
|
|
882
|
+
app: "grain",
|
|
883
|
+
notes: "Item-within-gallery; rendered via parent gallery."
|
|
884
|
+
},
|
|
885
|
+
"social.grain.photo": {
|
|
886
|
+
tier: "filtered",
|
|
887
|
+
app: "grain",
|
|
888
|
+
notes: "Raw photo asset; surfaced via the gallery that references it."
|
|
889
|
+
},
|
|
890
|
+
"social.grain.photo.exif": {
|
|
891
|
+
tier: "filtered",
|
|
892
|
+
app: "grain",
|
|
893
|
+
notes: "EXIF metadata for a photo."
|
|
894
|
+
},
|
|
895
|
+
"social.grain.story": {
|
|
896
|
+
tier: "filtered",
|
|
897
|
+
app: "grain",
|
|
898
|
+
notes: "Ephemeral story format."
|
|
899
|
+
},
|
|
900
|
+
"com.whtwnd.blog.entry": { tier: "creation", app: "whitewind" },
|
|
901
|
+
"fyi.unravel.frontpage.post": { tier: "creation", app: "frontpage" },
|
|
902
|
+
"fyi.unravel.frontpage.vote": { tier: "action", app: "frontpage" },
|
|
903
|
+
"social.psky.feed.post": { tier: "creation", app: "picosky" },
|
|
904
|
+
"link.pastesphere.snippet": { tier: "creation", app: "pastesphere" },
|
|
905
|
+
"site.standard.document": { tier: "creation", app: "standard" },
|
|
906
|
+
"computer.aetheros.page": { tier: "creation", app: "aetheros" },
|
|
907
|
+
"space.roomy.space.personal": { tier: "creation", app: "roomy" },
|
|
908
|
+
"dev.keytrace.claim": { tier: "creation", app: "keytrace" },
|
|
909
|
+
"social.popfeed.feed.review": { tier: "creation", app: "popfeed" },
|
|
910
|
+
"social.popfeed.feed.post": { tier: "creation", app: "popfeed" },
|
|
911
|
+
"social.popfeed.feed.note": { tier: "creation", app: "popfeed" },
|
|
912
|
+
"social.popfeed.feed.like": { tier: "action", app: "popfeed" },
|
|
913
|
+
"social.popfeed.challenge.participation": {
|
|
914
|
+
tier: "filtered",
|
|
915
|
+
app: "popfeed",
|
|
916
|
+
notes: "Challenge participation tracking."
|
|
917
|
+
},
|
|
918
|
+
"social.popfeed.actor.profile": {
|
|
919
|
+
tier: "filtered",
|
|
920
|
+
app: "popfeed",
|
|
921
|
+
notes: "Profile metadata record."
|
|
922
|
+
},
|
|
923
|
+
"place.stream.livestream": { tier: "creation", app: "streamplace" },
|
|
924
|
+
"place.stream.broadcast.origin": {
|
|
925
|
+
tier: "filtered",
|
|
926
|
+
app: "streamplace",
|
|
927
|
+
notes: "Broadcast origin/infrastructure record."
|
|
928
|
+
},
|
|
929
|
+
"place.stream.key": {
|
|
930
|
+
tier: "filtered",
|
|
931
|
+
app: "streamplace",
|
|
932
|
+
notes: "Stream key \u2014 sensitive infrastructure record."
|
|
933
|
+
},
|
|
934
|
+
"place.stream.metadata.configuration": {
|
|
935
|
+
tier: "filtered",
|
|
936
|
+
app: "streamplace",
|
|
937
|
+
notes: "Stream configuration metadata."
|
|
938
|
+
},
|
|
939
|
+
"place.stream.chat.message": {
|
|
940
|
+
tier: "filtered",
|
|
941
|
+
app: "streamplace",
|
|
942
|
+
notes: "Ephemeral chat message."
|
|
943
|
+
},
|
|
944
|
+
"place.stream.chat.profile": {
|
|
945
|
+
tier: "filtered",
|
|
946
|
+
app: "streamplace",
|
|
947
|
+
notes: "Chat profile metadata."
|
|
948
|
+
},
|
|
949
|
+
"app.sidetrail.trail": { tier: "creation", app: "semble" },
|
|
950
|
+
"app.sidetrail.walk": { tier: "creation", app: "semble" },
|
|
951
|
+
"at.youandme.connection": { tier: "creation", app: "youandme" },
|
|
952
|
+
"pub.leaflet.comment": { tier: "creation", app: "leaflet" },
|
|
953
|
+
"pub.leaflet.interactions.recommend": { tier: "action", app: "leaflet" },
|
|
954
|
+
"pub.leaflet.authFullPermissions": {
|
|
955
|
+
tier: "filtered",
|
|
956
|
+
app: "leaflet",
|
|
957
|
+
notes: "OAuth permission record."
|
|
958
|
+
},
|
|
959
|
+
"social.colibri.membership": { tier: "creation", app: "colibri" },
|
|
960
|
+
"social.colibri.message": {
|
|
961
|
+
tier: "filtered",
|
|
962
|
+
app: "colibri",
|
|
963
|
+
notes: "Chat message \u2014 high-volume conversational signal, not portfolio."
|
|
964
|
+
},
|
|
965
|
+
"social.colibri.reaction": { tier: "filtered", app: "colibri", notes: "Chat reaction." },
|
|
966
|
+
"social.colibri.channel": {
|
|
967
|
+
tier: "filtered",
|
|
968
|
+
app: "colibri",
|
|
969
|
+
notes: "Channel definition."
|
|
970
|
+
},
|
|
971
|
+
"social.colibri.community": {
|
|
972
|
+
tier: "filtered",
|
|
973
|
+
app: "colibri",
|
|
974
|
+
notes: "Community definition."
|
|
975
|
+
},
|
|
976
|
+
"social.colibri.approval": {
|
|
977
|
+
tier: "filtered",
|
|
978
|
+
app: "colibri",
|
|
979
|
+
notes: "Moderation approval record."
|
|
980
|
+
},
|
|
981
|
+
"social.colibri.category": {
|
|
982
|
+
tier: "filtered",
|
|
983
|
+
app: "colibri",
|
|
984
|
+
notes: "Category metadata."
|
|
985
|
+
},
|
|
986
|
+
"social.colibri.channel.read": {
|
|
987
|
+
tier: "filtered",
|
|
988
|
+
app: "colibri",
|
|
989
|
+
notes: "Read-state marker."
|
|
990
|
+
},
|
|
991
|
+
"social.colibri.actor.data": {
|
|
992
|
+
tier: "filtered",
|
|
993
|
+
app: "colibri",
|
|
994
|
+
notes: "Actor metadata."
|
|
995
|
+
},
|
|
996
|
+
"social.colibri.richtext.facet": {
|
|
997
|
+
tier: "filtered",
|
|
998
|
+
app: "colibri",
|
|
999
|
+
notes: "Richtext facet sub-record."
|
|
1000
|
+
},
|
|
1001
|
+
"app.collectivesocial.feed.list": {
|
|
1002
|
+
tier: "creation",
|
|
1003
|
+
app: "collectivesocial",
|
|
1004
|
+
notes: "Auto-created default Inbox lists are filtered at the consumer layer via isDefault=true predicate."
|
|
1005
|
+
},
|
|
1006
|
+
"net.alternativeproto.vote": {
|
|
1007
|
+
tier: "action",
|
|
1008
|
+
notes: "Vote record on a third-party protocol."
|
|
1009
|
+
},
|
|
1010
|
+
"network.cosmik.collection": {
|
|
1011
|
+
tier: "filtered",
|
|
1012
|
+
notes: "Stale registry id \u2014 Cosmik formerly in app registry."
|
|
1013
|
+
},
|
|
1014
|
+
"network.cosmik.collectionLink": { tier: "filtered" },
|
|
1015
|
+
"network.cosmik.connection": { tier: "filtered" },
|
|
1016
|
+
"network.cosmik.follow": { tier: "filtered" },
|
|
1017
|
+
"network.cosmik.card": { tier: "filtered", notes: "Link-in-bio card; consumption signal." },
|
|
1018
|
+
"social.pinksky.app.preference": {
|
|
1019
|
+
tier: "filtered",
|
|
1020
|
+
app: "bluesky",
|
|
1021
|
+
notes: "Pinkleap (Bluesky client) app preferences."
|
|
1022
|
+
},
|
|
1023
|
+
"at.margin.bookmark": {
|
|
1024
|
+
tier: "filtered",
|
|
1025
|
+
notes: "Bookmark \u2014 consumption signal, not creation."
|
|
1026
|
+
},
|
|
1027
|
+
"at.margin.highlight": {
|
|
1028
|
+
tier: "filtered",
|
|
1029
|
+
notes: "Highlight \u2014 consumption signal, not creation."
|
|
1030
|
+
},
|
|
1031
|
+
"community.lexicon.bookmarks.bookmark": {
|
|
1032
|
+
tier: "filtered",
|
|
1033
|
+
notes: "Bookmark \u2014 consumption signal."
|
|
1034
|
+
},
|
|
1035
|
+
"blue.linkat.board": { tier: "filtered", notes: "Link-in-bio board; consumption signal." },
|
|
1036
|
+
"dev.skyboard.board": { tier: "filtered", notes: "Skyboard task-board metadata." },
|
|
1037
|
+
"dev.skyboard.op": { tier: "filtered", notes: "Skyboard operation log." },
|
|
1038
|
+
"dev.skyboard.task": { tier: "filtered", notes: "Skyboard task record." },
|
|
1039
|
+
"net.anisota.player.state": { tier: "filtered", notes: "Anisota game player state." },
|
|
1040
|
+
"xyz.statusphere.status": {
|
|
1041
|
+
tier: "filtered",
|
|
1042
|
+
notes: "Statusphere emoji status \u2014 leisure signal."
|
|
1043
|
+
},
|
|
1044
|
+
"id.sifa.profile.self": {
|
|
1045
|
+
tier: "creation",
|
|
1046
|
+
app: "sifa",
|
|
1047
|
+
notes: "Sifa professional profile root."
|
|
1048
|
+
},
|
|
1049
|
+
"id.sifa.profile.position": { tier: "creation", app: "sifa" },
|
|
1050
|
+
"id.sifa.profile.education": { tier: "creation", app: "sifa" },
|
|
1051
|
+
"id.sifa.profile.skill": { tier: "creation", app: "sifa" },
|
|
1052
|
+
"id.sifa.profile.certification": { tier: "creation", app: "sifa" },
|
|
1053
|
+
"id.sifa.profile.project": { tier: "creation", app: "sifa" },
|
|
1054
|
+
"id.sifa.profile.volunteering": { tier: "creation", app: "sifa" },
|
|
1055
|
+
"id.sifa.profile.publication": { tier: "creation", app: "sifa" },
|
|
1056
|
+
"id.sifa.profile.course": { tier: "creation", app: "sifa" },
|
|
1057
|
+
"id.sifa.profile.honor": { tier: "creation", app: "sifa" },
|
|
1058
|
+
"id.sifa.profile.language": { tier: "creation", app: "sifa" },
|
|
1059
|
+
"id.sifa.profile.externalAccount": { tier: "creation", app: "sifa" },
|
|
1060
|
+
"id.sifa.profile.location": { tier: "creation", app: "sifa" },
|
|
1061
|
+
"id.sifa.endorsement": {
|
|
1062
|
+
tier: "creation",
|
|
1063
|
+
app: "sifa",
|
|
1064
|
+
notes: "Endorsement authored by the actor about another profile."
|
|
1065
|
+
},
|
|
1066
|
+
"id.sifa.endorsement.confirmation": {
|
|
1067
|
+
tier: "action",
|
|
1068
|
+
app: "sifa",
|
|
1069
|
+
notes: "Confirmation/acceptance of an endorsement received."
|
|
1070
|
+
},
|
|
1071
|
+
"id.sifa.graph.follow": { tier: "action", app: "sifa" },
|
|
1072
|
+
"id.sifa.graph.connection": {
|
|
1073
|
+
tier: "creation",
|
|
1074
|
+
app: "sifa",
|
|
1075
|
+
notes: "Mutual professional connection record."
|
|
1076
|
+
},
|
|
1077
|
+
"id.sifa.project.self": { tier: "creation", app: "sifa" },
|
|
1078
|
+
"id.sifa.project.member": { tier: "creation", app: "sifa" },
|
|
1079
|
+
"id.sifa.project.membership": { tier: "creation", app: "sifa" },
|
|
1080
|
+
"id.sifa.meeting": { tier: "creation", app: "sifa" },
|
|
1081
|
+
"id.sifa.authProfile": { tier: "filtered", app: "sifa", notes: "OAuth scope record." },
|
|
1082
|
+
"id.sifa.authProfileAccess": {
|
|
1083
|
+
tier: "filtered",
|
|
1084
|
+
app: "sifa",
|
|
1085
|
+
notes: "OAuth profile-access record."
|
|
1086
|
+
},
|
|
1087
|
+
"id.sifa.authProject": { tier: "filtered", app: "sifa", notes: "OAuth scope record." },
|
|
1088
|
+
"id.sifa.authConnection": { tier: "filtered", app: "sifa", notes: "OAuth scope record." },
|
|
1089
|
+
"id.sifa.authMeet": { tier: "filtered", app: "sifa", notes: "OAuth scope record." },
|
|
1090
|
+
"forum.barazo.post": { tier: "creation", app: "barazo" },
|
|
1091
|
+
"forum.barazo.community.member": { tier: "creation", app: "barazo" },
|
|
1092
|
+
"forum.barazo.reputation.event": { tier: "creation", app: "barazo" },
|
|
1093
|
+
"forum.barazo.reaction": { tier: "action", app: "barazo" },
|
|
1094
|
+
"forum.barazo.reply": {
|
|
1095
|
+
tier: "action",
|
|
1096
|
+
app: "barazo",
|
|
1097
|
+
notes: "Short conversational reply \u2014 engagement signal."
|
|
1098
|
+
},
|
|
1099
|
+
"forum.barazo.flag": { tier: "filtered", app: "barazo", notes: "Moderation flag." }
|
|
1100
|
+
}
|
|
1101
|
+
};
|
|
1102
|
+
|
|
1103
|
+
// src/taxonomy/activity-tiers.ts
|
|
1104
|
+
var tierMetaSchema = zod.z.object({
|
|
1105
|
+
label: zod.z.string().nullable(),
|
|
1106
|
+
description: zod.z.string(),
|
|
1107
|
+
shownOnPublicProfile: zod.z.boolean()
|
|
1108
|
+
});
|
|
1109
|
+
var lexiconEntrySchema = zod.z.object({
|
|
1110
|
+
tier: zod.z.enum(["creation", "action", "filtered"]),
|
|
1111
|
+
app: zod.z.string().optional(),
|
|
1112
|
+
notes: zod.z.string().optional()
|
|
1113
|
+
});
|
|
1114
|
+
var taxonomySchema = zod.z.object({
|
|
1115
|
+
version: zod.z.string(),
|
|
1116
|
+
updated: zod.z.string(),
|
|
1117
|
+
tiers: zod.z.object({
|
|
1118
|
+
creation: tierMetaSchema,
|
|
1119
|
+
action: tierMetaSchema,
|
|
1120
|
+
filtered: tierMetaSchema
|
|
1121
|
+
}),
|
|
1122
|
+
lexicons: zod.z.record(zod.z.string(), lexiconEntrySchema)
|
|
1123
|
+
});
|
|
1124
|
+
var parsed = taxonomySchema.parse(activity_tiers_default);
|
|
1125
|
+
var ACTIVITY_TIERS = Object.freeze(parsed);
|
|
1126
|
+
function getActivityTier(nsid) {
|
|
1127
|
+
if (!nsid) return "filtered";
|
|
1128
|
+
const entry = ACTIVITY_TIERS.lexicons[nsid];
|
|
1129
|
+
return entry ? entry.tier : "filtered";
|
|
1130
|
+
}
|
|
1131
|
+
function getLexiconEntry(nsid) {
|
|
1132
|
+
if (!nsid) return null;
|
|
1133
|
+
const entry = ACTIVITY_TIERS.lexicons[nsid];
|
|
1134
|
+
return entry ?? null;
|
|
1135
|
+
}
|
|
1136
|
+
function getTierMeta(tier) {
|
|
1137
|
+
return ACTIVITY_TIERS.tiers[tier];
|
|
1138
|
+
}
|
|
1139
|
+
function getActivityTaxonomyVersion() {
|
|
1140
|
+
return { version: ACTIVITY_TIERS.version, updated: ACTIVITY_TIERS.updated };
|
|
1141
|
+
}
|
|
1142
|
+
|
|
795
1143
|
// src/format/format-time.ts
|
|
796
1144
|
function formatRelativeTime(dateString) {
|
|
797
1145
|
const date = new Date(dateString);
|
|
@@ -957,6 +1305,31 @@ function detectPdsProvider(handle) {
|
|
|
957
1305
|
return null;
|
|
958
1306
|
}
|
|
959
1307
|
|
|
1308
|
+
// src/format/text-sanitize.ts
|
|
1309
|
+
var COMBINING_MARK = /\p{M}/u;
|
|
1310
|
+
var BIDI_CONTROLS = /[--]/gu;
|
|
1311
|
+
function limitCombiningMarks(value, maxPerBase = 4) {
|
|
1312
|
+
if (!value || !COMBINING_MARK.test(value)) return value;
|
|
1313
|
+
let out = "";
|
|
1314
|
+
let combiningRun = 0;
|
|
1315
|
+
for (const char of value) {
|
|
1316
|
+
if (/\p{M}/u.test(char)) {
|
|
1317
|
+
if (combiningRun < maxPerBase) {
|
|
1318
|
+
out += char;
|
|
1319
|
+
combiningRun += 1;
|
|
1320
|
+
}
|
|
1321
|
+
} else {
|
|
1322
|
+
out += char;
|
|
1323
|
+
combiningRun = 0;
|
|
1324
|
+
}
|
|
1325
|
+
}
|
|
1326
|
+
return out;
|
|
1327
|
+
}
|
|
1328
|
+
function sanitizeDisplayText(value, maxCombiningPerBase = 4) {
|
|
1329
|
+
if (!value) return value;
|
|
1330
|
+
return limitCombiningMarks(value.replace(BIDI_CONTROLS, ""), maxCombiningPerBase);
|
|
1331
|
+
}
|
|
1332
|
+
|
|
960
1333
|
// src/format/text-truncate.ts
|
|
961
1334
|
var ELLIPSIS = "\u2026";
|
|
962
1335
|
function truncateGraphemes(value, maxLen) {
|
|
@@ -1011,6 +1384,201 @@ function meetsContrastAA(foreground, background) {
|
|
|
1011
1384
|
return contrastRatio(foreground, background) >= 4.5;
|
|
1012
1385
|
}
|
|
1013
1386
|
|
|
1387
|
+
// src/cards/app-url-patterns.ts
|
|
1388
|
+
var APP_URL_PATTERNS = Object.freeze({
|
|
1389
|
+
bluesky: {
|
|
1390
|
+
urlPattern: "https://bsky.app/profile/{handle}/post/{rkey}",
|
|
1391
|
+
profileUrlPattern: "https://bsky.app/profile/{handle}"
|
|
1392
|
+
},
|
|
1393
|
+
tangled: {
|
|
1394
|
+
profileUrlPattern: "https://tangled.sh/{handle}"
|
|
1395
|
+
},
|
|
1396
|
+
smokesignal: {
|
|
1397
|
+
urlPattern: "https://smokesignal.events/{did}/{rkey}",
|
|
1398
|
+
profileUrlPattern: "https://smokesignal.events/{did}"
|
|
1399
|
+
},
|
|
1400
|
+
whitewind: {
|
|
1401
|
+
urlPattern: "https://whtwnd.com/{handle}/{rkey}",
|
|
1402
|
+
profileUrlPattern: "https://whtwnd.com/{handle}"
|
|
1403
|
+
},
|
|
1404
|
+
frontpage: {
|
|
1405
|
+
urlPattern: "https://frontpage.fyi/post/{did}/{rkey}",
|
|
1406
|
+
profileUrlPattern: "https://frontpage.fyi/profile/{did}"
|
|
1407
|
+
},
|
|
1408
|
+
linkat: {
|
|
1409
|
+
profileUrlPattern: "https://linkat.blue/{handle}"
|
|
1410
|
+
},
|
|
1411
|
+
pastesphere: {
|
|
1412
|
+
urlPattern: "https://pastesphere.link/user/{handle}/snippet/{rkey}",
|
|
1413
|
+
profileUrlPattern: "https://pastesphere.link/user/{handle}"
|
|
1414
|
+
},
|
|
1415
|
+
kipclip: {
|
|
1416
|
+
profileUrlPattern: "https://kipclip.com/{handle}"
|
|
1417
|
+
},
|
|
1418
|
+
keytrace: {
|
|
1419
|
+
profileUrlPattern: "https://keytrace.dev/@{handle}"
|
|
1420
|
+
},
|
|
1421
|
+
sifa: {
|
|
1422
|
+
profileUrlPattern: "https://sifa.id/p/{handle}"
|
|
1423
|
+
},
|
|
1424
|
+
popfeed: {
|
|
1425
|
+
urlPattern: "https://popfeed.social/profile/{handle}",
|
|
1426
|
+
profileUrlPattern: "https://popfeed.social/profile/{handle}"
|
|
1427
|
+
},
|
|
1428
|
+
streamplace: {
|
|
1429
|
+
profileUrlPattern: "https://stream.place/{handle}"
|
|
1430
|
+
},
|
|
1431
|
+
semble: {
|
|
1432
|
+
profileUrlPattern: "https://semble.so/profile/{handle}"
|
|
1433
|
+
},
|
|
1434
|
+
grain: {
|
|
1435
|
+
urlPattern: "https://grain.social/profile/{did}/gallery/{rkey}",
|
|
1436
|
+
profileUrlPattern: "https://grain.social/profile/{did}"
|
|
1437
|
+
},
|
|
1438
|
+
youandme: { profileUrlPattern: "https://youandme.at" },
|
|
1439
|
+
anisota: { profileUrlPattern: "https://anisota.net" },
|
|
1440
|
+
margin: { profileUrlPattern: "https://margin.at" },
|
|
1441
|
+
beaconbits: { profileUrlPattern: "https://beaconbits.app" },
|
|
1442
|
+
bookhive: { profileUrlPattern: "https://bookhive.buzz/profile/{handle}" },
|
|
1443
|
+
colibri: { profileUrlPattern: "https://colibri.social" },
|
|
1444
|
+
collectivesocial: { profileUrlPattern: "https://app.collectivesocial.app" },
|
|
1445
|
+
github: {}
|
|
1446
|
+
});
|
|
1447
|
+
var COLLECTION_TO_APP = [
|
|
1448
|
+
["app.bsky.", "bluesky"],
|
|
1449
|
+
["sh.tangled.", "tangled"],
|
|
1450
|
+
["events.smokesignal.", "smokesignal"],
|
|
1451
|
+
["community.lexicon.calendar.", "smokesignal"],
|
|
1452
|
+
["community.lexicon.bookmarks.", "kipclip"],
|
|
1453
|
+
["com.kipclip.", "kipclip"],
|
|
1454
|
+
["blue.flashes.", "flashes"],
|
|
1455
|
+
["social.grain.", "grain"],
|
|
1456
|
+
["com.whtwnd.", "whitewind"],
|
|
1457
|
+
["fyi.unravel.frontpage.", "frontpage"],
|
|
1458
|
+
["social.psky.", "picosky"],
|
|
1459
|
+
["blue.linkat.", "linkat"],
|
|
1460
|
+
["link.pastesphere.", "pastesphere"],
|
|
1461
|
+
["site.standard.", "standard"],
|
|
1462
|
+
["computer.aetheros.", "aetheros"],
|
|
1463
|
+
["space.roomy.", "roomy"],
|
|
1464
|
+
["dev.keytrace.", "keytrace"],
|
|
1465
|
+
["social.popfeed.", "popfeed"],
|
|
1466
|
+
["app.popsky.", "popfeed"],
|
|
1467
|
+
["place.stream.", "streamplace"],
|
|
1468
|
+
["app.sidetrail.", "semble"],
|
|
1469
|
+
["network.cosmik.", "cosmik"],
|
|
1470
|
+
["id.sifa.", "sifa"],
|
|
1471
|
+
["forum.barazo.", "barazo"],
|
|
1472
|
+
["xyz.statusphere.", "statusphere"],
|
|
1473
|
+
["at.youandme.", "youandme"],
|
|
1474
|
+
["net.anisota.", "anisota"],
|
|
1475
|
+
["at.margin.", "margin"],
|
|
1476
|
+
["app.beaconbits.", "beaconbits"],
|
|
1477
|
+
["buzz.bookhive.", "bookhive"],
|
|
1478
|
+
["social.colibri.", "colibri"]
|
|
1479
|
+
];
|
|
1480
|
+
|
|
1481
|
+
// src/cards/resolve-card-url.ts
|
|
1482
|
+
function getAppIdForCollection(collection) {
|
|
1483
|
+
for (const [prefix, appId] of COLLECTION_TO_APP) {
|
|
1484
|
+
if (collection.startsWith(prefix)) return appId;
|
|
1485
|
+
}
|
|
1486
|
+
const parts = collection.split(".");
|
|
1487
|
+
if (parts.length >= 2) return `${parts[0]}.${parts[1]}`;
|
|
1488
|
+
return collection;
|
|
1489
|
+
}
|
|
1490
|
+
function interpolate(pattern, vars) {
|
|
1491
|
+
let result = pattern;
|
|
1492
|
+
for (const [key, value] of Object.entries(vars)) {
|
|
1493
|
+
if (result.includes(`{${key}}`)) {
|
|
1494
|
+
if (!value) return null;
|
|
1495
|
+
result = result.replaceAll(`{${key}}`, encodeURIComponent(value));
|
|
1496
|
+
}
|
|
1497
|
+
}
|
|
1498
|
+
return result;
|
|
1499
|
+
}
|
|
1500
|
+
function patternUrl(appId, vars) {
|
|
1501
|
+
const patterns = APP_URL_PATTERNS[appId];
|
|
1502
|
+
if (!patterns) return null;
|
|
1503
|
+
if (patterns.urlPattern) {
|
|
1504
|
+
const url = interpolate(patterns.urlPattern, vars);
|
|
1505
|
+
if (url) return url;
|
|
1506
|
+
}
|
|
1507
|
+
if (patterns.profileUrlPattern) {
|
|
1508
|
+
const url = interpolate(patterns.profileUrlPattern, vars);
|
|
1509
|
+
if (url) return url;
|
|
1510
|
+
}
|
|
1511
|
+
return null;
|
|
1512
|
+
}
|
|
1513
|
+
function stringOrNull(value) {
|
|
1514
|
+
if (typeof value !== "string") return null;
|
|
1515
|
+
const trimmed = value.trim();
|
|
1516
|
+
return trimmed.length > 0 ? trimmed : null;
|
|
1517
|
+
}
|
|
1518
|
+
function parseAtUri(atUri) {
|
|
1519
|
+
const match = atUri.match(/^at:\/\/(did:[^/]+)\/[^/]+\/(.+)$/);
|
|
1520
|
+
if (!match || !match[1] || !match[2]) return null;
|
|
1521
|
+
return { did: match[1], rkey: match[2] };
|
|
1522
|
+
}
|
|
1523
|
+
function resolveCardUrl(item) {
|
|
1524
|
+
const { collection, record, uri, rkey, authorDid, authorHandle } = item;
|
|
1525
|
+
const appId = getAppIdForCollection(collection);
|
|
1526
|
+
if (collection.startsWith("sh.tangled.")) {
|
|
1527
|
+
const repoName = stringOrNull(record.name);
|
|
1528
|
+
if (repoName && authorHandle) {
|
|
1529
|
+
return `https://tangled.sh/${authorHandle}/${repoName}`;
|
|
1530
|
+
}
|
|
1531
|
+
return patternUrl("tangled", { handle: authorHandle, did: authorDid, rkey });
|
|
1532
|
+
}
|
|
1533
|
+
if (collection.startsWith("com.kipclip.") || collection.startsWith("community.lexicon.bookmarks.")) {
|
|
1534
|
+
const subject = stringOrNull(record.subject);
|
|
1535
|
+
if (subject) return subject;
|
|
1536
|
+
return patternUrl("kipclip", { handle: authorHandle, did: authorDid, rkey });
|
|
1537
|
+
}
|
|
1538
|
+
if (collection === "at.margin.bookmark") {
|
|
1539
|
+
const source = stringOrNull(record.source);
|
|
1540
|
+
if (source) return source;
|
|
1541
|
+
return null;
|
|
1542
|
+
}
|
|
1543
|
+
if (collection === "at.margin.annotation") {
|
|
1544
|
+
const target = record.target;
|
|
1545
|
+
if (target != null && typeof target === "object") {
|
|
1546
|
+
const source = stringOrNull(target.source);
|
|
1547
|
+
if (source) return source;
|
|
1548
|
+
}
|
|
1549
|
+
return APP_URL_PATTERNS.margin?.profileUrlPattern ?? null;
|
|
1550
|
+
}
|
|
1551
|
+
if (collection === "community.lexicon.calendar.rsvp") {
|
|
1552
|
+
const subject = record.subject;
|
|
1553
|
+
if (subject != null && typeof subject === "object") {
|
|
1554
|
+
const subjectUri = stringOrNull(subject.uri);
|
|
1555
|
+
if (subjectUri) {
|
|
1556
|
+
const parsed2 = parseAtUri(subjectUri);
|
|
1557
|
+
if (parsed2) {
|
|
1558
|
+
return `https://smokesignal.events/${parsed2.did}/${parsed2.rkey}`;
|
|
1559
|
+
}
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
return null;
|
|
1563
|
+
}
|
|
1564
|
+
if (collection === "community.lexicon.calendar.event") {
|
|
1565
|
+
const parsed2 = parseAtUri(uri);
|
|
1566
|
+
if (parsed2) {
|
|
1567
|
+
return `https://smokesignal.events/${parsed2.did}/${parsed2.rkey}`;
|
|
1568
|
+
}
|
|
1569
|
+
return null;
|
|
1570
|
+
}
|
|
1571
|
+
if (collection.startsWith("site.standard.")) {
|
|
1572
|
+
const siteUrl = stringOrNull(record.siteUrl);
|
|
1573
|
+
const path = stringOrNull(record.path);
|
|
1574
|
+
if (siteUrl && path) return `${siteUrl}${path}`;
|
|
1575
|
+
if (siteUrl) return siteUrl;
|
|
1576
|
+
}
|
|
1577
|
+
const recordUrl = stringOrNull(record.url);
|
|
1578
|
+
if (recordUrl) return recordUrl;
|
|
1579
|
+
return patternUrl(appId, { handle: authorHandle, did: authorDid, rkey });
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1014
1582
|
// src/logic/profile-completeness.ts
|
|
1015
1583
|
var COMPLETENESS_MAX_SCORE = 6;
|
|
1016
1584
|
function completenessScore(c) {
|
|
@@ -1231,10 +1799,13 @@ var ProfileVolunteeringRecordSchema = zod.z.object({
|
|
|
1231
1799
|
});
|
|
1232
1800
|
|
|
1233
1801
|
// src/index.ts
|
|
1234
|
-
var SIFA_SDK_VERSION = "0.9.
|
|
1802
|
+
var SIFA_SDK_VERSION = "0.9.5";
|
|
1235
1803
|
|
|
1804
|
+
exports.ACTIVITY_TIERS = ACTIVITY_TIERS;
|
|
1805
|
+
exports.APP_URL_PATTERNS = APP_URL_PATTERNS;
|
|
1236
1806
|
exports.CATEGORY_LABELS = CATEGORY_LABELS;
|
|
1237
1807
|
exports.CATEGORY_ORDER = CATEGORY_ORDER;
|
|
1808
|
+
exports.COLLECTION_TO_APP = COLLECTION_TO_APP;
|
|
1238
1809
|
exports.COMPLETENESS_MAX_SCORE = COMPLETENESS_MAX_SCORE;
|
|
1239
1810
|
exports.CONTINENTS = CONTINENTS;
|
|
1240
1811
|
exports.COUNTRIES = COUNTRIES;
|
|
@@ -1284,6 +1855,9 @@ exports.findIndustry = findIndustry;
|
|
|
1284
1855
|
exports.formatDistanceToNow = formatDistanceToNow;
|
|
1285
1856
|
exports.formatLocation = formatLocation;
|
|
1286
1857
|
exports.formatRelativeTime = formatRelativeTime;
|
|
1858
|
+
exports.getActivityTaxonomyVersion = getActivityTaxonomyVersion;
|
|
1859
|
+
exports.getActivityTier = getActivityTier;
|
|
1860
|
+
exports.getAppIdForCollection = getAppIdForCollection;
|
|
1287
1861
|
exports.getContinent = getContinent;
|
|
1288
1862
|
exports.getDisplayLabel = getDisplayLabel;
|
|
1289
1863
|
exports.getEmploymentTypeLabel = getEmploymentTypeLabel;
|
|
@@ -1291,22 +1865,27 @@ exports.getFaviconUrl = getFaviconUrl;
|
|
|
1291
1865
|
exports.getFilledDimensionsMap = getFilledDimensionsMap;
|
|
1292
1866
|
exports.getHandleStem = getHandleStem;
|
|
1293
1867
|
exports.getIndustryLabelKey = getIndustryLabelKey;
|
|
1868
|
+
exports.getLexiconEntry = getLexiconEntry;
|
|
1294
1869
|
exports.getOpenToLabelKey = getOpenToLabelKey;
|
|
1295
1870
|
exports.getPdsDisplayName = getPdsDisplayName;
|
|
1296
1871
|
exports.getPlatformLabel = getPlatformLabel;
|
|
1872
|
+
exports.getTierMeta = getTierMeta;
|
|
1297
1873
|
exports.getWorkplaceTypeLabel = getWorkplaceTypeLabel;
|
|
1298
1874
|
exports.groupSkillsByCategory = groupSkillsByCategory;
|
|
1299
1875
|
exports.isKnownPlatform = isKnownPlatform;
|
|
1300
1876
|
exports.isValidRgbColor = isValidRgbColor;
|
|
1301
1877
|
exports.languageTagSchema = languageTagSchema;
|
|
1302
1878
|
exports.lexiconDateExtractor = lexiconDateExtractor;
|
|
1879
|
+
exports.limitCombiningMarks = limitCombiningMarks;
|
|
1303
1880
|
exports.maxGraphemes = maxGraphemes;
|
|
1304
1881
|
exports.meetsContrastAA = meetsContrastAA;
|
|
1305
1882
|
exports.parseLocationString = parseLocationString;
|
|
1306
1883
|
exports.pdsProviderFromApi = pdsProviderFromApi;
|
|
1307
1884
|
exports.profileToDimensionInputs = profileToDimensionInputs;
|
|
1308
1885
|
exports.relativeLuminance = relativeLuminance;
|
|
1886
|
+
exports.resolveCardUrl = resolveCardUrl;
|
|
1309
1887
|
exports.rgbToString = rgbToString;
|
|
1888
|
+
exports.sanitizeDisplayText = sanitizeDisplayText;
|
|
1310
1889
|
exports.sanitizeHandleInput = sanitizeHandleInput;
|
|
1311
1890
|
exports.selfLabelsSchema = selfLabelsSchema;
|
|
1312
1891
|
exports.singleDateExtractor = singleDateExtractor;
|