@newpeak/barista-cli 0.1.4 → 0.1.5

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 (169) hide show
  1. package/dist/commands/liberica/auth/index.d.ts.map +1 -1
  2. package/dist/commands/liberica/auth/index.js +5 -0
  3. package/dist/commands/liberica/auth/index.js.map +1 -1
  4. package/dist/commands/liberica/index.d.ts.map +1 -1
  5. package/dist/commands/liberica/index.js +8 -0
  6. package/dist/commands/liberica/index.js.map +1 -1
  7. package/dist/commands/liberica/materials/create.d.ts +3 -0
  8. package/dist/commands/liberica/materials/create.d.ts.map +1 -0
  9. package/dist/commands/liberica/materials/create.js +154 -0
  10. package/dist/commands/liberica/materials/create.js.map +1 -0
  11. package/dist/commands/liberica/materials/delete.d.ts +3 -0
  12. package/dist/commands/liberica/materials/delete.d.ts.map +1 -0
  13. package/dist/commands/liberica/materials/delete.js +104 -0
  14. package/dist/commands/liberica/materials/delete.js.map +1 -0
  15. package/dist/commands/liberica/materials/disable.d.ts +3 -0
  16. package/dist/commands/liberica/materials/disable.d.ts.map +1 -0
  17. package/dist/commands/liberica/materials/disable.js +146 -0
  18. package/dist/commands/liberica/materials/disable.js.map +1 -0
  19. package/dist/commands/liberica/materials/enable.d.ts +3 -0
  20. package/dist/commands/liberica/materials/enable.d.ts.map +1 -0
  21. package/dist/commands/liberica/materials/enable.js +126 -0
  22. package/dist/commands/liberica/materials/enable.js.map +1 -0
  23. package/dist/commands/liberica/materials/get.d.ts +3 -0
  24. package/dist/commands/liberica/materials/get.d.ts.map +1 -0
  25. package/dist/commands/liberica/materials/get.js +71 -0
  26. package/dist/commands/liberica/materials/get.js.map +1 -0
  27. package/dist/commands/liberica/materials/index.d.ts +3 -0
  28. package/dist/commands/liberica/materials/index.d.ts.map +1 -0
  29. package/dist/commands/liberica/materials/index.js +21 -0
  30. package/dist/commands/liberica/materials/index.js.map +1 -0
  31. package/dist/commands/liberica/materials/list.d.ts +3 -0
  32. package/dist/commands/liberica/materials/list.d.ts.map +1 -0
  33. package/dist/commands/liberica/materials/list.js +107 -0
  34. package/dist/commands/liberica/materials/list.js.map +1 -0
  35. package/dist/commands/liberica/materials/update.d.ts +3 -0
  36. package/dist/commands/liberica/materials/update.d.ts.map +1 -0
  37. package/dist/commands/liberica/materials/update.js +118 -0
  38. package/dist/commands/liberica/materials/update.js.map +1 -0
  39. package/dist/commands/liberica/suppliers/create.d.ts +3 -0
  40. package/dist/commands/liberica/suppliers/create.d.ts.map +1 -0
  41. package/dist/commands/liberica/suppliers/create.js +140 -0
  42. package/dist/commands/liberica/suppliers/create.js.map +1 -0
  43. package/dist/commands/liberica/suppliers/delete.d.ts +3 -0
  44. package/dist/commands/liberica/suppliers/delete.d.ts.map +1 -0
  45. package/dist/commands/liberica/suppliers/delete.js +102 -0
  46. package/dist/commands/liberica/suppliers/delete.js.map +1 -0
  47. package/dist/commands/liberica/suppliers/disable.d.ts +3 -0
  48. package/dist/commands/liberica/suppliers/disable.d.ts.map +1 -0
  49. package/dist/commands/liberica/suppliers/disable.js +144 -0
  50. package/dist/commands/liberica/suppliers/disable.js.map +1 -0
  51. package/dist/commands/liberica/suppliers/enable.d.ts +3 -0
  52. package/dist/commands/liberica/suppliers/enable.d.ts.map +1 -0
  53. package/dist/commands/liberica/suppliers/enable.js +124 -0
  54. package/dist/commands/liberica/suppliers/enable.js.map +1 -0
  55. package/dist/commands/liberica/suppliers/get.d.ts +3 -0
  56. package/dist/commands/liberica/suppliers/get.d.ts.map +1 -0
  57. package/dist/commands/liberica/suppliers/get.js +75 -0
  58. package/dist/commands/liberica/suppliers/get.js.map +1 -0
  59. package/dist/commands/liberica/suppliers/index.d.ts +3 -0
  60. package/dist/commands/liberica/suppliers/index.d.ts.map +1 -0
  61. package/dist/commands/liberica/suppliers/index.js +21 -0
  62. package/dist/commands/liberica/suppliers/index.js.map +1 -0
  63. package/dist/commands/liberica/suppliers/list.d.ts +3 -0
  64. package/dist/commands/liberica/suppliers/list.d.ts.map +1 -0
  65. package/dist/commands/liberica/suppliers/list.js +100 -0
  66. package/dist/commands/liberica/suppliers/list.js.map +1 -0
  67. package/dist/commands/liberica/suppliers/update.d.ts +3 -0
  68. package/dist/commands/liberica/suppliers/update.d.ts.map +1 -0
  69. package/dist/commands/liberica/suppliers/update.js +122 -0
  70. package/dist/commands/liberica/suppliers/update.js.map +1 -0
  71. package/dist/commands/liberica/uoms/create.d.ts +3 -0
  72. package/dist/commands/liberica/uoms/create.d.ts.map +1 -0
  73. package/dist/commands/liberica/uoms/create.js +120 -0
  74. package/dist/commands/liberica/uoms/create.js.map +1 -0
  75. package/dist/commands/liberica/uoms/delete.d.ts +3 -0
  76. package/dist/commands/liberica/uoms/delete.d.ts.map +1 -0
  77. package/dist/commands/liberica/uoms/delete.js +104 -0
  78. package/dist/commands/liberica/uoms/delete.js.map +1 -0
  79. package/dist/commands/liberica/uoms/disable.d.ts +3 -0
  80. package/dist/commands/liberica/uoms/disable.d.ts.map +1 -0
  81. package/dist/commands/liberica/uoms/disable.js +146 -0
  82. package/dist/commands/liberica/uoms/disable.js.map +1 -0
  83. package/dist/commands/liberica/uoms/enable.d.ts +3 -0
  84. package/dist/commands/liberica/uoms/enable.d.ts.map +1 -0
  85. package/dist/commands/liberica/uoms/enable.js +126 -0
  86. package/dist/commands/liberica/uoms/enable.js.map +1 -0
  87. package/dist/commands/liberica/uoms/get.d.ts +3 -0
  88. package/dist/commands/liberica/uoms/get.d.ts.map +1 -0
  89. package/dist/commands/liberica/uoms/get.js +71 -0
  90. package/dist/commands/liberica/uoms/get.js.map +1 -0
  91. package/dist/commands/liberica/uoms/index.d.ts +3 -0
  92. package/dist/commands/liberica/uoms/index.d.ts.map +1 -0
  93. package/dist/commands/liberica/uoms/index.js +21 -0
  94. package/dist/commands/liberica/uoms/index.js.map +1 -0
  95. package/dist/commands/liberica/uoms/list.d.ts +3 -0
  96. package/dist/commands/liberica/uoms/list.d.ts.map +1 -0
  97. package/dist/commands/liberica/uoms/list.js +98 -0
  98. package/dist/commands/liberica/uoms/list.js.map +1 -0
  99. package/dist/commands/liberica/uoms/update.d.ts +3 -0
  100. package/dist/commands/liberica/uoms/update.d.ts.map +1 -0
  101. package/dist/commands/liberica/uoms/update.js +115 -0
  102. package/dist/commands/liberica/uoms/update.js.map +1 -0
  103. package/dist/core/api/client.d.ts +24 -0
  104. package/dist/core/api/client.d.ts.map +1 -1
  105. package/dist/core/api/client.js +465 -0
  106. package/dist/core/api/client.js.map +1 -1
  107. package/dist/index.js +1 -1
  108. package/dist/types/index.d.ts +5 -1
  109. package/dist/types/index.d.ts.map +1 -1
  110. package/dist/types/material.d.ts +49 -0
  111. package/dist/types/material.d.ts.map +1 -0
  112. package/dist/types/material.js +2 -0
  113. package/dist/types/material.js.map +1 -0
  114. package/dist/types/supplier.d.ts +53 -0
  115. package/dist/types/supplier.d.ts.map +1 -0
  116. package/dist/types/supplier.js +2 -0
  117. package/dist/types/supplier.js.map +1 -0
  118. package/dist/types/uom.d.ts +47 -0
  119. package/dist/types/uom.d.ts.map +1 -0
  120. package/dist/types/uom.js +2 -0
  121. package/dist/types/uom.js.map +1 -0
  122. package/docs/commands/liberica/materials-create.md +293 -0
  123. package/docs/commands/liberica/materials-delete.md +240 -0
  124. package/docs/commands/liberica/materials-disable.md +150 -0
  125. package/docs/commands/liberica/materials-enable.md +146 -0
  126. package/docs/commands/liberica/materials-get.md +188 -0
  127. package/docs/commands/liberica/materials-list.md +198 -0
  128. package/docs/commands/liberica/materials-update.md +250 -0
  129. package/docs/commands/liberica/uoms-create.md +136 -0
  130. package/docs/commands/liberica/uoms-delete.md +119 -0
  131. package/docs/commands/liberica/uoms-disable.md +117 -0
  132. package/docs/commands/liberica/uoms-enable.md +115 -0
  133. package/docs/commands/liberica/uoms-get.md +119 -0
  134. package/docs/commands/liberica/uoms-list.md +155 -0
  135. package/docs/commands/liberica/uoms-update.md +148 -0
  136. package/package.json +2 -4
  137. package/src/commands/liberica/auth/index.ts +6 -0
  138. package/src/commands/liberica/index.ts +8 -0
  139. package/src/commands/liberica/materials/create.ts +168 -0
  140. package/src/commands/liberica/materials/delete.ts +105 -0
  141. package/src/commands/liberica/materials/disable.ts +148 -0
  142. package/src/commands/liberica/materials/enable.ts +129 -0
  143. package/src/commands/liberica/materials/get.ts +83 -0
  144. package/src/commands/liberica/materials/index.ts +23 -0
  145. package/src/commands/liberica/materials/list.ts +142 -0
  146. package/src/commands/liberica/materials/update.ts +125 -0
  147. package/src/commands/liberica/suppliers/create.ts +149 -0
  148. package/src/commands/liberica/suppliers/delete.ts +102 -0
  149. package/src/commands/liberica/suppliers/disable.ts +145 -0
  150. package/src/commands/liberica/suppliers/enable.ts +126 -0
  151. package/src/commands/liberica/suppliers/get.ts +86 -0
  152. package/src/commands/liberica/suppliers/index.ts +23 -0
  153. package/src/commands/liberica/suppliers/list.ts +134 -0
  154. package/src/commands/liberica/suppliers/update.ts +128 -0
  155. package/src/commands/liberica/uoms/create.ts +134 -0
  156. package/src/commands/liberica/uoms/delete.ts +105 -0
  157. package/src/commands/liberica/uoms/disable.ts +148 -0
  158. package/src/commands/liberica/uoms/enable.ts +129 -0
  159. package/src/commands/liberica/uoms/get.ts +83 -0
  160. package/src/commands/liberica/uoms/index.ts +23 -0
  161. package/src/commands/liberica/uoms/list.ts +129 -0
  162. package/src/commands/liberica/uoms/update.ts +124 -0
  163. package/src/core/api/client.ts +585 -0
  164. package/src/index.ts +1 -1
  165. package/src/types/index.ts +5 -2
  166. package/src/types/material.ts +61 -0
  167. package/src/types/supplier.ts +66 -0
  168. package/src/types/uom.ts +60 -0
  169. package/bin/barista.js +0 -3
