@nurama/sdk 0.0.0-stage → 1.4.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 (220) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +5 -0
  3. package/README.md +1080 -2
  4. package/dist/BotClient.d.ts +66 -0
  5. package/dist/BotClient.d.ts.map +1 -0
  6. package/dist/BotClient.js +68 -0
  7. package/dist/BotClient.js.map +1 -0
  8. package/dist/NuramaClient.d.ts +448 -0
  9. package/dist/NuramaClient.d.ts.map +1 -0
  10. package/dist/NuramaClient.js +864 -0
  11. package/dist/NuramaClient.js.map +1 -0
  12. package/dist/browser/nurama-bot-sdk.js +11780 -0
  13. package/dist/browser/nurama-bot-sdk.min.js +1 -0
  14. package/dist/browser/nurama-sdk.js +11732 -0
  15. package/dist/browser/nurama-sdk.min.js +1 -0
  16. package/dist/routes/ai.d.ts +280 -0
  17. package/dist/routes/ai.d.ts.map +1 -0
  18. package/dist/routes/ai.js +173 -0
  19. package/dist/routes/ai.js.map +1 -0
  20. package/dist/routes/asset.d.ts +493 -0
  21. package/dist/routes/asset.d.ts.map +1 -0
  22. package/dist/routes/asset.js +848 -0
  23. package/dist/routes/asset.js.map +1 -0
  24. package/dist/routes/auth.d.ts +218 -0
  25. package/dist/routes/auth.d.ts.map +1 -0
  26. package/dist/routes/auth.js +454 -0
  27. package/dist/routes/auth.js.map +1 -0
  28. package/dist/routes/blogPosts.d.ts +17 -0
  29. package/dist/routes/blogPosts.d.ts.map +1 -0
  30. package/dist/routes/blogPosts.js +29 -0
  31. package/dist/routes/blogPosts.js.map +1 -0
  32. package/dist/routes/board.d.ts +187 -0
  33. package/dist/routes/board.d.ts.map +1 -0
  34. package/dist/routes/board.js +270 -0
  35. package/dist/routes/board.js.map +1 -0
  36. package/dist/routes/bot.d.ts +147 -0
  37. package/dist/routes/bot.d.ts.map +1 -0
  38. package/dist/routes/bot.js +157 -0
  39. package/dist/routes/bot.js.map +1 -0
  40. package/dist/routes/chat.d.ts +842 -0
  41. package/dist/routes/chat.d.ts.map +1 -0
  42. package/dist/routes/chat.js +863 -0
  43. package/dist/routes/chat.js.map +1 -0
  44. package/dist/routes/chatAi.d.ts +51 -0
  45. package/dist/routes/chatAi.d.ts.map +1 -0
  46. package/dist/routes/chatAi.js +109 -0
  47. package/dist/routes/chatAi.js.map +1 -0
  48. package/dist/routes/config.d.ts +11 -0
  49. package/dist/routes/config.d.ts.map +1 -0
  50. package/dist/routes/config.js +24 -0
  51. package/dist/routes/config.js.map +1 -0
  52. package/dist/routes/convo.d.ts +169 -0
  53. package/dist/routes/convo.d.ts.map +1 -0
  54. package/dist/routes/convo.js +284 -0
  55. package/dist/routes/convo.js.map +1 -0
  56. package/dist/routes/credits.d.ts +82 -0
  57. package/dist/routes/credits.d.ts.map +1 -0
  58. package/dist/routes/credits.js +49 -0
  59. package/dist/routes/credits.js.map +1 -0
  60. package/dist/routes/device.d.ts +74 -0
  61. package/dist/routes/device.d.ts.map +1 -0
  62. package/dist/routes/device.js +122 -0
  63. package/dist/routes/device.js.map +1 -0
  64. package/dist/routes/folder.d.ts +75 -0
  65. package/dist/routes/folder.d.ts.map +1 -0
  66. package/dist/routes/folder.js +99 -0
  67. package/dist/routes/folder.js.map +1 -0
  68. package/dist/routes/invite.d.ts +61 -0
  69. package/dist/routes/invite.d.ts.map +1 -0
  70. package/dist/routes/invite.js +86 -0
  71. package/dist/routes/invite.js.map +1 -0
  72. package/dist/routes/joinLink.d.ts +38 -0
  73. package/dist/routes/joinLink.d.ts.map +1 -0
  74. package/dist/routes/joinLink.js +81 -0
  75. package/dist/routes/joinLink.js.map +1 -0
  76. package/dist/routes/membership.d.ts +116 -0
  77. package/dist/routes/membership.d.ts.map +1 -0
  78. package/dist/routes/membership.js +183 -0
  79. package/dist/routes/membership.js.map +1 -0
  80. package/dist/routes/notification.d.ts +103 -0
  81. package/dist/routes/notification.d.ts.map +1 -0
  82. package/dist/routes/notification.js +89 -0
  83. package/dist/routes/notification.js.map +1 -0
  84. package/dist/routes/payment.d.ts +56 -0
  85. package/dist/routes/payment.d.ts.map +1 -0
  86. package/dist/routes/payment.js +78 -0
  87. package/dist/routes/payment.js.map +1 -0
  88. package/dist/routes/product.d.ts +43 -0
  89. package/dist/routes/product.d.ts.map +1 -0
  90. package/dist/routes/product.js +53 -0
  91. package/dist/routes/product.js.map +1 -0
  92. package/dist/routes/project.d.ts +821 -0
  93. package/dist/routes/project.d.ts.map +1 -0
  94. package/dist/routes/project.js +1153 -0
  95. package/dist/routes/project.js.map +1 -0
  96. package/dist/routes/public.d.ts +269 -0
  97. package/dist/routes/public.d.ts.map +1 -0
  98. package/dist/routes/public.js +412 -0
  99. package/dist/routes/public.js.map +1 -0
  100. package/dist/routes/scratch.d.ts +70 -0
  101. package/dist/routes/scratch.d.ts.map +1 -0
  102. package/dist/routes/scratch.js +67 -0
  103. package/dist/routes/scratch.js.map +1 -0
  104. package/dist/routes/settings.d.ts +102 -0
  105. package/dist/routes/settings.d.ts.map +1 -0
  106. package/dist/routes/settings.js +94 -0
  107. package/dist/routes/settings.js.map +1 -0
  108. package/dist/routes/shortlink.d.ts +79 -0
  109. package/dist/routes/shortlink.d.ts.map +1 -0
  110. package/dist/routes/shortlink.js +25 -0
  111. package/dist/routes/shortlink.js.map +1 -0
  112. package/dist/routes/socket.d.ts +108 -0
  113. package/dist/routes/socket.d.ts.map +1 -0
  114. package/dist/routes/socket.js +555 -0
  115. package/dist/routes/socket.js.map +1 -0
  116. package/dist/routes/storage.d.ts +44 -0
  117. package/dist/routes/storage.d.ts.map +1 -0
  118. package/dist/routes/storage.js +49 -0
  119. package/dist/routes/storage.js.map +1 -0
  120. package/dist/routes/subscription.d.ts +184 -0
  121. package/dist/routes/subscription.d.ts.map +1 -0
  122. package/dist/routes/subscription.js +219 -0
  123. package/dist/routes/subscription.js.map +1 -0
  124. package/dist/routes/supportChat.d.ts +40 -0
  125. package/dist/routes/supportChat.d.ts.map +1 -0
  126. package/dist/routes/supportChat.js +53 -0
  127. package/dist/routes/supportChat.js.map +1 -0
  128. package/dist/routes/supportTicket.d.ts +89 -0
  129. package/dist/routes/supportTicket.d.ts.map +1 -0
  130. package/dist/routes/supportTicket.js +54 -0
  131. package/dist/routes/supportTicket.js.map +1 -0
  132. package/dist/routes/tag.d.ts +72 -0
  133. package/dist/routes/tag.d.ts.map +1 -0
  134. package/dist/routes/tag.js +81 -0
  135. package/dist/routes/tag.js.map +1 -0
  136. package/dist/routes/task.d.ts +252 -0
  137. package/dist/routes/task.d.ts.map +1 -0
  138. package/dist/routes/task.js +284 -0
  139. package/dist/routes/task.js.map +1 -0
  140. package/dist/routes/taskRelation.d.ts +80 -0
  141. package/dist/routes/taskRelation.d.ts.map +1 -0
  142. package/dist/routes/taskRelation.js +71 -0
  143. package/dist/routes/taskRelation.js.map +1 -0
  144. package/dist/routes/token.d.ts +75 -0
  145. package/dist/routes/token.d.ts.map +1 -0
  146. package/dist/routes/token.js +51 -0
  147. package/dist/routes/token.js.map +1 -0
  148. package/dist/routes/user.d.ts +112 -0
  149. package/dist/routes/user.d.ts.map +1 -0
  150. package/dist/routes/user.js +151 -0
  151. package/dist/routes/user.js.map +1 -0
  152. package/dist/routes/version.d.ts +42 -0
  153. package/dist/routes/version.d.ts.map +1 -0
  154. package/dist/routes/version.js +38 -0
  155. package/dist/routes/version.js.map +1 -0
  156. package/dist/routes/webhook.d.ts +170 -0
  157. package/dist/routes/webhook.d.ts.map +1 -0
  158. package/dist/routes/webhook.js +173 -0
  159. package/dist/routes/webhook.js.map +1 -0
  160. package/dist/routes/workspace.d.ts +120 -0
  161. package/dist/routes/workspace.d.ts.map +1 -0
  162. package/dist/routes/workspace.js +199 -0
  163. package/dist/routes/workspace.js.map +1 -0
  164. package/dist/utils/uploadSessionManager.d.ts +133 -0
  165. package/dist/utils/uploadSessionManager.d.ts.map +1 -0
  166. package/dist/utils/uploadSessionManager.js +321 -0
  167. package/dist/utils/uploadSessionManager.js.map +1 -0
  168. package/dist/utils/urlParams.d.ts +35 -0
  169. package/dist/utils/urlParams.d.ts.map +1 -0
  170. package/dist/utils/urlParams.js +146 -0
  171. package/dist/utils/urlParams.js.map +1 -0
  172. package/dist/version.d.ts +15 -0
  173. package/dist/version.d.ts.map +1 -0
  174. package/dist/version.js +12 -0
  175. package/dist/version.js.map +1 -0
  176. package/package.json +87 -3
  177. package/src/BotClient.ts +113 -0
  178. package/src/NuramaClient.ts +1193 -0
  179. package/src/bot-browser-entry.js +15 -0
  180. package/src/browser-entry.js +20 -0
  181. package/src/routes/ai.ts +378 -0
  182. package/src/routes/asset.ts +1104 -0
  183. package/src/routes/auth.ts +587 -0
  184. package/src/routes/blogPosts.ts +29 -0
  185. package/src/routes/board.ts +403 -0
  186. package/src/routes/bot.ts +257 -0
  187. package/src/routes/chat.ts +1292 -0
  188. package/src/routes/chatAi.ts +125 -0
  189. package/src/routes/config.ts +31 -0
  190. package/src/routes/convo.ts +321 -0
  191. package/src/routes/credits.ts +112 -0
  192. package/src/routes/device.ts +133 -0
  193. package/src/routes/folder.ts +154 -0
  194. package/src/routes/invite.ts +133 -0
  195. package/src/routes/joinLink.ts +100 -0
  196. package/src/routes/membership.ts +237 -0
  197. package/src/routes/notification.ts +166 -0
  198. package/src/routes/payment.ts +104 -0
  199. package/src/routes/product.ts +67 -0
  200. package/src/routes/project.ts +1528 -0
  201. package/src/routes/public.ts +496 -0
  202. package/src/routes/scratch.ts +94 -0
  203. package/src/routes/settings.ts +152 -0
  204. package/src/routes/shortlink.ts +90 -0
  205. package/src/routes/socket.ts +739 -0
  206. package/src/routes/storage.ts +83 -0
  207. package/src/routes/subscription.ts +307 -0
  208. package/src/routes/supportChat.ts +62 -0
  209. package/src/routes/supportTicket.ts +114 -0
  210. package/src/routes/tag.ts +131 -0
  211. package/src/routes/task.ts +431 -0
  212. package/src/routes/taskRelation.ts +125 -0
  213. package/src/routes/token.ts +113 -0
  214. package/src/routes/user.ts +214 -0
  215. package/src/routes/version.ts +62 -0
  216. package/src/routes/webhook.ts +295 -0
  217. package/src/routes/workspace.ts +223 -0
  218. package/src/utils/uploadSessionManager.ts +407 -0
  219. package/src/utils/urlParams.ts +181 -0
  220. package/src/version.ts +22 -0
