rspack-plugin-mock 1.1.0 → 1.2.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.
@@ -0,0 +1,572 @@
1
+ import { Readable } from "node:stream";
2
+ import { CorsOptions } from "cors";
3
+ import { Buffer } from "node:buffer";
4
+ import Cookies from "cookies";
5
+ import { Options } from "co-body";
6
+ import formidable from "formidable";
7
+ import { WebSocketServer } from "ws";
8
+ import http from "node:http";
9
+
10
+ //#region src/types.d.ts
11
+
12
+ /**
13
+ * Configure plugin
14
+ *
15
+ * 插件配置项
16
+ */
17
+ interface MockServerPluginOptions {
18
+ /**
19
+ * To configure the path matching rules for http mock services,
20
+ * any request path starting with prefix will be intercepted and proxied.
21
+ * If the prefix starts with `^`, it will be recognized as a `RegExp`.
22
+ *
23
+ * 为 http mock 服务配置 路径匹配规则,任何请求路径以 prefix 开头的都将被拦截代理。
24
+ * 如果 prefix 以 `^` 开头,将被识别为 `RegExp`。
25
+ * @default []
26
+ * @example ['^/api']
27
+ */
28
+ prefix?: string | string[];
29
+ /**
30
+ * Configure path matching rules for WebSocket mock service.
31
+ * Any ws/wss requests with a request path starting with wsPrefix
32
+ * will be intercepted by the proxy.
33
+ * If wsPrefix starts with `^`, it will be recognized as a `RegExp`.
34
+ *
35
+ * 为 websocket mock 服务配置 路径匹配规则, 任何请求路径以 wsPrefix 开头的 ws/wss请求,
36
+ * 都将被代理拦截。
37
+ * 如果 wsPrefix 以 `^` 开头,将被识别为 `RegExp`。
38
+ * @default []
39
+ * @example ['/socket.io']
40
+ */
41
+ wsPrefix?: string | string[];
42
+ /**
43
+ * Configure the matching context for `include` and `exclude`.
44
+ *
45
+ * 配置 `include` 和 `exclude` 的匹配上下文
46
+ *
47
+ * @default process.cwd()
48
+ */
49
+ cwd?: string;
50
+ /**
51
+ * glob string matching mock includes files
52
+ *
53
+ * glob 字符串匹配 mock 包含的文件
54
+ * @see [picomatch](https://github.com/micromatch/picomatch#globbing-features)
55
+ * @default []
56
+ */
57
+ include?: string | string[];
58
+ /**
59
+ * glob string matching mock excluded files
60
+ *
61
+ * glob 字符串匹配 mock 排除的文件
62
+ * @see [picomatch](https://github.com/micromatch/picomatch#globbing-features)
63
+ */
64
+ exclude?: string | string[];
65
+ /**
66
+ * Enable log and configure log level
67
+ *
68
+ * 开启日志,或配置 日志级别
69
+ * @default 'info'
70
+ */
71
+ log?: boolean | LogLevel;
72
+ /**
73
+ * When the mock resource is hot updated, only the data content is updated,
74
+ * but the page is not refreshed by default.
75
+ * If you want to refresh the page every time you modify a mock file,
76
+ * you can open this option.
77
+ *
78
+ * mock资源热更新时,仅更新了数据内容,但是默认不重新刷新页面。
79
+ * 当你希望每次修改mock文件都刷新页面时,可以打开此选项。
80
+ * @default false
81
+ */
82
+ reload?: boolean;
83
+ /**
84
+ * Configure to `cors`
85
+ *
86
+ * 配置 `cors`
87
+ * @default true
88
+ * @see [cors](https://github.com/expressjs/cors#configuration-options)
89
+ */
90
+ cors?: boolean | CorsOptions;
91
+ /**
92
+ * formidable options
93
+ * @see [formidable](https://github.com/node-formidable/formidable#options)
94
+ */
95
+ formidableOptions?: formidable.Options;
96
+ /**
97
+ * cookies options
98
+ * @see [cookies](https://github.com/pillarjs/cookies#new-cookiesrequest-response--options)
99
+ */
100
+ cookiesOptions?: Cookies.Option;
101
+ /**
102
+ * Configure to `co-body`
103
+ *
104
+ * 配置 `co-body`
105
+ *
106
+ * @see [co-body](https://github.com/cojs/co-body#options)
107
+ */
108
+ bodyParserOptions?: BodyParserOptions;
109
+ /**
110
+ * When you need to build a small mock service, you can configure this option.
111
+ *
112
+ * 当需要构建一个小型mock服务时,可配置此项
113
+ * @default false
114
+ */
115
+ build?: boolean | ServerBuildOption;
116
+ /**
117
+ * Priority sorting for path matching rules is valid only for rules containing dynamic parameters.
118
+ * In most cases, the default sorting rules can meet the needs.
119
+ * However, in some cases where custom sorting rules are required, this option can be used.
120
+ *
121
+ * 路径匹配规则优先级排序,仅对包含动态参数的规则有效。
122
+ * 大部分情况下默认的排序规则都可以满足需求。
123
+ * 但有些情况下,需要自定义排序规则时,可以使用此选项。
124
+ *
125
+ * @example
126
+ * ```ts
127
+ * export default {
128
+ * priority: {
129
+ * global: ['/api/:a/b/c', '/api/a/:b/c', '/api/a/b/:c'],
130
+ * special: {
131
+ * '/api/:a/:b/c': {
132
+ * rules: ['/api/a/:b/:c', '/api/a/b/:c'],
133
+ * when: ['/api/a/b/c']
134
+ * }
135
+ * }
136
+ * }
137
+ * }
138
+ * ```
139
+ */
140
+ priority?: MockMatchPriority;
141
+ }
142
+ interface MockMatchPriority {
143
+ /**
144
+ * The priority of matching rules is global.
145
+ * The rules declared in this option will take priority over the default rules.
146
+ * The higher the position of the rule in the array, the higher the priority.
147
+ *
148
+ * Do not declare general rules in this option, such as /api/(.*),
149
+ * as it will prevent subsequent rules from taking effect.
150
+ * Unless you are clear about the priority of the rules,
151
+ * most of the time you do not need to configure this option.
152
+ *
153
+ * 匹配规则优先级, 全局生效。
154
+ * 声明在该选项中的规则将优先于默认规则生效。
155
+ * 规则在数组越靠前的位置,优先级越高。
156
+ *
157
+ * 不要在此选项中声明通用性的规则,比如 `/api/(.*)`,这将导致后续的规则无法生效。
158
+ * 除非你明确知道规则的优先级,否则大多数情况下都不需要配置该选项。
159
+ * @default []
160
+ */
161
+ global?: string[];
162
+ /**
163
+ * For some special cases where the priority of certain rules needs to be adjusted,
164
+ * this option can be used. For example, when a request matches both Rule A and Rule B,
165
+ * and Rule A has a higher priority than Rule B, but it is desired for Rule B to take effect.
166
+ *
167
+ * 对于一些特殊情况,需要调整部分规则的优先级,可以使用此选项。
168
+ * 比如一个请求同时命中了规则 A 和 B,且 A 比 B 优先级高, 但期望规则 B 生效时。
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * {
173
+ * special: {
174
+ * // /api/a/:b/c 优先级将提升到 /api/a/b/:c 前面
175
+ * // The /api/a/:b/c priority is promoted to /api/a/b/:c
176
+ * '/api/a/:b/c': ['/api/a/b/:c'],
177
+ * // 仅在请求满足 /api/a/b/c 时生效
178
+ * // Only when the request satisfies /api/a/b/c
179
+ * '/api/:a/b/c': {
180
+ * rules: ['/api/a/:b/c'],
181
+ * when: ['/api/a/b/c']
182
+ * }
183
+ * }
184
+ * }
185
+ * ```
186
+ */
187
+ special?: MockMatchSpecialPriority;
188
+ }
189
+ interface MockMatchSpecialPriority {
190
+ /**
191
+ * When both A and B or C match, and B or C is at the top of the sort order,
192
+ * insert A into the top position.The `when` option is used to further constrain
193
+ * the priority adjustment to be effective only for certain requests.
194
+ *
195
+ * 当 A 与 B或 C 同时满足匹配,`B` 或 `C` 在排序首位时,将A插入到首位。
196
+ * when 选项用于进一步约束该优先级调整仅针对哪些请求有效。
197
+ *
198
+ * @example
199
+ * ```ts
200
+ * {
201
+ * A: ['B', 'C'],
202
+ * A: { rules: ['B', 'C'], when: ['/api/a/b/c'] }
203
+ * }
204
+ * ```
205
+ */
206
+ [key: string]: string[] | {
207
+ rules: string[];
208
+ when: string[];
209
+ };
210
+ }
211
+ type BodyParserOptions = Options & {
212
+ jsonLimit?: string | number;
213
+ formLimit?: string | number;
214
+ textLimit?: string | number;
215
+ };
216
+ interface ServerBuildOption {
217
+ /**
218
+ * Service startup port
219
+ *
220
+ * 服务启动端口
221
+ * @default 8080
222
+ */
223
+ serverPort?: number;
224
+ /**
225
+ * Service application output directory
226
+ *
227
+ * 服务应用输出目录
228
+ * @default 'dist/mockServer'
229
+ */
230
+ dist?: string;
231
+ /**
232
+ * Service application log level
233
+ *
234
+ * 服务应用日志级别
235
+ * @default 'error'
236
+ */
237
+ log?: LogLevel;
238
+ }
239
+ type Method = "GET" | "POST" | "PUT" | "DELETE" | "PATCH" | "HEAD" | "TRACE" | "OPTIONS";
240
+ type Headers = http.IncomingHttpHeaders;
241
+ type ResponseBody = Record<string, any> | any[] | string | number | Readable | Buffer | null;
242
+ /**
243
+ * 扩展 request,添加额外的属性和方法
244
+ */
245
+ interface ExtraRequest {
246
+ /**
247
+ * The query string located after `?` in the request address has been parsed into JSON.
248
+ *
249
+ * 请求地址中位于 `?` 后面的 queryString,已解析为 json
250
+ */
251
+ query: Record<string, any>;
252
+ /**
253
+ * The queryString located after `?` in the referer request has been parsed as JSON.
254
+ *
255
+ * 请求 referer 中位于 `?` 后面的 queryString,已解析为 json
256
+ */
257
+ refererQuery: Record<string, any>;
258
+ /**
259
+ * Body data in the request
260
+ *
261
+ * 请求体中 body 数据
262
+ */
263
+ body: Record<string, any>;
264
+ /**
265
+ * The params parameter parsed from the `/api/id/:id` in the request address.
266
+ *
267
+ * 请求地址中,`/api/id/:id` 解析后的 params 参数
268
+ */
269
+ params: Record<string, any>;
270
+ /**
271
+ * headers data in the request
272
+ * 请求体中 headers
273
+ */
274
+ headers: Headers;
275
+ /**
276
+ * Get the cookie carried in the request.
277
+ *
278
+ * 获取 请求中携带的 cookie
279
+ * @see [cookies](https://github.com/pillarjs/cookies#cookiesgetname--options)
280
+ */
281
+ getCookie: (name: string, option?: Cookies.GetOption) => string | undefined;
282
+ }
283
+ type MockRequest = http.IncomingMessage & ExtraRequest;
284
+ type MockResponse = http.ServerResponse<http.IncomingMessage> & {
285
+ /**
286
+ * Set cookie in response
287
+ *
288
+ * 向请求响应中设置 cookie
289
+ * @see [cookies](https://github.com/pillarjs/cookies#cookiessetname--values--options)
290
+ */
291
+ setCookie: (name: string, value?: string | null, option?: Cookies.SetOption) => void;
292
+ };
293
+ type ResponseBodyFn = (request: MockRequest) => ResponseBody | Promise<ResponseBody>;
294
+ type ResponseHeaderFn = (request: MockRequest) => Headers | Promise<Headers>;
295
+ type CookieValue = string | [string, Cookies.SetOption];
296
+ type ResponseCookies = Record<string, CookieValue>;
297
+ type ResponseCookiesFn = (request: MockRequest) => ResponseCookies | Promise<ResponseCookies>;
298
+ interface MockBaseItem {
299
+ /**
300
+ * The interface address that needs to be mocked,
301
+ * supported by `path-to-regexp` for path matching.
302
+ *
303
+ * 需要进行 mock 的接口地址, 由 `path-to-regexp` 提供路径匹配支持
304
+ * @see [path-to-regexp](https://github.com/pillarjs/path-to-regexp)
305
+ * @example
306
+ * ```txt
307
+ * /api/login
308
+ * /api/post/:id
309
+ * /api/post/:id
310
+ * /api/anything/(.*)
311
+ * ```
312
+ */
313
+ url: string;
314
+ /**
315
+ * Enable WebSocket interface simulation
316
+ *
317
+ * 开启 websocket 接口模拟
318
+ *
319
+ * @default false
320
+ */
321
+ ws?: boolean;
322
+ /**
323
+ * Whether to enable mock for this interface.
324
+ * In most scenarios, we only need to mock some interfaces instead of all requests that
325
+ * have been configured with mock.
326
+ * Therefore, it is important to be able to configure whether to enable it or not.
327
+ *
328
+ * 是否启动对该接口的mock,在多数场景下,我们仅需要对部分接口进行 mock,
329
+ * 而不是对所有配置了mock的请求进行全量mock,所以是否能够配置是否启用很重要
330
+ * @default true
331
+ */
332
+ enabled?: boolean;
333
+ /**
334
+ * Enable log and configure log level
335
+ *
336
+ * 开启日志,或配置 日志级别
337
+ * @default 'info'
338
+ */
339
+ log?: boolean | LogLevel;
340
+ }
341
+ interface MockHttpItem extends MockBaseItem {
342
+ /**
343
+ * The interface allows request methods, and by default allows both GET and POST.
344
+ *
345
+ * 该接口允许的 请求方法,默认同时支持 GET 和 POST
346
+ * @default ['POST','GET']
347
+ */
348
+ method?: Method | Method[];
349
+ /**
350
+ * Configure the response body headers
351
+ *
352
+ * 配置响应体 headers
353
+ * @default
354
+ * ```json
355
+ * { "Content-Type": "application/json" }
356
+ * ```
357
+ */
358
+ headers?: Headers | ResponseHeaderFn;
359
+ /**
360
+ * Configure Response Header Status Code
361
+ *
362
+ * 配置 响应头状态码
363
+ * @default 200
364
+ */
365
+ status?: number;
366
+ /**
367
+ * Configure response header status text
368
+ *
369
+ * 配置响应头状态文本
370
+ * @default 'OK'
371
+ */
372
+ statusText?: string;
373
+ /**
374
+ * Configure response delay time,
375
+ * If an array is passed in, it represents the range of delay time.
376
+ * unit: `ms`
377
+ *
378
+ * 配置响应延迟时间, 如果传入的是一个数组,则代表延迟时间的范围
379
+ * 单位: `ms`
380
+ * @default 0
381
+ */
382
+ delay?: number | [number, number];
383
+ /**
384
+ * Configure response body cookies
385
+ *
386
+ * 设置响应体 cookies
387
+ * @example
388
+ * ```ts
389
+ * export default {
390
+ * cookies: {
391
+ * 'token1': '1234567',
392
+ * 'token2': ['1234567', { path: '/' }],
393
+ * },
394
+ * }
395
+ * ```
396
+ * @example
397
+ * ```ts
398
+ * export default {
399
+ * cookies: function (request) {
400
+ * return {
401
+ * 'token1': '1234567',
402
+ * 'token2': ['1234567', { path: '/' }],
403
+ * }
404
+ * },
405
+ * }
406
+ * ```
407
+ */
408
+ cookies?: ResponseCookies | ResponseCookiesFn;
409
+ /**
410
+ * Response body data type, optional values include `text, json, buffer`.
411
+ *
412
+ * And also support types included in `mime-db`.
413
+ * When the response body returns a file and you are not sure which type to use,
414
+ * you can pass the file name as the value. The plugin will internally search for matching
415
+ * `content-type` based on the file name suffix.
416
+ *
417
+ * However, if it is a TypeScript file such as `a.ts`, it may not be correctly matched
418
+ * as a JavaScript script. You need to modify `a.ts` to `a.js` as the value passed
419
+ * in order to recognize it correctly.
420
+ *
421
+ * 响应体数据类型, 可选值包括 `text, json, buffer`,
422
+ *
423
+ * 还支持`mime-db`中的包含的类型。
424
+ * 当响应体返回的是一个文件,而你不确定应该使用哪个类型时,可以将文件名作为值传入,
425
+ * 插件内部会根据文件名后缀查找匹配的`content-type`。
426
+ *
427
+ * 但如果是 `typescript`文件如 `a.ts`,可能不会被正确匹配为 `javascript`脚本,
428
+ * 你需要将 `a.ts` 修改为 `a.js`作为值传入才能正确识别。
429
+ * @see [mime-db](https://github.com/jshttp/mime-db)
430
+ * @default 'json'
431
+ * @example
432
+ * ```txt
433
+ * json
434
+ * buffer
435
+ * my-app.dmg
436
+ * music.mp4
437
+ * ```
438
+ */
439
+ type?: "text" | "json" | "buffer" | string;
440
+ /**
441
+ * Configure response body data content
442
+ *
443
+ * 配置响应体数据内容
444
+ * @default ''
445
+ * @example
446
+ * ```ts
447
+ * export default {
448
+ * body: { a: 1 },
449
+ * }
450
+ * ```
451
+ * @example
452
+ * ```ts
453
+ * export default {
454
+ * body: function(request) {
455
+ * return { a: 1, query: request.query }
456
+ * },
457
+ * }
458
+ * ```
459
+ */
460
+ body?: ResponseBody | ResponseBodyFn;
461
+ /**
462
+ * If you need to set complex response content, you can use the response method,
463
+ * which is a middleware. Here, you can get information such as req
464
+ * and res of the http request,
465
+ * and then return response data through res.write() | res.end().
466
+ * Otherwise, you need to execute next() method.
467
+ * In `req`, you can also get parsed request information such as
468
+ * `query`, `params`, `body` and `refererQuery`.
469
+ *
470
+ * 如果需要设置复杂的响应内容,可以使用 response 方法,
471
+ * 该方法是一个 middleware,你可以在这里拿到 http 请求的 req、res等信息,
472
+ * 然后通过 res.write() | res.end() 返回响应数据, 否则需要执行 next() 方法。
473
+ * 在 `req` 中,还可以拿到 query、params、body, refererQuery 等已解析的请求信息。
474
+ *
475
+ * @see [connect](https://github.com/senchalabs/connect#appusefn)
476
+ * @example
477
+ * ```ts
478
+ * export default {
479
+ * response(req, res) {
480
+ * res.setHeader('Content-Type', 'application/json')
481
+ * res.end(JSON.stringify({ a: 1 }))
482
+ * },
483
+ * }
484
+ * ```
485
+ *
486
+ */
487
+ response?: (req: MockRequest, res: MockResponse, next: (err?: any) => void) => void | Promise<void>;
488
+ /**
489
+ * Request Validator
490
+ *
491
+ * Sometimes, for the same API request, data needs to be returned based
492
+ * on different request parameters.
493
+ * However, if all of this is written in a single mock's body or response,
494
+ * the content can become cumbersome and difficult to manage.
495
+ * The function of a validator allows you to configure multiple mocks with
496
+ * the same URL simultaneously and determine which mock should be used through validation.
497
+ *
498
+ * 请求验证器
499
+ *
500
+ * 有时候,一个相同的API请求,需要根据不同的请求参数,来决定返回数据,
501
+ * 但全部都在单个 mock中的 body或者 response 中写,内容会很庞杂,不好管理,
502
+ * 验证器的功能,允许你同时配置多条相同url的mock,通过验证器来判断使哪个mock生效。
503
+ * @example
504
+ * ```ts
505
+ * export default {
506
+ * validator: {
507
+ * query: { id: 123 }
508
+ * }
509
+ * }
510
+ * ```
511
+ * @example
512
+ * ```ts
513
+ * export default {
514
+ * validator: function(request) {
515
+ * return request.query.id === 123
516
+ * }
517
+ * }
518
+ * ```
519
+ */
520
+ validator?: Partial<Omit<ExtraRequest, "getCookie">> | ((request: ExtraRequest) => boolean);
521
+ ws?: false;
522
+ }
523
+ interface MockWebsocketItem extends MockBaseItem {
524
+ ws: true;
525
+ /**
526
+ * Configure Websocket Server
527
+ *
528
+ * 配置 Websocket Server
529
+ * @example
530
+ * ```ts
531
+ * export default {
532
+ * ws: true
533
+ * setup: (wss, { onCleanup }) => {
534
+ * wss.on('connection', (ws,req) => {
535
+ * ws.on('message', (raw) => console.log(raw))
536
+ * const timer = setInterval(
537
+ * () => ws.send(JSON.stringify({ type: 'connected' })),
538
+ * 1000,
539
+ * )
540
+ * onCleanup(() => clearInterval(timer))
541
+ * })
542
+ * wss.on('error', (error) => console.error(error))
543
+ * }
544
+ * }
545
+ * ```
546
+ */
547
+ setup: (wss: WebSocketServer, context: WebSocketSetupContext) => void;
548
+ }
549
+ interface WebSocketSetupContext {
550
+ /**
551
+ * When defining WSS, you may perform some automatic or looping tasks.
552
+ * However, when hot updating, the plugin will re-execute `setup()`,
553
+ * which may result in duplicate registration of listening events and looping tasks
554
+ * such as setTimeout. You can use `onCleanup()` to clear these automatic or looping tasks.
555
+ *
556
+ * 当你在定义 WSS 时,可能会执行一些自动任务或循环任务,
557
+ * 但是当热更新时,插件内部会重新执行 setup() ,
558
+ * 这可能导致出现 重复注册监听事件 和 循环任务如 `setTimeout` 等。
559
+ * 通过 `onCleanup()` 可以来清除这些自动任务或循环任务。
560
+ * @example
561
+ * ``` ts
562
+ * onCleanup(() => clearTimeout(timeId))
563
+ * ```
564
+ */
565
+ onCleanup: (cleanup: () => void) => void;
566
+ }
567
+ type MockOptions = (MockHttpItem | MockWebsocketItem)[];
568
+ type FormidableFile = formidable.File | formidable.File[];
569
+ type LogType = "info" | "warn" | "error" | "debug";
570
+ type LogLevel = LogType | "silent";
571
+ //#endregion
572
+ export { BodyParserOptions, ExtraRequest, FormidableFile, LogLevel, LogType, Method, MockHttpItem, MockMatchPriority, MockMatchSpecialPriority, MockOptions, MockRequest, MockResponse, MockServerPluginOptions, MockWebsocketItem, ResponseBody, ServerBuildOption, WebSocketSetupContext };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "rspack-plugin-mock",
3
3
  "type": "module",
