@nurama/sdk 1.4.2 → 1.4.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.
- package/dist/NuramaClient.d.ts +3 -0
- package/dist/NuramaClient.d.ts.map +1 -1
- package/dist/NuramaClient.js +2 -0
- package/dist/NuramaClient.js.map +1 -1
- package/dist/browser/nurama-bot-sdk.js +313 -15
- package/dist/browser/nurama-bot-sdk.min.js +1 -1
- package/dist/browser/nurama-sdk.js +313 -15
- package/dist/browser/nurama-sdk.min.js +1 -1
- package/dist/routes/auth.d.ts +65 -2
- package/dist/routes/auth.d.ts.map +1 -1
- package/dist/routes/auth.js +120 -2
- package/dist/routes/auth.js.map +1 -1
- package/dist/routes/chat.d.ts +44 -1
- package/dist/routes/chat.d.ts.map +1 -1
- package/dist/routes/chat.js +52 -0
- package/dist/routes/chat.js.map +1 -1
- package/dist/routes/project.d.ts +18 -1
- package/dist/routes/project.d.ts.map +1 -1
- package/dist/routes/project.js +38 -0
- package/dist/routes/project.js.map +1 -1
- package/dist/routes/task.d.ts +9 -7
- package/dist/routes/task.d.ts.map +1 -1
- package/dist/routes/task.js +7 -11
- package/dist/routes/task.js.map +1 -1
- package/dist/routes/userFeed.d.ts +59 -0
- package/dist/routes/userFeed.d.ts.map +1 -0
- package/dist/routes/userFeed.js +99 -0
- package/dist/routes/userFeed.js.map +1 -0
- package/dist/version.js +4 -4
- package/package.json +2 -2
- package/src/NuramaClient.ts +4 -0
- package/src/routes/auth.ts +142 -2
- package/src/routes/chat.ts +67 -0
- package/src/routes/project.ts +39 -0
- package/src/routes/task.ts +11 -11
- package/src/routes/userFeed.ts +113 -0
- package/src/version.ts +4 -4
package/src/routes/auth.ts
CHANGED
|
@@ -9,6 +9,12 @@ import {
|
|
|
9
9
|
type LinkedAuthProvider,
|
|
10
10
|
type OAuthExchangeRequest,
|
|
11
11
|
type OAuthExchangeResponse,
|
|
12
|
+
type Passkey,
|
|
13
|
+
type PasskeyRegistrationProof,
|
|
14
|
+
type PasskeyCredentialOptions,
|
|
15
|
+
type PasskeyCredentialResponse,
|
|
16
|
+
type PasskeyDesktopLoginRequest,
|
|
17
|
+
type PasskeyDesktopLoginResponse,
|
|
12
18
|
} from '@nurama/types';
|
|
13
19
|
|
|
14
20
|
// Define specific types for auth requests
|
|
@@ -468,6 +474,134 @@ export default function createAuthMethods(client: NuramaClient) {
|
|
|
468
474
|
return result;
|
|
469
475
|
},
|
|
470
476
|
|
|
477
|
+
/**
|
|
478
|
+
* Gets the options for the browser's passkey sign-in prompt. Pass them to the WebAuthn library
|
|
479
|
+
* (`startAuthentication` in @simplewebauthn/browser), then send its result to `loginWithPasskey`.
|
|
480
|
+
* @param origin - The web origin to sign in for, from a native app (which has no browser `Origin`); pass the
|
|
481
|
+
* same one to `loginWithPasskey`. Browsers send their own and ignore this.
|
|
482
|
+
* @returns Promise resolving to WebAuthn request options.
|
|
483
|
+
*/
|
|
484
|
+
async getPasskeyLoginOptions(origin?: string): Promise<PasskeyCredentialOptions> {
|
|
485
|
+
return client._request<PasskeyCredentialOptions>({
|
|
486
|
+
endpoint: "/v1/auth/passkeys/login-options",
|
|
487
|
+
method: "POST",
|
|
488
|
+
sendJWT: false,
|
|
489
|
+
...(origin ? { customHeaders: { Origin: origin } } : {}),
|
|
490
|
+
});
|
|
491
|
+
},
|
|
492
|
+
|
|
493
|
+
/**
|
|
494
|
+
* Signs in with the browser's response to the passkey prompt and stores the tokens.
|
|
495
|
+
* A passkey stands in for two-factor, so this never returns an MFA challenge.
|
|
496
|
+
* @param credential - The WebAuthn library's AuthenticationResponseJSON.
|
|
497
|
+
* @param origin - From a native app: the origin passed to `getPasskeyLoginOptions`.
|
|
498
|
+
* @returns Promise resolving to the user and tokens.
|
|
499
|
+
*/
|
|
500
|
+
async loginWithPasskey(credential: PasskeyCredentialResponse, origin?: string): Promise<LoginRegisterResponse> {
|
|
501
|
+
const result: LoginRegisterResponse = await client._request({
|
|
502
|
+
endpoint: "/v1/auth/passkeys/login",
|
|
503
|
+
method: "POST",
|
|
504
|
+
body: { credential },
|
|
505
|
+
sendJWT: false,
|
|
506
|
+
...(origin ? { customHeaders: { Origin: origin } } : {}),
|
|
507
|
+
});
|
|
508
|
+
(client as any)._setTokens(
|
|
509
|
+
result.tokens.access.token,
|
|
510
|
+
result.tokens.refresh.token,
|
|
511
|
+
result.tokens.access.expires,
|
|
512
|
+
result.tokens.refresh.expires
|
|
513
|
+
);
|
|
514
|
+
return result;
|
|
515
|
+
},
|
|
516
|
+
|
|
517
|
+
/**
|
|
518
|
+
* Signs the desktop app in with a passkey, from the browser. Stores nothing: the tokens wait behind the
|
|
519
|
+
* returned one-time code, which the desktop app redeems with `exchangeOAuthCode(code, { codeVerifier })`.
|
|
520
|
+
* @param credential - The WebAuthn library's AuthenticationResponseJSON.
|
|
521
|
+
* @param handoff - The `state` and PKCE `codeChallenge` the desktop app made.
|
|
522
|
+
* @returns Promise resolving to the one-time code.
|
|
523
|
+
*/
|
|
524
|
+
async loginDesktopWithPasskey(
|
|
525
|
+
credential: PasskeyCredentialResponse,
|
|
526
|
+
handoff: Omit<PasskeyDesktopLoginRequest, "credential">
|
|
527
|
+
): Promise<PasskeyDesktopLoginResponse> {
|
|
528
|
+
return client._request<PasskeyDesktopLoginResponse>({
|
|
529
|
+
endpoint: "/v1/auth/passkeys/desktop-login",
|
|
530
|
+
method: "POST",
|
|
531
|
+
body: { credential, ...handoff } satisfies PasskeyDesktopLoginRequest,
|
|
532
|
+
sendJWT: false,
|
|
533
|
+
});
|
|
534
|
+
},
|
|
535
|
+
|
|
536
|
+
/**
|
|
537
|
+
* Gets the options for the browser's "create a passkey" prompt, after confirming who is asking.
|
|
538
|
+
* @param proof - The password when the account has one, and a two-factor code when two-factor is on.
|
|
539
|
+
* @returns Promise resolving to WebAuthn creation options.
|
|
540
|
+
*/
|
|
541
|
+
async getPasskeyRegistrationOptions(proof: PasskeyRegistrationProof = {}): Promise<PasskeyCredentialOptions> {
|
|
542
|
+
return client._request<PasskeyCredentialOptions>({
|
|
543
|
+
endpoint: "/v1/auth/passkeys/registration-options",
|
|
544
|
+
method: "POST",
|
|
545
|
+
body: proof,
|
|
546
|
+
sendJWT: true,
|
|
547
|
+
});
|
|
548
|
+
},
|
|
549
|
+
|
|
550
|
+
/**
|
|
551
|
+
* Saves the passkey the browser created.
|
|
552
|
+
* @param credential - The WebAuthn library's RegistrationResponseJSON.
|
|
553
|
+
* @param name - Optional name to tell it apart, e.g. "MacBook".
|
|
554
|
+
* @returns Promise resolving to the saved passkey.
|
|
555
|
+
*/
|
|
556
|
+
async registerPasskey(credential: PasskeyCredentialResponse, name?: string): Promise<Passkey> {
|
|
557
|
+
return client._request<Passkey>({
|
|
558
|
+
endpoint: "/v1/auth/passkeys",
|
|
559
|
+
method: "POST",
|
|
560
|
+
body: { credential, ...(name ? { name } : {}) },
|
|
561
|
+
sendJWT: true,
|
|
562
|
+
});
|
|
563
|
+
},
|
|
564
|
+
|
|
565
|
+
/**
|
|
566
|
+
* Lists the authenticated user's passkeys, oldest first.
|
|
567
|
+
* @returns Promise resolving to the user's passkeys.
|
|
568
|
+
*/
|
|
569
|
+
async listPasskeys(): Promise<Passkey[]> {
|
|
570
|
+
return client._request<Passkey[]>({
|
|
571
|
+
endpoint: "/v1/auth/passkeys",
|
|
572
|
+
method: "GET",
|
|
573
|
+
sendJWT: true,
|
|
574
|
+
});
|
|
575
|
+
},
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Renames one of the authenticated user's passkeys.
|
|
579
|
+
* @param passkeyId - The passkey's id.
|
|
580
|
+
* @param name - The new name.
|
|
581
|
+
* @returns Promise resolving to the renamed passkey.
|
|
582
|
+
*/
|
|
583
|
+
async renamePasskey(passkeyId: string, name: string): Promise<Passkey> {
|
|
584
|
+
return client._request<Passkey>({
|
|
585
|
+
endpoint: `/v1/auth/passkeys/${passkeyId}`,
|
|
586
|
+
method: "PATCH",
|
|
587
|
+
body: { name },
|
|
588
|
+
sendJWT: true,
|
|
589
|
+
});
|
|
590
|
+
},
|
|
591
|
+
|
|
592
|
+
/**
|
|
593
|
+
* Removes one of the authenticated user's passkeys.
|
|
594
|
+
* @param passkeyId - The passkey's id.
|
|
595
|
+
* @returns Promise resolving when complete.
|
|
596
|
+
*/
|
|
597
|
+
async deletePasskey(passkeyId: string): Promise<void> {
|
|
598
|
+
await client._request<void>({
|
|
599
|
+
endpoint: `/v1/auth/passkeys/${passkeyId}`,
|
|
600
|
+
method: "DELETE",
|
|
601
|
+
sendJWT: true,
|
|
602
|
+
});
|
|
603
|
+
},
|
|
604
|
+
|
|
471
605
|
/**
|
|
472
606
|
* Unlinks an OAuth provider from the authenticated user's account.
|
|
473
607
|
* User must have at least one authentication method remaining (password or another OAuth provider).
|
|
@@ -553,11 +687,17 @@ export default function createAuthMethods(client: NuramaClient) {
|
|
|
553
687
|
});
|
|
554
688
|
},
|
|
555
689
|
|
|
556
|
-
|
|
690
|
+
/**
|
|
691
|
+
* Exchanges a one-time sign-in code for tokens and stores them.
|
|
692
|
+
* @param code - The code from the sign-in redirect.
|
|
693
|
+
* @param options.codeVerifier - The PKCE verifier, for a code made with a challenge.
|
|
694
|
+
* @returns Promise resolving to the user and tokens, or a two-factor challenge.
|
|
695
|
+
*/
|
|
696
|
+
async exchangeOAuthCode(code: string, { codeVerifier }: { codeVerifier?: string } = {}): Promise<OAuthExchangeResponse> {
|
|
557
697
|
const result: OAuthExchangeResponse = await client._request({
|
|
558
698
|
endpoint: "/v1/auth/oauth/exchange",
|
|
559
699
|
method: "POST",
|
|
560
|
-
body: { code } satisfies OAuthExchangeRequest,
|
|
700
|
+
body: { code, ...(codeVerifier ? { codeVerifier } : {}) } satisfies OAuthExchangeRequest,
|
|
561
701
|
sendJWT: false, // No authentication needed - the code is the proof
|
|
562
702
|
});
|
|
563
703
|
|
package/src/routes/chat.ts
CHANGED
|
@@ -9,10 +9,24 @@ import {
|
|
|
9
9
|
type Membership,
|
|
10
10
|
type PaginatedResult,
|
|
11
11
|
type CursorPaginatedResult,
|
|
12
|
+
type ReadState,
|
|
12
13
|
} from '@nurama/types'; // Import pagination types
|
|
13
14
|
|
|
14
15
|
// --- Common Interfaces ---
|
|
15
16
|
|
|
17
|
+
/** Unread state for one member chat, as returned by `getMemberChatReadStates`. */
|
|
18
|
+
export interface MemberChatReadState {
|
|
19
|
+
chatId: string;
|
|
20
|
+
/** Epoch ms of the newest message, or null when the chat is empty. */
|
|
21
|
+
lastMessageAt: number | null;
|
|
22
|
+
/** Epoch ms you last read to, or null when you never have. */
|
|
23
|
+
lastReadAt: number | null;
|
|
24
|
+
/** Messages newer than your position, excluding your own. */
|
|
25
|
+
unreadCount: number;
|
|
26
|
+
/** `unreadCount > 0`. Null `lastReadAt` does not imply false. */
|
|
27
|
+
hasUnread: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
16
30
|
// Base interface for pagination options
|
|
17
31
|
export interface PaginationParams {
|
|
18
32
|
limit?: number;
|
|
@@ -617,6 +631,59 @@ export default function createChatMethods(client: NuramaClient) {
|
|
|
617
631
|
});
|
|
618
632
|
},
|
|
619
633
|
|
|
634
|
+
/**
|
|
635
|
+
* Gets unread state for every member chat you belong to — one row per chat,
|
|
636
|
+
* carrying the chat's `lastMessageAt`, your `lastReadAt` and a `hasUnread`
|
|
637
|
+
* flag. Compares timestamps rather than counting, so it costs the same
|
|
638
|
+
* whether you have three chats or three hundred; for a count, read the
|
|
639
|
+
* single-chat endpoint for the chat on screen.
|
|
640
|
+
* @returns {Promise<{ results: MemberChatReadState[] }>} Unread state per member chat.
|
|
641
|
+
*/
|
|
642
|
+
async getMemberChatReadStates(): Promise<{ results: MemberChatReadState[] }> {
|
|
643
|
+
return client._request<{ results: MemberChatReadState[] }>({
|
|
644
|
+
method: 'GET',
|
|
645
|
+
endpoint: `/v1/chats/member/read-state`,
|
|
646
|
+
sendJWT: true,
|
|
647
|
+
});
|
|
648
|
+
},
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* Gets where you had read up to in a member chat, and how many messages have
|
|
652
|
+
* arrived since. `lastReadAt` is null if you have never recorded a position,
|
|
653
|
+
* and `unreadCount` is 0 then. Your own messages never count.
|
|
654
|
+
* @param {string} chatId - The ID of the member chat.
|
|
655
|
+
* @returns {Promise<ReadState>} Your reading position in that chat.
|
|
656
|
+
* @throws {Error} 'chatId is required.' when `chatId` is falsy.
|
|
657
|
+
*/
|
|
658
|
+
async getMemberChatReadState(chatId: string): Promise<ReadState> {
|
|
659
|
+
if (!chatId) throw new Error('chatId is required.');
|
|
660
|
+
return client._request<ReadState>({
|
|
661
|
+
method: 'GET',
|
|
662
|
+
endpoint: `/v1/chats/member/${chatId}/read-state`,
|
|
663
|
+
sendJWT: true,
|
|
664
|
+
});
|
|
665
|
+
},
|
|
666
|
+
|
|
667
|
+
/**
|
|
668
|
+
* Marks a member chat as caught up. Pass `lastReadAt` (epoch ms) to catch up
|
|
669
|
+
* to the newest message you had loaded; omit it to catch up to now. The
|
|
670
|
+
* marker only moves forward and never past the present, so a stale value is
|
|
671
|
+
* a no-op rather than an error.
|
|
672
|
+
* @param {string} chatId - The ID of the member chat.
|
|
673
|
+
* @param {number} [lastReadAt] - Epoch ms of the newest message you had loaded.
|
|
674
|
+
* @returns {Promise<ReadState>} Your updated reading position.
|
|
675
|
+
* @throws {Error} 'chatId is required.' when `chatId` is falsy.
|
|
676
|
+
*/
|
|
677
|
+
async markMemberChatCaughtUp(chatId: string, lastReadAt?: number): Promise<ReadState> {
|
|
678
|
+
if (!chatId) throw new Error('chatId is required.');
|
|
679
|
+
return client._request<ReadState>({
|
|
680
|
+
method: 'POST',
|
|
681
|
+
endpoint: `/v1/chats/member/${chatId}/read-state`,
|
|
682
|
+
body: lastReadAt === undefined ? {} : { lastReadAt },
|
|
683
|
+
sendJWT: true,
|
|
684
|
+
});
|
|
685
|
+
},
|
|
686
|
+
|
|
620
687
|
/**
|
|
621
688
|
* Creates an icon asset for a member chat and returns signed upload URLs for it.
|
|
622
689
|
* Any existing icon is marked for deletion. The caller must be a member of the chat;
|
package/src/routes/project.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
type FeedVisibility,
|
|
20
20
|
type ListFeedEventsParams,
|
|
21
21
|
type CursorPaginatedFeedEvents,
|
|
22
|
+
type ReadState,
|
|
22
23
|
} from '@nurama/types';
|
|
23
24
|
|
|
24
25
|
// Combine pagination metadata with a results array
|
|
@@ -597,6 +598,44 @@ export default function createProjectMethods(client: NuramaClient) {
|
|
|
597
598
|
});
|
|
598
599
|
},
|
|
599
600
|
|
|
601
|
+
/**
|
|
602
|
+
* Gets where you had read up to in a project feed, and how many cards have
|
|
603
|
+
* moved since. `lastReadAt` is null if you have never recorded a position,
|
|
604
|
+
* and `unreadCount` is 0 then. Cards you are the actor on never count.
|
|
605
|
+
* @param {string} projectId - The ID of the project.
|
|
606
|
+
* @param {'creator' | 'reviewer'} visibility - Which feed to read.
|
|
607
|
+
* @returns {Promise<ReadState>} Your reading position in that feed.
|
|
608
|
+
*/
|
|
609
|
+
async getFeedReadState(projectId: string, visibility: FeedVisibility): Promise<ReadState> {
|
|
610
|
+
if (!projectId) throw new Error('projectId is required.');
|
|
611
|
+
if (!visibility) throw new Error('visibility is required (creator or reviewer).');
|
|
612
|
+
|
|
613
|
+
return client._request<ReadState>({
|
|
614
|
+
method: 'GET',
|
|
615
|
+
endpoint: `/v1/projects/${projectId}/feed-events/${visibility}/read-state`,
|
|
616
|
+
sendJWT: true,
|
|
617
|
+
});
|
|
618
|
+
},
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Marks a project feed as caught up. Pass `lastReadAt` (epoch ms) to catch
|
|
622
|
+
* up to the newest card you had loaded; omit it to catch up to now. The
|
|
623
|
+
* marker only moves forward and never past the present, so a stale value is
|
|
624
|
+
* a no-op rather than an error.
|
|
625
|
+
* @returns {Promise<ReadState>} Your updated reading position.
|
|
626
|
+
*/
|
|
627
|
+
async markFeedCaughtUp(projectId: string, visibility: FeedVisibility, lastReadAt?: number): Promise<ReadState> {
|
|
628
|
+
if (!projectId) throw new Error('projectId is required.');
|
|
629
|
+
if (!visibility) throw new Error('visibility is required (creator or reviewer).');
|
|
630
|
+
|
|
631
|
+
return client._request<ReadState>({
|
|
632
|
+
method: 'POST',
|
|
633
|
+
endpoint: `/v1/projects/${projectId}/feed-events/${visibility}/read-state`,
|
|
634
|
+
body: lastReadAt === undefined ? {} : { lastReadAt },
|
|
635
|
+
sendJWT: true,
|
|
636
|
+
});
|
|
637
|
+
},
|
|
638
|
+
|
|
600
639
|
// --- Folder Listing ---
|
|
601
640
|
|
|
602
641
|
/**
|
package/src/routes/task.ts
CHANGED
|
@@ -28,6 +28,8 @@ export interface GetTasksBaseParams extends SortParams {
|
|
|
28
28
|
relatedToId?: string;
|
|
29
29
|
visibility?: TaskVisibility;
|
|
30
30
|
acknowledged?: boolean;
|
|
31
|
+
/** `'chatMessage'` returns only mention-tasks; without it, board tasks assigned to you come too. */
|
|
32
|
+
originType?: 'chatMessage';
|
|
31
33
|
limit?: number;
|
|
32
34
|
}
|
|
33
35
|
|
|
@@ -223,31 +225,29 @@ export default function createTaskMethods(client: NuramaClient) {
|
|
|
223
225
|
},
|
|
224
226
|
|
|
225
227
|
/**
|
|
226
|
-
* Retrieves the count of unacknowledged tasks for the current user within a specific project
|
|
227
|
-
* Requires authentication.
|
|
228
|
-
* @param {string} projectId - The ID of the project.
|
|
228
|
+
* Retrieves the count of unacknowledged tasks for the current user within a specific project,
|
|
229
|
+
* or across every project when none is given. Requires authentication.
|
|
230
|
+
* @param {string} [projectId] - The ID of the project; omit for every project.
|
|
229
231
|
* @returns {Promise<UnacknowledgedTaskCountResponse>} An object containing total, creator, and reviewer unacknowledged task counts.
|
|
230
232
|
*/
|
|
231
|
-
async getUnacknowledgedTaskCount(projectId
|
|
232
|
-
if (!projectId) throw new Error('projectId is required.');
|
|
233
|
+
async getUnacknowledgedTaskCount(projectId?: string): Promise<UnacknowledgedTaskCountResponse> {
|
|
233
234
|
return client._request<UnacknowledgedTaskCountResponse>({
|
|
234
235
|
method: 'GET',
|
|
235
|
-
endpoint: `/v1/tasks/unacknowledged/${projectId}
|
|
236
|
+
endpoint: projectId ? `/v1/tasks/unacknowledged/${projectId}` : '/v1/tasks/unacknowledged',
|
|
236
237
|
sendJWT: true,
|
|
237
238
|
});
|
|
238
239
|
},
|
|
239
240
|
|
|
240
241
|
/**
|
|
241
242
|
* Acknowledge every unacknowledged mention-task the current user has in a
|
|
242
|
-
* project. Idempotent server-side.
|
|
243
|
-
* @param {string} projectId - The ID of the project.
|
|
243
|
+
* project, or in every project when none is given. Idempotent server-side.
|
|
244
|
+
* @param {string} [projectId] - The ID of the project; omit for every project.
|
|
244
245
|
* @returns {Promise<AcknowledgeAllTasksResponse>} The number acknowledged and the remaining unacknowledged count.
|
|
245
246
|
*/
|
|
246
|
-
async acknowledgeAllTasks(projectId
|
|
247
|
-
if (!projectId) throw new Error('projectId is required.');
|
|
247
|
+
async acknowledgeAllTasks(projectId?: string): Promise<AcknowledgeAllTasksResponse> {
|
|
248
248
|
return client._request<AcknowledgeAllTasksResponse>({
|
|
249
249
|
method: 'PUT',
|
|
250
|
-
endpoint: `/v1/tasks/acknowledge-all/${projectId}
|
|
250
|
+
endpoint: projectId ? `/v1/tasks/acknowledge-all/${projectId}` : '/v1/tasks/acknowledge-all',
|
|
251
251
|
sendJWT: true,
|
|
252
252
|
});
|
|
253
253
|
},
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import NuramaClient from '../NuramaClient.js';
|
|
2
|
+
import {
|
|
3
|
+
type ObjectId,
|
|
4
|
+
type ReadState,
|
|
5
|
+
type ListUserFeedParams,
|
|
6
|
+
type CursorPaginatedUserFeed,
|
|
7
|
+
type UserFeedEntry,
|
|
8
|
+
type UserFeedSummary,
|
|
9
|
+
} from '@nurama/types';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Defines the methods for the caller's own cross-project feed: project
|
|
13
|
+
* activity from every project they can read, and the things waiting on them.
|
|
14
|
+
* Every call is scoped to the signed-in user.
|
|
15
|
+
* @param {NuramaClient} client - The NuramaClient instance.
|
|
16
|
+
* @returns {object} An object containing the user feed methods.
|
|
17
|
+
*/
|
|
18
|
+
export default function createUserFeedMethods(client: NuramaClient) {
|
|
19
|
+
return {
|
|
20
|
+
/**
|
|
21
|
+
* Gets one page of your feed, most recent first. Pass `category` for only
|
|
22
|
+
* project activity or only action items; dismissed items are left out
|
|
23
|
+
* unless `states` asks for them.
|
|
24
|
+
* @returns {Promise<CursorPaginatedUserFeed>}
|
|
25
|
+
*/
|
|
26
|
+
async getFeed(params?: ListUserFeedParams): Promise<CursorPaginatedUserFeed> {
|
|
27
|
+
return client._request<CursorPaginatedUserFeed>({
|
|
28
|
+
method: 'GET',
|
|
29
|
+
endpoint: '/v1/users/feed',
|
|
30
|
+
params,
|
|
31
|
+
sendJWT: true,
|
|
32
|
+
});
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Gets every badge the app shows: open action items, project activity since
|
|
37
|
+
* you last caught up, and that activity broken down by project in
|
|
38
|
+
* `byProject` — one row per project with something new, for the badge on
|
|
39
|
+
* its icon. The two totals stop at 100.
|
|
40
|
+
*
|
|
41
|
+
* The totals and `byProject` move independently: the totals are measured
|
|
42
|
+
* against your feed-wide marker, each `byProject` row against that
|
|
43
|
+
* project's own. So catching up in the feed does not clear project badges,
|
|
44
|
+
* and reading one project does not clear the feed's own count.
|
|
45
|
+
* @returns {Promise<UserFeedSummary>}
|
|
46
|
+
*/
|
|
47
|
+
async getSummary(): Promise<UserFeedSummary> {
|
|
48
|
+
return client._request<UserFeedSummary>({
|
|
49
|
+
method: 'GET',
|
|
50
|
+
endpoint: '/v1/users/feed/summary',
|
|
51
|
+
sendJWT: true,
|
|
52
|
+
});
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Gets your reading position in your feed's project activity.
|
|
57
|
+
* @returns {Promise<ReadState>}
|
|
58
|
+
*/
|
|
59
|
+
async getReadState(): Promise<ReadState> {
|
|
60
|
+
return client._request<ReadState>({
|
|
61
|
+
method: 'GET',
|
|
62
|
+
endpoint: '/v1/users/feed/read-state',
|
|
63
|
+
sendJWT: true,
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Marks your feed's project activity as caught up. Pass `lastReadAt`
|
|
69
|
+
* (epoch ms) to catch up to the newest card you had loaded; omit it to
|
|
70
|
+
* catch up to now. The marker only moves forward.
|
|
71
|
+
* @returns {Promise<ReadState>}
|
|
72
|
+
*/
|
|
73
|
+
async markCaughtUp(lastReadAt?: number): Promise<ReadState> {
|
|
74
|
+
return client._request<ReadState>({
|
|
75
|
+
method: 'POST',
|
|
76
|
+
endpoint: '/v1/users/feed/read-state',
|
|
77
|
+
body: lastReadAt === undefined ? {} : { lastReadAt },
|
|
78
|
+
sendJWT: true,
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Clears one of your action items (`dismissed`), or brings a cleared one
|
|
84
|
+
* back (`open`).
|
|
85
|
+
* @returns {Promise<UserFeedEntry>} The updated item.
|
|
86
|
+
*/
|
|
87
|
+
async setEntryState(entryId: ObjectId, state: 'dismissed' | 'open'): Promise<UserFeedEntry> {
|
|
88
|
+
if (!entryId) throw new Error('entryId is required.');
|
|
89
|
+
|
|
90
|
+
return client._request<UserFeedEntry>({
|
|
91
|
+
method: 'PATCH',
|
|
92
|
+
endpoint: `/v1/users/feed/${entryId}`,
|
|
93
|
+
body: { state },
|
|
94
|
+
sendJWT: true,
|
|
95
|
+
});
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Clears every open action item up to `before` (epoch ms) — the newest one
|
|
100
|
+
* you had loaded — so one that arrived since stays. Omit it to clear
|
|
101
|
+
* everything open now.
|
|
102
|
+
* @returns {Promise<{ dismissed: number }>}
|
|
103
|
+
*/
|
|
104
|
+
async dismissAll(before?: number): Promise<{ dismissed: number }> {
|
|
105
|
+
return client._request<{ dismissed: number }>({
|
|
106
|
+
method: 'POST',
|
|
107
|
+
endpoint: '/v1/users/feed/dismiss',
|
|
108
|
+
body: before === undefined ? {} : { before },
|
|
109
|
+
sendJWT: true,
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -14,9 +14,9 @@ export interface SDKVersionInfo {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
export const SDK_VERSION: SDKVersionInfo = {
|
|
17
|
-
version: '1.4.
|
|
18
|
-
buildTimestamp: '2026-10-
|
|
19
|
-
buildHash: '
|
|
20
|
-
gitCommit: '
|
|
17
|
+
version: '1.4.4',
|
|
18
|
+
buildTimestamp: '2026-10-23T15:39:41.191Z',
|
|
19
|
+
buildHash: 'b0bbfd265120e5fd826237cc63c5bf7d',
|
|
20
|
+
gitCommit: '7c333f8',
|
|
21
21
|
dirty: false,
|
|
22
22
|
};
|