@recursiv/sdk 0.7.123 → 0.7.195
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/README.md +78 -6
- package/dist/index.d.ts +13 -7
- package/dist/index.js +6 -1
- package/dist/privacy/facts.generated.d.ts +52 -3
- package/dist/privacy/facts.generated.js +59 -3
- package/dist/resources/agents.d.ts +10 -1
- package/dist/resources/agents.js +11 -0
- package/dist/resources/alive.d.ts +61 -0
- package/dist/resources/alive.js +16 -0
- package/dist/resources/boosts.d.ts +110 -1
- package/dist/resources/boosts.js +80 -0
- package/dist/resources/deployments.d.ts +5 -1
- package/dist/resources/discovery.d.ts +5 -2
- package/dist/resources/evidence.d.ts +57 -2
- package/dist/resources/evidence.js +19 -0
- package/dist/resources/feeds.d.ts +63 -0
- package/dist/resources/feeds.js +12 -0
- package/dist/resources/member-experience.d.ts +24 -0
- package/dist/resources/member-experience.js +1 -0
- package/dist/resources/protocols.d.ts +409 -20
- package/dist/resources/protocols.js +153 -6
- package/dist/resources/reports.d.ts +11 -2
- package/dist/resources/reports.js +5 -1
- package/dist/resources/search.d.ts +94 -4
- package/dist/resources/settings.d.ts +12 -2
- package/dist/resources/settings.js +15 -2
- package/dist/types.d.ts +26 -1
- package/llm.md +49 -6
- package/package.json +1 -1
|
@@ -28,7 +28,22 @@ export const PROTOCOL_ADAPTER_MATURITIES = Object.freeze([
|
|
|
28
28
|
'beta',
|
|
29
29
|
'stable',
|
|
30
30
|
]);
|
|
31
|
+
function nostrStepUpBody(stepUp) {
|
|
32
|
+
const password = typeof stepUp?.password === 'string' ? stepUp.password : '';
|
|
33
|
+
const emailCode = typeof stepUp?.emailCode === 'string' ? stepUp.emailCode.trim() : '';
|
|
34
|
+
if (Boolean(password) === Boolean(emailCode)) {
|
|
35
|
+
throw new ValidationError({ type: 'validation_error', code: 'invalid_input', message: 'Send the account password, or the emailed nostr_key code, not both' });
|
|
36
|
+
}
|
|
37
|
+
return password ? { password } : { email_code: emailCode };
|
|
38
|
+
}
|
|
31
39
|
const NATIVE_NETWORKS = ['activitypub', 'atproto', 'nostr'];
|
|
40
|
+
function engageOneBody(input) {
|
|
41
|
+
if (input.identity !== undefined && input.identity !== 'native' && input.identity !== 'linked') {
|
|
42
|
+
throw new ValidationError({ type: 'validation_error', code: 'invalid_input', message: 'identity must be native or linked' });
|
|
43
|
+
}
|
|
44
|
+
return { clientMutationId: input.clientMutationId, protocol: input.protocol, nativeId: input.nativeId, action: input.action,
|
|
45
|
+
...(input.identity !== undefined ? { identity: input.identity } : {}), ...(input.accountId !== undefined ? { accountId: input.accountId } : {}) };
|
|
46
|
+
}
|
|
32
47
|
function nativeNetworkPath(network) {
|
|
33
48
|
if (!NATIVE_NETWORKS.includes(network)) {
|
|
34
49
|
throw new ValidationError({ type: 'validation_error', code: 'invalid_network', message: 'network must be activitypub, atproto or nostr' });
|
|
@@ -201,6 +216,15 @@ export class ProtocolsResource {
|
|
|
201
216
|
throw error;
|
|
202
217
|
}
|
|
203
218
|
}
|
|
219
|
+
/**
|
|
220
|
+
* A category's stories, open-network posts and clips for a signed-out visitor, in one keyless read (SharedCategorySurface).
|
|
221
|
+
* The answer is the same for every visitor of the app, category and Politics choice, and the URL carries nothing else,
|
|
222
|
+
* so a shared cache may keep it for 30 s. Only `category` and `compass` are sent: the server refuses any other
|
|
223
|
+
* parameter. An API that predates the route answers 401 `missing_api_key` (it falls through to the keyed routes) or 404.
|
|
224
|
+
*/
|
|
225
|
+
getSharedCategorySurface(projectId, params, options) {
|
|
226
|
+
return this.client.get(`/protocols/public/${encodeURIComponent(projectId)}/category`, { category: params.category, ...(params.compass !== undefined ? { compass: params.compass } : {}) }, ...readOptions(options));
|
|
227
|
+
}
|
|
204
228
|
publicNetworks() {
|
|
205
229
|
return this.client.get('/protocols/social/networks');
|
|
206
230
|
}
|
|
@@ -315,9 +339,14 @@ export class ProtocolsResource {
|
|
|
315
339
|
async getPublicViral(params = {}, options) {
|
|
316
340
|
return viralRead(await this.client.get('/protocols/social/viral', viralQuery(params), ...readOptions(options)));
|
|
317
341
|
}
|
|
318
|
-
/**
|
|
342
|
+
/**
|
|
343
|
+
* Popular public accounts with explicit provenance; served from the app's index when a fresh snapshot exists.
|
|
344
|
+
* `protocol: 'all'` reads the famous accounts of every network in one list, paged for infinite scroll, optionally
|
|
345
|
+
* narrowed to a `category`; `compass: 'hide'` leaves political accounts out of any list.
|
|
346
|
+
*/
|
|
319
347
|
getPublicPopularProfiles(params) {
|
|
320
|
-
return this.client.get('/protocols/social/popular-profiles', { protocol: params.protocol, limit: params.limit, cursor: params.cursor
|
|
348
|
+
return this.client.get('/protocols/social/popular-profiles', { protocol: params.protocol, limit: params.limit, cursor: params.cursor,
|
|
349
|
+
...(params.category !== undefined ? { category: params.category } : {}), ...(params.compass !== undefined ? { compass: params.compass } : {}) });
|
|
321
350
|
}
|
|
322
351
|
/** Read this connected account's current native following; never infer it from a public count. */
|
|
323
352
|
nativeFollowState(input) {
|
|
@@ -550,6 +579,122 @@ export class ProtocolsResource {
|
|
|
550
579
|
const body = input.enabled ? { enabled: true } : { enabled: false, ...(input.removePast !== undefined ? { remove_past: input.removePast } : {}) };
|
|
551
580
|
return this.client.put(nativeNetworkPath(network), body);
|
|
552
581
|
}
|
|
582
|
+
/**
|
|
583
|
+
* Which identity a one-tap action uses on a network when the member also linked an outside account there (0.7.191).
|
|
584
|
+
* `linked` needs a linked account (409 `linked_account_required`); `native` needs the network on, ready or pending
|
|
585
|
+
* (409 `native_network_off`) and a network that can send a tap as the member's identity (503
|
|
586
|
+
* `native_network_unavailable`, reason `adapter_missing`, otherwise), and sets the identity up now when that is what the
|
|
587
|
+
* choice needs. Needs `users:write`.
|
|
588
|
+
*/
|
|
589
|
+
setEngageDefault(network, engageDefault) {
|
|
590
|
+
if (engageDefault !== 'native' && engageDefault !== 'linked') {
|
|
591
|
+
throw new ValidationError({ type: 'validation_error', code: 'invalid_input', message: 'engageDefault must be native or linked' });
|
|
592
|
+
}
|
|
593
|
+
return this.client.put(`${nativeNetworkPath(network)}/engage-default`, { engage_default: engageDefault });
|
|
594
|
+
}
|
|
595
|
+
/**
|
|
596
|
+
* "Get my AT Protocol password" (0.7.191): the PDS emails a reset code to the member's verified address, the one their hosted AT
|
|
597
|
+
* Protocol account uses; Minds never holds or shows that password (it keeps only a revocable app password, which the
|
|
598
|
+
* member can revoke from any AT Protocol app). Needs a step-up (403 `step_up_required` / `step_up_failed`). Other
|
|
599
|
+
* refusals: 404 `no_identity`, 409 `needs_verified_email` or `email_changed`, 429 `rate_limited`. Needs `users:write`.
|
|
600
|
+
* Never auto-retried.
|
|
601
|
+
*/
|
|
602
|
+
claimAtprotoPassword(proof) {
|
|
603
|
+
const body = 'password' in proof ? { password: proof.password } : { email_code: proof.emailCode };
|
|
604
|
+
return this.client.post(`${nativeNetworkPath('atproto')}/claim-password`, body, { retry: false });
|
|
605
|
+
}
|
|
606
|
+
/**
|
|
607
|
+
* "Let Minds act as your AT Protocol account" (0.7.191): the way back when AT Protocol reads `needs_action` with reason
|
|
608
|
+
* `needs_atproto_grant` (an account made before Minds ran it natively) or `error` with `app_password_revoked`. The member
|
|
609
|
+
* enters their AT Protocol account's password once (the main one, which `claimAtprotoPassword` lets them set, or a
|
|
610
|
+
* non-privileged app password they made); Minds keeps only a new revocable app password and drops the password given.
|
|
611
|
+
* Refusals: 403 `password_failed`, 400 `privileged_app_password` (one that can read direct messages), 409
|
|
612
|
+
* `identity_mismatch`, 404 `no_identity`, 429 `rate_limited`. Needs `users:write`. Never auto-retried.
|
|
613
|
+
*/
|
|
614
|
+
grantAtproto(input) {
|
|
615
|
+
return this.client.post(`${nativeNetworkPath('atproto')}/grant`, { password: input.password }, { retry: false });
|
|
616
|
+
}
|
|
617
|
+
/** The member's one-tap actions waiting for their native identity to be set up, oldest first (0.7.191). Needs `users:read`. */
|
|
618
|
+
pendingInteractions() {
|
|
619
|
+
return this.client.get('/protocols/interactions/pending');
|
|
620
|
+
}
|
|
621
|
+
/**
|
|
622
|
+
* One-tap like or unlike (0.7.191). A native answer is sent (`NativeEngageSent`) or queued (`NativeEngageQueued`, 202)
|
|
623
|
+
* while the identity is set up; a linked answer is the review to submit with `submitNativeLike`, as before. Refusals:
|
|
624
|
+
* 409 `native_network_off` (with `reason`), 409 `linked_account_required`, 429 `too_many_pending`, and 503
|
|
625
|
+
* `native_network_unavailable` with reason `adapter_missing` while the network cannot send a tap as the member's identity
|
|
626
|
+
* (a linked account acts instead when there is one; nothing is set up or queued). Keep
|
|
627
|
+
* `clientMutationId` across retries: a retried tap is never sent twice, and once it expired unsent the retry answers
|
|
628
|
+
* `delivery: { state: 'failed', code: 'interaction_expired' }` (a new tap takes a new id). The same id on a different
|
|
629
|
+
* action, target or words is 409 `client_mutation_reused`. A tap whose identity went off before it was sent answers
|
|
630
|
+
* `delivery: { state: 'failed', code: 'native_network_off' }`. Never auto-retried.
|
|
631
|
+
*/
|
|
632
|
+
engageLike(input) {
|
|
633
|
+
return this.client.post('/protocols/social/likes/prepare', engageOneBody(input), { retry: false });
|
|
634
|
+
}
|
|
635
|
+
/** One-tap repost or unrepost (0.7.191); answers as `engageLike` does (linked: submit with `submitNativeRepost`). */
|
|
636
|
+
engageRepost(input) {
|
|
637
|
+
return this.client.post('/protocols/social/reposts/prepare', engageOneBody(input), { retry: false });
|
|
638
|
+
}
|
|
639
|
+
/** One-tap follow or unfollow (0.7.191); answers as `engageLike` does (linked: submit with `submitNativeFollow`). */
|
|
640
|
+
engageFollow(input) {
|
|
641
|
+
return this.client.post('/protocols/social/follows/prepare', engageOneBody(input), { retry: false });
|
|
642
|
+
}
|
|
643
|
+
/**
|
|
644
|
+
* A reply as the member's own identity on the parent's network, or (identity `linked`, or `accountIds`) the shared
|
|
645
|
+
* reply review as `prepareNativeReply` (0.7.191). Answers as `engageLike` does. `media` takes only the member's own
|
|
646
|
+
* Minds uploads, native or linked (400 `invalid_reply` otherwise; 422 `media_unsupported` for a GIF with other images
|
|
647
|
+
* on ActivityPub).
|
|
648
|
+
*/
|
|
649
|
+
engageReply(input) {
|
|
650
|
+
return this.client.post('/protocols/social/replies/prepare', { clientMutationId: input.clientMutationId, text: input.text,
|
|
651
|
+
parent: { protocol: input.parent.protocol, nativeId: input.parent.nativeId, ...(input.parent.readRef !== undefined ? { readRef: input.parent.readRef } : {}) },
|
|
652
|
+
...(input.media !== undefined ? { media: nativeMediaInput(input.media) } : {}),
|
|
653
|
+
...(input.identity !== undefined ? { identity: input.identity } : {}),
|
|
654
|
+
...(input.accountIds !== undefined ? { accountIds: input.accountIds } : {}) }, { retry: false });
|
|
655
|
+
}
|
|
656
|
+
/**
|
|
657
|
+
* A quote of a post as the member's own identity on its network, or (identity `linked`, or `accountIds`) the post
|
|
658
|
+
* review as `prepareNativePost` (0.7.191). A post with no quote is never native: the member's posts in the app reach
|
|
659
|
+
* their networks on their own (409 `native_post_from_app`). Answers as `engageLike` does.
|
|
660
|
+
*/
|
|
661
|
+
engageQuote(input) {
|
|
662
|
+
return this.client.post('/protocols/social/posts/prepare', { clientMutationId: input.clientMutationId, text: input.text,
|
|
663
|
+
quote: { protocol: input.quote.protocol, nativeId: input.quote.nativeId },
|
|
664
|
+
...(input.media !== undefined ? { media: nativeMediaInput(input.media) } : {}),
|
|
665
|
+
...(input.identity !== undefined ? { identity: input.identity } : {}),
|
|
666
|
+
...(input.accountIds !== undefined ? { accountIds: input.accountIds } : {}) }, { retry: false });
|
|
667
|
+
}
|
|
668
|
+
/**
|
|
669
|
+
* Takes the member's managed Nostr key home, step 1: the key as an `nsec`, after a step-up (403 `step_up_required`
|
|
670
|
+
* or `step_up_failed`, 429 `rate_limited`, 404 `no_managed_key`). Minds keeps its copy. Never retried. Needs
|
|
671
|
+
* `users:write`.
|
|
672
|
+
*/
|
|
673
|
+
exportNostrKey(stepUp) {
|
|
674
|
+
return this.client.post('/protocols/networks/nostr/export', nostrStepUpBody(stepUp), { retry: false });
|
|
675
|
+
}
|
|
676
|
+
/** Step 2a: a single-use challenge for the member's signer to sign with the same key (NIP-07, never published). */
|
|
677
|
+
nostrRebindChallenge() {
|
|
678
|
+
return this.client.post('/protocols/networks/nostr/rebind-challenge', {});
|
|
679
|
+
}
|
|
680
|
+
/**
|
|
681
|
+
* Step 2b: the signed challenge. A signature from the identity's own key sets the mode to `attached` (409
|
|
682
|
+
* `rebind_mismatch` for another key; 400 `invalid_proof`, `expired_proof` or `used_proof`). Minds still holds its copy.
|
|
683
|
+
*/
|
|
684
|
+
rebindNostrKey(event) {
|
|
685
|
+
return this.client.post('/protocols/networks/nostr/rebind', { event }, { retry: false });
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Step 3: after a step-up, and only once rebound (409 `rebind_required`), Minds deletes its encrypted copy of the
|
|
689
|
+
* key. First it signs, with the copy, a takedown for everything it published with the key, kept so a post deletion,
|
|
690
|
+
* "Remove what I already shared" or the account's deletion still takes Minds' notes down (409 `too_many_published`
|
|
691
|
+
* when there is too much: the copy is kept). The NIP-05 address keeps the same key; every later Nostr action is a
|
|
692
|
+
* signing request for the member's device. Not undoable by Minds: make sure their signer holds the key first. Never
|
|
693
|
+
* retried.
|
|
694
|
+
*/
|
|
695
|
+
deleteManagedNostrCopy(stepUp) {
|
|
696
|
+
return this.client.post('/protocols/networks/nostr/delete-managed-copy', nostrStepUpBody(stepUp), { retry: false });
|
|
697
|
+
}
|
|
553
698
|
/** Current Minds-hosted ActivityPub state for this app user; never provisions. */
|
|
554
699
|
federationIdentity() {
|
|
555
700
|
return this.client.get('/protocols/social/federation/identity');
|
|
@@ -577,7 +722,7 @@ export class ProtocolsResource {
|
|
|
577
722
|
source: { protocol: input.source.protocol, nativeId: input.source.nativeId,
|
|
578
723
|
...(input.source.readRef !== undefined ? { readRef: input.source.readRef } : {}) } }
|
|
579
724
|
: { action: input.action, postId: input.postId };
|
|
580
|
-
return this.client.post(`/protocols/social/nostr/${encodeURIComponent(id)}/prepare`, body, { retry: false });
|
|
725
|
+
return this.client.post(`/protocols/social/nostr/${encodeURIComponent(id)}/prepare`, input.send === true ? { ...body, send: true } : body, { retry: false });
|
|
581
726
|
}
|
|
582
727
|
/** Pass only the public signed event. After a timeout, read the prepared postId (delete) or eventId (publish/reply/linked_post).
|
|
583
728
|
* Any user-selected retry keeps the same intent/event. */
|
|
@@ -644,9 +789,11 @@ export class ProtocolsResource {
|
|
|
644
789
|
*
|
|
645
790
|
* Failures to expect: `handle_unavailable` (409, taken or reserved; choose
|
|
646
791
|
* another), `identity_conflict` (409, the member already has one),
|
|
647
|
-
* `creation_in_progress` (409),
|
|
648
|
-
*
|
|
649
|
-
*
|
|
792
|
+
* `creation_in_progress` (409), `outbound_refused` (403, the server's one
|
|
793
|
+
* outbound guard said no before the PDS was asked anything; nothing was
|
|
794
|
+
* created), and the operator-side 503s `handle_dns_unavailable`,
|
|
795
|
+
* `handle_unresolvable`, `handle_unverified` and `hosted_server_unavailable`,
|
|
796
|
+
* which succeed unchanged once the operator is done.
|
|
650
797
|
*/
|
|
651
798
|
createHostedIdentity(input) {
|
|
652
799
|
const { protocol, handle, email } = input;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { HttpClient } from '../client.js';
|
|
2
2
|
import type { PaginatedResponse, SingleResponse } from '../types.js';
|
|
3
|
-
export type ReportTargetType = 'post' | 'user' | 'community' | 'message' | 'source_actor' | 'source_post';
|
|
3
|
+
export type ReportTargetType = 'post' | 'user' | 'community' | 'message' | 'sealed_answer' | 'source_actor' | 'source_post';
|
|
4
4
|
export type ReportStatus = 'pending' | 'in_review' | 'escalated' | 'resolved' | 'dismissed';
|
|
5
5
|
export interface CreateReportInput {
|
|
6
6
|
/** External sources require protocols.reportSource so evidence is verified. */
|
|
7
7
|
target_type: Exclude<ReportTargetType, 'source_actor' | 'source_post'>;
|
|
8
|
+
/** For sealed_answer, the authenticated project key's project id; it does not accuse the reporter. Requires supporting API. */
|
|
8
9
|
target_id: string;
|
|
9
10
|
reason: string;
|
|
10
11
|
details?: string;
|
|
@@ -32,9 +33,13 @@ export declare class ReportsResource {
|
|
|
32
33
|
private client;
|
|
33
34
|
constructor(client: HttpClient);
|
|
34
35
|
/**
|
|
35
|
-
* Submit a content report. Targets a post, user, community, or
|
|
36
|
+
* Submit a content report. Targets a post, user, community, message, or Sealed answer
|
|
36
37
|
* by ID, with a short reason and optional free-text details. Reporter
|
|
37
38
|
* is the authenticated user.
|
|
39
|
+
* A sealed_answer targets the key's own project and needs posts:write on a human-owned,
|
|
40
|
+
* non-agent project key. This intake does not recheck live app membership; the Sealed
|
|
41
|
+
* gateway's report route does. Review applies no account enforcement.
|
|
42
|
+
* Deploy supporting API before client adoption.
|
|
38
43
|
*
|
|
39
44
|
* Sent once, never retried automatically: past the member's report budget
|
|
40
45
|
* the server answers 429 (`RateLimitError`, `retryAfter` = seconds until
|
|
@@ -42,6 +47,10 @@ export declare class ReportsResource {
|
|
|
42
47
|
*/
|
|
43
48
|
create(input: CreateReportInput): Promise<SingleResponse<{
|
|
44
49
|
success: true;
|
|
50
|
+
id?: string;
|
|
51
|
+
existing?: boolean;
|
|
52
|
+
/** Sealed answers: false when a join kept the reason but the selected exchange did not fit in full. */
|
|
53
|
+
details_kept?: boolean;
|
|
45
54
|
}>>;
|
|
46
55
|
/** List recent reports in the caller's project/network (admin only). */
|
|
47
56
|
list(): Promise<PaginatedResponse<ReportRecord>>;
|
|
@@ -4,9 +4,13 @@ export class ReportsResource {
|
|
|
4
4
|
this.client = client;
|
|
5
5
|
}
|
|
6
6
|
/**
|
|
7
|
-
* Submit a content report. Targets a post, user, community, or
|
|
7
|
+
* Submit a content report. Targets a post, user, community, message, or Sealed answer
|
|
8
8
|
* by ID, with a short reason and optional free-text details. Reporter
|
|
9
9
|
* is the authenticated user.
|
|
10
|
+
* A sealed_answer targets the key's own project and needs posts:write on a human-owned,
|
|
11
|
+
* non-agent project key. This intake does not recheck live app membership; the Sealed
|
|
12
|
+
* gateway's report route does. Review applies no account enforcement.
|
|
13
|
+
* Deploy supporting API before client adoption.
|
|
10
14
|
*
|
|
11
15
|
* Sent once, never retried automatically: past the member's report budget
|
|
12
16
|
* the server answers 429 (`RateLimitError`, `retryAfter` = seconds until
|
|
@@ -35,9 +35,35 @@ export interface SearchLadder {
|
|
|
35
35
|
pending: number;
|
|
36
36
|
unavailable: string[];
|
|
37
37
|
}
|
|
38
|
-
/**
|
|
38
|
+
/**
|
|
39
|
+
* What a search post's picture is (server 0.7.162, picture-facts-v1: Jev's background read of pictures every floor
|
|
40
|
+
* cleared, cached 30 days). Layout hints only, never a safety signal: absent until the picture is judged, when the
|
|
41
|
+
* server's switch is off, or on servers before 0.7.162, and a client keeps its own layout then.
|
|
42
|
+
*/
|
|
43
|
+
export interface SearchPicture {
|
|
44
|
+
/** `text_graphic`: a screenshot, headline card, table, chart, poster or infographic. `other`: a meme or anything else. */
|
|
45
|
+
kind: 'photo' | 'illustration' | 'text_graphic' | 'other';
|
|
46
|
+
/** Most of what it says is written text: show it whole (contain), not cropped, and do not lead with it. */
|
|
47
|
+
textHeavy: boolean;
|
|
48
|
+
/** How good a big tile it makes, 0 (unusable) to 3 (striking). */
|
|
49
|
+
tileQuality: number;
|
|
50
|
+
/** Where its main subject is, as fractions of the width (`x`) and height (`y`) from the top left: a crop's object position. */
|
|
51
|
+
focal?: {
|
|
52
|
+
x: number;
|
|
53
|
+
y: number;
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Whether the picture itself shows what was searched (0.7.190, search-picture-subject-v1, cached 7 days per query and
|
|
57
|
+
* picture): on a visitor's `deep` stage only, for the page's top pictures. Absent unless the operator turned on
|
|
58
|
+
* `SEARCH_PICTURE_SUBJECT` (with picture facts), and until that query's picture is judged. A layout hint (make a big
|
|
59
|
+
* tile of it when `true`), never a reason to hide a result and never a safety signal.
|
|
60
|
+
*/
|
|
61
|
+
showsQuery?: boolean;
|
|
62
|
+
}
|
|
63
|
+
/** A post as a search lists it: `via` says how the ladder found it (absent from servers before 0.7.79); `picture`: SearchPicture. */
|
|
39
64
|
export type SearchPost = Post & {
|
|
40
65
|
via?: SearchVia;
|
|
66
|
+
picture?: SearchPicture;
|
|
41
67
|
};
|
|
42
68
|
/**
|
|
43
69
|
* A visitor's search tabs (tRPC `publicDiscovery.search`, read keyless through the app's public client). `media` (server
|
|
@@ -62,12 +88,50 @@ export interface PublicSearchPage<T = Record<string, unknown>> {
|
|
|
62
88
|
};
|
|
63
89
|
/** The `media` tab only: what the web has for the words. Absent where the app does not get it (`ladder.unavailable` names `media`). */
|
|
64
90
|
media?: SearchMedia;
|
|
91
|
+
/**
|
|
92
|
+
* A posts tab's deep stage, page 1 only (server 0.7.137): searches related to what the words mean, best first, for
|
|
93
|
+
* related-topic chips ("hockey": NHL, Stanley Cup). Absent when the server has none in time, and from older servers.
|
|
94
|
+
*/
|
|
95
|
+
related_queries?: Array<{
|
|
96
|
+
query: string;
|
|
97
|
+
}>;
|
|
98
|
+
/**
|
|
99
|
+
* The page's clips in lead order (server 0.7.173): its posts' clips, the open networks' and the `media` tab's videos,
|
|
100
|
+
* the most about the words first (`SearchVideoLeadEntry`). The `videos` tab's `items` already come in this order.
|
|
101
|
+
* Absent with no clip, from older servers, or when the operator turned the lead order off.
|
|
102
|
+
*/
|
|
103
|
+
video_lead?: SearchVideoLeadEntry[];
|
|
104
|
+
}
|
|
105
|
+
/** Where a clip in a search's `video_lead` came from: a Minds member's post, an open-network post, PeerTube, or the web. */
|
|
106
|
+
export type SearchVideoLeadSource = 'minds' | 'open_network' | 'peertube' | 'web';
|
|
107
|
+
/**
|
|
108
|
+
* One clip of a search answer in lead order (server 0.7.173). The order: `on_subject` (`on`: about the words, `loose`: it
|
|
109
|
+
* mentions them, `off`: the popular tail), then freshness (within a day, a week, 30 days, a year, older, undated last),
|
|
110
|
+
* then a Minds member's clip before any other, then the newer. Play the first entry as the lead. `section` and `index`
|
|
111
|
+
* point at the item in the answer (`items` on a visitor's page); `ref` is the Minds post id, the open-network post's
|
|
112
|
+
* `sourceUrl` or the media item's `url`. A client merging two answers' entries sorts by the same rules.
|
|
113
|
+
*/
|
|
114
|
+
export interface SearchVideoLeadEntry {
|
|
115
|
+
section: 'top_posts' | 'latest_posts' | 'open_network' | 'media' | 'items';
|
|
116
|
+
index: number;
|
|
117
|
+
ref: string;
|
|
118
|
+
source: SearchVideoLeadSource;
|
|
119
|
+
on_subject: 'on' | 'loose' | 'off';
|
|
120
|
+
/** ISO 8601, when the clip is dated. */
|
|
121
|
+
published_at: string | null;
|
|
65
122
|
}
|
|
66
123
|
/** The kinds of a search's media items, in the order the server lists them. */
|
|
67
124
|
export declare const SEARCH_MEDIA_KINDS: readonly ["about", "video", "article", "image", "audio"];
|
|
68
125
|
export type SearchMediaKind = (typeof SEARCH_MEDIA_KINDS)[number];
|
|
69
|
-
/**
|
|
70
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Where a media item was found. `eventregistry` (0.7.133): a news article from the thousands the server's news lanes
|
|
128
|
+
* read each day (Event Registry and outlet feeds), matched by its headline: show its headline, `description` (a short
|
|
129
|
+
* excerpt), `publisher` (the outlet), `published_at`, `thumbnail` and link to `url`, never more of the article.
|
|
130
|
+
* `youtube` (0.7.181): a video the YouTube Data API found for the words; it always has YouTube's player as `embed`: play
|
|
131
|
+
* it in place by YouTube's player rules (no autoplay with sound, nothing drawn over it, YouTube named as the source)
|
|
132
|
+
* rather than opening `url`.
|
|
133
|
+
*/
|
|
134
|
+
export type SearchMediaSource = 'brave' | 'wikipedia' | 'peertube' | 'openverse' | 'eventregistry' | 'youtube';
|
|
71
135
|
/**
|
|
72
136
|
* How a video may play in place: YouTube's own player for `id` (use youtube-nocookie.com and follow its player rules:
|
|
73
137
|
* at least 200x200, nothing drawn over it, YouTube shown as the source), or a PeerTube instance's own embed page.
|
|
@@ -106,8 +170,20 @@ export interface SearchMediaItem {
|
|
|
106
170
|
* Visitors and members on safe defaults are never served such an item.
|
|
107
171
|
*/
|
|
108
172
|
sensitive?: true;
|
|
173
|
+
/**
|
|
174
|
+
* The same PeerTube video as a native Fediverse post (0.7.155, `SocialPost.software: 'peertube'`): show the post, which
|
|
175
|
+
* plays in place from its channel, and never open `url`. Present only on a PeerTube video the server could read off its
|
|
176
|
+
* own instance; the item's other fields stay for an app that does not read it.
|
|
177
|
+
*/
|
|
178
|
+
post?: SocialPost;
|
|
109
179
|
}
|
|
110
|
-
|
|
180
|
+
/**
|
|
181
|
+
* The reads behind the media section. `news_index` (0.7.133): today's articles about the words from those the server's
|
|
182
|
+
* news lanes already read; `eventregistry`: a live per-query Event Registry read, where the server has one; `youtube`
|
|
183
|
+
* (0.7.181): YouTube's videos for the words, asked only when the web's own videos about them are thin or the words name
|
|
184
|
+
* sport or music (`skipped` otherwise), within the server's daily YouTube quota (`budget` past it).
|
|
185
|
+
*/
|
|
186
|
+
export type SearchMediaProvider = 'brave_web' | 'brave_images' | 'wikipedia' | 'peertube' | 'openverse_images' | 'openverse_audio' | 'news_index' | 'eventregistry' | 'youtube';
|
|
111
187
|
/**
|
|
112
188
|
* What each provider did for this answer; `timeout`: it is still reading, ask again shortly for more; `budget`: a
|
|
113
189
|
* spending limit held it back (the day's Brave calls, or this caller's own calls a day or fresh answers an hour, past
|
|
@@ -226,6 +302,14 @@ export interface SearchRelated {
|
|
|
226
302
|
slug: string;
|
|
227
303
|
count: number;
|
|
228
304
|
}>;
|
|
305
|
+
/**
|
|
306
|
+
* Searches related to the query's subject, best first, for related-topic chips ("hockey": NHL, Stanley Cup, ice hockey):
|
|
307
|
+
* from the server's understanding of the query (server 0.7.137), so a query whose posts carry no topic still has them.
|
|
308
|
+
* Absent when the server has none for the query, and from older servers.
|
|
309
|
+
*/
|
|
310
|
+
queries?: Array<{
|
|
311
|
+
query: string;
|
|
312
|
+
}>;
|
|
229
313
|
}
|
|
230
314
|
/** One blended search answer. Only answered sections are present; an answered section may be empty. */
|
|
231
315
|
export interface SearchAnswer {
|
|
@@ -285,6 +369,12 @@ export interface SearchAnswer {
|
|
|
285
369
|
few_results: boolean;
|
|
286
370
|
/** The search ladder's account of the answer (server 0.7.79): present when the server ran the ladder. */
|
|
287
371
|
ladder?: SearchLadder;
|
|
372
|
+
/**
|
|
373
|
+
* Every clip the answer holds (Top's and Latest's Minds clips, the open networks', the media section's videos) in the
|
|
374
|
+
* order to lead and play them (server 0.7.173, `SearchVideoLeadEntry`): the most about the words first, then the
|
|
375
|
+
* freshest, a Minds member's clip winning a tie. Absent with no clip, from older servers, or when turned off.
|
|
376
|
+
*/
|
|
377
|
+
video_lead?: SearchVideoLeadEntry[];
|
|
288
378
|
}
|
|
289
379
|
export interface SearchResponse {
|
|
290
380
|
data: SearchAnswer;
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import type { HttpClient } from '../client.js';
|
|
2
2
|
import type { ChangePasswordInput, ConfirmationCodePurpose, ConfirmationCodeSent, DeletionStatus, DisableAccountInput, LoginHistoryEntry, PaginatedResponse, RequestEmailChangeInput, RevokeOtherSessionsInput, RevokeOtherSessionsResult, Session, SingleResponse, SuccessResponse, UpdateAppearanceInput, UpdateContentPreferencesInput, UpdateNotificationChannelsInput, UpdatePrivacyInput, UserPreferences } from '../types.js';
|
|
3
|
+
import type { MemberExperience, UpdateMemberExperienceInput } from './member-experience.js';
|
|
3
4
|
export declare class SettingsResource {
|
|
4
5
|
private client;
|
|
5
6
|
constructor(client: HttpClient);
|
|
6
7
|
/** Get user preferences */
|
|
7
8
|
getPreferences(): Promise<SingleResponse<UserPreferences>>;
|
|
9
|
+
/** Read your explicit goals and category starting point in this app; requires your own project-bound key. */
|
|
10
|
+
getExperience(): Promise<SingleResponse<MemberExperience>>;
|
|
11
|
+
/** Save explicit choices at the current version. This changes the saved starting point, not whole-feed ranking. */
|
|
12
|
+
updateExperience(input: UpdateMemberExperienceInput): Promise<SingleResponse<MemberExperience>>;
|
|
13
|
+
/** Restore the previous choices if this version is still current; a stale Undo is refused. */
|
|
14
|
+
undoExperience(input: {
|
|
15
|
+
version: number;
|
|
16
|
+
}): Promise<SingleResponse<MemberExperience>>;
|
|
8
17
|
/**
|
|
9
18
|
* Download a portable ZIP containing the caller's profile, posts, social
|
|
10
19
|
* graph, authored messages, account activity, preferences, and fetchable
|
|
@@ -50,8 +59,9 @@ export declare class SettingsResource {
|
|
|
50
59
|
* Email a six-digit confirmation code to the account's current address.
|
|
51
60
|
* Only for accounts with no password (`profiles.me().has_password === false`);
|
|
52
61
|
* a password account answers `password_required`. Send the code as
|
|
53
|
-
* `email_code` to `requestEmailChange`,
|
|
54
|
-
* `auth.*TwoFactor` methods
|
|
62
|
+
* `email_code` to `requestEmailChange`, as `emailCode` to the
|
|
63
|
+
* `auth.*TwoFactor` methods, or (purpose `nostr_key`) as `emailCode` to
|
|
64
|
+
* `protocols.exportNostrKey` and `protocols.deleteManagedNostrCopy`.
|
|
55
65
|
*/
|
|
56
66
|
requestConfirmationCode(purpose: ConfirmationCodePurpose): Promise<SingleResponse<ConfirmationCodeSent>>;
|
|
57
67
|
/**
|
|
@@ -8,6 +8,18 @@ export class SettingsResource {
|
|
|
8
8
|
getPreferences() {
|
|
9
9
|
return this.client.get('/settings/preferences');
|
|
10
10
|
}
|
|
11
|
+
/** Read your explicit goals and category starting point in this app; requires your own project-bound key. */
|
|
12
|
+
getExperience() {
|
|
13
|
+
return this.client.get('/settings/preferences/experience');
|
|
14
|
+
}
|
|
15
|
+
/** Save explicit choices at the current version. This changes the saved starting point, not whole-feed ranking. */
|
|
16
|
+
updateExperience(input) {
|
|
17
|
+
return this.client.patch('/settings/preferences/experience', input);
|
|
18
|
+
}
|
|
19
|
+
/** Restore the previous choices if this version is still current; a stale Undo is refused. */
|
|
20
|
+
undoExperience(input) {
|
|
21
|
+
return this.client.post('/settings/preferences/experience/undo', input);
|
|
22
|
+
}
|
|
11
23
|
/**
|
|
12
24
|
* Download a portable ZIP containing the caller's profile, posts, social
|
|
13
25
|
* graph, authored messages, account activity, preferences, and fetchable
|
|
@@ -87,8 +99,9 @@ export class SettingsResource {
|
|
|
87
99
|
* Email a six-digit confirmation code to the account's current address.
|
|
88
100
|
* Only for accounts with no password (`profiles.me().has_password === false`);
|
|
89
101
|
* a password account answers `password_required`. Send the code as
|
|
90
|
-
* `email_code` to `requestEmailChange`,
|
|
91
|
-
* `auth.*TwoFactor` methods
|
|
102
|
+
* `email_code` to `requestEmailChange`, as `emailCode` to the
|
|
103
|
+
* `auth.*TwoFactor` methods, or (purpose `nostr_key`) as `emailCode` to
|
|
104
|
+
* `protocols.exportNostrKey` and `protocols.deleteManagedNostrCopy`.
|
|
92
105
|
*/
|
|
93
106
|
requestConfirmationCode(purpose) {
|
|
94
107
|
return this.client.post('/settings/confirmation-code', { purpose });
|
package/dist/types.d.ts
CHANGED
|
@@ -184,6 +184,19 @@ export interface UserSummary {
|
|
|
184
184
|
* servers older than this field and from reads that do not label accounts.
|
|
185
185
|
*/
|
|
186
186
|
is_nsfw?: boolean;
|
|
187
|
+
/**
|
|
188
|
+
* An account the operator vouches for: draw the verified badge. Carried by a
|
|
189
|
+
* post's author. An app that draws one mark next to a name draws verified
|
|
190
|
+
* before `founder` before the plan mark. Absent from servers older than this
|
|
191
|
+
* field and from reads that do not mark accounts.
|
|
192
|
+
*/
|
|
193
|
+
verified?: boolean;
|
|
194
|
+
/** The account's Plus plan is live. Absent from reads that do not mark accounts. */
|
|
195
|
+
plus?: boolean;
|
|
196
|
+
/** The account's Pro plan is live. Absent from reads that do not mark accounts. */
|
|
197
|
+
pro?: boolean;
|
|
198
|
+
/** A founding member. Absent from reads that do not mark accounts. */
|
|
199
|
+
founder?: boolean;
|
|
187
200
|
}
|
|
188
201
|
export interface User extends UserSummary {
|
|
189
202
|
bio: string | null;
|
|
@@ -1378,6 +1391,13 @@ export interface AgentChatResult {
|
|
|
1378
1391
|
export interface AgentConversation {
|
|
1379
1392
|
id: string;
|
|
1380
1393
|
type: string;
|
|
1394
|
+
/**
|
|
1395
|
+
* The conversation's own name (a group's, the Asks thread's), else, for a one-to-one chat, its title: the first 60
|
|
1396
|
+
* characters of the first message the agent did not send, looked for in the chat's first 20 messages, made by the
|
|
1397
|
+
* server with no model call and gone when that message is. Null when no such message is among the first 20 (before
|
|
1398
|
+
* anyone but the agent has written in it, for one); absent from a server that predates it.
|
|
1399
|
+
*/
|
|
1400
|
+
name?: string | null;
|
|
1381
1401
|
members: {
|
|
1382
1402
|
id: string;
|
|
1383
1403
|
name: string;
|
|
@@ -1404,6 +1424,11 @@ export interface AgentConversationMessage {
|
|
|
1404
1424
|
} | null;
|
|
1405
1425
|
created_at: string;
|
|
1406
1426
|
}
|
|
1427
|
+
/** A new chat with the caller's own personal agent, as `agents.createConversation` returns it. */
|
|
1428
|
+
export interface CreatedAgentConversation extends AgentConversation {
|
|
1429
|
+
/** False when the member's empty chat with the agent in this app was handed back instead of a second blank one. */
|
|
1430
|
+
created: boolean;
|
|
1431
|
+
}
|
|
1407
1432
|
export interface CreateTagInput {
|
|
1408
1433
|
name: string;
|
|
1409
1434
|
description?: string;
|
|
@@ -1760,7 +1785,7 @@ export interface RequestEmailChangeInput {
|
|
|
1760
1785
|
email_code?: string;
|
|
1761
1786
|
}
|
|
1762
1787
|
/** What a confirmation code is for. A code for one purpose never confirms another. */
|
|
1763
|
-
export type ConfirmationCodePurpose = 'email_change' | 'two_factor';
|
|
1788
|
+
export type ConfirmationCodePurpose = 'email_change' | 'two_factor' | 'nostr_key';
|
|
1764
1789
|
export interface ConfirmationCodeSent {
|
|
1765
1790
|
success: true;
|
|
1766
1791
|
purpose: ConfirmationCodePurpose;
|