4
- "version": "1.1.0",
4
+ "version": "1.2.0",
5
5
  "description": "inject api mock server to development server",
6
6
  "author": "pengzhanbo <q942450674@outlook.com> (https://github.com/pengzhanbo)",
7
7
  "license": "MIT",
@@ -86,52 +86,52 @@
86
86
  }
87
87
  },
88
88
  "dependencies": {
89
- "@pengzhanbo/utils": "^2.0.0",
90
- "@rollup/pluginutils": "^5.1.4",
89
+ "@pengzhanbo/utils": "^2.1.0",
90
+ "@rollup/pluginutils": "^5.2.0",
91
91
  "chokidar": "3.6.0",
92
92
  "co-body": "^6.2.0",
93
93
  "cookies": "^0.9.1",
94
94
  "cors": "^2.8.5",
95
- "debug": "^4.4.0",
95
+ "debug": "^4.4.1",
96
96
  "fast-glob": "^3.3.3",
97
- "formidable": "2.1.2",
97
+ "formidable": "^3.5.4",
98
98
  "http-status": "^2.1.0",
99
99
  "is-core-module": "^2.16.1",
100
100
  "json5": "^2.2.3",
101
- "memfs": "^4.17.0",
101
+ "memfs": "^4.17.2",
102
102
  "mime-types": "^3.0.1",
103
103
  "path-to-regexp": "6.3.0",
104
104
  "picocolors": "^1.1.1",
105
- "portfinder": "^1.0.36",
106
- "ws": "^8.18.1"
105
+ "portfinder": "^1.0.37",
106
+ "ws": "^8.18.3"
107
107
  },
