@amaster.ai/admin-sdk 0.1.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.
package/dist/index.js ADDED
@@ -0,0 +1,727 @@
1
+ // src/error.ts
2
+ var AdminSDKError = class extends Error {
3
+ constructor(message, statusCode, response) {
4
+ super(message);
5
+ this.statusCode = statusCode;
6
+ this.response = response;
7
+ this.name = "AdminSDKError";
8
+ }
9
+ };
10
+
11
+ // src/http.ts
12
+ function createHttpClient(baseURL, commonHeaders) {
13
+ const normalizedBase = baseURL.replace(/\/$/, "");
14
+ return async function request(options) {
15
+ const { method, path, body, query } = options;
16
+ let url = normalizedBase + path;
17
+ if (query) {
18
+ const params = new URLSearchParams();
19
+ for (const [key, value] of Object.entries(query)) {
20
+ if (value !== void 0) {
21
+ params.set(key, String(value));
22
+ }
23
+ }
24
+ const qs = params.toString();
25
+ if (qs) url += "?" + qs;
26
+ }
27
+ const headers = {
28
+ "Content-Type": "application/json",
29
+ ...commonHeaders
30
+ };
31
+ const res = await fetch(url, {
32
+ method,
33
+ headers,
34
+ body: body !== void 0 ? JSON.stringify(body) : void 0
35
+ });
36
+ let json;
37
+ try {
38
+ json = await res.json();
39
+ } catch {
40
+ throw new AdminSDKError(
41
+ `Failed to parse response from ${method} ${path}`,
42
+ res.status
43
+ );
44
+ }
45
+ if (!res.ok) {
46
+ const err = json;
47
+ throw new AdminSDKError(
48
+ err?.message ?? `Request failed with status ${res.status}`,
49
+ res.status,
50
+ json
51
+ );
52
+ }
53
+ return json.data;
54
+ };
55
+ }
56
+
57
+ // src/modules/auth.ts
58
+ function createAuthModule(request) {
59
+ return {
60
+ /**
61
+ * Check whether a user has a specific permission.
62
+ *
63
+ * Uses the Service Key to query on behalf of any user by UID —
64
+ * no user token required.
65
+ *
66
+ * @example
67
+ * ```typescript
68
+ * // Check if user can access the dashboard page
69
+ * const result = await admin.auth.checkPermission('u-123456', {
70
+ * resource: 'page',
71
+ * action: 'access',
72
+ * resourceId: 'dashboard',
73
+ * });
74
+ * if (!result.allow) throw new Error('Forbidden');
75
+ * ```
76
+ */
77
+ async checkPermission(uid, params) {
78
+ return request({
79
+ method: "POST",
80
+ path: "/api/internal/acl/authorize",
81
+ body: { uid, ...params }
82
+ });
83
+ },
84
+ /**
85
+ * Get all ACL rules for a user.
86
+ *
87
+ * Returns the full set of permissions and roles. Useful when you need
88
+ * to perform multiple permission checks locally without making repeated
89
+ * network calls.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * const rules = await admin.auth.getRules('u-123456');
94
+ *
95
+ * // Check roles
96
+ * if (rules.roles.includes('admin')) { ... }
97
+ *
98
+ * // Check multiple permissions locally
99
+ * const canRead = rules.permissions.some(
100
+ * p => p.resource === 'order' && p.action === 'read'
101
+ * );
102
+ * ```
103
+ */
104
+ async getRules(uid) {
105
+ return request({
106
+ method: "GET",
107
+ path: "/api/internal/acl/rules",
108
+ query: { uid }
109
+ });
110
+ }
111
+ };
112
+ }
113
+
114
+ // src/modules/departments.ts
115
+ function createDepartmentsModule(request) {
116
+ return {
117
+ /**
118
+ * List all departments (flat list).
119
+ *
120
+ * @example
121
+ * ```typescript
122
+ * const depts = await admin.departments.list();
123
+ * const techDept = depts.find(d => d.name === '技术部');
124
+ * ```
125
+ */
126
+ async list() {
127
+ return request({
128
+ method: "GET",
129
+ path: "/api/internal/org/departments"
130
+ });
131
+ },
132
+ /**
133
+ * Get a single department by ID.
134
+ *
135
+ * @example
136
+ * ```typescript
137
+ * const dept = await admin.departments.get(1);
138
+ * ```
139
+ */
140
+ async get(id) {
141
+ return request({
142
+ method: "GET",
143
+ path: `/api/internal/org/departments/${id}`
144
+ });
145
+ },
146
+ /**
147
+ * Create a new department.
148
+ *
149
+ * @example
150
+ * ```typescript
151
+ * const dept = await admin.departments.create({
152
+ * name: '测试组',
153
+ * parentId: 1,
154
+ * });
155
+ * ```
156
+ */
157
+ async create(params) {
158
+ return request({
159
+ method: "POST",
160
+ path: "/api/internal/org/departments",
161
+ body: params
162
+ });
163
+ },
164
+ /**
165
+ * Update a department.
166
+ *
167
+ * @example
168
+ * ```typescript
169
+ * await admin.departments.update(3, { name: '质量保证组' });
170
+ * ```
171
+ */
172
+ async update(id, params) {
173
+ return request({
174
+ method: "PUT",
175
+ path: `/api/internal/org/departments/${id}`,
176
+ body: params
177
+ });
178
+ },
179
+ /**
180
+ * Delete a department.
181
+ * Note: departments with sub-departments or assigned users cannot be deleted directly.
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * await admin.departments.delete(3);
186
+ * ```
187
+ */
188
+ async delete(id) {
189
+ return request({
190
+ method: "DELETE",
191
+ path: `/api/internal/org/departments/${id}`
192
+ });
193
+ },
194
+ /**
195
+ * List members of a department.
196
+ *
197
+ * @param includeChildren - Whether to include members from sub-departments. Defaults to false.
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * const members = await admin.departments.listUsers(1);
202
+ * const allMembers = await admin.departments.listUsers(1, true);
203
+ * ```
204
+ */
205
+ async listUsers(id, includeChildren = false) {
206
+ return request({
207
+ method: "GET",
208
+ path: `/api/internal/org/departments/${id}/users`,
209
+ query: { include_children: includeChildren }
210
+ });
211
+ },
212
+ /**
213
+ * Add a user to a department.
214
+ *
215
+ * @example
216
+ * ```typescript
217
+ * await admin.departments.addUser(1, {
218
+ * userId: 123,
219
+ * isPrimary: true,
220
+ * position: '高级工程师',
221
+ * });
222
+ * ```
223
+ */
224
+ async addUser(deptId, params) {
225
+ return request({
226
+ method: "POST",
227
+ path: `/api/internal/org/departments/${deptId}/users`,
228
+ body: params
229
+ });
230
+ },
231
+ /**
232
+ * Remove a user from a department.
233
+ *
234
+ * @example
235
+ * ```typescript
236
+ * await admin.departments.removeUser(1, 123);
237
+ * ```
238
+ */
239
+ async removeUser(deptId, userUid) {
240
+ return request({
241
+ method: "DELETE",
242
+ path: `/api/internal/org/departments/${deptId}/users/${userUid}`
243
+ });
244
+ }
245
+ };
246
+ }
247
+
248
+ // src/modules/permissions.ts
249
+ function createPermissionsModule(request) {
250
+ return {
251
+ /**
252
+ * List all defined permissions.
253
+ *
254
+ * @example
255
+ * ```typescript
256
+ * const perms = await admin.permissions.list();
257
+ * const orderRead = perms.find(p => p.resource === 'order' && p.action === 'read');
258
+ * ```
259
+ */
260
+ async list() {
261
+ return request({
262
+ method: "GET",
263
+ path: "/api/internal/rbac/permissions"
264
+ });
265
+ },
266
+ /**
267
+ * Create a new permission definition.
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * const perm = await admin.permissions.create({
272
+ * resource: 'order',
273
+ * action: 'export',
274
+ * name: '导出订单',
275
+ * });
276
+ * ```
277
+ */
278
+ async create(params) {
279
+ return request({
280
+ method: "POST",
281
+ path: "/api/internal/rbac/permissions",
282
+ body: params
283
+ });
284
+ },
285
+ /**
286
+ * Update a permission definition.
287
+ *
288
+ * @example
289
+ * ```typescript
290
+ * await admin.permissions.update(10, { name: '导出报表' });
291
+ * ```
292
+ */
293
+ async update(id, params) {
294
+ return request({
295
+ method: "PUT",
296
+ path: `/api/internal/rbac/permissions/${id}`,
297
+ body: params
298
+ });
299
+ },
300
+ /**
301
+ * Delete a permission definition.
302
+ *
303
+ * @example
304
+ * ```typescript
305
+ * await admin.permissions.delete(10);
306
+ * ```
307
+ */
308
+ async delete(id) {
309
+ return request({
310
+ method: "DELETE",
311
+ path: `/api/internal/rbac/permissions/${id}`
312
+ });
313
+ },
314
+ /**
315
+ * List all permissions assigned to a role.
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * const perms = await admin.permissions.listForRole(roleId);
320
+ * ```
321
+ */
322
+ async listForRole(roleId) {
323
+ return request({
324
+ method: "GET",
325
+ path: `/api/internal/rbac/roles/${roleId}/permissions`
326
+ });
327
+ },
328
+ /**
329
+ * Assign a permission to a role with a data scope.
330
+ *
331
+ * @example
332
+ * ```typescript
333
+ * // Department-scoped permission
334
+ * await admin.permissions.assignToRole(roleId, {
335
+ * permissionId: 10,
336
+ * scopeType: 'department',
337
+ * });
338
+ *
339
+ * // Custom whitelist scope
340
+ * await admin.permissions.assignToRole(roleId, {
341
+ * permissionId: 20,
342
+ * scopeType: 'custom',
343
+ * scopeFilter: JSON.stringify({ id: [1, 2, 3] }),
344
+ * });
345
+ * ```
346
+ */
347
+ async assignToRole(roleId, params) {
348
+ return request({
349
+ method: "POST",
350
+ path: `/api/internal/rbac/roles/${roleId}/permissions`,
351
+ body: params
352
+ });
353
+ },
354
+ /**
355
+ * Remove a permission from a role.
356
+ *
357
+ * @example
358
+ * ```typescript
359
+ * await admin.permissions.removeFromRole(roleId, permId);
360
+ * ```
361
+ */
362
+ async removeFromRole(roleId, permId) {
363
+ return request({
364
+ method: "DELETE",
365
+ path: `/api/internal/rbac/roles/${roleId}/permissions/${permId}`
366
+ });
367
+ },
368
+ /**
369
+ * Update the data scope of a role–permission assignment.
370
+ *
371
+ * @example
372
+ * ```typescript
373
+ * await admin.permissions.updateRolePermissionScope(roleId, permId, {
374
+ * scopeType: 'all',
375
+ * });
376
+ * ```
377
+ */
378
+ async updateRolePermissionScope(roleId, permId, params) {
379
+ return request({
380
+ method: "PUT",
381
+ path: `/api/internal/rbac/roles/${roleId}/permissions/${permId}`,
382
+ body: params
383
+ });
384
+ },
385
+ /**
386
+ * Assign a direct (user-level) permission exception to a user.
387
+ *
388
+ * This bypasses role-based assignment and gives the user a direct
389
+ * data-scope override for the specified permission.
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * await admin.permissions.assignToUser('u-123456', {
394
+ * permissionId: 10,
395
+ * scopeType: 'department',
396
+ * });
397
+ * ```
398
+ */
399
+ async assignToUser(uid, params) {
400
+ return request({
401
+ method: "POST",
402
+ path: `/api/internal/rbac/users/${uid}/permissions`,
403
+ body: params
404
+ });
405
+ },
406
+ /**
407
+ * Remove a direct permission exception from a user.
408
+ *
409
+ * @example
410
+ * ```typescript
411
+ * await admin.permissions.removeFromUser('u-123456', permId);
412
+ * ```
413
+ */
414
+ async removeFromUser(uid, permId) {
415
+ return request({
416
+ method: "DELETE",
417
+ path: `/api/internal/rbac/users/${uid}/permissions/${permId}`
418
+ });
419
+ },
420
+ /**
421
+ * List permission exceptions for a specific user.
422
+ *
423
+ * @example
424
+ * ```typescript
425
+ * const exceptions = await admin.permissions.listForUser('u-123456');
426
+ * ```
427
+ */
428
+ async listForUser(uid) {
429
+ return request({
430
+ method: "GET",
431
+ path: `/api/internal/rbac/users/${uid}/permissions`
432
+ });
433
+ },
434
+ /**
435
+ * Update the data scope of a user-level permission exception.
436
+ *
437
+ * @example
438
+ * ```typescript
439
+ * await admin.permissions.updateUserPermissionScope('u-123456', permId, {
440
+ * scopeType: 'custom',
441
+ * scopeFilter: JSON.stringify({ id: [10, 20] }),
442
+ * });
443
+ * ```
444
+ */
445
+ async updateUserPermissionScope(uid, permId, params) {
446
+ return request({
447
+ method: "PUT",
448
+ path: `/api/internal/rbac/users/${uid}/permissions/${permId}`,
449
+ body: params
450
+ });
451
+ }
452
+ };
453
+ }
454
+
455
+ // src/modules/roles.ts
456
+ function createRolesModule(request) {
457
+ return {
458
+ /**
459
+ * List all roles.
460
+ *
461
+ * @example
462
+ * ```typescript
463
+ * const roles = await admin.roles.list();
464
+ * const managerRole = roles.find(r => r.code === 'manager');
465
+ * ```
466
+ */
467
+ async list() {
468
+ return request({
469
+ method: "GET",
470
+ path: "/api/internal/rbac/roles"
471
+ });
472
+ },
473
+ /**
474
+ * Get a role by its numeric ID.
475
+ *
476
+ * @example
477
+ * ```typescript
478
+ * const role = await admin.roles.get(1);
479
+ * ```
480
+ */
481
+ async get(id) {
482
+ return request({
483
+ method: "GET",
484
+ path: `/api/internal/rbac/roles/${id}`
485
+ });
486
+ },
487
+ /**
488
+ * Create a new role.
489
+ *
490
+ * @example
491
+ * ```typescript
492
+ * const role = await admin.roles.create({
493
+ * code: 'editor',
494
+ * displayName: '编辑',
495
+ * description: '负责内容编辑',
496
+ * });
497
+ * ```
498
+ */
499
+ async create(params) {
500
+ return request({
501
+ method: "POST",
502
+ path: "/api/internal/rbac/roles",
503
+ body: params
504
+ });
505
+ },
506
+ /**
507
+ * Update a role.
508
+ * Note: system roles (isSystem=true) cannot be modified.
509
+ *
510
+ * @example
511
+ * ```typescript
512
+ * await admin.roles.update(3, { displayName: '高级编辑' });
513
+ * ```
514
+ */
515
+ async update(id, params) {
516
+ return request({
517
+ method: "PUT",
518
+ path: `/api/internal/rbac/roles/${id}`,
519
+ body: params
520
+ });
521
+ },
522
+ /**
523
+ * Delete a role.
524
+ * Note: system roles cannot be deleted.
525
+ *
526
+ * @example
527
+ * ```typescript
528
+ * await admin.roles.delete(3);
529
+ * ```
530
+ */
531
+ async delete(id) {
532
+ return request({
533
+ method: "DELETE",
534
+ path: `/api/internal/rbac/roles/${id}`
535
+ });
536
+ },
537
+ /**
538
+ * Assign a role to a user, department, team, or another role.
539
+ *
540
+ * @example
541
+ * ```typescript
542
+ * // Assign to a user
543
+ * await admin.roles.assign(roleId, { assigneeType: 'user', assigneeId: 123 });
544
+ *
545
+ * // Assign to an entire department
546
+ * await admin.roles.assign(roleId, { assigneeType: 'department', assigneeId: 5 });
547
+ * ```
548
+ */
549
+ async assign(roleId, params) {
550
+ return request({
551
+ method: "POST",
552
+ path: `/api/internal/rbac/roles/${roleId}/assign`,
553
+ body: params
554
+ });
555
+ },
556
+ /**
557
+ * Remove a role assignment.
558
+ *
559
+ * @example
560
+ * ```typescript
561
+ * await admin.roles.unassign(roleId, { assigneeType: 'user', assigneeId: 123 });
562
+ * ```
563
+ */
564
+ async unassign(roleId, params) {
565
+ return request({
566
+ method: "POST",
567
+ path: `/api/internal/rbac/roles/${roleId}/unassign`,
568
+ body: params
569
+ });
570
+ },
571
+ /**
572
+ * List all assignees (users, departments, etc.) for a role.
573
+ *
574
+ * @example
575
+ * ```typescript
576
+ * const assignees = await admin.roles.listAssignees(roleId);
577
+ * const users = assignees.filter(a => a.assigneeType === 'user');
578
+ * ```
579
+ */
580
+ async listAssignees(roleId) {
581
+ return request({
582
+ method: "GET",
583
+ path: `/api/internal/rbac/roles/${roleId}/assignees`
584
+ });
585
+ },
586
+ /**
587
+ * Get all roles assigned to a user (by UID).
588
+ *
589
+ * Useful in Edge Functions to check what roles a user currently holds
590
+ * without making a full ACL check.
591
+ *
592
+ * @example
593
+ * ```typescript
594
+ * const roles = await admin.roles.getUserRoles('u-123456');
595
+ * if (roles.some(r => r.code === 'admin')) { ... }
596
+ * ```
597
+ */
598
+ async getUserRoles(uid) {
599
+ return request({
600
+ method: "GET",
601
+ path: `/api/internal/rbac/users/${uid}/roles`
602
+ });
603
+ }
604
+ };
605
+ }
606
+
607
+ // src/modules/users.ts
608
+ function createUsersModule(request) {
609
+ return {
610
+ /**
611
+ * List users with optional search and pagination.
612
+ *
613
+ * @example
614
+ * ```typescript
615
+ * const result = await admin.users.list({ query: 'zhang', pageSize: 50 });
616
+ * console.log(`Total: ${result.total}`);
617
+ * for (const user of result.list) {
618
+ * console.log(user.email);
619
+ * }
620
+ * ```
621
+ */
622
+ async list(params = {}) {
623
+ return request({
624
+ method: "GET",
625
+ path: "/api/internal/users",
626
+ query: {
627
+ page: params.page,
628
+ pageSize: params.pageSize,
629
+ query: params.query
630
+ }
631
+ });
632
+ },
633
+ /**
634
+ * Get a single user by UID.
635
+ *
636
+ * @example
637
+ * ```typescript
638
+ * const user = await admin.users.get('u-123456');
639
+ * console.log(user.email);
640
+ * ```
641
+ */
642
+ async get(uid) {
643
+ return request({
644
+ method: "GET",
645
+ path: `/api/internal/users/${uid}`
646
+ });
647
+ },
648
+ /**
649
+ * Create a new user.
650
+ * At least one of username / email / phone must be provided.
651
+ *
652
+ * @example
653
+ * ```typescript
654
+ * const user = await admin.users.create({
655
+ * email: 'user@example.com',
656
+ * password: 'Secure@123',
657
+ * displayName: '张三',
658
+ * });
659
+ * ```
660
+ */
661
+ async create(params) {
662
+ return request({
663
+ method: "POST",
664
+ path: "/api/internal/users",
665
+ body: params
666
+ });
667
+ },
668
+ /**
669
+ * Update an existing user.
670
+ *
671
+ * @example
672
+ * ```typescript
673
+ * // Reset password
674
+ * await admin.users.update('u-123456', { password: 'NewSecure@456' });
675
+ *
676
+ * // Grant super admin
677
+ * await admin.users.update('u-123456', { isSuperAdmin: true });
678
+ * ```
679
+ */
680
+ async update(uid, params) {
681
+ return request({
682
+ method: "PUT",
683
+ path: `/api/internal/users/${uid}`,
684
+ body: params
685
+ });
686
+ },
687
+ /**
688
+ * Delete a user.
689
+ *
690
+ * @example
691
+ * ```typescript
692
+ * await admin.users.delete('u-123456');
693
+ * ```
694
+ */
695
+ async delete(uid) {
696
+ return request({
697
+ method: "DELETE",
698
+ path: `/api/internal/users/${uid}`
699
+ });
700
+ }
701
+ };
702
+ }
703
+
704
+ // src/admin-sdk.ts
705
+ var AdminSDK = class {
706
+ constructor(options) {
707
+ const { baseURL, appId, env = "dev", serviceKey } = options;
708
+ const headers = {
709
+ "x-tenant-id": appId,
710
+ "x-env": env
711
+ };
712
+ if (serviceKey) {
713
+ headers["X-Service-Key"] = serviceKey;
714
+ headers["X-Bypass-Auth"] = "true";
715
+ }
716
+ const request = createHttpClient(baseURL, headers);
717
+ this.auth = createAuthModule(request);
718
+ this.users = createUsersModule(request);
719
+ this.roles = createRolesModule(request);
720
+ this.permissions = createPermissionsModule(request);
721
+ this.departments = createDepartmentsModule(request);
722
+ }
723
+ };
724
+
725
+ export { AdminSDK, AdminSDKError };
726
+ //# sourceMappingURL=index.js.map
727
+ //# sourceMappingURL=index.js.map