feat: 把每个组件进行拆包处理
Some checks failed
/ release (push) Failing after 1m1s

This commit is contained in:
zhaoyingbo 2024-08-19 01:45:18 +00:00
parent 8af6ea863b
commit 686a77d8d1
24 changed files with 8416 additions and 549 deletions

View File

@ -0,0 +1,28 @@
{
"name": "egg_tools",
"image": "mcr.microsoft.com/devcontainers/typescript-node:20",
"customizations": {
"vscode": {
"settings": {
"files.autoSave": "afterDelay",
"editor.guides.bracketPairs": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "always"
}
},
"extensions": [
"eamodio.gitlens",
"Gruntfuggly.todo-tree",
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"YoavBls.pretty-ts-errors",
"ChakrounAnas.turbo-console-log",
"streetsidesoftware.code-spell-checker",
"MS-CEINTL.vscode-language-pack-zh-hans"
]
}
},
"onCreateCommand": "curl -fsSL https://bun.sh/install | bash"
}

View File

@ -8,26 +8,26 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v2
- name: Checkout repository
uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 18
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: 18
- name: Install dependencies
run: npm install
- name: Install dependencies
run: npm install
- name: Bump version and push tag
id: bump_version
run: |
git config --global user.name 'zhaoyingbo'
git config --global user.email 'zhaoyingbo@live.cn'
npm version patch -m "chore(release): %s"
git push --follow-tags
- name: Bump version and push tag
id: bump_version
run: |
git config --global user.name 'zhaoyingbo'
git config --global user.email 'zhaoyingbo@live.cn'
npx lerna version patch --yes
git push --follow-tags
- name: Publish package
run: |
echo "//git.yingbo.im:333/api/packages/zhaoyingbo/npm/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc
npm publish
- name: Publish packages
run: |
echo "//git.yingbo.im:333/api/packages/zhaoyingbo/npm/:_authToken=${{ secrets.NPM_TOKEN }}" >> .npmrc
npx lerna publish from-package --yes

8
.gitignore vendored
View File

@ -32,6 +32,7 @@ jspm_packages
# Optional npm cache directory
.npm
.npmrc
# Optional REPL history
.node_repl_history
@ -57,5 +58,8 @@ profile*
*clinic*
*flamegraph*
# npm
.npmrc
# dist
dist
# ts
tsconfig.tsbuildinfo

3
dist/index.d.ts vendored
View File

@ -1,3 +0,0 @@
import loggerIns from "./logger";
import { NetTool, NetToolBase } from "./netTool";
export { loggerIns, NetTool, NetToolBase };

3
dist/index.js vendored
View File

@ -1,3 +0,0 @@
import loggerIns from "./logger";
import { NetTool, NetToolBase } from "./netTool";
export { loggerIns, NetTool, NetToolBase };

5
dist/logger.d.ts vendored
View File

@ -1,5 +0,0 @@
import "winston-daily-rotate-file";
import winston from "winston";
declare const loggerIns: winston.Logger;
export default loggerIns;

42
dist/logger.js vendored
View File

@ -1,42 +0,0 @@
import "winston-daily-rotate-file";
import winston, { format } from "winston";
const isProd = process.env.NODE_ENV === "production";
const transports = [
new winston.transports.Console({
level: "info",
}),
];
if (isProd) {
const config = {
datePattern: "YYYY-MM-DD",
zippedArchive: true,
maxSize: "20m",
maxFiles: "14d",
};
transports.push(new winston.transports.DailyRotateFile({
level: "info",
filename: "/home/work/log/egg-info-%DATE%.log",
...config,
}));
transports.push(new winston.transports.DailyRotateFile({
level: "debug",
filename: "/home/work/log/egg-debug-%DATE%.log",
...config,
}));
}
const loggerIns = winston.createLogger({
level: "silly",
format: format.combine(format.colorize({
level: !isProd,
}), // 开发环境下输出彩色日志
format.simple(), // 简单文本格式化
format.timestamp({ format: "YYYY-MM-DD HH:mm:ss" }), format.printf(({ level, message, timestamp, requestId }) => {
const singleLineMessage = isProd
? message.replace(/\n/g, " ") // 将换行符替换为空格
: message;
return `${timestamp} [${level}]${requestId ? ` [RequestId: ${requestId}]` : ""}: ${singleLineMessage}`;
})),
transports,
});
export default loggerIns;

152
dist/netTool.d.ts vendored
View File

