meeglesdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (190) hide show
  1. package/README.md +191 -0
  2. package/dist/client.d.ts +186 -0
  3. package/dist/client.d.ts.map +1 -0
  4. package/dist/client.js +197 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/core/base-service.d.ts +156 -0
  7. package/dist/core/base-service.d.ts.map +1 -0
  8. package/dist/core/base-service.js +240 -0
  9. package/dist/core/base-service.js.map +1 -0
  10. package/dist/core/errors.d.ts +181 -0
  11. package/dist/core/errors.d.ts.map +1 -0
  12. package/dist/core/errors.js +250 -0
  13. package/dist/core/errors.js.map +1 -0
  14. package/dist/core/rate-limiter.d.ts +72 -0
  15. package/dist/core/rate-limiter.d.ts.map +1 -0
  16. package/dist/core/rate-limiter.js +269 -0
  17. package/dist/core/rate-limiter.js.map +1 -0
  18. package/dist/core/request.d.ts +270 -0
  19. package/dist/core/request.d.ts.map +1 -0
  20. package/dist/core/request.js +842 -0
  21. package/dist/core/request.js.map +1 -0
  22. package/dist/core/token-manager.d.ts +134 -0
  23. package/dist/core/token-manager.d.ts.map +1 -0
  24. package/dist/core/token-manager.js +412 -0
  25. package/dist/core/token-manager.js.map +1 -0
  26. package/dist/helpers/auth.d.ts +7 -0
  27. package/dist/helpers/auth.d.ts.map +1 -0
  28. package/dist/helpers/auth.js +19 -0
  29. package/dist/helpers/auth.js.map +1 -0
  30. package/dist/index.d.ts +72 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +61 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/service/auth/index.d.ts +96 -0
  35. package/dist/service/auth/index.d.ts.map +1 -0
  36. package/dist/service/auth/index.js +163 -0
  37. package/dist/service/auth/index.js.map +1 -0
  38. package/dist/service/config/basic.d.ts +37 -0
  39. package/dist/service/config/basic.d.ts.map +1 -0
  40. package/dist/service/config/basic.js +54 -0
  41. package/dist/service/config/basic.js.map +1 -0
  42. package/dist/service/config/config.d.ts +27 -0
  43. package/dist/service/config/config.d.ts.map +1 -0
  44. package/dist/service/config/config.js +34 -0
  45. package/dist/service/config/config.js.map +1 -0
  46. package/dist/service/config/field.d.ts +50 -0
  47. package/dist/service/config/field.d.ts.map +1 -0
  48. package/dist/service/config/field.js +74 -0
  49. package/dist/service/config/field.js.map +1 -0
  50. package/dist/service/config/relation.d.ts +53 -0
  51. package/dist/service/config/relation.d.ts.map +1 -0
  52. package/dist/service/config/relation.js +66 -0
  53. package/dist/service/config/relation.js.map +1 -0
  54. package/dist/service/config/resource.d.ts +59 -0
  55. package/dist/service/config/resource.d.ts.map +1 -0
  56. package/dist/service/config/resource.js +75 -0
  57. package/dist/service/config/resource.js.map +1 -0
  58. package/dist/service/config/role.d.ts +55 -0
  59. package/dist/service/config/role.d.ts.map +1 -0
  60. package/dist/service/config/role.js +90 -0
  61. package/dist/service/config/role.js.map +1 -0
  62. package/dist/service/config/template.d.ts +65 -0
  63. package/dist/service/config/template.d.ts.map +1 -0
  64. package/dist/service/config/template.js +95 -0
  65. package/dist/service/config/template.js.map +1 -0
  66. package/dist/service/measure/index.d.ts +26 -0
  67. package/dist/service/measure/index.d.ts.map +1 -0
  68. package/dist/service/measure/index.js +36 -0
  69. package/dist/service/measure/index.js.map +1 -0
  70. package/dist/service/measure/query.d.ts +56 -0
  71. package/dist/service/measure/query.d.ts.map +1 -0
  72. package/dist/service/measure/query.js +86 -0
  73. package/dist/service/measure/query.js.map +1 -0
  74. package/dist/service/space/relation.d.ts +63 -0
  75. package/dist/service/space/relation.d.ts.map +1 -0
  76. package/dist/service/space/relation.js +102 -0
  77. package/dist/service/space/relation.js.map +1 -0
  78. package/dist/service/space/space.d.ts +81 -0
  79. package/dist/service/space/space.d.ts.map +1 -0
  80. package/dist/service/space/space.js +110 -0
  81. package/dist/service/space/space.js.map +1 -0
  82. package/dist/service/tenant/tenant.d.ts +52 -0
  83. package/dist/service/tenant/tenant.d.ts.map +1 -0
  84. package/dist/service/tenant/tenant.js +75 -0
  85. package/dist/service/tenant/tenant.js.map +1 -0
  86. package/dist/service/user/group.d.ts +47 -0
  87. package/dist/service/user/group.d.ts.map +1 -0
  88. package/dist/service/user/group.js +70 -0
  89. package/dist/service/user/group.js.map +1 -0
  90. package/dist/service/user/query.d.ts +25 -0
  91. package/dist/service/user/query.d.ts.map +1 -0
  92. package/dist/service/user/query.js +26 -0
  93. package/dist/service/user/query.js.map +1 -0
  94. package/dist/service/user/search.d.ts +25 -0
  95. package/dist/service/user/search.d.ts.map +1 -0
  96. package/dist/service/user/search.js +26 -0
  97. package/dist/service/user/search.js.map +1 -0
  98. package/dist/service/user/user.d.ts +37 -0
  99. package/dist/service/user/user.d.ts.map +1 -0
  100. package/dist/service/user/user.js +46 -0
  101. package/dist/service/user/user.js.map +1 -0
  102. package/dist/service/view/query.d.ts +52 -0
  103. package/dist/service/view/query.d.ts.map +1 -0
  104. package/dist/service/view/query.js +76 -0
  105. package/dist/service/view/query.js.map +1 -0
  106. package/dist/service/view/view.d.ts +76 -0
  107. package/dist/service/view/view.d.ts.map +1 -0
  108. package/dist/service/view/view.js +108 -0
  109. package/dist/service/view/view.js.map +1 -0
  110. package/dist/service/workitem/attachment.d.ts +143 -0
  111. package/dist/service/workitem/attachment.d.ts.map +1 -0
  112. package/dist/service/workitem/attachment.js +231 -0
  113. package/dist/service/workitem/attachment.js.map +1 -0
  114. package/dist/service/workitem/batch.d.ts +135 -0
  115. package/dist/service/workitem/batch.d.ts.map +1 -0
  116. package/dist/service/workitem/batch.js +146 -0
  117. package/dist/service/workitem/batch.js.map +1 -0
  118. package/dist/service/workitem/chat.d.ts +42 -0
  119. package/dist/service/workitem/chat.d.ts.map +1 -0
  120. package/dist/service/workitem/chat.js +50 -0
  121. package/dist/service/workitem/chat.js.map +1 -0
  122. package/dist/service/workitem/comment.d.ts +139 -0
  123. package/dist/service/workitem/comment.d.ts.map +1 -0
  124. package/dist/service/workitem/comment.js +180 -0
  125. package/dist/service/workitem/comment.js.map +1 -0
  126. package/dist/service/workitem/review.d.ts +44 -0
  127. package/dist/service/workitem/review.d.ts.map +1 -0
  128. package/dist/service/workitem/review.js +49 -0
  129. package/dist/service/workitem/review.js.map +1 -0
  130. package/dist/service/workitem/search.d.ts +213 -0
  131. package/dist/service/workitem/search.d.ts.map +1 -0
  132. package/dist/service/workitem/search.js +242 -0
  133. package/dist/service/workitem/search.js.map +1 -0
  134. package/dist/service/workitem/subtask.d.ts +193 -0
  135. package/dist/service/workitem/subtask.d.ts.map +1 -0
  136. package/dist/service/workitem/subtask.js +247 -0
  137. package/dist/service/workitem/subtask.js.map +1 -0
  138. package/dist/service/workitem/workItem.d.ts +225 -0
  139. package/dist/service/workitem/workItem.d.ts.map +1 -0
  140. package/dist/service/workitem/workItem.js +310 -0
  141. package/dist/service/workitem/workItem.js.map +1 -0
  142. package/dist/service/workitem/workflow.d.ts +214 -0
  143. package/dist/service/workitem/workflow.d.ts.map +1 -0
  144. package/dist/service/workitem/workflow.js +281 -0
  145. package/dist/service/workitem/workflow.js.map +1 -0
  146. package/dist/service/workitem/workhour.d.ts +63 -0
  147. package/dist/service/workitem/workhour.d.ts.map +1 -0
  148. package/dist/service/workitem/workhour.js +93 -0
  149. package/dist/service/workitem/workhour.js.map +1 -0
  150. package/dist/types/auth.d.ts +115 -0
  151. package/dist/types/auth.d.ts.map +1 -0
  152. package/dist/types/auth.js +6 -0
  153. package/dist/types/auth.js.map +1 -0
  154. package/dist/types/common.d.ts +354 -0
  155. package/dist/types/common.d.ts.map +1 -0
  156. package/dist/types/common.js +14 -0
  157. package/dist/types/common.js.map +1 -0
  158. package/dist/types/config.d.ts +305 -0
  159. package/dist/types/config.d.ts.map +1 -0
  160. package/dist/types/config.js +6 -0
  161. package/dist/types/config.js.map +1 -0
  162. package/dist/types/index.d.ts +13 -0
  163. package/dist/types/index.d.ts.map +1 -0
  164. package/dist/types/index.js +13 -0
  165. package/dist/types/index.js.map +1 -0
  166. package/dist/types/measure.d.ts +55 -0
  167. package/dist/types/measure.d.ts.map +1 -0
  168. package/dist/types/measure.js +6 -0
  169. package/dist/types/measure.js.map +1 -0
  170. package/dist/types/space.d.ts +164 -0
  171. package/dist/types/space.d.ts.map +1 -0
  172. package/dist/types/space.js +6 -0
  173. package/dist/types/space.js.map +1 -0
  174. package/dist/types/tenant.d.ts +106 -0
  175. package/dist/types/tenant.d.ts.map +1 -0
  176. package/dist/types/tenant.js +6 -0
  177. package/dist/types/tenant.js.map +1 -0
  178. package/dist/types/user.d.ts +110 -0
  179. package/dist/types/user.d.ts.map +1 -0
  180. package/dist/types/user.js +6 -0
  181. package/dist/types/user.js.map +1 -0
  182. package/dist/types/view.d.ts +162 -0
  183. package/dist/types/view.d.ts.map +1 -0
  184. package/dist/types/view.js +6 -0
  185. package/dist/types/view.js.map +1 -0
  186. package/dist/types/workitem.d.ts +1523 -0
  187. package/dist/types/workitem.d.ts.map +1 -0
  188. package/dist/types/workitem.js +6 -0
  189. package/dist/types/workitem.js.map +1 -0
  190. package/package.json +43 -0
