@sycsq/common 0.0.2 → 0.0.4

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/README.md CHANGED
@@ -1,327 +1,615 @@
1
- # Personal Utils
1
+ # @sycsq/common
2
2
 
3
- 一个基于 Vite 构建的 TypeScript 工具库,提供 HTTP 请求封装和常用工具函数,支持完整的类型声明。
3
+ 中文 | [English](#english)
4
4
 
5
- ## 特性
5
+ `@sycsq/common` 是一个基于 TypeScript 和 Vite 构建的通用工具库,提供 Axios 请求封装、请求辅助函数、请求取消管理和常用类型判断工具。
6
6
 
7
- - 🚀 基于 Vite 构建,支持 ES Module 和 UMD 格式
8
- - 📦 完整的 TypeScript 类型支持
9
- - 🔧 封装的 HTTP 请求工具,基于 Axios
10
- - 🛠️ 丰富的工具函数集合
11
- - 📱 支持浏览器和 Node.js 环境
12
- - 🎯 零配置,开箱即用
7
+ ## 特性
13
8
 
14
- ## 📦 安装
9
+ - TypeScript 类型声明
10
+ - 基于 Axios 的 HTTP 客户端封装
11
+ - 支持请求/响应转换钩子
12
+ - 支持重复请求取消、时间戳参数、日期参数格式化
13
+ - 支持 ESM 和 UMD 构建产物
14
+ - 包含 Vitest 单元测试和 GitHub Actions 自动化检查
15
+
16
+ ## 环境要求
17
+
18
+ - Node.js `^20.19.0 || >=22.12.0`
19
+ - pnpm `>= 7`
20
+
21
+ ## 安装
15
22
 
16
23
  ```bash
17
24
  npm install @sycsq/common
18
- # 或
25
+ ```
26
+
27
+ ```bash
19
28
  yarn add @sycsq/common
20
- # 或
29
+ ```
30
+
31
+ ```bash
21
32
  pnpm add @sycsq/common
22
33
  ```
23
34
 
24
- ## 🚀 快速开始
35
+ ## 快速开始
36
+
37
+ ### 按需引入
25
38
 
26
- ### HTTP 工具使用
39
+ 推荐在业务项目中优先使用子路径引入,避免因为根入口同时暴露 HTTP 和工具函数而让打包器分析更多模块:
40
+
41
+ ```typescript
42
+ import { isEmpty, isString } from '@sycsq/common/utils';
43
+ import { http } from '@sycsq/common/http';
44
+ import { joinTimestamp } from '@sycsq/common/http/helper';
45
+ ```
46
+
47
+ 包本身已配置 `sideEffects: false`,并提供独立的 ESM/CJS 子路径产物。`axios` 会作为外部运行时依赖处理,库构建不会把 Axios 打进产物。
48
+
49
+ ### HTTP 请求
27
50
 
28
51
  ```typescript
29
52
  import { http } from '@sycsq/common';
30
53
 
31
- // GET 请求
32
- const getData = async () => {
33
- try {
34
- const response = await http.get('/api/users');
35
- console.log(response.data);
36
- } catch (error) {
37
- console.error('请求失败:', error);
38
- }
39
- };
40
-
41
- // POST 请求
42
- const createUser = async (userData: any) => {
43
- try {
44
- const response = await http.post('/api/users', userData);
45
- console.log('用户创建成功:', response.data);
46
- } catch (error) {
47
- console.error('创建失败:', error);
48
- }
49
- };
54
+ const users = await http.get('/api/users', {
55
+ params: { page: 1 }
56
+ });
57
+
58
+ const created = await http.post('/api/users', {
59
+ name: 'Alice'
60
+ });
50
61
  ```
51
62
 
52
- ### 工具函数使用
63
+ 也可以使用配置对象形式:
53
64
 
54
65
  ```typescript
55
- import { isString, isEmpty, isUrl } from '@sycsq/common';
66
+ import { request } from '@sycsq/common';
56
67
 
57
- // 类型检查
58
- console.log(isString('hello')); // true
59
- console.log(isString(123)); // false
68
+ const result = await request({
69
+ url: '/api/users',
70
+ method: 'GET',
71
+ params: { page: 1 }
72
+ });
73
+ ```
60
74
 
61
- // 空值检查
62
- console.log(isEmpty('')); // true
63
- console.log(isEmpty([])); // true
64
- console.log(isEmpty({})); // true
75
+ ### 工具函数
65
76
 
66
- // URL 验证
67
- console.log(isUrl('https://example.com')); // true
68
- console.log(isUrl('not-a-url')); // false
77
+ ```typescript
78
+ import { isEmpty, isString, isUrl } from '@sycsq/common';
79
+
80
+ isString('hello'); // true
81
+ isEmpty({}); // true
82
+ isUrl('https://example.com'); // true
69
83
  ```
70
84
 
71
- ## 📚 API 文档
85
+ ## 导出内容
86
+
87
+ 根入口会继续导出全部公共 API,兼容已有用法:
72
88
 
73
- ### HTTP 模块
89
+ ```typescript
90
+ import {
91
+ Axios,
92
+ AxiosCanceler,
93
+ axiosTransform,
94
+ http,
95
+ request,
96
+ isString,
97
+ isEmpty,
98
+ joinTimestamp,
99
+ setObjToUrlParams
100
+ } from '@sycsq/common';
101
+ ```
74
102
 
75
- #### 配置选项
103
+ ## HTTP API
104
+
105
+ ### 默认实例
76
106
 
77
107
  ```typescript
78
- interface RequestOptions {
79
- joinPrefix?: boolean; // 是否添加 URL 前缀
80
- isReturnNativeResponse?: boolean; // 是否返回原生响应
81
- isTransformResponse?: boolean; // 是否转换响应数据
82
- joinParamsToUrl?: boolean; // POST 请求是否将参数添加到 URL
83
- formatDate?: boolean; // 是否格式化日期参数
84
- apiUrl?: string; // API 基础地址
85
- urlPrefix?: string; // URL 前缀
86
- joinTime?: boolean; // 是否添加时间戳
87
- ignoreCancelToken?: boolean; // 是否忽略重复请求
88
- withToken?: boolean; // 是否携带 Token
89
- }
108
+ import { http, request } from '@sycsq/common';
90
109
  ```
91
110
 
92
- #### 请求方法
111
+ - `http`:默认 Axios 封装实例
112
+ - `request`:`http.request.bind(http)` 的快捷导出
113
+
114
+ ### 请求方法
93
115
 
94
- - `http.get(url, config?)` - GET 请求
95
- - `http.post(url, data?, config?)` - POST 请求
96
- - `http.put(url, data?, config?)` - PUT 请求
97
- - `http.delete(url, config?)` - DELETE 请求
98
- - `http.patch(url, data?, config?)` - PATCH 请求
116
+ 每个方法都支持配置对象形式;常用方法也支持 URL 优先形式。
99
117
 
100
- ### 工具函数模块
118
+ ```typescript
119
+ http.request<T>(config, options?)
120
+ http.get<T>(config, options?)
121
+ http.get<T>(url, config?, options?)
122
+ http.post<T>(config, options?)
123
+ http.post<T>(url, data?, config?, options?)
124
+ http.put<T>(config, options?)
125
+ http.put<T>(url, data?, config?, options?)
126
+ http.delete<T>(config, options?)
127
+ http.delete<T>(url, config?, options?)
128
+ http.patch<T>(config, options?)
129
+ http.patch<T>(url, data?, config?, options?)
130
+ ```
101
131
 
102
- #### 类型检查函数
132
+ ### 创建自定义实例
103
133
 
104
- - `is(val, type)` - 检查值是否为指定类型
105
- - `isString(val)` - 检查是否为字符串
106
- - `isNumber(val)` - 检查是否为数字
107
- - `isBoolean(val)` - 检查是否为布尔值
108
- - `isObject(val)` - 检查是否为对象
109
- - `isArray(val)` - 检查是否为数组
110
- - `isFunction(val)` - 检查是否为函数
111
- - `isDate(val)` - 检查是否为日期
112
- - `isPromise(val)` - 检查是否为 Promise
113
- - `isRegExp(val)` - 检查是否为正则表达式
134
+ ```typescript
135
+ import { Axios, ContentTypeEnum, axiosTransform } from '@sycsq/common';
136
+
137
+ const api = new Axios({
138
+ baseURL: 'https://api.example.com',
139
+ timeout: 10000,
140
+ headers: {
141
+ 'Content-Type': ContentTypeEnum.JSON
142
+ },
143
+ transform: axiosTransform,
144
+ requestOptions: {
145
+ joinPrefix: false,
146
+ isReturnNativeResponse: false,
147
+ isTransformResponse: true,
148
+ joinParamsToUrl: false,
149
+ formatDate: true,
150
+ apiUrl: '',
151
+ urlPrefix: '',
152
+ joinTime: true,
153
+ ignoreCancelToken: true,
154
+ withToken: true
155
+ }
156
+ });
157
+ ```
114
158
 
115
- #### 值检查函数
159
+ ### RequestOptions
160
+
161
+ ```typescript
162
+ interface RequestOptions {
163
+ joinParamsToUrl?: boolean;
164
+ formatDate?: boolean;
165
+ isTransformResponse?: boolean;
166
+ isReturnNativeResponse?: boolean;
167
+ joinPrefix?: boolean;
168
+ apiUrl?: string;
169
+ urlPrefix?: string;
170
+ joinTime?: boolean;
171
+ ignoreCancelToken?: boolean;
172
+ withToken?: boolean;
173
+ errorHandler?: Function;
174
+ }
175
+ ```
116
176
 
117
- - `isDef(val)` - 检查是否已定义
118
- - `isUnDef(val)` - 检查是否未定义
119
- - `isNull(val)` - 检查是否为 null
120
- - `isEmpty(val)` - 检查是否为空值
121
- - `isNullOrUnDef(val)` - 检查是否为 null 或 undefined
177
+ ### 响应转换规则
122
178
 
123
- #### 环境检查函数
179
+ 默认 `axiosTransform` 会根据业务响应结构处理数据:
124
180
 
125
- - `isServer` - 是否为服务端环境
126
- - `isClient` - 是否为客户端环境
127
- - `isWindow(val)` - 检查是否为 Window 对象
128
- - `isElement(val)` - 检查是否为 DOM 元素
129
- - `isUrl(path)` - 检查是否为有效 URL
181
+ - `isReturnNativeResponse: true`:返回完整 Axios 响应
182
+ - `isTransformResponse: false`:返回 `response.data`
183
+ - 成功业务码 `200` `202`:返回 `data`,如果 `data` 为 `undefined` 则返回 `body`
184
+ - 失败业务码:调用 `errorHandler` 或输出错误信息,并抛出错误
130
185
 
131
- ## 🏗️ 项目结构
186
+ ### 辅助函数
132
187
 
188
+ ```typescript
189
+ joinTimestamp(join, restful)
190
+ formatRequestDate(params)
191
+ setObjToUrlParams(baseUrl, obj)
133
192
  ```
134
- personal-utils/
135
- ├── packages/ # 源代码
136
- │ ├── index.ts # 主入口文件
137
- │ ├── http/ # HTTP 工具模块
138
- │ │ ├── Axios.ts # Axios 封装类
139
- │ │ ├── axiosTransform.ts # 请求/响应转换器
140
- │ │ ├── axiosCancel.ts # 请求取消处理
141
- │ │ ├── helper.ts # 辅助函数
142
- │ │ ├── types.ts # 类型定义
143
- │ │ └── index.ts # HTTP 模块入口
144
- │ └── utils/ # 工具函数模块
145
- │ └── index.ts # 工具函数集合
146
- ├── lib/ # 构建输出
147
- │ ├── index.esm.js # ES 模块格式
148
- │ ├── index.umd.js # UMD 格式
149
- │ └── index.d.ts # 类型声明
150
- ├── types/ # 类型声明文件
151
- ├── example/ # Vue 3 示例项目
152
- ├── pnpm-workspace.yaml # pnpm workspace 配置
153
- └── package.json # 项目配置
193
+
194
+ ### 请求取消
195
+
196
+ ```typescript
197
+ import { AxiosCanceler } from '@sycsq/common';
198
+
199
+ const canceler = new AxiosCanceler();
200
+
201
+ canceler.addPending(config);
202
+ canceler.removePending(config);
203
+ canceler.removeAllPending();
204
+ canceler.reset();
154
205
  ```
155
206
 
156
- ## 🛠️ 开发
207
+ ## 工具函数 API
208
+
209
+ ### 类型判断
210
+
211
+ - `is(val, type)`
212
+ - `isString(val)`
213
+ - `isNumber(val)`
214
+ - `isBoolean(val)`
215
+ - `isObject(val)`
216
+ - `isArray(val)`
217
+ - `isFunction(val)`
218
+ - `isDate(val)`
219
+ - `isPromise(val)`
220
+ - `isRegExp(val)`
221
+ - `isSymbol(val)`
222
+
223
+ ### 值判断
157
224
 
158
- ### 环境要求
225
+ - `isDef(val)`
226
+ - `isUnDef(val)`
227
+ - `isNull(val)`
228
+ - `isNullAndUnDef(val)`
229
+ - `isNullOrUnDef(val)`
230
+ - `isEmpty(val)`
159
231
 
160
- - Node.js >= 16
161
- - pnpm >= 7
232
+ ### 环境与 DOM 判断
162
233
 
163
- ### 安装依赖
234
+ - `isServer`
235
+ - `isClient`
236
+ - `isWindow(val)`
237
+ - `isElement(val)`
238
+ - `isUrl(path)`
239
+
240
+ ## 开发
164
241
 
165
242
  ```bash
166
243
  pnpm install
167
244
  ```
168
245
 
169
- ### 开发命令
246
+ ```bash
247
+ pnpm test
248
+ ```
170
249
 
171
250
  ```bash
172
- # 构建库
173
251
  pnpm build
252
+ ```
174
253
 
175
- # 仅构建类型声明
254
+ ```bash
176
255
  pnpm build:types
256
+ ```
257
+
258
+ ## 示例项目
177
259
 
178
- # 开发模式
179
- pnpm dev
260
+ 仓库包含一个 Vue 示例项目:
180
261
 
181
- # 启动示例项目
262
+ ```bash
182
263
  pnpm example:dev
264
+ pnpm example:build
265
+ pnpm example:preview
266
+ ```
267
+
268
+ ## 自动化
269
+
270
+ 项目包含两个 GitHub Actions 工作流:
271
+
272
+ - `CI`:在 pull request 和 `main` 分支 push 时执行 `pnpm install --frozen-lockfile`、`pnpm test` 和 `pnpm build`
273
+ - `Publish Package`:在 `main` 分支相关源码变更或手动触发时执行测试、构建、npm 发布和 GitHub Release 创建
274
+
275
+ 发布到 npm 需要在仓库的 `Settings -> Secrets and variables -> Actions` 中配置:
276
+
277
+ - `NPM_TOKEN`:npm automation token,需要具备发布 `@sycsq/common` 的权限
278
+
279
+ ## 构建体积策略
280
+
281
+ - 多入口构建:`index`、`http`、`utils` 和细粒度 HTTP 子模块分别输出
282
+ - 依赖外部化:`axios` 不会被打入库产物,避免宿主项目重复打包
283
+ - 移除额外运行时依赖:form-urlencoded 序列化由轻量内置实现完成
284
+ - 禁用 public 目录复制,npm 包只包含运行所需文件
285
+ - 使用 ESM + CJS 双格式,并通过 `exports` 暴露子路径入口
183
286
 
184
- # 一键设置(推荐)
185
- pnpm example:setup
287
+ ## 项目结构
288
+
289
+ ```text
290
+ .
291
+ ├── .github/workflows/ # GitHub Actions workflows
292
+ ├── example/ # Vue example
293
+ ├── packages/ # Source code
294
+ │ ├── http/ # HTTP wrapper and helpers
295
+ │ ├── utils/ # Utility functions
296
+ │ └── index.ts # Package entry
297
+ ├── tests/ # Unit tests
298
+ ├── types/ # Generated declaration files
299
+ ├── package.json
300
+ ├── pnpm-lock.yaml
301
+ ├── tsconfig.json
302
+ └── vite.config.ts
186
303
  ```
187
304
 
188
- ### 示例项目
305
+ ## 许可证
306
+
307
+ MIT
308
+
309
+ ---
310
+
311
+ ## English
312
+
313
+ `@sycsq/common` is a TypeScript utility library built with Vite. It provides an Axios-based HTTP wrapper, request helpers, request cancellation management, and common type guard utilities.
314
+
315
+ ## Features
316
+
317
+ - TypeScript declaration files
318
+ - Axios-based HTTP client wrapper
319
+ - Request and response transform hooks
320
+ - Duplicate request cancellation, timestamp parameters, and date parameter formatting
321
+ - ESM and UMD build outputs
322
+ - Vitest unit tests and GitHub Actions automation
323
+
324
+ ## Requirements
325
+
326
+ - Node.js `^20.19.0 || >=22.12.0`
327
+ - pnpm `>= 7`
189
328
 
190
- 项目包含一个完整的 Vue 3 示例,展示如何使用库中的功能:
329
+ ## Installation
191
330
 
192
331
  ```bash
193
- # 启动示例项目
194
- pnpm example:dev
332
+ npm install @sycsq/common
333
+ ```
195
334
 
196
- # 构建示例项目
197
- pnpm example:build
335
+ ```bash
336
+ yarn add @sycsq/common
337
+ ```
198
338
 
199
- # 预览构建结果
200
- pnpm example:preview
339
+ ```bash
340
+ pnpm add @sycsq/common
341
+ ```
342
+
343
+ ## Quick Start
344
+
345
+ ### On-demand Imports
346
+
347
+ Prefer subpath imports in application projects so bundlers only need to analyze the module family you actually use:
348
+
349
+ ```typescript
350
+ import { isEmpty, isString } from '@sycsq/common/utils';
351
+ import { http } from '@sycsq/common/http';
352
+ import { joinTimestamp } from '@sycsq/common/http/helper';
353
+ ```
354
+
355
+ The package is marked with `sideEffects: false` and ships independent ESM/CJS subpath outputs. `axios` is treated as an external runtime dependency, so it is not bundled into the library output.
356
+
357
+ ### HTTP Requests
358
+
359
+ ```typescript
360
+ import { http } from '@sycsq/common';
361
+
362
+ const users = await http.get('/api/users', {
363
+ params: { page: 1 }
364
+ });
365
+
366
+ const created = await http.post('/api/users', {
367
+ name: 'Alice'
368
+ });
369
+ ```
370
+
371
+ You can also use the config-object form:
372
+
373
+ ```typescript
374
+ import { request } from '@sycsq/common';
375
+
376
+ const result = await request({
377
+ url: '/api/users',
378
+ method: 'GET',
379
+ params: { page: 1 }
380
+ });
381
+ ```
382
+
383
+ ### Utility Functions
384
+
385
+ ```typescript
386
+ import { isEmpty, isString, isUrl } from '@sycsq/common';
387
+
388
+ isString('hello'); // true
389
+ isEmpty({}); // true
390
+ isUrl('https://example.com'); // true
391
+ ```
392
+
393
+ ## Exports
394
+
395
+ The root entry still re-exports every public API for backward compatibility:
396
+
397
+ ```typescript
398
+ import {
399
+ Axios,
400
+ AxiosCanceler,
401
+ axiosTransform,
402
+ http,
403
+ request,
404
+ isString,
405
+ isEmpty,
406
+ joinTimestamp,
407
+ setObjToUrlParams
408
+ } from '@sycsq/common';
201
409
  ```
202
410
 
203
- ## 📝 类型支持
411
+ ## HTTP API
204
412
 
205
- 本库提供完整的 TypeScript 类型支持,包括:
413
+ ### Default Instance
206
414
 
207
- - 所有工具函数的类型定义
208
- - HTTP 请求配置的类型定义
209
- - 响应数据的类型定义
210
- - 完整的 IntelliSense 支持
415
+ ```typescript
416
+ import { http, request } from '@sycsq/common';
417
+ ```
211
418
 
212
- ## 🤝 贡献
419
+ - `http`: default wrapped Axios instance
420
+ - `request`: shortcut for `http.request.bind(http)`
213
421
 
214
- 欢迎提交 Issue 和 Pull Request!
422
+ ### Request Methods
215
423
 
216
- ## 📄 许可证
424
+ Every method supports the config-object form. Common methods also support the URL-first form.
217
425
 
218
- MIT License
426
+ ```typescript
427
+ http.request<T>(config, options?)
428
+ http.get<T>(config, options?)
429
+ http.get<T>(url, config?, options?)
430
+ http.post<T>(config, options?)
431
+ http.post<T>(url, data?, config?, options?)
432
+ http.put<T>(config, options?)
433
+ http.put<T>(url, data?, config?, options?)
434
+ http.delete<T>(config, options?)
435
+ http.delete<T>(url, config?, options?)
436
+ http.patch<T>(config, options?)
437
+ http.patch<T>(url, data?, config?, options?)
438
+ ```
219
439
 
220
- ## 🔗 相关链接
440
+ ### Custom Instance
221
441
 
222
- - [Vite](https://vitejs.dev/) - 构建工具
223
- - [Axios](https://axios-http.com/) - HTTP 客户端
224
- - [TypeScript](https://www.typescriptlang.org/) - 编程语言
442
+ ```typescript
443
+ import { Axios, ContentTypeEnum, axiosTransform } from '@sycsq/common';
444
+
445
+ const api = new Axios({
446
+ baseURL: 'https://api.example.com',
447
+ timeout: 10000,
448
+ headers: {
449
+ 'Content-Type': ContentTypeEnum.JSON
450
+ },
451
+ transform: axiosTransform,
452
+ requestOptions: {
453
+ joinPrefix: false,
454
+ isReturnNativeResponse: false,
455
+ isTransformResponse: true,
456
+ joinParamsToUrl: false,
457
+ formatDate: true,
458
+ apiUrl: '',
459
+ urlPrefix: '',
460
+ joinTime: true,
461
+ ignoreCancelToken: true,
462
+ withToken: true
463
+ }
464
+ });
465
+ ```
225
466
 
467
+ ### RequestOptions
226
468
 
469
+ ```typescript
470
+ interface RequestOptions {
471
+ joinParamsToUrl?: boolean;
472
+ formatDate?: boolean;
473
+ isTransformResponse?: boolean;
474
+ isReturnNativeResponse?: boolean;
475
+ joinPrefix?: boolean;
476
+ apiUrl?: string;
477
+ urlPrefix?: string;
478
+ joinTime?: boolean;
479
+ ignoreCancelToken?: boolean;
480
+ withToken?: boolean;
481
+ errorHandler?: Function;
482
+ }
483
+ ```
227
484
 
228
- # GitHub Actions 自动发布配置
485
+ ### Response Transform Behavior
229
486
 
230
- 本项目配置了 GitHub Actions 工作流,实现提交到 main 分支时自动构建和发布到 NPM。
487
+ The default `axiosTransform` processes business responses as follows:
231
488
 
232
- ## 🚀 工作流说明
489
+ - `isReturnNativeResponse: true`: returns the full Axios response
490
+ - `isTransformResponse: false`: returns `response.data`
491
+ - Success codes `200` or `202`: returns `data`; if `data` is `undefined`, returns `body`
492
+ - Failed business codes: calls `errorHandler` or logs the error, then throws
233
493
 
234
- ### 触发条件
235
- - 推送到 `main` 分支
236
- - 忽略以下文件的变更:
237
- - `*.md` 文件
238
- - `.gitignore`
239
- - `LICENSE`
240
- - `.github/**`
241
- - `example/**`
494
+ ### Helpers
242
495
 
243
- ### 执行步骤
244
- 1. **检出代码** - 获取最新代码
245
- 2. **设置环境** - 配置 Node.js 18 和 pnpm 8
246
- 3. **安装依赖** - 使用 pnpm 安装项目依赖
247
- 4. **构建项目** - 执行 TypeScript 编译和 Vite 构建
248
- 5. **生成类型** - 生成 TypeScript 类型声明文件
249
- 6. **版本管理** - 自动检查并更新版本号
250
- 7. **发布到 NPM** - 自动发布到 npm 仓库
251
- 8. **创建 Release** - 在 GitHub 上创建发布版本
496
+ ```typescript
497
+ joinTimestamp(join, restful)
498
+ formatRequestDate(params)
499
+ setObjToUrlParams(baseUrl, obj)
500
+ ```
252
501
 
253
- ## ⚙️ 环境变量配置
502
+ ### Request Cancellation
254
503
 
255
- ### 必需的环境变量
504
+ ```typescript
505
+ import { AxiosCanceler } from '@sycsq/common';
506
+
507
+ const canceler = new AxiosCanceler();
508
+
509
+ canceler.addPending(config);
510
+ canceler.removePending(config);
511
+ canceler.removeAllPending();
512
+ canceler.reset();
513
+ ```
256
514
 
257
- GitHub 仓库的 Settings → Secrets and variables → Actions 中添加以下密钥:
515
+ ## Utility API
258
516
 
259
- #### `NPM_TOKEN`
260
- - **获取方式**: 在 [npmjs.com](https://www.npmjs.com/) 登录后,进入 Profile → Access Tokens
261
- - **权限**: 选择 "Automation" 类型,确保有发布权限
262
- - **用途**: 用于自动发布包到 NPM
517
+ ### Type Guards
263
518
 
264
- ### 自动提供的环境变量
519
+ - `is(val, type)`
520
+ - `isString(val)`
521
+ - `isNumber(val)`
522
+ - `isBoolean(val)`
523
+ - `isObject(val)`
524
+ - `isArray(val)`
525
+ - `isFunction(val)`
526
+ - `isDate(val)`
527
+ - `isPromise(val)`
528
+ - `isRegExp(val)`
529
+ - `isSymbol(val)`
265
530
 
266
- - `GITHUB_TOKEN` - GitHub 自动提供,用于创建 Release
531
+ ### Value Guards
267
532
 
268
- ## 🔧 手动发布命令
533
+ - `isDef(val)`
534
+ - `isUnDef(val)`
535
+ - `isNull(val)`
536
+ - `isNullAndUnDef(val)`
537
+ - `isNullOrUnDef(val)`
538
+ - `isEmpty(val)`
269
539
 
270
- 如果需要在本地手动发布,可以使用以下命令:
540
+ ### Environment and DOM Guards
541
+
542
+ - `isServer`
543
+ - `isClient`
544
+ - `isWindow(val)`
545
+ - `isElement(val)`
546
+ - `isUrl(path)`
547
+
548
+ ## Development
271
549
 
272
550
  ```bash
273
- # 增加 patch 版本并发布
274
- pnpm publish:patch
551
+ pnpm install
552
+ ```
275
553
 
276
- # 增加 minor 版本并发布
277
- pnpm publish:minor
554
+ ```bash
555
+ pnpm test
556
+ ```
278
557
 
279
- # 增加 major 版本并发布
280
- pnpm publish:major
558
+ ```bash
559
+ pnpm build
560
+ ```
281
561
 
282
- # 仅更新版本号
283
- pnpm version:patch
284
- pnpm version:minor
285
- pnpm version:major
562
+ ```bash
563
+ pnpm build:types
286
564
  ```
287
565
 
288
- ## 📋 版本管理规则
566
+ ## Example Project
289
567
 
290
- - **首次发布**: 使用 `package.json` 中的初始版本
291
- - **后续发布**: 如果本地版本与 NPM 版本相同,自动增加 patch 版本
292
- - **版本格式**: 遵循语义化版本 (SemVer) 规范
568
+ The repository includes a Vue example project:
293
569
 
294
- ## 🚨 注意事项
570
+ ```bash
571
+ pnpm example:dev
572
+ pnpm example:build
573
+ pnpm example:preview
574
+ ```
295
575
 
296
- 1. **权限检查**: 确保 GitHub Actions 有足够的权限访问仓库
297
- 2. **NPM 权限**: 确保 NPM_TOKEN 有发布 `@sycsq/common` 包的权限
298
- 3. **版本冲突**: 避免手动修改版本号,让工作流自动管理
299
- 4. **构建失败**: 如果构建失败,检查依赖和构建配置
576
+ ## Automation
300
577
 
301
- ## 🔍 故障排除
578
+ This project includes two GitHub Actions workflows:
302
579
 
303
- ### 常见问题
580
+ - `CI`: runs `pnpm install --frozen-lockfile`, `pnpm test`, and `pnpm build` on pull requests and pushes to `main`
581
+ - `Publish Package`: runs tests, builds the package, publishes to npm, and creates a GitHub Release on relevant `main` branch changes or manual dispatch
304
582
 
305
- 1. **构建失败**
306
- - 检查 `pnpm install` 是否成功
307
- - 验证 TypeScript 配置
308
- - 检查 Vite 构建配置
583
+ Publishing to npm requires this repository secret under `Settings -> Secrets and variables -> Actions`:
309
584
 
310
- 2. **发布失败**
311
- - 验证 NPM_TOKEN 是否正确
312
- - 检查包名是否可用
313
- - 确认版本号是否冲突
585
+ - `NPM_TOKEN`: an npm automation token with permission to publish `@sycsq/common`
314
586
 
315
- 3. **权限问题**
316
- - 检查 GitHub Actions 权限设置
317
- - 验证 NPM 账户权限
587
+ ## Bundle Size Strategy
318
588
 
319
- ### 查看日志
589
+ - Multi-entry build: `index`, `http`, `utils`, and fine-grained HTTP submodules are emitted separately
590
+ - Externalized dependency: `axios` is not bundled into the package output, preventing duplicate vendor code in host projects
591
+ - Removed extra runtime dependency: form-urlencoded serialization uses a lightweight internal implementation
592
+ - Public asset copying is disabled, so the npm package only includes runtime files
593
+ - ESM and CJS outputs are both exposed through package `exports`
320
594
 
321
- GitHub 仓库的 Actions 标签页中查看工作流执行日志,定位具体问题。
595
+ ## Project Structure
596
+
597
+ ```text
598
+ .
599
+ ├── .github/workflows/ # GitHub Actions workflows
600
+ ├── example/ # Vue example
601
+ ├── packages/ # Source code
602
+ │ ├── http/ # HTTP wrapper and helpers
603
+ │ ├── utils/ # Utility functions
604
+ │ └── index.ts # Package entry
605
+ ├── tests/ # Unit tests
606
+ ├── types/ # Generated declaration files
607
+ ├── package.json
608
+ ├── pnpm-lock.yaml
609
+ ├── tsconfig.json
610
+ └── vite.config.ts
611
+ ```
322
612
 
323
- ## 📚 相关链接
613
+ ## License
324
614
 
325
- - [GitHub Actions 文档](https://docs.github.com/en/actions)
326
- - [NPM 发布指南](https://docs.npmjs.com/cli/v8/commands/npm-publish)
327
- - [语义化版本](https://semver.org/)
615
+ MIT