@singi-labs/sifa-sdk 0.7.3 → 0.7.4

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.
@@ -0,0 +1,913 @@
1
+ // src/query/client.ts
2
+ var ApiError = class extends Error {
3
+ status;
4
+ body;
5
+ constructor(message, status, body) {
6
+ super(message);
7
+ this.name = "ApiError";
8
+ this.status = status;
9
+ this.body = body;
10
+ }
11
+ };
12
+ var DEFAULT_TIMEOUT_MS = 1e4;
13
+ var MAX_RATE_LIMIT_RETRIES = 3;
14
+ var RATE_LIMIT_RETRY_CAP_SECONDS = 3;
15
+ async function apiFetch(config, path, options = {}) {
16
+ const fetchFn = config.fetch ?? globalThis.fetch;
17
+ const url = `${config.baseUrl}${path}`;
18
+ const maxRetries = options.retryOn429 ? MAX_RATE_LIMIT_RETRIES : 0;
19
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
20
+ const signal = options.signal ?? AbortSignal.timeout(options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
21
+ const headers = { ...options.headers ?? {} };
22
+ let body;
23
+ if (options.body !== void 0) {
24
+ headers["Content-Type"] ??= "application/json";
25
+ body = JSON.stringify(options.body);
26
+ }
27
+ const init = {
28
+ method: options.method ?? "GET",
29
+ headers,
30
+ body,
31
+ signal,
32
+ credentials: options.credentials,
33
+ cache: options.cache,
34
+ ...options.next ? { next: options.next } : {}
35
+ };
36
+ const res = await fetchFn(url, init);
37
+ if (res.status === 429 && attempt < maxRetries) {
38
+ const retryAfterRaw = res.headers.get("retry-after");
39
+ const retryAfter = retryAfterRaw ? Number.parseInt(retryAfterRaw, 10) : 2;
40
+ const waitSeconds = Math.min(
41
+ Number.isFinite(retryAfter) ? retryAfter : 2,
42
+ RATE_LIMIT_RETRY_CAP_SECONDS
43
+ );
44
+ await new Promise((r) => setTimeout(r, waitSeconds * 1e3));
45
+ continue;
46
+ }
47
+ if (!res.ok) {
48
+ let errBody;
49
+ try {
50
+ errBody = await res.json();
51
+ } catch {
52
+ try {
53
+ errBody = await res.text();
54
+ } catch {
55
+ errBody = void 0;
56
+ }
57
+ }
58
+ throw new ApiError(`Sifa API ${res.status} on ${path}`, res.status, errBody);
59
+ }
60
+ return await res.json();
61
+ }
62
+ throw new ApiError(`Sifa API exhausted retries on ${path}`, 429);
63
+ }
64
+ async function apiFetchOrNull(config, path, options = {}) {
65
+ try {
66
+ return await apiFetch(config, path, options);
67
+ } catch (e) {
68
+ if (e instanceof ApiError && e.status === 404) return null;
69
+ throw e;
70
+ }
71
+ }
72
+ function extractWriteError(data, status) {
73
+ const body = data ?? {};
74
+ return {
75
+ error: body.message ?? `Request failed (${status})`,
76
+ ...body.pdsHost ? { pdsHost: body.pdsHost } : {}
77
+ };
78
+ }
79
+ async function apiWrite(config, path, method, options = {}) {
80
+ try {
81
+ const data = await apiFetch(config, path, {
82
+ method,
83
+ credentials: "include",
84
+ ...options
85
+ });
86
+ return { success: true, ...data ?? {} };
87
+ } catch (e) {
88
+ if (e instanceof ApiError) {
89
+ return { success: false, ...extractWriteError(e.body, e.status) };
90
+ }
91
+ return { success: false, error: "Network error" };
92
+ }
93
+ }
94
+ function apiWriteCreate(config, path, body, options = {}) {
95
+ return apiWrite(config, path, "POST", {
96
+ body,
97
+ ...options
98
+ });
99
+ }
100
+
101
+ // src/query/fetchers/profile.ts
102
+ function fetchProfile(config, handleOrDid, options = {}) {
103
+ const path = `/api/profile/${encodeURIComponent(handleOrDid)}`;
104
+ return apiFetchOrNull(config, path, {
105
+ retryOn429: true,
106
+ ...options
107
+ });
108
+ }
109
+ async function fetchAtFundLink(config, did, options = {}) {
110
+ const path = `/api/profiles/${encodeURIComponent(did)}/at-fund-link`;
111
+ try {
112
+ const data = await apiFetch(config, path, {
113
+ next: { revalidate: 3600 },
114
+ timeoutMs: 5e3,
115
+ ...options
116
+ });
117
+ return typeof data.url === "string" ? data.url : null;
118
+ } catch {
119
+ return null;
120
+ }
121
+ }
122
+
123
+ // src/query/fetchers/profile-mutations.ts
124
+ function updateProfileSelf(config, data, options = {}) {
125
+ return apiWrite(config, "/api/profile/self", "PUT", { body: data, ...options });
126
+ }
127
+ function updateProfileOverride(config, data, options = {}) {
128
+ return apiWrite(config, "/api/profile/override", "PUT", { body: data, ...options });
129
+ }
130
+ function refreshPds(config, options = {}) {
131
+ return apiWrite(
132
+ config,
133
+ "/api/profile/refresh-pds",
134
+ "POST",
135
+ options
136
+ );
137
+ }
138
+ async function uploadAvatar(config, file, options = {}) {
139
+ const fetchFn = config.fetch ?? globalThis.fetch;
140
+ const url = `${config.baseUrl}/api/profile/avatar`;
141
+ const formData = new FormData();
142
+ formData.append("file", file);
143
+ try {
144
+ const res = await fetchFn(url, {
145
+ method: "POST",
146
+ credentials: options.credentials ?? "include",
147
+ body: formData,
148
+ signal: options.signal ?? AbortSignal.timeout(options.timeoutMs ?? 3e4),
149
+ headers: options.headers
150
+ });
151
+ if (!res.ok) {
152
+ const errBody = await res.json().catch(() => ({}));
153
+ const msg = errBody.message ?? `Request failed (${res.status})`;
154
+ const pdsHost = errBody.pdsHost;
155
+ return { success: false, error: msg, ...pdsHost ? { pdsHost } : {} };
156
+ }
157
+ const data = await res.json();
158
+ return { success: true, url: data.url };
159
+ } catch {
160
+ return { success: false, error: "Network error" };
161
+ }
162
+ }
163
+ function deleteAvatarOverride(config, options = {}) {
164
+ return apiWrite(config, "/api/profile/avatar", "DELETE", options);
165
+ }
166
+
167
+ // src/query/fetchers/positions.ts
168
+ function createPosition(config, data, options = {}) {
169
+ return apiWriteCreate(config, "/api/profile/position", data, options);
170
+ }
171
+ function updatePosition(config, rkey, data, options = {}) {
172
+ return apiWrite(config, `/api/profile/position/${encodeURIComponent(rkey)}`, "PUT", {
173
+ body: data,
174
+ ...options
175
+ });
176
+ }
177
+ function deletePosition(config, rkey, options = {}) {
178
+ return apiWrite(config, `/api/profile/position/${encodeURIComponent(rkey)}`, "DELETE", options);
179
+ }
180
+ function setPositionPrimary(config, rkey, options = {}) {
181
+ return apiWrite(
182
+ config,
183
+ `/api/profile/position/${encodeURIComponent(rkey)}/primary`,
184
+ "PUT",
185
+ options
186
+ );
187
+ }
188
+ function unsetPositionPrimary(config, rkey, options = {}) {
189
+ return apiWrite(
190
+ config,
191
+ `/api/profile/position/${encodeURIComponent(rkey)}/primary`,
192
+ "DELETE",
193
+ options
194
+ );
195
+ }
196
+ function buildPositionPayload(position, skills) {
197
+ return {
198
+ company: position.company,
199
+ title: position.title,
200
+ description: position.description,
201
+ startedAt: position.startedAt,
202
+ endedAt: position.endedAt,
203
+ location: position.location ?? void 0,
204
+ skills
205
+ };
206
+ }
207
+ function linkSkillToPosition(config, position, skillRef, options = {}) {
208
+ const currentSkills = position.skills ?? [];
209
+ if (currentSkills.some((s) => s.uri === skillRef.uri)) {
210
+ return Promise.resolve({ success: true });
211
+ }
212
+ return updatePosition(
213
+ config,
214
+ position.rkey,
215
+ buildPositionPayload(position, [...currentSkills, skillRef]),
216
+ options
217
+ );
218
+ }
219
+ function unlinkSkillFromPosition(config, position, skillRef, options = {}) {
220
+ const remaining = (position.skills ?? []).filter((s) => s.uri !== skillRef.uri);
221
+ return updatePosition(config, position.rkey, buildPositionPayload(position, remaining), options);
222
+ }
223
+
224
+ // src/query/fetchers/education.ts
225
+ function createEducation(config, data, options = {}) {
226
+ return apiWriteCreate(config, "/api/profile/education", data, options);
227
+ }
228
+ function updateEducation(config, rkey, data, options = {}) {
229
+ return apiWrite(config, `/api/profile/education/${encodeURIComponent(rkey)}`, "PUT", {
230
+ body: data,
231
+ ...options
232
+ });
233
+ }
234
+ function deleteEducation(config, rkey, options = {}) {
235
+ return apiWrite(config, `/api/profile/education/${encodeURIComponent(rkey)}`, "DELETE", options);
236
+ }
237
+
238
+ // src/query/fetchers/skills.ts
239
+ function createSkill(config, data, options = {}) {
240
+ return apiWriteCreate(config, "/api/profile/skill", data, options);
241
+ }
242
+ function updateSkill(config, rkey, data, options = {}) {
243
+ return apiWrite(config, `/api/profile/skill/${encodeURIComponent(rkey)}`, "PUT", {
244
+ body: data,
245
+ ...options
246
+ });
247
+ }
248
+ function deleteSkill(config, rkey, options = {}) {
249
+ return apiWrite(config, `/api/profile/skill/${encodeURIComponent(rkey)}`, "DELETE", options);
250
+ }
251
+
252
+ // src/query/fetchers/records.ts
253
+ function createRecord(config, collection, data, options = {}) {
254
+ return apiWriteCreate(
255
+ config,
256
+ `/api/profile/records/${encodeURIComponent(collection)}`,
257
+ data,
258
+ options
259
+ );
260
+ }
261
+ function updateRecord(config, collection, rkey, data, options = {}) {
262
+ const path = `/api/profile/records/${encodeURIComponent(collection)}/${encodeURIComponent(rkey)}`;
263
+ return apiWrite(config, path, "PUT", { body: data, ...options });
264
+ }
265
+ function deleteRecord(config, collection, rkey, options = {}) {
266
+ const path = `/api/profile/records/${encodeURIComponent(collection)}/${encodeURIComponent(rkey)}`;
267
+ return apiWrite(config, path, "DELETE", options);
268
+ }
269
+
270
+ // src/query/fetchers/profile-locations.ts
271
+ function createProfileLocation(config, data, options = {}) {
272
+ return apiWriteCreate(config, "/api/profile/location", data, options);
273
+ }
274
+ function updateProfileLocation(config, rkey, data, options = {}) {
275
+ return apiWrite(config, `/api/profile/location/${encodeURIComponent(rkey)}`, "PUT", {
276
+ body: data,
277
+ ...options
278
+ });
279
+ }
280
+ function deleteProfileLocation(config, rkey, options = {}) {
281
+ return apiWrite(config, `/api/profile/location/${encodeURIComponent(rkey)}`, "DELETE", options);
282
+ }
283
+
284
+ // src/query/fetchers/external-accounts.ts
285
+ async function fetchExternalAccounts(config, handleOrDid, options = {}) {
286
+ const path = `/api/profile/${encodeURIComponent(handleOrDid)}/external-accounts`;
287
+ try {
288
+ const data = await apiFetch(config, path, {
289
+ credentials: "include",
290
+ ...options
291
+ });
292
+ return data.accounts ?? [];
293
+ } catch {
294
+ return [];
295
+ }
296
+ }
297
+ function createExternalAccount(config, data, options = {}) {
298
+ return apiWrite(
299
+ config,
300
+ "/api/profile/external-accounts",
301
+ "POST",
302
+ { body: data, ...options }
303
+ );
304
+ }
305
+ function updateExternalAccount(config, rkey, data, options = {}) {
306
+ return apiWrite(config, `/api/profile/external-accounts/${encodeURIComponent(rkey)}`, "PUT", {
307
+ body: data,
308
+ ...options
309
+ });
310
+ }
311
+ function deleteExternalAccount(config, rkey, options = {}) {
312
+ return apiWrite(
313
+ config,
314
+ `/api/profile/external-accounts/${encodeURIComponent(rkey)}`,
315
+ "DELETE",
316
+ options
317
+ );
318
+ }
319
+ function setExternalAccountPrimary(config, rkey, options = {}) {
320
+ return apiWrite(
321
+ config,
322
+ `/api/profile/external-accounts/${encodeURIComponent(rkey)}/primary`,
323
+ "PUT",
324
+ options
325
+ );
326
+ }
327
+ function unsetExternalAccountPrimary(config, rkey, options = {}) {
328
+ return apiWrite(
329
+ config,
330
+ `/api/profile/external-accounts/${encodeURIComponent(rkey)}/primary`,
331
+ "DELETE",
332
+ options
333
+ );
334
+ }
335
+ function verifyExternalAccount(config, rkey, options = {}) {
336
+ return apiWrite(
337
+ config,
338
+ `/api/profile/external-accounts/${encodeURIComponent(rkey)}/verify`,
339
+ "POST",
340
+ { body: {}, ...options }
341
+ );
342
+ }
343
+
344
+ // src/query/fetchers/endorsements.ts
345
+ function createEndorsement(config, data, options = {}) {
346
+ return apiWriteCreate(config, "/api/endorsements", data, options);
347
+ }
348
+
349
+ // src/query/fetchers/keytrace-claims.ts
350
+ function hideKeytraceClaim(config, rkey, options = {}) {
351
+ return apiWrite(
352
+ config,
353
+ `/api/profile/keytrace-claims/${encodeURIComponent(rkey)}/hide`,
354
+ "POST",
355
+ options
356
+ );
357
+ }
358
+ function unhideKeytraceClaim(config, rkey, options = {}) {
359
+ return apiWrite(
360
+ config,
361
+ `/api/profile/keytrace-claims/${encodeURIComponent(rkey)}/hide`,
362
+ "DELETE",
363
+ options
364
+ );
365
+ }
366
+
367
+ // src/query/fetchers/publications.ts
368
+ function hideOrcidPublication(config, putCode, options = {}) {
369
+ return apiWrite(config, `/api/profile/orcid-publications/${putCode}/hide`, "POST", options);
370
+ }
371
+ function unhideOrcidPublication(config, putCode, options = {}) {
372
+ return apiWrite(config, `/api/profile/orcid-publications/${putCode}/hide`, "DELETE", options);
373
+ }
374
+ function hideStandardPublication(config, uri, options = {}) {
375
+ return apiWrite(
376
+ config,
377
+ `/api/profile/standard-publications/${encodeURIComponent(uri)}/hide`,
378
+ "POST",
379
+ options
380
+ );
381
+ }
382
+ function unhideStandardPublication(config, uri, options = {}) {
383
+ return apiWrite(
384
+ config,
385
+ `/api/profile/standard-publications/${encodeURIComponent(uri)}/hide`,
386
+ "DELETE",
387
+ options
388
+ );
389
+ }
390
+ function bulkHideStandardPublications(config, uris, options = {}) {
391
+ return apiWrite(config, "/api/profile/standard-publications/bulk-hide", "POST", {
392
+ body: { uris },
393
+ ...options
394
+ });
395
+ }
396
+ function bulkUnhideStandardPublications(config, uris, options = {}) {
397
+ return apiWrite(config, "/api/profile/standard-publications/bulk-hide", "DELETE", {
398
+ body: { uris },
399
+ ...options
400
+ });
401
+ }
402
+ function hideSifaPublication(config, rkey, options = {}) {
403
+ return apiWrite(config, `/api/profile/publications/${rkey}/hide`, "POST", options);
404
+ }
405
+ function unhideSifaPublication(config, rkey, options = {}) {
406
+ return apiWrite(config, `/api/profile/publications/${rkey}/hide`, "DELETE", options);
407
+ }
408
+ async function refreshOrcidPublications(config, options = {}) {
409
+ const result = await apiWrite(
410
+ config,
411
+ "/api/profile/orcid-publications/refresh",
412
+ "POST",
413
+ { body: {}, ...options }
414
+ );
415
+ if (result.success && result.error) {
416
+ return { success: false, error: result.error };
417
+ }
418
+ return result;
419
+ }
420
+
421
+ // src/query/fetchers/stats.ts
422
+ async function fetchStats(config, options = {}) {
423
+ try {
424
+ return await apiFetch(config, "/api/stats", {
425
+ next: { revalidate: 900 },
426
+ ...options
427
+ });
428
+ } catch {
429
+ return null;
430
+ }
431
+ }
432
+
433
+ // src/query/fetchers/apps.ts
434
+ async function fetchAppsRegistry(config, options = {}) {
435
+ try {
436
+ return await apiFetch(config, "/api/apps/registry", {
437
+ next: { revalidate: 86400 },
438
+ ...options
439
+ });
440
+ } catch {
441
+ return [];
442
+ }
443
+ }
444
+ async function fetchHiddenApps(config, options = {}) {
445
+ const headers = { ...options.headers ?? {} };
446
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
447
+ try {
448
+ const data = await apiFetch(config, "/api/profile/hidden-apps", {
449
+ credentials: "include",
450
+ ...options,
451
+ headers
452
+ });
453
+ return data.apps;
454
+ } catch {
455
+ return [];
456
+ }
457
+ }
458
+
459
+ // src/query/fetchers/search.ts
460
+ var EMPTY_SEARCH = { profiles: [], total: 0, limit: 20, offset: 0 };
461
+ var EMPTY_FILTERS = { countries: [], industries: [], apps: [] };
462
+ async function fetchSearchProfiles(config, filters, options = {}) {
463
+ const params = new URLSearchParams();
464
+ if (filters.q) params.set("q", filters.q);
465
+ if (filters.skill) params.set("skill", filters.skill);
466
+ if (filters.country) params.set("country", filters.country);
467
+ if (filters.industry) params.set("industry", filters.industry);
468
+ if (filters.domain) params.set("domain", filters.domain);
469
+ if (filters.workplace) params.set("workplace", filters.workplace);
470
+ if (filters.app) params.set("app", filters.app);
471
+ if (filters.limit !== void 0) params.set("limit", String(filters.limit));
472
+ if (params.size === 0) return EMPTY_SEARCH;
473
+ return apiFetch(config, `/api/search/profiles?${params.toString()}`, {
474
+ cache: "no-store",
475
+ ...options
476
+ });
477
+ }
478
+ async function fetchSkillSuggestions(config, query, options = {}) {
479
+ if (!query.trim()) return [];
480
+ const path = `/api/search/skills?q=${encodeURIComponent(query)}&limit=8`;
481
+ const data = await apiFetch(config, path, {
482
+ cache: "no-store",
483
+ ...options
484
+ });
485
+ return data.skills ?? [];
486
+ }
487
+ async function fetchSearchFilters(config, options = {}) {
488
+ try {
489
+ return await apiFetch(config, "/api/search/filters", {
490
+ next: { revalidate: 300 },
491
+ ...options
492
+ });
493
+ } catch {
494
+ return EMPTY_FILTERS;
495
+ }
496
+ }
497
+ async function searchSkills(config, query, limit = 10, options = {}) {
498
+ if (!query.trim()) return [];
499
+ const path = `/api/skills/search?q=${encodeURIComponent(query)}&limit=${limit}`;
500
+ try {
501
+ const data = await apiFetch(config, path, {
502
+ cache: "no-store",
503
+ ...options
504
+ });
505
+ return data.skills ?? [];
506
+ } catch {
507
+ return [];
508
+ }
509
+ }
510
+
511
+ // src/query/fetchers/discovery.ts
512
+ async function fetchSimilarProfiles(config, did, opts = {}) {
513
+ const limit = opts.limit ?? 5;
514
+ const path = `/api/discover/similar/${encodeURIComponent(did)}?limit=${limit}`;
515
+ try {
516
+ const data = await apiFetch(config, path, {
517
+ next: { revalidate: 300 },
518
+ timeoutMs: 5e3,
519
+ ...opts
520
+ });
521
+ return data.profiles ?? [];
522
+ } catch {
523
+ return [];
524
+ }
525
+ }
526
+ async function fetchSuggestions(config, opts = {}) {
527
+ const params = new URLSearchParams();
528
+ if (opts.source) params.set("source", opts.source);
529
+ if (opts.includeDismissed) params.set("include_dismissed", "true");
530
+ if (opts.cursor) params.set("cursor", opts.cursor);
531
+ if (opts.limit) params.set("limit", String(opts.limit));
532
+ const qs = params.toString();
533
+ const headers = { ...opts.headers ?? {} };
534
+ if (opts.cookieHeader) headers.cookie = opts.cookieHeader;
535
+ try {
536
+ return await apiFetch(config, `/api/suggestions${qs ? `?${qs}` : ""}`, {
537
+ credentials: "include",
538
+ cache: "no-store",
539
+ timeoutMs: 8e3,
540
+ ...opts,
541
+ headers
542
+ });
543
+ } catch {
544
+ return { onSifa: [], notOnSifa: [] };
545
+ }
546
+ }
547
+ async function fetchSuggestionCount(config, since, options = {}) {
548
+ const params = since ? `?since=${encodeURIComponent(since)}` : "";
549
+ try {
550
+ const data = await apiFetch(config, `/api/suggestions/count${params}`, {
551
+ credentials: "include",
552
+ cache: "no-store",
553
+ ...options
554
+ });
555
+ return data.count ?? 0;
556
+ } catch {
557
+ return 0;
558
+ }
559
+ }
560
+ async function fetchFeaturedProfile(config, options = {}) {
561
+ try {
562
+ return await apiFetch(config, "/api/featured-profile", {
563
+ next: { revalidate: 900 },
564
+ ...options
565
+ });
566
+ } catch {
567
+ return null;
568
+ }
569
+ }
570
+
571
+ // src/query/fetchers/follow.ts
572
+ async function fetchFollowing(config, opts = {}) {
573
+ const params = new URLSearchParams();
574
+ if (opts.source) params.set("source", opts.source);
575
+ if (opts.cursor) params.set("cursor", opts.cursor);
576
+ if (opts.limit) params.set("limit", String(opts.limit));
577
+ const qs = params.toString();
578
+ try {
579
+ return await apiFetch(config, `/api/following${qs ? `?${qs}` : ""}`, {
580
+ credentials: "include",
581
+ cache: "no-store",
582
+ ...opts
583
+ });
584
+ } catch {
585
+ return { follows: [] };
586
+ }
587
+ }
588
+
589
+ // src/query/fetchers/activity.ts
590
+ async function fetchHeatmapData(config, handleOrDid, days, options = {}) {
591
+ const path = `/api/activity/${encodeURIComponent(handleOrDid)}/heatmap?days=${days}`;
592
+ try {
593
+ return await apiFetch(config, path, {
594
+ next: { revalidate: 900, tags: [`heatmap-${handleOrDid}`] },
595
+ ...options
596
+ });
597
+ } catch {
598
+ return null;
599
+ }
600
+ }
601
+ async function fetchActivityTeaser(config, handleOrDid, options = {}) {
602
+ const headers = { ...options.headers ?? {} };
603
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
604
+ try {
605
+ return await apiFetch(
606
+ config,
607
+ `/api/activity/${encodeURIComponent(handleOrDid)}/teaser`,
608
+ {
609
+ credentials: "include",
610
+ timeoutMs: 8e3,
611
+ next: { revalidate: 300, tags: [`activity-teaser-${handleOrDid}`] },
612
+ ...options,
613
+ headers
614
+ }
615
+ );
616
+ } catch {
617
+ return null;
618
+ }
619
+ }
620
+ async function fetchActivityFeed(config, handleOrDid, options = {}) {
621
+ const params = new URLSearchParams();
622
+ if (options.category) params.set("category", options.category);
623
+ if (options.limit) params.set("limit", String(options.limit));
624
+ if (options.cursor) params.set("cursor", options.cursor);
625
+ const qs = params.toString();
626
+ const headers = { ...options.headers ?? {} };
627
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
628
+ try {
629
+ return await apiFetch(
630
+ config,
631
+ `/api/activity/${encodeURIComponent(handleOrDid)}${qs ? `?${qs}` : ""}`,
632
+ {
633
+ credentials: "include",
634
+ cache: "no-store",
635
+ ...options,
636
+ headers
637
+ }
638
+ );
639
+ } catch {
640
+ return null;
641
+ }
642
+ }
643
+
644
+ // src/query/fetchers/endorsement.ts
645
+ async function fetchEndorsementCount(config, did, options = {}) {
646
+ const path = `/api/endorsement/${encodeURIComponent(did)}`;
647
+ try {
648
+ const data = await apiFetch(config, path, {
649
+ cache: "no-store",
650
+ timeoutMs: 5e3,
651
+ ...options
652
+ });
653
+ if (typeof data !== "object" || data === null || !("endorsements" in data)) {
654
+ return 0;
655
+ }
656
+ const endorsements = data.endorsements;
657
+ return Array.isArray(endorsements) ? endorsements.length : 0;
658
+ } catch {
659
+ return 0;
660
+ }
661
+ }
662
+
663
+ // src/query/fetchers/stream.ts
664
+ async function fetchNetworkStreamCount(config, did, options = {}) {
665
+ const headers = { ...options.headers ?? {} };
666
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
667
+ try {
668
+ const data = await apiFetch(
669
+ config,
670
+ `/api/stream/network?did=${encodeURIComponent(did)}`,
671
+ {
672
+ cache: "no-store",
673
+ timeoutMs: 5e3,
674
+ ...options.cookieHeader ? {} : { credentials: "include" },
675
+ ...options,
676
+ headers
677
+ }
678
+ );
679
+ if (typeof data !== "object" || data === null || !("items" in data)) {
680
+ return 0;
681
+ }
682
+ const items = data.items;
683
+ return Array.isArray(items) ? items.length : 0;
684
+ } catch {
685
+ return 0;
686
+ }
687
+ }
688
+
689
+ // src/query/fetchers/reactions.ts
690
+ async function fetchReactionStatus(config, uris, options = {}) {
691
+ if (uris.length === 0) return {};
692
+ const headers = { ...options.headers ?? {} };
693
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
694
+ try {
695
+ return await apiFetch(
696
+ config,
697
+ `/api/reactions/status?uris=${encodeURIComponent(uris.join(","))}`,
698
+ {
699
+ credentials: "include",
700
+ ...options,
701
+ headers
702
+ }
703
+ );
704
+ } catch {
705
+ return null;
706
+ }
707
+ }
708
+ async function checkAppAccount(config, appId, options = {}) {
709
+ const headers = { ...options.headers ?? {} };
710
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
711
+ try {
712
+ return await apiFetch(
713
+ config,
714
+ `/api/reactions/account-check/${encodeURIComponent(appId)}`,
715
+ {
716
+ credentials: "include",
717
+ ...options,
718
+ headers
719
+ }
720
+ );
721
+ } catch {
722
+ return null;
723
+ }
724
+ }
725
+ async function createReaction(config, targetUri, appId, targetCid, options = {}) {
726
+ const fetchFn = config.fetch ?? globalThis.fetch;
727
+ const url = `${config.baseUrl}/api/reactions`;
728
+ try {
729
+ const res = await fetchFn(url, {
730
+ method: "POST",
731
+ headers: { "Content-Type": "application/json", ...options.headers ?? {} },
732
+ credentials: options.credentials ?? "include",
733
+ body: JSON.stringify({ targetUri, appId, targetCid }),
734
+ signal: options.signal ?? AbortSignal.timeout(options.timeoutMs ?? 1e4)
735
+ });
736
+ if (!res.ok) {
737
+ if (res.status === 403) {
738
+ try {
739
+ const body = await res.json();
740
+ if (body.error === "ScopeInsufficient") {
741
+ return {
742
+ ok: false,
743
+ error: { type: "scope_insufficient", requiredScope: body.requiredScope }
744
+ };
745
+ }
746
+ } catch {
747
+ }
748
+ }
749
+ return { ok: false, error: { type: "error" } };
750
+ }
751
+ const data = await res.json();
752
+ return { ok: true, data };
753
+ } catch {
754
+ return { ok: false, error: { type: "error" } };
755
+ }
756
+ }
757
+ function deleteReaction(config, targetUri, appId, options = {}) {
758
+ return apiWrite(config, "/api/reactions", "DELETE", {
759
+ body: { targetUri, appId },
760
+ ...options
761
+ });
762
+ }
763
+
764
+ // src/query/fetchers/quoted-posts.ts
765
+ var QUOTED_POSTS_BATCH_MAX = 20;
766
+ async function resolveQuotedPosts(config, uris, options = {}) {
767
+ if (uris.length === 0) return {};
768
+ const unique = [...new Set(uris)];
769
+ const batches = [];
770
+ for (let i = 0; i < unique.length; i += QUOTED_POSTS_BATCH_MAX) {
771
+ batches.push(unique.slice(i, i + QUOTED_POSTS_BATCH_MAX));
772
+ }
773
+ const headers = { ...options.headers ?? {} };
774
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
775
+ const results = {};
776
+ await Promise.all(
777
+ batches.map(async (batch) => {
778
+ try {
779
+ const data = await apiFetch(
780
+ config,
781
+ "/api/quoted-posts/resolve",
782
+ {
783
+ method: "POST",
784
+ body: { uris: batch },
785
+ credentials: "include",
786
+ timeoutMs: 8e3,
787
+ ...options,
788
+ headers
789
+ }
790
+ );
791
+ Object.assign(results, data);
792
+ } catch {
793
+ }
794
+ })
795
+ );
796
+ return results;
797
+ }
798
+
799
+ // src/query/fetchers/roadmap.ts
800
+ async function fetchRoadmapVotes(config, options = {}) {
801
+ try {
802
+ return await apiFetch(config, "/api/roadmap/votes", {
803
+ cache: "no-store",
804
+ ...options
805
+ });
806
+ } catch {
807
+ return {};
808
+ }
809
+ }
810
+ async function fetchMyRoadmapVotes(config, options = {}) {
811
+ const headers = { ...options.headers ?? {} };
812
+ if (options.cookieHeader) headers.cookie = options.cookieHeader;
813
+ try {
814
+ const data = await apiFetch(config, "/api/roadmap/votes/me", {
815
+ credentials: "include",
816
+ ...options,
817
+ headers
818
+ });
819
+ return data.voted ?? [];
820
+ } catch {
821
+ return [];
822
+ }
823
+ }
824
+ function castRoadmapVote(config, key, options = {}) {
825
+ return apiWrite(config, `/api/roadmap/votes/${encodeURIComponent(key)}`, "POST", options);
826
+ }
827
+ function retractRoadmapVote(config, key, options = {}) {
828
+ return apiWrite(config, `/api/roadmap/votes/${encodeURIComponent(key)}`, "DELETE", options);
829
+ }
830
+
831
+ // src/query/fetchers/destructive.ts
832
+ function resetProfile(config, deletePdsData, options = {}) {
833
+ return apiWrite(config, "/api/profile/reset", "DELETE", {
834
+ body: { deletePdsData },
835
+ ...options
836
+ });
837
+ }
838
+ function deleteAccount(config, deletePdsData, options = {}) {
839
+ return apiWrite(config, "/api/profile/account", "DELETE", {
840
+ body: { deletePdsData },
841
+ ...options
842
+ });
843
+ }
844
+
845
+ // src/query/keys.ts
846
+ var sifaQueryKeys = {
847
+ all: () => ["sifa"],
848
+ profile: {
849
+ all: () => ["sifa", "profile"],
850
+ byHandle: (handleOrDid) => ["sifa", "profile", handleOrDid],
851
+ atFundLink: (did) => ["sifa", "profile", "at-fund-link", did],
852
+ externalAccounts: (handleOrDid) => ["sifa", "profile", "external-accounts", handleOrDid]
853
+ },
854
+ position: {
855
+ all: () => ["sifa", "position"],
856
+ byOwner: (did) => ["sifa", "position", "by-owner", did]
857
+ },
858
+ search: {
859
+ all: () => ["sifa", "search"],
860
+ profiles: (filters) => ["sifa", "search", "profiles", filters],
861
+ skills: (query) => ["sifa", "search", "skills", query],
862
+ canonicalSkills: (query, limit) => ["sifa", "search", "canonical-skills", query, limit],
863
+ filters: () => ["sifa", "search", "filters"]
864
+ },
865
+ discovery: {
866
+ all: () => ["sifa", "discovery"],
867
+ similar: (did, limit) => ["sifa", "discovery", "similar", did, limit],
868
+ suggestions: (opts) => ["sifa", "discovery", "suggestions", opts],
869
+ suggestionCount: (since) => ["sifa", "discovery", "suggestion-count", since ?? null],
870
+ featured: () => ["sifa", "discovery", "featured"]
871
+ },
872
+ follow: {
873
+ all: () => ["sifa", "follow"],
874
+ following: (opts) => ["sifa", "follow", "following", opts]
875
+ },
876
+ stats: {
877
+ all: () => ["sifa", "stats"],
878
+ homepage: () => ["sifa", "stats", "homepage"]
879
+ },
880
+ apps: {
881
+ all: () => ["sifa", "apps"],
882
+ registry: () => ["sifa", "apps", "registry"],
883
+ hidden: () => ["sifa", "apps", "hidden"]
884
+ },
885
+ activity: {
886
+ all: () => ["sifa", "activity"],
887
+ heatmap: (handleOrDid, days) => ["sifa", "activity", "heatmap", handleOrDid, days],
888
+ teaser: (handleOrDid) => ["sifa", "activity", "teaser", handleOrDid],
889
+ feed: (handleOrDid, opts) => ["sifa", "activity", "feed", handleOrDid, opts]
890
+ },
891
+ endorsement: {
892
+ all: () => ["sifa", "endorsement"],
893
+ count: (did) => ["sifa", "endorsement", "count", did]
894
+ },
895
+ stream: {
896
+ all: () => ["sifa", "stream"],
897
+ networkCount: (did) => ["sifa", "stream", "network-count", did]
898
+ },
899
+ reactions: {
900
+ all: () => ["sifa", "reactions"],
901
+ status: (uris) => ["sifa", "reactions", "status", uris],
902
+ accountCheck: (appId) => ["sifa", "reactions", "account-check", appId]
903
+ },
904
+ roadmap: {
905
+ all: () => ["sifa", "roadmap"],
906
+ votes: () => ["sifa", "roadmap", "votes"],
907
+ myVotes: () => ["sifa", "roadmap", "my-votes"]
908
+ }
909
+ };
910
+
911
+ export { ApiError, QUOTED_POSTS_BATCH_MAX, apiFetch, apiFetchOrNull, apiWrite, apiWriteCreate, bulkHideStandardPublications, bulkUnhideStandardPublications, castRoadmapVote, checkAppAccount, createEducation, createEndorsement, createExternalAccount, createPosition, createProfileLocation, createReaction, createRecord, createSkill, deleteAccount, deleteAvatarOverride, deleteEducation, deleteExternalAccount, deletePosition, deleteProfileLocation, deleteReaction, deleteRecord, deleteSkill, fetchActivityFeed, fetchActivityTeaser, fetchAppsRegistry, fetchAtFundLink, fetchEndorsementCount, fetchExternalAccounts, fetchFeaturedProfile, fetchFollowing, fetchHeatmapData, fetchHiddenApps, fetchMyRoadmapVotes, fetchNetworkStreamCount, fetchProfile, fetchReactionStatus, fetchRoadmapVotes, fetchSearchFilters, fetchSearchProfiles, fetchSimilarProfiles, fetchSkillSuggestions, fetchStats, fetchSuggestionCount, fetchSuggestions, hideKeytraceClaim, hideOrcidPublication, hideSifaPublication, hideStandardPublication, linkSkillToPosition, refreshOrcidPublications, refreshPds, resetProfile, resolveQuotedPosts, retractRoadmapVote, searchSkills, setExternalAccountPrimary, setPositionPrimary, sifaQueryKeys, unhideKeytraceClaim, unhideOrcidPublication, unhideSifaPublication, unhideStandardPublication, unlinkSkillFromPosition, unsetExternalAccountPrimary, unsetPositionPrimary, updateEducation, updateExternalAccount, updatePosition, updateProfileLocation, updateProfileOverride, updateProfileSelf, updateRecord, updateSkill, uploadAvatar, verifyExternalAccount };
912
+ //# sourceMappingURL=index.js.map
913
+ //# sourceMappingURL=index.js.map