This commit is contained in:
parent
478b8b4da3
commit
1cebc94640
255
package-lock.json
generated
255
package-lock.json
generated
@ -12,6 +12,7 @@
|
||||
"packages/*"
|
||||
],
|
||||
"dependencies": {
|
||||
"@gitbeaker/rest": "^41.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"winston": "3.14.2",
|
||||
"winston-daily-rotate-file": "5.0.0"
|
||||
@ -576,6 +577,48 @@
|
||||
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@gitbeaker/core": {
|
||||
"version": "41.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@gitbeaker/core/-/core-41.2.0.tgz",
|
||||
"integrity": "sha512-kd9iwBBoBZB/MiZOclOWLN4QX/WoBb/WwB5o7JkAH9bS7jv2gB5hblKgmmxUfxKhT5wJasqNMk/VhFcZmOSHKg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@gitbeaker/requester-utils": "^41.2.0",
|
||||
"qs": "^6.12.2",
|
||||
"xcase": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@gitbeaker/requester-utils": {
|
||||
"version": "41.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@gitbeaker/requester-utils/-/requester-utils-41.2.0.tgz",
|
||||
"integrity": "sha512-mgGSAvyEes1Mt845NqxqDLDDRwGqiEIxiR6p2LgmZJQEoTgPRkuEhSJxF/5bJK401eReR/TgOdP0IVmLK9owFA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"picomatch-browser": "^2.2.6",
|
||||
"qs": "^6.12.2",
|
||||
"rate-limiter-flexible": "^4.0.1",
|
||||
"xcase": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@gitbeaker/rest": {
|
||||
"version": "41.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@gitbeaker/rest/-/rest-41.2.0.tgz",
|
||||
"integrity": "sha512-+ozz5gq+ZnipBHSLTrGShScLSqW7lQ7NEgBjZKjtBAVSVPZHyCCEwDnvGOKo6D3RI5HndLGS3MXZ590IpLMg1g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@gitbeaker/core": "^41.2.0",
|
||||
"@gitbeaker/requester-utils": "^41.2.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18.20.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@humanwhocodes/module-importer": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
|
||||
@ -3062,6 +3105,25 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
|
||||
"integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"set-function-length": "^1.2.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/callsites": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
|
||||
@ -4053,6 +4115,23 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.4",
|
||||
"resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz",
|
||||
"integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0",
|
||||
"es-errors": "^1.3.0",
|
||||
"gopd": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/define-lazy-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||
@ -4306,6 +4385,27 @@
|
||||
"is-arrayish": "^0.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/es-define-property": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz",
|
||||
"integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/es-errors": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
|
||||
"integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
|
||||
@ -5138,7 +5238,6 @@
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
@ -5195,6 +5294,25 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
|
||||
"integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-pkg-repo": {
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz",
|
||||
@ -5612,6 +5730,18 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
|
||||
"integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/graceful-fs": {
|
||||
"version": "4.2.11",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
|
||||
@ -5668,6 +5798,42 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz",
|
||||
"integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"es-define-property": "^1.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-proto": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz",
|
||||
"integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
"integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-unicode": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
|
||||
@ -5679,7 +5845,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
|
||||
"integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
@ -9279,6 +9444,18 @@
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
||||
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
@ -9851,6 +10028,18 @@
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/picomatch-browser": {
|
||||
"version": "2.2.6",
|
||||
"resolved": "https://registry.npmjs.org/picomatch-browser/-/picomatch-browser-2.2.6.tgz",
|
||||
"integrity": "sha512-0ypsOQt9D4e3hziV8O4elD9uN0z/jtUEfxVRtNaAAtXIyUx9m/SzlO020i8YNL2aL/E6blOvvHQcin6HZlFy/w==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/jonschlinkert"
|
||||
}
|
||||
},
|
||||
"node_modules/pidtree": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz",
|
||||
@ -10128,6 +10317,21 @@
|
||||
"teleport": ">=0.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/qs": {
|
||||
"version": "6.13.0",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
|
||||
"integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"side-channel": "^1.0.6"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.6"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/queue-microtask": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
@ -10159,6 +10363,12 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/rate-limiter-flexible": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/rate-limiter-flexible/-/rate-limiter-flexible-4.0.1.tgz",
|
||||
"integrity": "sha512-2/dGHpDFpeA0+755oUkW+EKyklqLS9lu0go9pDsbhqQjZcxfRyJ6LA4JI0+HAdZ2bemD/oOjUeZQB2lCZqXQfQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/react-is": {
|
||||
"version": "18.3.1",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz",
|
||||
@ -10746,6 +10956,23 @@
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
|
||||
"integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.4",
|
||||
"es-errors": "^1.3.0",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/shallow-clone": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz",
|
||||
@ -10782,6 +11009,24 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz",
|
||||
"integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.7",
|
||||
"es-errors": "^1.3.0",
|
||||
"get-intrinsic": "^1.2.4",
|
||||
"object-inspect": "^1.13.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/signal-exit": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
|
||||
@ -12030,6 +12275,12 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/xcase": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/xcase/-/xcase-2.0.1.tgz",
|
||||
"integrity": "sha512-UmFXIPU+9Eg3E9m/728Bii0lAIuoc+6nbrNUKaRPJOFp91ih44qqGlWtxMB6kXFrRD6po+86ksHM5XHCfk6iPw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/xtend": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
||||
|
@ -39,6 +39,7 @@
|
||||
"typescript-eslint": "8.1.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@gitbeaker/rest": "^41.2.0",
|
||||
"lodash": "^4.17.21",
|
||||
"winston": "3.14.2",
|
||||
"winston-daily-rotate-file": "5.0.0"
|
||||
|
@ -18,6 +18,7 @@
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@egg/logger": "^1.4.4",
|
||||
"winston": "*"
|
||||
"winston": "*",
|
||||
"@gitbeaker/rest": "*"
|
||||
}
|
||||
}
|
||||
}
|
35
packages/net-tool/src/gitlabServer/badge.ts
Normal file
35
packages/net-tool/src/gitlabServer/badge.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import type { Gitlab } from "../types"
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class Badge extends GitlabBaseService {
|
||||
/**
|
||||
* 为特定项目检索 GitLab 徽章。
|
||||
* @returns {Promise<Gitlab.Badge[]>} 一个承诺,解析为 GitLab 徽章的数组。
|
||||
*/
|
||||
async getList(): Promise<Gitlab.Badge[]> {
|
||||
const URL = `/projects/${this.project_id}/badges`
|
||||
return this.errorWarp<Gitlab.Badge[]>(() => this.get(URL), [])
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 GitLab 徽章。
|
||||
* @param {BadgeSetParams} badge - 徽章参数。
|
||||
* @returns {Promise<Gitlab.Badge | null>} 一个承诺,解析为更新后的徽章。
|
||||
*/
|
||||
async set(badge: Gitlab.BadgeSetParams): Promise<Gitlab.Badge | null> {
|
||||
const URL = `/projects/${badge.id}/badges/${badge.badge_id}`
|
||||
return this.errorWarp<Gitlab.Badge>(() => this.put(URL, badge), null)
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 GitLab 徽章。
|
||||
* @param {BadgeSetParams} badge - 徽章参数。
|
||||
* @returns {Promise<Gitlab.Badge | null>} 一个承诺,解析为添加的徽章。
|
||||
*/
|
||||
async add(badge: Gitlab.BadgeSetParams): Promise<Gitlab.Badge | null> {
|
||||
const URL = `/projects/${badge.id}/badges`
|
||||
return this.errorWarp<Gitlab.Badge>(() => this.post(URL, badge), null)
|
||||
}
|
||||
}
|
||||
|
||||
export default Badge
|
38
packages/net-tool/src/gitlabServer/base.ts
Normal file
38
packages/net-tool/src/gitlabServer/base.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import NetToolBase from "../netTool/base"
|
||||
import type { Gitlab } from "../types"
|
||||
|
||||
class GitlabBaseService extends NetToolBase {
|
||||
public project_id: number = 0;
|
||||
public merge_request_iid: number = 0;
|
||||
|
||||
constructor(baseUrl: string, authKey: string, requestId: string) {
|
||||
super({
|
||||
prefix: baseUrl,
|
||||
requestId,
|
||||
headers: { "PRIVATE-TOKEN": authKey },
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 包装一个 GitLab 请求函数,处理错误并返回默认值。
|
||||
* @template T
|
||||
* @param {() => Promise<T>} func - 要执行的请求函数。
|
||||
* @param {any} default_value - 请求失败时返回的默认值。
|
||||
* @returns {Promise<T>} 一个解析为请求结果或默认值的 promise。
|
||||
*/
|
||||
protected async errorWarp<T = any>(
|
||||
func: () => Promise<T>,
|
||||
default_value: any
|
||||
): Promise<T> {
|
||||
try {
|
||||
let response = {} as T & Gitlab.Error
|
||||
response = (await func()) as T & Gitlab.Error
|
||||
if (response.message === "404 Project Not Found") return default_value
|
||||
return response
|
||||
} catch {
|
||||
return default_value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default GitlabBaseService
|
16
packages/net-tool/src/gitlabServer/commit.ts
Normal file
16
packages/net-tool/src/gitlabServer/commit.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import type { Gitlab } from "../types"
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class Commit extends GitlabBaseService {
|
||||
/**
|
||||
* 检索与特定提交关联的合并请求。
|
||||
* @param {string} sha - 提交的SHA。
|
||||
* @returns {Promise<Gitlab.MergeRequest[]>} 一个解析为合并请求数组的promise。
|
||||
*/
|
||||
async getMr(sha: string): Promise<Gitlab.MergeRequest[]> {
|
||||
const URL = `/projects/${this.project_id}/repository/commits/${sha}/merge_requests`
|
||||
return this.errorWarp<Gitlab.MergeRequest[]>(() => this.get(URL), [])
|
||||
}
|
||||
}
|
||||
|
||||
export default Commit
|
34
packages/net-tool/src/gitlabServer/discussions.ts
Normal file
34
packages/net-tool/src/gitlabServer/discussions.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { DiscussionSchema } from "@gitbeaker/rest"
|
||||
|
||||
import type { Gitlab } from "../types"
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class Discussions extends GitlabBaseService {
|
||||
/**
|
||||
* 获取合并请求的讨论列表。IID。
|
||||
* @returns {Promise<DiscussionSchema[]>} 返回包含讨论列表的Promise。
|
||||
*/
|
||||
async getList(): Promise<DiscussionSchema[]> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}/discussions`
|
||||
return this.errorWarp<DiscussionSchema[]>(() => this.get(URL), [])
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建合并请求的讨论。
|
||||
* @param {string} body - 讨论内容。
|
||||
* @param {CreateRangeDiscussionPosition} position - 讨论位置。
|
||||
* @returns {Promise<DiscussionSchema | null>} 返回包含创建的讨论的Promise。
|
||||
*/
|
||||
async create2Mr(
|
||||
body: string,
|
||||
position: Gitlab.CreateRangeDiscussionPosition
|
||||
): Promise<DiscussionSchema | null> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}/discussions`
|
||||
return this.errorWarp<DiscussionSchema>(
|
||||
() => this.post(URL, { body, position }),
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Discussions
|
68
packages/net-tool/src/gitlabServer/index.ts
Normal file
68
packages/net-tool/src/gitlabServer/index.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import Badge from "./badge"
|
||||
import Commit from "./commit"
|
||||
import Discussions from "./discussions"
|
||||
import MergeRequests from "./mergeRequests"
|
||||
import Notes from "./notes"
|
||||
import Pipelines from "./pipelines"
|
||||
import Project from "./project"
|
||||
import Repository from "./repository"
|
||||
|
||||
class GitlabService {
|
||||
badge: Badge
|
||||
commit: Commit
|
||||
discussions: Discussions
|
||||
mergeRequests: MergeRequests
|
||||
notes: Notes
|
||||
pipelines: Pipelines
|
||||
project: Project
|
||||
repository: Repository
|
||||
|
||||
/**
|
||||
* 创建一个 GitLab 服务对象。
|
||||
* @param {string} baseUrl - GitLab 服务器的 URL。
|
||||
* @param {string} authKey - 用于授权的密钥。
|
||||
* @param {string} requestId - 请求 ID。
|
||||
*/
|
||||
constructor(baseUrl: string, authKey: string, requestId: string) {
|
||||
this.badge = new Badge(baseUrl, authKey, requestId)
|
||||
this.commit = new Commit(baseUrl, authKey, requestId)
|
||||
this.discussions = new Discussions(baseUrl, authKey, requestId)
|
||||
this.mergeRequests = new MergeRequests(baseUrl, authKey, requestId)
|
||||
this.notes = new Notes(baseUrl, authKey, requestId)
|
||||
this.pipelines = new Pipelines(baseUrl, authKey, requestId)
|
||||
this.project = new Project(baseUrl, authKey, requestId)
|
||||
this.repository = new Repository(baseUrl, authKey, requestId)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置项目 ID。
|
||||
* @param {number} project_id - 项目 ID。
|
||||
*/
|
||||
setProjectId(project_id: number) {
|
||||
this.badge.project_id = project_id
|
||||
this.commit.project_id = project_id
|
||||
this.discussions.project_id = project_id
|
||||
this.mergeRequests.project_id = project_id
|
||||
this.notes.project_id = project_id
|
||||
this.pipelines.project_id = project_id
|
||||
this.project.project_id = project_id
|
||||
this.repository.project_id = project_id
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置合并请求 IID。
|
||||
* @param {number} merge_request_iid - 合并请求 IID。
|
||||
*/
|
||||
setMergeRequestIid(merge_request_iid: number) {
|
||||
this.badge.merge_request_iid = merge_request_iid
|
||||
this.commit.merge_request_iid = merge_request_iid
|
||||
this.discussions.merge_request_iid = merge_request_iid
|
||||
this.mergeRequests.merge_request_iid = merge_request_iid
|
||||
this.notes.merge_request_iid = merge_request_iid
|
||||
this.pipelines.merge_request_iid = merge_request_iid
|
||||
this.project.merge_request_iid = merge_request_iid
|
||||
this.repository.merge_request_iid = merge_request_iid
|
||||
}
|
||||
}
|
||||
|
||||
export default GitlabService
|
62
packages/net-tool/src/gitlabServer/mergeRequests.ts
Normal file
62
packages/net-tool/src/gitlabServer/mergeRequests.ts
Normal file
@ -0,0 +1,62 @@
|
||||
import type {
|
||||
ExpandedMergeRequestSchema,
|
||||
MergeRequestChangesSchema,
|
||||
MergeRequestDiffVersionsSchema,
|
||||
MergeRequestNoteSchema,
|
||||
} from "@gitbeaker/rest"
|
||||
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class MergeRequests extends GitlabBaseService {
|
||||
/**
|
||||
* 获取合并请求的评论,支持分页。
|
||||
* @param {number} [page=1] - 页码。
|
||||
* @param {number} [per_page=20] - 每页的评论数。
|
||||
* @returns {Promise<MergeRequestNoteSchema[]>} 返回包含评论的Promise。
|
||||
*/
|
||||
async getComments(
|
||||
page: number = 1,
|
||||
per_page: number = 20
|
||||
): Promise<MergeRequestNoteSchema[]> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}/notes?page=${page}&per_page=${per_page}`
|
||||
return this.errorWarp<MergeRequestNoteSchema[]>(() => this.get(URL), [])
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并请求的变更。
|
||||
* @returns {Promise<MergeRequestChangesSchema | null>} 返回包含变更的Promise。
|
||||
*/
|
||||
async getChanges(): Promise<MergeRequestChangesSchema | null> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}/changes`
|
||||
return this.errorWarp<MergeRequestChangesSchema | null>(
|
||||
() => this.get(URL),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并请求的详细信息。
|
||||
* @returns {Promise<ExpandedMergeRequestSchema | null>} 返回包含详细信息的Promise。
|
||||
*/
|
||||
async getDetail(): Promise<ExpandedMergeRequestSchema | null> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}`
|
||||
return this.errorWarp<ExpandedMergeRequestSchema | null>(
|
||||
() => this.get(URL),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取合并请求的差异版本。
|
||||
* @returns {Promise<MergeRequestDiffVersionsSchema[]>} 返回包含差异版本的Promise。
|
||||
*/
|
||||
async getDiffVersions(): Promise<MergeRequestDiffVersionsSchema[]> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}/versions`
|
||||
return this.errorWarp<MergeRequestDiffVersionsSchema[]>(
|
||||
() => this.get(URL),
|
||||
[]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default MergeRequests
|
34
packages/net-tool/src/gitlabServer/notes.ts
Normal file
34
packages/net-tool/src/gitlabServer/notes.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { MergeRequestNoteSchema } from "@gitbeaker/rest"
|
||||
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class Notes extends GitlabBaseService {
|
||||
/**
|
||||
* 创建一个新的合并请求备注
|
||||
* @param {string} body - 备注内容
|
||||
* @returns {Promise<MergeRequestNoteSchema>} - 返回包含新创建备注的Promise
|
||||
*/
|
||||
async create(body: string): Promise<MergeRequestNoteSchema> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}/notes`
|
||||
return this.errorWarp<MergeRequestNoteSchema>(
|
||||
() => this.post(URL, { body }),
|
||||
null
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改一个现有的合并请求备注
|
||||
* @param {number} note_id - 备注ID
|
||||
* @param {string} body - 新的备注内容
|
||||
* @returns {Promise<MergeRequestNoteSchema>} - 返回包含修改后备注的Promise
|
||||
*/
|
||||
async modify(note_id: number, body: string): Promise<MergeRequestNoteSchema> {
|
||||
const URL = `/projects/${this.project_id}/merge_requests/${this.merge_request_iid}/notes/${note_id}`
|
||||
return this.errorWarp<MergeRequestNoteSchema>(
|
||||
() => this.put(URL, { body }),
|
||||
null
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
export default Notes
|
43
packages/net-tool/src/gitlabServer/pipelines.ts
Normal file
43
packages/net-tool/src/gitlabServer/pipelines.ts
Normal file
@ -0,0 +1,43 @@
|
||||
import type { Gitlab } from "../types"
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class Pipelines extends GitlabBaseService {
|
||||
/**
|
||||
* 获取特定GitLab流水线的详细信息。
|
||||
* @param {number} pipeline_id - 流水线的ID。
|
||||
* @param {string} created_at - 流水线的创建日期。
|
||||
* @returns 返回包含详细信息的Promise。
|
||||
*/
|
||||
async getDetail(pipeline_id: number, created_at?: string) {
|
||||
const URL = `/projects/${this.project_id}/pipelines/${pipeline_id}`
|
||||
const res = await this.errorWarp<Gitlab.PipelineDetail>(
|
||||
() => this.get(URL),
|
||||
null
|
||||
)
|
||||
if (res === null) return null
|
||||
return { ...res, created_at }
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取特定项目的GitLab流水线列表。
|
||||
* @param {number} [page=1] - 结果的页码(默认值:1)。
|
||||
* @returns {Promise<Gitlab.Pipeline[]>} 一个解析为流水线数组的promise。
|
||||
*/
|
||||
async getList(page = 1): Promise<Gitlab.Pipeline[]> {
|
||||
const URL = `/projects/${this.project_id}/pipelines`
|
||||
const params = { scope: "finished", per_page: 100, page }
|
||||
return this.errorWarp<Gitlab.Pipeline[]>(() => this.get(URL, params), [])
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取特定GitLab流水线的任务列表。
|
||||
* @param {number} pipeline_id - 流水线的ID。
|
||||
* @returns {Promise<Gitlab.Job[]>} 一个解析为任务数组的promise。
|
||||
*/
|
||||
async getJobs(pipeline_id: number): Promise<Gitlab.Job[]> {
|
||||
const URL = `/projects/${this.project_id}/pipelines/${pipeline_id}/jobs`
|
||||
return this.errorWarp<Gitlab.Job[]>(() => this.get(URL), [])
|
||||
}
|
||||
}
|
||||
|
||||
export default Pipelines
|
19
packages/net-tool/src/gitlabServer/project.ts
Normal file
19
packages/net-tool/src/gitlabServer/project.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import type { Gitlab } from "../types"
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class Project extends GitlabBaseService {
|
||||
/**
|
||||
* 获取 GitLab 项目的详细信息。
|
||||
* @returns {Promise<Gitlab.ProjDetail | null>} 一个解析为项目详细信息的 promise。
|
||||
*/
|
||||
async getDetail(): Promise<Gitlab.ProjDetail | null> {
|
||||
const projectId =
|
||||
typeof this.project_id === "string"
|
||||
? encodeURIComponent(this.project_id)
|
||||
: this.project_id
|
||||
const URL = `/projects/${projectId}`
|
||||
return this.errorWarp<Gitlab.ProjDetail>(() => this.get(URL), null)
|
||||
}
|
||||
}
|
||||
|
||||
export default Project
|
16
packages/net-tool/src/gitlabServer/repository.ts
Normal file
16
packages/net-tool/src/gitlabServer/repository.ts
Normal file
@ -0,0 +1,16 @@
|
||||
import GitlabBaseService from "./base"
|
||||
|
||||
class Repository extends GitlabBaseService {
|
||||
/**
|
||||
* 获取指定项目中某个文件的内容。
|
||||
* @param {string} path - 文件路径。
|
||||
* @param {string} ref - 分支或标签名称。
|
||||
* @returns {Promise<string>} 返回包含文件内容的Promise。
|
||||
*/
|
||||
async getFileContent(path: string, ref: string): Promise<string> {
|
||||
const URL = `/projects/${this.project_id}/repository/files/${encodeURIComponent(path)}/raw?ref=${ref}`
|
||||
return this.errorWarp<string>(() => this.get(URL), "")
|
||||
}
|
||||
}
|
||||
|
||||
export default Repository
|
@ -1,517 +1,7 @@
|
||||
import logger from "@egg/logger"
|
||||
import { Logger } from "winston"
|
||||
import GitlabService from "./gitlabServer"
|
||||
import NetTool from "./netTool"
|
||||
import NetToolBase from "./netTool/base"
|
||||
import type { Gitlab, NetErrorDetail, NetRequestParams } from "./types"
|
||||
|
||||
interface NetRequestParams {
|
||||
url: string
|
||||
method: string
|
||||
queryParams?: any
|
||||
payload?: any
|
||||
additionalHeaders?: Record<string, string>
|
||||
}
|
||||
|
||||
interface NetErrorDetail {
|
||||
response: Response | null
|
||||
code: number
|
||||
message: string
|
||||
data?: any
|
||||
}
|
||||
|
||||
export class NetError extends Error {
|
||||
public response: Response | null
|
||||
public code: number
|
||||
public message: string
|
||||
public data?: any
|
||||
|
||||
constructor({ response, code, message, data }: NetErrorDetail) {
|
||||
super(message)
|
||||
this.response = response
|
||||
this.code = code
|
||||
this.message = message
|
||||
this.data = data
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络工具类,提供发送HTTP请求的方法。
|
||||
*/
|
||||
class NetToolBase {
|
||||
protected prefix: string
|
||||
protected headers: Record<string, string>
|
||||
protected getHeaders: () => Promise<Record<string, string>>
|
||||
protected logger: Logger
|
||||
protected requestId: string
|
||||
|
||||
/**
|
||||
* 创建一个网络工具类实例。
|
||||
*
|
||||
* @param {Object} params - 构造函数参数。
|
||||
* @param {string} [params.prefix] - URL前缀。
|
||||
* @param {Record<string, string>} [params.headers] - 默认请求头。
|
||||
* @param {Function} [params.getHeaders] - 获取请求头的方法。
|
||||
* @param {string} [params.requestId] - 请求ID。
|
||||
*/
|
||||
constructor({
|
||||
prefix,
|
||||
headers,
|
||||
getHeaders,
|
||||
requestId,
|
||||
}: {
|
||||
prefix?: string
|
||||
headers?: Record<string, string>
|
||||
getHeaders?: () => Promise<Record<string, string>>
|
||||
requestId?: string
|
||||
} = {}) {
|
||||
this.prefix = prefix || ""
|
||||
this.headers = headers || {}
|
||||
this.getHeaders = getHeaders || (async () => ({}))
|
||||
this.requestId = requestId || ""
|
||||
this.logger = logger.child({ requestId })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个网络工具类实例。
|
||||
*
|
||||
* @param {Object} params - 构造函数参数。
|
||||
* @param {string} [params.prefix] - URL前缀。
|
||||
* @param {Record<string, string>} [params.headers] - 默认请求头。
|
||||
* @param {Function} [params.getHeaders] - 获取请求头的方法。
|
||||
* @param {string} [params.requestId] - 请求ID。
|
||||
* @returns 一个网络工具类实例。
|
||||
*/
|
||||
child({
|
||||
prefix,
|
||||
headers,
|
||||
getHeaders,
|
||||
requestId,
|
||||
}: {
|
||||
prefix?: string
|
||||
headers?: Record<string, string>
|
||||
getHeaders?: () => Promise<Record<string, string>>
|
||||
requestId?: string
|
||||
} = {}) {
|
||||
return new NetToolBase({
|
||||
prefix: prefix || this.prefix,
|
||||
headers: headers || this.headers,
|
||||
getHeaders: getHeaders || this.getHeaders,
|
||||
requestId: requestId || this.requestId,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录响应详情并返回响应日志对象。
|
||||
* @param {string} url - 请求地址。
|
||||
* @param {string} method - 请求使用的HTTP方法。
|
||||
* @param {Record<string, string>} headers - 请求头。
|
||||
* @param {any} requestBody - 请求体。
|
||||
* @param {any} responseBody - 响应体。
|
||||
* @param {number} requestTime - 请求时间。
|
||||
* @param {Response} [response] - 响应对象。
|
||||
* @returns 响应日志对象。
|
||||
*/
|
||||
private logResponse(
|
||||
url: string,
|
||||
method: string,
|
||||
headers: Record<string, string>,
|
||||
requestBody: any,
|
||||
responseBody: any,
|
||||
requestTime: number,
|
||||
response?: Response
|
||||
) {
|
||||
const responseLog = {
|
||||
ok: response?.ok,
|
||||
status: response?.status,
|
||||
statusText: response?.statusText,
|
||||
url,
|
||||
method: method,
|
||||
requestHeaders: headers,
|
||||
responseHeaders: response?.headers,
|
||||
requestBody,
|
||||
responseBody,
|
||||
requestTime,
|
||||
responseTime: new Date().getTime(),
|
||||
}
|
||||
this.logger.http(JSON.stringify(responseLog, null, 2))
|
||||
return responseLog
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送网络请求并返回一个解析为响应数据的Promise。
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param method - 请求使用的HTTP方法。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
* @throws 如果网络响应不成功或存在解析错误,则抛出错误。
|
||||
*/
|
||||
protected async request<T = any>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
}: NetRequestParams): Promise<T> {
|
||||
// 拼接完整的URL
|
||||
let fullUrl = `${this.prefix}${url}`
|
||||
if (queryParams) {
|
||||
if (typeof queryParams === "string") {
|
||||
fullUrl = `${fullUrl}?${queryParams}`
|
||||
} else {
|
||||
const queryString = new URLSearchParams(queryParams).toString()
|
||||
if (queryString) fullUrl = `${fullUrl}?${queryString}`
|
||||
}
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
const headers = {
|
||||
...this.headers,
|
||||
...(await this.getHeaders()),
|
||||
...(additionalHeaders || {}),
|
||||
} as Record<string, string>
|
||||
|
||||
// 设置请求Header
|
||||
if (!(payload instanceof FormData)) {
|
||||
headers["Content-Type"] = "application/json"
|
||||
}
|
||||
|
||||
// 处理请求数据
|
||||
const body = payload instanceof FormData ? payload : JSON.stringify(payload)
|
||||
|
||||
// 获取响应数据
|
||||
let resData: any = null
|
||||
let resText: string = ""
|
||||
let res: Response
|
||||
// 开始计时
|
||||
const requestTime = new Date().getTime()
|
||||
|
||||
try {
|
||||
res = await fetch(fullUrl, {
|
||||
method,
|
||||
body,
|
||||
headers,
|
||||
})
|
||||
try {
|
||||
resText = await res.text()
|
||||
resData = JSON.parse(resText)
|
||||
} catch {
|
||||
/* empty */
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 网络请求异常,如请求超时、DNS解析失败、CORS请求被阻止等
|
||||
this.logResponse(
|
||||
fullUrl,
|
||||
method,
|
||||
headers,
|
||||
payload,
|
||||
resData || resText,
|
||||
requestTime
|
||||
)
|
||||
throw new NetError({
|
||||
response: null,
|
||||
code: 1,
|
||||
message: error.message || "网络请求异常",
|
||||
})
|
||||
}
|
||||
// 记录响应
|
||||
this.logResponse(
|
||||
fullUrl,
|
||||
method,
|
||||
headers,
|
||||
payload,
|
||||
resData || resText,
|
||||
requestTime,
|
||||
res
|
||||
)
|
||||
// http 错误码异常
|
||||
if (!res.ok) {
|
||||
throw new NetError({
|
||||
response: res,
|
||||
code: resData.code || res.status,
|
||||
message: resData.message || resData.msg || resText || res.statusText,
|
||||
data: resData.data,
|
||||
})
|
||||
}
|
||||
// http 错误码正常,但解析异常
|
||||
if (!resData) {
|
||||
throw new NetError({
|
||||
response: res,
|
||||
code: 1,
|
||||
message: "解析响应数据异常",
|
||||
})
|
||||
}
|
||||
// 响应数据异常
|
||||
if ("code" in resData && resData.code !== 0) {
|
||||
throw new NetError({
|
||||
response: res,
|
||||
code: resData.code,
|
||||
message: resData.message || resData.msg || "网络请求失败",
|
||||
})
|
||||
}
|
||||
return resData as T
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送GET请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected get<T = any>(
|
||||
url: string,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({ url, method: "get", queryParams, additionalHeaders })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected post<T = any>(
|
||||
url: string,
|
||||
payload?: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "post",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送PUT请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected put<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "put",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送DELETE请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected del<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "delete",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送PATCH请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected patch<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "patch",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
class NetTool extends NetToolBase {
|
||||
public request<T = any>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
}: NetRequestParams): Promise<T> {
|
||||
return super.request<T>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
public get<T = any>(
|
||||
url: string,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.get<T>(url, queryParams, additionalHeaders)
|
||||
}
|
||||
public post<T = any>(
|
||||
url: string,
|
||||
payload?: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.post<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public put<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.put<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public del<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.del<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public patch<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.patch<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
/**
|
||||
* 创建一个表示400 Bad Request的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @returns 一个表示400 Bad Request的响应对象。
|
||||
*/
|
||||
badRequest(message: string) {
|
||||
this.logger.error(`return a bad request response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 400, message, requestId: this.requestId },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示404 Not Found的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @returns 一个表示404 Not Found的响应对象。
|
||||
*/
|
||||
notFound(message: string) {
|
||||
this.logger.error(`return a not found response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 404, message, requestId: this.requestId },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示500 Internal Server Error的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @param data - 错误数据。
|
||||
* @returns 一个表示500 Internal Server Error的响应对象。
|
||||
*/
|
||||
serverError(message: string, data?: any) {
|
||||
this.logger.error(`return a server error response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 500, message, data, requestId: this.requestId },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示200 OK的响应对象。
|
||||
*
|
||||
* @param data - 响应数据。
|
||||
* @returns 一个表示200 OK的响应对象。
|
||||
*/
|
||||
ok(data?: any) {
|
||||
this.logger.info(
|
||||
`return a ok response${data ? ": " + JSON.stringify(data) : ""}`
|
||||
)
|
||||
return Response.json({
|
||||
code: 0,
|
||||
message: "success",
|
||||
data,
|
||||
requestId: this.requestId,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示200 OK的响应对象。
|
||||
*
|
||||
* @param data - 响应数据。
|
||||
* @returns 一个表示200 OK的响应对象。
|
||||
*/
|
||||
json(data = {}) {
|
||||
this.logger.info(`return a json response: ${JSON.stringify(data)}`)
|
||||
return Response.json(data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个自定义状态码的响应对象。
|
||||
* @param data - 响应数据。
|
||||
* @param status - 响应状态码。
|
||||
* @returns 一个自定义状态码的响应对象。
|
||||
*/
|
||||
custom(data = null as any, status = 200) {
|
||||
this.logger.info(
|
||||
`return a ${status} response${data ? ": " + JSON.stringify(data) : ""}`
|
||||
)
|
||||
return new Response(data, { status: status })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示200 OK的健康检查响应对象。
|
||||
*
|
||||
* @param message - 响应消息。
|
||||
* @returns 一个表示200 OK的健康检查响应对象。
|
||||
*/
|
||||
healthCheck(message = "success") {
|
||||
return Response.json({ code: 0, message })
|
||||
}
|
||||
}
|
||||
|
||||
export { NetTool, NetToolBase }
|
||||
export { GitlabService, NetTool, NetToolBase }
|
||||
export type { Gitlab, NetErrorDetail, NetRequestParams }
|
||||
|
353
packages/net-tool/src/netTool/base.ts
Normal file
353
packages/net-tool/src/netTool/base.ts
Normal file
@ -0,0 +1,353 @@
|
||||
import logger from "@egg/logger"
|
||||
import { Logger } from "winston"
|
||||
|
||||
import { NetErrorDetail, NetRequestParams } from "../types"
|
||||
|
||||
export class NetError extends Error {
|
||||
public response: Response | null
|
||||
public code: number
|
||||
public message: string
|
||||
public data?: any
|
||||
|
||||
constructor({ response, code, message, data }: NetErrorDetail) {
|
||||
super(message)
|
||||
this.response = response
|
||||
this.code = code
|
||||
this.message = message
|
||||
this.data = data
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 网络工具类,提供发送HTTP请求的方法。
|
||||
*/
|
||||
class NetToolBase {
|
||||
protected prefix: string
|
||||
protected headers: Record<string, string>
|
||||
protected getHeaders: () => Promise<Record<string, string>>
|
||||
protected logger: Logger
|
||||
protected requestId: string
|
||||
|
||||
/**
|
||||
* 创建一个网络工具类实例。
|
||||
*
|
||||
* @param {Object} params - 构造函数参数。
|
||||
* @param {string} [params.prefix] - URL前缀。
|
||||
* @param {Record<string, string>} [params.headers] - 默认请求头。
|
||||
* @param {Function} [params.getHeaders] - 获取请求头的方法。
|
||||
* @param {string} [params.requestId] - 请求ID。
|
||||
*/
|
||||
constructor({
|
||||
prefix,
|
||||
headers,
|
||||
getHeaders,
|
||||
requestId,
|
||||
}: {
|
||||
prefix?: string
|
||||
headers?: Record<string, string>
|
||||
getHeaders?: () => Promise<Record<string, string>>
|
||||
requestId?: string
|
||||
} = {}) {
|
||||
this.prefix = prefix || ""
|
||||
this.headers = headers || {}
|
||||
this.getHeaders = getHeaders || (async () => ({}))
|
||||
this.requestId = requestId || ""
|
||||
this.logger = logger.child({ requestId })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个网络工具类实例。
|
||||
*
|
||||
* @param {Object} params - 构造函数参数。
|
||||
* @param {string} [params.prefix] - URL前缀。
|
||||
* @param {Record<string, string>} [params.headers] - 默认请求头。
|
||||
* @param {Function} [params.getHeaders] - 获取请求头的方法。
|
||||
* @param {string} [params.requestId] - 请求ID。
|
||||
* @returns 一个网络工具类实例。
|
||||
*/
|
||||
child({
|
||||
prefix,
|
||||
headers,
|
||||
getHeaders,
|
||||
requestId,
|
||||
}: {
|
||||
prefix?: string
|
||||
headers?: Record<string, string>
|
||||
getHeaders?: () => Promise<Record<string, string>>
|
||||
requestId?: string
|
||||
} = {}) {
|
||||
return new NetToolBase({
|
||||
prefix: prefix || this.prefix,
|
||||
headers: headers || this.headers,
|
||||
getHeaders: getHeaders || this.getHeaders,
|
||||
requestId: requestId || this.requestId,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录响应详情并返回响应日志对象。
|
||||
* @param {string} url - 请求地址。
|
||||
* @param {string} method - 请求使用的HTTP方法。
|
||||
* @param {Record<string, string>} headers - 请求头。
|
||||
* @param {any} requestBody - 请求体。
|
||||
* @param {any} responseBody - 响应体。
|
||||
* @param {number} requestTime - 请求时间。
|
||||
* @param {Response} [response] - 响应对象。
|
||||
* @returns 响应日志对象。
|
||||
*/
|
||||
private logResponse(
|
||||
url: string,
|
||||
method: string,
|
||||
headers: Record<string, string>,
|
||||
requestBody: any,
|
||||
responseBody: any,
|
||||
requestTime: number,
|
||||
response?: Response
|
||||
) {
|
||||
const responseLog = {
|
||||
ok: response?.ok,
|
||||
status: response?.status,
|
||||
statusText: response?.statusText,
|
||||
url,
|
||||
method: method,
|
||||
requestHeaders: headers,
|
||||
responseHeaders: response?.headers,
|
||||
requestBody,
|
||||
responseBody,
|
||||
requestTime,
|
||||
responseTime: new Date().getTime(),
|
||||
}
|
||||
this.logger.http(JSON.stringify(responseLog, null, 2))
|
||||
return responseLog
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送网络请求并返回一个解析为响应数据的Promise。
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param method - 请求使用的HTTP方法。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
* @throws 如果网络响应不成功或存在解析错误,则抛出错误。
|
||||
*/
|
||||
protected async request<T = any>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
}: NetRequestParams): Promise<T> {
|
||||
// 拼接完整的URL
|
||||
let fullUrl = `${this.prefix}${url}`
|
||||
if (queryParams) {
|
||||
if (typeof queryParams === "string") {
|
||||
fullUrl = `${fullUrl}?${queryParams}`
|
||||
} else {
|
||||
const queryString = new URLSearchParams(queryParams).toString()
|
||||
if (queryString) fullUrl = `${fullUrl}?${queryString}`
|
||||
}
|
||||
}
|
||||
|
||||
// 设置请求头
|
||||
const headers = {
|
||||
...this.headers,
|
||||
...(await this.getHeaders()),
|
||||
...(additionalHeaders || {}),
|
||||
} as Record<string, string>
|
||||
|
||||
// 设置请求Header
|
||||
if (!(payload instanceof FormData)) {
|
||||
headers["Content-Type"] = "application/json"
|
||||
}
|
||||
|
||||
// 处理请求数据
|
||||
const body = payload instanceof FormData ? payload : JSON.stringify(payload)
|
||||
|
||||
// 获取响应数据
|
||||
let resData: any = null
|
||||
let resText: string = ""
|
||||
let res: Response
|
||||
// 开始计时
|
||||
const requestTime = new Date().getTime()
|
||||
|
||||
try {
|
||||
res = await fetch(fullUrl, {
|
||||
method,
|
||||
body,
|
||||
headers,
|
||||
})
|
||||
try {
|
||||
resText = await res.text()
|
||||
resData = JSON.parse(resText)
|
||||
} catch {
|
||||
/* empty */
|
||||
}
|
||||
} catch (error: any) {
|
||||
// 网络请求异常,如请求超时、DNS解析失败、CORS请求被阻止等
|
||||
this.logResponse(
|
||||
fullUrl,
|
||||
method,
|
||||
headers,
|
||||
payload,
|
||||
resData || resText,
|
||||
requestTime
|
||||
)
|
||||
throw new NetError({
|
||||
response: null,
|
||||
code: 1,
|
||||
message: error.message || "网络请求异常",
|
||||
})
|
||||
}
|
||||
// 记录响应
|
||||
this.logResponse(
|
||||
fullUrl,
|
||||
method,
|
||||
headers,
|
||||
payload,
|
||||
resData || resText,
|
||||
requestTime,
|
||||
res
|
||||
)
|
||||
// http 错误码异常
|
||||
if (!res.ok) {
|
||||
throw new NetError({
|
||||
response: res,
|
||||
code: resData.code || res.status,
|
||||
message: resData.message || resData.msg || resText || res.statusText,
|
||||
data: resData.data,
|
||||
})
|
||||
}
|
||||
// http 错误码正常,但解析异常
|
||||
if (!resData) {
|
||||
throw new NetError({
|
||||
response: res,
|
||||
code: 1,
|
||||
message: "解析响应数据异常",
|
||||
})
|
||||
}
|
||||
// 响应数据异常
|
||||
if ("code" in resData && resData.code !== 0) {
|
||||
throw new NetError({
|
||||
response: res,
|
||||
code: resData.code,
|
||||
message: resData.message || resData.msg || "网络请求失败",
|
||||
})
|
||||
}
|
||||
return resData as T
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送GET请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected get<T = any>(
|
||||
url: string,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({ url, method: "get", queryParams, additionalHeaders })
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送POST请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected post<T = any>(
|
||||
url: string,
|
||||
payload?: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "post",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送PUT请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected put<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "put",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送DELETE请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected del<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "delete",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送PATCH请求并返回一个解析为响应数据的Promise。
|
||||
*
|
||||
* @param url - 要发送请求的URL。
|
||||
* @param payload - 请求的有效负载数据。
|
||||
* @param queryParams - 要包含在URL中的查询参数。
|
||||
* @param additionalHeaders - 要包含在请求中的附加头。
|
||||
* @returns 一个解析为响应数据的Promise。
|
||||
*/
|
||||
protected patch<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return this.request({
|
||||
url,
|
||||
method: "patch",
|
||||
payload,
|
||||
queryParams,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
export default NetToolBase
|
155
packages/net-tool/src/netTool/index.ts
Normal file
155
packages/net-tool/src/netTool/index.ts
Normal file
@ -0,0 +1,155 @@
|
||||
import { NetRequestParams } from "../types"
|
||||
import NetToolBase from "./base"
|
||||
|
||||
class NetTool extends NetToolBase {
|
||||
public request<T = any>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
}: NetRequestParams): Promise<T> {
|
||||
return super.request<T>({
|
||||
url,
|
||||
method,
|
||||
queryParams,
|
||||
payload,
|
||||
additionalHeaders,
|
||||
})
|
||||
}
|
||||
public get<T = any>(
|
||||
url: string,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.get<T>(url, queryParams, additionalHeaders)
|
||||
}
|
||||
public post<T = any>(
|
||||
url: string,
|
||||
payload?: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.post<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public put<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.put<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public del<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.del<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
public patch<T = any>(
|
||||
url: string,
|
||||
payload: any,
|
||||
queryParams?: any,
|
||||
additionalHeaders?: any
|
||||
): Promise<T> {
|
||||
return super.patch<T>(url, payload, queryParams, additionalHeaders)
|
||||
}
|
||||
/**
|
||||
* 创建一个表示400 Bad Request的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @returns 一个表示400 Bad Request的响应对象。
|
||||
*/
|
||||
badRequest(message: string) {
|
||||
this.logger.error(`return a bad request response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 400, message, requestId: this.requestId },
|
||||
{ status: 400 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示404 Not Found的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @returns 一个表示404 Not Found的响应对象。
|
||||
*/
|
||||
notFound(message: string) {
|
||||
this.logger.error(`return a not found response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 404, message, requestId: this.requestId },
|
||||
{ status: 404 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示500 Internal Server Error的响应对象。
|
||||
*
|
||||
* @param message - 错误消息。
|
||||
* @param data - 错误数据。
|
||||
* @returns 一个表示500 Internal Server Error的响应对象。
|
||||
*/
|
||||
serverError(message: string, data?: any) {
|
||||
this.logger.error(`return a server error response: ${message}`)
|
||||
return Response.json(
|
||||
{ code: 500, message, data, requestId: this.requestId },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示200 OK的响应对象。
|
||||
*
|
||||
* @param data - 响应数据。
|
||||
* @returns 一个表示200 OK的响应对象。
|
||||
*/
|
||||
ok(data?: any) {
|
||||
this.logger.info(
|
||||
`return a ok response${data ? ": " + JSON.stringify(data) : ""}`
|
||||
)
|
||||
return Response.json({
|
||||
code: 0,
|
||||
message: "success",
|
||||
data,
|
||||
requestId: this.requestId,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示200 OK的响应对象。
|
||||
*
|
||||
* @param data - 响应数据。
|
||||
* @returns 一个表示200 OK的响应对象。
|
||||
*/
|
||||
json(data = {}) {
|
||||
this.logger.info(`return a json response: ${JSON.stringify(data)}`)
|
||||
return Response.json(data)
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个自定义状态码的响应对象。
|
||||
* @param data - 响应数据。
|
||||
* @param status - 响应状态码。
|
||||
* @returns 一个自定义状态码的响应对象。
|
||||
*/
|
||||
custom(data = null as any, status = 200) {
|
||||
this.logger.info(
|
||||
`return a ${status} response${data ? ": " + JSON.stringify(data) : ""}`
|
||||
)
|
||||
return new Response(data, { status: status })
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个表示200 OK的健康检查响应对象。
|
||||
*
|
||||
* @param message - 响应消息。
|
||||
* @returns 一个表示200 OK的健康检查响应对象。
|
||||
*/
|
||||
healthCheck(message = "success") {
|
||||
return Response.json({ code: 0, message })
|
||||
}
|
||||
}
|
||||
|
||||
export default NetTool
|
420
packages/net-tool/src/types/gitlab.ts
Normal file
420
packages/net-tool/src/types/gitlab.ts
Normal file
@ -0,0 +1,420 @@
|
||||
export namespace Gitlab {
|
||||
export interface InitParams {
|
||||
baseUrl: string
|
||||
requestId: string
|
||||
authKey: string
|
||||
project_id?: number
|
||||
merge_request_iid?: number
|
||||
}
|
||||
/* 错误 */
|
||||
export interface Error {
|
||||
/**
|
||||
* 错误消息
|
||||
*/
|
||||
message: string
|
||||
}
|
||||
/* 用户 */
|
||||
export interface User {
|
||||
/**
|
||||
* 用户ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
username: string
|
||||
/**
|
||||
* 用户全名
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* 用户状态
|
||||
*/
|
||||
state: string
|
||||
/**
|
||||
* 用户头像URL
|
||||
*/
|
||||
avatar_url: string
|
||||
/**
|
||||
* 用户网页URL
|
||||
*/
|
||||
web_url: string
|
||||
}
|
||||
|
||||
/* 项目详情 */
|
||||
export interface ProjDetail {
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 项目描述
|
||||
*/
|
||||
description: string
|
||||
/**
|
||||
* 项目名称
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* 带命名空间的项目路径
|
||||
*/
|
||||
path_with_namespace: string
|
||||
/**
|
||||
* 项目网页URL
|
||||
*/
|
||||
web_url: string
|
||||
/**
|
||||
* 项目头像URL(可选)
|
||||
*/
|
||||
avatar_url?: any
|
||||
/**
|
||||
* 消息(可选)
|
||||
*/
|
||||
message?: string
|
||||
}
|
||||
|
||||
/* 管道详情 */
|
||||
export interface PipelineDetail {
|
||||
/**
|
||||
* 管道ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
project_id: number
|
||||
/**
|
||||
* 分支名
|
||||
*/
|
||||
ref: string
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
status: string
|
||||
/**
|
||||
* 管道网页URL
|
||||
*/
|
||||
web_url: string
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
user: User
|
||||
/**
|
||||
* 开始时间
|
||||
*/
|
||||
started_at: string
|
||||
/**
|
||||
* 完成时间
|
||||
*/
|
||||
finished_at: string
|
||||
/**
|
||||
* 持续时间
|
||||
*/
|
||||
duration: number
|
||||
/**
|
||||
* 排队持续时间
|
||||
*/
|
||||
queued_duration: number
|
||||
/**
|
||||
* 消息(可选)
|
||||
*/
|
||||
message?: string
|
||||
}
|
||||
|
||||
/* 管道 */
|
||||
export interface Pipeline {
|
||||
/**
|
||||
* 管道ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
project_id: number
|
||||
/**
|
||||
* SHA值
|
||||
*/
|
||||
sha: string
|
||||
/**
|
||||
* 分支名
|
||||
*/
|
||||
ref: string
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
status: string
|
||||
/**
|
||||
* 来源
|
||||
*/
|
||||
source: string
|
||||
/**
|
||||
* 创建时间
|
||||
*/
|
||||
created_at: string
|
||||
/**
|
||||
* 更新时间
|
||||
*/
|
||||
updated_at: string
|
||||
/**
|
||||
* 管道网页URL
|
||||
*/
|
||||
web_url: string
|
||||
}
|
||||
|
||||
/* 任务 */
|
||||
export interface Job {
|
||||
status: string
|
||||
stage: string
|
||||
}
|
||||
|
||||
/* 徽章 */
|
||||
export interface Badge {
|
||||
/**
|
||||
* 徽章ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 徽章名称
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* 链接URL
|
||||
*/
|
||||
link_url: string
|
||||
/**
|
||||
* 图片URL
|
||||
*/
|
||||
image_url: string
|
||||
/**
|
||||
* 渲染后的链接URL
|
||||
*/
|
||||
rendered_link_url: string
|
||||
/**
|
||||
* 渲染后的图片URL
|
||||
*/
|
||||
rendered_image_url: string
|
||||
/**
|
||||
* 类型(项目或组)
|
||||
*/
|
||||
kind: "project" | "group"
|
||||
}
|
||||
|
||||
/* 管道事件 */
|
||||
export interface PipelineEvent {
|
||||
/**
|
||||
* 对象属性,包含了构建的详细信息
|
||||
*/
|
||||
object_attributes: {
|
||||
/**
|
||||
* 管道ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 分支名
|
||||
*/
|
||||
ref: string
|
||||
/**
|
||||
* 提交的SHA值
|
||||
*/
|
||||
sha: string
|
||||
/**
|
||||
* 构建状态
|
||||
*/
|
||||
status: string
|
||||
/**
|
||||
* 构建创建时间
|
||||
*/
|
||||
created_at: string
|
||||
/**
|
||||
* 构建完成时间
|
||||
*/
|
||||
finished_at: string
|
||||
/**
|
||||
* 构建持续时间,单位为秒
|
||||
*/
|
||||
duration: number
|
||||
}
|
||||
/**
|
||||
* 用户信息
|
||||
*/
|
||||
user: {
|
||||
/**
|
||||
* 用户姓名
|
||||
*/
|
||||
name: string
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
username: string
|
||||
}
|
||||
/**
|
||||
* 项目信息
|
||||
*/
|
||||
project: {
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 项目的web URL
|
||||
*/
|
||||
web_url: string
|
||||
/**
|
||||
* 带命名空间的项目路径
|
||||
*/
|
||||
path_with_namespace: string
|
||||
}
|
||||
/**
|
||||
* 提交信息
|
||||
*/
|
||||
commit: {
|
||||
/**
|
||||
* 提交的ID
|
||||
*/
|
||||
id: string
|
||||
/**
|
||||
* 提交的标题
|
||||
*/
|
||||
title: string
|
||||
/**
|
||||
* 提交的链接URL
|
||||
*/
|
||||
url: string
|
||||
}
|
||||
/**
|
||||
* 构建信息
|
||||
*/
|
||||
builds: {
|
||||
/**
|
||||
* 构建的ID
|
||||
*/
|
||||
id: number
|
||||
/**
|
||||
* 构建的步骤
|
||||
*/
|
||||
stage: string
|
||||
/**
|
||||
* 构建的状态
|
||||
*/
|
||||
status: string
|
||||
/**
|
||||
* 构建的结束时间
|
||||
* @example 2024-07-29 15:49:21 +0800
|
||||
*/
|
||||
finished_at: string | null
|
||||
}[]
|
||||
}
|
||||
|
||||
/* 合并请求 */
|
||||
export interface MergeRequest {
|
||||
/**
|
||||
* 合并请求的标题
|
||||
*/
|
||||
title: string
|
||||
/**
|
||||
* 目标分支
|
||||
*/
|
||||
target_branch: string
|
||||
/**
|
||||
* 源分支
|
||||
*/
|
||||
source_branch: string
|
||||
/**
|
||||
* 作者信息
|
||||
*/
|
||||
author: {
|
||||
/**
|
||||
* 用户名
|
||||
*/
|
||||
username: string
|
||||
/**
|
||||
* 用户姓名
|
||||
*/
|
||||
name: string
|
||||
}
|
||||
/**
|
||||
* 提交的SHA值
|
||||
*/
|
||||
sha: string
|
||||
/**
|
||||
* 合并提交的SHA值
|
||||
*/
|
||||
merge_commit_sha: string
|
||||
/**
|
||||
* 引用信息
|
||||
*/
|
||||
references: {
|
||||
/**
|
||||
* 完整引用
|
||||
*/
|
||||
full: string
|
||||
}
|
||||
/**
|
||||
* 合并请求的web URL
|
||||
*/
|
||||
web_url: string
|
||||
}
|
||||
|
||||
/* 合并请求事件 */
|
||||
export interface MergeRequestEvent {
|
||||
/**
|
||||
* 事件对象类型
|
||||
*/
|
||||
object_kind: "merge_request"
|
||||
/**
|
||||
* 事件类型
|
||||
*/
|
||||
event_type: "merge_request"
|
||||
/**
|
||||
* 项目信息
|
||||
*/
|
||||
project: {
|
||||
/**
|
||||
* 项目ID
|
||||
*/
|
||||
id: number
|
||||
}
|
||||
/**
|
||||
* 合并请求的属性
|
||||
*/
|
||||
object_attributes: {
|
||||
/**
|
||||
* 合并请求的内部ID
|
||||
*/
|
||||
iid: number
|
||||
/**
|
||||
* 合并请求的状态
|
||||
*/
|
||||
state: "opened" | "closed" | "reopened" | "merged"
|
||||
/**
|
||||
* 合并请求的变更信息
|
||||
*/
|
||||
changes?: any
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 代表设置 GitLab 徽章的参数。
|
||||
*/
|
||||
export type BadgeSetParams = Omit<Badge, "kind" | "name"> & {
|
||||
badge_id?: number
|
||||
}
|
||||
|
||||
export interface CreateRangeDiscussionPosition {
|
||||
base_sha: string
|
||||
start_sha: string
|
||||
head_sha: string
|
||||
new_path: string
|
||||
old_path: string
|
||||
position_type: "text"
|
||||
new_line: number
|
||||
line_range: {
|
||||
start: {
|
||||
line_code: string
|
||||
}
|
||||
end: {
|
||||
line_code: string
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
18
packages/net-tool/src/types/index.ts
Normal file
18
packages/net-tool/src/types/index.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import type { Gitlab } from "./gitlab"
|
||||
|
||||
export interface NetRequestParams {
|
||||
url: string
|
||||
method: string
|
||||
queryParams?: any
|
||||
payload?: any
|
||||
additionalHeaders?: Record<string, string>
|
||||
}
|
||||
|
||||
export interface NetErrorDetail {
|
||||
response: Response | null
|
||||
code: number
|
||||
message: string
|
||||
data?: any
|
||||
}
|
||||
|
||||
export type { Gitlab }
|
Loading…
x
Reference in New Issue
Block a user