@ -1,152 +0,0 @@
import { Logger } from "winston";
interface NetRequestParams {
url: string;
method: string;
queryParams?: any;
payload?: any;
additionalHeaders?: any;
}
interface NetErrorDetail {
httpStatus: number;
code: number;
message: string;
}
export declare class NetError extends Error {
code: number;
message: string;
httpStatus: number;
constructor({ code, message, httpStatus }: NetErrorDetail);
}
/**
* HTTP请求的方法
*/
declare class NetToolBase {
protected prefix: string;
protected headers: any;
protected getHeaders: () => any;
protected logger: Logger;
protected requestId: string;
/**
*
*
* @param {Object} params -
* @param {string} [params.prefix] - URL前缀
* @param {any} [params.headers] -
* @param {Function} [params.getHeaders] -
* @param {string} [params.requestId] - ID
*/
constructor({ prefix, headers, getHeaders, requestId, }?: {
prefix?: string;
headers?: any;
getHeaders?: () => any;
requestId?: string;
});
/**
*
* @param response -
* @param method - 使HTTP方法
* @param headers -
* @param requestBody -
* @param responseBody -
* @returns
*/
private logResponse;
/**
* Promise
* @param url - URL
* @param method - 使HTTP方法
* @param queryParams - URL中的查询参数
* @param payload -
* @param additionalHeaders -
* @returns Promise
* @throws
*/
protected request<T = any>({ url, method, queryParams, payload, additionalHeaders, }: NetRequestParams): Promise<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>;
/**
* 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>;
/**
* 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>;
/**
* 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>;
/**
* 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>;
}
declare class NetTool extends NetToolBase {
request<T = any>({ url, method, queryParams, payload, additionalHeaders, }: NetRequestParams): Promise<T>;
get<T = any>(url: string, queryParams?: any, additionalHeaders?: any): Promise<T>;
post<T = any>(url: string, payload?: any, queryParams?: any, additionalHeaders?: any): Promise<T>;
put<T = any>(url: string, payload: any, queryParams?: any, additionalHeaders?: any): Promise<T>;
del<T = any>(url: string, payload: any, queryParams?: any, additionalHeaders?: any): Promise<T>;
patch<T = any>(url: string, payload: any, queryParams?: any, additionalHeaders?: any): Promise<T>;
/**
* 400 Bad Request的响应对象
*
* @param message -
* @returns 400 Bad Request的响应对象
*/
badRequest(message: string): import("undici-types").Response;
/**
* 404 Not Found的响应对象
*
* @param message -
* @returns 404 Not Found的响应对象
*/
notFound(message: string): import("undici-types").Response;
/**
* 500 Internal Server Error的响应对象
*
* @param message -
* @param data -
* @returns 500 Internal Server Error的响应对象
*/
serverError(message: string, data?: any): import("undici-types").Response;
/**
* 200 OK的响应对象
*
* @param data -
* @returns 200 OK的响应对象
*/
ok(data?: any): import("undici-types").Response;
}
export { NetTool, NetToolBase };

303
dist/netTool.js vendored
View File