@@ -0,0 +1,1528 @@
1
+ import NuramaClient from '../NuramaClient.js';
2
+ import {
3
+ type Project,
4
+ type Asset,
5
+ type Folder,
6
+ type Chat,
7
+ type ChatMessage,
8
+ type ChatSubmission, // Correct type name
9
+ type PaginatedResult,
10
+ type CursorPaginatedResult,
11
+ type PublicAssetResponse,
12
+ type PublicChatMessagesResponse,
13
+ type CreatePublicChatMessageRequest,
14
+ type CreatePublicAssetChatMessageResponse,
15
+ type SearchProjectParams,
16
+ type SearchResponse,
17
+ type DeleteImpact,
18
+ type FeedEvent,
19
+ type FeedVisibility,
20
+ type ListFeedEventsParams,
21
+ type CursorPaginatedFeedEvents,
22
+ } from '@nurama/types';
23
+
24
+ // Combine pagination metadata with a results array
25
+ // (Should be defined centrally or imported if used across multiple route files)
26
+ export type PaginatedResponse<T> = (PaginatedResult | CursorPaginatedResult) & {
27
+ results?: T[];
28
+ };
29
+
30
+ // --- Request Body Interfaces ---
31
+ export interface CreateProjectData {
32
+ name: string;
33
+ workspaceId: string;
34
+ }
35
+
36
+ export interface UpdateProjectData {
37
+ name?: string;
38
+ description?: string;
39
+ updateSlug?: boolean;
40
+ }
41
+
42
+ export interface FileUploadData {
43
+ id: number; // Client-side ID, likely ignored by backend but present in tests
44
+ name: string;
45
+ checksum: string;
46
+ sizeInMB: number;
47
+ basePath?: string; // Optional path within the project structure
48
+ }
49
+
50
+ export interface ProjectFileUploadBody {
51
+ files: FileUploadData[];
52
+ destinationPath?: string;
53
+ }
54
+
55
+ export interface LogoUploadData extends FileUploadData {}
56
+
57
+ export interface CreateSubmissionData {
58
+ itemPaths?: string[];
59
+ subject?: string;
60
+ description?: string;
61
+ version?: string;
62
+ /**
63
+ * When false, the submission is staged as `unreleased` — hidden from
64
+ * reviewers until it is released via `releaseSubmission`. Defaults to true
65
+ * (goes live immediately).
66
+ */
67
+ releaseImmediately?: boolean;
68
+ }
69
+
70
+ export interface AddItemsToSubmissionData {
71
+ itemPaths: string[];
72
+ destinationPath?: string;
73
+ }
74
+
75
+ export interface UpdateSubmissionData {
76
+ subject?: string;
77
+ description?: string;
78
+ version?: string;
79
+ }
80
+
81
+ export interface TagSubmissionData {
82
+ tagId: string;
83
+ }
84
+
85
+ export interface CreateSubmissionFolderData {
86
+ name: string;
87
+ color?: string;
88
+ basePath?: string;
89
+ }
90
+
91
+ export interface GetSubmissionParams {
92
+ chatMessageSort?: {
93
+ id?: 1 | -1;
94
+ createdAt?: 1 | -1;
95
+ updatedAt?: 1 | -1;
96
+ };
97
+ chatReplySort?: {
98
+ id?: 1 | -1;
99
+ createdAt?: 1 | -1;
100
+ updatedAt?: 1 | -1;
101
+ };
102
+ chatMessageLimit?: number;
103
+ chatReplyLimit?: number;
104
+ }
105
+
106
+ export interface MoveSubmissionItemsData {
107
+ itemPaths: string[];
108
+ destinationPath: string;
109
+ }
110
+
111
+ export interface CopySubmissionItemsData {
112
+ itemPaths: string[];
113
+ destinationPath: string;
114
+ }
115
+
116
+ export interface DeleteSubmissionItemsData {
117
+ itemPaths: string[];
118
+ }
119
+
120
+ export interface CreateFolderData {
121
+ name: string;
122
+ color?: string;
123
+ basePath?: string;
124
+ }
125
+
126
+ export interface PublishItemsData {
127
+ resourceIds: string[];
128
+ basePath?: string;
129
+ sendEmailNotification?: boolean;
130
+ }
131
+
132
+ export interface UnpublishItemsData {
133
+ resourceIds: string[];
134
+ }
135
+
136
+ export interface MoveItemsData {
137
+ itemPaths: string[];
138
+ destinationPath: string;
139
+ }
140
+
141
+ /**
142
+ * A move into a virtual folder is not a move. `Public/` and `Submission/`
143
+ * copy the items into that collection; `Review/` publishes them. Both leave
144
+ * the sources in place, and both report through the extra fields below.
145
+ */
146
+ export interface MoveItemsResult {
147
+ /** Items copied, or published when `published` is true. */
148
+ count: number;
149
+ /** Set when the destination resolved to a virtual folder. */
150
+ virtualDestination?: boolean;
151
+ /** Set when the destination was `Review/`, so the items were published. */
152
+ published?: boolean;
153
+ /** Items the publish rejected. Empty or absent when everything went through. */
154
+ errors?: Array<{ type: string; data?: unknown; message?: string }>;
155
+ }
156
+
157
+ export interface CopyItemsData {
158
+ itemPaths: string[];
159
+ destinationPath: string;
160
+ }
161
+
162
+ export interface DeleteItemsData {
163
+ itemPaths: string[];
164
+ }
165
+
166
+ // --- Public File System Interfaces ---
167
+
168
+ export interface CreatePublicFileSystemData {
169
+ itemPaths?: string[];
170
+ title: string;
171
+ description?: string;
172
+ validity?: number; // Validity period in milliseconds
173
+ /** Repress asset/folder creators + the "Shared by" user in the external public API output. */
174
+ hideCreators?: boolean;
175
+ /** Allow unauthenticated visitors to comment with just a display name + color. */
176
+ allowAnonymousComments?: boolean;
177
+ /**
178
+ * When false, the release is staged as `unreleased` — externally
179
+ * inaccessible until it is released via `releasePublicFileSystem`. Defaults
180
+ * to true (goes live immediately).
181
+ */
182
+ releaseImmediately?: boolean;
183
+ }
184
+
185
+ export interface UpdatePublicFileSystemData {
186
+ title?: string;
187
+ description?: string;
188
+ validity?: number; // Validity extension period in milliseconds (from now)
189
+ status?: 'active' | 'disabled' | 'expired' | 'error' | 'unreleased';
190
+ /** Repress asset/folder creators + the "Shared by" user in the external public API output. */
191
+ hideCreators?: boolean;
192
+ /** Allow unauthenticated visitors to comment with just a display name + color. */
193
+ allowAnonymousComments?: boolean;
194
+ }
195
+
196
+ export interface AddItemsToPublicFileSystemData {
197
+ itemPaths: string[];
198
+ }
199
+
200
+ export interface MovePublicItemsData {
201
+ itemPaths: string[];
202
+ destinationPath: string;
203
+ }
204
+
205
+ export interface CopyPublicItemsData {
206
+ itemPaths: string[];
207
+ destinationPath: string;
208
+ }
209
+
210
+ export interface DeletePublicItemsData {
211
+ itemPaths: string[];
212
+ }
213
+
214
+ // --- Query Parameter Interfaces ---
215
+
216
+ // Base interface for pagination options
217
+ export interface PaginationParams {
218
+ limit?: number;
219
+ page?: number; // For index pagination
220
+ paginate?: 'cursor' | 'index'; // Specify pagination type
221
+ cursor?: string; // For cursor pagination
222
+ paginateReverse?: boolean; // For cursor pagination
223
+ includeCursorRecord?: boolean; // For cursor pagination
224
+ startAt?: string; // For cursor pagination - start at a specific record ID
225
+ includeCounts?: boolean; // For cursor pagination - include counts
226
+ }
227
+
228
+ export interface GetItemsAtPathParams extends SortParams, DateRangeParams {
229
+ paginate?: 'cursor' | 'index';
230
+ resourceIds?: string[];
231
+ resourceType?: 'asset' | 'folder';
232
+ resourceTags?: string[];
233
+ creatorId?: string;
234
+ mediaTypes?: ('image' | 'video' | 'folder')[];
235
+ resourceStatus?: 'active' | 'pendingDelete';
236
+ nameSearch?: string;
237
+ limit?: number;
238
+ // Cursor pagination options
239
+ cursor?: string;
240
+ paginateReverse?: boolean;
241
+ includeCounts?: boolean;
242
+ includeCursorRecord?: boolean;
243
+ startAt?: string;
244
+ includeStartAtRecord?: boolean;
245
+ // Index pagination options
246
+ page?: number;
247
+ }
248
+
249
+ export interface SortParams {
250
+ sort?: Record<string, 1 | -1>;
251
+ }
252
+
253
+ export interface DateRangeParams {
254
+ createdBefore?: string | number; // Timestamp or ISO string
255
+ createdAfter?: string | number; // Timestamp or ISO string
256
+ }
257
+
258
+
259
+ // interface ListProjectsParams extends SortParams, PaginationParams {
260
+ // // No specific project list filters identified in tests yet
261
+ // }
262
+
263
+ export interface ListAssetsParams extends SortParams, PaginationParams, DateRangeParams {
264
+ mediaTypes?: ('image' | 'video' | string)[]; // Allow other types if needed
265
+ includeChats?: boolean;
266
+ folderId?: string;
267
+ ignoreFolder?: boolean;
268
+ }
269
+
270
+ export interface ListFeedParams extends ListAssetsParams {
271
+ // Feed uses similar params to ListAssetsParams
272
+ followedChatsOnly?: boolean;
273
+ hideIfNoChatMessages?: boolean;
274
+ chatMessageSort?: Record<string, 1 | -1>;
275
+ chatReplySort?: Record<string, 1 | -1>;
276
+ chatMessageLimit?: number;
277
+ chatReplyLimit?: number;
278
+ }
279
+
280
+ export interface ListFoldersParams extends SortParams, PaginationParams, DateRangeParams {
281
+ mediaTypes?: ('image' | 'video' | string)[];
282
+ // empty?: boolean; // Test checks for non-empty, API might support this
283
+ }
284
+
285
+ export interface ListSubmissionsParams extends SortParams, PaginationParams, DateRangeParams {
286
+ search?: string;
287
+ }
288
+
289
+ export type PublicFileSystemStatus = 'active' | 'expired' | 'disabled' | 'unreleased';
290
+
291
+ export interface ListPublicFileSystemsParams extends SortParams, PaginationParams {
292
+ search?: string;
293
+ status?: PublicFileSystemStatus | PublicFileSystemStatus[];
294
+ creatorId?: string;
295
+ }
296
+
297
+ export interface GetHighlightedMessagesParams extends SortParams, PaginationParams {
298
+ // Cursor pagination support for highlighted messages
299
+ }
300
+
301
+ export interface GetPublicChatMessagesParams extends PaginationParams {
302
+ replyLimit?: number;
303
+ }
304
+
305
+ export interface GetChatParams {
306
+ messages?: number;
307
+ replies?: number;
308
+ }
309
+
310
+ // --- Response Interfaces (using imported types) ---
311
+ export type ProjectResponse = Project;
312
+ export type AssetResponse = Asset;
313
+ export type FolderResponse = Folder;
314
+ export type ChatResponse = Chat;
315
+ export type SubmissionResponse = ChatSubmission; // Use ChatSubmission type
316
+
317
+ export interface PublicFileSystemResponse {
318
+ id: string;
319
+ projectId: string;
320
+ token: string;
321
+ title: string;
322
+ description?: string;
323
+ itemPaths: string[];
324
+ expiresAt: string;
325
+ createdAt: string;
326
+ updatedAt: string;
327
+ hideCreators?: boolean;
328
+ allowAnonymousComments?: boolean;
329
+ }
330
+
331
+ export interface PublicAuditAssetResponse {
332
+ id: string;
333
+ name: string;
334
+ mediaType: string;
335
+ thumbnail: { keyPath: string } | null;
336
+ creator: {
337
+ id: string;
338
+ displayName?: string;
339
+ firstName?: string;
340
+ lastName?: string;
341
+ avatar?: any; // eslint-disable-line @typescript-eslint/no-explicit-any
342
+ color?: string;
343
+ } | null;
344
+ publicFileSystems: Array<{ id: string; title: string; status: string }>;
345
+ publicLinkCount: number;
346
+ hasActivePublicLink: boolean;
347
+ everPublic: boolean;
348
+ createdAt: string;
349
+ }
350
+
351
+ /**
352
+ * Defines project-related methods for the NuramaClient.
353
+ */
354
+ export interface ProjectTopAccessActivityResponse {
355
+ range: string;
356
+ from: string;
357
+ to: string;
358
+ eventType: string;
359
+ results: Array<{ assetId: string; count: number }>;
360
+ }
361
+
362
+ export default function createProjectMethods(client: NuramaClient) {
363
+ return {
364
+ /**
365
+ * Creates a new project.
366
+ * @param {CreateProjectData} projectData - Data for the new project.
367
+ * @returns {Promise<ProjectResponse>} The created project object.
368
+ */
369
+ async createProject(projectData: CreateProjectData): Promise<ProjectResponse> {
370
+ return client._request<ProjectResponse>({
371
+ method: 'POST',
372
+ endpoint: '/v1/projects',
373
+ body: projectData,
374
+ sendJWT: true,
375
+ });
376
+ },
377
+
378
+ /**
379
+ * Retrieves projects accessible by the user.
380
+ * NOTE: API endpoint `/v1/projects` does not currently support pagination.
381
+ * @returns {Promise<ProjectResponse[]>} List of project objects.
382
+ */
383
+ async getProjects(): Promise<ProjectResponse[]> {
384
+ return client._request<ProjectResponse[]>({
385
+ method: 'GET',
386
+ endpoint: '/v1/projects',
387
+ sendJWT: true,
388
+ });
389
+ },
390
+
391
+ /**
392
+ * Retrieves a specific project by its ID.
393
+ * @param {string} projectId - The ID of the project.
394
+ * @returns {Promise<ProjectResponse>} The project object.
395
+ */
396
+ async getProject(projectId: string): Promise<ProjectResponse> {
397
+ if (!projectId) throw new Error('projectId is required.');
398
+ return client._request<ProjectResponse>({
399
+ method: 'GET',
400
+ endpoint: `/v1/projects/${projectId}`,
401
+ sendJWT: true,
402
+ });
403
+ },
404
+
405
+ /**
406
+ * Updates a project.
407
+ * @param {string} projectId - The ID of the project to update.
408
+ * @param {UpdateProjectData} updateData - Data to update.
409
+ * @returns {Promise<ProjectResponse>} The updated project object.
410
+ */
411
+ async updateProject(projectId: string, updateData: UpdateProjectData): Promise<ProjectResponse> {
412
+ if (!projectId) throw new Error('projectId is required.');
413
+ return client._request<ProjectResponse>({
414
+ method: 'PUT',
415
+ endpoint: `/v1/projects/${projectId}`,
416
+ body: updateData,
417
+ sendJWT: true,
418
+ });
419
+ },
420
+
421
+ /**
422
+ * Updates a single project setting (e.g. `aiPolishEnabled`,
423
+ * `aiCustomPreprompt`). Pass `null` to inherit the workspace's value;
424
+ * pass a typed value to override. The valid setting names are validated
425
+ * server-side against `projectService.validProjectSettings`.
426
+ *
427
+ * @param {string} projectId
428
+ * @param {string} name - Setting key (e.g. 'aiPolishEnabled').
429
+ * @param {unknown} value - null (inherit) | boolean | string.
430
+ */
431
+ async updateSetting(projectId: string, name: string, value: unknown): Promise<ProjectResponse> {
432
+ if (!projectId) throw new Error('projectId is required.');
433
+ if (!name) throw new Error('name is required.');
434
+ return client._request<ProjectResponse>({
435
+ method: 'PATCH',
436
+ endpoint: `/v1/projects/${projectId}/settings/${encodeURIComponent(name)}`,
437
+ body: { value },
438
+ sendJWT: true,
439
+ });
440
+ },
441
+
442
+ /**
443
+ * Full-text search across assets, chat messages, and tasks within a project.
444
+ * Results are populated per the content type's native list view (asset →
445
+ * creator/publisher/tags; chatMessage → author/mentions/attachments; task →
446
+ * creator/assignee/project/origin).
447
+ *
448
+ * @param {string} projectId
449
+ * @param {SearchProjectParams} params - At minimum `q`. Optional filters: `contentTypes`, `dateFrom`, `dateTo`, `creatorId`, `sortBy`, `page`, `limit`.
450
+ * @returns {Promise<SearchResponse>} Paginated search results.
451
+ */
452
+ async searchProject(projectId: string, params: SearchProjectParams): Promise<SearchResponse> {
453
+ if (!projectId) throw new Error('projectId is required.');
454
+ if (!params || !params.q) throw new Error('params.q is required.');
455
+ return client._request<SearchResponse>({
456
+ method: 'GET',
457
+ endpoint: `/v1/projects/${projectId}/search`,
458
+ params: params,
459
+ sendJWT: true,
460
+ });
461
+ },
462
+
463
+ /**
464
+ * Deletes a project (marks for deletion).
465
+ * @param {string} projectId - The ID of the project to delete.
466
+ * @returns {Promise<PublicFileSystemResponse>} The deleted public release record.
467
+ */
468
+ async deleteProject(projectId: string): Promise<void> {
469
+ if (!projectId) throw new Error('projectId is required.');
470
+ return client._request({
471
+ method: 'DELETE',
472
+ endpoint: `/v1/projects/${projectId}`,
473
+ sendJWT: true,
474
+ });
475
+ },
476
+
477
+ /**
478
+ * Creates a new logo asset for a project.
479
+ * @param {string} projectId - The ID of the project.
480
+ * @param {LogoUploadData} logoData - File metadata for the logo.
481
+ * @returns {Promise<any>} Object containing signed URL data and updated project info.
482
+ */
483
+ async createLogo(projectId: string, logoData: LogoUploadData): Promise<any> {
484
+ if (!projectId) throw new Error('projectId is required.');
485
+ return client._request({
486
+ method: 'POST',
487
+ endpoint: `/v1/projects/${projectId}/logo`,
488
+ body: logoData,
489
+ sendJWT: true,
490
+ });
491
+ },
492
+
493
+ /**
494
+ * Updates the logo asset for a project.
495
+ * @param {string} projectId - The ID of the project.
496
+ * @param {LogoUploadData} logoData - File metadata for the new logo.
497
+ * @returns {Promise<any>} Object containing signed URL data and updated project info.
498
+ */
499
+ async updateLogo(projectId: string, logoData: LogoUploadData): Promise<any> {
500
+ if (!projectId) throw new Error('projectId is required.');
501
+ return client._request({
502
+ method: 'PUT',
503
+ endpoint: `/v1/projects/${projectId}/logo`,
504
+ body: logoData,
505
+ sendJWT: true,
506
+ });
507
+ },
508
+
509
+ /**
510
+ * Create assets within a project and return their signed links for upload.
511
+ * @param {string} projectId - The ID of the project.
512
+ * @param {ProjectFileUploadBody} fileUploadBody - List of files to upload with optional destination path.
513
+ * @returns {Promise<any[]>} Array of results, each containing asset info and signed URL data.
514
+ */
515
+ async createAssets(projectId: string, fileUploadBody: ProjectFileUploadBody): Promise<any[]> {
516
+ if (!projectId) throw new Error('projectId is required.');
517
+ return client._request<any[]>({
518
+ method: 'POST',
519
+ endpoint: `/v1/projects/${projectId}`,
520
+ body: fileUploadBody,
521
+ sendJWT: true,
522
+ });
523
+ },
524
+
525
+ // --- Asset Listing ---
526
+
527
+ /**
528
+ * Gets the home feed for a project with a specified visibility.
529
+ * @param {string} projectId - The ID of the project.
530
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
531
+ * @param {ListFeedParams} [params] - Query parameters for filtering and pagination.
532
+ * @returns {Promise<PaginatedResponse<AssetResponse>>} Paginated feed items.
533
+ */
534
+ async getHomeFeed(projectId: string, visibility: 'creator' | 'reviewer', params?: ListFeedParams): Promise<PaginatedResponse<AssetResponse>> {
535
+ if (!projectId) throw new Error('projectId is required.');
536
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
537
+
538
+ return client._request<PaginatedResponse<AssetResponse>>({
539
+ method: 'GET',
540
+ endpoint: `/v1/projects/${projectId}/feed/${visibility}`,
541
+ params: params,
542
+ sendJWT: true,
543
+ });
544
+ },
545
+
546
+ // --- Event Feed ---
547
+
548
+ /**
549
+ * Gets one page of the project's event feed (uploads, asset discussions,
550
+ * publishes, submissions and public releases), most recent activity first.
551
+ * The creator and reviewer feeds never share events.
552
+ * @param {string} projectId - The ID of the project.
553
+ * @param {'creator' | 'reviewer'} visibility - Which feed to read.
554
+ * @param {ListFeedEventsParams} [params] - Filters and cursor.
555
+ * @returns {Promise<CursorPaginatedFeedEvents>} One page of feed events.
556
+ */
557
+ async getFeedEvents(projectId: string, visibility: FeedVisibility, params?: ListFeedEventsParams): Promise<CursorPaginatedFeedEvents> {
558
+ if (!projectId) throw new Error('projectId is required.');
559
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
560
+
561
+ return client._request<CursorPaginatedFeedEvents>({
562
+ method: 'GET',
563
+ endpoint: `/v1/projects/${projectId}/feed-events/${visibility}`,
564
+ params,
565
+ sendJWT: true,
566
+ });
567
+ },
568
+
569
+ /**
570
+ * Sets your reaction on a feed event. One per person — a new emoji
571
+ * replaces your previous one.
572
+ * @returns {Promise<FeedEvent>} The updated event.
573
+ */
574
+ async setFeedEventReaction(projectId: string, visibility: FeedVisibility, eventId: string, emoji: string): Promise<FeedEvent> {
575
+ if (!projectId || !visibility || !eventId) throw new Error('projectId, visibility and eventId are required.');
576
+ if (!emoji) throw new Error('emoji is required.');
577
+
578
+ return client._request<FeedEvent>({
579
+ method: 'POST',
580
+ endpoint: `/v1/projects/${projectId}/feed-events/${visibility}/${eventId}/reaction`,
581
+ body: { emoji },
582
+ sendJWT: true,
583
+ });
584
+ },
585
+
586
+ /**
587
+ * Removes your reaction from a feed event.
588
+ * @returns {Promise<FeedEvent>} The updated event.
589
+ */
590
+ async removeFeedEventReaction(projectId: string, visibility: FeedVisibility, eventId: string): Promise<FeedEvent> {
591
+ if (!projectId || !visibility || !eventId) throw new Error('projectId, visibility and eventId are required.');
592
+
593
+ return client._request<FeedEvent>({
594
+ method: 'DELETE',
595
+ endpoint: `/v1/projects/${projectId}/feed-events/${visibility}/${eventId}/reaction`,
596
+ sendJWT: true,
597
+ });
598
+ },
599
+
600
+ // --- Folder Listing ---
601
+
602
+ /**
603
+ * Gets folders within a project with specified visibility.
604
+ * @param {string} projectId - The ID of the project.
605
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
606
+ * @param {ListFoldersParams} [params] - Query parameters for filtering and pagination.
607
+ * @returns {Promise<PaginatedResponse<FolderResponse>>} Paginated list of folders.
608
+ */
609
+ async getFolders(projectId: string, visibility: 'creator' | 'reviewer', params?: ListFoldersParams): Promise<PaginatedResponse<FolderResponse>> {
610
+ if (!projectId) throw new Error('projectId is required.');
611
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
612
+
613
+ // Use file system API with folder filter
614
+ const fileSystemParams: GetItemsAtPathParams = {
615
+ ...(params as object),
616
+ resourceType: 'folder',
617
+ mediaTypes: ['folder'],
618
+ };
619
+
620
+ return this.getItemsAtPath(projectId, visibility, '', fileSystemParams) as Promise<PaginatedResponse<FolderResponse>>;
621
+ },
622
+
623
+ // --- Chat ---
624
+
625
+ /**
626
+ * Gets the project chat with the specified visibility.
627
+ * @param {string} projectId - The ID of the project.
628
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
629
+ * @param {GetChatParams} [params] - Query parameters for message/reply limits.
630
+ * @returns {Promise<ChatResponse>} The chat object.
631
+ */
632
+ async getProjectChat(projectId: string, visibility: 'creator' | 'reviewer', params?: GetChatParams): Promise<ChatResponse> {
633
+ if (!projectId) throw new Error('projectId is required.');
634
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
635
+
636
+ return client._request<ChatResponse>({
637
+ method: 'GET',
638
+ endpoint: `/v1/projects/${projectId}/chat/${visibility}`,
639
+ params: params,
640
+ sendJWT: true,
641
+ });
642
+ },
643
+
644
+ // --- Submissions ---
645
+
646
+ /**
647
+ * Creates a new submission for a project.
648
+ * @param {string} projectId - The ID of the project.
649
+ * @param {CreateSubmissionData} submissionData - Data for the submission.
650
+ * @returns {Promise<SubmissionResponse>} The created submission object.
651
+ */
652
+ async createSubmission(projectId: string, submissionData: CreateSubmissionData): Promise<SubmissionResponse> {
653
+ if (!projectId) throw new Error('projectId is required.');
654
+ return client._request<SubmissionResponse>({
655
+ method: 'POST',
656
+ endpoint: `/v1/projects/${projectId}/submission`,
657
+ body: submissionData,
658
+ sendJWT: true,
659
+ });
660
+ },
661
+
662
+ /**
663
+ * Adds items to an existing submission.
664
+ * @param {string} projectId - The ID of the project.
665
+ * @param {string} submissionId - The ID of the submission.
666
+ * @param {AddItemsToSubmissionData} addItemsData - Data for adding items to the submission.
667
+ * @returns {Promise<SubmissionResponse>} The updated submission object.
668
+ */
669
+ async addItemsToSubmission(projectId: string, submissionId: string, addItemsData: AddItemsToSubmissionData): Promise<SubmissionResponse> {
670
+ if (!projectId) throw new Error('projectId is required.');
671
+ if (!submissionId) throw new Error('submissionId is required.');
672
+ return client._request<SubmissionResponse>({
673
+ method: 'POST',
674
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/add`,
675
+ body: addItemsData,
676
+ sendJWT: true,
677
+ });
678
+ },
679
+
680
+ /**
681
+ * Retrieves submissions for a project.
682
+ * @param {string} projectId - The ID of the project.
683
+ * @param {ListSubmissionsParams} [params] - Query parameters for filtering and pagination.
684
+ * @returns {Promise<PaginatedResponse<SubmissionResponse>>} Paginated list of submissions.
685
+ */
686
+ async getSubmissions(projectId: string, params?: ListSubmissionsParams): Promise<PaginatedResponse<SubmissionResponse>> {
687
+ if (!projectId) throw new Error('projectId is required.');
688
+ return client._request<PaginatedResponse<SubmissionResponse>>({
689
+ method: 'GET',
690
+ endpoint: `/v1/projects/${projectId}/submission`,
691
+ params: params,
692
+ sendJWT: true,
693
+ });
694
+ },
695
+
696
+ /**
697
+ * Retrieves a specific submission by its ID.
698
+ * @param {string} projectId - The ID of the project.
699
+ * @param {string} submissionId - The ID of the submission.
700
+ * @param {GetSubmissionParams} [params] - Query parameters for chat message/reply options.
701
+ * @returns {Promise<SubmissionResponse>} The submission object.
702
+ */
703
+ async getSubmission(projectId: string, submissionId: string, params?: GetSubmissionParams): Promise<SubmissionResponse> {
704
+ if (!projectId) throw new Error('projectId is required.');
705
+ if (!submissionId) throw new Error('submissionId is required.');
706
+ return client._request<SubmissionResponse>({
707
+ method: 'GET',
708
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}`,
709
+ params: params,
710
+ sendJWT: true,
711
+ });
712
+ },
713
+
714
+ /**
715
+ * Updates a submission.
716
+ * @param {string} projectId - The ID of the project.
717
+ * @param {string} submissionId - The ID of the submission.
718
+ * @param {UpdateSubmissionData} updateData - Data to update.
719
+ * @returns {Promise<SubmissionResponse>} The updated submission object.
720
+ */
721
+ async updateSubmission(projectId: string, submissionId: string, updateData: UpdateSubmissionData): Promise<SubmissionResponse> {
722
+ if (!projectId) throw new Error('projectId is required.');
723
+ if (!submissionId) throw new Error('submissionId is required.');
724
+ return client._request<SubmissionResponse>({
725
+ method: 'PUT',
726
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}`,
727
+ body: updateData,
728
+ sendJWT: true,
729
+ });
730
+ },
731
+
732
+ /**
733
+ * Releases a staged (unreleased) submission, making it visible to reviewers
734
+ * and firing the deferred "new submission" side effects (emails,
735
+ * notifications, system messages).
736
+ * @param {string} projectId - The ID of the project.
737
+ * @param {string} submissionId - The ID of the submission.
738
+ * @returns {Promise<SubmissionResponse>} The released submission object.
739
+ */
740
+ async releaseSubmission(projectId: string, submissionId: string): Promise<SubmissionResponse> {
741
+ if (!projectId) throw new Error('projectId is required.');
742
+ if (!submissionId) throw new Error('submissionId is required.');
743
+ return client._request<SubmissionResponse>({
744
+ method: 'POST',
745
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/release`,
746
+ sendJWT: true,
747
+ });
748
+ },
749
+
750
+ /**
751
+ * Re-releases an already-released submission's side effects (the "Release
752
+ * Update" action) — re-notifies reviewers with the submission-update email
753
+ * template + `submissionUpdate` notification. Does not change status.
754
+ * @param {string} projectId - The ID of the project.
755
+ * @param {string} submissionId - The ID of the submission.
756
+ * @returns {Promise<SubmissionResponse>} The submission object.
757
+ */
758
+ async releaseSubmissionUpdate(projectId: string, submissionId: string): Promise<SubmissionResponse> {
759
+ if (!projectId) throw new Error('projectId is required.');
760
+ if (!submissionId) throw new Error('submissionId is required.');
761
+ return client._request<SubmissionResponse>({
762
+ method: 'POST',
763
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/release-update`,
764
+ sendJWT: true,
765
+ });
766
+ },
767
+
768
+ /**
769
+ * Gets files for a specific submission.
770
+ * @param {string} projectId - The ID of the project.
771
+ * @param {string} submissionId - The ID of the submission.
772
+ * @param {string} [path] - The path to get items from (optional, defaults to root).
773
+ * @param {GetItemsAtPathParams} [params] - Query parameters for filtering and pagination.
774
+ * @returns {Promise<PaginatedResponse<any>>} Paginated list of files.
775
+ */
776
+ async getSubmissionItems(projectId: string, submissionId: string, path?: string, params?: GetItemsAtPathParams): Promise<PaginatedResponse<any>> {
777
+ if (!projectId) throw new Error('projectId is required.');
778
+ if (!submissionId) throw new Error('submissionId is required.');
779
+
780
+ // Build endpoint with optional path segment (backend supports wildcard paths)
781
+ let endpoint = `/v1/projects/${projectId}/submission/${submissionId}/files`;
782
+ if (path && typeof path === 'string' && path.trim() !== '') {
783
+ // Add path to URL - backend route supports /:path(*) wildcard
784
+ endpoint += `/${encodeURIComponent(path)}`;
785
+ }
786
+
787
+ return client._request<PaginatedResponse<any>>({
788
+ method: 'GET',
789
+ endpoint,
790
+ params: params,
791
+ sendJWT: true,
792
+ });
793
+ },
794
+
795
+ /**
796
+ * Creates a folder within a submission.
797
+ * @param {string} projectId - The ID of the project.
798
+ * @param {string} submissionId - The ID of the submission.
799
+ * @param {CreateSubmissionFolderData} folderData - Data for creating the folder.
800
+ * @returns {Promise<FolderResponse>} The created folder object.
801
+ */
802
+ async createSubmissionFolder(projectId: string, submissionId: string, folderData: CreateSubmissionFolderData): Promise<FolderResponse> {
803
+ if (!projectId) throw new Error('projectId is required.');
804
+ if (!submissionId) throw new Error('submissionId is required.');
805
+ return client._request<FolderResponse>({
806
+ method: 'POST',
807
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/files/create-folder`,
808
+ body: folderData,
809
+ sendJWT: true,
810
+ });
811
+ },
812
+
813
+ /**
814
+ * Moves items within a submission.
815
+ * @param {string} projectId - The ID of the project.
816
+ * @param {string} submissionId - The ID of the submission.
817
+ * @param {MoveSubmissionItemsData} moveData - Data for moving items.
818
+ * @returns {Promise<{count: number}>} Object containing the count of moved items.
819
+ */
820
+ async moveSubmissionItems(projectId: string, submissionId: string, moveData: MoveSubmissionItemsData): Promise<{count: number}> {
821
+ if (!projectId) throw new Error('projectId is required.');
822
+ if (!submissionId) throw new Error('submissionId is required.');
823
+ return client._request<{count: number}>({
824
+ method: 'PUT',
825
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/files/move`,
826
+ body: moveData,
827
+ sendJWT: true,
828
+ });
829
+ },
830
+
831
+ /**
832
+ * Copies items within a submission.
833
+ * @param {string} projectId - The ID of the project.
834
+ * @param {string} submissionId - The ID of the submission.
835
+ * @param {CopySubmissionItemsData} copyData - Data for copying items.
836
+ * @returns {Promise<{count: number}>} Object containing the count of copied items.
837
+ */
838
+ async copySubmissionItems(projectId: string, submissionId: string, copyData: CopySubmissionItemsData): Promise<{count: number}> {
839
+ if (!projectId) throw new Error('projectId is required.');
840
+ if (!submissionId) throw new Error('submissionId is required.');
841
+ return client._request<{count: number}>({
842
+ method: 'PUT',
843
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/files/copy`,
844
+ body: copyData,
845
+ sendJWT: true,
846
+ });
847
+ },
848
+
849
+ /**
850
+ * Deletes items within a submission.
851
+ * @param {string} projectId - The ID of the project.
852
+ * @param {string} submissionId - The ID of the submission.
853
+ * @param {DeleteSubmissionItemsData} deleteData - Data for deleting items.
854
+ * @returns {Promise<{count: number}>} Object containing the count of deleted items.
855
+ */
856
+ async deleteSubmissionItems(projectId: string, submissionId: string, deleteData: DeleteSubmissionItemsData): Promise<{count: number}> {
857
+ if (!projectId) throw new Error('projectId is required.');
858
+ if (!submissionId) throw new Error('submissionId is required.');
859
+ return client._request<{count: number}>({
860
+ method: 'PUT',
861
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/files/delete`,
862
+ body: deleteData,
863
+ sendJWT: true,
864
+ });
865
+ },
866
+
867
+ /**
868
+ * Adds a tag to a submission.
869
+ * @param {string} projectId - The ID of the project.
870
+ * @param {string} submissionId - The ID of the submission.
871
+ * @param {TagSubmissionData} tagData - Data for tagging the submission.
872
+ * @returns {Promise<SubmissionResponse>} The updated submission object.
873
+ */
874
+ async tagSubmission(projectId: string, submissionId: string, tagData: TagSubmissionData): Promise<SubmissionResponse> {
875
+ if (!projectId) throw new Error('projectId is required.');
876
+ if (!submissionId) throw new Error('submissionId is required.');
877
+ return client._request<SubmissionResponse>({
878
+ method: 'PUT',
879
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/tag`,
880
+ body: tagData,
881
+ sendJWT: true,
882
+ });
883
+ },
884
+
885
+ /**
886
+ * Removes a tag from a submission.
887
+ * @param {string} projectId - The ID of the project.
888
+ * @param {string} submissionId - The ID of the submission.
889
+ * @param {TagSubmissionData} tagData - Data for untagging the submission.
890
+ * @returns {Promise<SubmissionResponse>} The updated submission object.
891
+ */
892
+ async untagSubmission(projectId: string, submissionId: string, tagData: TagSubmissionData): Promise<SubmissionResponse> {
893
+ if (!projectId) throw new Error('projectId is required.');
894
+ if (!submissionId) throw new Error('submissionId is required.');
895
+ return client._request<SubmissionResponse>({
896
+ method: 'PUT',
897
+ endpoint: `/v1/projects/${projectId}/submission/${submissionId}/untag`,
898
+ body: tagData,
899
+ sendJWT: true,
900
+ });
901
+ },
902
+
903
+ // --- Publishing / File System Functions ---
904
+
905
+ /**
906
+ * Publishes a list of items (assets, folders) within a project.
907
+ * @param {string} projectId - The ID of the project.
908
+ * @param {PublishItemsData} publishData - Data for publishing items.
909
+ * @returns {Promise<any>} Object containing lists of published items and results.
910
+ */
911
+ async publishItems(projectId: string, publishData: PublishItemsData): Promise<any> {
912
+ if (!projectId) throw new Error('projectId is required.');
913
+ return client._request<any>({
914
+ method: 'POST',
915
+ endpoint: `/v1/projects/${projectId}/publish`,
916
+ body: publishData,
917
+ sendJWT: true,
918
+ });
919
+ },
920
+
921
+ /**
922
+ * Unpublishes a list of items (assets, folders) within a project.
923
+ * @param {string} projectId - The ID of the project.
924
+ * @param {UnpublishItemsData} unpublishData - Data for unpublishing items.
925
+ * @returns {Promise<any>} Object containing lists of unpublished items and results.
926
+ */
927
+ async unpublishItems(projectId: string, unpublishData: UnpublishItemsData): Promise<any> {
928
+ if (!projectId) throw new Error('projectId is required.');
929
+ return client._request<any>({
930
+ method: 'POST',
931
+ endpoint: `/v1/projects/${projectId}/unpublish`,
932
+ body: unpublishData,
933
+ sendJWT: true,
934
+ });
935
+ },
936
+
937
+ /**
938
+ * Creates a folder within a project with file system integration.
939
+ * @param {string} projectId - The ID of the project.
940
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
941
+ * @param {CreateFolderData} folderData - Data for creating the folder.
942
+ * @returns {Promise<FolderResponse>} The created folder object.
943
+ */
944
+ async createFolder(projectId: string, visibility: 'creator' | 'reviewer', folderData: CreateFolderData): Promise<FolderResponse> {
945
+ if (!projectId) throw new Error('projectId is required.');
946
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
947
+ return client._request<FolderResponse>({
948
+ method: 'POST',
949
+ endpoint: `/v1/projects/${projectId}/files/${visibility}/create-folder`,
950
+ body: folderData,
951
+ sendJWT: true,
952
+ });
953
+ },
954
+
955
+ /**
956
+ * Gets items at a specific path within a project.
957
+ * @param {string} projectId - The ID of the project.
958
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
959
+ * @param {string} [path] - The path to get items from (optional, defaults to root).
960
+ * @param {GetItemsAtPathParams} [params] - Query parameters for filtering and pagination.
961
+ * @param {boolean} [usePost] - Whether to use POST method (useful for large resourceIds arrays).
962
+ * @returns {Promise<PaginatedResponse<any>>} Paginated list of items at the path.
963
+ */
964
+ async getItemsAtPath(projectId: string, visibility: 'creator' | 'reviewer', path?: string, params?: GetItemsAtPathParams, usePost: boolean = false): Promise<PaginatedResponse<any>> {
965
+ if (!projectId) throw new Error('projectId is required.');
966
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
967
+
968
+ let endpoint = `/v1/projects/${projectId}/files/${visibility}`;
969
+ if (path && path.trim() !== '') {
970
+ endpoint += `/${encodeURIComponent(path)}`;
971
+ }
972
+
973
+ // Use POST method if specified (useful for large resourceIds arrays)
974
+ const method = usePost ? 'POST' : 'GET';
975
+
976
+ return client._request<PaginatedResponse<any>>({
977
+ method: method,
978
+ endpoint: endpoint,
979
+ params: method === 'GET' ? params : undefined,
980
+ body: method === 'POST' ? params : undefined,
981
+ sendJWT: true,
982
+ });
983
+ },
984
+
985
+ /**
986
+ * Moves items to a specific path within a project.
987
+ * @param {string} projectId - The ID of the project.
988
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
989
+ * @param {MoveItemsData} moveData - Data for moving items.
990
+ * @returns {Promise<{count: number}>} Object containing the count of moved items.
991
+ */
992
+ async moveItemsToPath(projectId: string, visibility: 'creator' | 'reviewer', moveData: MoveItemsData): Promise<MoveItemsResult> {
993
+ if (!projectId) throw new Error('projectId is required.');
994
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
995
+ return client._request<MoveItemsResult>({
996
+ method: 'PUT',
997
+ endpoint: `/v1/projects/${projectId}/files/${visibility}/move`,
998
+ body: moveData,
999
+ sendJWT: true,
1000
+ });
1001
+ },
1002
+
1003
+ /**
1004
+ * Copies items to a specific path within a project.
1005
+ * @param {string} projectId - The ID of the project.
1006
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
1007
+ * @param {CopyItemsData} copyData - Data for copying items.
1008
+ * @returns {Promise<{count: number}>} Object containing the count of copied items.
1009
+ */
1010
+ async copyItemsToPath(projectId: string, visibility: 'creator' | 'reviewer', copyData: CopyItemsData): Promise<{count: number}> {
1011
+ if (!projectId) throw new Error('projectId is required.');
1012
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
1013
+ return client._request<{count: number}>({
1014
+ method: 'PUT',
1015
+ endpoint: `/v1/projects/${projectId}/files/${visibility}/copy`,
1016
+ body: copyData,
1017
+ sendJWT: true,
1018
+ });
1019
+ },
1020
+
1021
+ /**
1022
+ * Deletes items at a specific path within a project.
1023
+ * @param {string} projectId - The ID of the project.
1024
+ * @param {'creator' | 'reviewer'} visibility - The visibility context ('creator' or 'reviewer').
1025
+ * @param {DeleteItemsData} deleteData - Data for deleting items.
1026
+ * @returns {Promise<{count: number}>} Object containing the count of deleted items.
1027
+ */
1028
+ async deleteItemsAtPath(projectId: string, visibility: 'creator' | 'reviewer', deleteData: DeleteItemsData): Promise<{count: number}> {
1029
+ if (!projectId) throw new Error('projectId is required.');
1030
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
1031
+ return client._request<{count: number}>({
1032
+ method: 'PUT',
1033
+ endpoint: `/v1/projects/${projectId}/files/${visibility}/delete`,
1034
+ body: deleteData,
1035
+ sendJWT: true,
1036
+ });
1037
+ },
1038
+
1039
+ /**
1040
+ * Asks what deleting these paths would reach, without deleting anything.
1041
+ *
1042
+ * Computed from the same cascade the delete runs, so the answer is what
1043
+ * will happen rather than an estimate of it. Only SECONDARY references
1044
+ * come back — the reviewer, submission and public-release copies that
1045
+ * would go with the selection.
1046
+ *
1047
+ * @param {string} projectId
1048
+ * @param {'creator'|'reviewer'} visibility
1049
+ * @param {DeleteItemsData} deleteData - The same body the delete takes.
1050
+ * @returns {Promise<DeleteImpact>}
1051
+ */
1052
+ async previewDeleteItemsAtPath(
1053
+ projectId: string,
1054
+ visibility: 'creator' | 'reviewer',
1055
+ deleteData: DeleteItemsData,
1056
+ ): Promise<DeleteImpact> {
1057
+ if (!projectId) throw new Error('projectId is required.');
1058
+ if (!visibility) throw new Error('visibility is required (creator or reviewer).');
1059
+ return client._request<DeleteImpact>({
1060
+ method: 'POST',
1061
+ endpoint: `/v1/projects/${projectId}/files/${visibility}/delete-preview`,
1062
+ body: deleteData,
1063
+ sendJWT: true,
1064
+ });
1065
+ },
1066
+
1067
+ // --- Public File System Methods ---
1068
+
1069
+ /**
1070
+ * Gets all public file systems for a project.
1071
+ * @param {string} projectId - The ID of the project.
1072
+ * @param {ListPublicFileSystemsParams} [params] - Query parameters (pagination, sort, search, status, creatorId).
1073
+ * @returns {Promise<PaginatedResponse<PublicFileSystemResponse>>} Paginated list of public file systems.
1074
+ */
1075
+ async getPublicFileSystems(projectId: string, params?: ListPublicFileSystemsParams): Promise<PaginatedResponse<PublicFileSystemResponse>> {
1076
+ if (!projectId) throw new Error('projectId is required.');
1077
+ return client._request<PaginatedResponse<PublicFileSystemResponse>>({
1078
+ method: 'GET',
1079
+ endpoint: `/v1/projects/${projectId}/public`,
1080
+ params: params,
1081
+ sendJWT: true,
1082
+ });
1083
+ },
1084
+
1085
+ /**
1086
+ * Get the public audit for a project — assets that are or have been publicly exposed.
1087
+ *
1088
+ * @requires `projectAdmin` or `projectOwner` on the project (or workspace-tier admin via inheritance).
1089
+ * @param {string} projectId
1090
+ * @param {Object} [params]
1091
+ * @param {boolean} [params.currentlyPublic=false] - When true, only assets currently public.
1092
+ * @param {number} [params.page]
1093
+ * @param {number} [params.limit]
1094
+ */
1095
+ async getPublicAudit(
1096
+ projectId: string,
1097
+ params?: { currentlyPublic?: boolean; page?: number; limit?: number },
1098
+ ): Promise<PaginatedResponse<PublicAuditAssetResponse>> {
1099
+ if (!projectId) throw new Error('projectId is required.');
1100
+ return client._request<PaginatedResponse<PublicAuditAssetResponse>>({
1101
+ method: 'GET',
1102
+ endpoint: `/v1/projects/${projectId}/public-audit`,
1103
+ params,
1104
+ sendJWT: true,
1105
+ });
1106
+ },
1107
+
1108
+ /**
1109
+ * Creates a public file system with a secure token for sharing project assets publicly.
1110
+ * @param {string} projectId - The ID of the project.
1111
+ * @param {CreatePublicFileSystemData} publicFileSystemData - Data for creating the public file system.
1112
+ * @returns {Promise<PublicFileSystemResponse>} The created public file system object.
1113
+ */
1114
+ async createPublicFileSystem(projectId: string, publicFileSystemData: CreatePublicFileSystemData): Promise<PublicFileSystemResponse> {
1115
+ if (!projectId) throw new Error('projectId is required.');
1116
+ return client._request<PublicFileSystemResponse>({
1117
+ method: 'POST',
1118
+ endpoint: `/v1/projects/${projectId}/public`,
1119
+ body: publicFileSystemData,
1120
+ sendJWT: true,
1121
+ });
1122
+ },
1123
+
1124
+ /**
1125
+ * Updates an existing public file system's title and description.
1126
+ * @param {string} projectId - The ID of the project.
1127
+ * @param {string} publicId - The ID of the public file system.
1128
+ * @param {UpdatePublicFileSystemData} updateData - Data to update.
1129
+ * @returns {Promise<PublicFileSystemResponse>} The updated public file system object.
1130
+ */
1131
+ async updatePublicFileSystem(projectId: string, publicId: string, updateData: UpdatePublicFileSystemData): Promise<PublicFileSystemResponse> {
1132
+ if (!projectId) throw new Error('projectId is required.');
1133
+ if (!publicId) throw new Error('publicId is required.');
1134
+ return client._request<PublicFileSystemResponse>({
1135
+ method: 'PUT',
1136
+ endpoint: `/v1/projects/${projectId}/public/${publicId}`,
1137
+ body: updateData,
1138
+ sendJWT: true,
1139
+ });
1140
+ },
1141
+
1142
+ /**
1143
+ * Releases a staged (unreleased) public file system, making it externally
1144
+ * accessible via its public token.
1145
+ * @param {string} projectId - The ID of the project.
1146
+ * @param {string} publicId - The ID of the public file system.
1147
+ * @returns {Promise<PublicFileSystemResponse>} The released public file system object.
1148
+ */
1149
+ async releasePublicFileSystem(projectId: string, publicId: string): Promise<PublicFileSystemResponse> {
1150
+ if (!projectId) throw new Error('projectId is required.');
1151
+ if (!publicId) throw new Error('publicId is required.');
1152
+ return client._request<PublicFileSystemResponse>({
1153
+ method: 'POST',
1154
+ endpoint: `/v1/projects/${projectId}/public/${publicId}/release`,
1155
+ sendJWT: true,
1156
+ });
1157
+ },
1158
+
1159
+ /**
1160
+ * Retrieves a specific public file system by its ID.
1161
+ * @param {string} projectId - The ID of the project.
1162
+ * @param {string} publicId - The ID of the public file system.
1163
+ * @returns {Promise<PublicFileSystemResponse>} The public file system object.
1164
+ */
1165
+ async getPublicFileSystem(projectId: string, publicId: string): Promise<PublicFileSystemResponse> {
1166
+ if (!projectId) throw new Error('projectId is required.');
1167
+ if (!publicId) throw new Error('publicId is required.');
1168
+ return client._request<PublicFileSystemResponse>({
1169
+ method: 'GET',
1170
+ endpoint: `/v1/projects/${projectId}/public/${publicId}`,
1171
+ sendJWT: true,
1172
+ });
1173
+ },
1174
+
1175
+ /**
1176
+ * Deletes a public file system and invalidates its access token.
1177
+ * @param {string} projectId - The ID of the project.
1178
+ * @param {string} publicId - The ID of the public file system.
1179
+ * @returns {Promise<PublicFileSystemResponse>} The deleted public release record.
1180
+ */
1181
+ async deletePublicFileSystem(projectId: string, publicId: string): Promise<PublicFileSystemResponse> {
1182
+ if (!projectId) throw new Error('projectId is required.');
1183
+ if (!publicId) throw new Error('publicId is required.');
1184
+ return client._request({
1185
+ method: 'DELETE',
1186
+ endpoint: `/v1/projects/${projectId}/public/${publicId}`,
1187
+ sendJWT: true,
1188
+ });
1189
+ },
1190
+
1191
+ /**
1192
+ * Adds additional items to an existing public file system.
1193
+ * @param {string} projectId - The ID of the project.
1194
+ * @param {string} publicId - The ID of the public file system.
1195
+ * @param {AddItemsToPublicFileSystemData} addItemsData - Data for adding items.
1196
+ * @returns {Promise<PublicFileSystemResponse>} The updated public file system object.
1197
+ */
1198
+ async addItemsToPublicFileSystem(projectId: string, publicId: string, addItemsData: AddItemsToPublicFileSystemData): Promise<PublicFileSystemResponse> {
1199
+ if (!projectId) throw new Error('projectId is required.');
1200
+ if (!publicId) throw new Error('publicId is required.');
1201
+ return client._request<PublicFileSystemResponse>({
1202
+ method: 'POST',
1203
+ endpoint: `/v1/projects/${projectId}/public/${publicId}/add`,
1204
+ body: addItemsData,
1205
+ sendJWT: true,
1206
+ });
1207
+ },
1208
+
1209
+ /**
1210
+ * Gets items from a public file system at a specific path (authenticated management).
1211
+ * @param {string} projectId - The ID of the project.
1212
+ * @param {string} token - The public access token.
1213
+ * @param {string} [path] - The path to get items from (optional, defaults to root).
1214
+ * @param {GetItemsAtPathParams} [params] - Query parameters for filtering and pagination.
1215
+ * @returns {Promise<PaginatedResponse<any>>} Paginated list of public file system items.
1216
+ */
1217
+ async getPublicItemsAtPath(projectId: string, token: string, path?: string, params?: GetItemsAtPathParams): Promise<PaginatedResponse<any>> {
1218
+ if (!projectId) throw new Error('projectId is required.');
1219
+ if (!token) throw new Error('token is required.');
1220
+
1221
+ let endpoint = `/v1/projects/${projectId}/public/${token}/files`;
1222
+ if (path && path.trim() !== '') {
1223
+ endpoint += `/${encodeURIComponent(path)}`;
1224
+ }
1225
+
1226
+ return client._request<PaginatedResponse<any>>({
1227
+ method: 'GET',
1228
+ endpoint,
1229
+ params: params,
1230
+ sendJWT: true,
1231
+ });
1232
+ },
1233
+
1234
+ /**
1235
+ * Moves items within a public file system (authenticated management).
1236
+ * @param {string} projectId - The ID of the project.
1237
+ * @param {string} token - The public access token.
1238
+ * @param {MovePublicItemsData} moveData - Data for moving items.
1239
+ * @returns {Promise<{count: number}>} Object containing the count of moved items.
1240
+ */
1241
+ async movePublicItemsAtPath(projectId: string, token: string, moveData: MovePublicItemsData): Promise<{count: number}> {
1242
+ if (!projectId) throw new Error('projectId is required.');
1243
+ if (!token) throw new Error('token is required.');
1244
+ return client._request<{count: number}>({
1245
+ method: 'PUT',
1246
+ endpoint: `/v1/projects/${projectId}/public/${token}/files/move`,
1247
+ body: moveData,
1248
+ sendJWT: true,
1249
+ });
1250
+ },
1251
+
1252
+ /**
1253
+ * Copies items within a public file system (authenticated management).
1254
+ * @param {string} projectId - The ID of the project.
1255
+ * @param {string} token - The public access token.
1256
+ * @param {CopyPublicItemsData} copyData - Data for copying items.
1257
+ * @returns {Promise<{count: number}>} Object containing the count of copied items.
1258
+ */
1259
+ async copyPublicItemsAtPath(projectId: string, token: string, copyData: CopyPublicItemsData): Promise<{count: number}> {
1260
+ if (!projectId) throw new Error('projectId is required.');
1261
+ if (!token) throw new Error('token is required.');
1262
+ return client._request<{count: number}>({
1263
+ method: 'PUT',
1264
+ endpoint: `/v1/projects/${projectId}/public/${token}/files/copy`,
1265
+ body: copyData,
1266
+ sendJWT: true,
1267
+ });
1268
+ },
1269
+
1270
+ /**
1271
+ * Deletes items from a public file system (authenticated management).
1272
+ * @param {string} projectId - The ID of the project.
1273
+ * @param {string} token - The public access token.
1274
+ * @param {DeletePublicItemsData} deleteData - Data for deleting items.
1275
+ * @returns {Promise<{count: number}>} Object containing the count of deleted items.
1276
+ */
1277
+ async deletePublicItemsAtPath(projectId: string, token: string, deleteData: DeletePublicItemsData): Promise<{count: number}> {
1278
+ if (!projectId) throw new Error('projectId is required.');
1279
+ if (!token) throw new Error('token is required.');
1280
+ return client._request<{count: number}>({
1281
+ method: 'PUT',
1282
+ endpoint: `/v1/projects/${projectId}/public/${token}/files/delete`,
1283
+ body: deleteData,
1284
+ sendJWT: true,
1285
+ });
1286
+ },
1287
+
1288
+ /**
1289
+ * Creates a folder inside a public file system (authenticated management).
1290
+ * @param {string} projectId - The ID of the project.
1291
+ * @param {string} token - The public access token.
1292
+ * @param {CreateFolderData} folderData - Data for creating the folder (name, color, basePath).
1293
+ * @returns {Promise<FolderResponse>} The created folder object.
1294
+ */
1295
+ async createPublicFolder(projectId: string, token: string, folderData: CreateFolderData): Promise<FolderResponse> {
1296
+ if (!projectId) throw new Error('projectId is required.');
1297
+ if (!token) throw new Error('token is required.');
1298
+ return client._request<FolderResponse>({
1299
+ method: 'POST',
1300
+ endpoint: `/v1/projects/${projectId}/public/${token}/files/create-folder`,
1301
+ body: folderData,
1302
+ sendJWT: true,
1303
+ });
1304
+ },
1305
+
1306
+ /**
1307
+ * Gets a public chat from an authenticated project context.
1308
+ * Unlike the public endpoint, this does NOT check token expiration.
1309
+ * Use this for internal management of public file systems.
1310
+ *
1311
+ * @param {string} projectId - The ID of the project.
1312
+ * @param {string} token - The public access token.
1313
+ * @returns {Promise<any>} The public chat or null if none exists.
1314
+ */
1315
+ async getProjectPublicChat(projectId: string, token: string): Promise<any> {
1316
+ if (!projectId) throw new Error('projectId is required.');
1317
+ if (!token) throw new Error('token is required.');
1318
+
1319
+ return client._request<any>({
1320
+ method: 'GET',
1321
+ endpoint: `/v1/projects/${projectId}/public/${token}/chat`,
1322
+ sendJWT: true,
1323
+ });
1324
+ },
1325
+
1326
+ /**
1327
+ * Gets a public asset with its public chat from an authenticated project context.
1328
+ * Unlike the public endpoint, this does NOT check token expiration.
1329
+ * Use this for internal management of public file systems.
1330
+ *
1331
+ * @param {string} projectId - The ID of the project.
1332
+ * @param {string} token - The public access token.
1333
+ * @param {string} assetId - The ID of the asset to retrieve.
1334
+ * @returns {Promise<PublicAssetResponse>} The asset with its public chat.
1335
+ */
1336
+ async getProjectPublicAsset(projectId: string, token: string, assetId: string): Promise<PublicAssetResponse> {
1337
+ if (!projectId) throw new Error('projectId is required.');
1338
+ if (!token) throw new Error('token is required.');
1339
+ if (!assetId) throw new Error('assetId is required.');
1340
+
1341
+ return client._request<PublicAssetResponse>({
1342
+ method: 'GET',
1343
+ endpoint: `/v1/projects/${projectId}/public/${token}/assets/${assetId}`,
1344
+ sendJWT: true,
1345
+ });
1346
+ },
1347
+
1348
+ /**
1349
+ * Gets messages from a public chat from an authenticated project context.
1350
+ * Unlike the public endpoint, this does NOT check token expiration.
1351
+ * Use this for internal management of public file systems.
1352
+ *
1353
+ * @param {string} projectId - The ID of the project.
1354
+ * @param {string} token - The public access token.
1355
+ * @param {string} chatId - The ID of the chat.
1356
+ * @param {GetPublicChatMessagesParams} [params] - Query parameters for pagination.
1357
+ * @returns {Promise<PublicChatMessagesResponse>} Paginated list of chat messages.
1358
+ */
1359
+ async getProjectPublicChatMessages(
1360
+ projectId: string,
1361
+ token: string,
1362
+ chatId: string,
1363
+ params?: GetPublicChatMessagesParams
1364
+ ): Promise<PublicChatMessagesResponse> {
1365
+ if (!projectId) throw new Error('projectId is required.');
1366
+ if (!token) throw new Error('token is required.');
1367
+ if (!chatId) throw new Error('chatId is required.');
1368
+
1369
+ return client._request<PublicChatMessagesResponse>({
1370
+ method: 'GET',
1371
+ endpoint: `/v1/projects/${projectId}/public/${token}/chat/${chatId}/messages`,
1372
+ params: params,
1373
+ sendJWT: true,
1374
+ });
1375
+ },
1376
+
1377
+ /**
1378
+ * Creates a message in an existing public chat from an authenticated project context.
1379
+ * Unlike the public endpoint, this does NOT check token expiration.
1380
+ *
1381
+ * @param {string} projectId - The ID of the project.
1382
+ * @param {string} token - The public access token.
1383
+ * @param {string} chatId - The ID of the chat.
1384
+ * @param {CreatePublicChatMessageRequest} data - Message data.
1385
+ * @returns {Promise<ChatMessage>} The created message.
1386
+ */
1387
+ async createProjectPublicChatMessage(
1388
+ projectId: string,
1389
+ token: string,
1390
+ chatId: string,
1391
+ data: CreatePublicChatMessageRequest
1392
+ ): Promise<ChatMessage> {
1393
+ if (!projectId) throw new Error('projectId is required.');
1394
+ if (!token) throw new Error('token is required.');
1395
+ if (!chatId) throw new Error('chatId is required.');
1396
+
1397
+ return client._request<ChatMessage>({
1398
+ method: 'POST',
1399
+ endpoint: `/v1/projects/${projectId}/public/${token}/chat/${chatId}/messages`,
1400
+ body: data,
1401
+ sendJWT: true,
1402
+ });
1403
+ },
1404
+
1405
+ /**
1406
+ * Creates a message on the main public topic chat from an authenticated project context.
1407
+ * Creates the chat lazily if it doesn't exist yet.
1408
+ * Unlike the public endpoint, this does NOT check token expiration.
1409
+ *
1410
+ * @param {string} projectId - The ID of the project.
1411
+ * @param {string} token - The public access token.
1412
+ * @param {CreatePublicChatMessageRequest} data - Message data.
1413
+ * @returns {Promise<CreatePublicAssetChatMessageResponse>} The chat and created message.
1414
+ */
1415
+ async createProjectPublicTopicChatMessage(
1416
+ projectId: string,
1417
+ token: string,
1418
+ data: CreatePublicChatMessageRequest
1419
+ ): Promise<CreatePublicAssetChatMessageResponse> {
1420
+ if (!projectId) throw new Error('projectId is required.');
1421
+ if (!token) throw new Error('token is required.');
1422
+
1423
+ return client._request<CreatePublicAssetChatMessageResponse>({
1424
+ method: 'POST',
1425
+ endpoint: `/v1/projects/${projectId}/public/${token}/chat/messages`,
1426
+ body: data,
1427
+ sendJWT: true,
1428
+ });
1429
+ },
1430
+
1431
+ /**
1432
+ * Creates a message on an asset's public chat from an authenticated project context.
1433
+ * Creates the chat lazily if it doesn't exist yet.
1434
+ * Unlike the public endpoint, this does NOT check token expiration.
1435
+ *
1436
+ * @param {string} projectId - The ID of the project.
1437
+ * @param {string} token - The public access token.
1438
+ * @param {string} assetId - The ID of the asset.
1439
+ * @param {CreatePublicChatMessageRequest} data - Message data.
1440
+ * @returns {Promise<CreatePublicAssetChatMessageResponse>} The chat and created message.
1441
+ */
1442
+ async createProjectPublicAssetChatMessage(
1443
+ projectId: string,
1444
+ token: string,
1445
+ assetId: string,
1446
+ data: CreatePublicChatMessageRequest
1447
+ ): Promise<CreatePublicAssetChatMessageResponse> {
1448
+ if (!projectId) throw new Error('projectId is required.');
1449
+ if (!token) throw new Error('token is required.');
1450
+ if (!assetId) throw new Error('assetId is required.');
1451
+
1452
+ return client._request<CreatePublicAssetChatMessageResponse>({
1453
+ method: 'POST',
1454
+ endpoint: `/v1/projects/${projectId}/public/${token}/assets/${assetId}/messages`,
1455
+ body: data,
1456
+ sendJWT: true,
1457
+ });
1458
+ },
1459
+
1460
+ // --- Highlighted Messages ---
1461
+
1462
+ /**
1463
+ * Lists a project's assets for one visibility tier.
1464
+ * `creator` requires `canGetCreatorAssets`; `reviewer` requires `canGetReviewerAssets`.
1465
+ * @param {string} projectId - The project ID.
1466
+ * @param {'creator'|'reviewer'} visibility - Which tier's assets to list.
1467
+ * @param {ListAssetsParams} [params] - Filters and pagination. See ListAssetsParams.
1468
+ * @returns {Promise<PaginatedResponse<AssetResponse>>} Paginated assets.
1469
+ * @throws {Error} 'projectId is required.' or 'visibility is required.'.
1470
+ */
1471
+ async getAssets(projectId: string, visibility: 'creator' | 'reviewer', params?: ListAssetsParams): Promise<PaginatedResponse<AssetResponse>> {
1472
+ if (!projectId) throw new Error('projectId is required.');
1473
+ if (!visibility) throw new Error('visibility is required.');
1474
+ return client._request<PaginatedResponse<AssetResponse>>({
1475
+ method: 'GET',
1476
+ endpoint: `/v1/projects/${projectId}/assets/${visibility}`,
1477
+ params: params,
1478
+ sendJWT: true,
1479
+ });
1480
+ },
1481
+
1482
+ /**
1483
+ * Lists highlighted chat messages across a project for one visibility tier (cursor pagination only).
1484
+ * `creator` requires `canGetCreatorHighlights`; `reviewer` requires `canGetReviewerHighlights`.
1485
+ * @param {string} projectId - The project ID.
1486
+ * @param {'creator'|'reviewer'} visibility - Which tier's highlights to list.
1487
+ * @param {GetHighlightedMessagesParams} [params] - Cursor pagination. See GetHighlightedMessagesParams.
1488
+ * @returns {Promise<PaginatedResponse<ChatMessage>>} Paginated highlighted messages.
1489
+ * @throws {Error} 'projectId is required.' or 'visibility is required.'.
1490
+ */
1491
+ async getHighlightedMessages(projectId: string, visibility: 'creator' | 'reviewer', params?: GetHighlightedMessagesParams): Promise<PaginatedResponse<ChatMessage>> {
1492
+ if (!projectId) throw new Error('projectId is required.');
1493
+ if (!visibility) throw new Error('visibility is required.');
1494
+ return client._request<PaginatedResponse<ChatMessage>>({
1495
+ method: 'GET',
1496
+ endpoint: `/v1/projects/${projectId}/${visibility}/highlighted-messages`,
1497
+ params: params,
1498
+ sendJWT: true,
1499
+ });
1500
+ },
1501
+
1502
+ /**
1503
+ * Top-N assets in a project by access-activity event type (plays, downloads, embeds).
1504
+ * Requires project read access. Returns asset IDs and counts only; hydrate names and
1505
+ * thumbnails through the normal asset fetch path.
1506
+ * @param {string} projectId - The project ID.
1507
+ * @param {object} [params] - `range` ('7d' | '30d' | '90d'), `eventType`, `limit`.
1508
+ * @returns {Promise<ProjectTopAccessActivityResponse>} Ranked asset IDs with counts.
1509
+ * @throws {Error} 'projectId is required.' when `projectId` is falsy.
1510
+ */
1511
+ async getTopAccessActivity(
1512
+ projectId: string,
1513
+ params?: {
1514
+ range?: '7d' | '30d' | '90d';
1515
+ eventType?: 'play_started' | 'play_completed' | 'download' | 'embed_resolved';
1516
+ limit?: number;
1517
+ },
1518
+ ): Promise<ProjectTopAccessActivityResponse> {
1519
+ if (!projectId) throw new Error('projectId is required.');
1520
+ return client._request<ProjectTopAccessActivityResponse>({
1521
+ method: 'GET',
1522
+ endpoint: `/v1/projects/${projectId}/access-activity/top-assets`,
1523
+ params,
1524
+ sendJWT: true,
1525
+ });
1526
+ },
1527
+ };
1528
+ }