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