@ewanc26/atproto 0.2.8 → 0.2.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/fetch.d.ts +13 -1
- package/dist/fetch.d.ts.map +1 -1
- package/dist/fetch.js +431 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/types.d.ts +111 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +7 -7
- package/src/fetch.ts +559 -1
- package/src/index.ts +28 -2
- package/src/types.ts +127 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ewanc26/atproto",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"description": "AT Protocol service layer extracted from ewancroft.uk",
|
|
5
5
|
"author": "Ewan Croft",
|
|
6
6
|
"license": "AGPL-3.0-only",
|
|
@@ -35,16 +35,16 @@
|
|
|
35
35
|
},
|
|
36
36
|
"main": "./dist/index.js",
|
|
37
37
|
"types": "./dist/index.d.ts",
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc --project tsconfig.json",
|
|
40
|
+
"dev": "tsc --project tsconfig.json --watch",
|
|
41
|
+
"check": "tsc --noEmit"
|
|
42
|
+
},
|
|
38
43
|
"peerDependencies": {
|
|
39
44
|
"@atproto/api": ">=0.13.0"
|
|
40
45
|
},
|
|
41
46
|
"devDependencies": {
|
|
42
47
|
"@atproto/api": "^0.19.3",
|
|
43
48
|
"typescript": "^5.9.3"
|
|
44
|
-
},
|
|
45
|
-
"scripts": {
|
|
46
|
-
"build": "tsc --project tsconfig.json",
|
|
47
|
-
"dev": "tsc --project tsconfig.json --watch",
|
|
48
|
-
"check": "tsc --noEmit"
|
|
49
49
|
}
|
|
50
|
-
}
|
|
50
|
+
}
|
package/src/fetch.ts
CHANGED
|
@@ -12,7 +12,19 @@ import type {
|
|
|
12
12
|
TangledReposData,
|
|
13
13
|
PopfeedReview,
|
|
14
14
|
PopfeedCreativeWorkType,
|
|
15
|
-
PopfeedMainCreditRole
|
|
15
|
+
PopfeedMainCreditRole,
|
|
16
|
+
SifaProfileData,
|
|
17
|
+
SifaSkill,
|
|
18
|
+
SifaProject,
|
|
19
|
+
SifaLanguage,
|
|
20
|
+
SifaCertification,
|
|
21
|
+
SifaExternalAccount,
|
|
22
|
+
SifaPosition,
|
|
23
|
+
SifaEducation,
|
|
24
|
+
SifaVolunteering,
|
|
25
|
+
SifaHonor,
|
|
26
|
+
SifaCourse,
|
|
27
|
+
SifaPublication
|
|
16
28
|
} from './types.js';
|
|
17
29
|
|
|
18
30
|
export async function fetchProfile(did: string, fetchFn?: typeof fetch): Promise<ProfileData> {
|
|
@@ -363,6 +375,295 @@ export async function fetchRecentPopfeedReviews(
|
|
|
363
375
|
}
|
|
364
376
|
}
|
|
365
377
|
|
|
378
|
+
export async function fetchSifaPositions(
|
|
379
|
+
did: string,
|
|
380
|
+
fetchFn?: typeof fetch
|
|
381
|
+
): Promise<SifaPosition[]> {
|
|
382
|
+
const cacheKey = `sifa:positions:${did}`;
|
|
383
|
+
const cached = cache.get<SifaPosition[]>(cacheKey);
|
|
384
|
+
if (cached) return cached;
|
|
385
|
+
|
|
386
|
+
try {
|
|
387
|
+
const records = await withFallback(
|
|
388
|
+
did,
|
|
389
|
+
async (agent) => {
|
|
390
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
391
|
+
repo: did,
|
|
392
|
+
collection: 'id.sifa.profile.position',
|
|
393
|
+
limit: 100
|
|
394
|
+
});
|
|
395
|
+
return response.data.records;
|
|
396
|
+
},
|
|
397
|
+
true,
|
|
398
|
+
fetchFn
|
|
399
|
+
);
|
|
400
|
+
|
|
401
|
+
const data: SifaPosition[] = records.map((record) => {
|
|
402
|
+
const value = record.value as any;
|
|
403
|
+
return {
|
|
404
|
+
company: value.company,
|
|
405
|
+
companyDid: value.companyDid,
|
|
406
|
+
title: value.title,
|
|
407
|
+
description: value.description,
|
|
408
|
+
employmentType: value.employmentType,
|
|
409
|
+
workplaceType: value.workplaceType,
|
|
410
|
+
location: value.location,
|
|
411
|
+
startedAt: value.startedAt,
|
|
412
|
+
endedAt: value.endedAt,
|
|
413
|
+
skills: value.skills,
|
|
414
|
+
isPrimary: value.isPrimary,
|
|
415
|
+
uri: record.uri
|
|
416
|
+
};
|
|
417
|
+
});
|
|
418
|
+
|
|
419
|
+
data.sort((a, b) => {
|
|
420
|
+
if (!a.startedAt) return 1;
|
|
421
|
+
if (!b.startedAt) return -1;
|
|
422
|
+
return new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime();
|
|
423
|
+
});
|
|
424
|
+
|
|
425
|
+
cache.set(cacheKey, data);
|
|
426
|
+
return data;
|
|
427
|
+
} catch {
|
|
428
|
+
return [];
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
export async function fetchSifaEducation(
|
|
433
|
+
did: string,
|
|
434
|
+
fetchFn?: typeof fetch
|
|
435
|
+
): Promise<SifaEducation[]> {
|
|
436
|
+
const cacheKey = `sifa:education:${did}`;
|
|
437
|
+
const cached = cache.get<SifaEducation[]>(cacheKey);
|
|
438
|
+
if (cached) return cached;
|
|
439
|
+
|
|
440
|
+
try {
|
|
441
|
+
const records = await withFallback(
|
|
442
|
+
did,
|
|
443
|
+
async (agent) => {
|
|
444
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
445
|
+
repo: did,
|
|
446
|
+
collection: 'id.sifa.profile.education',
|
|
447
|
+
limit: 100
|
|
448
|
+
});
|
|
449
|
+
return response.data.records;
|
|
450
|
+
},
|
|
451
|
+
true,
|
|
452
|
+
fetchFn
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const data: SifaEducation[] = records.map((record) => {
|
|
456
|
+
const value = record.value as any;
|
|
457
|
+
return {
|
|
458
|
+
institution: value.institution,
|
|
459
|
+
institutionDid: value.institutionDid,
|
|
460
|
+
degree: value.degree,
|
|
461
|
+
fieldOfStudy: value.fieldOfStudy,
|
|
462
|
+
grade: value.grade,
|
|
463
|
+
activities: value.activities,
|
|
464
|
+
description: value.description,
|
|
465
|
+
location: value.location,
|
|
466
|
+
startedAt: value.startedAt,
|
|
467
|
+
endedAt: value.endedAt,
|
|
468
|
+
uri: record.uri
|
|
469
|
+
};
|
|
470
|
+
});
|
|
471
|
+
|
|
472
|
+
data.sort((a, b) => {
|
|
473
|
+
const aEnd = a.endedAt ? new Date(a.endedAt).getTime() : Date.now();
|
|
474
|
+
const bEnd = b.endedAt ? new Date(b.endedAt).getTime() : Date.now();
|
|
475
|
+
return bEnd - aEnd;
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
cache.set(cacheKey, data);
|
|
479
|
+
return data;
|
|
480
|
+
} catch {
|
|
481
|
+
return [];
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
export async function fetchSifaVolunteering(
|
|
486
|
+
did: string,
|
|
487
|
+
fetchFn?: typeof fetch
|
|
488
|
+
): Promise<SifaVolunteering[]> {
|
|
489
|
+
const cacheKey = `sifa:volunteering:${did}`;
|
|
490
|
+
const cached = cache.get<SifaVolunteering[]>(cacheKey);
|
|
491
|
+
if (cached) return cached;
|
|
492
|
+
|
|
493
|
+
try {
|
|
494
|
+
const records = await withFallback(
|
|
495
|
+
did,
|
|
496
|
+
async (agent) => {
|
|
497
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
498
|
+
repo: did,
|
|
499
|
+
collection: 'id.sifa.profile.volunteering',
|
|
500
|
+
limit: 100
|
|
501
|
+
});
|
|
502
|
+
return response.data.records;
|
|
503
|
+
},
|
|
504
|
+
true,
|
|
505
|
+
fetchFn
|
|
506
|
+
);
|
|
507
|
+
|
|
508
|
+
const data: SifaVolunteering[] = records.map((record) => {
|
|
509
|
+
const value = record.value as any;
|
|
510
|
+
return {
|
|
511
|
+
organization: value.organization,
|
|
512
|
+
organizationDid: value.organizationDid,
|
|
513
|
+
role: value.role,
|
|
514
|
+
cause: value.cause,
|
|
515
|
+
description: value.description,
|
|
516
|
+
startedAt: value.startedAt,
|
|
517
|
+
endedAt: value.endedAt,
|
|
518
|
+
uri: record.uri
|
|
519
|
+
};
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
cache.set(cacheKey, data);
|
|
523
|
+
return data;
|
|
524
|
+
} catch {
|
|
525
|
+
return [];
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
export async function fetchSifaHonors(
|
|
530
|
+
did: string,
|
|
531
|
+
fetchFn?: typeof fetch
|
|
532
|
+
): Promise<SifaHonor[]> {
|
|
533
|
+
const cacheKey = `sifa:honors:${did}`;
|
|
534
|
+
const cached = cache.get<SifaHonor[]>(cacheKey);
|
|
535
|
+
if (cached) return cached;
|
|
536
|
+
|
|
537
|
+
try {
|
|
538
|
+
const records = await withFallback(
|
|
539
|
+
did,
|
|
540
|
+
async (agent) => {
|
|
541
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
542
|
+
repo: did,
|
|
543
|
+
collection: 'id.sifa.profile.honor',
|
|
544
|
+
limit: 100
|
|
545
|
+
});
|
|
546
|
+
return response.data.records;
|
|
547
|
+
},
|
|
548
|
+
true,
|
|
549
|
+
fetchFn
|
|
550
|
+
);
|
|
551
|
+
|
|
552
|
+
const data: SifaHonor[] = records.map((record) => {
|
|
553
|
+
const value = record.value as any;
|
|
554
|
+
return {
|
|
555
|
+
title: value.title,
|
|
556
|
+
issuer: value.issuer,
|
|
557
|
+
issuerDid: value.issuerDid,
|
|
558
|
+
description: value.description,
|
|
559
|
+
awardedAt: value.awardedAt,
|
|
560
|
+
uri: record.uri
|
|
561
|
+
};
|
|
562
|
+
});
|
|
563
|
+
|
|
564
|
+
data.sort((a, b) => {
|
|
565
|
+
if (!a.awardedAt) return 1;
|
|
566
|
+
if (!b.awardedAt) return -1;
|
|
567
|
+
return new Date(b.awardedAt).getTime() - new Date(a.awardedAt).getTime();
|
|
568
|
+
});
|
|
569
|
+
|
|
570
|
+
cache.set(cacheKey, data);
|
|
571
|
+
return data;
|
|
572
|
+
} catch {
|
|
573
|
+
return [];
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
export async function fetchSifaCourses(
|
|
578
|
+
did: string,
|
|
579
|
+
fetchFn?: typeof fetch
|
|
580
|
+
): Promise<SifaCourse[]> {
|
|
581
|
+
const cacheKey = `sifa:courses:${did}`;
|
|
582
|
+
const cached = cache.get<SifaCourse[]>(cacheKey);
|
|
583
|
+
if (cached) return cached;
|
|
584
|
+
|
|
585
|
+
try {
|
|
586
|
+
const records = await withFallback(
|
|
587
|
+
did,
|
|
588
|
+
async (agent) => {
|
|
589
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
590
|
+
repo: did,
|
|
591
|
+
collection: 'id.sifa.profile.course',
|
|
592
|
+
limit: 100
|
|
593
|
+
});
|
|
594
|
+
return response.data.records;
|
|
595
|
+
},
|
|
596
|
+
true,
|
|
597
|
+
fetchFn
|
|
598
|
+
);
|
|
599
|
+
|
|
600
|
+
const data: SifaCourse[] = records.map((record) => {
|
|
601
|
+
const value = record.value as any;
|
|
602
|
+
return {
|
|
603
|
+
name: value.name,
|
|
604
|
+
number: value.number,
|
|
605
|
+
institution: value.institution,
|
|
606
|
+
education: value.education,
|
|
607
|
+
uri: record.uri
|
|
608
|
+
};
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
cache.set(cacheKey, data);
|
|
612
|
+
return data;
|
|
613
|
+
} catch {
|
|
614
|
+
return [];
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
export async function fetchSifaPublications(
|
|
619
|
+
did: string,
|
|
620
|
+
fetchFn?: typeof fetch
|
|
621
|
+
): Promise<SifaPublication[]> {
|
|
622
|
+
const cacheKey = `sifa:publications:${did}`;
|
|
623
|
+
const cached = cache.get<SifaPublication[]>(cacheKey);
|
|
624
|
+
if (cached) return cached;
|
|
625
|
+
|
|
626
|
+
try {
|
|
627
|
+
const records = await withFallback(
|
|
628
|
+
did,
|
|
629
|
+
async (agent) => {
|
|
630
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
631
|
+
repo: did,
|
|
632
|
+
collection: 'id.sifa.profile.publication',
|
|
633
|
+
limit: 100
|
|
634
|
+
});
|
|
635
|
+
return response.data.records;
|
|
636
|
+
},
|
|
637
|
+
true,
|
|
638
|
+
fetchFn
|
|
639
|
+
);
|
|
640
|
+
|
|
641
|
+
const data: SifaPublication[] = records.map((record) => {
|
|
642
|
+
const value = record.value as any;
|
|
643
|
+
return {
|
|
644
|
+
title: value.title,
|
|
645
|
+
publisher: value.publisher,
|
|
646
|
+
url: value.url,
|
|
647
|
+
description: value.description,
|
|
648
|
+
authors: value.authors,
|
|
649
|
+
publishedAt: value.publishedAt,
|
|
650
|
+
uri: record.uri
|
|
651
|
+
};
|
|
652
|
+
});
|
|
653
|
+
|
|
654
|
+
data.sort((a, b) => {
|
|
655
|
+
if (!a.publishedAt) return 1;
|
|
656
|
+
if (!b.publishedAt) return -1;
|
|
657
|
+
return new Date(b.publishedAt).getTime() - new Date(a.publishedAt).getTime();
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
cache.set(cacheKey, data);
|
|
661
|
+
return data;
|
|
662
|
+
} catch {
|
|
663
|
+
return [];
|
|
664
|
+
}
|
|
665
|
+
}
|
|
666
|
+
|
|
366
667
|
export async function fetchTangledRepos(
|
|
367
668
|
did: string,
|
|
368
669
|
fetchFn?: typeof fetch
|
|
@@ -410,3 +711,260 @@ export async function fetchTangledRepos(
|
|
|
410
711
|
return null;
|
|
411
712
|
}
|
|
412
713
|
}
|
|
714
|
+
|
|
715
|
+
// Sifa Professional Profile fetch functions
|
|
716
|
+
|
|
717
|
+
export async function fetchSifaProfile(
|
|
718
|
+
did: string,
|
|
719
|
+
fetchFn?: typeof fetch
|
|
720
|
+
): Promise<SifaProfileData | null> {
|
|
721
|
+
const cacheKey = `sifa:profile:${did}`;
|
|
722
|
+
const cached = cache.get<SifaProfileData>(cacheKey);
|
|
723
|
+
if (cached) return cached;
|
|
724
|
+
|
|
725
|
+
try {
|
|
726
|
+
const result = await withFallback(
|
|
727
|
+
did,
|
|
728
|
+
async (agent) => {
|
|
729
|
+
const response = await agent.com.atproto.repo.getRecord({
|
|
730
|
+
repo: did,
|
|
731
|
+
collection: 'id.sifa.profile.self',
|
|
732
|
+
rkey: 'self'
|
|
733
|
+
});
|
|
734
|
+
return response.data;
|
|
735
|
+
},
|
|
736
|
+
true,
|
|
737
|
+
fetchFn
|
|
738
|
+
);
|
|
739
|
+
|
|
740
|
+
if (!result?.value) return null;
|
|
741
|
+
const value = result.value as any;
|
|
742
|
+
const data: SifaProfileData = {
|
|
743
|
+
headline: value.headline,
|
|
744
|
+
about: value.about,
|
|
745
|
+
industry: value.industry,
|
|
746
|
+
location: value.location,
|
|
747
|
+
openTo: value.openTo || [],
|
|
748
|
+
preferredWorkplace: value.preferredWorkplace || [],
|
|
749
|
+
langs: value.langs || [],
|
|
750
|
+
createdAt: value.createdAt
|
|
751
|
+
};
|
|
752
|
+
cache.set(cacheKey, data);
|
|
753
|
+
return data;
|
|
754
|
+
} catch {
|
|
755
|
+
return null;
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
|
|
759
|
+
export async function fetchSifaSkills(
|
|
760
|
+
did: string,
|
|
761
|
+
fetchFn?: typeof fetch
|
|
762
|
+
): Promise<SifaSkill[]> {
|
|
763
|
+
const cacheKey = `sifa:skills:${did}`;
|
|
764
|
+
const cached = cache.get<SifaSkill[]>(cacheKey);
|
|
765
|
+
if (cached) return cached;
|
|
766
|
+
|
|
767
|
+
try {
|
|
768
|
+
const records = await withFallback(
|
|
769
|
+
did,
|
|
770
|
+
async (agent) => {
|
|
771
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
772
|
+
repo: did,
|
|
773
|
+
collection: 'id.sifa.profile.skill',
|
|
774
|
+
limit: 100
|
|
775
|
+
});
|
|
776
|
+
return response.data.records;
|
|
777
|
+
},
|
|
778
|
+
true,
|
|
779
|
+
fetchFn
|
|
780
|
+
);
|
|
781
|
+
|
|
782
|
+
const data: SifaSkill[] = records.map((record) => {
|
|
783
|
+
const value = record.value as any;
|
|
784
|
+
return {
|
|
785
|
+
name: value.name,
|
|
786
|
+
category: value.category,
|
|
787
|
+
uri: record.uri
|
|
788
|
+
};
|
|
789
|
+
});
|
|
790
|
+
|
|
791
|
+
cache.set(cacheKey, data);
|
|
792
|
+
return data;
|
|
793
|
+
} catch {
|
|
794
|
+
return [];
|
|
795
|
+
}
|
|
796
|
+
}
|
|
797
|
+
|
|
798
|
+
export async function fetchSifaProjects(
|
|
799
|
+
did: string,
|
|
800
|
+
fetchFn?: typeof fetch
|
|
801
|
+
): Promise<SifaProject[]> {
|
|
802
|
+
const cacheKey = `sifa:projects:${did}`;
|
|
803
|
+
const cached = cache.get<SifaProject[]>(cacheKey);
|
|
804
|
+
if (cached) return cached;
|
|
805
|
+
|
|
806
|
+
try {
|
|
807
|
+
const records = await withFallback(
|
|
808
|
+
did,
|
|
809
|
+
async (agent) => {
|
|
810
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
811
|
+
repo: did,
|
|
812
|
+
collection: 'id.sifa.profile.project',
|
|
813
|
+
limit: 100
|
|
814
|
+
});
|
|
815
|
+
return response.data.records;
|
|
816
|
+
},
|
|
817
|
+
true,
|
|
818
|
+
fetchFn
|
|
819
|
+
);
|
|
820
|
+
|
|
821
|
+
const data: SifaProject[] = records.map((record) => {
|
|
822
|
+
const value = record.value as any;
|
|
823
|
+
return {
|
|
824
|
+
name: value.name,
|
|
825
|
+
description: value.description,
|
|
826
|
+
url: value.url,
|
|
827
|
+
startedAt: value.startedAt,
|
|
828
|
+
uri: record.uri
|
|
829
|
+
};
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
data.sort((a, b) => {
|
|
833
|
+
if (!a.startedAt) return 1;
|
|
834
|
+
if (!b.startedAt) return -1;
|
|
835
|
+
return new Date(b.startedAt).getTime() - new Date(a.startedAt).getTime();
|
|
836
|
+
});
|
|
837
|
+
|
|
838
|
+
cache.set(cacheKey, data);
|
|
839
|
+
return data;
|
|
840
|
+
} catch {
|
|
841
|
+
return [];
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
export async function fetchSifaLanguages(
|
|
846
|
+
did: string,
|
|
847
|
+
fetchFn?: typeof fetch
|
|
848
|
+
): Promise<SifaLanguage[]> {
|
|
849
|
+
const cacheKey = `sifa:languages:${did}`;
|
|
850
|
+
const cached = cache.get<SifaLanguage[]>(cacheKey);
|
|
851
|
+
if (cached) return cached;
|
|
852
|
+
|
|
853
|
+
try {
|
|
854
|
+
const records = await withFallback(
|
|
855
|
+
did,
|
|
856
|
+
async (agent) => {
|
|
857
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
858
|
+
repo: did,
|
|
859
|
+
collection: 'id.sifa.profile.language',
|
|
860
|
+
limit: 100
|
|
861
|
+
});
|
|
862
|
+
return response.data.records;
|
|
863
|
+
},
|
|
864
|
+
true,
|
|
865
|
+
fetchFn
|
|
866
|
+
);
|
|
867
|
+
|
|
868
|
+
const data: SifaLanguage[] = records.map((record) => {
|
|
869
|
+
const value = record.value as any;
|
|
870
|
+
return {
|
|
871
|
+
name: value.name,
|
|
872
|
+
proficiency: value.proficiency,
|
|
873
|
+
uri: record.uri
|
|
874
|
+
};
|
|
875
|
+
});
|
|
876
|
+
|
|
877
|
+
cache.set(cacheKey, data);
|
|
878
|
+
return data;
|
|
879
|
+
} catch {
|
|
880
|
+
return [];
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
export async function fetchSifaCertifications(
|
|
885
|
+
did: string,
|
|
886
|
+
fetchFn?: typeof fetch
|
|
887
|
+
): Promise<SifaCertification[]> {
|
|
888
|
+
const cacheKey = `sifa:certifications:${did}`;
|
|
889
|
+
const cached = cache.get<SifaCertification[]>(cacheKey);
|
|
890
|
+
if (cached) return cached;
|
|
891
|
+
|
|
892
|
+
try {
|
|
893
|
+
const records = await withFallback(
|
|
894
|
+
did,
|
|
895
|
+
async (agent) => {
|
|
896
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
897
|
+
repo: did,
|
|
898
|
+
collection: 'id.sifa.profile.certification',
|
|
899
|
+
limit: 100
|
|
900
|
+
});
|
|
901
|
+
return response.data.records;
|
|
902
|
+
},
|
|
903
|
+
true,
|
|
904
|
+
fetchFn
|
|
905
|
+
);
|
|
906
|
+
|
|
907
|
+
const data: SifaCertification[] = records.map((record) => {
|
|
908
|
+
const value = record.value as any;
|
|
909
|
+
return {
|
|
910
|
+
name: value.name,
|
|
911
|
+
authority: value.authority,
|
|
912
|
+
issuedAt: value.issuedAt,
|
|
913
|
+
uri: record.uri
|
|
914
|
+
};
|
|
915
|
+
});
|
|
916
|
+
|
|
917
|
+
data.sort((a, b) => {
|
|
918
|
+
if (!a.issuedAt) return 1;
|
|
919
|
+
if (!b.issuedAt) return -1;
|
|
920
|
+
return new Date(b.issuedAt).getTime() - new Date(a.issuedAt).getTime();
|
|
921
|
+
});
|
|
922
|
+
|
|
923
|
+
cache.set(cacheKey, data);
|
|
924
|
+
return data;
|
|
925
|
+
} catch {
|
|
926
|
+
return [];
|
|
927
|
+
}
|
|
928
|
+
}
|
|
929
|
+
|
|
930
|
+
export async function fetchSifaExternalAccounts(
|
|
931
|
+
did: string,
|
|
932
|
+
fetchFn?: typeof fetch
|
|
933
|
+
): Promise<SifaExternalAccount[]> {
|
|
934
|
+
const cacheKey = `sifa:externalAccounts:${did}`;
|
|
935
|
+
const cached = cache.get<SifaExternalAccount[]>(cacheKey);
|
|
936
|
+
if (cached) return cached;
|
|
937
|
+
|
|
938
|
+
try {
|
|
939
|
+
const records = await withFallback(
|
|
940
|
+
did,
|
|
941
|
+
async (agent) => {
|
|
942
|
+
const response = await agent.com.atproto.repo.listRecords({
|
|
943
|
+
repo: did,
|
|
944
|
+
collection: 'id.sifa.profile.externalAccount',
|
|
945
|
+
limit: 100
|
|
946
|
+
});
|
|
947
|
+
return response.data.records;
|
|
948
|
+
},
|
|
949
|
+
true,
|
|
950
|
+
fetchFn
|
|
951
|
+
);
|
|
952
|
+
|
|
953
|
+
const data: SifaExternalAccount[] = records.map((record) => {
|
|
954
|
+
const value = record.value as any;
|
|
955
|
+
return {
|
|
956
|
+
platform: value.platform,
|
|
957
|
+
url: value.url,
|
|
958
|
+
label: value.label,
|
|
959
|
+
feedUrl: value.feedUrl,
|
|
960
|
+
isPrimary: value.isPrimary,
|
|
961
|
+
uri: record.uri
|
|
962
|
+
};
|
|
963
|
+
});
|
|
964
|
+
|
|
965
|
+
cache.set(cacheKey, data);
|
|
966
|
+
return data;
|
|
967
|
+
} catch {
|
|
968
|
+
return [];
|
|
969
|
+
}
|
|
970
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -37,7 +37,21 @@ export type {
|
|
|
37
37
|
StandardSiteDocument,
|
|
38
38
|
StandardSiteDocumentsData,
|
|
39
39
|
StandardSiteBasicTheme,
|
|
40
|
-
StandardSiteThemeColor
|
|
40
|
+
StandardSiteThemeColor,
|
|
41
|
+
SifaProfileData,
|
|
42
|
+
SifaSkill,
|
|
43
|
+
SifaProject,
|
|
44
|
+
SifaLanguage,
|
|
45
|
+
SifaCertification,
|
|
46
|
+
SifaExternalAccount,
|
|
47
|
+
SifaLocation,
|
|
48
|
+
SifaPosition,
|
|
49
|
+
SifaEducation,
|
|
50
|
+
SifaVolunteering,
|
|
51
|
+
SifaHonor,
|
|
52
|
+
SifaCourse,
|
|
53
|
+
SifaPublication,
|
|
54
|
+
SifaPublicationAuthor
|
|
41
55
|
} from './types.js';
|
|
42
56
|
|
|
43
57
|
export {
|
|
@@ -47,7 +61,19 @@ export {
|
|
|
47
61
|
fetchMusicStatus,
|
|
48
62
|
fetchKibunStatus,
|
|
49
63
|
fetchTangledRepos,
|
|
50
|
-
fetchRecentPopfeedReviews
|
|
64
|
+
fetchRecentPopfeedReviews,
|
|
65
|
+
fetchSifaProfile,
|
|
66
|
+
fetchSifaSkills,
|
|
67
|
+
fetchSifaProjects,
|
|
68
|
+
fetchSifaLanguages,
|
|
69
|
+
fetchSifaCertifications,
|
|
70
|
+
fetchSifaExternalAccounts,
|
|
71
|
+
fetchSifaPositions,
|
|
72
|
+
fetchSifaEducation,
|
|
73
|
+
fetchSifaVolunteering,
|
|
74
|
+
fetchSifaHonors,
|
|
75
|
+
fetchSifaCourses,
|
|
76
|
+
fetchSifaPublications
|
|
51
77
|
} from './fetch.js';
|
|
52
78
|
|
|
53
79
|
export {
|