@ccw-api/api 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (114) hide show
  1. package/AGENT.md +271 -0
  2. package/coverage/clover.xml +605 -0
  3. package/coverage/coverage-final.json +49 -0
  4. package/coverage/lcov-report/base.css +224 -0
  5. package/coverage/lcov-report/block-navigation.js +87 -0
  6. package/coverage/lcov-report/favicon.png +0 -0
  7. package/coverage/lcov-report/index.html +671 -0
  8. package/coverage/lcov-report/prettify.css +1 -0
  9. package/coverage/lcov-report/prettify.js +2 -0
  10. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  11. package/coverage/lcov-report/sorter.js +210 -0
  12. package/coverage/lcov.info +977 -0
  13. package/dist/esm/community-web/api/v1/short_code/encode.js +25 -0
  14. package/dist/esm/community-web/api/v1/short_code/shortcode.test.js +5 -0
  15. package/dist/esm/community-web/approval/approval.test.js +5 -0
  16. package/dist/esm/community-web/approval/list.js +16 -0
  17. package/dist/esm/community-web/base/dateTime.js +10 -0
  18. package/dist/esm/community-web/base/dateTime.test.js +6 -0
  19. package/dist/esm/community-web/campaign_resource/detail.js +12 -0
  20. package/dist/esm/community-web/campaign_resource/detail.test.js +10 -0
  21. package/dist/esm/community-web/check_in_record/check_in_record.test.js +8 -0
  22. package/dist/esm/community-web/check_in_record/detail.js +8 -0
  23. package/dist/esm/community-web/check_in_record/insert.js +12 -0
  24. package/dist/esm/community-web/cloud_asset/search.js +25 -0
  25. package/dist/esm/community-web/cloud_asset/search.test.js +6 -0
  26. package/dist/esm/community-web/cloud_asset/user/privacy.js +11 -0
  27. package/dist/esm/community-web/cloud_asset/user/privacy.test.js +4 -0
  28. package/dist/esm/community-web/comment/page.js +26 -0
  29. package/dist/esm/community-web/comment/page.test.js +15 -0
  30. package/dist/esm/community-web/comment/page_by_topic.js +26 -0
  31. package/dist/esm/community-web/comment/page_by_topic.test.js +13 -0
  32. package/dist/esm/community-web/config/detail.js +13 -0
  33. package/dist/esm/community-web/creation/creation.test.js +118 -0
  34. package/dist/esm/community-web/creation/detail.js +14 -0
  35. package/dist/esm/community-web/creation/excellent/list.js +13 -0
  36. package/dist/esm/community-web/creation/introduction/detail.js +13 -0
  37. package/dist/esm/community-web/creation/like/detail.js +13 -0
  38. package/dist/esm/community-web/creation/loading/tips.js +11 -0
  39. package/dist/esm/community-web/creation/page.js +24 -0
  40. package/dist/esm/community-web/creation/page_by_student.js +24 -0
  41. package/dist/esm/community-web/creation/potential/list.js +13 -0
  42. package/dist/esm/community-web/creation/recommend.js +23 -0
  43. package/dist/esm/community-web/creation/search/page.js +24 -0
  44. package/dist/esm/community-web/creation/student/detail.js +13 -0
  45. package/dist/esm/community-web/creation/tag/list.js +12 -0
  46. package/dist/esm/community-web/index.js +50 -0
  47. package/dist/esm/community-web/short_url/create.js +15 -0
  48. package/dist/esm/community-web/short_url/shortUrl.test.js +4 -0
  49. package/dist/esm/index.js +5 -2
  50. package/dist/esm/queryPages.js +22 -0
  51. package/dist/esm/sso/index.js +5 -3
  52. package/dist/esm/sso/web/auth/auth.test.js +13 -61
  53. package/dist/esm/sso/web/auth/login-by-password.js +25 -82
  54. package/dist/esm/sso/web/auth/logout.js +9 -48
  55. package/dist/esm/sso/web/auth/logout_by_session.js +12 -0
  56. package/dist/node/community-web/api/v1/short_code/encode.js +29 -0
  57. package/dist/node/community-web/api/v1/short_code/shortcode.test.js +7 -0
  58. package/dist/node/community-web/approval/approval.test.js +7 -0
  59. package/dist/node/community-web/approval/list.js +23 -0
  60. package/dist/node/community-web/base/dateTime.js +17 -0
  61. package/dist/node/community-web/base/dateTime.test.js +8 -0
  62. package/dist/node/community-web/campaign_resource/detail.js +16 -0
  63. package/dist/node/community-web/campaign_resource/detail.test.js +12 -0
  64. package/dist/node/community-web/check_in_record/check_in_record.test.js +10 -0
  65. package/dist/node/community-web/check_in_record/detail.js +12 -0
  66. package/dist/node/community-web/check_in_record/insert.js +16 -0
  67. package/dist/node/community-web/cloud_asset/search.js +29 -0
  68. package/dist/node/community-web/cloud_asset/search.test.js +8 -0
  69. package/dist/node/community-web/cloud_asset/user/privacy.js +15 -0
  70. package/dist/node/community-web/cloud_asset/user/privacy.test.js +6 -0
  71. package/dist/node/community-web/comment/page.js +30 -0
  72. package/dist/node/community-web/comment/page.test.js +17 -0
  73. package/dist/node/community-web/comment/page_by_topic.js +30 -0
  74. package/dist/node/community-web/comment/page_by_topic.test.js +15 -0
  75. package/dist/node/community-web/config/detail.js +17 -0
  76. package/dist/node/community-web/creation/creation.test.js +120 -0
  77. package/dist/node/community-web/creation/detail.js +18 -0
  78. package/dist/node/community-web/creation/excellent/list.js +17 -0
  79. package/dist/node/community-web/creation/introduction/detail.js +17 -0
  80. package/dist/node/community-web/creation/like/detail.js +17 -0
  81. package/dist/node/community-web/creation/loading/tips.js +15 -0
  82. package/dist/node/community-web/creation/page.js +28 -0
  83. package/dist/node/community-web/creation/page_by_student.js +28 -0
  84. package/dist/node/community-web/creation/potential/list.js +17 -0
  85. package/dist/node/community-web/creation/recommend.js +27 -0
  86. package/dist/node/community-web/creation/search/page.js +28 -0
  87. package/dist/node/community-web/creation/student/detail.js +17 -0
  88. package/dist/node/community-web/creation/tag/list.js +16 -0
  89. package/dist/node/community-web/index.js +53 -0
  90. package/dist/node/community-web/short_url/create.js +19 -0
  91. package/dist/node/community-web/short_url/shortUrl.test.js +6 -0
  92. package/dist/node/index.js +6 -2
  93. package/dist/node/queryPages.js +26 -0
  94. package/dist/node/sso/index.js +4 -2
  95. package/dist/node/sso/web/auth/auth.test.js +15 -63
  96. package/dist/node/sso/web/auth/login-by-password.js +25 -82
  97. package/dist/node/sso/web/auth/logout.js +9 -48
  98. package/dist/node/sso/web/auth/logout_by_session.js +16 -0
  99. package/package.json +7 -2
  100. package/tsconfig.json +5 -3
  101. package/dist/esm/types.js +0 -1
  102. package/dist/node/types.js +0 -2
  103. package/dist/types/index.d.ts +0 -10
  104. package/dist/types/sso/index.d.ts +0 -6
  105. package/dist/types/sso/web/auth/login-by-password.d.ts +0 -38
  106. package/dist/types/sso/web/auth/logout.d.ts +0 -3
  107. package/dist/types/types.d.ts +0 -17
  108. package/jest.config.ts +0 -13
  109. package/src/index.ts +0 -8
  110. package/src/sso/index.ts +0 -7
  111. package/src/sso/web/auth/auth.test.ts +0 -16
  112. package/src/sso/web/auth/login-by-password.ts +0 -58
  113. package/src/sso/web/auth/logout.ts +0 -9
  114. package/src/types.ts +0 -18