@@ -0,0 +1,134 @@
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 { SupplierListResponse, StatusFlag } from '../../../types/supplier.js';
7
+ import { Environment } from '../../../types/index.js';
8
+
9
+ export function createSupplierListCommand(): Command {
10
+ const listCommand = new Command('list');
11
+ listCommand.description('List suppliers with pagination');
12
+
13
+ listCommand
14
+ .option('-p, --page <number>', 'Page number', '1')
15
+ .option('-s, --size <number>', 'Page size', '20')
16
+ .option('--status <number>', 'Status filter (1=enable, 2=disable)')
17
+ .option('--keyword <string>', 'Keyword search (supplierName and supplierCode)')
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 page = parseInt(options.page as string, 10) - 1; // API uses 0-based pagination
25
+ const size = parseInt(options.size as string, 10);
26
+
27
+ const params: {
28
+ pageNo: number;
29
+ pageSize: number;
30
+ status?: StatusFlag;
31
+ supplierCode?: string;
32
+ supplierName?: string;
33
+ } = { pageNo: page, pageSize: size };
34
+
35
+ if (options.status !== undefined) {
36
+ const statusNum = parseInt(options.status as string, 10);
37
+ if (statusNum === 1 || statusNum === 2) {
38
+ params.status = statusNum as StatusFlag;
39
+ }
40
+ }
41
+
42
+ // Keyword searches both supplierName and supplierCode
43
+ if (options.keyword !== undefined) {
44
+ const keyword = options.keyword as string;
45
+ params.supplierCode = keyword;
46
+ params.supplierName = keyword;
47
+ }
48
+
49
+ const response = await apiClient.listSuppliers(environment, tenant, params);
50
+
51
+ if (!response.success) {
52
+ console.error(chalk.red(`\n✗ Failed to list suppliers: ${response.error?.message || 'Unknown error'}`));
53
+ if (response.error?.code) {
54
+ console.error(chalk.gray(` Error code: ${response.error.code}`));
55
+ }
56
+ console.error();
57
+ process.exit(1);
58
+ }
59
+
60
+ const data = response.data as SupplierListResponse | null;
61
+
62
+ if (!data) {
63
+ if (options.json) {
64
+ console.log(JSON.stringify({ success: true, data: { items: [], pagination: { pageNo: 0, pageSize: 20, totalRows: 0 } } }, null, 2));
65
+ } else {
66
+ console.log(chalk.bold('\n📋 Supplier List\n'));
67
+ console.log(chalk.gray(' No suppliers found\n'));
68
+ }
69
+ return;
70
+ }
71
+
72
+ if (options.json) {
73
+ console.log(
74
+ JSON.stringify(
75
+ {
76
+ success: true,
77
+ data: {
78
+ items: data.rows || [],
79
+ pagination: {
80
+ pageNo: data.pageNo,
81
+ pageSize: data.pageSize,
82
+ totalRows: data.totalRows,
83
+ },
84
+ },
85
+ },
86
+ null,
87
+ 2
88
+ )
89
+ );
90
+ return;
91
+ }
92
+
93
+ const records = data.rows || [];
94
+
95
+ if (records.length === 0) {
96
+ console.log(chalk.bold('\n📋 Supplier List\n'));
97
+ console.log(chalk.gray(' No suppliers found\n'));
98
+ return;
99
+ }
100
+
101
+ console.log(chalk.bold('\n📋 Supplier List\n'));
102
+
103
+ const table = new Table({
104
+ head: [chalk.bold('ID'), chalk.bold('Code'), chalk.bold('Name'), chalk.bold('Type'), chalk.bold('Status')],
105
+ colWidths: [12, 15, 25, 15, 10],
106
+ style: {
107
+ head: [],
108
+ border: [],
109
+ },
110
+ });
111
+
112
+ for (const supplier of records) {
113
+ const statusText = supplier.statusFlag === 1 ? chalk.green('Enable') : chalk.red('Disable');
114
+ table.push([
115
+ supplier.supplierId,
116
+ supplier.supplierCode || '-',
117
+ supplier.supplierName || '-',
118
+ supplier.supplierType || '-',
119
+ statusText,
120
+ ]);
121
+ }
122
+
123
+ console.log(table.toString());
124
+ console.log();
125
+ console.log(
126
+ chalk.gray(
127
+ ` Total: ${data.totalRows} | Page: ${data.pageNo} / ${Math.ceil(data.totalRows / data.pageSize) || 1} | Size: ${data.pageSize}`
128
+ )
129
+ );
130
+ console.log();
131
+ });
132
+
133
+ return listCommand;
134
+ }
@@ -0,0 +1,128 @@
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
+ import { Supplier, UpdateSupplierRequest } from '../../../types/supplier.js';
7
+
8
+ export function createSupplierUpdateCommand(): Command {
9
+ const updateCommand = new Command('update');
10
+ updateCommand
11
+ .description('Update supplier information')
12
+ .argument('<supplierId>', 'Supplier ID')
13
+ .option('-n, --name <name>', 'Supplier name')
14
+ .option('-t, --type <type>', 'Supplier type')
15
+ .option('--contact <contact>', 'Contact person')
16
+ .option('-p, --phone <phone>', 'Phone number')
17
+ .option('-a, --address <address>', 'Address')
18
+ .option('--dry-run', 'Preview changes without making API call')
19
+ .option('--json', 'Output result as JSON')
20
+ .action(async (supplierId: string, options: Record<string, unknown>) => {
21
+ const context = configManager.getCurrentContext();
22
+ const environment = context.environment as Environment;
23
+ const tenant = context.tenant;
24
+
25
+ const fields: Partial<UpdateSupplierRequest> = {};
26
+ if (options.name) fields.supplierName = options.name as string;
27
+ if (options.type) fields.supplierType = options.type as string;
28
+ if (options.contact) fields.contactPerson = options.contact as string;
29
+ if (options.phone) fields.contactPhone = options.phone as string;
30
+ if (options.address) fields.address = options.address as string;
31
+
32
+ const providedFields = Object.keys(fields).filter(
33
+ (k) => fields[k as keyof UpdateSupplierRequest] !== undefined
34
+ );
35
+ if (providedFields.length === 0) {
36
+ console.error(
37
+ chalk.red('\n✗ No fields to update. Provide at least one of: --name, --type, --contact, --phone, --address\n')
38
+ );
39
+ process.exit(1);
40
+ }
41
+
42
+ if (options.phone && !/^\+?[\d\s\-()]+$/.test(options.phone as string)) {
43
+ console.error(chalk.red('\n✗ Invalid phone number format\n'));
44
+ process.exit(1);
45
+ }
46
+
47
+ if (options.dryRun) {
48
+ console.log(chalk.bold(`\n🏭 Update Supplier — Dry Run (${environment})\n`));
49
+ console.log(chalk.gray(` Supplier ID: ${supplierId}`));
50
+ console.log(chalk.gray('\n Changes to be applied:'));
51
+ for (const field of providedFields) {
52
+ const label = field.replace(/([A-Z])/g, (m) => ` ${m.toLowerCase()}`).trim();
53
+ console.log(chalk.cyan(` ${label}: "${fields[field as keyof UpdateSupplierRequest]}"`));
54
+ }
55
+ console.log();
56
+ return;
57
+ }
58
+
59
+ let currentSupplier: Supplier | undefined;
60
+ try {
61
+ const supplierResponse = await apiClient.getSupplier(environment, tenant, supplierId);
62
+ if (!supplierResponse.success || !supplierResponse.data) {
63
+ console.error(chalk.red(`\n✗ Supplier not found: ${supplierId}`));
64
+ if (supplierResponse.error?.message) {
65
+ console.error(chalk.gray(` ${supplierResponse.error.message}`));
66
+ }
67
+ if (supplierResponse.error?.code) {
68
+ console.error(chalk.gray(` Error code: ${supplierResponse.error.code}`));
69
+ }
70
+ console.error();
71
+ process.exit(1);
72
+ }
73
+ currentSupplier = supplierResponse.data as Supplier;
74
+ } catch (error) {
75
+ console.error(chalk.red(`\n✗ Failed to fetch supplier: ${error instanceof Error ? error.message : 'Unknown error'}\n`));
76
+ process.exit(1);
77
+ }
78
+
79
+ console.log(chalk.bold(`\n🏭 Update Supplier (${environment})\n`));
80
+ console.log(chalk.gray(` Supplier ID: ${supplierId}`));
81
+ console.log(chalk.gray(` Current Name: ${currentSupplier.supplierName}`));
82
+ console.log(chalk.gray('\n Changes:'));
83
+ for (const field of providedFields) {
84
+ const label = field.replace(/([A-Z])/g, (m) => ` ${m.toLowerCase()}`).trim();
85
+ const currentVal = (currentSupplier as unknown as Record<string, unknown>)[field] ?? '(not set)';
86
+ const newVal = fields[field as keyof UpdateSupplierRequest];
87
+ console.log(chalk.cyan(` ${label}: "${currentVal}" → "${newVal}"`));
88
+ }
89
+
90
+ const updateData: UpdateSupplierRequest = { supplierId, ...fields };
91
+ try {
92
+ const response = await apiClient.updateSupplier(environment, tenant, updateData);
93
+
94
+ if (response.success) {
95
+ if (options.json) {
96
+ console.log(JSON.stringify({ success: true, data: response.data }, null, 2));
97
+ } else {
98
+ console.log(chalk.green(`\n✓ Supplier updated successfully\n`));
99
+ }
100
+ } else {
101
+ if (options.json) {
102
+ console.log(JSON.stringify({ success: false, error: response.error }, null, 2));
103
+ } else {
104
+ console.error(chalk.red(`\n✗ Update failed: ${response.error?.message || 'Unknown error'}`));
105
+ if (response.error?.code) {
106
+ console.error(chalk.gray(` Error code: ${response.error.code}`));
107
+ }
108
+ console.error();
109
+ }
110
+ process.exit(1);
111
+ }
112
+ } catch (error) {
113
+ if (options.json) {
114
+ console.log(
115
+ JSON.stringify({
116
+ success: false,
117
+ error: { message: error instanceof Error ? error.message : 'Unknown error' },
118
+ })
119
+ );
120
+ } else {
121
+ console.error(chalk.red(`\n✗ Error: ${error instanceof Error ? error.message : 'Unknown error'}\n`));
122
+ }
123
+ process.exit(1);
124
+ }
125
+ });
126
+
127
+ return updateCommand;
128
+ }
@@ -0,0 +1,134 @@
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 { CreateUomRequest } from '../../../types/uom.js';
7
+
8
+ function formatTable(data: CreateUomRequest): string {
9
+ const lines: string[] = [];
10
+ lines.push(` ${chalk.gray('Code:')} ${data.uomCode || '(not set)'}`);
11
+ lines.push(` ${chalk.gray('Name:')} ${data.uomName || '(not set)'}`);
12
+ lines.push(` ${chalk.gray('Fraction Places:')} ${data.uomFractionPlaces ?? '(default)'}`);
13
+ if (data.remark) lines.push(` ${chalk.gray('Remark:')} ${data.remark}`);
14
+ return lines.join('\n');
15
+ }
16
+
17
+ export function createUomCreateCommand(): Command {
18
+ const cmd = new Command('create');
19
+ cmd.description('Create a new UOM');
20
+
21
+ cmd
22
+ .option('-c, --code <code>', 'UOM code (required)')
23
+ .option('-n, --name <name>', 'UOM name (required)')
24
+ .option('--fraction-places <number>', 'Fraction places', '1')
25
+ .option('--remark <text>', 'Remark')
26
+ .option('--dry-run', 'Preview without making API call')
27
+ .option('--json', 'Output as JSON');
28
+
29
+ cmd.action(async () => {
30
+ const context = configManager.getCurrentContext();
31
+ const opts = cmd.opts();
32
+
33
+ let code = opts.code as string | undefined;
34
+ let name = opts.name as string | undefined;
35
+ const fractionPlaces = parseInt(opts.fractionPlaces as string, 10) || 1;
36
+ const remark = opts.remark as string | undefined;
37
+ const dryRun = opts.dryRun === true;
38
+ const outputJson = (opts as any).json === true || process.argv.includes('--json');
39
+
40
+ if (!code) {
41
+ const { inputCode } = await inquirer.prompt([
42
+ {
43
+ type: 'input',
44
+ name: 'inputCode',
45
+ message: 'Enter UOM code:',
46
+ validate: (input: string) => input.trim().length > 0 || 'UOM code is required',
47
+ },
48
+ ]);
49
+ code = inputCode;
50
+ }
51
+
52
+ if (!name) {
53
+ const { inputName } = await inquirer.prompt([
54
+ {
55
+ type: 'input',
56
+ name: 'inputName',
57
+ message: 'Enter UOM name:',
58
+ validate: (input: string) => input.trim().length > 0 || 'UOM name is required',
59
+ },
60
+ ]);
61
+ name = inputName;
62
+ }
63
+
64
+ const data: CreateUomRequest = {
65
+ uomCode: code!,
66
+ uomName: name!,
67
+ uomFractionPlaces: fractionPlaces,
68
+ remark: remark,
69
+ };
70
+
71
+ if (dryRun) {
72
+ if (outputJson) {
73
+ console.log(JSON.stringify({ success: true, dryRun: true, data }));
74
+ } else {
75
+ console.log(chalk.bold('\n🔍 Dry-Run Mode: No changes will be made\n'));
76
+ console.log(' UOM to be created:');
77
+ console.log(formatTable(data));
78
+ console.log();
79
+ }
80
+ return;
81
+ }
82
+
83
+ if (!outputJson) {
84
+ console.log(chalk.bold('\n📝 Creating UOM\n'));
85
+ }
86
+
87
+ const response = await apiClient.createUom(context.environment, context.tenant, data);
88
+
89
+ if (!response.success) {
90
+ const errorMsg = response.error?.message || 'Failed to create UOM';
91
+ const errorCode = response.error?.code || 'CREATE_UOM_ERROR';
92
+ if (outputJson) {
93
+ console.log(JSON.stringify({ success: false, error: { code: errorCode, message: errorMsg } }));
94
+ } else {
95
+ console.error(chalk.red(`\n✗ Failed to create UOM: ${errorMsg}`));
96
+ if (response.error?.code) {
97
+ console.error(chalk.gray(` Error code: ${response.error.code}`));
98
+ }
99
+ console.error();
100
+ }
101
+ process.exit(1);
102
+ }
103
+
104
+ if (response.success) {
105
+ const uom = response.data as {
106
+ uomId?: number;
107
+ uomCode?: string;
108
+ uomName?: string;
109
+ uomFractionPlaces?: number;
110
+ statusFlag?: number;
111
+ remark?: string;
112
+ createTime?: string;
113
+ } | undefined;
114
+
115
+ if (outputJson) {
116
+ console.log(JSON.stringify({ success: true, data: uom }));
117
+ } else {
118
+ console.log(chalk.green('✓ UOM created successfully\n'));
119
+ if (uom?.uomId) console.log(` ${chalk.gray('UOM ID:')} ${chalk.green(String(uom.uomId))}`);
120
+ if (uom?.uomCode) console.log(` ${chalk.gray('Code:')} ${uom.uomCode}`);
121
+ if (uom?.uomName) console.log(` ${chalk.gray('Name:')} ${uom.uomName}`);
122
+ if (uom?.uomFractionPlaces !== undefined) console.log(` ${chalk.gray('Fraction Places:')} ${uom.uomFractionPlaces}`);
123
+ if (uom?.statusFlag !== undefined) {
124
+ const statusText = uom.statusFlag === 1 ? 'Enabled' : 'Disabled';
125
+ console.log(` ${chalk.gray('Status:')} ${chalk.green(statusText)}`);
126
+ }
127
+ if (uom?.remark) console.log(` ${chalk.gray('Remark:')} ${uom.remark}`);
128
+ console.log();
129
+ }
130
+ }
131
+ });
132
+
133
+ return cmd;
134
+ }
@@ -0,0 +1,105 @@
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
+ import { Uom } from '../../../types/uom.js';
7
+
8
+ export function createUomDeleteCommand(): Command {
9
+ const deleteCommand = new Command('delete');
10
+ deleteCommand
11
+ .description('Delete a UOM')
12
+ .argument('<uomId>', 'UOM ID')
13
+ .option('--force', 'Skip confirmation and delete directly')
14
+ .option('--json', 'Output as JSON')
15
+ .action(async (uomId: string, options: Record<string, unknown>) => {
16
+ const context = configManager.getCurrentContext();
17
+ const environment = context.environment as Environment;
18
+ const tenant = context.tenant;
19
+
20
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
21
+ (options as any).json = process.argv.includes('--json');
22
+ const jsonOutput = options.json === true;
23
+
24
+ if (!jsonOutput) {
25
+ console.log(chalk.bold(`\n🗑️ Delete UOM (${environment})\n`));
26
+ console.log(chalk.gray(` UOM ID: ${uomId}`));
27
+ }
28
+
29
+ let uom: Uom | undefined;
30
+ try {
31
+ const uomResponse = await apiClient.getUom(environment, tenant, uomId);
32
+ if (!uomResponse.success || !uomResponse.data || !('uomId' in uomResponse.data)) {
33
+ const errMsg = `UOM not found: ${uomId}`;
34
+ if (jsonOutput) {
35
+ console.log(JSON.stringify({ success: false, error: { code: 'NOT_FOUND', message: errMsg } }));
36
+ } else {
37
+ console.error(chalk.red(`\n✗ ${errMsg}\n`));
38
+ }
39
+ process.exit(1);
40
+ }
41
+ uom = uomResponse.data as Uom;
42
+ } catch (error) {
43
+ const errMsg = error instanceof Error ? error.message : 'Unknown error';
44
+ if (jsonOutput) {
45
+ console.log(JSON.stringify({ success: false, error: { code: 'FETCH_ERROR', message: `Failed to fetch UOM: ${errMsg}` } }));
46
+ } else {
47
+ console.error(chalk.red(`\n✗ Failed to fetch UOM: ${errMsg}\n`));
48
+ }
49
+ process.exit(1);
50
+ }
51
+
52
+ if (!jsonOutput) {
53
+ console.log(chalk.gray(` Name: ${uom.uomName}`));
54
+ console.log(chalk.gray(` Code: ${uom.uomCode}`));
55
+ if (uom.uomFractionPlaces !== undefined) {
56
+ console.log(chalk.gray(` Fraction Places: ${uom.uomFractionPlaces}`));
57
+ }
58
+ }
59
+
60
+ if (!options.force) {
61
+ if (jsonOutput) {
62
+ console.log(JSON.stringify({ success: true, dryRun: true, uom }));
63
+ } else {
64
+ console.log(chalk.cyan('\n🔍 Dry-Run Mode: No actual deletion will be made\n'));
65
+ console.log(chalk.yellow(' To delete, add: --force\n'));
66
+ }
67
+ return;
68
+ }
69
+
70
+ try {
71
+ const response = await apiClient.deleteUom(environment, tenant, uomId);
72
+
73
+ if (response.success) {
74
+ if (jsonOutput) {
75
+ console.log(JSON.stringify({ success: true, uomId, name: uom.uomName }));
76
+ } else {
77
+ console.log(chalk.green(`\n✓ UOM "${uom.uomName}" (ID: ${uomId}) deleted\n`));
78
+ }
79
+ } else {
80
+ const errorMsg = response.error?.message || 'Unknown error';
81
+ const errorCode = response.error?.code || 'DELETE_ERROR';
82
+ if (jsonOutput) {
83
+ console.log(JSON.stringify({ success: false, error: { code: errorCode, message: errorMsg } }));
84
+ } else {
85
+ console.error(chalk.red(`\n✗ Failed to delete UOM: ${errorMsg}`));
86
+ if (response.error?.code) {
87
+ console.error(chalk.gray(` Error code: ${response.error.code}`));
88
+ }
89
+ console.error();
90
+ }
91
+ process.exit(1);
92
+ }
93
+ } catch (error) {
94
+ const errMsg = error instanceof Error ? error.message : 'Unknown error';
95
+ if (jsonOutput) {
96
+ console.log(JSON.stringify({ success: false, error: { code: 'ERROR', message: errMsg } }));
97
+ } else {
98
+ console.error(chalk.red(`\n✗ Error: ${errMsg}\n`));
99
+ }
100
+ process.exit(1);
101
+ }
102
+ });
103
+
104
+ return deleteCommand;
105
+ }
@@ -0,0 +1,148 @@
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
+ import { Uom } from '../../../types/uom.js';
8
+
9
+ export function createUomDisableCommand(): Command {
10
+ const disableCommand = new Command('disable');
11
+ disableCommand
12
+ .description('Disable (deactivate) a UOM')
13
+ .argument('<uomId>', 'UOM ID')
14
+ .option('--force', 'Skip confirmation prompt')
15
+ .option('--dry-run', 'Preview the operation without executing')
16
+ .option('--json', 'Output as JSON')
17
+ .action(async (uomId: string, options: Record<string, unknown>) => {
18
+ const context = configManager.getCurrentContext();
19
+ const environment = context.environment as Environment;
20
+ const tenant = context.tenant;
21
+ const force = options.force === true;
22
+ const dryRun = options.dryRun === true;
23
+
24
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
25
+ (options as any).json = process.argv.includes('--json');
26
+ const jsonOutput = options.json === true;
27
+
28
+ if (!uomId || uomId.trim() === '') {
29
+ const errMsg = 'Invalid UOM ID';
30
+ if (jsonOutput) {
31
+ console.log(JSON.stringify({ success: false, error: { code: 'INVALID_ID', message: errMsg } }));
32
+ } else {
33
+ console.error(chalk.red(`\n✗ ${errMsg}\n`));
34
+ }
35
+ process.exit(1);
36
+ }
37
+
38
+ if (!jsonOutput) {
39
+ console.log(chalk.bold(`\n⬇ Disable UOM (${environment})\n`));
40
+ console.log(chalk.gray(` UOM ID: ${uomId}`));
41
+ }
42
+
43
+ if (dryRun) {
44
+ if (jsonOutput) {
45
+ console.log(JSON.stringify({ success: true, dryRun: true, message: 'No actual API call will be made' }));
46
+ } else {
47
+ console.log(chalk.cyan('\n🔍 Dry-Run Mode: No actual API call will be made\n'));
48
+ console.log(chalk.gray(' This operation will disable the UOM.'));
49
+ console.log();
50
+ }
51
+ return;
52
+ }
53
+
54
+ let uom: Uom | undefined;
55
+ try {
56
+ const uomResponse = await apiClient.getUom(environment, tenant, uomId);
57
+ if (!uomResponse.success || !uomResponse.data || !('uomId' in uomResponse.data)) {
58
+ const errMsg = `UOM not found: ${uomId}`;
59
+ if (jsonOutput) {
60
+ console.log(JSON.stringify({ success: false, error: { code: 'NOT_FOUND', message: errMsg } }));
61
+ } else {
62
+ console.error(chalk.red(`\n✗ ${errMsg}\n`));
63
+ }
64
+ process.exit(1);
65
+ }
66
+ uom = uomResponse.data as Uom;
67
+ } catch (error) {
68
+ const errMsg = error instanceof Error ? error.message : 'Unknown error';
69
+ const jsonErr = { success: false, error: { code: 'FETCH_ERROR', message: 'Failed to fetch UOM: ' + errMsg } };
70
+ if (jsonOutput) {
71
+ console.log(JSON.stringify(jsonErr));
72
+ } else {
73
+ console.error(chalk.red(`\n✗ Failed to fetch UOM: ${errMsg}\n`));
74
+ }
75
+ process.exit(1);
76
+ }
77
+
78
+ if (uom.statusFlag === 2) {
79
+ const errMsg = `UOM "${uom.uomName}" is already disabled`;
80
+ if (jsonOutput) {
81
+ console.log(JSON.stringify({ success: false, error: { code: 'ALREADY_DISABLED', message: errMsg } }));
82
+ } else {
83
+ console.error(chalk.yellow(`\n⚠ ${errMsg}\n`));
84
+ }
85
+ process.exit(1);
86
+ }
87
+
88
+ if (!force) {
89
+ if (!jsonOutput) {
90
+ console.log(chalk.gray(` Name: ${uom.uomName}`));
91
+ console.log(chalk.gray(` Code: ${uom.uomCode}`));
92
+ }
93
+
94
+ const { confirm } = await inquirer.prompt([
95
+ {
96
+ type: 'confirm',
97
+ name: 'confirm',
98
+ message: `Disable UOM "${uom.uomName}"?`,
99
+ default: false,
100
+ },
101
+ ]);
102
+
103
+ if (!confirm) {
104
+ if (jsonOutput) {
105
+ console.log(JSON.stringify({ success: false, error: { code: 'CANCELLED', message: 'Operation cancelled' } }));
106
+ } else {
107
+ console.log(chalk.gray('\n Operation cancelled.\n'));
108
+ }
109
+ process.exit(0);
110
+ }
111
+ }
112
+
113
+ try {
114
+ const response = await apiClient.disableUom(environment, tenant, uomId);
115
+
116
+ if (response.success) {
117
+ if (jsonOutput) {
118
+ console.log(JSON.stringify({ success: true, uomId, name: uom?.uomName }));
119
+ } else {
120
+ console.log(chalk.green(`\n✓ UOM ${uom?.uomName || uomId} disabled\n`));
121
+ }
122
+ } else {
123
+ const errorMsg = response.error?.message || 'Unknown error';
124
+ const errorCode = response.error?.code || 'DISABLE_ERROR';
125
+ if (jsonOutput) {
126
+ console.log(JSON.stringify({ success: false, error: { code: errorCode, message: errorMsg } }));
127
+ } else {
128
+ console.error(chalk.red(`\n✗ Failed to disable UOM: ${errorMsg}`));
129
+ if (response.error?.code) {
130
+ console.error(chalk.gray(` Error code: ${response.error.code}`));
131
+ }
132
+ console.error();
133
+ }
134
+ process.exit(1);
135
+ }
136
+ } catch (error) {
137
+ const errMsg = error instanceof Error ? error.message : 'Unknown error';
138
+ if (jsonOutput) {
139
+ console.log(JSON.stringify({ success: false, error: { code: 'ERROR', message: errMsg } }));
140
+ } else {
141
+ console.error(chalk.red(`\n✗ Error: ${errMsg}\n`));
142
+ }
143
+ process.exit(1);
144
+ }
145
+ });
146
+
147
+ return disableCommand;
148
+ }