@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,83 @@
1
+ import NuramaClient from '../NuramaClient.js';
2
+
3
+ // --- Resource Type Enum ---
4
+ export type ResourceType = 'user' | 'workspace' | 'project' | 'chat' | 'asset';
5
+
6
+ // --- Query Parameter Interfaces ---
7
+ export interface GetStorageChartParams {
8
+ startDate?: number; // Unix timestamp (ms) or similar number format expected by backend
9
+ endDate?: number; // Unix timestamp (ms) or similar number format expected by backend
10
+ aggregationPeriod?: 'year' | 'month' | 'week' | 'day';
11
+ }
12
+
13
+ // --- Response Interfaces ---
14
+ export interface ChartDataEntry {
15
+ period: string; // e.g., "YYYY-MM-DD", "YYYY-W##", "YYYY-MM", "YYYY"
16
+ averageSizeInBytes: number;
17
+ }
18
+
19
+ export type ChartDataResponse = ChartDataEntry[];
20
+
21
+ export interface StorageRecord {
22
+ resourceId: string;
23
+ resourceType: ResourceType;
24
+ sizeInBytes: number;
25
+ id: string; // The ID of the storage record itself
26
+ }
27
+
28
+ // --- Method Definitions ---
29
+
30
+ /**
31
+ * Defines storage-related methods for the NuramaClient.
32
+ * @param {NuramaClient} client - The NuramaClient instance.
33
+ * @returns {object} An object containing the storage-related methods.
34
+ */
35
+ export default function createStorageMethods(client: NuramaClient) {
36
+ return {
37
+ /**
38
+ * Retrieves storage usage chart data for a specific resource.
39
+ * Requires authentication and permission.
40
+ * @param {ResourceType} resourceType - The type of the resource.
41
+ * @param {string} resourceId - The ID of the resource.
42
+ * @param {GetStorageChartParams} [params] - Optional query parameters for date range and aggregation.
43
+ * @returns {Promise<ChartDataResponse>} An array of chart data entries.
44
+ */
45
+ async getStorageChart(
46
+ resourceType: ResourceType,
47
+ resourceId: string,
48
+ params?: GetStorageChartParams
49
+ ): Promise<ChartDataResponse> {
50
+ if (!resourceType) throw new Error('resourceType is required.');
51
+ if (!resourceId) throw new Error('resourceId is required.');
52
+ return client._request<ChartDataResponse>({
53
+ method: 'GET',
54
+ endpoint: `/v1/storage/chart/${resourceType}/${resourceId}`,
55
+ params,
56
+ sendJWT: true,
57
+ });
58
+ },
59
+
60
+ /**
61
+ * Retrieves the latest storage record for a specific resource.
62
+ * Requires authentication and permission.
63
+ * @param {ResourceType} resourceType - The type of the resource.
64
+ * @param {string} resourceId - The ID of the resource.
65
+ * @returns {Promise<StorageRecord>} The latest storage record for the resource.
66
+ */
67
+ async getStorageRecord(
68
+ resourceType: ResourceType,
69
+ resourceId: string
70
+ ): Promise<StorageRecord> {
71
+ if (!resourceType) throw new Error('resourceType is required.');
72
+ if (!resourceId) throw new Error('resourceId is required.');
73
+ return client._request<StorageRecord>({
74
+ method: 'GET',
75
+ endpoint: `/v1/storage/${resourceType}/${resourceId}`,
76
+ sendJWT: true,
77
+ });
78
+ },
79
+ };
80
+ }
81
+
82
+ // --- Export Method Type ---
83
+ export type StorageMethods = ReturnType<typeof createStorageMethods>;
@@ -0,0 +1,307 @@
1
+ import NuramaClient from '../NuramaClient.js';
2
+ import { type Subscription } from '@nurama/types'; // Import Subscription type
3
+
4
+ // --- Common Interfaces (Should be shared) ---
5
+ export interface SortParams {
6
+ sort?: Record<string, 1 | -1>;
7
+ }
8
+
9
+ export type SubscriptionStatus = 'active' | 'pending' | 'canceled' | 'expired' | 'pastDue' | 'paused' | 'paymentFailed' | 'unpaid';
10
+
11
+ /**
12
+ * Soft warnings returned by a plan swap / dry-run. STRUCTURED (not localized
13
+ * strings) so the multi-lingual FE renders the copy from these values.
14
+ */
15
+ export type PlanChangeWarning =
16
+ | { type: 'capabilityRemoved'; capability: string }
17
+ | {
18
+ type: 'seatMigration';
19
+ currentSeats: number;
20
+ unitPrice: number | null;
21
+ total: number | null;
22
+ currency: string;
23
+ period: 'month' | 'year';
24
+ };
25
+
26
+ // --- Query Parameter Interfaces ---
27
+ export interface GetSubscriptionsParams extends SortParams {
28
+ status?: SubscriptionStatus;
29
+ limit?: number;
30
+ page?: number;
31
+ }
32
+
33
+ export interface CreateWorkspaceOrderParams {
34
+ productId: string;
35
+ quantity: number;
36
+ /**
37
+ * Customer-chosen purchase amount in the subscription's currency MINOR
38
+ * unit (pence for GBP, cents for USD, yen for JPY, etc.). Required for
39
+ * variable-amount products (currently only the AI add-on, `productType:
40
+ * 'enableAi'`). Server enforces a per-currency minimum.
41
+ */
42
+ amountInMinor?: number;
43
+ }
44
+
45
+ export interface GetSubscriptionOrdersParams {
46
+ limit?: number;
47
+ page?: number;
48
+ sortBy?: string;
49
+ }
50
+
51
+ // --- Response Interfaces (based on YAML and tests) ---
52
+ // Subscription type is imported from nurama-types
53
+
54
+ // Keep local definitions for these as they are not in nurama-types
55
+ export interface ResourceLimits {
56
+ totalStorageInBytes: number;
57
+ totalSeats: number;
58
+ totalCredits: number;
59
+ }
60
+
61
+ export interface SeatUsage {
62
+ totalSeats: number;
63
+ usedSeats: number;
64
+ availableSeats: number;
65
+ }
66
+
67
+ export interface RoleSeatUsage {
68
+ /** Distinct users occupying this seat type across the workspace + projects. */
69
+ used: number;
70
+ /** Plan cap for this seat type, or `null` when the plan is unlimited for it. */
71
+ limit: number | null;
72
+ }
73
+
74
+ export interface RoleUsage {
75
+ creators: RoleSeatUsage;
76
+ reviewers: RoleSeatUsage;
77
+ }
78
+
79
+ export interface StorageUsage {
80
+ totalStorageInBytes: number;
81
+ usedStorageInBytes: number;
82
+ availableStorageInBytes: number;
83
+ }
84
+
85
+ // --- Method Definitions ---
86
+
87
+ /**
88
+ * Defines subscription-related methods for the NuramaClient.
89
+ * @param {NuramaClient} client - The NuramaClient instance.
90
+ * @returns {object} An object containing the subscription-related methods.
91
+ */
92
+ export default function createSubscriptionMethods(client: NuramaClient) {
93
+ return {
94
+ /**
95
+ * Retrieves the active subscription for a specific workspace.
96
+ * Requires authentication and permission.
97
+ * @param {string} workspaceId - The ID of the workspace.
98
+ * @returns {Promise<Subscription>} The workspace subscription object.
99
+ */
100
+ async getWorkspaceSubscription(workspaceId: string): Promise<Subscription> {
101
+ if (!workspaceId) throw new Error('workspaceId is required.');
102
+ return client._request<Subscription>({
103
+ method: 'GET',
104
+ endpoint: `/v1/subscriptions/workspace/${workspaceId}`,
105
+ sendJWT: true,
106
+ });
107
+ },
108
+
109
+ /**
110
+ * Cancels the subscription for a specific workspace.
111
+ * Requires authentication and permission.
112
+ * @param {string} workspaceId - The ID of the workspace.
113
+ * @returns {Promise<any>} The cancellation response.
114
+ */
115
+ async cancelWorkspaceSubscription(workspaceId: string): Promise<any> {
116
+ if (!workspaceId) throw new Error('workspaceId is required.');
117
+ return client._request<any>({
118
+ method: 'DELETE',
119
+ endpoint: `/v1/subscriptions/workspace/${workspaceId}`,
120
+ sendJWT: true,
121
+ });
122
+ },
123
+
124
+ /**
125
+ * Reverse a scheduled (period-end) cancellation, keeping the workspace's
126
+ * subscription on its normal renewal cycle. Only valid while the
127
+ * subscription is still active with a pending cancellation; a fully
128
+ * lapsed subscription can't be resumed (the owner must re-subscribe).
129
+ * Requires authentication and permission.
130
+ * @param {string} workspaceId - The ID of the workspace.
131
+ * @returns {Promise<any>} The resume response.
132
+ */
133
+ async resumeWorkspaceSubscription(workspaceId: string): Promise<any> {
134
+ if (!workspaceId) throw new Error('workspaceId is required.');
135
+ return client._request<any>({
136
+ method: 'POST',
137
+ endpoint: `/v1/subscriptions/workspace/${workspaceId}/resume`,
138
+ sendJWT: true,
139
+ });
140
+ },
141
+
142
+ /**
143
+ * Swap the workspace's active basePlan line for a different basePlan product.
144
+ * Same code path both upgrades and downgrades; the API's pre-flight
145
+ * capacity check is what distinguishes a permitted change from a refused
146
+ * one. Pass `dryRun: true` to get the pre-flight verdict without mutating.
147
+ *
148
+ * On over-allocation the API returns 400 `planCapacityInsufficient` with
149
+ * `errorData.violations: [{ resource, current, newLimit }]`, surfaced via
150
+ * the SDK's normal error path.
151
+ *
152
+ * On success, returns the updated subscription plus a `warnings[]` array
153
+ * of feature-gate capabilities the destination plan does NOT include (the
154
+ * FE renders these as a confirmation notice).
155
+ */
156
+ async swapWorkspacePlan(workspaceId: string, params: {
157
+ newProductId: string;
158
+ currency: string;
159
+ billingPeriod: 'month' | 'year';
160
+ dryRun?: boolean;
161
+ }): Promise<{ subscription: Subscription | null; warnings: PlanChangeWarning[] }> {
162
+ if (!workspaceId) throw new Error('workspaceId is required.');
163
+ if (!params.newProductId) throw new Error('newProductId is required.');
164
+ if (!params.currency) throw new Error('currency is required.');
165
+ if (!params.billingPeriod) throw new Error('billingPeriod is required.');
166
+ return client._request<{ subscription: Subscription | null; warnings: PlanChangeWarning[] }>({
167
+ method: 'PUT',
168
+ endpoint: `/v1/subscriptions/workspace/${workspaceId}/plan`,
169
+ body: params,
170
+ sendJWT: true,
171
+ });
172
+ },
173
+
174
+ /**
175
+ * Retrieves subscription orders for a specific workspace.
176
+ * Requires authentication and permission.
177
+ * @param {string} workspaceId - The ID of the workspace.
178
+ * @param {GetSubscriptionOrdersParams} [params] - Optional query parameters.
179
+ * @returns {Promise<any[]>} An array of subscription order objects.
180
+ */
181
+ async getWorkspaceOrders(workspaceId: string, params?: GetSubscriptionOrdersParams): Promise<any[]> {
182
+ if (!workspaceId) throw new Error('workspaceId is required.');
183
+ return client._request<any[]>({
184
+ method: 'GET',
185
+ endpoint: `/v1/subscriptions/workspace/${workspaceId}/orders`,
186
+ params,
187
+ sendJWT: true,
188
+ });
189
+ },
190
+
191
+ /**
192
+ * Creates a subscription order for a specific workspace.
193
+ * Requires authentication and permission.
194
+ * @param {string} workspaceId - The ID of the workspace.
195
+ * @param {CreateWorkspaceOrderParams} orderData - The order data.
196
+ * @returns {Promise<any>} The created order response.
197
+ */
198
+ async createWorkspaceOrder(workspaceId: string, orderData: CreateWorkspaceOrderParams): Promise<any> {
199
+ if (!workspaceId) throw new Error('workspaceId is required.');
200
+ if (!orderData.productId) throw new Error('productId is required.');
201
+ if (typeof orderData.quantity !== 'number') throw new Error('quantity is required and must be a number.');
202
+
203
+ return client._request<any>({
204
+ method: 'POST',
205
+ endpoint: `/v1/subscriptions/workspace/${workspaceId}/order`,
206
+ body: orderData,
207
+ sendJWT: true,
208
+ });
209
+ },
210
+
211
+ /**
212
+ * Retrieves all subscriptions owned by the currently authenticated user.
213
+ * Requires authentication.
214
+ * @param {GetSubscriptionsParams} [params] - Optional query parameters for status and sorting.
215
+ * @returns {Promise<Subscription[]>} An array of subscription objects.
216
+ */
217
+ async getUserSubscriptions(params?: GetSubscriptionsParams): Promise<Subscription[]> {
218
+ return client._request<Subscription[]>({
219
+ method: 'GET',
220
+ endpoint: '/v1/subscriptions/',
221
+ params,
222
+ sendJWT: true,
223
+ });
224
+ },
225
+
226
+ /**
227
+ * Retrieves the resource limits (e.g., storage, seats) for a specific resource (typically workspace).
228
+ * Requires authentication.
229
+ * @param {string} resourceId - The ID of the resource (e.g., workspaceId).
230
+ * @returns {Promise<ResourceLimits>} An object containing the resource limits.
231
+ */
232
+ async getResourceLimits(resourceId: string): Promise<ResourceLimits> {
233
+ if (!resourceId) throw new Error('resourceId is required.');
234
+ // Note: Backend route uses /limits/:resourceId, validation uses resourceId
235
+ // Endpoint in test file is not hit for limits directly, assuming workspace ID based on context
236
+ return client._request<ResourceLimits>({
237
+ method: 'GET',
238
+ endpoint: `/v1/subscriptions/limits/${resourceId}`, // Assuming resourceId here is workspaceId
239
+ sendJWT: true,
240
+ });
241
+ },
242
+
243
+ /**
244
+ * Retrieves the seat usage for a specific resource (typically workspace).
245
+ * Requires authentication.
246
+ * @param {string} resourceId - The ID of the resource (e.g., workspaceId).
247
+ * @returns {Promise<SeatUsage>} An object containing seat usage details.
248
+ */
249
+ async getSeatUsage(resourceId: string): Promise<SeatUsage> {
250
+ if (!resourceId) throw new Error('resourceId is required.');
251
+ return client._request<SeatUsage>({
252
+ method: 'GET',
253
+ endpoint: `/v1/subscriptions/usage/seats/${resourceId}`, // Assuming resourceId here is workspaceId
254
+ sendJWT: true,
255
+ });
256
+ },
257
+
258
+ /**
259
+ * Retrieves per-role (creator / reviewer) seat usage and caps for a
260
+ * workspace. `limit` is `null` when the plan is unlimited for that
261
+ * seat type. Requires authentication.
262
+ * @param {string} resourceId - The workspace ID.
263
+ * @returns {Promise<RoleUsage>} Creator- and reviewer-side seat usage.
264
+ */
265
+ async getRoleUsage(resourceId: string): Promise<RoleUsage> {
266
+ if (!resourceId) throw new Error('resourceId is required.');
267
+ return client._request<RoleUsage>({
268
+ method: 'GET',
269
+ endpoint: `/v1/subscriptions/usage/roles/${resourceId}`,
270
+ sendJWT: true,
271
+ });
272
+ },
273
+
274
+ /**
275
+ * Retrieves the storage usage for a specific resource (typically workspace).
276
+ * Requires authentication.
277
+ * @param {string} resourceId - The ID of the resource (e.g., workspaceId).
278
+ * @returns {Promise<StorageUsage>} An object containing storage usage details.
279
+ */
280
+ async getStorageUsage(resourceId: string): Promise<StorageUsage> {
281
+ if (!resourceId) throw new Error('resourceId is required.');
282
+ return client._request<StorageUsage>({
283
+ method: 'GET',
284
+ endpoint: `/v1/subscriptions/usage/storage/${resourceId}`, // Assuming resourceId here is workspaceId
285
+ sendJWT: true,
286
+ });
287
+ },
288
+
289
+ /**
290
+ * Retrieves the workspace usage summary (billable seats and storage used).
291
+ * Requires authentication and subscription management permission.
292
+ * @param {string} workspaceId - The ID of the workspace.
293
+ * @returns {Promise<{billableSeatCount: number; storageUsedInBytes: number}>} Usage summary.
294
+ */
295
+ async getWorkspaceUsageSummary(workspaceId: string): Promise<{
296
+ billableSeatCount: number;
297
+ storageUsedInBytes: number;
298
+ }> {
299
+ if (!workspaceId) throw new Error('workspaceId is required.');
300
+ return client._request({
301
+ method: 'GET',
302
+ endpoint: `/v1/subscriptions/workspace/${workspaceId}/usage-summary`,
303
+ sendJWT: true,
304
+ });
305
+ },
306
+ };
307
+ }
@@ -0,0 +1,62 @@
1
+ import NuramaClient from '../NuramaClient.js';
2
+ import type {
3
+ SupportChatGetTopicResponse,
4
+ SupportChatCreateAttachmentRequest,
5
+ SupportChatCreateAttachmentResponse,
6
+ } from '@nurama/types';
7
+
8
+ /**
9
+ * Nurama Support chat — one topic per user on the `/news` page.
10
+ *
11
+ * The surface is intentionally tiny: one endpoint that lazily creates
12
+ * the user's support topic on first call and returns the existing row
13
+ * on every subsequent call. There is no list / archive / delete — each
14
+ * user has exactly one support conversation that persists across visits.
15
+ *
16
+ * Messages flow through the regular chat endpoints on
17
+ * `nuramaClient.chat`:
18
+ *
19
+ * - send: `nuramaClient.chat.createMessage(topic.chatId, { content })`
20
+ * - list: `nuramaClient.chat.getMessages(topic.chatId, …)`
21
+ *
22
+ * Backend gates: `auth → requireGlobalSupportChatEnabled → supportChatLimiter`.
23
+ * Unmetered (no credit deduction) — abuse is bounded by the per-user
24
+ * per-day rate limiter, not a credit balance check.
25
+ */
26
+ export default function createSupportChatMethods(client: NuramaClient) {
27
+ return {
28
+ /**
29
+ * Get-or-create the caller's Support topic. Idempotent: re-calling
30
+ * returns the same row, so this is safe to invoke on every page mount.
31
+ */
32
+ async getTopic(): Promise<SupportChatGetTopicResponse> {
33
+ return client._request({
34
+ endpoint: '/v1/ai/support-chat/topic',
35
+ method: 'GET',
36
+ sendJWT: true,
37
+ });
38
+ },
39
+
40
+ /**
41
+ * Mint a Scratch upload bundle for one image attachment. The bytes
42
+ * land in a Scratch row with a 72-hour TTL and are read by the
43
+ * orchestrator's vision pass on the next user message — never
44
+ * promoted to a permanent Asset.
45
+ *
46
+ * Same upload protocol as every other multipart upload on the
47
+ * platform: call this, multipart-upload the bytes to `urls`, then
48
+ * call `nuramaClient.scratch.completeUpload(scratchId, { uploadId, parts })`.
49
+ * Send the message with `attachments: [{ scratchId, name }]`.
50
+ */
51
+ async createAttachment(
52
+ data: SupportChatCreateAttachmentRequest,
53
+ ): Promise<SupportChatCreateAttachmentResponse> {
54
+ return client._request({
55
+ endpoint: '/v1/ai/support-chat/attachments',
56
+ method: 'POST',
57
+ body: data,
58
+ sendJWT: true,
59
+ });
60
+ },
61
+ };
62
+ }
@@ -0,0 +1,114 @@
1
+ import NuramaClient from '../NuramaClient.js';
2
+
3
+ export type SupportTicketScope = 'user' | 'workspace' | 'project';
4
+ export type SupportTicketStatus = 'open' | 'pending' | 'resolved' | 'closed';
5
+
6
+ export interface CreateSupportTicketRequest {
7
+ scopeType: SupportTicketScope;
8
+ /** Required for workspace/project scope; ignored for user scope. */
9
+ scopeId?: string;
10
+ subject: string;
11
+ body: string;
12
+ /** Browser/app/device snapshot collected at submit time. */
13
+ deviceInfo?: Record<string, unknown>;
14
+ /**
15
+ * `true` when the ticket was drafted by Nu via the
16
+ * `create_support_ticket` chat tool and submitted by the user from
17
+ * the pre-populated SupportTicketCreateModal. Stamped onto the
18
+ * `SupportTicket` row for ops analytics; the FE sets this when the
19
+ * modal was opened by an AI-draft CTA.
20
+ */
21
+ aiGenerated?: boolean;
22
+ }
23
+
24
+ export interface SupportTicket {
25
+ id: string;
26
+ ticketNumber: number;
27
+ subject: string;
28
+ scopeType: SupportTicketScope;
29
+ scopeId: string | null;
30
+ creatorId: string;
31
+ status: SupportTicketStatus;
32
+ priority: string;
33
+ chatId: string;
34
+ deviceInfo: Record<string, unknown>;
35
+ /** True for tickets drafted by Nu's `create_support_ticket` tool. */
36
+ aiGenerated: boolean;
37
+ createdAt: string;
38
+ updatedAt: string;
39
+ }
40
+
41
+ export interface SupportTicketListParams {
42
+ status?: SupportTicketStatus;
43
+ page?: number;
44
+ limit?: number;
45
+ }
46
+
47
+ export interface SupportTicketListResponse {
48
+ results: SupportTicket[];
49
+ page: number;
50
+ limit: number;
51
+ totalPages: number;
52
+ totalResults: number;
53
+ }
54
+
55
+ /** A logo asset (thumbnail-ready) attached to a scope for avatar rendering. */
56
+ export type SupportTicketScopeLogo = { files?: unknown[]; [key: string]: unknown } | null;
57
+
58
+ export interface SupportTicketScopeOptions {
59
+ workspaces: { id: string; name: string; slug: string; color?: string | null; logo?: SupportTicketScopeLogo }[];
60
+ projects: { id: string; name: string; slug: string | null; workspaceId: string; color?: string | null; logo?: SupportTicketScopeLogo }[];
61
+ }
62
+
63
+ /**
64
+ * Support tickets. A ticket carries the metadata + a backing Chat thread; the
65
+ * conversation itself is sent/read through the regular chat endpoints:
66
+ *
67
+ * - send: `nuramaClient.chat.createMessage(ticket.chatId, …)`
68
+ * - read: `nuramaClient.chat.getMessages(ticket.chatId, …)`
69
+ *
70
+ * Nurama customer service replies (as the support persona) from the admin site.
71
+ */
72
+ export default function createSupportTicketMethods(client: NuramaClient) {
73
+ const buildQuery = (params: Record<string, unknown> = {}): string => {
74
+ const search = new URLSearchParams();
75
+ for (const [key, value] of Object.entries(params)) {
76
+ if (value === undefined || value === null || value === '') continue;
77
+ search.set(key, String(value));
78
+ }
79
+ const query = search.toString();
80
+ return query ? `?${query}` : '';
81
+ };
82
+
83
+ return {
84
+ /** Create a ticket. The opening message body becomes the first thread entry. */
85
+ async createSupportTicket(data: CreateSupportTicketRequest): Promise<SupportTicket> {
86
+ if (!data?.scopeType) throw new Error('scopeType is required.');
87
+ if (data.scopeType !== 'user' && !data.scopeId) {
88
+ throw new Error('scopeId is required for workspace/project scope.');
89
+ }
90
+ if (!data?.subject) throw new Error('subject is required.');
91
+ if (!data?.body) throw new Error('body is required.');
92
+ return client._request({ endpoint: '/v1/support-tickets', method: 'POST', body: data, sendJWT: true });
93
+ },
94
+
95
+ /** List the caller's own tickets + (for resource admins) tickets in their scope. */
96
+ async listSupportTickets(params: SupportTicketListParams = {}): Promise<SupportTicketListResponse> {
97
+ return client._request({ endpoint: `/v1/support-tickets${buildQuery(params as Record<string, unknown>)}`, method: 'GET', sendJWT: true });
98
+ },
99
+
100
+ async getSupportTicket(ticketId: string): Promise<SupportTicket> {
101
+ if (!ticketId) throw new Error('ticketId is required.');
102
+ return client._request({
103
+ endpoint: `/v1/support-tickets/${encodeURIComponent(ticketId)}`,
104
+ method: 'GET',
105
+ sendJWT: true,
106
+ });
107
+ },
108
+
109
+ /** Workspaces/projects the caller may scope a new ticket to. */
110
+ async getSupportTicketScopeOptions(): Promise<SupportTicketScopeOptions> {
111
+ return client._request({ endpoint: '/v1/support-tickets/scope-options', method: 'GET', sendJWT: true });
112
+ },
113
+ };
114
+ }
@@ -0,0 +1,131 @@
1
+ import NuramaClient from '../NuramaClient.js';
2
+ import { type Tag, type TagOwnerResourceType } from '@nurama/types';
3
+
4
+ /**
5
+ * Data required to create a new tag
6
+ */
7
+ export interface CreateTagData {
8
+ /** The name of the tag */
9
+ name: string;
10
+
11
+ /** The type of resource that will own this tag */
12
+ ownerResourceType: TagOwnerResourceType;
13
+
14
+ /** The ID of the resource that will own this tag */
15
+ ownerResourceId: string;
16
+
17
+ /** Optional hex color code for the tag. If not provided, a color will be assigned automatically */
18
+ color?: string;
19
+ }
20
+
21
+ /**
22
+ * Data for updating an existing tag
23
+ */
24
+ export interface UpdateTagData {
25
+ /** The new name for the tag */
26
+ name?: string;
27
+
28
+ /** The new hex color code for the tag */
29
+ color?: string;
30
+ }
31
+
32
+ /**
33
+ * Parameters for getting tags for a resource
34
+ */
35
+ export interface GetTagsParams {
36
+ /** Filter tags by partial name match (case-insensitive) */
37
+ name?: string;
38
+
39
+ /** Sort tags by field */
40
+ sortBy?: 'name' | 'createdAt' | 'updatedAt';
41
+ }
42
+
43
+ /**
44
+ * Array of tags
45
+ */
46
+ export type Tags = Tag[];
47
+
48
+ /**
49
+ * Defines tag-related methods for the NuramaClient.
50
+ * @param {NuramaClient} client - The NuramaClient instance.
51
+ * @returns {object} An object containing the tag-related methods.
52
+ */
53
+ export default function createTagMethods(client: NuramaClient) {
54
+ return {
55
+ /**
56
+ * Creates a new tag for a specific resource.
57
+ * @param {CreateTagData} tagData - The tag data to create.
58
+ * @returns {Promise<Tag>} The created tag object.
59
+ */
60
+ async createTag(tagData: CreateTagData): Promise<Tag> {
61
+ if (!tagData.name) throw new Error('Tag name is required.');
62
+ if (!tagData.ownerResourceType) throw new Error('Owner resource type is required.');
63
+ if (!tagData.ownerResourceId) throw new Error('Owner resource ID is required.');
64
+
65
+ return client._request<Tag>({
66
+ method: 'POST',
67
+ endpoint: '/v1/tags',
68
+ body: tagData,
69
+ sendJWT: true,
70
+ });
71
+ },
72
+
73
+ /**
74
+ * Retrieves all tags for a specific resource.
75
+ * @param {TagOwnerResourceType} ownerResourceType - The type of resource to get tags for.
76
+ * @param {string} ownerResourceId - The ID of the resource to get tags for.
77
+ * @param {GetTagsParams} [params] - Optional parameters for filtering and sorting.
78
+ * @returns {Promise<Tags>} Array of tag objects.
79
+ */
80
+ async getTags(
81
+ ownerResourceType: TagOwnerResourceType,
82
+ ownerResourceId: string,
83
+ params?: GetTagsParams
84
+ ): Promise<Tags> {
85
+ if (!ownerResourceType) throw new Error('Owner resource type is required.');
86
+ if (!ownerResourceId) throw new Error('Owner resource ID is required.');
87
+
88
+ return client._request<Tags>({
89
+ method: 'GET',
90
+ endpoint: `/v1/tags/${ownerResourceType}/${ownerResourceId}`,
91
+ params,
92
+ sendJWT: true,
93
+ });
94
+ },
95
+
96
+ /**
97
+ * Updates an existing tag.
98
+ * @param {string} tagId - The ID of the tag to update.
99
+ * @param {UpdateTagData} updateData - The data to update.
100
+ * @returns {Promise<Tag>} The updated tag object.
101
+ */
102
+ async updateTag(tagId: string, updateData: UpdateTagData): Promise<Tag> {
103
+ if (!tagId) throw new Error('Tag ID is required.');
104
+ if (!updateData.name && !updateData.color) {
105
+ throw new Error('At least one field (name or color) must be provided for update.');
106
+ }
107
+
108
+ return client._request<Tag>({
109
+ method: 'PUT',
110
+ endpoint: `/v1/tags/${tagId}`,
111
+ body: updateData,
112
+ sendJWT: true,
113
+ });
114
+ },
115
+
116
+ /**
117
+ * Deletes a tag permanently.
118
+ * @param {string} tagId - The ID of the tag to delete.
119
+ * @returns {Promise<Tag>} The deleted tag object.
120
+ */
121
+ async deleteTag(tagId: string): Promise<Tag> {
122
+ if (!tagId) throw new Error('Tag ID is required.');
123
+
124
+ return client._request<Tag>({
125
+ method: 'DELETE',
126
+ endpoint: `/v1/tags/${tagId}`,
127
+ sendJWT: true,
128
+ });
129
+ },
130
+ };
131
+ }