@sublay/js 7.7.1 → 7.9.0

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.
Files changed (30) hide show
  1. package/dist/index.d.mts +527 -36
  2. package/dist/index.d.ts +7 -1
  3. package/dist/index.js +102 -23
  4. package/dist/index.mjs +102 -23
  5. package/dist/interfaces/ChatMessage.d.ts +8 -0
  6. package/dist/interfaces/Comment.d.ts +8 -0
  7. package/dist/interfaces/Entity.d.ts +8 -0
  8. package/dist/interfaces/Push.d.ts +55 -1
  9. package/dist/interfaces/ReputationGrant.d.ts +85 -0
  10. package/dist/interfaces/Workspace.d.ts +30 -0
  11. package/dist/modules/auth/changePassword.d.ts +23 -0
  12. package/dist/modules/auth/signOut.d.ts +95 -1
  13. package/dist/modules/chat/getMessage.d.ts +5 -0
  14. package/dist/modules/chat/listMessages.d.ts +5 -1
  15. package/dist/modules/reputation/createGrant.d.ts +45 -0
  16. package/dist/modules/reputation/index.d.ts +2 -0
  17. package/dist/modules/reputation/listGrants.d.ts +45 -0
  18. package/dist/modules/workspaces/createWorkspaceInvite.d.ts +50 -1
  19. package/dist/modules/workspaces/deleteWorkspace.d.ts +2 -2
  20. package/dist/modules/workspaces/fetchManyWorkspaces.d.ts +5 -1
  21. package/dist/modules/workspaces/fetchWorkspaceAuthority.d.ts +5 -0
  22. package/dist/modules/workspaces/fetchWorkspaceMemberStanding.d.ts +5 -1
  23. package/dist/modules/workspaces/fetchWorkspaceMembers.d.ts +5 -0
  24. package/dist/modules/workspaces/leaveWorkspace.d.ts +3 -2
  25. package/dist/modules/workspaces/removeWorkspaceMember.d.ts +1 -1
  26. package/dist/modules/workspaces/transferWorkspaceOwnership.d.ts +1 -1
  27. package/dist/modules/workspaces/updateWorkspace.d.ts +1 -1
  28. package/dist/modules/workspaces/updateWorkspaceInheritFlag.d.ts +1 -1
  29. package/dist/modules/workspaces/updateWorkspaceMember.d.ts +19 -1
  30. package/package.json +1 -1
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ import * as Follows from "./modules/follows";
10
10
  import * as Connections from "./modules/connections";
11
11
  import * as AppNotifications from "./modules/app-notifications";
12
12
  import * as Reports from "./modules/reports";
13
+ import * as Reputation from "./modules/reputation";
13
14
  import * as Search from "./modules/search";
14
15
  import * as Storage from "./modules/storage";
15
16
  import * as OAuth from "./modules/oauth";
