@singi-labs/sifa-sdk 0.12.10 → 0.12.11

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 CHANGED
@@ -2720,17 +2720,40 @@ var streamAddressSchema = zod.z.object({
2720
2720
  country: zod.z.string().optional(),
2721
2721
  postalCode: zod.z.string().optional()
2722
2722
  });
2723
+ var streamRichSegmentSchema = zod.z.object({
2724
+ text: zod.z.string(),
2725
+ link: zod.z.string().optional(),
2726
+ mention: zod.z.string().optional(),
2727
+ tag: zod.z.string().optional()
2728
+ });
2723
2729
  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() }),
2730
+ zod.z.object({
2731
+ kind: zod.z.literal("text"),
2732
+ text: zod.z.string(),
2733
+ richSegments: zod.z.array(streamRichSegmentSchema).optional(),
2734
+ tags: zod.z.array(zod.z.string()).optional()
2735
+ }),
2736
+ zod.z.object({
2737
+ kind: zod.z.literal("media"),
2738
+ text: zod.z.string().optional(),
2739
+ tags: zod.z.array(zod.z.string()).optional()
2740
+ }),
2741
+ zod.z.object({
2742
+ kind: zod.z.literal("link"),
2743
+ text: zod.z.string().optional(),
2744
+ tags: zod.z.array(zod.z.string()).optional()
2745
+ }),
2727
2746
  zod.z.object({
2728
2747
  kind: zod.z.literal("track"),
2729
2748
  text: zod.z.string().optional(),
2730
2749
  trackTitle: zod.z.string().optional(),
2731
2750
  artist: zod.z.string().optional()
2732
2751
  }),
