@singi-labs/sifa-sdk 0.7.3 → 0.7.5

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