@@ -33,6 +34,7 @@ export declare class SublayClient {
33
34
  connections: BoundModule<typeof Connections>;
34
35
  appNotifications: BoundModule<typeof AppNotifications>;
35
36
  reports: BoundModule<typeof Reports>;
37
+ reputation: BoundModule<typeof Reputation>;
36
38
  search: BoundModule<typeof Search>;
37
39
  storage: BoundModule<typeof Storage>;
38
40
  oauth: BoundModule<typeof OAuth>;
@@ -56,9 +58,13 @@ export type { ClientConfig, AuthTokens } from "./core/client";
56
58
  export type { PaginatedResponse, PaginationMetadata, } from "./interfaces/IPaginatedResponse";
57
59
  export type { SpaceReputationContextParams, SpaceReputationUserParams, } from "./interfaces/SpaceReputation";
58
60
  export type { UserSearchParams } from "./interfaces/UserSearch";
61
+ export type { ReputationGrant, ReputationGrantSourceType, ReputationGrantTargetType, ReputationGrantTargetFilter, GrantSummary, } from "./interfaces/ReputationGrant";
62
+ export type { CreateGrantProps } from "./modules/reputation/createGrant";
63
+ export type { ListGrantsProps, ListGrantsResponse, } from "./modules/reputation/listGrants";
59
64
  export type { Workspace, WorkspaceMember, WorkspaceInvitation, WorkspaceCapability, WorkspaceInvitationStatus, WorkspaceAuthorityReason, WorkspaceAuthorityReasonDetail, WorkspaceRosterReason, WorkspaceRosterEntry, WorkspaceRosterResponse, WorkspaceRosterCountsResponse, WorkspaceStandingUser, WorkspaceMemberStanding, WorkspaceAuthority, RemoveWorkspaceMemberFromSubtreeResponse, SkippedWorkspace, } from "./interfaces/Workspace";
60
65
  export { PUSH_EVENT_TYPES, MUTE_DURATIONS } from "./interfaces/Push";
61
- export type { PushEventType, MuteDuration, NotificationPreferences, } from "./interfaces/Push";
66
+ export type { PushEventType, MuteDuration, NotificationPreferences, PushDeviceIdentifier, WebPushSubscription, } from "./interfaces/Push";
67
+ export type { SignOutResult, PushUnbindSkipReason, } from "./modules/auth/signOut";
62
68
  export type { UpdateNotificationPreferencesProps } from "./modules/push/updateNotificationPreferences";
63
69
  export type { MuteConversationProps, MuteConversationResponse, } from "./modules/chat/muteConversation";
64
70
  export type { TableAccessor, TableRow, TableQuery, DbFilter, DbFilterOperator, BulkDeleteProps, DeleteResult, BulkDeleteResult, } from "./interfaces/Table";
package/dist/index.js CHANGED
@@ -212,13 +212,54 @@ async function signIn(client, data) {
212
212
  }
213
213
 
214
214
  // src/modules/auth/signOut.ts
215
+ var PUSH_UNBIND_STATUS_UNKNOWN_CODE = "auth/push-unbind-status-unknown";
216
+ var UNBIND_FAILURE_CODES = [
217
+ "auth/device-deregistration-failed",
218
+ "auth/sign-out-failed"
219
+ ];
220
+ function isUnbindFailure(error) {
221
+ const code = error?.response?.data?.code;
222
+ return typeof code === "string" && UNBIND_FAILURE_CODES.includes(code);
223
+ }
215
224
  async function signOut(client, data) {
216
225
  const refreshToken = data?.refreshToken ?? client.getRefreshToken();
217
- await client.projectInstance.post(
218
- "/auth/sign-out",
219
- refreshToken ? { refreshToken } : {}
220
- );
226
+ const localUnbindSkipped = Boolean(data?.pushDevice) && !refreshToken;
227
+ const body = refreshToken ? { refreshToken } : {};
228
+ if (data?.pushDevice && !localUnbindSkipped) body.pushDevice = data.pushDevice;
229
+ let response;
230
+ try {
231
+ response = await client.projectInstance.post(
232
+ "/auth/sign-out",
233
+ body
234
+ );
235
+ } catch (error) {
236
+ if (isUnbindFailure(error)) throw error;
237
+ console.warn(
238
+ "signOut: the server sign-out did not complete, so the session may still be live on the server until its refresh token expires. Signing out locally anyway \u2014 a user must always be able to sign out; only a refused push unbind keeps the local session, because that is the one failure that leaves a binding to retry against.",
239
+ error
240
+ );
241
+ }
221
242
  client.clearTokens();
243
+ const serverUnbindSkipped = typeof response?.data === "object" && response.data !== null && response.data.code === PUSH_UNBIND_STATUS_UNKNOWN_CODE;
244
+ if (localUnbindSkipped) {
245
+ console.warn(
246
+ "signOut: signed out, but the push unbind was SKIPPED \u2014 `pushDevice` was supplied and no refresh token could be resolved (none stored and none provided). The unbind is scoped to the refresh token's subject, so the server would have unbound nothing. This device keeps receiving that account's notifications until something else removes the binding. Pass `refreshToken` alongside `pushDevice` \u2014 required in host-managed mode, where the SDK stores no refresh token."
247
+ );
248
+ return {
249
+ pushUnbindSkipped: true,
250
+ pushUnbindSkipReason: "no-refresh-token"
251
+ };
252
+ }
253
+ if (serverUnbindSkipped) {
254
+ console.warn(
255
+ "signOut: signed out, but the push unbind was SKIPPED \u2014 the server could not determine whether this project has push devices, so it did not attempt one. This device may still be bound to that account and can keep receiving its notifications. The sign-out itself committed, so there is no credential left to retry with: the binding clears when that account next registers on this device, or when the server prunes the token as undeliverable."
256
+ );
257
+ return {
258
+ pushUnbindSkipped: true,
259
+ pushUnbindSkipReason: "push-unbind-status-unknown"
260
+ };
261
+ }
262
+ return { pushUnbindSkipped: false };
222
263
  }
223
264
 
224
265
  // src/modules/auth/requestNewAccessToken.ts
@@ -266,7 +307,11 @@ async function resetPassword(client, data) {
266
307
  async function changePassword(client, data) {
267
308
  const response = await client.projectInstance.post(
268
309
  "/auth/change-password",
269
- data
310
+ {
311
+ password: data.password,
312
+ newPassword: data.newPassword,
313
+ ...data.pushDevice ? { pushDevice: data.pushDevice } : {}
314
+ }
270
315
  );
271
316
  return response.data;
272
317
  }
@@ -1933,6 +1978,49 @@ async function fetchModeratedReports(client, data) {
1933
1978
  return response.data;
1934
1979
  }
1935
1980
 
1981
+ // src/modules/reputation/index.ts
1982
+ var reputation_exports = {};
1983
+ __export(reputation_exports, {
1984
+ createGrant: () => createGrant,
1985
+ listGrants: () => listGrants
1986
+ });
1987
+
1988
+ // src/modules/reputation/createGrant.ts
1989
+ async function createGrant(client, data) {
1990
+ const response = await client.projectInstance.post(
1991
+ "/reputation-grants",
1992
+ data
1993
+ );
1994
+ return response.data;
1995
+ }
1996
+
1997
+ // src/modules/reputation/listGrants.ts
1998
+ async function listGrants(client, data) {
1999
+ const {
2000
+ spaceReputation,
2001
+ spaceReputationId,
2002
+ spaceReputationDescendants,
2003
+ ...rest
2004
+ } = data;
2005
+ const response = await client.projectInstance.get(
2006
+ "/reputation-grants",
2007
+ {
2008
+ params: {
2009
+ ...rest,
2010
+ // `spaceReputationId=context` scores each hydrated user against THAT
2011
+ // GRANT'S own bucket. Normalized rather than spread raw — axios would
2012
+ // bracket-encode the object and the server would ignore it.
2013
+ ...buildSpaceReputationParams({
2014
+ spaceReputation,
2015
+ spaceReputationId,
2016
+ spaceReputationDescendants
2017
+ })
2018
+ }
2019
+ }
2020
+ );
2021
+ return response.data;
2022
+ }
2023
+
1936
2024
  // src/modules/search/index.ts
1937
2025
  var search_exports = {};
1938
2026
  __export(search_exports, {
@@ -2553,11 +2641,9 @@ __export(workspaces_exports, {
2553
2641
 
2554
2642
  // src/modules/workspaces/createWorkspace.ts
2555
2643
  async function createWorkspace(client, data) {
2556
- const body = { ...data };
2557
- delete body.userId;
2558
2644
  const response = await client.projectInstance.post(
2559
2645
  "/workspaces",
2560
- body
2646
+ data
2561
2647
  );
2562
2648
  return response.data;
2563
2649
  }
@@ -2574,17 +2660,13 @@ async function fetchWorkspace(client, data) {
2574
2660
 
2575
2661
  // src/modules/workspaces/fetchManyWorkspaces.ts
2576
2662
  async function fetchManyWorkspaces(client, data = {}) {
2577
- const params = { ...data };
2578
- delete params.userId;
2579
- const response = await client.projectInstance.get("/workspaces", { params });
2663
+ const response = await client.projectInstance.get("/workspaces", { params: data });
2580
2664
  return response.data;
2581
2665
  }
2582
2666
 
2583
2667
  // src/modules/workspaces/updateWorkspace.ts
2584
2668
  async function updateWorkspace(client, data) {
2585
- const { workspaceId, ...rest } = data;
2586
- const body = { ...rest };
2587
- delete body.userId;
2669
+ const { workspaceId, ...body } = data;
2588
2670
  const response = await client.projectInstance.patch(
2589
2671
  `/workspaces/${workspaceId}`,
2590
2672
  body
@@ -2613,9 +2695,7 @@ async function deleteWorkspace(client, data) {
2613
2695
 
2614
2696
  // src/modules/workspaces/transferWorkspaceOwnership.ts
2615
2697
  async function transferWorkspaceOwnership(client, data) {
2616
- const { workspaceId, ...rest } = data;
2617
- const body = { ...rest };
2618
- delete body.userId;
2698
+ const { workspaceId, ...body } = data;
2619
2699
  const response = await client.projectInstance.post(
2620
2700
  `/workspaces/${workspaceId}/transfer-ownership`,
2621
2701
  body
@@ -2625,9 +2705,7 @@ async function transferWorkspaceOwnership(client, data) {
2625
2705
 
2626
2706
  // src/modules/workspaces/fetchWorkspaceMembers.ts
2627
2707
  async function fetchWorkspaceMembers(client, data) {
2628
- const { workspaceId, ...rest } = data;
2629
- const params = { ...rest };
2630
- delete params.userId;
2708
+ const { workspaceId, ...params } = data;
2631
2709
  const response = await client.projectInstance.get(`/workspaces/${workspaceId}/members`, { params });
2632
2710
  return response.data;
2633
2711
  }
@@ -2643,9 +2721,7 @@ async function fetchWorkspaceMemberStanding(client, data) {
2643
2721
 
2644
2722
  // src/modules/workspaces/updateWorkspaceMember.ts
2645
2723
  async function updateWorkspaceMember(client, data) {
2646
- const { workspaceId, targetUserId, ...rest } = data;
2647
- const body = { ...rest };
2648
- delete body.userId;
2724
+ const { workspaceId, targetUserId, ...body } = data;
2649
2725
  const response = await client.projectInstance.patch(
2650
2726
  `/workspaces/${workspaceId}/members/${targetUserId}`,
2651
2727
  body
@@ -2863,6 +2939,7 @@ var PUSH_EVENT_TYPES = [
2863
2939
  "event-invite",
2864
2940
  "event-updated",
2865
2941
  "event-cancelled",
2942
+ "reputation-grant",
2866
2943
  "message"
2867
2944
  ];
2868
2945
  var MUTE_DURATIONS = ["8h", "24h", "1w", "forever"];
@@ -2881,6 +2958,7 @@ var SublayClient = class _SublayClient {
2881
2958
  connections;
2882
2959
  appNotifications;
2883
2960
  reports;
2961
+ reputation;
2884
2962
  search;
2885
2963
  storage;
2886
2964
  oauth;
@@ -2900,6 +2978,7 @@ var SublayClient = class _SublayClient {
2900
2978
  this.connections = bindModule(connections_exports, this.http);
2901
2979
  this.appNotifications = bindModule(app_notifications_exports, this.http);
2902
2980
  this.reports = bindModule(reports_exports, this.http);
2981
+ this.reputation = bindModule(reputation_exports, this.http);
2903
2982
  this.search = bindModule(search_exports, this.http);
2904
2983
  this.storage = bindModule(storage_exports, this.http);
2905
2984
  this.oauth = bindModule(oauth_exports, this.http);
package/dist/index.mjs CHANGED
@@ -180,13 +180,54 @@ async function signIn(client, data) {
180
180
  }
181
181
 
182
182
  // src/modules/auth/signOut.ts
183
+ var PUSH_UNBIND_STATUS_UNKNOWN_CODE = "auth/push-unbind-status-unknown";
184
+ var UNBIND_FAILURE_CODES = [
185
+ "auth/device-deregistration-failed",
186
+ "auth/sign-out-failed"
187
+ ];
188
+ function isUnbindFailure(error) {
189
+ const code = error?.response?.data?.code;
190
+ return typeof code === "string" && UNBIND_FAILURE_CODES.includes(code);
191
+ }
183
192
  async function signOut(client, data) {
184
193
  const refreshToken = data?.refreshToken ?? client.getRefreshToken();
185
- await client.projectInstance.post(
186
- "/auth/sign-out",
187
- refreshToken ? { refreshToken } : {}
188
- );
194
+ const localUnbindSkipped = Boolean(data?.pushDevice) && !refreshToken;
195
+ const body = refreshToken ? { refreshToken } : {};
196
+ if (data?.pushDevice && !localUnbindSkipped) body.pushDevice = data.pushDevice;
197
+ let response;
198
+ try {
199
+ response = await client.projectInstance.post(
200
+ "/auth/sign-out",
201
+ body
202
+ );
203
+ } catch (error) {
204
+ if (isUnbindFailure(error)) throw error;
205
+ console.warn(
206
+ "signOut: the server sign-out did not complete, so the session may still be live on the server until its refresh token expires. Signing out locally anyway \u2014 a user must always be able to sign out; only a refused push unbind keeps the local session, because that is the one failure that leaves a binding to retry against.",
207
+ error
208
+ );
209
+ }
189
210
  client.clearTokens();
211
+ const serverUnbindSkipped = typeof response?.data === "object" && response.data !== null && response.data.code === PUSH_UNBIND_STATUS_UNKNOWN_CODE;
212
+ if (localUnbindSkipped) {
213
+ console.warn(
214
+ "signOut: signed out, but the push unbind was SKIPPED \u2014 `pushDevice` was supplied and no refresh token could be resolved (none stored and none provided). The unbind is scoped to the refresh token's subject, so the server would have unbound nothing. This device keeps receiving that account's notifications until something else removes the binding. Pass `refreshToken` alongside `pushDevice` \u2014 required in host-managed mode, where the SDK stores no refresh token."
215
+ );
216
+ return {
217
+ pushUnbindSkipped: true,
218
+ pushUnbindSkipReason: "no-refresh-token"
219
+ };
220
+ }
221
+ if (serverUnbindSkipped) {
222
+ console.warn(
223
+ "signOut: signed out, but the push unbind was SKIPPED \u2014 the server could not determine whether this project has push devices, so it did not attempt one. This device may still be bound to that account and can keep receiving its notifications. The sign-out itself committed, so there is no credential left to retry with: the binding clears when that account next registers on this device, or when the server prunes the token as undeliverable."
224
+ );
225
+ return {
226
+ pushUnbindSkipped: true,
227
+ pushUnbindSkipReason: "push-unbind-status-unknown"
228
+ };
229
+ }
230
+ return { pushUnbindSkipped: false };
190
231
  }
191
232
 
192
233
  // src/modules/auth/requestNewAccessToken.ts
@@ -234,7 +275,11 @@ async function resetPassword(client, data) {
234
275
  async function changePassword(client, data) {
235
276
  const response = await client.projectInstance.post(
236
277
  "/auth/change-password",
237
- data
278
+ {
279
+ password: data.password,
280
+ newPassword: data.newPassword,
281
+ ...data.pushDevice ? { pushDevice: data.pushDevice } : {}
282
+ }
238
283
  );
239
284
  return response.data;
240
285
  }
@@ -1901,6 +1946,49 @@ async function fetchModeratedReports(client, data) {
1901
1946
  return response.data;
1902
1947
  }
1903
1948
 
1949
+ // src/modules/reputation/index.ts
1950
+ var reputation_exports = {};
1951
+ __export(reputation_exports, {
1952
+ createGrant: () => createGrant,
1953
+ listGrants: () => listGrants
1954
+ });
1955
+
1956
+ // src/modules/reputation/createGrant.ts
1957
+ async function createGrant(client, data) {
1958
+ const response = await client.projectInstance.post(
1959
+ "/reputation-grants",
1960
+ data
1961
+ );
1962
+ return response.data;
1963
+ }
1964
+
1965
+ // src/modules/reputation/listGrants.ts
1966
+ async function listGrants(client, data) {
1967
+ const {
1968
+ spaceReputation,
1969
+ spaceReputationId,
1970
+ spaceReputationDescendants,
1971
+ ...rest
1972
+ } = data;
1973
+ const response = await client.projectInstance.get(
1974
+ "/reputation-grants",
1975
+ {
1976
+ params: {
1977
+ ...rest,
1978
+ // `spaceReputationId=context` scores each hydrated user against THAT
1979
+ // GRANT'S own bucket. Normalized rather than spread raw — axios would
1980
+ // bracket-encode the object and the server would ignore it.
1981
+ ...buildSpaceReputationParams({
1982
+ spaceReputation,
1983
+ spaceReputationId,
1984
+ spaceReputationDescendants
1985
+ })
1986
+ }
1987
+ }
1988
+ );
1989
+ return response.data;
1990
+ }
1991
+
1904
1992
  // src/modules/search/index.ts
1905
1993
  var search_exports = {};
1906
1994
  __export(search_exports, {
@@ -2521,11 +2609,9 @@ __export(workspaces_exports, {
2521
2609
 
2522
2610
  // src/modules/workspaces/createWorkspace.ts
2523
2611
  async function createWorkspace(client, data) {
2524
- const body = { ...data };
2525
- delete body.userId;
2526
2612
  const response = await client.projectInstance.post(
2527
2613
  "/workspaces",
2528
- body
2614
+ data
2529
2615
  );
2530
2616
  return response.data;
2531
2617
  }
@@ -2542,17 +2628,13 @@ async function fetchWorkspace(client, data) {
2542
2628
 
2543
2629
  // src/modules/workspaces/fetchManyWorkspaces.ts
2544
2630
  async function fetchManyWorkspaces(client, data = {}) {
2545
- const params = { ...data };
2546
- delete params.userId;
2547
- const response = await client.projectInstance.get("/workspaces", { params });
2631
+ const response = await client.projectInstance.get("/workspaces", { params: data });
2548
2632
  return response.data;
2549
2633
  }
2550
2634
 
2551
2635
  // src/modules/workspaces/updateWorkspace.ts
2552
2636
  async function updateWorkspace(client, data) {
2553
- const { workspaceId, ...rest } = data;
2554
- const body = { ...rest };
2555
- delete body.userId;
2637
+ const { workspaceId, ...body } = data;
2556
2638
  const response = await client.projectInstance.patch(
2557
2639
  `/workspaces/${workspaceId}`,
2558
2640
  body
@@ -2581,9 +2663,7 @@ async function deleteWorkspace(client, data) {
2581
2663
 
2582
2664
  // src/modules/workspaces/transferWorkspaceOwnership.ts
2583
2665
  async function transferWorkspaceOwnership(client, data) {
2584
- const { workspaceId, ...rest } = data;
2585
- const body = { ...rest };
2586
- delete body.userId;
2666
+ const { workspaceId, ...body } = data;
2587
2667
  const response = await client.projectInstance.post(
2588
2668
  `/workspaces/${workspaceId}/transfer-ownership`,
2589
2669
  body
@@ -2593,9 +2673,7 @@ async function transferWorkspaceOwnership(client, data) {
2593
2673
 
2594
2674
  // src/modules/workspaces/fetchWorkspaceMembers.ts
2595
2675
  async function fetchWorkspaceMembers(client, data) {
2596
- const { workspaceId, ...rest } = data;
2597
- const params = { ...rest };
2598
- delete params.userId;
2676
+ const { workspaceId, ...params } = data;
2599
2677
  const response = await client.projectInstance.get(`/workspaces/${workspaceId}/members`, { params });
2600
2678
  return response.data;
2601
2679
  }
@@ -2611,9 +2689,7 @@ async function fetchWorkspaceMemberStanding(client, data) {
2611
2689
 
2612
2690
  // src/modules/workspaces/updateWorkspaceMember.ts
2613
2691
  async function updateWorkspaceMember(client, data) {
2614
- const { workspaceId, targetUserId, ...rest } = data;
2615
- const body = { ...rest };
2616
- delete body.userId;
2692
+ const { workspaceId, targetUserId, ...body } = data;
2617
2693
  const response = await client.projectInstance.patch(
2618
2694
  `/workspaces/${workspaceId}/members/${targetUserId}`,
2619
2695
  body
@@ -2831,6 +2907,7 @@ var PUSH_EVENT_TYPES = [
2831
2907
  "event-invite",
2832
2908
  "event-updated",
2833
2909
  "event-cancelled",
2910
+ "reputation-grant",
2834
2911
  "message"
2835
2912
  ];
2836
2913
  var MUTE_DURATIONS = ["8h", "24h", "1w", "forever"];
@@ -2849,6 +2926,7 @@ var SublayClient = class _SublayClient {
2849
2926
  connections;
2850
2927
  appNotifications;
2851
2928
  reports;
2929
+ reputation;
2852
2930
  search;
2853
2931
  storage;
2854
2932
  oauth;
@@ -2868,6 +2946,7 @@ var SublayClient = class _SublayClient {
2868
2946
  this.connections = bindModule(connections_exports, this.http);
2869
2947
  this.appNotifications = bindModule(app_notifications_exports, this.http);
2870
2948
  this.reports = bindModule(reports_exports, this.http);
2949
+ this.reputation = bindModule(reputation_exports, this.http);
2871
2950
  this.search = bindModule(search_exports, this.http);
2872
2951
  this.storage = bindModule(storage_exports, this.http);
2873
2952
  this.oauth = bindModule(oauth_exports, this.http);
@@ -1,3 +1,4 @@
1
+ import { GrantSummary } from "./ReputationGrant";
1
2
  import { GifData } from "./Comment";
2
3
  import { File } from "./File";
3
4
  import { Mention } from "./Mention";
@@ -17,6 +18,13 @@ export interface ChatMessage {
17
18
  threadReplyCount: number;
18
19
  reactionCounts: Record<string, number>;
19
20
  userReactions: string[];
21
+ /**
22
+ * Reputation-grant summary. Opt-in — present exactly when the read requested
23
+ * `include=grants`. Once requested the server always returns the object,
24
+ * zero-filled rather than omitted, on projects with no grants and on projects
25
+ * without the reputation bundle alike.
26
+ */
27
+ grants?: GrantSummary;
20
28
  editedAt: string | null;
21
29
  userDeletedAt: string | null;
22
30
  moderationStatus: "approved" | "removed" | null;
@@ -1,3 +1,4 @@
1
+ import { GrantSummary } from "./ReputationGrant";
1
2
  import { Entity } from "./Entity";
2
3
  import { Mention } from "./Mention";
3
4
  import { User } from "./User";
@@ -28,6 +29,13 @@ export interface Comment {
28
29
  reactionCounts: ReactionCounts;
29
30
  userReaction?: ReactionType | null;
30
31
  repliesCount: number;
32
+ /**
33
+ * Reputation-grant summary. Opt-in — present exactly when the read requested
34
+ * `include=grants`. Once requested the server always returns the object,
35
+ * zero-filled rather than omitted, on projects with no grants and on projects
36
+ * without the reputation bundle alike.
37
+ */
38
+ grants?: GrantSummary;
31
39
  metadata: Record<string, any>;
32
40
  createdAt: string;
33
41
  updatedAt: string;
@@ -1,3 +1,4 @@
1
+ import { GrantSummary } from "./ReputationGrant";
1
2
  import { Mention } from "./Mention";
2
3
  import { User } from "./User";
3
4
  import { Space } from "./Space";
@@ -43,6 +44,13 @@ export interface Entity {
43
44
  nsfwEffective: boolean;
44
45
  topComment: TopComment | null;
45
46
  isSaved?: boolean;
47
+ /**
48
+ * Reputation-grant summary. Opt-in — present exactly when the read requested
49
+ * `include=grants`. Once requested the server always returns the object,
50
+ * zero-filled rather than omitted, on projects with no grants and on projects
51
+ * without the reputation bundle alike.
52
+ */
53
+ grants?: GrantSummary;
46
54
  isDraft: boolean | null;
47
55
  moderationStatus: "approved" | "removed" | null;
48
56
  moderatedAt: string | null;
@@ -4,7 +4,7 @@
4
4
  * (server `src/constants/push/pushEvents.ts`); these are the only names a
5
5
  * `disabledTypes` set may contain.
6
6
  */
7
- export declare const PUSH_EVENT_TYPES: readonly ["entity-comment", "comment-reply", "entity-mention", "comment-mention", "entity-reaction", "comment-reaction", "entity-reaction-milestone-specific", "entity-reaction-milestone-total", "comment-reaction-milestone-specific", "comment-reaction-milestone-total", "new-follow", "connection-request", "connection-accepted", "space-membership-approved", "event-invite", "event-updated", "event-cancelled", "message"];
7
+ export declare const PUSH_EVENT_TYPES: readonly ["entity-comment", "comment-reply", "entity-mention", "comment-mention", "entity-reaction", "comment-reaction", "entity-reaction-milestone-specific", "entity-reaction-milestone-total", "comment-reaction-milestone-specific", "comment-reaction-milestone-total", "new-follow", "connection-request", "connection-accepted", "space-membership-approved", "event-invite", "event-updated", "event-cancelled", "reputation-grant", "message"];
8
8
  export type PushEventType = (typeof PUSH_EVENT_TYPES)[number];
9
9
  /**
10
10
  * The four conversation-mute duration choices. Send the CHOICE, never a raw
@@ -18,3 +18,57 @@ export type MuteDuration = (typeof MUTE_DURATIONS)[number];
18
18
  export interface NotificationPreferences {
19
19
  disabledTypes: PushEventType[];
20
20
  }
21
+ /**
22
+ * A Web Push subscription in its SERIALIZED form — the JSON the server reads,
23
+ * not the live browser object.
24
+ *
25
+ * A `PushSubscription` straight from `PushManager.subscribe()` does NOT satisfy
26
+ * this type. It exposes its keys only through `getKey(name)`; there is no `keys`
27
+ * property to read, so it is not assignable here under strict TypeScript, and
28
+ * passing one through a cast sends a body the server rejects.
29
+ *
30
+ * To produce a value of this type:
31
+ *
32
+ * 1. **Serialize** the subscription with `subscription.toJSON()`.
33
+ * 2. **Confirm** `endpoint`, `keys.p256dh` and `keys.auth` are all present —
34
+ * `PushSubscriptionJSON` types every one of them as optional, while the
35
+ * server requires all three as non-empty strings and 400s otherwise.
36
+ *
37
+ * ```ts
38
+ * const json = subscription.toJSON();
39
+ * if (!json.endpoint || !json.keys?.p256dh || !json.keys?.auth) {
40
+ * throw new Error("Incomplete Web Push subscription");
41
+ * }
42
+ * const webPushSubscription: WebPushSubscription = {
43
+ * endpoint: json.endpoint,
44
+ * keys: { p256dh: json.keys.p256dh, auth: json.keys.auth },
45
+ * };
46
+ * ```
47
+ *
48
+ * Mirrors the server's `webPushSubscriptionSchema`
49
+ * (server `src/v7/validation/push-notifications/push-notifications.schema.ts`).
50
+ */
51
+ export interface WebPushSubscription {
52
+ endpoint: string;
53
+ keys: {
54
+ p256dh: string;
55
+ auth: string;
56
+ };
57
+ }
58
+ /**
59
+ * Identifies one physical device. Mirrors the server's device-identifier body
60
+ * exactly (server `src/v7/validation/push-notifications/push-notifications.schema.ts`):
61
+ * a provider token for `ios`/`android`, a Web Push subscription for `web`. The
62
+ * union encodes the server's own cross-check — it rejects the same
63
+ * combinations the server's `superRefine` rejects.
64
+ *
65
+ * Passed to `auth.signOut` to unbind that device's push binding in the same
66
+ * transaction as the sign-out.
67
+ */
68
+ export type PushDeviceIdentifier = {
69
+ platform: "ios" | "android";
70
+ token: string;
71
+ } | {
72
+ platform: "web";
73
+ subscription: WebPushSubscription;
74
+ };
@@ -0,0 +1,85 @@
1
+ import { User } from "./User";
2
+ /** The three grantable target kinds. Polymorphic — `targetId` carries no FK. */
3
+ export type ReputationGrantTargetType = "entity" | "comment" | "chat-message";
4
+ /**
5
+ * Who created the grant. `"user"` is a debited transfer (reputation moved out
6
+ * of `senderId`'s bucket); `"app"` is a mint issued by the project itself with
7
+ * a null `senderId`. Persisted rather than inferred from `senderId`, which is
8
+ * also null for a transfer whose sender was later deleted.
9
+ */
10
+ export type ReputationGrantSourceType = "user" | "app";
11
+ /**
12
+ * The "which item was rewarded" pair, as a both-or-neither union.
13
+ *
14
+ * Modelled as a two-branch union rather than two independent optional fields so
15
+ * a half-filled target — `{ targetType }` with no `targetId`, or the reverse —
16
+ * does not compile. The server answers that shape with
17
+ * `400 reputation-grant/invalid-body` on the write (a shared
18
+ * `bothOrNeitherTarget` refinement) and
19
+ * `400 reputation-grant/invalid-filter` on the list, so the union turns a
20
+ * guaranteed round trip into a red squiggle.
21
+ *
22
+ * The empty branch is `?: undefined`, NOT `?: null` — deliberately, and for the
23
+ * same reason `metadata` is not nullable: `grantBodyFields.targetType` is
24
+ * `.optional()` with no `.nullable()`, so an explicit `targetType: null` is
25
+ * rejected. Omit both keys to mean "no target".
26
+ *
27
+ * Building the pair conditionally needs one accommodation: an inline
28
+ * conditional spread of just these two keys widens both to `T | undefined` and
29
+ * then matches neither branch. Either branch the whole argument, or name this
30
+ * type on a helper and spread that:
31
+ *
32
+ * ```ts
33
+ * const target: ReputationGrantTargetFilter = item
34
+ * ? { targetType: "entity", targetId: item.id }
35
+ * : {};
36
+ * await listGrants(client, { ...base, ...target });
37
+ * ```
38
+ */
39
+ export type ReputationGrantTargetFilter = {
40
+ /** The kind of item rewarded. Requires `targetId` alongside it. */
41
+ targetType: ReputationGrantTargetType;
42
+ /** The rewarded item's id. Requires `targetType` alongside it. */
43
+ targetId: string;
44
+ } | {
45
+ targetType?: undefined;
46
+ targetId?: undefined;
47
+ };
48
+ /**
49
+ * Per-item reputation-grant summary. Covers positive grants only — negative
50
+ * grants (app deductions) are invisible on every public read surface.
51
+ */
52
+ export interface GrantSummary {
53
+ /** Sum of positive grant amounts on the item. */
54
+ total: number;
55
+ /** Number of positive grants on the item. */
56
+ count: number;
57
+ /** The calling user's own summed positive grants on the item. */
58
+ viewerTotal: number;
59
+ }
60
+ /**
61
+ * A single reputation movement. Rows are append-only — nothing updates or
62
+ * soft-deletes them — so the table is the audit log behind every balance.
63
+ */
64
+ export interface ReputationGrant {
65
+ id: string;
66
+ sourceType: ReputationGrantSourceType;
67
+ /** Null for an app mint, and for a transfer whose sender was deleted. */
68
+ senderId: string | null;
69
+ /** Populated when the list is called with `include: "user"`. */
70
+ sender?: User | null;
71
+ recipientId: string;
72
+ /** Populated when the list is called with `include: "user"`. */
73
+ recipient?: User | null;
74
+ /** Non-zero. Negative only when `sourceType` is `"app"`. */
75
+ amount: number;
76
+ /** The bucket both legs moved in; null = the project-general bucket. */
77
+ spaceId: string | null;
78
+ /** Both null or both non-null. */
79
+ targetType: ReputationGrantTargetType | null;
80
+ targetId: string | null;
81
+ note: string | null;
82
+ metadata: Record<string, any> | null;
83
+ createdAt: string;
84
+ updatedAt: string;
85
+ }