@singi-labs/sifa-sdk 0.12.8 → 0.12.10
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/dist/index.cjs +808 -50
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +353 -2
- package/dist/index.d.ts +353 -2
- package/dist/index.js +793 -51
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2409,34 +2409,34 @@ function resolveCardHealth(item) {
|
|
|
2409
2409
|
if (subject != null && typeof subject === "object") {
|
|
2410
2410
|
const subjectUri = stringOrNull(subject.uri);
|
|
2411
2411
|
if (subjectUri) {
|
|
2412
|
-
const
|
|
2413
|
-
if (
|
|
2414
|
-
return urlHealth(`https://smokesignal.events/${
|
|
2412
|
+
const parsed3 = parseAtUri(subjectUri);
|
|
2413
|
+
if (parsed3) {
|
|
2414
|
+
return urlHealth(`https://smokesignal.events/${parsed3.did}/${parsed3.rkey}`);
|
|
2415
2415
|
}
|
|
2416
2416
|
}
|
|
2417
2417
|
}
|
|
2418
2418
|
return { url: null, strategy: "none" };
|
|
2419
2419
|
}
|
|
2420
2420
|
if (collection === "community.lexicon.calendar.event") {
|
|
2421
|
-
const
|
|
2422
|
-
if (
|
|
2423
|
-
return recordHealth(`https://smokesignal.events/${
|
|
2421
|
+
const parsed3 = parseAtUri(uri);
|
|
2422
|
+
if (parsed3) {
|
|
2423
|
+
return recordHealth(`https://smokesignal.events/${parsed3.did}/${parsed3.rkey}`);
|
|
2424
2424
|
}
|
|
2425
2425
|
return { url: null, strategy: "none" };
|
|
2426
2426
|
}
|
|
2427
2427
|
if (collection === "quest.atmo.event") {
|
|
2428
|
-
const
|
|
2429
|
-
if (
|
|
2430
|
-
return recordHealth(`https://atmo.rsvp/p/${
|
|
2428
|
+
const parsed3 = parseAtUri(uri);
|
|
2429
|
+
if (parsed3) {
|
|
2430
|
+
return recordHealth(`https://atmo.rsvp/p/${parsed3.did}/e/${parsed3.rkey}`);
|
|
2431
2431
|
}
|
|
2432
2432
|
return { url: null, strategy: "none" };
|
|
2433
2433
|
}
|
|
2434
2434
|
if (collection === "quest.atmo.checkin") {
|
|
2435
2435
|
const eventUri = stringOrNull(record.event);
|
|
2436
2436
|
if (eventUri) {
|
|
2437
|
-
const
|
|
2438
|
-
if (
|
|
2439
|
-
return urlHealth(`https://atmo.rsvp/p/${
|
|
2437
|
+
const parsed3 = parseAtUri(eventUri);
|
|
2438
|
+
if (parsed3) {
|
|
2439
|
+
return urlHealth(`https://atmo.rsvp/p/${parsed3.did}/e/${parsed3.rkey}`);
|
|
2440
2440
|
}
|
|
2441
2441
|
}
|
|
2442
2442
|
return { url: null, strategy: "none" };
|
|
@@ -2581,9 +2581,9 @@ function getPublisherFromSiteUrl(siteUrl) {
|
|
|
2581
2581
|
let hostname;
|
|
2582
2582
|
let homeUrl;
|
|
2583
2583
|
try {
|
|
2584
|
-
const
|
|
2585
|
-
hostname =
|
|
2586
|
-
homeUrl = `${
|
|
2584
|
+
const parsed3 = new URL(siteUrl);
|
|
2585
|
+
hostname = parsed3.hostname;
|
|
2586
|
+
homeUrl = `${parsed3.protocol}//${parsed3.hostname}`;
|
|
2587
2587
|
} catch {
|
|
2588
2588
|
return {
|
|
2589
2589
|
id: STANDARD_PUBLISHER_ID,
|
|
@@ -2602,6 +2602,780 @@ function getPublisherFromSiteUrl(siteUrl) {
|
|
|
2602
2602
|
};
|
|
2603
2603
|
}
|
|
2604
2604
|
|
|
2605
|
+
// src/stream/verbs.json
|
|
2606
|
+
var verbs_default = {
|
|
2607
|
+
$schema: "https://sifa.id/schemas/activity-verbs/v1.json",
|
|
2608
|
+
version: "1.0.0",
|
|
2609
|
+
updated: "2026-07-17",
|
|
2610
|
+
defaultVerb: "created",
|
|
2611
|
+
verbs: {
|
|
2612
|
+
"app.bsky.feed.post": "posted",
|
|
2613
|
+
"blue.flashes.feed.post": "posted",
|
|
2614
|
+
"social.psky.feed.post": "posted",
|
|
2615
|
+
"social.popfeed.feed.post": "posted",
|
|
2616
|
+
"social.popfeed.feed.note": "posted",
|
|
2617
|
+
"fyi.unravel.frontpage.post": "posted",
|
|
2618
|
+
"forum.barazo.post": "posted",
|
|
2619
|
+
"app.bsky.feed.repost": "reposted",
|
|
2620
|
+
"com.whtwnd.blog.entry": "published",
|
|
2621
|
+
"site.standard.document": "published",
|
|
2622
|
+
"computer.aetheros.page": "published",
|
|
2623
|
+
"link.pastesphere.snippet": "published",
|
|
2624
|
+
"pub.leaflet.comment": "published",
|
|
2625
|
+
"id.sifa.profile.presentation": "presented",
|
|
2626
|
+
"id.sifa.profile.presentationDelivery": "presented",
|
|
2627
|
+
"id.sifa.endorsement": "endorsed",
|
|
2628
|
+
"sh.tangled.repo": "shipped",
|
|
2629
|
+
"sh.tangled.repo.issue": "shipped",
|
|
2630
|
+
"sh.tangled.repo.pull": "shipped",
|
|
2631
|
+
"app.sidetrail.trail": "shipped",
|
|
2632
|
+
"app.sidetrail.walk": "shipped",
|
|
2633
|
+
"social.colibri.membership": "joined",
|
|
2634
|
+
"id.sifa.project.membership": "joined",
|
|
2635
|
+
"id.sifa.project.member": "joined",
|
|
2636
|
+
"community.lexicon.calendar.rsvp": "joined",
|
|
2637
|
+
"at.youandme.connection": "joined",
|
|
2638
|
+
"id.sifa.graph.connection": "joined"
|
|
2639
|
+
}
|
|
2640
|
+
};
|
|
2641
|
+
|
|
2642
|
+
// src/stream/verbs.ts
|
|
2643
|
+
var STREAM_VERBS = [
|
|
2644
|
+
"posted",
|
|
2645
|
+
"reposted",
|
|
2646
|
+
"published",
|
|
2647
|
+
"presented",
|
|
2648
|
+
"endorsed",
|
|
2649
|
+
"joined",
|
|
2650
|
+
"shipped",
|
|
2651
|
+
"created"
|
|
2652
|
+
];
|
|
2653
|
+
var streamVerbSchema = zod.z.enum(STREAM_VERBS);
|
|
2654
|
+
var verbMapSchema = zod.z.object({
|
|
2655
|
+
version: zod.z.string(),
|
|
2656
|
+
updated: zod.z.string(),
|
|
2657
|
+
defaultVerb: streamVerbSchema,
|
|
2658
|
+
verbs: zod.z.record(zod.z.string(), streamVerbSchema)
|
|
2659
|
+
});
|
|
2660
|
+
var parsed2 = verbMapSchema.parse(verbs_default);
|
|
2661
|
+
var ACTIVITY_VERBS = Object.freeze(parsed2);
|
|
2662
|
+
function verbForCollection(collection) {
|
|
2663
|
+
if (!collection) return ACTIVITY_VERBS.defaultVerb;
|
|
2664
|
+
return ACTIVITY_VERBS.verbs[collection] ?? ACTIVITY_VERBS.defaultVerb;
|
|
2665
|
+
}
|
|
2666
|
+
function getActivityVerbsVersion() {
|
|
2667
|
+
return { version: ACTIVITY_VERBS.version, updated: ACTIVITY_VERBS.updated };
|
|
2668
|
+
}
|
|
2669
|
+
var rgbChannelSchema = zod.z.number().min(0).max(255);
|
|
2670
|
+
var rgbColorSchema = zod.z.object({
|
|
2671
|
+
r: rgbChannelSchema,
|
|
2672
|
+
g: rgbChannelSchema,
|
|
2673
|
+
b: rgbChannelSchema
|
|
2674
|
+
});
|
|
2675
|
+
var aspectRatioSchema = zod.z.object({
|
|
2676
|
+
width: zod.z.number(),
|
|
2677
|
+
height: zod.z.number()
|
|
2678
|
+
});
|
|
2679
|
+
var streamSourceSchema = zod.z.object({
|
|
2680
|
+
appId: zod.z.string(),
|
|
2681
|
+
label: zod.z.string(),
|
|
2682
|
+
color: zod.z.string()
|
|
2683
|
+
});
|
|
2684
|
+
var streamThemeSchema = zod.z.object({
|
|
2685
|
+
background: rgbColorSchema,
|
|
2686
|
+
foreground: rgbColorSchema,
|
|
2687
|
+
accent: rgbColorSchema
|
|
2688
|
+
});
|
|
2689
|
+
var streamMediaResolvedSchema = zod.z.object({
|
|
2690
|
+
url: zod.z.string(),
|
|
2691
|
+
alt: zod.z.string(),
|
|
2692
|
+
aspectRatio: aspectRatioSchema.optional(),
|
|
2693
|
+
mimeType: zod.z.string().optional()
|
|
2694
|
+
});
|
|
2695
|
+
var streamMediaBlobSchema = zod.z.object({
|
|
2696
|
+
did: zod.z.string(),
|
|
2697
|
+
cid: zod.z.string(),
|
|
2698
|
+
alt: zod.z.string(),
|
|
2699
|
+
aspectRatio: aspectRatioSchema.optional(),
|
|
2700
|
+
mimeType: zod.z.string().optional()
|
|
2701
|
+
});
|
|
2702
|
+
var streamMediaSchema = zod.z.union([
|
|
2703
|
+
streamMediaResolvedSchema,
|
|
2704
|
+
streamMediaBlobSchema
|
|
2705
|
+
]);
|
|
2706
|
+
var streamExternalLinkSchema = zod.z.object({
|
|
2707
|
+
url: zod.z.string(),
|
|
2708
|
+
title: zod.z.string().optional(),
|
|
2709
|
+
thumb: zod.z.string().optional()
|
|
2710
|
+
});
|
|
2711
|
+
var streamGeoSchema = zod.z.object({
|
|
2712
|
+
latitude: zod.z.number(),
|
|
2713
|
+
longitude: zod.z.number()
|
|
2714
|
+
});
|
|
2715
|
+
var streamAddressSchema = zod.z.object({
|
|
2716
|
+
name: zod.z.string().optional(),
|
|
2717
|
+
street: zod.z.string().optional(),
|
|
2718
|
+
locality: zod.z.string().optional(),
|
|
2719
|
+
region: zod.z.string().optional(),
|
|
2720
|
+
country: zod.z.string().optional(),
|
|
2721
|
+
postalCode: zod.z.string().optional()
|
|
2722
|
+
});
|
|
2723
|
+
var streamCardBodySchema = zod.z.discriminatedUnion("kind", [
|
|
2724
|
+
zod.z.object({ kind: zod.z.literal("text"), text: zod.z.string() }),
|
|
2725
|
+
zod.z.object({ kind: zod.z.literal("media"), text: zod.z.string().optional() }),
|
|
2726
|
+
zod.z.object({ kind: zod.z.literal("link"), text: zod.z.string().optional() }),
|
|
2727
|
+
zod.z.object({
|
|
2728
|
+
kind: zod.z.literal("track"),
|
|
2729
|
+
text: zod.z.string().optional(),
|
|
2730
|
+
trackTitle: zod.z.string().optional(),
|
|
2731
|
+
artist: zod.z.string().optional()
|
|
2732
|
+
}),
|
|
2733
|
+
zod.z.object({ kind: zod.z.literal("generic"), text: zod.z.string().optional() }),
|
|
2734
|
+
zod.z.object({
|
|
2735
|
+
kind: zod.z.literal("github-pr"),
|
|
2736
|
+
repoOwner: zod.z.string(),
|
|
2737
|
+
repoName: zod.z.string(),
|
|
2738
|
+
prNumber: zod.z.number(),
|
|
2739
|
+
title: zod.z.string(),
|
|
2740
|
+
url: zod.z.string().optional(),
|
|
2741
|
+
language: zod.z.string().optional(),
|
|
2742
|
+
additions: zod.z.number(),
|
|
2743
|
+
deletions: zod.z.number(),
|
|
2744
|
+
mergedAt: zod.z.string().optional()
|
|
2745
|
+
}),
|
|
2746
|
+
zod.z.object({
|
|
2747
|
+
kind: zod.z.literal("book"),
|
|
2748
|
+
title: zod.z.string(),
|
|
2749
|
+
authors: zod.z.array(zod.z.string()),
|
|
2750
|
+
stars: zod.z.number().optional(),
|
|
2751
|
+
status: zod.z.string().optional(),
|
|
2752
|
+
review: zod.z.string().optional()
|
|
2753
|
+
}),
|
|
2754
|
+
zod.z.object({
|
|
2755
|
+
kind: zod.z.literal("media-review"),
|
|
2756
|
+
reviewKind: zod.z.enum(["review", "post", "note", "other"]),
|
|
2757
|
+
title: zod.z.string().optional(),
|
|
2758
|
+
mediaType: zod.z.string().optional(),
|
|
2759
|
+
rating: zod.z.number().optional(),
|
|
2760
|
+
mainCredit: zod.z.string().optional(),
|
|
2761
|
+
reviewText: zod.z.string().optional(),
|
|
2762
|
+
isRevisit: zod.z.boolean()
|
|
2763
|
+
}),
|
|
2764
|
+
zod.z.object({
|
|
2765
|
+
kind: zod.z.literal("event-rsvp"),
|
|
2766
|
+
rsvpStatus: zod.z.enum(["going", "interested", "notgoing", "unknown"]),
|
|
2767
|
+
eventName: zod.z.string().optional(),
|
|
2768
|
+
startsAt: zod.z.string().optional(),
|
|
2769
|
+
endsAt: zod.z.string().optional(),
|
|
2770
|
+
mode: zod.z.enum(["inperson", "virtual", "hybrid"]).optional(),
|
|
2771
|
+
locationName: zod.z.string().optional(),
|
|
2772
|
+
locationLocality: zod.z.string().optional(),
|
|
2773
|
+
locationCountry: zod.z.string().optional()
|
|
2774
|
+
}),
|
|
2775
|
+
zod.z.object({
|
|
2776
|
+
kind: zod.z.literal("verification"),
|
|
2777
|
+
platform: zod.z.string(),
|
|
2778
|
+
verified: zod.z.boolean(),
|
|
2779
|
+
subjectLabel: zod.z.string().optional(),
|
|
2780
|
+
handle: zod.z.string().optional(),
|
|
2781
|
+
profileUrl: zod.z.string().optional()
|
|
2782
|
+
}),
|
|
2783
|
+
zod.z.object({
|
|
2784
|
+
kind: zod.z.literal("membership"),
|
|
2785
|
+
communityName: zod.z.string().optional(),
|
|
2786
|
+
description: zod.z.string().optional(),
|
|
2787
|
+
communityUri: zod.z.string().optional()
|
|
2788
|
+
}),
|
|
2789
|
+
zod.z.object({
|
|
2790
|
+
kind: zod.z.literal("location"),
|
|
2791
|
+
venueName: zod.z.string().optional(),
|
|
2792
|
+
shout: zod.z.string().optional(),
|
|
2793
|
+
address: streamAddressSchema.optional(),
|
|
2794
|
+
geo: streamGeoSchema.optional()
|
|
2795
|
+
}),
|
|
2796
|
+
zod.z.object({
|
|
2797
|
+
kind: zod.z.literal("travel"),
|
|
2798
|
+
origin: zod.z.string().optional(),
|
|
2799
|
+
destination: zod.z.string().optional(),
|
|
2800
|
+
transportation: zod.z.string().optional(),
|
|
2801
|
+
carrier: zod.z.string().optional(),
|
|
2802
|
+
carrierCode: zod.z.string().optional(),
|
|
2803
|
+
startDate: zod.z.string().optional(),
|
|
2804
|
+
endDate: zod.z.string().optional()
|
|
2805
|
+
}),
|
|
2806
|
+
zod.z.object({
|
|
2807
|
+
kind: zod.z.literal("standard-site"),
|
|
2808
|
+
title: zod.z.string().optional(),
|
|
2809
|
+
description: zod.z.string().optional(),
|
|
2810
|
+
siteUrl: zod.z.string().optional(),
|
|
2811
|
+
path: zod.z.string().optional(),
|
|
2812
|
+
publisherName: zod.z.string().optional(),
|
|
2813
|
+
icon: zod.z.string().optional(),
|
|
2814
|
+
coverImageUrl: zod.z.string().optional(),
|
|
2815
|
+
readingTime: zod.z.number().optional(),
|
|
2816
|
+
publishedAt: zod.z.string().optional()
|
|
2817
|
+
})
|
|
2818
|
+
]);
|
|
2819
|
+
var streamCardSubjectSchema = zod.z.discriminatedUnion("kind", [
|
|
2820
|
+
zod.z.object({
|
|
2821
|
+
kind: zod.z.literal("post"),
|
|
2822
|
+
post: zod.z.lazy(() => streamCardVMSchema)
|
|
2823
|
+
}),
|
|
2824
|
+
zod.z.object({
|
|
2825
|
+
kind: zod.z.literal("person"),
|
|
2826
|
+
did: zod.z.string(),
|
|
2827
|
+
handle: zod.z.string().optional(),
|
|
2828
|
+
displayName: zod.z.string().optional(),
|
|
2829
|
+
avatar: zod.z.string().optional()
|
|
2830
|
+
}),
|
|
2831
|
+
zod.z.object({
|
|
2832
|
+
kind: zod.z.literal("record"),
|
|
2833
|
+
uri: zod.z.string(),
|
|
2834
|
+
title: zod.z.string().optional()
|
|
2835
|
+
})
|
|
2836
|
+
]);
|
|
2837
|
+
var streamCardVMSchema = zod.z.lazy(
|
|
2838
|
+
() => zod.z.object({
|
|
2839
|
+
uri: zod.z.string(),
|
|
2840
|
+
cid: zod.z.string(),
|
|
2841
|
+
verb: streamVerbSchema,
|
|
2842
|
+
source: streamSourceSchema,
|
|
2843
|
+
tier: zod.z.enum(["creation", "action", "filtered"]),
|
|
2844
|
+
timestamp: zod.z.string(),
|
|
2845
|
+
title: zod.z.string(),
|
|
2846
|
+
body: streamCardBodySchema.optional(),
|
|
2847
|
+
media: zod.z.array(streamMediaSchema).optional(),
|
|
2848
|
+
externalLink: streamExternalLinkSchema.optional(),
|
|
2849
|
+
theme: streamThemeSchema.optional(),
|
|
2850
|
+
subject: zod.z.lazy(() => streamCardSubjectSchema).optional()
|
|
2851
|
+
})
|
|
2852
|
+
);
|
|
2853
|
+
function maxGraphemes(max) {
|
|
2854
|
+
return (value) => {
|
|
2855
|
+
const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
2856
|
+
let count = 0;
|
|
2857
|
+
for (const _ of segmenter.segment(value)) {
|
|
2858
|
+
count++;
|
|
2859
|
+
if (count > max) return false;
|
|
2860
|
+
}
|
|
2861
|
+
return true;
|
|
2862
|
+
};
|
|
2863
|
+
}
|
|
2864
|
+
var didSchema = zod.z.string().regex(/^did:[a-z]+:[a-zA-Z0-9._:%-]+$/, "Invalid DID");
|
|
2865
|
+
var datetimeSchema = zod.z.string().datetime({ offset: true });
|
|
2866
|
+
var partialDateSchema = zod.z.string().regex(/^\d{4}(-\d{2}(-\d{2}(T.+)?)?)?$/, "Expected YYYY, YYYY-MM, YYYY-MM-DD, or a datetime");
|
|
2867
|
+
var atUriSchema = zod.z.string().regex(/^at:\/\/[^\s]+$/, "Invalid AT-URI");
|
|
2868
|
+
var cidSchema = zod.z.string().regex(/^(Qm[1-9A-HJ-NP-Za-km-z]{44}|b[A-Za-z0-9+/=]+)$/, "Invalid CID");
|
|
2869
|
+
var languageTagSchema = zod.z.string().regex(/^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/, "Invalid BCP 47 language tag");
|
|
2870
|
+
var uriSchema = zod.z.string().url();
|
|
2871
|
+
var strongRefSchema = zod.z.object({
|
|
2872
|
+
uri: atUriSchema,
|
|
2873
|
+
cid: cidSchema
|
|
2874
|
+
});
|
|
2875
|
+
var externalRecordRefSchema = zod.z.object({
|
|
2876
|
+
uri: atUriSchema,
|
|
2877
|
+
cid: cidSchema.optional()
|
|
2878
|
+
});
|
|
2879
|
+
var selfLabelsSchema = zod.z.object({
|
|
2880
|
+
$type: zod.z.literal("com.atproto.label.defs#selfLabels").optional(),
|
|
2881
|
+
values: zod.z.array(zod.z.object({ val: zod.z.string() }))
|
|
2882
|
+
});
|
|
2883
|
+
|
|
2884
|
+
// src/publishing/registry.ts
|
|
2885
|
+
var STANDARD_SITE_PUBLISHERS = Object.freeze([
|
|
2886
|
+
{ host: "leaflet.pub", name: "Leaflet", iconKey: "leaflet" },
|
|
2887
|
+
{ host: "pckt.blog", name: "pckt", iconKey: "pckt" },
|
|
2888
|
+
{ host: "offprint.app", name: "Offprint", iconKey: "offprint" }
|
|
2889
|
+
]);
|
|
2890
|
+
function hostMatches(host, target) {
|
|
2891
|
+
return host === target || host.endsWith("." + target);
|
|
2892
|
+
}
|
|
2893
|
+
function hostFromUri(uri) {
|
|
2894
|
+
if (!uri) return null;
|
|
2895
|
+
try {
|
|
2896
|
+
return new URL(uri).host.toLowerCase();
|
|
2897
|
+
} catch {
|
|
2898
|
+
return null;
|
|
2899
|
+
}
|
|
2900
|
+
}
|
|
2901
|
+
function matchPublisherByHost(host) {
|
|
2902
|
+
if (!host) return null;
|
|
2903
|
+
const lower = host.toLowerCase();
|
|
2904
|
+
return STANDARD_SITE_PUBLISHERS.find((p) => hostMatches(lower, p.host)) ?? null;
|
|
2905
|
+
}
|
|
2906
|
+
function matchPublisherByUri(uri) {
|
|
2907
|
+
return matchPublisherByHost(hostFromUri(uri));
|
|
2908
|
+
}
|
|
2909
|
+
|
|
2910
|
+
// src/stream/to-stream-card-vm.ts
|
|
2911
|
+
var DEFAULT_SOURCE_COLOR = "slate";
|
|
2912
|
+
function asRecord(value) {
|
|
2913
|
+
return value !== null && typeof value === "object" ? value : null;
|
|
2914
|
+
}
|
|
2915
|
+
function asNonEmptyString(value) {
|
|
2916
|
+
return typeof value === "string" && value.length > 0 ? value : void 0;
|
|
2917
|
+
}
|
|
2918
|
+
function didFromUri(uri) {
|
|
2919
|
+
const match = uri.match(/^at:\/\/(did:[^/]+)\//);
|
|
2920
|
+
return match?.[1];
|
|
2921
|
+
}
|
|
2922
|
+
function blobCid(blob) {
|
|
2923
|
+
const rec = asRecord(blob);
|
|
2924
|
+
if (!rec) return void 0;
|
|
2925
|
+
const ref = rec.ref;
|
|
2926
|
+
if (typeof ref === "string") return ref;
|
|
2927
|
+
const link2 = asRecord(ref)?.["$link"];
|
|
2928
|
+
return typeof link2 === "string" ? link2 : void 0;
|
|
2929
|
+
}
|
|
2930
|
+
function aspectRatio(value) {
|
|
2931
|
+
const rec = asRecord(value);
|
|
2932
|
+
const width = rec?.width;
|
|
2933
|
+
const height = rec?.height;
|
|
2934
|
+
if (typeof width === "number" && typeof height === "number") return { width, height };
|
|
2935
|
+
return void 0;
|
|
2936
|
+
}
|
|
2937
|
+
function asFiniteNumber(value) {
|
|
2938
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2939
|
+
}
|
|
2940
|
+
function looseBlobCid(value) {
|
|
2941
|
+
const viaRef = blobCid(value);
|
|
2942
|
+
if (viaRef) return viaRef;
|
|
2943
|
+
const cid = asRecord(value)?.cid;
|
|
2944
|
+
return typeof cid === "string" && cid.length > 0 ? cid : void 0;
|
|
2945
|
+
}
|
|
2946
|
+
function blobMedia(value, did, alt) {
|
|
2947
|
+
const cid = looseBlobCid(value);
|
|
2948
|
+
if (!cid) return void 0;
|
|
2949
|
+
const media = { did, cid, alt };
|
|
2950
|
+
const ratio = aspectRatio(asRecord(value)?.aspectRatio);
|
|
2951
|
+
if (ratio) media.aspectRatio = ratio;
|
|
2952
|
+
const mimeType = asNonEmptyString(asRecord(value)?.mimeType);
|
|
2953
|
+
if (mimeType) media.mimeType = mimeType;
|
|
2954
|
+
return media;
|
|
2955
|
+
}
|
|
2956
|
+
function hashSuffix(value) {
|
|
2957
|
+
const i = value.lastIndexOf("#");
|
|
2958
|
+
return i >= 0 ? value.slice(i) : "";
|
|
2959
|
+
}
|
|
2960
|
+
var WORDS_PER_MINUTE = 200;
|
|
2961
|
+
function estimateReadingTime(text) {
|
|
2962
|
+
if (!text) return void 0;
|
|
2963
|
+
const words = text.trim().split(/\s+/).filter(Boolean).length;
|
|
2964
|
+
if (words === 0) return void 0;
|
|
2965
|
+
return Math.max(1, Math.round(words / WORDS_PER_MINUTE));
|
|
2966
|
+
}
|
|
2967
|
+
function beaconGeo(value) {
|
|
2968
|
+
const rec = asRecord(value);
|
|
2969
|
+
if (!rec) return void 0;
|
|
2970
|
+
const { latitude, longitude } = rec;
|
|
2971
|
+
const okType = (v) => typeof v === "string" || typeof v === "number";
|
|
2972
|
+
if (!okType(latitude) || !okType(longitude)) return void 0;
|
|
2973
|
+
const lat = Number(latitude);
|
|
2974
|
+
const lng = Number(longitude);
|
|
2975
|
+
if (!Number.isFinite(lat) || !Number.isFinite(lng)) return void 0;
|
|
2976
|
+
return { latitude: lat, longitude: lng };
|
|
2977
|
+
}
|
|
2978
|
+
function beaconAddress(value) {
|
|
2979
|
+
const rec = asRecord(value);
|
|
2980
|
+
if (!rec) return void 0;
|
|
2981
|
+
const address = {};
|
|
2982
|
+
const name = asNonEmptyString(rec.name);
|
|
2983
|
+
if (name) address.name = name;
|
|
2984
|
+
const street = asNonEmptyString(rec.street);
|
|
2985
|
+
if (street) address.street = street;
|
|
2986
|
+
const locality = asNonEmptyString(rec.locality);
|
|
2987
|
+
if (locality) address.locality = locality;
|
|
2988
|
+
const region = asNonEmptyString(rec.region);
|
|
2989
|
+
if (region) address.region = region;
|
|
2990
|
+
const country = asNonEmptyString(rec.country);
|
|
2991
|
+
if (country) address.country = country;
|
|
2992
|
+
const postalCode = asNonEmptyString(rec.postalCode);
|
|
2993
|
+
if (postalCode) address.postalCode = postalCode;
|
|
2994
|
+
return Object.keys(address).length > 0 ? address : void 0;
|
|
2995
|
+
}
|
|
2996
|
+
function parseAuthors(value) {
|
|
2997
|
+
if (typeof value !== "string") return [];
|
|
2998
|
+
return value.split(" ").map((a) => a.trim()).filter((a) => a.length > 0);
|
|
2999
|
+
}
|
|
3000
|
+
function buildSource(item, options) {
|
|
3001
|
+
return {
|
|
3002
|
+
appId: item.appId,
|
|
3003
|
+
label: item.appName,
|
|
3004
|
+
color: options.resolveSourceColor?.(item.appId) ?? DEFAULT_SOURCE_COLOR
|
|
3005
|
+
};
|
|
3006
|
+
}
|
|
3007
|
+
var TITLE_BY_VERB = {
|
|
3008
|
+
posted: (label) => `Posted on ${label}`,
|
|
3009
|
+
reposted: () => "Reposted a post",
|
|
3010
|
+
published: (label) => `Published on ${label}`,
|
|
3011
|
+
presented: () => "Gave a presentation",
|
|
3012
|
+
endorsed: () => "Wrote an endorsement",
|
|
3013
|
+
joined: (label) => `Joined ${label}`,
|
|
3014
|
+
shipped: (label) => `Shipped on ${label}`,
|
|
3015
|
+
created: (label) => `Created a record on ${label}`
|
|
3016
|
+
};
|
|
3017
|
+
function buildTitle(verb, label) {
|
|
3018
|
+
return TITLE_BY_VERB[verb](label);
|
|
3019
|
+
}
|
|
3020
|
+
function readTheme(record) {
|
|
3021
|
+
const theme = asRecord(record?.publicationTheme ?? record?.theme);
|
|
3022
|
+
if (!theme) return void 0;
|
|
3023
|
+
const { background, foreground, accent } = theme;
|
|
3024
|
+
if (isValidRgbColor(background) && isValidRgbColor(foreground) && isValidRgbColor(accent)) {
|
|
3025
|
+
return { background, foreground, accent };
|
|
3026
|
+
}
|
|
3027
|
+
return void 0;
|
|
3028
|
+
}
|
|
3029
|
+
function bskyImages(embed, did) {
|
|
3030
|
+
const images = embed.images;
|
|
3031
|
+
if (!Array.isArray(images)) return [];
|
|
3032
|
+
const out = [];
|
|
3033
|
+
for (const raw of images) {
|
|
3034
|
+
const img = asRecord(raw);
|
|
3035
|
+
if (!img) continue;
|
|
3036
|
+
const cid = blobCid(img.image);
|
|
3037
|
+
if (!cid) continue;
|
|
3038
|
+
const media = { did, cid, alt: asNonEmptyString(img.alt) ?? "" };
|
|
3039
|
+
const ratio = aspectRatio(img.aspectRatio);
|
|
3040
|
+
if (ratio) media.aspectRatio = ratio;
|
|
3041
|
+
const mimeType = asNonEmptyString(asRecord(img.image)?.mimeType);
|
|
3042
|
+
if (mimeType) media.mimeType = mimeType;
|
|
3043
|
+
out.push(media);
|
|
3044
|
+
}
|
|
3045
|
+
return out;
|
|
3046
|
+
}
|
|
3047
|
+
function bskyExternal(embed) {
|
|
3048
|
+
const external = asRecord(embed.external);
|
|
3049
|
+
if (!external) return void 0;
|
|
3050
|
+
const url = asNonEmptyString(external.uri);
|
|
3051
|
+
if (!url) return void 0;
|
|
3052
|
+
const link2 = { url };
|
|
3053
|
+
const title = asNonEmptyString(external.title);
|
|
3054
|
+
if (title) link2.title = title;
|
|
3055
|
+
return link2;
|
|
3056
|
+
}
|
|
3057
|
+
function bskyEmbedContent(record, did) {
|
|
3058
|
+
const embed = asRecord(record.embed);
|
|
3059
|
+
if (!embed) return {};
|
|
3060
|
+
const type = asNonEmptyString(embed["$type"]);
|
|
3061
|
+
const target = type === "app.bsky.embed.recordWithMedia" ? asRecord(embed.media) : embed;
|
|
3062
|
+
if (!target) return {};
|
|
3063
|
+
if (Array.isArray(target.images)) {
|
|
3064
|
+
const media = bskyImages(target, did);
|
|
3065
|
+
return media.length > 0 ? { media } : {};
|
|
3066
|
+
}
|
|
3067
|
+
if (target.external != null) {
|
|
3068
|
+
const externalLink = bskyExternal(target);
|
|
3069
|
+
return externalLink ? { externalLink } : {};
|
|
3070
|
+
}
|
|
3071
|
+
return {};
|
|
3072
|
+
}
|
|
3073
|
+
function applyBskyPost(vm, item, record) {
|
|
3074
|
+
if (!record) {
|
|
3075
|
+
vm.body = { kind: "generic" };
|
|
3076
|
+
return vm;
|
|
3077
|
+
}
|
|
3078
|
+
const did = didFromUri(item.uri);
|
|
3079
|
+
const text = asNonEmptyString(record.text);
|
|
3080
|
+
const { media, externalLink } = did ? bskyEmbedContent(record, did) : {};
|
|
3081
|
+
if (media) vm.media = media;
|
|
3082
|
+
if (externalLink) vm.externalLink = externalLink;
|
|
3083
|
+
let body;
|
|
3084
|
+
if (text) body = { kind: "text", text };
|
|
3085
|
+
else if (vm.media) body = { kind: "media" };
|
|
3086
|
+
else if (vm.externalLink) body = { kind: "link" };
|
|
3087
|
+
else body = { kind: "generic" };
|
|
3088
|
+
vm.body = body;
|
|
3089
|
+
return vm;
|
|
3090
|
+
}
|
|
3091
|
+
function withGeneric(vm) {
|
|
3092
|
+
vm.body = { kind: "generic" };
|
|
3093
|
+
return vm;
|
|
3094
|
+
}
|
|
3095
|
+
function applyGithubPr(vm, record) {
|
|
3096
|
+
const body = {
|
|
3097
|
+
kind: "github-pr",
|
|
3098
|
+
repoOwner: asNonEmptyString(record.repoOwner) ?? "",
|
|
3099
|
+
repoName: asNonEmptyString(record.repoName) ?? "",
|
|
3100
|
+
prNumber: asFiniteNumber(record.prNumber) ?? 0,
|
|
3101
|
+
title: asNonEmptyString(record.title) ?? "",
|
|
3102
|
+
additions: asFiniteNumber(record.additions) ?? 0,
|
|
3103
|
+
deletions: asFiniteNumber(record.deletions) ?? 0
|
|
3104
|
+
};
|
|
3105
|
+
const url = asNonEmptyString(record.url);
|
|
3106
|
+
if (url) body.url = url;
|
|
3107
|
+
const language = asNonEmptyString(record.language);
|
|
3108
|
+
if (language) body.language = language;
|
|
3109
|
+
const mergedAt = asNonEmptyString(record.mergedAt);
|
|
3110
|
+
if (mergedAt) body.mergedAt = mergedAt;
|
|
3111
|
+
vm.body = body;
|
|
3112
|
+
return vm;
|
|
3113
|
+
}
|
|
3114
|
+
function applyBook(vm, item, record) {
|
|
3115
|
+
const title = asNonEmptyString(record.title) ?? "Untitled book";
|
|
3116
|
+
const body = {
|
|
3117
|
+
kind: "book",
|
|
3118
|
+
title,
|
|
3119
|
+
authors: parseAuthors(record.authors)
|
|
3120
|
+
};
|
|
3121
|
+
const stars = asFiniteNumber(record.stars);
|
|
3122
|
+
if (stars !== void 0 && stars > 0) body.stars = stars;
|
|
3123
|
+
const status = asNonEmptyString(record.status);
|
|
3124
|
+
if (status) body.status = status;
|
|
3125
|
+
const review = asNonEmptyString(
|
|
3126
|
+
typeof record.review === "string" ? record.review.trim() : void 0
|
|
3127
|
+
);
|
|
3128
|
+
if (review) body.review = review;
|
|
3129
|
+
vm.body = body;
|
|
3130
|
+
const did = didFromUri(item.uri);
|
|
3131
|
+
if (did) {
|
|
3132
|
+
const cover = blobMedia(record.cover, did, `The cover of ${title}`);
|
|
3133
|
+
if (cover) vm.media = [cover];
|
|
3134
|
+
}
|
|
3135
|
+
return vm;
|
|
3136
|
+
}
|
|
3137
|
+
function popfeedReviewKind(collection) {
|
|
3138
|
+
if (collection.endsWith(".review")) return "review";
|
|
3139
|
+
if (collection.endsWith(".post")) return "post";
|
|
3140
|
+
if (collection.endsWith(".note")) return "note";
|
|
3141
|
+
return "other";
|
|
3142
|
+
}
|
|
3143
|
+
function applyMediaReview(vm, item, record) {
|
|
3144
|
+
const title = asNonEmptyString(record.title) ?? asNonEmptyString(record.name);
|
|
3145
|
+
const body = {
|
|
3146
|
+
kind: "media-review",
|
|
3147
|
+
reviewKind: popfeedReviewKind(item.collection),
|
|
3148
|
+
isRevisit: record.isRevisit === true
|
|
3149
|
+
};
|
|
3150
|
+
if (title) body.title = title;
|
|
3151
|
+
const mediaType = asNonEmptyString(record.creativeWorkType);
|
|
3152
|
+
if (mediaType) body.mediaType = mediaType;
|
|
3153
|
+
const rating = asFiniteNumber(record.rating);
|
|
3154
|
+
if (rating !== void 0) body.rating = rating;
|
|
3155
|
+
const mainCredit = asNonEmptyString(record.mainCredit);
|
|
3156
|
+
if (mainCredit) body.mainCredit = mainCredit;
|
|
3157
|
+
const reviewText = asNonEmptyString(record.text);
|
|
3158
|
+
if (reviewText) body.reviewText = reviewText;
|
|
3159
|
+
vm.body = body;
|
|
3160
|
+
const posterUrl = asNonEmptyString(record.posterUrl);
|
|
3161
|
+
if (posterUrl) vm.media = [{ url: posterUrl, alt: title ? `${title} poster` : "" }];
|
|
3162
|
+
return vm;
|
|
3163
|
+
}
|
|
3164
|
+
var RSVP_STATUS = {
|
|
3165
|
+
"#going": "going",
|
|
3166
|
+
"#interested": "interested",
|
|
3167
|
+
"#notgoing": "notgoing"
|
|
3168
|
+
};
|
|
3169
|
+
var RSVP_MODE = {
|
|
3170
|
+
"#inperson": "inperson",
|
|
3171
|
+
"#virtual": "virtual",
|
|
3172
|
+
"#hybrid": "hybrid"
|
|
3173
|
+
};
|
|
3174
|
+
function applyEventRsvp(vm, record) {
|
|
3175
|
+
const status = asNonEmptyString(record.status);
|
|
3176
|
+
const body = {
|
|
3177
|
+
kind: "event-rsvp",
|
|
3178
|
+
rsvpStatus: (status ? RSVP_STATUS[hashSuffix(status)] : void 0) ?? "unknown"
|
|
3179
|
+
};
|
|
3180
|
+
const meta = asRecord(record.eventMeta);
|
|
3181
|
+
if (meta) {
|
|
3182
|
+
const eventName = asNonEmptyString(meta.name);
|
|
3183
|
+
if (eventName) body.eventName = eventName;
|
|
3184
|
+
const startsAt = asNonEmptyString(meta.startsAt);
|
|
3185
|
+
if (startsAt) body.startsAt = startsAt;
|
|
3186
|
+
const endsAt = asNonEmptyString(meta.endsAt);
|
|
3187
|
+
if (endsAt) body.endsAt = endsAt;
|
|
3188
|
+
const mode = asNonEmptyString(meta.mode);
|
|
3189
|
+
const modeEnum = mode ? RSVP_MODE[hashSuffix(mode)] : void 0;
|
|
3190
|
+
if (modeEnum) body.mode = modeEnum;
|
|
3191
|
+
const locationName = asNonEmptyString(meta.locationName);
|
|
3192
|
+
if (locationName) body.locationName = locationName;
|
|
3193
|
+
const locationLocality = asNonEmptyString(meta.locationLocality);
|
|
3194
|
+
if (locationLocality) body.locationLocality = locationLocality;
|
|
3195
|
+
const locationCountry = asNonEmptyString(meta.locationCountry);
|
|
3196
|
+
if (locationCountry) body.locationCountry = locationCountry;
|
|
3197
|
+
}
|
|
3198
|
+
vm.body = body;
|
|
3199
|
+
return vm;
|
|
3200
|
+
}
|
|
3201
|
+
function applyKeytraceVerification(vm, record) {
|
|
3202
|
+
const identity = asRecord(record.identity) ?? {};
|
|
3203
|
+
const subject = asNonEmptyString(identity.subject);
|
|
3204
|
+
const displayName = asNonEmptyString(identity.displayName);
|
|
3205
|
+
const body = {
|
|
3206
|
+
kind: "verification",
|
|
3207
|
+
platform: asNonEmptyString(record.type) ?? "unknown",
|
|
3208
|
+
verified: record.status === "verified"
|
|
3209
|
+
};
|
|
3210
|
+
const subjectLabel = displayName ?? subject;
|
|
3211
|
+
if (subjectLabel) body.subjectLabel = subjectLabel;
|
|
3212
|
+
const profileUrl = asNonEmptyString(identity.profileUrl);
|
|
3213
|
+
if (profileUrl) body.profileUrl = profileUrl;
|
|
3214
|
+
vm.body = body;
|
|
3215
|
+
return vm;
|
|
3216
|
+
}
|
|
3217
|
+
function applyBskyVerification(vm, record) {
|
|
3218
|
+
const handle = asNonEmptyString(record.handle);
|
|
3219
|
+
const displayName = asNonEmptyString(record.displayName);
|
|
3220
|
+
const body = {
|
|
3221
|
+
kind: "verification",
|
|
3222
|
+
platform: "bluesky",
|
|
3223
|
+
verified: true
|
|
3224
|
+
};
|
|
3225
|
+
const subjectLabel = displayName ?? handle;
|
|
3226
|
+
if (subjectLabel) body.subjectLabel = subjectLabel;
|
|
3227
|
+
if (handle) body.handle = handle;
|
|
3228
|
+
vm.body = body;
|
|
3229
|
+
return vm;
|
|
3230
|
+
}
|
|
3231
|
+
function applyMembership(vm, record) {
|
|
3232
|
+
const body = { kind: "membership" };
|
|
3233
|
+
const communityUri = asNonEmptyString(record.community);
|
|
3234
|
+
if (communityUri) body.communityUri = communityUri;
|
|
3235
|
+
const meta = asRecord(record.communityMeta);
|
|
3236
|
+
const communityName = meta ? asNonEmptyString(meta.name) : void 0;
|
|
3237
|
+
if (communityName) body.communityName = communityName;
|
|
3238
|
+
const description = meta ? asNonEmptyString(meta.description) : void 0;
|
|
3239
|
+
if (description) body.description = description;
|
|
3240
|
+
vm.body = body;
|
|
3241
|
+
if (meta) {
|
|
3242
|
+
const ownerDid = asNonEmptyString(meta.ownerDid) ?? (communityUri ? didFromUri(communityUri) : void 0);
|
|
3243
|
+
if (ownerDid) {
|
|
3244
|
+
const picture = blobMedia(meta.picture, ownerDid, communityName ?? "");
|
|
3245
|
+
if (picture) vm.media = [picture];
|
|
3246
|
+
}
|
|
3247
|
+
}
|
|
3248
|
+
return vm;
|
|
3249
|
+
}
|
|
3250
|
+
function applyLocation(vm, record) {
|
|
3251
|
+
const body = { kind: "location" };
|
|
3252
|
+
const venueName = asNonEmptyString(record.venueName);
|
|
3253
|
+
if (venueName) body.venueName = venueName;
|
|
3254
|
+
const shout = asNonEmptyString(record.shout);
|
|
3255
|
+
if (shout) body.shout = shout;
|
|
3256
|
+
const address = beaconAddress(record.addressDetails);
|
|
3257
|
+
if (address) body.address = address;
|
|
3258
|
+
const geo = beaconGeo(record.location);
|
|
3259
|
+
if (geo) body.geo = geo;
|
|
3260
|
+
vm.body = body;
|
|
3261
|
+
return vm;
|
|
3262
|
+
}
|
|
3263
|
+
function applyTravel(vm, record) {
|
|
3264
|
+
const body = { kind: "travel" };
|
|
3265
|
+
const origin = asNonEmptyString(record.originTransportCode);
|
|
3266
|
+
if (origin) body.origin = origin;
|
|
3267
|
+
const destination = asNonEmptyString(record.destinationTransportCode);
|
|
3268
|
+
if (destination) body.destination = destination;
|
|
3269
|
+
const transportation = asNonEmptyString(record.transportation);
|
|
3270
|
+
if (transportation) body.transportation = transportation;
|
|
3271
|
+
const carrier = asNonEmptyString(record.carrier);
|
|
3272
|
+
if (carrier) body.carrier = carrier;
|
|
3273
|
+
const carrierCode = asNonEmptyString(record.carrierCode);
|
|
3274
|
+
if (carrierCode) body.carrierCode = carrierCode;
|
|
3275
|
+
const startDate = asNonEmptyString(record.startDate);
|
|
3276
|
+
if (startDate) body.startDate = startDate;
|
|
3277
|
+
const endDate = asNonEmptyString(record.endDate);
|
|
3278
|
+
if (endDate) body.endDate = endDate;
|
|
3279
|
+
vm.body = body;
|
|
3280
|
+
return vm;
|
|
3281
|
+
}
|
|
3282
|
+
function applyStandardSite(vm, record) {
|
|
3283
|
+
const body = { kind: "standard-site" };
|
|
3284
|
+
const title = asNonEmptyString(record.title);
|
|
3285
|
+
if (title) body.title = title;
|
|
3286
|
+
const description = asNonEmptyString(record.description);
|
|
3287
|
+
if (description) body.description = description;
|
|
3288
|
+
const siteUrl = asNonEmptyString(record.siteUrl);
|
|
3289
|
+
if (siteUrl) {
|
|
3290
|
+
body.siteUrl = siteUrl;
|
|
3291
|
+
const publisherName = matchPublisherByUri(siteUrl)?.name;
|
|
3292
|
+
if (publisherName) body.publisherName = publisherName;
|
|
3293
|
+
}
|
|
3294
|
+
const path = asNonEmptyString(record.path);
|
|
3295
|
+
if (path) body.path = path;
|
|
3296
|
+
const icon = asNonEmptyString(record.publicationIcon);
|
|
3297
|
+
if (icon) body.icon = icon;
|
|
3298
|
+
const coverImageUrl = asNonEmptyString(record.coverImageUrl);
|
|
3299
|
+
if (coverImageUrl) body.coverImageUrl = coverImageUrl;
|
|
3300
|
+
const readingTime = estimateReadingTime(asNonEmptyString(record.textContent));
|
|
3301
|
+
if (readingTime !== void 0) body.readingTime = readingTime;
|
|
3302
|
+
const publishedAt = asNonEmptyString(record.publishedAt);
|
|
3303
|
+
if (publishedAt) body.publishedAt = publishedAt;
|
|
3304
|
+
vm.body = body;
|
|
3305
|
+
return vm;
|
|
3306
|
+
}
|
|
3307
|
+
function applyYouAndMe(vm, record) {
|
|
3308
|
+
const did = asNonEmptyString(record.subject);
|
|
3309
|
+
if (did) vm.subject = { kind: "person", did };
|
|
3310
|
+
vm.body = { kind: "generic" };
|
|
3311
|
+
return vm;
|
|
3312
|
+
}
|
|
3313
|
+
function applyAsqAnswer(vm, record) {
|
|
3314
|
+
const uri = asNonEmptyString(asRecord(record.subject)?.uri);
|
|
3315
|
+
if (uri) vm.subject = { kind: "record", uri };
|
|
3316
|
+
vm.body = { kind: "generic" };
|
|
3317
|
+
return vm;
|
|
3318
|
+
}
|
|
3319
|
+
function toStreamCardVM(item, options = {}) {
|
|
3320
|
+
const verb = verbForCollection(item.collection);
|
|
3321
|
+
const source = buildSource(item, options);
|
|
3322
|
+
const record = asRecord(item.record);
|
|
3323
|
+
const timestamp = (record ? asNonEmptyString(record.createdAt) : void 0) ?? item.indexedAt;
|
|
3324
|
+
const vm = {
|
|
3325
|
+
uri: item.uri,
|
|
3326
|
+
cid: item.cid,
|
|
3327
|
+
verb,
|
|
3328
|
+
source,
|
|
3329
|
+
tier: getActivityTier(item.collection),
|
|
3330
|
+
timestamp,
|
|
3331
|
+
title: buildTitle(verb, source.label)
|
|
3332
|
+
};
|
|
3333
|
+
const theme = readTheme(record);
|
|
3334
|
+
if (theme) vm.theme = theme;
|
|
3335
|
+
if (item.subject) {
|
|
3336
|
+
vm.subject = { kind: "post", post: toStreamCardVM(item.subject, options) };
|
|
3337
|
+
}
|
|
3338
|
+
switch (item.collection) {
|
|
3339
|
+
case "app.bsky.feed.post":
|
|
3340
|
+
return applyBskyPost(vm, item, record);
|
|
3341
|
+
case "github.pull_request":
|
|
3342
|
+
return record ? applyGithubPr(vm, record) : withGeneric(vm);
|
|
3343
|
+
case "buzz.bookhive.book":
|
|
3344
|
+
return record ? applyBook(vm, item, record) : withGeneric(vm);
|
|
3345
|
+
case "community.lexicon.calendar.rsvp":
|
|
3346
|
+
return record ? applyEventRsvp(vm, record) : withGeneric(vm);
|
|
3347
|
+
case "dev.keytrace.claim":
|
|
3348
|
+
return record ? applyKeytraceVerification(vm, record) : withGeneric(vm);
|
|
3349
|
+
case "app.bsky.graph.verification":
|
|
3350
|
+
return record ? applyBskyVerification(vm, record) : withGeneric(vm);
|
|
3351
|
+
case "social.colibri.membership":
|
|
3352
|
+
return record ? applyMembership(vm, record) : withGeneric(vm);
|
|
3353
|
+
case "app.beaconbits.beacon":
|
|
3354
|
+
return record ? applyLocation(vm, record) : withGeneric(vm);
|
|
3355
|
+
case "social.passports.travel.leg":
|
|
3356
|
+
return record ? applyTravel(vm, record) : withGeneric(vm);
|
|
3357
|
+
case "site.standard.document":
|
|
3358
|
+
return record ? applyStandardSite(vm, record) : withGeneric(vm);
|
|
3359
|
+
case "at.youandme.connection":
|
|
3360
|
+
return record ? applyYouAndMe(vm, record) : withGeneric(vm);
|
|
3361
|
+
case "fyi.asq.answer":
|
|
3362
|
+
return record ? applyAsqAnswer(vm, record) : withGeneric(vm);
|
|
3363
|
+
}
|
|
3364
|
+
if (record && item.collection.startsWith("social.popfeed.feed.")) {
|
|
3365
|
+
return applyMediaReview(vm, item, record);
|
|
3366
|
+
}
|
|
3367
|
+
return withGeneric(vm);
|
|
3368
|
+
}
|
|
3369
|
+
function toStreamCardVMs(items, options = {}) {
|
|
3370
|
+
const out = [];
|
|
3371
|
+
for (const item of items) {
|
|
3372
|
+
if (isVisibleActivityItem(item.collection, item.record)) {
|
|
3373
|
+
out.push(toStreamCardVM(item, options));
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
return out;
|
|
3377
|
+
}
|
|
3378
|
+
|
|
2605
3379
|
// src/logic/profile-completeness.ts
|
|
2606
3380
|
var COMPLETENESS_MAX_SCORE = 6;
|
|
2607
3381
|
function completenessScore(c) {
|
|
@@ -3006,38 +3780,6 @@ function groupInvolvementByHeading(items) {
|
|
|
3006
3780
|
}
|
|
3007
3781
|
return groups;
|
|
3008
3782
|
}
|
|
3009
|
-
function maxGraphemes(max) {
|
|
3010
|
-
return (value) => {
|
|
3011
|
-
const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
|
|
3012
|
-
let count = 0;
|
|
3013
|
-
for (const _ of segmenter.segment(value)) {
|
|
3014
|
-
count++;
|
|
3015
|
-
if (count > max) return false;
|
|
3016
|
-
}
|
|
3017
|
-
return true;
|
|
3018
|
-
};
|
|
3019
|
-
}
|
|
3020
|
-
var didSchema = zod.z.string().regex(/^did:[a-z]+:[a-zA-Z0-9._:%-]+$/, "Invalid DID");
|
|
3021
|
-
var datetimeSchema = zod.z.string().datetime({ offset: true });
|
|
3022
|
-
var partialDateSchema = zod.z.string().regex(/^\d{4}(-\d{2}(-\d{2}(T.+)?)?)?$/, "Expected YYYY, YYYY-MM, YYYY-MM-DD, or a datetime");
|
|
3023
|
-
var atUriSchema = zod.z.string().regex(/^at:\/\/[^\s]+$/, "Invalid AT-URI");
|
|
3024
|
-
var cidSchema = zod.z.string().regex(/^(Qm[1-9A-HJ-NP-Za-km-z]{44}|b[A-Za-z0-9+/=]+)$/, "Invalid CID");
|
|
3025
|
-
var languageTagSchema = zod.z.string().regex(/^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/, "Invalid BCP 47 language tag");
|
|
3026
|
-
var uriSchema = zod.z.string().url();
|
|
3027
|
-
var strongRefSchema = zod.z.object({
|
|
3028
|
-
uri: atUriSchema,
|
|
3029
|
-
cid: cidSchema
|
|
3030
|
-
});
|
|
3031
|
-
var externalRecordRefSchema = zod.z.object({
|
|
3032
|
-
uri: atUriSchema,
|
|
3033
|
-
cid: cidSchema.optional()
|
|
3034
|
-
});
|
|
3035
|
-
var selfLabelsSchema = zod.z.object({
|
|
3036
|
-
$type: zod.z.literal("com.atproto.label.defs#selfLabels").optional(),
|
|
3037
|
-
values: zod.z.array(zod.z.object({ val: zod.z.string() }))
|
|
3038
|
-
});
|
|
3039
|
-
|
|
3040
|
-
// src/schemas/endorsement-confirmation.ts
|
|
3041
3783
|
var EndorsementConfirmationRecordSchema = zod.z.object({
|
|
3042
3784
|
endorsement: strongRefSchema,
|
|
3043
3785
|
createdAt: datetimeSchema
|
|
@@ -3217,8 +3959,8 @@ function encodeFeedCursor(cursor) {
|
|
|
3217
3959
|
}
|
|
3218
3960
|
function decodeFeedCursor(encoded) {
|
|
3219
3961
|
const json = fromBase64Url(encoded);
|
|
3220
|
-
const
|
|
3221
|
-
return FeedCursorSchema.parse(
|
|
3962
|
+
const parsed3 = JSON.parse(json);
|
|
3963
|
+
return FeedCursorSchema.parse(parsed3);
|
|
3222
3964
|
}
|
|
3223
3965
|
var ProfileCertificationRecordSchema = zod.z.object({
|
|
3224
3966
|
name: zod.z.string().min(1).refine(maxGraphemes(100)).max(1e3),
|
|
@@ -3432,9 +4174,10 @@ var ProfileVolunteeringRecordSchema = zod.z.object({
|
|
|
3432
4174
|
});
|
|
3433
4175
|
|
|
3434
4176
|
// src/index.ts
|
|
3435
|
-
var SIFA_SDK_VERSION = "0.12.
|
|
4177
|
+
var SIFA_SDK_VERSION = "0.12.10";
|
|
3436
4178
|
|
|
3437
4179
|
exports.ACTIVITY_TIERS = ACTIVITY_TIERS;
|
|
4180
|
+
exports.ACTIVITY_VERBS = ACTIVITY_VERBS;
|
|
3438
4181
|
exports.ACTIVITY_VISIBILITY_RULES = ACTIVITY_VISIBILITY_RULES;
|
|
3439
4182
|
exports.ADULT_CONTENT_LABELS = ADULT_CONTENT_LABELS;
|
|
3440
4183
|
exports.ALL_SECTIONS = ALL_SECTIONS;
|
|
@@ -3521,6 +4264,7 @@ exports.SECTION_LABELS = SECTION_LABELS;
|
|
|
3521
4264
|
exports.SIFA_SDK_VERSION = SIFA_SDK_VERSION;
|
|
3522
4265
|
exports.SKILL_CATEGORIES = SKILL_CATEGORIES;
|
|
3523
4266
|
exports.STANDARD_PUBLISHER_ID = STANDARD_PUBLISHER_ID;
|
|
4267
|
+
exports.STREAM_VERBS = STREAM_VERBS;
|
|
3524
4268
|
exports.SifaFeedItemSchema = SifaFeedItemSchema;
|
|
3525
4269
|
exports.VERIFICATION_PROVIDERS = VERIFICATION_PROVIDERS;
|
|
3526
4270
|
exports.WORKPLACE_TYPE_LABELS = WORKPLACE_TYPE_LABELS;
|
|
@@ -3558,6 +4302,7 @@ exports.formatRelativeTime = formatRelativeTime;
|
|
|
3558
4302
|
exports.formatTimelineDate = formatTimelineDate;
|
|
3559
4303
|
exports.getActivityTaxonomyVersion = getActivityTaxonomyVersion;
|
|
3560
4304
|
exports.getActivityTier = getActivityTier;
|
|
4305
|
+
exports.getActivityVerbsVersion = getActivityVerbsVersion;
|
|
3561
4306
|
exports.getAppCategoryIcon = getAppCategoryIcon;
|
|
3562
4307
|
exports.getAppIdForCollection = getAppIdForCollection;
|
|
3563
4308
|
exports.getArtifactLinkKindLabel = getArtifactLinkKindLabel;
|
|
@@ -3648,11 +4393,24 @@ exports.sortLanguagesByProficiency = sortLanguagesByProficiency;
|
|
|
3648
4393
|
exports.sortPositions = sortPositions;
|
|
3649
4394
|
exports.sortProjects = sortProjects;
|
|
3650
4395
|
exports.sortPublications = sortPublications;
|
|
4396
|
+
exports.streamAddressSchema = streamAddressSchema;
|
|
4397
|
+
exports.streamCardBodySchema = streamCardBodySchema;
|
|
4398
|
+
exports.streamCardSubjectSchema = streamCardSubjectSchema;
|
|
4399
|
+
exports.streamCardVMSchema = streamCardVMSchema;
|
|
4400
|
+
exports.streamExternalLinkSchema = streamExternalLinkSchema;
|
|
4401
|
+
exports.streamGeoSchema = streamGeoSchema;
|
|
4402
|
+
exports.streamMediaSchema = streamMediaSchema;
|
|
4403
|
+
exports.streamSourceSchema = streamSourceSchema;
|
|
4404
|
+
exports.streamThemeSchema = streamThemeSchema;
|
|
4405
|
+
exports.streamVerbSchema = streamVerbSchema;
|
|
3651
4406
|
exports.stripHtmlToText = stripHtmlToText;
|
|
3652
4407
|
exports.strongRefSchema = strongRefSchema;
|
|
3653
4408
|
exports.summarizePresentationDeliveries = summarizePresentationDeliveries;
|
|
4409
|
+
exports.toStreamCardVM = toStreamCardVM;
|
|
4410
|
+
exports.toStreamCardVMs = toStreamCardVMs;
|
|
3654
4411
|
exports.truncateGraphemes = truncateGraphemes;
|
|
3655
4412
|
exports.uriSchema = uriSchema;
|
|
4413
|
+
exports.verbForCollection = verbForCollection;
|
|
3656
4414
|
exports.visibleItems = visibleItems;
|
|
3657
4415
|
//# sourceMappingURL=index.cjs.map
|
|
3658
4416
|
//# sourceMappingURL=index.cjs.map
|