chandao4 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/.env.example +10 -0
- package/CHANGELOG.md +21 -0
- package/LICENSE +21 -0
- package/README.md +184 -0
- package/dist/commands/bug.d.ts +3 -0
- package/dist/commands/bug.js +373 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +38 -0
- package/dist/commands/login.d.ts +3 -0
- package/dist/commands/login.js +83 -0
- package/dist/commands/product.d.ts +3 -0
- package/dist/commands/product.js +41 -0
- package/dist/commands/project.d.ts +3 -0
- package/dist/commands/project.js +70 -0
- package/dist/commands/task.d.ts +3 -0
- package/dist/commands/task.js +445 -0
- package/dist/config/config.d.ts +17 -0
- package/dist/config/config.js +216 -0
- package/dist/config/defaults.d.ts +5 -0
- package/dist/config/defaults.js +23 -0
- package/dist/core/api-client.d.ts +20 -0
- package/dist/core/api-client.js +127 -0
- package/dist/core/auth.d.ts +44 -0
- package/dist/core/auth.js +244 -0
- package/dist/core/errors.d.ts +17 -0
- package/dist/core/errors.js +61 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +125 -0
- package/dist/services/bug.service.d.ts +59 -0
- package/dist/services/bug.service.js +232 -0
- package/dist/services/product.service.d.ts +12 -0
- package/dist/services/product.service.js +43 -0
- package/dist/services/project.service.d.ts +18 -0
- package/dist/services/project.service.js +35 -0
- package/dist/services/task.service.d.ts +55 -0
- package/dist/services/task.service.js +254 -0
- package/dist/types/api.d.ts +31 -0
- package/dist/types/api.js +3 -0
- package/dist/types/config.d.ts +18 -0
- package/dist/types/config.js +3 -0
- package/dist/types/models.d.ts +65 -0
- package/dist/types/models.js +33 -0
- package/dist/utils/format.d.ts +38 -0
- package/dist/utils/format.js +201 -0
- package/dist/utils/prompt.d.ts +12 -0
- package/dist/utils/prompt.js +154 -0
- package/dist/utils/validators.d.ts +14 -0
- package/dist/utils/validators.js +42 -0
- package/package.json +63 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// 交互式用户输入
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
37
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
38
|
+
};
|
|
39
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
40
|
+
exports.confirm = confirm;
|
|
41
|
+
exports.prompt = prompt;
|
|
42
|
+
exports.promptPassword = promptPassword;
|
|
43
|
+
const readline = __importStar(require("readline"));
|
|
44
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
45
|
+
/**
|
|
46
|
+
* 询问用户确认
|
|
47
|
+
*/
|
|
48
|
+
function confirm(message) {
|
|
49
|
+
const rl = readline.createInterface({
|
|
50
|
+
input: process.stdin,
|
|
51
|
+
output: process.stdout,
|
|
52
|
+
});
|
|
53
|
+
return new Promise((resolve) => {
|
|
54
|
+
rl.question(`${chalk_1.default.yellow('?')} ${message} (y/N) `, (answer) => {
|
|
55
|
+
rl.close();
|
|
56
|
+
resolve(answer.toLowerCase() === 'y' || answer.toLowerCase() === 'yes');
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 询问用户输入
|
|
62
|
+
*/
|
|
63
|
+
function prompt(message, defaultValue) {
|
|
64
|
+
const rl = readline.createInterface({
|
|
65
|
+
input: process.stdin,
|
|
66
|
+
output: process.stdout,
|
|
67
|
+
});
|
|
68
|
+
const promptMsg = defaultValue
|
|
69
|
+
? `${chalk_1.default.cyan('?')} ${message} [${defaultValue}]: `
|
|
70
|
+
: `${chalk_1.default.cyan('?')} ${message}: `;
|
|
71
|
+
return new Promise((resolve) => {
|
|
72
|
+
rl.question(promptMsg, (answer) => {
|
|
73
|
+
rl.close();
|
|
74
|
+
resolve(answer || defaultValue || '');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* 询问密码(不回显)
|
|
80
|
+
*/
|
|
81
|
+
function promptPassword(message) {
|
|
82
|
+
const rl = readline.createInterface({
|
|
83
|
+
input: process.stdin,
|
|
84
|
+
output: process.stdout,
|
|
85
|
+
});
|
|
86
|
+
return new Promise((resolve) => {
|
|
87
|
+
const stdin = process.stdin;
|
|
88
|
+
const stdout = process.stdout;
|
|
89
|
+
const promptText = `${chalk_1.default.cyan('?')} ${message}: `;
|
|
90
|
+
stdout.write(promptText);
|
|
91
|
+
if (stdin.isTTY) {
|
|
92
|
+
stdin.setRawMode(true);
|
|
93
|
+
}
|
|
94
|
+
let password = '';
|
|
95
|
+
let buf = Buffer.alloc(0);
|
|
96
|
+
const redraw = () => {
|
|
97
|
+
const stars = '*'.repeat(password.length);
|
|
98
|
+
// \r moves to line start, trailing space clears any echoed char, second \r repositions cursor
|
|
99
|
+
stdout.write(`\r${promptText}${stars} \r${promptText}${stars}`);
|
|
100
|
+
};
|
|
101
|
+
const onData = (char) => {
|
|
102
|
+
buf = Buffer.concat([buf, char]);
|
|
103
|
+
let processed = 0;
|
|
104
|
+
while (processed < buf.length) {
|
|
105
|
+
const byte = buf[processed];
|
|
106
|
+
let charLen;
|
|
107
|
+
if ((byte & 0x80) === 0)
|
|
108
|
+
charLen = 1;
|
|
109
|
+
else if ((byte & 0xE0) === 0xC0)
|
|
110
|
+
charLen = 2;
|
|
111
|
+
else if ((byte & 0xF0) === 0xE0)
|
|
112
|
+
charLen = 3;
|
|
113
|
+
else if ((byte & 0xF8) === 0xF0)
|
|
114
|
+
charLen = 4;
|
|
115
|
+
else {
|
|
116
|
+
processed++;
|
|
117
|
+
continue;
|
|
118
|
+
}
|
|
119
|
+
if (processed + charLen > buf.length)
|
|
120
|
+
break;
|
|
121
|
+
const charStr = buf.slice(processed, processed + charLen).toString();
|
|
122
|
+
processed += charLen;
|
|
123
|
+
if (charStr === '\r' || charStr === '\n') {
|
|
124
|
+
stdout.write('\n');
|
|
125
|
+
stdin.removeListener('data', onData);
|
|
126
|
+
if (stdin.isTTY)
|
|
127
|
+
stdin.setRawMode(false);
|
|
128
|
+
rl.close();
|
|
129
|
+
resolve(password);
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
if (charStr === '\b' || charStr === '\x7f') {
|
|
133
|
+
if (password.length > 0) {
|
|
134
|
+
password = password.slice(0, -1);
|
|
135
|
+
redraw();
|
|
136
|
+
}
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
if (charStr === '\x03') {
|
|
140
|
+
stdout.write('\n');
|
|
141
|
+
stdin.removeListener('data', onData);
|
|
142
|
+
if (stdin.isTTY)
|
|
143
|
+
stdin.setRawMode(false);
|
|
144
|
+
rl.close();
|
|
145
|
+
process.exit(0);
|
|
146
|
+
}
|
|
147
|
+
password += charStr;
|
|
148
|
+
redraw();
|
|
149
|
+
}
|
|
150
|
+
buf = buf.slice(processed);
|
|
151
|
+
};
|
|
152
|
+
stdin.on('data', onData);
|
|
153
|
+
});
|
|
154
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 校验数字 ID(正整数)
|
|
3
|
+
*/
|
|
4
|
+
export declare function isValidId(value: string | number): boolean;
|
|
5
|
+
export declare function isValidBugStatus(status: string): boolean;
|
|
6
|
+
export declare function isValidTaskStatus(status: string): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* 校验严重程度 (1-4)
|
|
9
|
+
*/
|
|
10
|
+
export declare function isValidSeverity(value: string | number): boolean;
|
|
11
|
+
/**
|
|
12
|
+
* 校验优先级 (1-4)
|
|
13
|
+
*/
|
|
14
|
+
export declare function isValidPriority(value: string | number): boolean;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// 参数校验
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.isValidId = isValidId;
|
|
5
|
+
exports.isValidBugStatus = isValidBugStatus;
|
|
6
|
+
exports.isValidTaskStatus = isValidTaskStatus;
|
|
7
|
+
exports.isValidSeverity = isValidSeverity;
|
|
8
|
+
exports.isValidPriority = isValidPriority;
|
|
9
|
+
/**
|
|
10
|
+
* 校验数字 ID(正整数)
|
|
11
|
+
*/
|
|
12
|
+
function isValidId(value) {
|
|
13
|
+
const num = typeof value === 'string' ? parseInt(value, 10) : value;
|
|
14
|
+
return Number.isInteger(num) && num > 0;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 校验 Bug 状态
|
|
18
|
+
*/
|
|
19
|
+
const VALID_BUG_STATUSES = ['active', 'resolved', 'closed'];
|
|
20
|
+
function isValidBugStatus(status) {
|
|
21
|
+
return VALID_BUG_STATUSES.includes(status);
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* 校验 Task 状态
|
|
25
|
+
*/
|
|
26
|
+
const VALID_TASK_STATUSES = ['wait', 'doing', 'done', 'pause', 'cancel', 'closed'];
|
|
27
|
+
function isValidTaskStatus(status) {
|
|
28
|
+
return VALID_TASK_STATUSES.includes(status);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* 校验严重程度 (1-4)
|
|
32
|
+
*/
|
|
33
|
+
function isValidSeverity(value) {
|
|
34
|
+
const num = typeof value === 'string' ? parseInt(value, 10) : value;
|
|
35
|
+
return num >= 1 && num <= 4;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* 校验优先级 (1-4)
|
|
39
|
+
*/
|
|
40
|
+
function isValidPriority(value) {
|
|
41
|
+
return isValidSeverity(value); // 范围相同 1-4
|
|
42
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "chandao4",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "禅道命令行工具 - Bug、任务、项目和产品管理,支持企业版 4.1.3+",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"chandao4": "./dist/index.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "tsx src/index.ts",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"start": "node dist/index.js",
|
|
13
|
+
"check": "tsc --noEmit",
|
|
14
|
+
"prepublishOnly": "npm run build"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"README.md",
|
|
19
|
+
"LICENSE",
|
|
20
|
+
"CHANGELOG.md",
|
|
21
|
+
".env.example"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [
|
|
24
|
+
"chandao",
|
|
25
|
+
"chandao4",
|
|
26
|
+
"zentao",
|
|
27
|
+
"禅道",
|
|
28
|
+
"cli",
|
|
29
|
+
"bug",
|
|
30
|
+
"task",
|
|
31
|
+
"project",
|
|
32
|
+
"product",
|
|
33
|
+
"项目管理",
|
|
34
|
+
"研发管理"
|
|
35
|
+
],
|
|
36
|
+
"author": "gaoshang212",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/gaoshang212/chandao4.git"
|
|
41
|
+
},
|
|
42
|
+
"homepage": "https://github.com/gaoshang212/chandao4#readme",
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/gaoshang212/chandao4/issues"
|
|
45
|
+
},
|
|
46
|
+
"engines": {
|
|
47
|
+
"node": ">=18"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"axios": "^1.16.1",
|
|
51
|
+
"chalk": "^5.6.2",
|
|
52
|
+
"cli-table3": "^0.6.5",
|
|
53
|
+
"commander": "^14.0.3",
|
|
54
|
+
"dotenv": "^17.4.2",
|
|
55
|
+
"ora": "^9.4.0",
|
|
56
|
+
"zod": "^4.4.3"
|
|
57
|
+
},
|
|
58
|
+
"devDependencies": {
|
|
59
|
+
"@types/node": "^25.9.1",
|
|
60
|
+
"tsx": "^4.22.3",
|
|
61
|
+
"typescript": "^6.0.3"
|
|
62
|
+
}
|
|
63
|
+
}
|