@@ -0,0 +1,250 @@
1
+ /**
2
+ * 错误处理
3
+ * 100% 参考 Meego API 文档: Meego-API-docs/common/Open API 错误码.md
4
+ */
5
+ /**
6
+ * 错误码常量
7
+ * 参考: Meego-API-docs/common/Open API 错误码.md
8
+ */
9
+ export const ErrorCodes = {
10
+ // 权限相关 (403)
11
+ NO_PERMISSION: 10001,
12
+ ILLEGAL_OPERATION: 10002,
13
+ OPERATION_FAILED: 10004,
14
+ // Token 相关 (401)
15
+ TOKEN_NOT_EXIST: 10021,
16
+ CHECK_TOKEN_FAILED: 10022,
17
+ CHECK_TOKEN_PERM_FAILED: 10301,
18
+ USER_RESIGNED: 10302,
19
+ // 授权相关 (403)
20
+ CODE_INVALID: 10210,
21
+ TOKEN_INFO_INVALID: 10211,
22
+ NO_PROJECT_PERMISSION: 10404,
23
+ // 频率限制 (429)
24
+ API_REQUEST_FREQUENCY_LIMIT: 10429,
25
+ API_REQUEST_IDEMPOTENT_LIMIT: 10430,
26
+ // 参数相关 (400)
27
+ PARAM_REQUEST_LIMIT: 20001,
28
+ PAGE_SIZE_LIMIT: 20002,
29
+ WRONG_WORKITEM_TYPE_PARAM: 20003,
30
+ SEARCH_USER_LIMIT: 20004,
31
+ MISSING_PARAM: 20005,
32
+ INVALID_PARAM: 20006,
33
+ WORKITEM_ALREADY_ABORTED: 20007,
34
+ WORKITEM_ALREADY_RESTORED: 20008,
35
+ ABORT_OR_RESTORE_NO_REASON: 20009,
36
+ WORKITEM_TYPE_NOT_SAME: 20010,
37
+ INPUT_VIEW_NOT_FIX_VIEW: 20011,
38
+ VIEW_NOT_IN_PROJECT: 20012,
39
+ INVALID_TIME_INTERVAL: 20013,
40
+ PROJECT_WORKITEM_NOT_MATCH: 20014,
41
+ FIELD_MIX_ERROR: 20015,
42
+ NODE_NOT_ARRIVED: 20016,
43
+ NODE_ALREADY_COMPLETED: 20017,
44
+ NODE_ID_NOT_EXIST: 20018,
45
+ UPLOADED_FILE_SIZE_LIMIT: 20024,
46
+ FIELD_KEY_ALIAS_MISSING: 20025,
47
+ FLOWTYPE_ERROR_STATUS: 20026,
48
+ FLOWTYPE_ERROR_NODE: 20027,
49
+ WORKITEM_IDS_LIMIT: 20028,
50
+ UNSUPPORTED_FIELD_TYPE: 20029,
51
+ DIFFERENT_SCHEDULE_SET_OWNER_INVALID: 20032,
52
+ UPDATE_FIELD_INVALID: 20033,
53
+ NODE_NOT_COMPLETED_ROLLBACK: 20037,
54
+ REQUIRED_FIELD_NOT_SET: 20038,
55
+ PLUGIN_TOKEN_MUST_HAVE_USER_KEY: 20039,
56
+ REQUEST_FORM_NULL: 20040,
57
+ ROLE_OWNER_MUST_SET: 20041,
58
+ X_USER_KEY_WRONG: 20042,
59
+ VIEW_IDS_LIMIT: 20043,
60
+ WORKITEM_DISABLED: 20044,
61
+ COMMENT_WORKITEM_NOT_MATCH: 20045,
62
+ TASK_ID_NOT_EXIST: 20046,
63
+ ROLE_ASSIGNEE_ASSIGNEE_CONFLICT: 20047,
64
+ ROLE_ASSIGNEE_ROLE_NOT_MATCH: 20048,
65
+ SEARCH_RESULT_TOO_LARGE: 20055,
66
+ ONLY_WORKFLOW_MODE_ABORT: 20056,
67
+ SEARCH_PROJECT_LIMIT: 20057,
68
+ SEARCH_USER_ROLE_FIELDKEY_ERROR: 20058,
69
+ SEARCH_USER_KEYS_REQUIRED: 20059,
70
+ SEARCH_OPERATOR_ERROR: 20063,
71
+ SEARCH_OPTION_SIZE_LIMIT: 20064,
72
+ SEARCH_PARAM_NOT_SUPPORT_STATEFLOW: 20065,
73
+ SEARCH_SIGNAL_LEN_ERROR: 20066,
74
+ SEARCH_SIGNAL_VALUE_NOT_SUPPORT: 20067,
75
+ SEARCH_PARAM_NOT_SUPPORT: 20068,
76
+ SEARCH_PARAM_VALUE_ERROR: 20069,
77
+ FIELD_INVALID: 20070,
78
+ SEARCH_PEOPLE_NOT_SUPPORT_ISSUE: 20071,
79
+ CONJUNCTION_VALUE_ERROR: 20072,
80
+ QUERY_LENGTH_ERROR: 20080,
81
+ QUERY_TYPE_NOT_SUPPORTED: 20081,
82
+ ACTION_NOT_SUPPORTED: 20082,
83
+ DUPLICATION_FIELD: 20083,
84
+ REQUEST_INTERCEPTED: 20090,
85
+ INVALID_PARAM_9999: 9999,
86
+ COMMERCIAL_USAGE_EXCEEDED: 1000051942,
87
+ UPLOAD_FILE_SIZE_LIMIT_100M: 1000050174,
88
+ // 资源未找到 (404)
89
+ WORKITEM_NOT_FOUND: 30005,
90
+ USER_NOT_FOUND: 30006,
91
+ WORKFLOW_NOT_FOUND: 30007,
92
+ BUSINESS_NOT_FOUND: 30008,
93
+ FIELD_NOT_FOUND: 30009,
94
+ STATEFLOW_NOT_FOUND: 30010,
95
+ NODE_NOT_FOUND_IN_WORKFLOW: 30011,
96
+ STATE_NOT_FOUND_IN_STATEFLOW: 30012,
97
+ VIEW_NOT_EXIST: 13001,
98
+ RECORD_NOT_FOUND: 30015,
99
+ // 系统错误 (500)
100
+ RPC_CALL_ERROR: 50006,
101
+ };
102
+ /**
103
+ * Meego API 错误
104
+ */
105
+ export class MeegoError extends Error {
106
+ /** 错误码 */
107
+ errCode;
108
+ /** 错误信息 */
109
+ errMsg;
110
+ /** 错误详情 */
111
+ detail;
112
+ /** HTTP 状态码 */
113
+ httpStatus;
114
+ constructor(message, errCode, errMsg, detail, httpStatus) {
115
+ super(message);
116
+ this.name = 'MeegoError';
117
+ this.errCode = errCode;
118
+ this.errMsg = errMsg;
119
+ this.detail = detail;
120
+ this.httpStatus = httpStatus;
121
+ // 保持原型链
122
+ Object.setPrototypeOf(this, MeegoError.prototype);
123
+ }
124
+ /**
125
+ * 是否为认证错误 (Token 相关)
126
+ * 10021: Token Not Exist
127
+ * 10022: Check Token Failed
128
+ * 10301: Check Token Perm Failed
129
+ */
130
+ get isAuthError() {
131
+ return (this.errCode === ErrorCodes.TOKEN_NOT_EXIST ||
132
+ this.errCode === ErrorCodes.CHECK_TOKEN_FAILED ||
133
+ this.errCode === ErrorCodes.CHECK_TOKEN_PERM_FAILED);
134
+ }
135
+ /**
136
+ * 是否为权限错误
137
+ * 10001: No Permission
138
+ * 10002: Illegal Operation
139
+ * 10404: No Project Permission
140
+ */
141
+ get isPermissionError() {
142
+ return (this.errCode === ErrorCodes.NO_PERMISSION ||
143
+ this.errCode === ErrorCodes.ILLEGAL_OPERATION ||
144
+ this.errCode === ErrorCodes.NO_PROJECT_PERMISSION);
145
+ }
146
+ /**
147
+ * 是否为资源未找到错误
148
+ * 30005: WorkItem Not Found
149
+ * 30006: User Not Found
150
+ * 30009: Field Not Found
151
+ * 13001: View Not Exist
152
+ */
153
+ get isNotFoundError() {
154
+ return (this.errCode === ErrorCodes.WORKITEM_NOT_FOUND ||
155
+ this.errCode === ErrorCodes.USER_NOT_FOUND ||
156
+ this.errCode === ErrorCodes.FIELD_NOT_FOUND ||
157
+ this.errCode === ErrorCodes.VIEW_NOT_EXIST ||
158
+ this.errCode === ErrorCodes.WORKFLOW_NOT_FOUND ||
159
+ this.errCode === ErrorCodes.STATEFLOW_NOT_FOUND ||
160
+ this.errCode === ErrorCodes.NODE_NOT_FOUND_IN_WORKFLOW ||
161
+ this.errCode === ErrorCodes.STATE_NOT_FOUND_IN_STATEFLOW ||
162
+ this.errCode === ErrorCodes.RECORD_NOT_FOUND);
163
+ }
164
+ /**
165
+ * 是否为频率限制错误
166
+ * 10429: API Request Frequency Limit (15 QPS)
167
+ * 10430: API Request Idempotent Limit
168
+ */
169
+ get isRateLimitError() {
170
+ return (this.errCode === ErrorCodes.API_REQUEST_FREQUENCY_LIMIT ||
171
+ this.errCode === ErrorCodes.API_REQUEST_IDEMPOTENT_LIMIT);
172
+ }
173
+ /**
174
+ * 是否可重试
175
+ * 10429: 频率限制,可以稍后重试
176
+ * 50006: RPC Call Error / 服务瞬时超载
177
+ */
178
+ get isRetryable() {
179
+ return (this.errCode === ErrorCodes.API_REQUEST_FREQUENCY_LIMIT ||
180
+ this.errCode === ErrorCodes.RPC_CALL_ERROR);
181
+ }
182
+ /**
183
+ * 是否为参数错误
184
+ */
185
+ get isParamError() {
186
+ return this.errCode >= 20001 && this.errCode <= 20099;
187
+ }
188
+ /**
189
+ * 获取 log_id (用于追踪)
190
+ */
191
+ get logId() {
192
+ return this.detail?.log_id;
193
+ }
194
+ /**
195
+ * 转换为 JSON
196
+ */
197
+ toJSON() {
198
+ return {
199
+ name: this.name,
200
+ message: this.message,
201
+ errCode: this.errCode,
202
+ errMsg: this.errMsg,
203
+ detail: this.detail,
204
+ httpStatus: this.httpStatus,
205
+ };
206
+ }
207
+ }
208
+ /**
209
+ * 认证错误(用于认证接口)
210
+ */
211
+ export class MeegoAuthError extends MeegoError {
212
+ constructor(code, msg) {
213
+ super(`[${code}] ${msg}`, code, msg, undefined, 401);
214
+ this.name = 'MeegoAuthError';
215
+ Object.setPrototypeOf(this, MeegoAuthError.prototype);
216
+ }
217
+ }
218
+ /**
219
+ * 网络错误
220
+ */
221
+ export class MeegoNetworkError extends Error {
222
+ cause;
223
+ constructor(message, cause) {
224
+ super(message);
225
+ this.name = 'MeegoNetworkError';
226
+ this.cause = cause;
227
+ Object.setPrototypeOf(this, MeegoNetworkError.prototype);
228
+ }
229
+ }
230
+ /**
231
+ * 超时错误
232
+ */
233
+ export class MeegoTimeoutError extends MeegoNetworkError {
234
+ constructor(timeout) {
235
+ super(`Request timeout after ${timeout}ms`);
236
+ this.name = 'MeegoTimeoutError';
237
+ Object.setPrototypeOf(this, MeegoTimeoutError.prototype);
238
+ }
239
+ }
240
+ /**
241
+ * 主动取消错误
242
+ */
243
+ export class MeegoAbortError extends MeegoNetworkError {
244
+ constructor(message = 'Request aborted') {
245
+ super(message);
246
+ this.name = 'MeegoAbortError';
247
+ Object.setPrototypeOf(this, MeegoAbortError.prototype);
248
+ }
249
+ }
250
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Simple per-key rate limiter (token bucket).
3
+ */
4
+ import type { HttpMethod } from './request.js';
5
+ export type RateLimitScope = 'token' | 'token+path' | 'token+method+path';
6
+ export type RateLimitPreset = 'meego-openapi';
7
+ export type RateLimitConfig = RateLimitOptions | RateLimitPreset;
8
+ export interface RateLimitOptions {
9
+ /** Enable rate limiting (default: true when options provided) */
10
+ enabled?: boolean;
11
+ /** Use a built-in preset */
12
+ preset?: RateLimitPreset;
13
+ /** Requests per second */
14
+ qps?: number;
15
+ /** Requests per minute */
16
+ qpm?: number;
17
+ /** Max burst size (default: qps) */
18
+ burst?: number;
19
+ /** Key scope */
20
+ scope?: RateLimitScope;
21
+ /** Rule overrides for specific endpoints */
22
+ rules?: RateLimitRule[];
23
+ /** Idle bucket TTL in milliseconds (default: 10 minutes, set 0 to disable cleanup) */
24
+ entryTtlMs?: number;
25
+ }
26
+ export interface RateLimitRule {
27
+ /** HTTP method to match */
28
+ method?: HttpMethod;
29
+ /** Path pattern, supports :params */
30
+ path: string;
31
+ /** Requests per second override */
32
+ qps?: number;
33
+ /** Requests per minute override */
34
+ qpm?: number;
35
+ /** Max burst size override (applies to QPS limiter) */
36
+ burst?: number;
37
+ /** Scope override */
38
+ scope?: RateLimitScope;
39
+ }
40
+ export declare class RateLimiter {
41
+ private readonly qps;
42
+ private readonly burst;
43
+ private readonly entryTtlMs?;
44
+ private readonly cleanupIntervalMs?;
45
+ private lastCleanup;
46
+ private readonly buckets;
47
+ private readonly queues;
48
+ constructor(options: RateLimitOptions);
49
+ acquire(key: string): Promise<void>;
50
+ private getBucket;
51
+ private maybeCleanup;
52
+ private refill;
53
+ private consumeToken;
54
+ private sleep;
55
+ }
56
+ export declare const normalizeRateLimitOptions: (config?: RateLimitConfig) => RateLimitOptions | undefined;
57
+ export declare class RateLimitManager {
58
+ private readonly defaultRule;
59
+ private readonly rules;
60
+ private readonly limiters;
61
+ private readonly entryTtlMs?;
62
+ constructor(options: RateLimitOptions);
63
+ acquire(context: {
64
+ token?: string;
65
+ method: HttpMethod;
66
+ path: string;
67
+ }): Promise<void>;
68
+ private resolveRule;
69
+ private buildKey;
70
+ private getLimiter;
71
+ }
72
+ //# sourceMappingURL=rate-limiter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.d.ts","sourceRoot":"","sources":["../../src/core/rate-limiter.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,YAAY,GAAG,mBAAmB,CAAC;AAE1E,MAAM,MAAM,eAAe,GAAG,eAAe,CAAC;AAE9C,MAAM,MAAM,eAAe,GAAG,gBAAgB,GAAG,eAAe,CAAC;AAEjE,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4BAA4B;IAC5B,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,0BAA0B;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oCAAoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gBAAgB;IAChB,KAAK,CAAC,EAAE,cAAc,CAAC;IACvB,4CAA4C;IAC5C,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,sFAAsF;IACtF,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,2BAA2B;IAC3B,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,uDAAuD;IACvD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,KAAK,CAAC,EAAE,cAAc,CAAC;CACxB;AAQD,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAS;IAC7B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAS;IAC5C,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkC;IAC1D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;gBAE/C,OAAO,EAAE,gBAAgB;IAY/B,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA0BzC,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,YAAY;IAgBpB,OAAO,CAAC,MAAM;YAYA,YAAY;IAgB1B,OAAO,CAAC,KAAK;CAGd;AA4DD,eAAO,MAAM,yBAAyB,GAAI,SAAS,eAAe,KAAG,gBAAgB,GAAG,SAQvF,CAAC;AAEF,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAoB;IAChD,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAiB;IACvC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAkC;IAC3D,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAS;gBAEzB,OAAO,EAAE,gBAAgB;IAiD/B,OAAO,CAAC,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3F,OAAO,CAAC,WAAW;IAgCnB,OAAO,CAAC,QAAQ;IAUhB,OAAO,CAAC,UAAU;CAUnB"}
@@ -0,0 +1,269 @@
1
+ /**
2
+ * Simple per-key rate limiter (token bucket).
3
+ */
4
+ export class RateLimiter {
5
+ qps;
6
+ burst;
7
+ entryTtlMs;
8
+ cleanupIntervalMs;
9
+ lastCleanup = 0;
10
+ buckets = new Map();
11
+ queues = new Map();
12
+ constructor(options) {
13
+ const qps = options.qps ?? 15;
14
+ if (!Number.isFinite(qps) || qps <= 0) {
15
+ throw new Error('rateLimit.qps must be a positive number');
16
+ }
17
+ this.qps = qps;
18
+ this.burst = Math.max(1, options.burst ?? qps);
19
+ const entryTtlMs = options.entryTtlMs ?? 10 * 60 * 1000;
20
+ this.entryTtlMs = Number.isFinite(entryTtlMs) && entryTtlMs > 0 ? entryTtlMs : undefined;
21
+ this.cleanupIntervalMs = this.entryTtlMs ? Math.min(this.entryTtlMs, 60 * 1000) : undefined;
22
+ }
23
+ async acquire(key) {
24
+ const previous = this.queues.get(key) ?? Promise.resolve();
25
+ let release;
26
+ const current = new Promise((resolve) => {
27
+ release = resolve;
28
+ });
29
+ this.queues.set(key, previous.then(() => current).catch(() => current));
30
+ await previous;
31
+ this.maybeCleanup();
32
+ try {
33
+ await this.consumeToken(key);
34
+ }
35
+ finally {
36
+ release();
37
+ if (this.queues.get(key) === current) {
38
+ this.queues.delete(key);
39
+ }
40
+ }
41
+ }
42
+ getBucket(key) {
43
+ let state = this.buckets.get(key);
44
+ if (!state) {
45
+ const now = Date.now();
46
+ state = { tokens: this.burst, lastRefill: now, lastSeen: now };
47
+ this.buckets.set(key, state);
48
+ }
49
+ state.lastSeen = Date.now();
50
+ return state;
51
+ }
52
+ maybeCleanup() {
53
+ if (!this.entryTtlMs || !this.cleanupIntervalMs) {
54
+ return;
55
+ }
56
+ const now = Date.now();
57
+ if (now - this.lastCleanup < this.cleanupIntervalMs) {
58
+ return;
59
+ }
60
+ this.lastCleanup = now;
61
+ for (const [key, state] of this.buckets.entries()) {
62
+ if (now - state.lastSeen > this.entryTtlMs) {
63
+ this.buckets.delete(key);
64
+ }
65
+ }
66
+ }
67
+ refill(state) {
68
+ const now = Date.now();
69
+ const elapsedMs = now - state.lastRefill;
70
+ if (elapsedMs <= 0) {
71
+ return;
72
+ }
73
+ const refillTokens = (elapsedMs / 1000) * this.qps;
74
+ state.tokens = Math.min(this.burst, state.tokens + refillTokens);
75
+ state.lastRefill = now;
76
+ }
77
+ async consumeToken(key) {
78
+ const state = this.getBucket(key);
79
+ while (true) {
80
+ this.refill(state);
81
+ if (state.tokens >= 1) {
82
+ state.tokens -= 1;
83
+ return;
84
+ }
85
+ const missing = 1 - state.tokens;
86
+ const waitMs = Math.ceil((missing / this.qps) * 1000);
87
+ await this.sleep(waitMs);
88
+ }
89
+ }
90
+ sleep(ms) {
91
+ return new Promise((resolve) => setTimeout(resolve, ms));
92
+ }
93
+ }
94
+ const PRESET_CONFIGS = {
95
+ 'meego-openapi': {
96
+ default: {
97
+ qps: 15,
98
+ burst: 15,
99
+ scope: 'token+method+path',
100
+ },
101
+ rules: [
102
+ {
103
+ method: 'POST',
104
+ path: '/open_api/view/v1/update_condition_view',
105
+ qpm: 450,
106
+ },
107
+ {
108
+ method: 'POST',
109
+ path: '/open_api/work_items/filter_across_project',
110
+ qpm: 450,
111
+ },
112
+ {
113
+ method: 'POST',
114
+ path: '/open_api/work_item/subtask/search',
115
+ qpm: 450,
116
+ },
117
+ {
118
+ method: 'POST',
119
+ path: '/open_api/:project_key/work_item/:work_item_type_key/search/params',
120
+ qpm: 450,
121
+ },
122
+ {
123
+ method: 'POST',
124
+ path: '/open_api/:project_key/work_item/filter',
125
+ qpm: 450,
126
+ },
127
+ {
128
+ method: 'POST',
129
+ path: '/open_api/:project_key/work_item/:work_item_type_key/:work_item_id/search_by_relation',
130
+ qps: 10,
131
+ },
132
+ {
133
+ method: 'POST',
134
+ path: '/open_api/work_item/actual_time/update',
135
+ qps: 10,
136
+ },
137
+ ],
138
+ },
139
+ };
140
+ export const normalizeRateLimitOptions = (config) => {
141
+ if (!config) {
142
+ return undefined;
143
+ }
144
+ if (typeof config === 'string') {
145
+ return { preset: config };
146
+ }
147
+ return config;
148
+ };
149
+ export class RateLimitManager {
150
+ defaultRule;
151
+ rules;
152
+ limiters = new Map();
153
+ entryTtlMs;
154
+ constructor(options) {
155
+ const preset = options.preset;
156
+ const presetConfig = preset ? PRESET_CONFIGS[preset] : undefined;
157
+ const baseRule = {
158
+ ...presetConfig?.default,
159
+ };
160
+ if (options.qps !== undefined) {
161
+ baseRule.qps = options.qps;
162
+ }
163
+ if (options.qpm !== undefined) {
164
+ baseRule.qpm = options.qpm;
165
+ }
166
+ if (options.burst !== undefined) {
167
+ baseRule.burst = options.burst;
168
+ }
169
+ if (options.scope !== undefined) {
170
+ baseRule.scope = options.scope;
171
+ }
172
+ if (baseRule.qps === undefined && baseRule.qpm === undefined) {
173
+ baseRule.qps = 15;
174
+ if (baseRule.burst === undefined) {
175
+ baseRule.burst = 15;
176
+ }
177
+ }
178
+ if (baseRule.qps !== undefined && baseRule.burst === undefined) {
179
+ baseRule.burst = baseRule.qps;
180
+ }
181
+ this.defaultRule = baseRule;
182
+ const rules = [];
183
+ if (presetConfig?.rules) {
184
+ rules.push(...presetConfig.rules);
185
+ }
186
+ if (options.rules) {
187
+ rules.push(...options.rules);
188
+ }
189
+ this.rules = rules.map((rule) => ({
190
+ ...rule,
191
+ regex: compilePathPattern(rule.path),
192
+ }));
193
+ this.entryTtlMs = options.entryTtlMs;
194
+ }
195
+ async acquire(context) {
196
+ if (!context.token) {
197
+ return;
198
+ }
199
+ const resolved = this.resolveRule(context.method, context.path);
200
+ if (!resolved.qps && !resolved.qpm) {
201
+ return;
202
+ }
203
+ const scope = resolved.scope ?? 'token';
204
+ const key = this.buildKey(context.token, context.method, context.path, scope);
205
+ if (resolved.qps && resolved.qps > 0) {
206
+ const qpsLimiter = this.getLimiter(resolved.qps, resolved.burst ?? resolved.qps);
207
+ await qpsLimiter.acquire(key);
208
+ }
209
+ if (resolved.qpm && resolved.qpm > 0) {
210
+ const qpmRate = resolved.qpm / 60;
211
+ const qpmLimiter = this.getLimiter(qpmRate, resolved.qpm);
212
+ await qpmLimiter.acquire(key);
213
+ }
214
+ }
215
+ resolveRule(method, path) {
216
+ let resolved = { ...this.defaultRule };
217
+ for (const rule of this.rules) {
218
+ if (rule.method && rule.method !== method) {
219
+ continue;
220
+ }
221
+ if (!rule.regex.test(path)) {
222
+ continue;
223
+ }
224
+ const hasQps = rule.qps !== undefined;
225
+ const hasBurst = rule.burst !== undefined;
226
+ if (hasQps) {
227
+ resolved.qps = rule.qps;
228
+ }
229
+ if (rule.qpm !== undefined) {
230
+ resolved.qpm = rule.qpm;
231
+ }
232
+ if (hasBurst) {
233
+ resolved.burst = rule.burst;
234
+ }
235
+ else if (hasQps) {
236
+ resolved.burst = rule.qps;
237
+ }
238
+ if (rule.scope !== undefined) {
239
+ resolved.scope = rule.scope;
240
+ }
241
+ }
242
+ return resolved;
243
+ }
244
+ buildKey(token, method, path, scope) {
245
+ if (scope === 'token') {
246
+ return token;
247
+ }
248
+ if (scope === 'token+path') {
249
+ return `${token}|${path}`;
250
+ }
251
+ return `${token}|${method}|${path}`;
252
+ }
253
+ getLimiter(qps, burst) {
254
+ const key = `${qps}:${burst}`;
255
+ const existing = this.limiters.get(key);
256
+ if (existing) {
257
+ return existing;
258
+ }
259
+ const limiter = new RateLimiter({ qps, burst, entryTtlMs: this.entryTtlMs });
260
+ this.limiters.set(key, limiter);
261
+ return limiter;
262
+ }
263
+ }
264
+ const compilePathPattern = (path) => {
265
+ const escaped = path.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
266
+ const pattern = escaped.replace(/:[^/]+/g, '[^/]+');
267
+ return new RegExp(`^${pattern}$`);
268
+ };
269
+ //# sourceMappingURL=rate-limiter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rate-limiter.js","sourceRoot":"","sources":["../../src/core/rate-limiter.ts"],"names":[],"mappings":"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"}