@explorins/pers-sdk 2.0.7 → 2.0.11

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 (171) hide show
  1. package/README.md +113 -59
  2. package/dist/analytics/index.d.ts +0 -2
  3. package/dist/analytics/index.d.ts.map +1 -1
  4. package/dist/analytics/models/index.d.ts +1 -10
  5. package/dist/analytics/models/index.d.ts.map +1 -1
  6. package/dist/analytics.cjs +44 -29
  7. package/dist/analytics.cjs.map +1 -1
  8. package/dist/analytics.js +45 -2
  9. package/dist/analytics.js.map +1 -1
  10. package/dist/business/index.d.ts +0 -1
  11. package/dist/business/index.d.ts.map +1 -1
  12. package/dist/business.cjs +7 -774
  13. package/dist/business.cjs.map +1 -1
  14. package/dist/business.js +3 -751
  15. package/dist/business.js.map +1 -1
  16. package/dist/campaign/index.d.ts +0 -1
  17. package/dist/campaign/index.d.ts.map +1 -1
  18. package/dist/campaign.cjs +429 -29
  19. package/dist/campaign.cjs.map +1 -1
  20. package/dist/campaign.js +431 -3
  21. package/dist/campaign.js.map +1 -1
  22. package/dist/chunks/business-membership-service-8KC_qRj7.cjs +756 -0
  23. package/dist/chunks/business-membership-service-8KC_qRj7.cjs.map +1 -0
  24. package/dist/chunks/business-membership-service-D6vaVQTR.js +751 -0
  25. package/dist/chunks/business-membership-service-D6vaVQTR.js.map +1 -0
  26. package/dist/chunks/{web3-chain-service-BeBjALg2.cjs → index-B-g2JPVK.cjs} +1 -220
  27. package/dist/chunks/index-B-g2JPVK.cjs.map +1 -0
  28. package/dist/chunks/{web3-chain-service-DKHCnHQX.js → index-CKm_V5XE.js} +2 -219
  29. package/dist/chunks/index-CKm_V5XE.js.map +1 -0
  30. package/dist/chunks/payment-service-Bkw7ZXev.cjs +214 -0
  31. package/dist/chunks/payment-service-Bkw7ZXev.cjs.map +1 -0
  32. package/dist/chunks/payment-service-IvM6rryM.js +211 -0
  33. package/dist/chunks/payment-service-IvM6rryM.js.map +1 -0
  34. package/dist/chunks/{pers-sdk-JIExM712.js → pers-sdk-DYnIZvcx.js} +12 -291
  35. package/dist/chunks/pers-sdk-DYnIZvcx.js.map +1 -0
  36. package/dist/chunks/{pers-sdk-h-uoLpBx.cjs → pers-sdk-Dr9W8stD.cjs} +38 -318
  37. package/dist/chunks/pers-sdk-Dr9W8stD.cjs.map +1 -0
  38. package/dist/chunks/redemption-service-D-hBqh42.js +339 -0
  39. package/dist/chunks/redemption-service-D-hBqh42.js.map +1 -0
  40. package/dist/chunks/redemption-service-rMB6T2W5.cjs +342 -0
  41. package/dist/chunks/redemption-service-rMB6T2W5.cjs.map +1 -0
  42. package/dist/chunks/tenant-service-CsRA3O2V.js +163 -0
  43. package/dist/chunks/tenant-service-CsRA3O2V.js.map +1 -0
  44. package/dist/chunks/tenant-service-fj-pkXTw.cjs +166 -0
  45. package/dist/chunks/tenant-service-fj-pkXTw.cjs.map +1 -0
  46. package/dist/chunks/{transaction-request.builder-DrqTWcyC.cjs → transaction-request.builder-BwWmfHXm.cjs} +6 -6
  47. package/dist/chunks/{transaction-request.builder-DrqTWcyC.cjs.map → transaction-request.builder-BwWmfHXm.cjs.map} +1 -1
  48. package/dist/chunks/{transaction-request.builder-DltmruUC.js → transaction-request.builder-C1FPWmYN.js} +6 -6
  49. package/dist/chunks/{transaction-request.builder-DltmruUC.js.map → transaction-request.builder-C1FPWmYN.js.map} +1 -1
  50. package/dist/chunks/web3-chain-service-D68-0WaW.cjs +224 -0
  51. package/dist/chunks/web3-chain-service-D68-0WaW.cjs.map +1 -0
  52. package/dist/chunks/web3-chain-service-DuvxmKSj.js +221 -0
  53. package/dist/chunks/web3-chain-service-DuvxmKSj.js.map +1 -0
  54. package/dist/chunks/{explorer.utils-Cx3wrqAj.cjs → web3-manager-C_cFaMCm.cjs} +411 -144
  55. package/dist/chunks/web3-manager-C_cFaMCm.cjs.map +1 -0
  56. package/dist/chunks/{explorer.utils-BkS3k8hX.js → web3-manager-OExwBWB7.js} +412 -146
  57. package/dist/chunks/web3-manager-OExwBWB7.js.map +1 -0
  58. package/dist/core.cjs +18 -21
  59. package/dist/core.cjs.map +1 -1
  60. package/dist/core.js +10 -12
  61. package/dist/core.js.map +1 -1
  62. package/dist/donation/index.d.ts +0 -1
  63. package/dist/donation/index.d.ts.map +1 -1
  64. package/dist/donation.cjs +48 -29
  65. package/dist/donation.cjs.map +1 -1
  66. package/dist/donation.js +50 -3
  67. package/dist/donation.js.map +1 -1
  68. package/dist/index.cjs +43 -69
  69. package/dist/index.cjs.map +1 -1
  70. package/dist/index.d.ts +1 -3
  71. package/dist/index.d.ts.map +1 -1
  72. package/dist/index.js +13 -15
  73. package/dist/index.js.map +1 -1
  74. package/dist/managers/analytics-manager.d.ts +1 -1
  75. package/dist/managers/index.d.ts +0 -1
  76. package/dist/managers/index.d.ts.map +1 -1
  77. package/dist/managers/web3-manager.d.ts +1 -1
  78. package/dist/managers/web3-manager.d.ts.map +1 -1
  79. package/dist/node.cjs +10 -13
  80. package/dist/node.cjs.map +1 -1
  81. package/dist/node.js +10 -13
  82. package/dist/node.js.map +1 -1
  83. package/dist/package.json +4 -10
  84. package/dist/payment/index.d.ts +0 -1
  85. package/dist/payment/index.d.ts.map +1 -1
  86. package/dist/payment.cjs +5 -232
  87. package/dist/payment.cjs.map +1 -1
  88. package/dist/payment.js +3 -210
  89. package/dist/payment.js.map +1 -1
  90. package/dist/pers-sdk.d.ts +1 -13
  91. package/dist/pers-sdk.d.ts.map +1 -1
  92. package/dist/redemption/index.d.ts +0 -1
  93. package/dist/redemption/index.d.ts.map +1 -1
  94. package/dist/redemption/services/redemption-service.d.ts +1 -2
  95. package/dist/redemption/services/redemption-service.d.ts.map +1 -1
  96. package/dist/redemption.cjs +5 -360
  97. package/dist/redemption.cjs.map +1 -1
  98. package/dist/redemption.js +3 -338
  99. package/dist/redemption.js.map +1 -1
  100. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts +15 -21
  101. package/dist/shared/interfaces/pers-shared-lib.interfaces.d.ts.map +1 -1
  102. package/dist/tenant/index.d.ts +0 -1
  103. package/dist/tenant/index.d.ts.map +1 -1
  104. package/dist/tenant.cjs +5 -184
  105. package/dist/tenant.cjs.map +1 -1
  106. package/dist/tenant.js +3 -162
  107. package/dist/tenant.js.map +1 -1
  108. package/dist/token/index.d.ts +0 -1
  109. package/dist/token/index.d.ts.map +1 -1
  110. package/dist/token.cjs +1 -25
  111. package/dist/token.cjs.map +1 -1
  112. package/dist/token.js +1 -1
  113. package/dist/transaction/models/transaction-request.builder.d.ts +4 -4
  114. package/dist/transaction/models/transaction-request.builder.d.ts.map +1 -1
  115. package/dist/transaction.cjs +1 -1
  116. package/dist/transaction.js +1 -1
  117. package/dist/user/index.d.ts +0 -1
  118. package/dist/user/index.d.ts.map +1 -1
  119. package/dist/user-status/index.d.ts +0 -1
  120. package/dist/user-status/index.d.ts.map +1 -1
  121. package/dist/user-status.cjs +0 -25
  122. package/dist/user-status.cjs.map +1 -1
  123. package/dist/user-status.js +0 -1
  124. package/dist/user-status.js.map +1 -1
  125. package/dist/user.cjs +209 -29
  126. package/dist/user.cjs.map +1 -1
  127. package/dist/user.js +211 -3
  128. package/dist/user.js.map +1 -1
  129. package/dist/web3/index.d.ts +1 -0
  130. package/dist/web3/index.d.ts.map +1 -1
  131. package/dist/web3-chain/index.d.ts +0 -1
  132. package/dist/web3-chain/index.d.ts.map +1 -1
  133. package/dist/web3-chain.cjs +14 -29
  134. package/dist/web3-chain.cjs.map +1 -1
  135. package/dist/web3-chain.js +16 -3
  136. package/dist/web3-chain.js.map +1 -1
  137. package/dist/web3-manager.cjs +13 -0
  138. package/dist/web3-manager.cjs.map +1 -0
  139. package/dist/web3-manager.js +7 -0
  140. package/dist/web3-manager.js.map +1 -0
  141. package/dist/web3.cjs +10 -6
  142. package/dist/web3.cjs.map +1 -1
  143. package/dist/web3.js +4 -1
  144. package/dist/web3.js.map +1 -1
  145. package/package.json +4 -10
  146. package/dist/chunks/analytics-service-CitlimKJ.cjs +0 -49
  147. package/dist/chunks/analytics-service-CitlimKJ.cjs.map +0 -1
  148. package/dist/chunks/analytics-service-CxyrOwel.js +0 -46
  149. package/dist/chunks/analytics-service-CxyrOwel.js.map +0 -1
  150. package/dist/chunks/campaign-service-CdEz0jpP.cjs +0 -435
  151. package/dist/chunks/campaign-service-CdEz0jpP.cjs.map +0 -1
  152. package/dist/chunks/campaign-service-DrTAqFZM.js +0 -432
  153. package/dist/chunks/campaign-service-DrTAqFZM.js.map +0 -1
  154. package/dist/chunks/donation-service--6cnTvWq.cjs +0 -54
  155. package/dist/chunks/donation-service--6cnTvWq.cjs.map +0 -1
  156. package/dist/chunks/donation-service-xiXZ2Eto.js +0 -51
  157. package/dist/chunks/donation-service-xiXZ2Eto.js.map +0 -1
  158. package/dist/chunks/explorer.utils-BkS3k8hX.js.map +0 -1
  159. package/dist/chunks/explorer.utils-Cx3wrqAj.cjs.map +0 -1
  160. package/dist/chunks/index-BtDNXaFq.js +0 -13
  161. package/dist/chunks/index-BtDNXaFq.js.map +0 -1
  162. package/dist/chunks/index-CMk3Aqkk.cjs +0 -15
  163. package/dist/chunks/index-CMk3Aqkk.cjs.map +0 -1
  164. package/dist/chunks/pers-sdk-JIExM712.js.map +0 -1
  165. package/dist/chunks/pers-sdk-h-uoLpBx.cjs.map +0 -1
  166. package/dist/chunks/user-service-BGP3SZpk.js +0 -212
  167. package/dist/chunks/user-service-BGP3SZpk.js.map +0 -1
  168. package/dist/chunks/user-service-gITOx4qj.cjs +0 -215
  169. package/dist/chunks/user-service-gITOx4qj.cjs.map +0 -1
  170. package/dist/chunks/web3-chain-service-BeBjALg2.cjs.map +0 -1
  171. package/dist/chunks/web3-chain-service-DKHCnHQX.js.map +0 -1
