@newpeak/barista-cli 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.
Files changed (82) hide show
  1. package/.eslintrc.json +23 -0
  2. package/.prettierrc +9 -0
  3. package/.sisyphus/notepads/liberica-employees/learnings.md +73 -0
  4. package/AGENTS.md +270 -0
  5. package/CONTRIBUTING.md +291 -0
  6. package/README.md +707 -0
  7. package/bin/barista +6 -0
  8. package/bin/barista.js +3 -0
  9. package/docs/ARCHITECTURE.md +184 -0
  10. package/docs/COMMANDS.md +352 -0
  11. package/docs/COMMAND_DESIGN_SPEC.md +811 -0
  12. package/docs/INTEGRATION_NOTES.md +270 -0
  13. package/docs/commands/REFERENCE.md +297 -0
  14. package/docs/commands/arabica/auth/index.md +296 -0
  15. package/docs/commands/liberica/auth/index.md +133 -0
  16. package/docs/commands/liberica/context/index.md +60 -0
  17. package/docs/commands/liberica/employees/create.md +185 -0
  18. package/docs/commands/liberica/employees/disable.md +138 -0
  19. package/docs/commands/liberica/employees/enable.md +137 -0
  20. package/docs/commands/liberica/employees/get.md +153 -0
  21. package/docs/commands/liberica/employees/list.md +168 -0
  22. package/docs/commands/liberica/employees/update.md +180 -0
  23. package/docs/commands/liberica/orgs/list.md +62 -0
  24. package/docs/commands/liberica/positions/list.md +61 -0
  25. package/docs/commands/liberica/roles/list.md +67 -0
  26. package/docs/commands/liberica/users/create.md +170 -0
  27. package/docs/commands/liberica/users/get.md +151 -0
  28. package/docs/commands/liberica/users/list.md +175 -0
  29. package/package.json +37 -0
  30. package/src/commands/arabica/auth/index.ts +277 -0
  31. package/src/commands/arabica/auth/login.ts +5 -0
  32. package/src/commands/arabica/auth/logout.ts +5 -0
  33. package/src/commands/arabica/auth/register.ts +5 -0
  34. package/src/commands/arabica/auth/status.ts +5 -0
  35. package/src/commands/arabica/index.ts +23 -0
  36. package/src/commands/auth.ts +107 -0
  37. package/src/commands/context.ts +60 -0
  38. package/src/commands/liberica/auth/index.ts +170 -0
  39. package/src/commands/liberica/context/index.ts +43 -0
  40. package/src/commands/liberica/employees/create.ts +275 -0
  41. package/src/commands/liberica/employees/delete.ts +122 -0
  42. package/src/commands/liberica/employees/disable.ts +97 -0
  43. package/src/commands/liberica/employees/enable.ts +97 -0
  44. package/src/commands/liberica/employees/get.ts +115 -0
  45. package/src/commands/liberica/employees/index.ts +23 -0
  46. package/src/commands/liberica/employees/list.ts +131 -0
  47. package/src/commands/liberica/employees/update.ts +157 -0
  48. package/src/commands/liberica/index.ts +36 -0
  49. package/src/commands/liberica/orgs/index.ts +35 -0
  50. package/src/commands/liberica/positions/index.ts +30 -0
  51. package/src/commands/liberica/roles/index.ts +59 -0
  52. package/src/commands/liberica/users/create.ts +132 -0
  53. package/src/commands/liberica/users/delete.ts +49 -0
  54. package/src/commands/liberica/users/disable.ts +41 -0
  55. package/src/commands/liberica/users/enable.ts +30 -0
  56. package/src/commands/liberica/users/get.ts +46 -0
  57. package/src/commands/liberica/users/index.ts +27 -0
  58. package/src/commands/liberica/users/list.ts +68 -0
  59. package/src/commands/liberica/users/me.ts +42 -0
  60. package/src/commands/liberica/users/reset-password.ts +42 -0
  61. package/src/commands/liberica/users/update.ts +48 -0
  62. package/src/core/api/client.ts +825 -0
  63. package/src/core/auth/token-manager.ts +183 -0
  64. package/src/core/config/manager.ts +164 -0
  65. package/src/index.ts +37 -0
  66. package/src/types/employee.ts +102 -0
  67. package/src/types/index.ts +75 -0
  68. package/src/types/org.ts +25 -0
  69. package/src/types/position.ts +24 -0
  70. package/src/types/user.ts +64 -0
  71. package/tests/unit/commands/arabica/auth.test.ts +230 -0
  72. package/tests/unit/commands/liberica/auth.test.ts +175 -0
  73. package/tests/unit/commands/liberica/context.test.ts +98 -0
  74. package/tests/unit/commands/liberica/employees/create.test.ts +463 -0
  75. package/tests/unit/commands/liberica/employees/disable.test.ts +82 -0
  76. package/tests/unit/commands/liberica/employees/enable.test.ts +82 -0
  77. package/tests/unit/commands/liberica/employees/get.test.ts +111 -0
  78. package/tests/unit/commands/liberica/employees/list.test.ts +294 -0
  79. package/tests/unit/commands/liberica/employees/update.test.ts +210 -0
  80. package/tests/unit/config.test.ts +141 -0
  81. package/tests/unit/types.test.ts +195 -0
  82. package/tsconfig.json +20 -0