package/AGENT.md ADDED
@@ -0,0 +1,271 @@
1
+ # API 编写规范
2
+
3
+ ## 目录结构
4
+
5
+ API 文件应按照后端服务域名进行分组,文件路径与 API URL 路径保持一致。
6
+
7
+ ```
8
+ src/
9
+ ├── sso/ # sso.ccw.site 服务
10
+ │ └── index.ts # 导出该服务的所有 API
11
+ ├── community-web/ # community-web.ccw.site 服务
12
+ │ └── index.ts
13
+ ├── index.ts # 根导出
14
+ └── types/ # 公共类型定义
15
+ ```
16
+
17
+ ## 文件命名规范
18
+
19
+ - 使用 `kebab-case`(短横线分隔)命名文件
20
+ - 文件名应为 API endpoint名称,如 `login-by-password.ts`、`create-short-url.ts`
21
+ - 测试文件命名为 `${功能}.test.ts`,放置在同一目录下
22
+
23
+ ## 代码结构规范
24
+
25
+ 每个 API 文件应遵循以下顺序:
26
+
27
+ ```typescript
28
+ // 1. 导入依赖
29
+ import { ccwAxios } from "@ccw-api/axios";
30
+ import { ApiResponse, MongoDBId } from "types/api";
31
+
32
+ // 2. 导出 URL(用于调试和测试)
33
+ export const url = "https://domain.ccw.site/path/to/api";
34
+
35
+ // 3. 请求类型定义 优先寻找已在types中定义的类型,oid studentId等key的类型固定为MongoDBId
36
+ export type Req = {
37
+ field1: string;
38
+ field2: number;
39
+ };
40
+
41
+ // 4. 响应类型定义
42
+ export type Res<T = any> = {
43
+ data: T;
44
+ };
45
+
46
+ // 5. 辅助类型或接口(如需要)
47
+ export type ExtraInfo = {
48
+ detail: string;
49
+ };
50
+
51
+ // 6. JSDoc 注释
52
+ /**
53
+ * API 功能描述
54
+ * @param {string} param1 参数1说明
55
+ * @param {number} param2 参数2说明
56
+ * @returns {Promise<Res>} 返回值说明
57
+ */
58
+
59
+ // 7. 导出函数
60
+ export async function apiFunctionName(
61
+ param1: string,
62
+ param2: number,
63
+ ): Promise<Res> {
64
+ const req: Req = { field1: param1, field2: param2 };
65
+ return await ccwAxios
66
+ .post<ApiResponse<Res>>(url, req)
67
+ .then((res) => res.data.body);
68
+ }
69
+ ```
70
+
71
+ ## 类型定义规范
72
+
73
+ ### 通用类型
74
+
75
+ 项目提供以下公共类型,应优先使用:
76
+
77
+ - `ApiResponse<T>` - 统一响应格式
78
+ - `MongoDBId` - MongoDB ObjectID 类型
79
+ - `CachedOssUrl` - OSS 缓存 URL 类型
80
+ - `HexSecTimeStamp` - 十六进制秒级时间戳
81
+
82
+ ### 请求类型
83
+
84
+ - 使用 `Req` 命名请求参数类型
85
+ - 定义所有必填字段和可选字段
86
+ - 使用字面量类型限制枚举值,如 `clientCode: "STUDY_COMMUNITY"`
87
+
88
+ ### 响应类型
89
+
90
+ - 使用 `Res` 命名响应类型
91
+ - 支持泛型参数以适应不同响应结构,如 `Res<Extra = string>`
92
+ - 直接定义响应体结构,无需嵌套 `body`(由 `ApiResponse` 包装)
93
+
94
+ ## 函数编写规范
95
+
96
+ ### 参数处理
97
+
98
+ - 函数参数应清晰命名,避免使用缩写
99
+ - 将复杂对象参数拆分为多个简单参数,提高可读性
100
+ - 提供合理的默认值,如 `reqExtra: ReqExtra = { device: "Node", browser: "Node.js" }`
101
+
102
+ ### 请求封装
103
+
104
+ - 使用 `ccwAxios` 发送请求,不要直接使用 `axios`
105
+ - 将请求体封装为 `Req` 类型变量后再发送
106
+ - 使用 `satisfies Req` 确保请求体类型正确
107
+
108
+ ### 响应处理
109
+
110
+ - 使用 `ApiResponse<T>` 包装响应类型
111
+ - 通过 `.then((res) => res.data.body)` 直接返回响应体
112
+ - 对于需要特殊处理的响应数据(如 JSON 解析),在函数内部完成
113
+
114
+ ## 导入规范
115
+
116
+ ### 统一导入方式
117
+
118
+ ```typescript
119
+ // 正确 - 使用命名导入
120
+ import { ccwAxios } from "@ccw-api/axios";
121
+
122
+ // 错误 - 默认导入方式不一致
123
+ import ccwAxios from "@ccw-api/axios";
124
+ ```
125
+
126
+ ### 类型导入
127
+
128
+ ```typescript
129
+ // 正确 - 使用项目路径别名
130
+ import { ApiResponse, MongoDBId } from "types/api";
131
+ import { queryPage } from "src/queryPages";
132
+
133
+ // 错误 - 相对路径不一致或太长
134
+ import { ApiResponse } from "../../../types";
135
+ ```
136
+
137
+ ## 注释规范
138
+
139
+ ### JSDoc 注释
140
+
141
+ 所有导出函数必须添加 JSDoc 注释:
142
+
143
+ ```typescript
144
+ /**
145
+ * 通过密码登录
146
+ * @param {string} loginKey 用户名
147
+ * @param {string} password 密码
148
+ * @param {ReqExtra} reqExtra 设备和浏览器信息(可选)
149
+ * @returns {Promise<Res<Extra>>} 登录结果
150
+ */
151
+ export async function loginByPassword(
152
+ loginKey: string,
153
+ password: string,
154
+ reqExtra?: ReqExtra,
155
+ ): Promise<Res<Extra>> {
156
+ // ...
157
+ }
158
+ ```
159
+
160
+ ### 类型注释
161
+
162
+ 对于复杂类型,添加适当的注释说明:
163
+ 如果该属性可能为url,请立即询问开发者
164
+
165
+ ```typescript
166
+ export type ApprovalStatus<Tid extends number, Tn extends string> = {
167
+ /**
168
+ * 浮于iconLink之上的icon
169
+ */
170
+ mediumImage: CachedOssUrl;
171
+ /**
172
+ * 有时会包含tag的名称,如"Gandi开发者"
173
+ */
174
+ iconLink: CachedOssUrl;
175
+ };
176
+ ```
177
+
178
+ ## 测试规范
179
+
180
+ ### 测试文件位置
181
+
182
+ 测试文件与 API 文件放在同一目录下,命名为 `${功能}.test.ts`。
183
+
184
+ ### 测试内容
185
+
186
+ 测试应覆盖:
187
+
188
+ - 正常流程返回值验证
189
+ - 异常情况错误信息验证
190
+ - 参数边界情况
191
+
192
+ ```typescript
193
+ import { getApprovalTags } from "./list";
194
+
195
+ test("test approval list", async () => {
196
+ const tags = await getApprovalTags("63c2807d669fa967f17f5559");
197
+ expect(tags.find((v) => v.approvalTagId == 235).approvalTagName).toEqual(
198
+ "Gandi 开发者",
199
+ );
200
+ });
201
+ ```
202
+
203
+ ## 导出规范
204
+
205
+ ### 服务入口导出
206
+
207
+ 每个服务目录(如 `sso/`、`community-web/`)应有 `index.ts`,统一导出该服务的所有 API:
208
+
209
+ ```typescript
210
+ import { loginByPassword } from "./web/auth/login-by-password";
211
+ import { logout } from "./web/auth/logout";
212
+
213
+ export const sso = {
214
+ loginByPassword,
215
+ logout,
216
+ };
217
+ ```
218
+
219
+ ### 根导出
220
+
221
+ `src/index.ts` 导出所有服务:
222
+
223
+ ```typescript
224
+ import { sso } from "./sso";
225
+ import { communityWeb } from "./community-web";
226
+ export type * from "./types";
227
+
228
+ export { sso, communityWeb };
229
+
230
+ export default {
231
+ sso,
232
+ communityWeb,
233
+ };
234
+ ```
235
+
236
+ ## 错误处理
237
+
238
+ - 使用 `@ccw-api/axios` 的拦截器自动处理错误
239
+ - 测试时验证错误信息是否符合预期
240
+ - 不要在 API 函数中捕获错误,让调用方处理
241
+
242
+ ## 最佳实践
243
+
244
+ 1. **URL 一致性**:`url` 常量应与实际 API 地址完全一致
245
+ 2. **类型安全**:使用 TypeScript 泛型提供灵活的类型支持
246
+ 3. **函数命名**:使用 `camelCase`,前缀描述操作(如 `get`, `create`, `login`)
247
+ 4. **单一职责**:每个文件只包含一个 API 函数
248
+ 5. **可测试性**:导出 `url` 常量便于测试和调试
249
+
250
+ ### 分页请求
251
+
252
+ ```typescript
253
+ import { DEFAULT_PAGE_ARGS, queryPage } from "src/queryPages";
254
+
255
+ // 其他一般请求配置
256
+
257
+ export async function getDonatedRecordRanking(
258
+ args: any, // 其他参数
259
+ pageArgs_: Partial<PageArgs> = {},
260
+ ): Promise<Res> {
261
+ const pageArgs = {
262
+ ...DEFAULT_PAGE_ARGS,
263
+ ...pageArgs_,
264
+ };
265
+ const queryUrl = queryPage(url, pageArgs);
266
+ const req: Req = { ... }; // 构造请求
267
+ return await ccwAxios
268
+ .post<ApiResponse<Res>>(queryUrl, req)
269
+ .then((res) => res.data.body);
270
+ }
271
+ ```