@@ -0,0 +1,751 @@
1
+ import { b as buildPaginationParams, n as normalizeToPaginated } from './pagination-utils-9vQ-Npkr.js';
2
+ import { MembershipRole, hasMinimumRole } from '@explorins/pers-shared';
3
+
4
+ /**
5
+ * Platform-Agnostic Business API Client
6
+ *
7
+ * Updated to match the actual RESTful endpoints:
8
+ * - /businesses for business operations
9
+ * - /business-types for business type operations (separate controller)
10
+ */
11
+ class BusinessApi {
12
+ constructor(apiClient) {
13
+ this.apiClient = apiClient;
14
+ this.basePath = '/businesses';
15
+ this.businessTypesPath = '/businesses/types';
16
+ }
17
+ // ==========================================
18
+ // 🌐 BUSINESS TYPES MANAGEMENT
19
+ // ==========================================
20
+ /**
21
+ * Get all business types (project key required)
22
+ *
23
+ * Endpoint: GET /business-types
24
+ * Auth: @ApiSecurity('projectKey')
25
+ *
26
+ * @param options Pagination options (page, limit, sortBy, sortOrder)
27
+ * @returns Paginated response with business types
28
+ */
29
+ async getBusinessTypes(options) {
30
+ const params = buildPaginationParams(options);
31
+ const response = await this.apiClient.get(`${this.businessTypesPath}?${params.toString()}`);
32
+ return normalizeToPaginated(response);
33
+ }
34
+ /**
35
+ * ADMIN: Create business type
36
+ *
37
+ * Endpoint: POST /business-types
38
+ * Auth: @TenantAdmin()
39
+ */
40
+ async createBusinessType(dto) {
41
+ return this.apiClient.post(this.businessTypesPath, dto);
42
+ }
43
+ /**
44
+ * ADMIN: Update business type
45
+ *
46
+ * Endpoint: PUT /business-types
47
+ * Auth: @TenantAdmin()
48
+ */
49
+ async updateBusinessType(dto) {
50
+ return this.apiClient.put(this.businessTypesPath, dto);
51
+ }
52
+ /**
53
+ * ADMIN: Delete business type
54
+ *
55
+ * Endpoint: DELETE /business-types/{id}
56
+ * Auth: @TenantAdmin()
57
+ */
58
+ async deleteBusinessType(id) {
59
+ return this.apiClient.delete(`${this.businessTypesPath}/${id}`);
60
+ }
61
+ // ==========================================
62
+ // 🏢 BUSINESS MANAGEMENT
63
+ // ==========================================
64
+ /**
65
+ * Get current business info (business authentication required)
66
+ *
67
+ * Endpoint: GET /businesses/me
68
+ * Auth: @Business()
69
+ */
70
+ async getCurrentBusiness() {
71
+ return this.apiClient.get(`${this.basePath}/me`);
72
+ }
73
+ /**
74
+ * Get all businesses with role-based filtering and pagination
75
+ *
76
+ * Endpoint: GET /businesses?active={boolean}&sanitize={mode}&page={number}&limit={number}
77
+ * Auth: @ApiSecurity('projectKey') (enhanced with role-based filtering)
78
+ *
79
+ * Note:
80
+ * - Project API Key users: Active businesses only (automatically filtered)
81
+ * - Admin JWT users: Full access with all query parameters
82
+ *
83
+ * @param options - Filter and pagination options
84
+ * @returns Paginated list of businesses
85
+ *
86
+ * @example
87
+ * ```typescript
88
+ * // Get first page of active businesses
89
+ * const page1 = await businessApi.getBusinesses({ active: true });
90
+ *
91
+ * // Get all businesses (admin only) with pagination
92
+ * const page2 = await businessApi.getBusinesses({
93
+ * page: 2,
94
+ * limit: 25,
95
+ * sanitize: 'soft'
96
+ * });
97
+ * ```
98
+ */
99
+ async getBusinesses(options) {
100
+ const params = buildPaginationParams(options);
101
+ if (options?.active !== undefined) {
102
+ params.set('active', String(options.active));
103
+ }
104
+ if (options?.sanitize) {
105
+ params.set('sanitize', options.sanitize);
106
+ }
107
+ const response = await this.apiClient.get(`${this.basePath}?${params.toString()}`);
108
+ return normalizeToPaginated(response);
109
+ }
110
+ /**
111
+ * Get business by ID
112
+ *
113
+ * Endpoint: GET /businesses/{id}
114
+ * Auth: @ApiSecurity('projectKey')
115
+ */
116
+ async getBusinessById(businessId) {
117
+ return this.apiClient.get(`${this.basePath}/${businessId}`);
118
+ }
119
+ /**
120
+ * Get business by account address
121
+ *
122
+ * Endpoint: GET /businesses/account/{accountAddress}
123
+ * Auth: @ApiSecurity('projectKey')
124
+ */
125
+ async getBusinessByAccount(accountAddress) {
126
+ return this.apiClient.get(`${this.basePath}/account/${accountAddress}`);
127
+ }
128
+ // ==========================================
129
+ // 🔧 ADMIN OPERATIONS
130
+ // ==========================================
131
+ /**
132
+ * ADMIN: Create business
133
+ *
134
+ * Endpoint: POST /businesses
135
+ * Auth: @TenantAdmin()
136
+ * Returns: BusinessApiKeyDTO | BusinessTokenBalancesDTO
137
+ */
138
+ async createBusiness(dto) {
139
+ return this.apiClient.post(this.basePath, dto);
140
+ }
141
+ /**
142
+ * ADMIN: Create business by display name (convenience method)
143
+ */
144
+ async createBusinessByDisplayName(displayName) {
145
+ const dto = {
146
+ displayName,
147
+ // Add other required fields based on BusinessCreateRequestDTO structure
148
+ };
149
+ return this.createBusiness(dto);
150
+ }
151
+ /**
152
+ * ADMIN: Create businesses from URL
153
+ *
154
+ * Endpoint: POST /businesses/bulk/url
155
+ * Auth: @TenantAdmin()
156
+ */
157
+ async createBusinessesFromUrl(url) {
158
+ return this.apiClient.post(`${this.basePath}/bulk/url`, { url });
159
+ }
160
+ /**
161
+ * ADMIN: Update business
162
+ *
163
+ * Endpoint: PUT /businesses/{id}
164
+ * Auth: @TenantAdmin()
165
+ */
166
+ async updateBusiness(id, businessData) {
167
+ return this.apiClient.put(`${this.basePath}/${id}`, businessData);
168
+ }
169
+ /**
170
+ * ADMIN: Toggle business active status
171
+ *
172
+ * Endpoint: PUT /businesses/{id}/status
173
+ * Auth: @TenantAdmin()
174
+ */
175
+ async toggleBusinessStatus(id, dto) {
176
+ return this.apiClient.put(`${this.basePath}/${id}/status`, dto);
177
+ }
178
+ }
179
+
180
+ /**
181
+ * Business Membership API Client
182
+ *
183
+ * Platform-agnostic API client for managing business memberships.
184
+ * Handles user access to businesses with role-based permissions.
185
+ *
186
+ * Base Path: /businesses/:businessId/members
187
+ *
188
+ * Required Headers:
189
+ * - Authorization: Bearer <business_jwt_token>
190
+ * - X-Project-Key: <project_key>
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * const membershipApi = new BusinessMembershipApi(apiClient);
195
+ *
196
+ * // List all members of a business
197
+ * const members = await membershipApi.getMembers('business-123');
198
+ *
199
+ * // Add a new member
200
+ * const newMember = await membershipApi.addMember('business-123', {
201
+ * userId: 'user-456',
202
+ * role: MembershipRole.EDITOR
203
+ * });
204
+ * ```
205
+ *
206
+ * @version 2.0.0
207
+ */
208
+ class BusinessMembershipApi {
209
+ constructor(apiClient) {
210
+ this.apiClient = apiClient;
211
+ }
212
+ /**
213
+ * Build the membership endpoint path for a business
214
+ */
215
+ getMembersPath(businessId) {
216
+ return `/businesses/${businessId}/members`;
217
+ }
218
+ /**
219
+ * Build the membership endpoint path for a specific member
220
+ */
221
+ getMemberPath(businessId, userId) {
222
+ return `/businesses/${businessId}/members/${userId}`;
223
+ }
224
+ // ==========================================
225
+ // LIST MEMBERS
226
+ // ==========================================
227
+ /**
228
+ * List all members of a business with pagination
229
+ *
230
+ * Endpoint: GET /businesses/:businessId/members
231
+ * Min Role: VIEWER (any member can view)
232
+ *
233
+ * @param businessId - The business UUID
234
+ * @param options - Pagination and filter options
235
+ * @returns Paginated array of business memberships with user and role details
236
+ *
237
+ * @throws {AuthenticationError} 401 - Not authenticated
238
+ * @throws {PersApiError} 403 - businessId in path doesn't match JWT's business
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * // Get first page of members
243
+ * const page1 = await membershipApi.getMembers('business-123');
244
+ * page1.data.forEach(m => console.log(`${m.userId}: ${m.role}`));
245
+ *
246
+ * // Filter by role
247
+ * const admins = await membershipApi.getMembers('business-123', {
248
+ * role: MembershipRole.ADMIN,
249
+ * page: 1,
250
+ * limit: 50
251
+ * });
252
+ *
253
+ * // Paginate through all members
254
+ * const page2 = await membershipApi.getMembers('business-123', { page: 2 });
255
+ * ```
256
+ */
257
+ async getMembers(businessId, options) {
258
+ const params = buildPaginationParams(options);
259
+ if (options?.role) {
260
+ params.set('role', options.role);
261
+ }
262
+ const response = await this.apiClient.get(`${this.getMembersPath(businessId)}?${params.toString()}`);
263
+ return normalizeToPaginated(response);
264
+ }
265
+ // ==========================================
266
+ // ADD MEMBER
267
+ // ==========================================
268
+ /**
269
+ * Add a member to a business
270
+ *
271
+ * Endpoint: POST /businesses/:businessId/members
272
+ * Min Role: ADMIN
273
+ *
274
+ * @param businessId - The business UUID
275
+ * @param request - The add member request with userId and optional role
276
+ * @returns The created business membership
277
+ *
278
+ * @throws {AuthenticationError} 401 - Not authenticated
279
+ * @throws {PersApiError} 403 - Insufficient role (requires ADMIN or higher)
280
+ * @throws {PersApiError} 404 - User not found
281
+ * @throws {PersApiError} 409 - User is already a member
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * const newMember = await membershipApi.addMember('business-123', {
286
+ * userId: 'user-456',
287
+ * role: MembershipRole.EDITOR
288
+ * });
289
+ * ```
290
+ */
291
+ async addMember(businessId, request) {
292
+ return this.apiClient.post(this.getMembersPath(businessId), request);
293
+ }
294
+ /**
295
+ * Add a member to a business with explicit parameters
296
+ *
297
+ * Convenience method that constructs the request DTO internally.
298
+ *
299
+ * @param businessId - The business UUID
300
+ * @param userId - The user UUID to add
301
+ * @param role - The role to assign (defaults to VIEWER)
302
+ * @returns The created business membership
303
+ *
304
+ * @example
305
+ * ```typescript
306
+ * const member = await membershipApi.addMemberByUserId(
307
+ * 'business-123',
308
+ * 'user-456',
309
+ * MembershipRole.EDITOR
310
+ * );
311
+ * ```
312
+ */
313
+ async addMemberByUserId(businessId, userId, role = MembershipRole.VIEWER) {
314
+ return this.addMember(businessId, { userId, role });
315
+ }
316
+ // ==========================================
317
+ // UPDATE MEMBER ROLE
318
+ // ==========================================
319
+ /**
320
+ * Update a member's role in a business
321
+ *
322
+ * Endpoint: PUT /businesses/:businessId/members/:userId
323
+ * Min Role: ADMIN
324
+ *
325
+ * Business Rules:
326
+ * - Cannot demote the last OWNER (must transfer ownership first)
327
+ * - Can only assign roles up to your own level (ADMIN cannot create OWNER)
328
+ *
329
+ * @param businessId - The business UUID
330
+ * @param userId - The user UUID to update
331
+ * @param request - The update request with new role
332
+ * @returns The updated business membership
333
+ *
334
+ * @throws {AuthenticationError} 401 - Not authenticated
335
+ * @throws {PersApiError} 403 - Insufficient role (requires ADMIN or higher)
336
+ * @throws {PersApiError} 404 - Membership not found
337
+ * @throws {PersApiError} 400 - Cannot demote last OWNER
338
+ *
339
+ * @example
340
+ * ```typescript
341
+ * const updated = await membershipApi.updateMemberRole(
342
+ * 'business-123',
343
+ * 'user-456',
344
+ * { role: MembershipRole.ADMIN }
345
+ * );
346
+ * ```
347
+ */
348
+ async updateMemberRole(businessId, userId, request) {
349
+ return this.apiClient.put(this.getMemberPath(businessId, userId), request);
350
+ }
351
+ /**
352
+ * Update a member's role with explicit parameters
353
+ *
354
+ * Convenience method that constructs the request DTO internally.
355
+ *
356
+ * @param businessId - The business UUID
357
+ * @param userId - The user UUID to update
358
+ * @param role - The new role to assign
359
+ * @returns The updated business membership
360
+ *
361
+ * @example
362
+ * ```typescript
363
+ * const updated = await membershipApi.setMemberRole(
364
+ * 'business-123',
365
+ * 'user-456',
366
+ * MembershipRole.ADMIN
367
+ * );
368
+ * ```
369
+ */
370
+ async setMemberRole(businessId, userId, role) {
371
+ return this.updateMemberRole(businessId, userId, { role });
372
+ }
373
+ // ==========================================
374
+ // REMOVE MEMBER
375
+ // ==========================================
376
+ /**
377
+ * Remove a member from a business
378
+ *
379
+ * Endpoint: DELETE /businesses/:businessId/members/:userId
380
+ * Min Role: ADMIN
381
+ *
382
+ * Business Rules:
383
+ * - Cannot remove the last OWNER
384
+ * - Cannot remove yourself (use leave endpoint or transfer ownership)
385
+ *
386
+ * @param businessId - The business UUID
387
+ * @param userId - The user UUID to remove
388
+ * @returns Success confirmation
389
+ *
390
+ * @throws {AuthenticationError} 401 - Not authenticated
391
+ * @throws {PersApiError} 403 - Insufficient role (requires ADMIN or higher)
392
+ * @throws {PersApiError} 404 - Membership not found
393
+ * @throws {PersApiError} 400 - Cannot remove last OWNER
394
+ *
395
+ * @example
396
+ * ```typescript
397
+ * const result = await membershipApi.removeMember('business-123', 'user-456');
398
+ * if (result.success) {
399
+ * console.log('Member removed successfully');
400
+ * }
401
+ * ```
402
+ */
403
+ async removeMember(businessId, userId) {
404
+ return this.apiClient.delete(this.getMemberPath(businessId, userId));
405
+ }
406
+ }
407
+
408
+ /**
409
+ * Platform-Agnostic Business Service
410
+ *
411
+ * Contains business logic and operations that work across platforms.
412
+ * No framework dependencies - pure TypeScript business logic.
413
+ *
414
+ * Focuses only on actual backend capabilities.
415
+ */
416
+ class BusinessService {
417
+ constructor(businessApi) {
418
+ this.businessApi = businessApi;
419
+ }
420
+ /**
421
+ * Get all active businesses with pagination
422
+ * @deprecated Use getBusinesses({ active: true }) for more control
423
+ */
424
+ async getActiveBusinesses(options) {
425
+ return this.businessApi.getBusinesses({ active: true, ...options });
426
+ }
427
+ /**
428
+ * Get all business types with pagination
429
+ */
430
+ async getBusinessTypes(options) {
431
+ return this.businessApi.getBusinessTypes(options);
432
+ }
433
+ /**
434
+ * Get business by ID
435
+ */
436
+ async getBusinessById(businessId) {
437
+ return this.businessApi.getBusinessById(businessId);
438
+ }
439
+ /**
440
+ * Get business by account address
441
+ */
442
+ async getBusinessByAccount(accountAddress) {
443
+ return this.businessApi.getBusinessByAccount(accountAddress);
444
+ }
445
+ /**
446
+ * Get businesses by type (client-side filtering)
447
+ * @deprecated Consider implementing server-side filtering for better performance
448
+ */
449
+ async getBusinessesByType(typeId, options) {
450
+ const response = await this.getActiveBusinesses(options);
451
+ const filtered = response.data.filter((business) => business.businessType && business.businessType.id === parseInt(typeId));
452
+ return {
453
+ data: filtered,
454
+ pagination: {
455
+ ...response.pagination,
456
+ total: filtered.length,
457
+ pages: Math.ceil(filtered.length / (response.pagination.limit || 20))
458
+ }
459
+ };
460
+ }
461
+ // ==========================================
462
+ // ADMIN OPERATIONS
463
+ // ==========================================
464
+ /**
465
+ * ADMIN: Get all businesses with pagination (active and inactive)
466
+ */
467
+ async getBusinesses(options) {
468
+ return this.businessApi.getBusinesses(options);
469
+ }
470
+ /**
471
+ * ADMIN: Create business by display name
472
+ */
473
+ async createBusinessByDisplayName(displayName) {
474
+ return this.businessApi.createBusinessByDisplayName(displayName);
475
+ }
476
+ /**
477
+ * ADMIN: Update business
478
+ */
479
+ async updateBusiness(id, businessData) {
480
+ return this.businessApi.updateBusiness(id, businessData);
481
+ }
482
+ /**
483
+ * ADMIN: Toggle business active status
484
+ */
485
+ async toggleBusinessStatus(id, dto) {
486
+ return this.businessApi.toggleBusinessStatus(id, dto);
487
+ }
488
+ }
489
+
490
+ /**
491
+ * Business Membership Service
492
+ *
493
+ * Platform-agnostic service for managing business memberships.
494
+ * Provides business logic layer on top of the API client with
495
+ * convenience methods and role-based utilities.
496
+ *
497
+ * @example
498
+ * ```typescript
499
+ * const service = new BusinessMembershipService(membershipApi);
500
+ *
501
+ * // Get members with admin permissions
502
+ * const admins = await service.getMembersByRole('business-123', MembershipRole.ADMIN);
503
+ *
504
+ * // Check permissions
505
+ * const canManage = service.canManageMembers(MembershipRole.ADMIN); // true
506
+ * ```
507
+ *
508
+ * @version 2.0.0
509
+ */
510
+ class BusinessMembershipService {
511
+ constructor(membershipApi) {
512
+ this.membershipApi = membershipApi;
513
+ }
514
+ // ==========================================
515
+ // MEMBER LISTING
516
+ // ==========================================
517
+ /**
518
+ * Get all members of a business with pagination
519
+ *
520
+ * @param businessId - The business UUID
521
+ * @param options - Pagination options
522
+ * @returns Paginated response with business memberships
523
+ */
524
+ async getMembers(businessId, options) {
525
+ return this.membershipApi.getMembers(businessId, options);
526
+ }
527
+ /**
528
+ * Get members filtered by role (client-side filtering)
529
+ * @deprecated Consider server-side role filtering for better performance
530
+ */
531
+ async getMembersByRole(businessId, role, options) {
532
+ const response = await this.getMembers(businessId, options);
533
+ const filtered = response.data.filter((m) => m.role === role);
534
+ return {
535
+ data: filtered,
536
+ pagination: {
537
+ ...response.pagination,
538
+ total: filtered.length,
539
+ pages: Math.ceil(filtered.length / (response.pagination.limit || 20))
540
+ }
541
+ };
542
+ }
543
+ /**
544
+ * Get members with at least a minimum role level
545
+ *
546
+ * Uses the role hierarchy: OWNER > ADMIN > EDITOR > VIEWER
547
+ *
548
+ * @param businessId - The business UUID
549
+ * @param minRole - The minimum role level
550
+ * @returns Array of memberships with role >= minRole
551
+ *
552
+ * @example
553
+ * ```typescript
554
+ * // Get all members who can manage content (EDITOR and above)
555
+ * const editors = await service.getMembersWithMinRole('biz-123', MembershipRole.EDITOR);
556
+ * ```
557
+ */
558
+ async getMembersWithMinRole(businessId, minRole) {
559
+ const response = await this.getMembers(businessId);
560
+ return response.data.filter((m) => hasMinimumRole(m.role, minRole));
561
+ }
562
+ /**
563
+ * Get a specific member by user ID
564
+ *
565
+ * @param businessId - The business UUID
566
+ * @param userId - The user UUID to find
567
+ * @returns The membership if found, undefined otherwise
568
+ */
569
+ async getMemberByUserId(businessId, userId) {
570
+ const response = await this.getMembers(businessId);
571
+ return response.data.find((m) => m.userId === userId);
572
+ }
573
+ /**
574
+ * Count members by role
575
+ *
576
+ * @param businessId - The business UUID
577
+ * @returns Object with count per role
578
+ *
579
+ * @example
580
+ * ```typescript
581
+ * const counts = await service.getMemberCountsByRole('biz-123');
582
+ * // { OWNER: 1, ADMIN: 2, EDITOR: 5, VIEWER: 10 }
583
+ * ```
584
+ */
585
+ async getMemberCountsByRole(businessId) {
586
+ const response = await this.getMembers(businessId);
587
+ const counts = {
588
+ [MembershipRole.OWNER]: 0,
589
+ [MembershipRole.ADMIN]: 0,
590
+ [MembershipRole.EDITOR]: 0,
591
+ [MembershipRole.VIEWER]: 0,
592
+ };
593
+ for (const member of response.data) {
594
+ if (member.role in counts) {
595
+ counts[member.role]++;
596
+ }
597
+ }
598
+ return counts;
599
+ }
600
+ // ==========================================
601
+ // MEMBER MANAGEMENT
602
+ // ==========================================
603
+ /**
604
+ * Add a new member to a business
605
+ *
606
+ * @param businessId - The business UUID
607
+ * @param userId - The user UUID to add
608
+ * @param role - The role to assign (defaults to VIEWER)
609
+ * @returns The created membership
610
+ */
611
+ async addMember(businessId, userId, role = MembershipRole.VIEWER) {
612
+ return this.membershipApi.addMemberByUserId(businessId, userId, role);
613
+ }
614
+ /**
615
+ * Update a member's role
616
+ *
617
+ * @param businessId - The business UUID
618
+ * @param userId - The user UUID to update
619
+ * @param newRole - The new role to assign
620
+ * @returns The updated membership
621
+ */
622
+ async updateMemberRole(businessId, userId, newRole) {
623
+ return this.membershipApi.setMemberRole(businessId, userId, newRole);
624
+ }
625
+ /**
626
+ * Remove a member from a business
627
+ *
628
+ * @param businessId - The business UUID
629
+ * @param userId - The user UUID to remove
630
+ * @returns Success confirmation
631
+ */
632
+ async removeMember(businessId, userId) {
633
+ return this.membershipApi.removeMember(businessId, userId);
634
+ }
635
+ /**
636
+ * Promote a member to a higher role
637
+ *
638
+ * @param businessId - The business UUID
639
+ * @param userId - The user UUID to promote
640
+ * @param targetRole - The target role (must be higher than current)
641
+ * @returns The updated membership
642
+ * @throws Error if target role is not higher than current
643
+ */
644
+ async promoteMember(businessId, userId, targetRole) {
645
+ const member = await this.getMemberByUserId(businessId, userId);
646
+ if (!member) {
647
+ throw new Error(`Member not found: ${userId}`);
648
+ }
649
+ // Validate that target role is actually a promotion
650
+ if (!hasMinimumRole(targetRole, member.role) || targetRole === member.role) {
651
+ throw new Error(`Cannot promote to ${targetRole}: current role is ${member.role}`);
652
+ }
653
+ return this.updateMemberRole(businessId, userId, targetRole);
654
+ }
655
+ /**
656
+ * Demote a member to a lower role
657
+ *
658
+ * Note: Cannot demote the last OWNER
659
+ *
660
+ * @param businessId - The business UUID
661
+ * @param userId - The user UUID to demote
662
+ * @param targetRole - The target role (must be lower than current)
663
+ * @returns The updated membership
664
+ * @throws Error if target role is not lower than current
665
+ */
666
+ async demoteMember(businessId, userId, targetRole) {
667
+ const member = await this.getMemberByUserId(businessId, userId);
668
+ if (!member) {
669
+ throw new Error(`Member not found: ${userId}`);
670
+ }
671
+ // Validate that target role is actually a demotion
672
+ if (hasMinimumRole(targetRole, member.role)) {
673
+ throw new Error(`Cannot demote to ${targetRole}: current role is ${member.role}`);
674
+ }
675
+ return this.updateMemberRole(businessId, userId, targetRole);
676
+ }
677
+ // ==========================================
678
+ // PERMISSION UTILITIES
679
+ // ==========================================
680
+ /**
681
+ * Check if a role can view members (any member)
682
+ */
683
+ canViewMembers(role) {
684
+ return role !== null;
685
+ }
686
+ /**
687
+ * Check if a role can manage members (ADMIN or higher)
688
+ */
689
+ canManageMembers(role) {
690
+ return role !== null && hasMinimumRole(role, MembershipRole.ADMIN);
691
+ }
692
+ /**
693
+ * Check if a role can edit content (EDITOR or higher)
694
+ */
695
+ canEditContent(role) {
696
+ return role !== null && hasMinimumRole(role, MembershipRole.EDITOR);
697
+ }
698
+ /**
699
+ * Check if a role can delete the business (OWNER only)
700
+ */
701
+ canDeleteBusiness(role) {
702
+ return role === MembershipRole.OWNER;
703
+ }
704
+ /**
705
+ * Get permissions object for a role
706
+ *
707
+ * Useful for UI components to conditionally render based on permissions.
708
+ *
709
+ * @param role - The membership role (or null if not a member)
710
+ * @returns Object with boolean permission flags
711
+ *
712
+ * @example
713
+ * ```typescript
714
+ * const perms = service.getPermissions(MembershipRole.EDITOR);
715
+ * // { canViewMembers: true, canManageMembers: false, canEditContent: true, canDeleteBusiness: false }
716
+ *
717
+ * if (perms.canManageMembers) {
718
+ * showAddMemberButton();
719
+ * }
720
+ * ```
721
+ */
722
+ getPermissions(role) {
723
+ return {
724
+ canViewMembers: this.canViewMembers(role),
725
+ canManageMembers: this.canManageMembers(role),
726
+ canEditContent: this.canEditContent(role),
727
+ canDeleteBusiness: this.canDeleteBusiness(role),
728
+ };
729
+ }
730
+ /**
731
+ * Check if a role can assign another role
732
+ *
733
+ * Rule: Can only assign roles up to your own level
734
+ * (ADMIN cannot create OWNER, but OWNER can create anything)
735
+ *
736
+ * @param assignerRole - The role of the user assigning
737
+ * @param targetRole - The role being assigned
738
+ * @returns true if the assigner can assign the target role
739
+ */
740
+ canAssignRole(assignerRole, targetRole) {
741
+ // Must be at least ADMIN to assign any role
742
+ if (!hasMinimumRole(assignerRole, MembershipRole.ADMIN)) {
743
+ return false;
744
+ }
745
+ // Can only assign roles up to your own level
746
+ return hasMinimumRole(assignerRole, targetRole);
747
+ }
748
+ }
749
+
750
+ export { BusinessApi as B, BusinessMembershipApi as a, BusinessService as b, BusinessMembershipService as c };
751
+ //# sourceMappingURL=business-membership-service-D6vaVQTR.js.map