2733
- zod.z.object({ kind: zod.z.literal("generic"), text: zod.z.string().optional() }),
2752
+ zod.z.object({
2753
+ kind: zod.z.literal("generic"),
2754
+ text: zod.z.string().optional(),
2755
+ tags: zod.z.array(zod.z.string()).optional()
2756
+ }),
2734
2757
  zod.z.object({
2735
2758
  kind: zod.z.literal("github-pr"),
2736
2759
  repoOwner: zod.z.string(),
@@ -3316,6 +3339,188 @@ function applyAsqAnswer(vm, record) {
3316
3339
  vm.body = { kind: "generic" };
3317
3340
  return vm;
3318
3341
  }
3342
+ function nonBlankString(value) {
3343
+ return typeof value === "string" && value.trim().length > 0 ? value : void 0;
3344
+ }
3345
+ function readBodyField(value) {
3346
+ const direct = nonBlankString(value);
3347
+ if (direct) return direct;
3348
+ return nonBlankString(asRecord(value)?.value);
3349
+ }
3350
+ function httpUrl(value) {
3351
+ return typeof value === "string" && /^https?:\/\//i.test(value) ? value : void 0;
3352
+ }
3353
+ var GENERIC_TEXT_ORDER = [
3354
+ "text",
3355
+ "title",
3356
+ "name",
3357
+ "description",
3358
+ "content",
3359
+ "body",
3360
+ "message",
3361
+ "note",
3362
+ "caption",
3363
+ "summary",
3364
+ "status"
3365
+ ];
3366
+ function genericText(collection, record) {
3367
+ if (collection === "social.passports.fiftyStates.visit") {
3368
+ return nonBlankString(record.city);
3369
+ }
3370
+ for (const field of GENERIC_TEXT_ORDER) {
3371
+ if (field === "body") {
3372
+ const body = readBodyField(record.body);
3373
+ if (body) return body;
3374
+ continue;
3375
+ }
3376
+ const value = nonBlankString(record[field]);
3377
+ if (value) return value;
3378
+ }
3379
+ return void 0;
3380
+ }
3381
+ function genericTags(record) {
3382
+ const tags = record.tags;
3383
+ if (!Array.isArray(tags)) return void 0;
3384
+ const out = tags.filter((t) => typeof t === "string" && t.length > 0);
3385
+ return out.length > 0 ? out : void 0;
3386
+ }
3387
+ function genericMedia(record, did, alt) {
3388
+ const fromArray = (raw) => {
3389
+ const img = asRecord(raw);
3390
+ if (!img) return void 0;
3391
+ return blobMedia(img.image ?? raw, did, asNonEmptyString(img.alt) ?? alt);
3392
+ };
3393
+ const images = record.images;
3394
+ if (Array.isArray(images)) {
3395
+ const out = images.map(fromArray).filter((m) => m !== void 0);
3396
+ if (out.length > 0) return out;
3397
+ }
3398
+ const embed = asRecord(record.embed);
3399
+ if (embed && Array.isArray(embed.images)) {
3400
+ const out = embed.images.map(fromArray).filter((m) => m !== void 0);
3401
+ if (out.length > 0) return out;
3402
+ }
3403
+ const single = blobMedia(record.image, did, alt) ?? blobMedia(record.thumbnail, did, alt) ?? blobMedia(record.thumb, did, alt) ?? blobMedia(record.photo, did, alt) ?? (embed ? blobMedia(embed.thumbnail, did, alt) : void 0);
3404
+ if (single) return [single];
3405
+ const coverCid = asRecord(record.galleryMeta)?.coverPhotoCid;
3406
+ if (typeof coverCid === "string" && coverCid.length > 0) {
3407
+ return [{ did, cid: coverCid, alt }];
3408
+ }
3409
+ return [];
3410
+ }
3411
+ function genericExternalLink(record) {
3412
+ const embed = asRecord(record.embed);
3413
+ if (embed) {
3414
+ const fromEmbed = bskyExternal(embed);
3415
+ if (fromEmbed) return fromEmbed;
3416
+ }
3417
+ const url = httpUrl(record.source) ?? httpUrl(record.subject) ?? httpUrl(record.url);
3418
+ return url ? { url } : void 0;
3419
+ }
3420
+ function genericSubject(record) {
3421
+ const subject = record.subject;
3422
+ if (typeof subject === "string") {
3423
+ if (subject.startsWith("at://")) return { kind: "record", uri: subject };
3424
+ if (subject.startsWith("did:")) return { kind: "person", did: subject };
3425
+ return void 0;
3426
+ }
3427
+ const uri = nonBlankString(asRecord(subject)?.uri);
3428
+ if (uri && uri.startsWith("at://")) return { kind: "record", uri };
3429
+ return void 0;
3430
+ }
3431
+ function parseFacetFeature(features) {
3432
+ for (const raw of features) {
3433
+ const feat = asRecord(raw);
3434
+ if (!feat) continue;
3435
+ const type = asNonEmptyString(feat["$type"]) ?? "";
3436
+ const uri = asNonEmptyString(feat.uri);
3437
+ const did = asNonEmptyString(feat.did);
3438
+ const tag = asNonEmptyString(feat.tag);
3439
+ if (type.endsWith("#link") && uri) return { link: uri };
3440
+ if (type.endsWith("#mention") && did) return { mention: did };
3441
+ if (type.endsWith("#tag") && tag) return { tag };
3442
+ if (uri) return { link: uri };
3443
+ if (did) return { mention: did };
3444
+ if (tag) return { tag };
3445
+ }
3446
+ return void 0;
3447
+ }
3448
+ function genericRichSegments(text, record) {
3449
+ const facets = record.facets;
3450
+ if (!Array.isArray(facets)) return void 0;
3451
+ const parsed3 = [];
3452
+ for (const raw of facets) {
3453
+ const facet = asRecord(raw);
3454
+ const index = asRecord(facet?.index);
3455
+ const start = asFiniteNumber(index?.byteStart);
3456
+ const end = asFiniteNumber(index?.byteEnd);
3457
+ if (start === void 0 || end === void 0 || start < 0 || end <= start) continue;
3458
+ const features = facet?.features;
3459
+ if (!Array.isArray(features)) continue;
3460
+ const feature = parseFacetFeature(features);
3461
+ if (!feature) continue;
3462
+ parsed3.push({ start, end, ...feature });
3463
+ }
3464
+ if (parsed3.length === 0) return void 0;
3465
+ const bytes = new TextEncoder().encode(text);
3466
+ const decoder = new TextDecoder();
3467
+ parsed3.sort((a, b) => a.start - b.start);
3468
+ const segments = [];
3469
+ let cursor = 0;
3470
+ for (const span of parsed3) {
3471
+ if (span.start < cursor || span.start > bytes.length) continue;
3472
+ const end = Math.min(span.end, bytes.length);
3473
+ if (span.start > cursor) {
3474
+ const plain = decoder.decode(bytes.slice(cursor, span.start));
3475
+ if (plain) segments.push({ text: plain });
3476
+ }
3477
+ const seg = { text: decoder.decode(bytes.slice(span.start, end)) };
3478
+ if (span.link) seg.link = span.link;
3479
+ if (span.mention) seg.mention = span.mention;
3480
+ if (span.tag) seg.tag = span.tag;
3481
+ segments.push(seg);
3482
+ cursor = end;
3483
+ }
3484
+ if (cursor < bytes.length) {
3485
+ const rest = decoder.decode(bytes.slice(cursor));
3486
+ if (rest) segments.push({ text: rest });
3487
+ }
3488
+ return segments.some((s) => s.link ?? s.mention ?? s.tag) ? segments : void 0;
3489
+ }
3490
+ function applyGeneric(vm, item, record) {
3491
+ if (!record) return withGeneric(vm);
3492
+ const text = genericText(item.collection, record);
3493
+ const tags = genericTags(record);
3494
+ const did = didFromUri(item.uri);
3495
+ if (did) {
3496
+ const media = genericMedia(record, did, text ?? "");
3497
+ if (media.length > 0) vm.media = media;
3498
+ }
3499
+ const externalLink = genericExternalLink(record);
3500
+ if (externalLink) vm.externalLink = externalLink;
3501
+ if (!vm.subject) {
3502
+ const subject = genericSubject(record);
3503
+ if (subject) vm.subject = subject;
3504
+ }
3505
+ let body;
3506
+ if (text) {
3507
+ body = { kind: "text", text };
3508
+ const richSegments = genericRichSegments(text, record);
3509
+ if (richSegments) body.richSegments = richSegments;
3510
+ if (tags) body.tags = tags;
3511
+ } else if (vm.media) {
3512
+ body = { kind: "media" };
3513
+ if (tags) body.tags = tags;
3514
+ } else if (vm.externalLink) {
3515
+ body = { kind: "link" };
3516
+ if (tags) body.tags = tags;
3517
+ } else {
3518
+ body = { kind: "generic" };
3519
+ if (tags) body.tags = tags;
3520
+ }
3521
+ vm.body = body;
3522
+ return vm;
3523
+ }
3319
3524
  function toStreamCardVM(item, options = {}) {
3320
3525
  const verb = verbForCollection(item.collection);
3321
3526
  const source = buildSource(item, options);
@@ -3364,7 +3569,7 @@ function toStreamCardVM(item, options = {}) {
3364
3569
  if (record && item.collection.startsWith("social.popfeed.feed.")) {
3365
3570
  return applyMediaReview(vm, item, record);
3366
3571
  }
3367
- return withGeneric(vm);
3572
+ return applyGeneric(vm, item, record);
3368
3573
  }
3369
3574
  function toStreamCardVMs(items, options = {}) {
3370
3575
  const out = [];
@@ -4174,7 +4379,7 @@ var ProfileVolunteeringRecordSchema = zod.z.object({
4174
4379
  });
4175
4380
 
4176
4381
  // src/index.ts
4177
- var SIFA_SDK_VERSION = "0.12.10";
4382
+ var SIFA_SDK_VERSION = "0.12.11";
4178
4383
 
4179
4384
  exports.ACTIVITY_TIERS = ACTIVITY_TIERS;
4180
4385
  exports.ACTIVITY_VERBS = ACTIVITY_VERBS;
@@ -4400,6 +4605,7 @@ exports.streamCardVMSchema = streamCardVMSchema;
4400
4605
  exports.streamExternalLinkSchema = streamExternalLinkSchema;
4401
4606
  exports.streamGeoSchema = streamGeoSchema;
4402
4607
  exports.streamMediaSchema = streamMediaSchema;
4608
+ exports.streamRichSegmentSchema = streamRichSegmentSchema;
4403
4609
  exports.streamSourceSchema = streamSourceSchema;
4404
4610
  exports.streamThemeSchema = streamThemeSchema;
4405
4611
  exports.streamVerbSchema = streamVerbSchema;