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