108
108
  "devDependencies": {
109
- "@pengzhanbo/eslint-config": "^1.29.0",
110
- "@rsbuild/core": "^1.3.6",
111
- "@rspack/core": "^1.3.4",
109
+ "@pengzhanbo/eslint-config": "^1.34.0",
110
+ "@rsbuild/core": "^1.4.3",
111
+ "@rspack/core": "^1.4.2",
112
112
  "@types/co-body": "^6.1.3",
113
- "@types/cookies": "^0.9.0",
114
- "@types/cors": "^2.8.17",
113
+ "@types/cookies": "^0.9.1",
114
+ "@types/cors": "^2.8.19",
115
115
  "@types/debug": "^4.1.12",
116
- "@types/formidable": "2.0.6",
116
+ "@types/formidable": "^3.4.5",
117
117
  "@types/is-core-module": "^2.2.2",
118
- "@types/mime-types": "^2.1.4",
119
- "@types/node": "^22.14.1",
118
+ "@types/mime-types": "^3.0.1",
119
+ "@types/node": "^22.16.0",
120
120
  "@types/ws": "^8.18.1",
121
- "bumpp": "^10.1.0",
121
+ "bumpp": "^10.2.0",
122
122
  "conventional-changelog-cli": "^5.0.0",
123
- "eslint": "^9.24.0",
123
+ "eslint": "^9.30.1",
124
124
  "husky": "^9.1.7",
125
- "lint-staged": "^15.5.1",
126
- "tsup": "^8.4.0",
125
+ "lint-staged": "^16.1.2",
126
+ "tsdown": "^0.12.9",
127
127
  "typescript": "^5.8.3"
128
128
  },
129
129
  "lint-staged": {
130
130
  "*": "eslint --fix"
131
131
  },
132
132
  "scripts": {
133
- "dev": "tsup src --watch",
134
- "build": "tsup",
133
+ "dev": "tsdown src --watch",
134
+ "build": "tsdown",
135
135
  "lint": "eslint .",
136
136
  "release:changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
137
137
  "release": "bumpp package.json --execute=\"pnpm release:changelog\" --commit --all --push --tag && pnpm publish --access public"