@@ -0,0 +1,35 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import Table from 'cli-table3';
4
+ import { configManager } from '../../../core/config/manager.js';
5
+ import { apiClient } from '../../../core/api/client.js';
6
+ import { Environment } from '../../../types/index.js';
7
+
8
+ export function createOrgsCommand(): Command {
9
+ const orgsCommand = new Command('orgs');
10
+ orgsCommand.description('List organizations');
11
+
12
+ orgsCommand
13
+ .command('list')
14
+ .description('List all organizations')
15
+ .option('--json', 'Output as JSON')
16
+ .action(async (options) => {
17
+ const context = configManager.getCurrentContext();
18
+ const environment = (options.env as Environment) || context.environment;
19
+ const tenant = options.tenant || context.tenant;
20
+
21
+ const response = await apiClient.getOrgListName(environment, tenant);
22
+
23
+ if (!response.success) {
24
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
25
+ process.exit(1);
26
+ }
27
+
28
+ const orgs = response.data || [];
29
+
30
+ // Always show full IDs
31
+ console.log(JSON.stringify({ success: true, data: orgs }, null, 2));
32
+ });
33
+
34
+ return orgsCommand;
35
+ }
@@ -0,0 +1,30 @@
1
+ import { Command } from 'commander';
2
+ import { configManager } from '../../../core/config/manager.js';
3
+ import { apiClient } from '../../../core/api/client.js';
4
+ import { Environment } from '../../../types/index.js';
5
+
6
+ export function createPositionsCommand(): Command {
7
+ const positionsCommand = new Command('positions');
8
+ positionsCommand.description('List positions');
9
+
10
+ positionsCommand
11
+ .command('list')
12
+ .description('List all positions')
13
+ .action(async (options) => {
14
+ const context = configManager.getCurrentContext();
15
+ const environment = (options.env as Environment) || context.environment;
16
+ const tenant = options.tenant || context.tenant;
17
+
18
+ const response = await apiClient.listPositions(environment, tenant);
19
+
20
+ if (!response.success) {
21
+ console.error(`\n✗ Failed: ${response.error?.message}\n`);
22
+ process.exit(1);
23
+ }
24
+
25
+ const positions = response.data || [];
26
+ console.log(JSON.stringify({ success: true, data: positions }, null, 2));
27
+ });
28
+
29
+ return positionsCommand;
30
+ }
@@ -0,0 +1,59 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import Table from 'cli-table3';
4
+ import { apiClient } from '../../../core/api/client.js';
5
+ import { Environment } from '../../../types/index.js';
6
+ import { configManager } from '../../../core/config/manager.js';
7
+
8
+ export function createRolesCommand(): Command {
9
+ const rolesCommand = new Command('roles');
10
+ rolesCommand.description('List roles');
11
+
12
+ rolesCommand
13
+ .command('list')
14
+ .description('List all available roles')
15
+ .option('--json', 'Output as JSON')
16
+ .action(async (options) => {
17
+ const context = configManager.getCurrentContext();
18
+ const environment = (options.env as Environment) || context.environment;
19
+ const tenant = options.tenant || context.tenant;
20
+
21
+ try {
22
+ const response = await apiClient.listRoles(environment, tenant);
23
+
24
+ if (!response.success) {
25
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
26
+ process.exit(1);
27
+ }
28
+
29
+ const roles = response.data || [];
30
+
31
+ if (options.json) {
32
+ console.log(JSON.stringify({ success: true, data: roles }, null, 2));
33
+ return;
34
+ }
35
+
36
+ const table = new Table({
37
+ head: [chalk.bold('ID'), chalk.bold('Role Code'), chalk.bold('Role Name'), chalk.bold('Status')],
38
+ colWidths: [20, 20, 20, 10],
39
+ });
40
+
41
+ for (const role of roles) {
42
+ table.push([
43
+ role.roleId,
44
+ role.roleCode || '-',
45
+ role.roleName || '-',
46
+ role.statusFlag === 1 ? chalk.green('Enabled') : chalk.red('Disabled'),
47
+ ]);
48
+ }
49
+
50
+ console.log(table.toString());
51
+ console.log(chalk.gray(`\nTotal: ${roles.length} roles`));
52
+ } catch (error: any) {
53
+ console.error(chalk.red(`\n✗ Error: ${error.message}\n`));
54
+ process.exit(1);
55
+ }
56
+ });
57
+
58
+ return rolesCommand;
59
+ }
@@ -0,0 +1,132 @@
1
+ import { Command } from 'commander';
2
+ import { configManager } from '../../../core/config/manager.js';
3
+ import { apiClient } from '../../../core/api/client.js';
4
+ import { Environment } from '../../../types/index.js';
5
+ import chalk from 'chalk';
6
+
7
+ export function createUserCreateCommand(): Command {
8
+ const createCommand = new Command('create');
9
+ createCommand.description('Create a new user');
10
+
11
+ createCommand
12
+ .option('-n, --name <name>', 'User real name (required)')
13
+ .option('-a, --account <account>', 'User account (required)')
14
+ .option('-e, --email <email>', 'User email')
15
+ .option('-r, --role-ids <roleIds>', 'Role IDs (comma-separated, required)')
16
+ .option('--employee-code <employeeCode>', 'Employee code (optional, used to find employee)')
17
+ .option('--employee-name <employeeName>', 'Employee name (optional, used to find employee)')
18
+ .option('--org-id <orgId>', 'Organization ID (optional, auto-assigned if not provided)')
19
+ .option('--dry-run', 'Preview without executing')
20
+ .option('--json', 'Output as JSON')
21
+ .action(async (options) => {
22
+ // Commander.js boolean flag parsing workaround
23
+ options.dryRun = process.argv.includes('--dry-run');
24
+ options.json = process.argv.includes('--json');
25
+
26
+ const context = configManager.getCurrentContext();
27
+ const environment = (options.env as Environment) || context.environment;
28
+ const tenant = options.tenant || context.tenant;
29
+
30
+ if (!options.name || !options.account || !options.roleIds) {
31
+ console.error(chalk.red('\n✗ Missing required options: --name, --account, --role-ids\n'));
32
+ createCommand.help();
33
+ }
34
+
35
+ const roleIdList = options.roleIds.split(',').map((id: string) => id.trim());
36
+
37
+ const userData: any = {
38
+ realName: options.name,
39
+ account: options.account,
40
+ email: options.email,
41
+ roleIdList,
42
+ };
43
+
44
+ if (options.employeeCode || options.employeeName) {
45
+ const searchText = options.employeeCode || options.employeeName;
46
+ const searchResponse = await apiClient.searchEmployees(environment, tenant, searchText);
47
+ if (!searchResponse.success) {
48
+ console.error(chalk.red(`\n✗ 职员搜索失败: ${searchResponse.error?.message}\n`));
49
+ process.exit(1);
50
+ }
51
+
52
+ let employees = searchResponse.data || [];
53
+
54
+ if (options.employeeCode && options.employeeName) {
55
+ employees = employees.filter((emp: any) =>
56
+ emp.code === options.employeeCode &&
57
+ emp.name && emp.name.includes(options.employeeName)
58
+ );
59
+ } else if (options.employeeCode) {
60
+ employees = employees.filter((emp: any) => emp.code === options.employeeCode);
61
+ } else if (options.employeeName) {
62
+ employees = employees.filter((emp: any) =>
63
+ emp.name && emp.name.includes(options.employeeName)
64
+ );
65
+ }
66
+
67
+ if (employees.length === 0) {
68
+ console.error(chalk.red('\n✗ 未找到匹配的职员\n'));
69
+ process.exit(1);
70
+ }
71
+
72
+ if (employees.length > 1) {
73
+ console.error(chalk.red(`\n✗ 找到多个职员,请使用更精确的条件\n`));
74
+ process.exit(1);
75
+ }
76
+
77
+ const employee = employees[0];
78
+ userData.employeeCode = employee.code;
79
+ userData.employeeNumber = employee.no;
80
+ userData.employeeId = employee.id;
81
+ }
82
+
83
+ // 检查账号是否已存在
84
+ const existCheckResponse = await apiClient.existCheck(environment, tenant, options.account);
85
+ if (!existCheckResponse.success) {
86
+ console.error(chalk.red(`\n✗ 账号校验失败: ${existCheckResponse.error?.message}\n`));
87
+ process.exit(1);
88
+ }
89
+
90
+ // 如果账号已存在,根据模式处理
91
+ if (existCheckResponse.data === false) {
92
+ if (options.dryRun) {
93
+ console.log(chalk.yellow(`\n⚠️ 警告: 账号 "${options.account}" 已存在 (dry-run模式继续预览)\n`));
94
+ } else {
95
+ console.error(chalk.red(`\n✗ 账号 "${options.account}" 已存在,请使用其他账号\n`));
96
+ process.exit(1);
97
+ }
98
+ }
99
+
100
+ if (!options.dryRun) {
101
+ try {
102
+ const userIndexResponse = await apiClient.getUserIndexInfo(environment, tenant);
103
+ if (userIndexResponse.success && userIndexResponse.data?.userOrgInfoList?.length > 0) {
104
+ const firstOrg = userIndexResponse.data.userOrgInfoList[0];
105
+ await apiClient.updateUserOrgOrApp(environment, tenant, { newOrgId: String(firstOrg.orgId) });
106
+ }
107
+ } catch (err) {
108
+ }
109
+ }
110
+
111
+ if (options.dryRun) {
112
+ console.log(chalk.bold('\n🔍 Dry-Run Mode: No changes will be made\n'));
113
+ console.log(chalk.gray('User Data:'));
114
+ console.log(JSON.stringify(userData, null, 2));
115
+ return;
116
+ }
117
+
118
+ const response = await apiClient.createUser(environment, tenant, userData);
119
+
120
+ if (!response.success) {
121
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
122
+ process.exit(1);
123
+ }
124
+
125
+ console.log(chalk.green('\n✓ User created successfully\n'));
126
+ if (options.json) {
127
+ console.log(JSON.stringify({ success: true, data: response.data }, null, 2));
128
+ }
129
+ });
130
+
131
+ return createCommand;
132
+ }
@@ -0,0 +1,49 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import inquirer from 'inquirer';
4
+ import { configManager } from '../../../core/config/manager.js';
5
+ import { apiClient } from '../../../core/api/client.js';
6
+ import { Environment } from '../../../types/index.js';
7
+
8
+ export function createUserDeleteCommand(): Command {
9
+ const deleteCommand = new Command('delete');
10
+ deleteCommand.description('Delete a user');
11
+
12
+ deleteCommand
13
+ .argument('<userId>', 'User ID')
14
+ .option('--force', 'Skip confirmation')
15
+ .option('--dry-run', 'Preview without executing')
16
+ .option('--json', 'Output as JSON')
17
+ .action(async (userId, options) => {
18
+ const context = configManager.getCurrentContext();
19
+ const environment = (options.env as Environment) || context.environment;
20
+ const tenant = options.tenant || context.tenant;
21
+
22
+ if (options.dryRun) {
23
+ console.log(chalk.bold('\n🔍 Dry-Run Mode\n'));
24
+ console.log(chalk.gray(`Would delete user: ${userId}`));
25
+ return;
26
+ }
27
+
28
+ if (!options.force) {
29
+ const { confirm } = await inquirer.prompt([
30
+ { type: 'confirm', name: 'confirm', message: `Delete user ${userId}?`, default: false },
31
+ ]);
32
+ if (!confirm) {
33
+ console.log(chalk.yellow('\n↩ Cancelled\n'));
34
+ process.exit(0);
35
+ }
36
+ }
37
+
38
+ const response = await apiClient.deleteUser(environment, tenant, userId);
39
+
40
+ if (!response.success) {
41
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
42
+ process.exit(1);
43
+ }
44
+
45
+ console.log(chalk.green('\n✓ User deleted successfully\n'));
46
+ });
47
+
48
+ return deleteCommand;
49
+ }
@@ -0,0 +1,41 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import inquirer from 'inquirer';
4
+ import { configManager } from '../../../core/config/manager.js';
5
+ import { apiClient } from '../../../core/api/client.js';
6
+ import { Environment } from '../../../types/index.js';
7
+
8
+ export function createUserDisableCommand(): Command {
9
+ const disableCommand = new Command('disable');
10
+ disableCommand.description('Disable a user');
11
+
12
+ disableCommand
13
+ .argument('<userId>', 'User ID')
14
+ .option('--force', 'Skip confirmation')
15
+ .action(async (userId, options) => {
16
+ const context = configManager.getCurrentContext();
17
+ const environment = (options.env as Environment) || context.environment;
18
+ const tenant = options.tenant || context.tenant;
19
+
20
+ if (!options.force) {
21
+ const { confirm } = await inquirer.prompt([
22
+ { type: 'confirm', name: 'confirm', message: `Disable user ${userId}?`, default: false },
23
+ ]);
24
+ if (!confirm) {
25
+ console.log(chalk.yellow('\n↩ Cancelled\n'));
26
+ process.exit(0);
27
+ }
28
+ }
29
+
30
+ const response = await apiClient.disableUser(environment, tenant, userId);
31
+
32
+ if (!response.success) {
33
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
34
+ process.exit(1);
35
+ }
36
+
37
+ console.log(chalk.green('\n✓ User disabled successfully\n'));
38
+ });
39
+
40
+ return disableCommand;
41
+ }
@@ -0,0 +1,30 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { configManager } from '../../../core/config/manager.js';
4
+ import { apiClient } from '../../../core/api/client.js';
5
+ import { Environment } from '../../../types/index.js';
6
+
7
+ export function createUserEnableCommand(): Command {
8
+ const enableCommand = new Command('enable');
9
+ enableCommand.description('Enable a user');
10
+
11
+ enableCommand
12
+ .argument('<userId>', 'User ID')
13
+ .option('--force', 'Skip confirmation')
14
+ .action(async (userId, options) => {
15
+ const context = configManager.getCurrentContext();
16
+ const environment = (options.env as Environment) || context.environment;
17
+ const tenant = options.tenant || context.tenant;
18
+
19
+ const response = await apiClient.enableUser(environment, tenant, userId);
20
+
21
+ if (!response.success) {
22
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
23
+ process.exit(1);
24
+ }
25
+
26
+ console.log(chalk.green('\n✓ User enabled successfully\n'));
27
+ });
28
+
29
+ return enableCommand;
30
+ }
@@ -0,0 +1,46 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { configManager } from '../../../core/config/manager.js';
4
+ import { apiClient } from '../../../core/api/client.js';
5
+ import { Environment } from '../../../types/index.js';
6
+
7
+ export function createUserGetCommand(): Command {
8
+ const getCommand = new Command('get');
9
+ getCommand.description('Get user details');
10
+
11
+ getCommand
12
+ .argument('<userId>', 'User ID')
13
+ .option('--json', 'Output as JSON')
14
+ .action(async (userId, options) => {
15
+ const context = configManager.getCurrentContext();
16
+ const environment = (options.env as Environment) || context.environment;
17
+ const tenant = options.tenant || context.tenant;
18
+
19
+ const response = await apiClient.getUser(environment, tenant, userId);
20
+
21
+ if (!response.success) {
22
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
23
+ process.exit(1);
24
+ }
25
+
26
+ const user = response.data as any;
27
+
28
+ if (options.json) {
29
+ console.log(JSON.stringify({ success: true, data: user }, null, 2));
30
+ return;
31
+ }
32
+
33
+ console.log(chalk.bold('\n👤 User Details\n'));
34
+ console.log(chalk.gray('ID: ') + user.userId);
35
+ console.log(chalk.gray('Name: ') + user.realName);
36
+ console.log(chalk.gray('Account: ') + user.account);
37
+ console.log(chalk.gray('Email: ') + (user.email || '-'));
38
+ console.log(chalk.gray('Status: ') + (user.statusFlag === 1 ? chalk.green('Enabled') : chalk.red('Disabled')));
39
+ console.log(chalk.gray('Employee: ') + (user.employeeName || '-'));
40
+ console.log(chalk.gray('Roles: ') + (user.roleNameList?.join(', ') || '-'));
41
+ console.log(chalk.gray('Created: ') + user.createTime);
42
+ console.log();
43
+ });
44
+
45
+ return getCommand;
46
+ }
@@ -0,0 +1,27 @@
1
+ import { Command } from 'commander';
2
+ import { createUserCreateCommand } from './create.js';
3
+ import { createUserListCommand } from './list.js';
4
+ import { createUserGetCommand } from './get.js';
5
+ import { createUserUpdateCommand } from './update.js';
6
+ import { createUserDeleteCommand } from './delete.js';
7
+ import { createUserEnableCommand } from './enable.js';
8
+ import { createUserDisableCommand } from './disable.js';
9
+ import { createUserMeCommand } from './me.js';
10
+ import { createUserResetPasswordCommand } from './reset-password.js';
11
+
12
+ export function createUsersCommand(): Command {
13
+ const usersCommand = new Command('users');
14
+ usersCommand.description('Manage users');
15
+
16
+ usersCommand.addCommand(createUserCreateCommand());
17
+ usersCommand.addCommand(createUserListCommand());
18
+ usersCommand.addCommand(createUserGetCommand());
19
+ usersCommand.addCommand(createUserUpdateCommand());
20
+ usersCommand.addCommand(createUserDeleteCommand());
21
+ usersCommand.addCommand(createUserEnableCommand());
22
+ usersCommand.addCommand(createUserDisableCommand());
23
+ usersCommand.addCommand(createUserMeCommand());
24
+ usersCommand.addCommand(createUserResetPasswordCommand());
25
+
26
+ return usersCommand;
27
+ }
@@ -0,0 +1,68 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import Table from 'cli-table3';
4
+ import { configManager } from '../../../core/config/manager.js';
5
+ import { apiClient } from '../../../core/api/client.js';
6
+ import { Environment } from '../../../types/index.js';
7
+
8
+ export function createUserListCommand(): Command {
9
+ const listCommand = new Command('list');
10
+ listCommand.description('List users with pagination');
11
+
12
+ listCommand
13
+ .option('-p, --page <number>', 'Page number', '1')
14
+ .option('-s, --size <number>', 'Page size', '20')
15
+ .option('--status <status>', 'Status (1=enabled, 2=disabled)')
16
+ .option('--account <account>', 'Filter by account')
17
+ .option('--real-name <realName>', 'Filter by name')
18
+ .option('--json', 'Output as JSON')
19
+ .action(async (options) => {
20
+ const context = configManager.getCurrentContext();
21
+ const environment = (options.env as Environment) || context.environment;
22
+ const tenant = options.tenant || context.tenant;
23
+
24
+ const params: any = {
25
+ pageNo: parseInt(options.page) - 1,
26
+ pageSize: parseInt(options.size),
27
+ };
28
+
29
+ if (options.status) params.status = parseInt(options.status);
30
+ if (options.account) params.account = options.account;
31
+ if (options.realName) params.realName = options.realName;
32
+
33
+ const response = await apiClient.listUsers(environment, tenant, params);
34
+
35
+ if (!response.success) {
36
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
37
+ process.exit(1);
38
+ }
39
+
40
+ const data = response.data as any;
41
+ const items = data?.rows || [];
42
+
43
+ if (options.json) {
44
+ console.log(JSON.stringify({ success: true, data: { items, pagination: data } }, null, 2));
45
+ return;
46
+ }
47
+
48
+ const table = new Table({
49
+ head: [chalk.bold('ID'), chalk.bold('Name'), chalk.bold('Account'), chalk.bold('Email'), chalk.bold('Status')],
50
+ colWidths: [10, 18, 18, 25, 10],
51
+ });
52
+
53
+ for (const user of items) {
54
+ table.push([
55
+ user.userId,
56
+ user.realName,
57
+ user.account,
58
+ user.email || '-',
59
+ user.statusFlag === 1 ? chalk.green('Enabled') : chalk.red('Disabled'),
60
+ ]);
61
+ }
62
+
63
+ console.log(table.toString());
64
+ console.log(chalk.gray(`\nTotal: ${data?.totalRows || 0} users`));
65
+ });
66
+
67
+ return listCommand;
68
+ }
@@ -0,0 +1,42 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { configManager } from '../../../core/config/manager.js';
4
+ import { apiClient } from '../../../core/api/client.js';
5
+ import { Environment } from '../../../types/index.js';
6
+
7
+ export function createUserMeCommand(): Command {
8
+ const meCommand = new Command('me');
9
+ meCommand.description('Get current user info');
10
+
11
+ meCommand
12
+ .option('--json', 'Output as JSON')
13
+ .action(async (options) => {
14
+ const context = configManager.getCurrentContext();
15
+ const environment = (options.env as Environment) || context.environment;
16
+ const tenant = options.tenant || context.tenant;
17
+
18
+ const response = await apiClient.getCurrentUser(environment, tenant);
19
+
20
+ if (!response.success) {
21
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
22
+ process.exit(1);
23
+ }
24
+
25
+ const user = response.data as any;
26
+
27
+ if (options.json) {
28
+ console.log(JSON.stringify({ success: true, data: user }, null, 2));
29
+ return;
30
+ }
31
+
32
+ console.log(chalk.bold('\n👤 Current User\n'));
33
+ console.log(chalk.gray('ID: ') + user.userId);
34
+ console.log(chalk.gray('Name: ') + user.realName);
35
+ console.log(chalk.gray('Account: ') + user.account);
36
+ console.log(chalk.gray('Email: ') + (user.email || '-'));
37
+ console.log(chalk.gray('Roles: ') + (user.roleNameList?.join(', ') || '-'));
38
+ console.log();
39
+ });
40
+
41
+ return meCommand;
42
+ }
@@ -0,0 +1,42 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import inquirer from 'inquirer';
4
+ import { configManager } from '../../../core/config/manager.js';
5
+ import { apiClient } from '../../../core/api/client.js';
6
+ import { Environment } from '../../../types/index.js';
7
+
8
+ export function createUserResetPasswordCommand(): Command {
9
+ const resetCommand = new Command('reset-password');
10
+ resetCommand.description('Reset user password');
11
+
12
+ resetCommand
13
+ .argument('<userId>', 'User ID')
14
+ .option('--force', 'Skip confirmation')
15
+ .action(async (userId, options) => {
16
+ const context = configManager.getCurrentContext();
17
+ const environment = (options.env as Environment) || context.environment;
18
+ const tenant = options.tenant || context.tenant;
19
+
20
+ if (!options.force) {
21
+ const { confirm } = await inquirer.prompt([
22
+ { type: 'confirm', name: 'confirm', message: `Reset password for user ${userId}?`, default: false },
23
+ ]);
24
+ if (!confirm) {
25
+ console.log(chalk.yellow('\n↩ Cancelled\n'));
26
+ process.exit(0);
27
+ }
28
+ }
29
+
30
+ const response = await apiClient.resetPassword(environment, tenant, userId);
31
+
32
+ if (!response.success) {
33
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
34
+ process.exit(1);
35
+ }
36
+
37
+ console.log(chalk.green('\n✓ Password reset successfully\n'));
38
+ console.log(chalk.yellow('Note: New password will be sent to user email\n'));
39
+ });
40
+
41
+ return resetCommand;
42
+ }
@@ -0,0 +1,48 @@
1
+ import { Command } from 'commander';
2
+ import chalk from 'chalk';
3
+ import { configManager } from '../../../core/config/manager.js';
4
+ import { apiClient } from '../../../core/api/client.js';
5
+ import { Environment } from '../../../types/index.js';
6
+
7
+ export function createUserUpdateCommand(): Command {
8
+ const updateCommand = new Command('update');
9
+ updateCommand.description('Update user information');
10
+
11
+ updateCommand
12
+ .argument('<userId>', 'User ID')
13
+ .option('-n, --name <name>', 'User real name')
14
+ .option('-e, --email <email>', 'User email')
15
+ .option('-r, --role-ids <roleIds>', 'Role IDs (comma-separated)')
16
+ .option('--dry-run', 'Preview without executing')
17
+ .option('--json', 'Output as JSON')
18
+ .action(async (userId, options) => {
19
+ const context = configManager.getCurrentContext();
20
+ const environment = (options.env as Environment) || context.environment;
21
+ const tenant = options.tenant || context.tenant;
22
+
23
+ const updateData: any = { userId };
24
+ if (options.name) updateData.realName = options.name;
25
+ if (options.email) updateData.email = options.email;
26
+ if (options.roleIds) {
27
+ updateData.roleIdList = options.roleIds.split(',').map((id: string) => id.trim());
28
+ }
29
+
30
+ if (options.dryRun) {
31
+ console.log(chalk.bold('\n🔍 Dry-Run Mode\n'));
32
+ console.log(chalk.gray('Update Data:'));
33
+ console.log(JSON.stringify(updateData, null, 2));
34
+ return;
35
+ }
36
+
37
+ const response = await apiClient.updateUser(environment, tenant, updateData);
38
+
39
+ if (!response.success) {
40
+ console.error(chalk.red(`\n✗ Failed: ${response.error?.message}\n`));
41
+ process.exit(1);
42
+ }
43
+
44
+ console.log(chalk.green('\n✓ User updated successfully\n'));
45
+ });
46
+
47
+ return updateCommand;
48
+ }