@ -1,303 +0,0 @@
import loggerIns from "./logger";
export class NetError extends Error {
code;
message;
httpStatus;
constructor({ code, message, httpStatus }) {
super(message);
this.code = code;
this.message = message;
this.httpStatus = httpStatus;
}
}
/**
* 网络工具类提供发送HTTP请求的方法
*/
class NetToolBase {
prefix;
headers;
getHeaders;
logger;
requestId;
/**
* 创建一个网络工具类实例
*
* @param {Object} params - 构造函数参数
* @param {string} [params.prefix] - URL前缀
* @param {any} [params.headers] - 默认请求头
* @param {Function} [params.getHeaders] - 获取请求头的方法
* @param {string} [params.requestId] - 请求ID
*/
constructor({ prefix, headers, getHeaders, requestId, } = {}) {
this.prefix = prefix || "";
this.headers = headers || {};
this.getHeaders = getHeaders || (() => ({}));
this.requestId = requestId || "";
this.logger = loggerIns.child({ requestId });
}
/**
* 记录响应详情并返回响应日志对象
* @param response - 响应对象
* @param method - 请求使用的HTTP方法
* @param headers - 请求头
* @param requestBody - 请求体
* @param responseBody - 响应体
* @returns 响应日志对象
*/
logResponse(response, method, headers, requestBody, responseBody) {
const responseLog = {
ok: response.ok,
status: response.status,
statusText: response.statusText,
url: response.url,
method: method,
requestHeaders: headers,
responseHeaders: response.headers,
requestBody,
responseBody,
};
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 如果网络响应不成功或存在解析错误则抛出错误
*/
async request({ url, method, queryParams, payload, additionalHeaders, }) {
// 拼接完整的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,
};
// 设置请求Header
if (!(payload instanceof FormData)) {
headers["Content-Type"] = "application/json";
}
// 处理请求数据
const body = payload instanceof FormData ? payload : JSON.stringify(payload);
// 发送请求
const res = await fetch(fullUrl, {
method,
body,
headers,
});
// 获取响应数据
let resData = null;
let resText = "";
try {
resText = await res.text();
resData = JSON.parse(resText);
}
catch {
/* empty */
}
// 记录响应
this.logResponse(res, method, headers, payload, resData || resText);
if (!res.ok) {
if (resData?.message || resData?.msg) {
throw new NetError({
httpStatus: res.status,
code: resData?.code,
message: resData?.message || resData?.msg,
});
}
throw new NetError({
httpStatus: res.status,
code: res.status,
message: resText || "网络响应异常",
});
}
// http 错误码正常,但解析异常
if (!resData) {
throw new NetError({
httpStatus: res.status,
code: 1,
message: "解析响应数据异常",
});
}
// 响应数据异常
if ("code" in resData && resData.code !== 0) {
throw new NetError({
httpStatus: res.status,
code: resData.code,
message: resData.message || resData.msg || "网络请求失败",
});
}
return resData;
}
/**
* 发送GET请求并返回一个解析为响应数据的Promise
*
* @param url - 要发送请求的URL
* @param queryParams - 要包含在URL中的查询参数
* @param additionalHeaders - 要包含在请求中的附加头
* @returns 一个解析为响应数据的Promise
*/
get(url, queryParams, additionalHeaders) {
return this.request({ url, method: "get", queryParams, additionalHeaders });
}
/**
* 发送POST请求并返回一个解析为响应数据的Promise
*
* @param url - 要发送请求的URL
* @param payload - 请求的有效负载数据
* @param queryParams - 要包含在URL中的查询参数
* @param additionalHeaders - 要包含在请求中的附加头
* @returns 一个解析为响应数据的Promise
*/
post(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "post",
payload,
queryParams,
additionalHeaders,
});
}
/**
* 发送PUT请求并返回一个解析为响应数据的Promise
*
* @param url - 要发送请求的URL
* @param payload - 请求的有效负载数据
* @param queryParams - 要包含在URL中的查询参数
* @param additionalHeaders - 要包含在请求中的附加头
* @returns 一个解析为响应数据的Promise
*/
put(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "put",
payload,
queryParams,
additionalHeaders,
});
}
/**
* 发送DELETE请求并返回一个解析为响应数据的Promise
*
* @param url - 要发送请求的URL
* @param payload - 请求的有效负载数据
* @param queryParams - 要包含在URL中的查询参数
* @param additionalHeaders - 要包含在请求中的附加头
* @returns 一个解析为响应数据的Promise
*/
del(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "delete",
payload,
queryParams,
additionalHeaders,
});
}
/**
* 发送PATCH请求并返回一个解析为响应数据的Promise
*
* @param url - 要发送请求的URL
* @param payload - 请求的有效负载数据
* @param queryParams - 要包含在URL中的查询参数
* @param additionalHeaders - 要包含在请求中的附加头
* @returns 一个解析为响应数据的Promise
*/
patch(url, payload, queryParams, additionalHeaders) {
return this.request({
url,
method: "patch",
payload,
queryParams,
additionalHeaders,
});
}
}
class NetTool extends NetToolBase {
request({ url, method, queryParams, payload, additionalHeaders, }) {
return super.request({
url,
method,
queryParams,
payload,
additionalHeaders,
});
}
get(url, queryParams, additionalHeaders) {
return super.get(url, queryParams, additionalHeaders);
}
post(url, payload, queryParams, additionalHeaders) {
return super.post(url, payload, queryParams, additionalHeaders);
}
put(url, payload, queryParams, additionalHeaders) {
return super.put(url, payload, queryParams, additionalHeaders);
}
del(url, payload, queryParams, additionalHeaders) {
return super.del(url, payload, queryParams, additionalHeaders);
}
patch(url, payload, queryParams, additionalHeaders) {
return super.patch(url, payload, queryParams, additionalHeaders);
}
/**
* 创建一个表示400 Bad Request的响应对象
*
* @param message - 错误消息
* @returns 一个表示400 Bad Request的响应对象
*/
badRequest(message) {
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) {
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, data) {
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) {
this.logger.info(`return a ok response: ${JSON.stringify(data)}`);
return Response.json({
code: 0,
message: "success",
data,
requestId: this.requestId,
});
}
}
export { NetTool, NetToolBase };

12
lerna.json Normal file
View File

@ -0,0 +1,12 @@
{
"packages": [
"packages/*"
],
"version": "independent",
"command": {
"publish": {
"conventionalCommits": true,
"yes": true
}
}
}

