@singi-labs/sifa-sdk 0.12.9 → 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.js CHANGED
@@ -2706,6 +2706,18 @@ var streamExternalLinkSchema = z.object({
2706
2706
  title: z.string().optional(),
2707
2707
  thumb: z.string().optional()
2708
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
+ });
2709
2721
  var streamCardBodySchema = z.discriminatedUnion("kind", [
2710
2722
  z.object({ kind: z.literal("text"), text: z.string() }),
2711
2723
  z.object({ kind: z.literal("media"), text: z.string().optional() }),
@@ -2716,7 +2728,91 @@ var streamCardBodySchema = z.discriminatedUnion("kind", [
2716
2728
  trackTitle: z.string().optional(),
2717
2729
  artist: z.string().optional()
2718
2730
  }),
2719
- z.object({ kind: z.literal("generic"), text: z.string().optional() })
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
+ })
2720
2816
  ]);
2721
2817
  var streamCardSubjectSchema = z.discriminatedUnion("kind", [
2722
2818
  z.object({
@@ -2752,6 +2848,62 @@ var streamCardVMSchema = z.lazy(
2752
2848
  subject: z.lazy(() => streamCardSubjectSchema).optional()
2753
2849
  })
2754
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
+ }
2755
2907
 
2756
2908
  // src/stream/to-stream-card-vm.ts
2757
2909
  var DEFAULT_SOURCE_COLOR = "slate";
@@ -2780,6 +2932,69 @@ function aspectRatio(value) {
2780
2932
  if (typeof width === "number" && typeof height === "number") return { width, height };
2781
2933
  return void 0;
2782
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
+ }
2783
2998
  function buildSource(item, options) {
2784
2999
  return {
2785
3000
  appId: item.appId,
@@ -2871,6 +3086,234 @@ function applyBskyPost(vm, item, record) {
2871
3086
  vm.body = body;
2872
3087
  return vm;
2873
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
+ }
2874
3317
  function toStreamCardVM(item, options = {}) {
2875
3318
  const verb = verbForCollection(item.collection);
2876
3319
  const source = buildSource(item, options);
@@ -2890,11 +3333,36 @@ function toStreamCardVM(item, options = {}) {
2890
3333
  if (item.subject) {
2891
3334
  vm.subject = { kind: "post", post: toStreamCardVM(item.subject, options) };
2892
3335
  }
2893
- if (item.collection === "app.bsky.feed.post") {
2894
- return applyBskyPost(vm, item, record);
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);
2895
3361
  }
2896
- vm.body = { kind: "generic" };
2897
- return vm;
3362
+ if (record && item.collection.startsWith("social.popfeed.feed.")) {
3363
+ return applyMediaReview(vm, item, record);
3364
+ }
3365
+ return withGeneric(vm);
2898
3366
  }
2899
3367
  function toStreamCardVMs(items, options = {}) {
2900
3368
  const out = [];
@@ -3310,38 +3778,6 @@ function groupInvolvementByHeading(items) {
3310
3778
  }
3311
3779
  return groups;
3312
3780
  }
3313
- function maxGraphemes(max) {
3314
- return (value) => {
3315
- const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
3316
- let count = 0;
3317
- for (const _ of segmenter.segment(value)) {
3318
- count++;
3319
- if (count > max) return false;
3320
- }
3321
- return true;
3322
- };
3323
- }
3324
- var didSchema = z.string().regex(/^did:[a-z]+:[a-zA-Z0-9._:%-]+$/, "Invalid DID");
3325
- var datetimeSchema = z.string().datetime({ offset: true });
3326
- var partialDateSchema = z.string().regex(/^\d{4}(-\d{2}(-\d{2}(T.+)?)?)?$/, "Expected YYYY, YYYY-MM, YYYY-MM-DD, or a datetime");
3327
- var atUriSchema = z.string().regex(/^at:\/\/[^\s]+$/, "Invalid AT-URI");
3328
- var cidSchema = z.string().regex(/^(Qm[1-9A-HJ-NP-Za-km-z]{44}|b[A-Za-z0-9+/=]+)$/, "Invalid CID");
3329
- var languageTagSchema = z.string().regex(/^[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*$/, "Invalid BCP 47 language tag");
3330
- var uriSchema = z.string().url();
3331
- var strongRefSchema = z.object({
3332
- uri: atUriSchema,
3333
- cid: cidSchema
3334
- });
3335
- var externalRecordRefSchema = z.object({
3336
- uri: atUriSchema,
3337
- cid: cidSchema.optional()
3338
- });
3339
- var selfLabelsSchema = z.object({
3340
- $type: z.literal("com.atproto.label.defs#selfLabels").optional(),
3341
- values: z.array(z.object({ val: z.string() }))
3342
- });
3343
-
3344
- // src/schemas/endorsement-confirmation.ts
3345
3781
  var EndorsementConfirmationRecordSchema = z.object({
3346
3782
  endorsement: strongRefSchema,
3347
3783
  createdAt: datetimeSchema
@@ -3736,8 +4172,8 @@ var ProfileVolunteeringRecordSchema = z.object({
3736
4172
  });
3737
4173
 
3738
4174
  // src/index.ts
3739
- var SIFA_SDK_VERSION = "0.12.9";
4175
+ var SIFA_SDK_VERSION = "0.12.10";
3740
4176
 
3741
- 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, streamCardBodySchema, streamCardSubjectSchema, streamCardVMSchema, streamExternalLinkSchema, streamMediaSchema, streamSourceSchema, streamThemeSchema, streamVerbSchema, stripHtmlToText, strongRefSchema, summarizePresentationDeliveries, toStreamCardVM, toStreamCardVMs, truncateGraphemes, uriSchema, verbForCollection, 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 };
3742
4178
  //# sourceMappingURL=index.js.map
3743
4179
  //# sourceMappingURL=index.js.map