8192
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,26 +1,28 @@
{
"name": "@egg/tools",
"version": "1.0.5",
"description": "Tools for Egg projects, including netTool and logger",
"description": "Tools for Egg projects",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"lint": "eslint --fix ./src",
"build": "npm run build -ws",
"publish": "npm run publish -ws",
"lint": "eslint --fix ./packages",
"prepare": "husky",
"prettier": "prettier --write ./src"
"prettier": "prettier --write ./packages"
},
"keywords": [
"egg",
"tools",
"logger",
"netTool"
"tools"
],
"author": "RainSun <zhaoyingbo@live.cn>",
"license": "ISC",
"workspaces": [
"packages/*"
],
"lint-staged": {
"src/*.{js,jsx,ts,tsx}": [
"packages/*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write",
"git add"
@ -30,11 +32,13 @@
"@commitlint/cli": "^19.4.0",
"@commitlint/config-conventional": "^19.2.2",
"@eslint/js": "^9.9.0",
"@lerna/conventional-commits": "^6.4.1",
"@types/node": "^22.4.0",
"eslint": "^9.9.0",
"eslint-plugin-simple-import-sort": "^12.1.1",
"globals": "^15.9.0",
"husky": "^9.1.4",
"lerna": "^8.1.8",
"lint-staged": "^15.2.9",
"prettier": "^3.3.3",
"typescript": "^5.5.4",

View File

@ -0,0 +1,23 @@
{
"name": "@egg/logger",
"version": "1.0.0",
"description": "Logger for Egg projects",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
},
"keywords": [
"egg",
"tools",
"logger"
],
"author": "RainSun <zhaoyingbo@live.cn>",
"license": "ISC",
"dependencies": {
"winston": "*",
"winston-daily-rotate-file": "*"
}
}

View File

@ -34,7 +34,7 @@ if (isProd) {
)
}
const loggerIns = winston.createLogger({
const logger = winston.createLogger({
level: "silly",
format: format.combine(
format.colorize({
@ -52,4 +52,4 @@ const loggerIns = winston.createLogger({
transports,
})
export default loggerIns
export default logger

View File

@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["./src"]
}

View File

@ -0,0 +1,23 @@
{
"name": "@egg/net-tool",
"version": "1.0.0",
"description": "Net Tools for Egg projects",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
},
"keywords": [
"egg",
"tools",
"net-tool"
],
"author": "RainSun <zhaoyingbo@live.cn>",
"license": "ISC",
"dependencies": {
"winston": "*",
"@egg/logger": "*"
}
}

View File

@ -1,6 +1,5 @@
import { Logger } from "winston"
import loggerIns from "./logger"
import logger from "@egg/logger"
interface NetRequestParams {
url: string
@ -63,7 +62,7 @@ class NetToolBase {
this.headers = headers || {}
this.getHeaders = getHeaders || (() => ({}))
this.requestId = requestId || ""
this.logger = loggerIns.child({ requestId })
this.logger = logger.child({ requestId })
}
/**

View File

@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["./src"]
}

View File

@ -0,0 +1,19 @@
{
"name": "@egg/path-tool",
"version": "1.0.0",
"description": "Path Tools for Egg projects",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"build": "tsc",
"prepublishOnly": "npm run build"
},
"keywords": [
"egg",
"tools",
"path-tool"
],
"author": "RainSun <zhaoyingbo@live.cn>",
"license": "ISC"
}

View File

@ -0,0 +1,51 @@
/**
*
* @param {string} url - URL
* @param {string} [prefix] -
* @returns {object}
*/
export const makeCheckPathTool = (url: string, prefix?: string) => {
const { pathname } = new URL(url)
const makePath = (path: string) => `${prefix || ""}${path}`
return {
/**
* URL
* @param {string} path -
* @returns {boolean} true false
*/
exactCheck: (path: string) => {
return pathname === makePath(path)
},
/**
* URL
* @param {string} path -
* @returns {boolean} URL true false
*/
startsWithCheck: (path: string) => pathname.startsWith(makePath(path)),
/**
* URL
* @param {string} path -
* @returns {boolean} URL true false
*/
fullCheck: (path: string) => pathname === path,
}
}
/**
* 20
*
* @param {string} path -
* @returns {string} - 20
*/
export const shortenPath = (path: string): string => {
if (path.length <= 20) {
return path
}
const parts = path.split("/")
if (parts.length <= 2) {
return path
}
return `.../${parts[parts.length - 2]}/${parts[parts.length - 1]}`
}

View File

@ -0,0 +1,8 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": "./dist",
"rootDir": "./src"
},
"include": ["./src"]
}

View File

@ -1,4 +0,0 @@
import loggerIns from "./logger"
import { NetTool, NetToolBase } from "./netTool"
export { loggerIns, NetTool, NetToolBase }

View File

@ -16,9 +16,10 @@
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"declaration": true,
"rootDir": "./src", // rootDir
"sourceMap": true,
"rootDir": "./packages",
"outDir": "./dist"
},
"include": ["src"],
"include": ["./packages/**/*"],
"exclude": ["node_modules", "**/*.test.ts"]
}

File diff suppressed because one or more lines are too long