@midwayjs/busboy 4.0.0-alpha.1 → 4.0.0-beta.10

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
@@ -9,4 +9,4 @@ Document: [https://midwayjs.org](https://midwayjs.org)
9
9
 
10
10
  ## License
11
11
 
12
- [MIT]((http://github.com/midwayjs/midway/blob/master/LICENSE))
12
+ [MIT](https://github.com/midwayjs/midway/blob/master/LICENSE)
@@ -16,6 +16,8 @@ const constants_1 = require("./constants");
16
16
  const path_1 = require("path");
17
17
  const os_1 = require("os");
18
18
  let BusboyConfiguration = class BusboyConfiguration {
19
+ uploadConfig;
20
+ logger;
19
21
  async onReady() {
20
22
  const { tmpdir, cleanTimeout, mode } = this.uploadConfig;
21
23
  if (mode === 'file' && tmpdir) {
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Readable } from 'stream';
3
2
  import { IgnoreMatcher, IMidwayContext } from '@midwayjs/core';
4
3
  import { BusboyConfig } from 'busboy';
@@ -36,6 +35,10 @@ export interface UploadOptions extends BusboyConfig {
36
35
  * Mime type white list
37
36
  */
38
37
  mimeTypeWhiteList?: Record<string, string | string[]> | ((ctx: IMidwayContext<any>) => string | string[]);
38
+ /**
39
+ * Whether to allow fields duplication, default is `false`, only for `file` and `stream` mode
40
+ */
41
+ allowFieldsDuplication?: boolean;
39
42
  }
40
43
  export interface UploadFileInfo {
41
44
  /**
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  import { IMiddleware, ILogger, IgnoreMatcher, IMidwayApplication } from '@midwayjs/core';
4
2
  import { UploadOptions, UploadMode } from './interface';
5
3
  import { BusboyConfig } from 'busboy';
@@ -22,18 +22,20 @@ const busboy = require("busboy");
22
22
  const constants_1 = require("./constants");
23
23
  const { unlink, writeFile } = fs_1.promises;
24
24
  let UploadMiddleware = class UploadMiddleware {
25
- constructor() {
26
- /**
27
- * cache global upload white list when uploadConfig.whitelist is set
28
- * @private
29
- */
30
- this.uploadWhiteListMap = new Map();
31
- /**
32
- * cache global upload mime type white list when uploadConfig.mimeTypeWhiteList is set
33
- * @private
34
- */
35
- this.uploadFileMimeTypeMap = new Map();
36
- }
25
+ uploadConfig;
26
+ logger;
27
+ /**
28
+ * cache global upload white list when uploadConfig.whitelist is set
29
+ * @private
30
+ */
31
+ uploadWhiteListMap = new Map();
32
+ /**
33
+ * cache global upload mime type white list when uploadConfig.mimeTypeWhiteList is set
34
+ * @private
35
+ */
36
+ uploadFileMimeTypeMap = new Map();
37
+ match;
38
+ ignore;
37
39
  async init() {
38
40
  if (this.uploadConfig.match) {
39
41
  this.match = [].concat(this.uploadConfig.match || []);
@@ -119,7 +121,7 @@ let UploadMiddleware = class UploadMiddleware {
119
121
  }
120
122
  async processFileOrStream(req, uploadConfig, currentContextWhiteListMap, currentContextMimeTypeWhiteListMap, ctxOrReq) {
121
123
  let isStreamResolve = false;
122
- const { mode, tmpdir } = uploadConfig;
124
+ const { mode, tmpdir, allowFieldsDuplication } = uploadConfig;
123
125
  const { files = [], fields = [] } = await new Promise((resolveP, reject) => {
124
126
  const bb = busboy({
125
127
  headers: req.headers,
@@ -219,10 +221,27 @@ let UploadMiddleware = class UploadMiddleware {
219
221
  req.pipe(bb);
220
222
  });
221
223
  ctxOrReq.files = files;
222
- ctxOrReq.fields = fields.reduce((accumulator, current) => {
223
- accumulator[current.name] = current.value;
224
- return accumulator;
225
- }, {});
224
+ if (allowFieldsDuplication) {
225
+ // 如果重复,则使用数组
226
+ ctxOrReq.fields = fields.reduce((accumulator, current) => {
227
+ if (accumulator[current.name]) {
228
+ if (!Array.isArray(accumulator[current.name])) {
229
+ accumulator[current.name] = [accumulator[current.name]];
230
+ }
231
+ accumulator[current.name].push(current.value);
232
+ }
233
+ else {
234
+ accumulator[current.name] = current.value;
235
+ }
236
+ return accumulator;
237
+ }, {});
238
+ }
239
+ else {
240
+ ctxOrReq.fields = fields.reduce((accumulator, current) => {
241
+ accumulator[current.name] = current.value;
242
+ return accumulator;
243
+ }, {});
244
+ }
226
245
  }
227
246
  async processAsyncIterator(req, uploadConfig, currentContextWhiteListMap, currentContextMimeTypeWhiteListMap, ctxOrReq) {
228
247
  const bb = busboy({
package/dist/parse.d.ts CHANGED
@@ -1,5 +1,3 @@
1
- /// <reference types="node" />
2
- /// <reference types="node" />
3
1
  import { UploadOptions } from './interface';
4
2
  export declare const parseMultipart: (body: any, boundary: string, uploadConfig: UploadOptions) => Promise<{
5
3
  files: any[];
package/dist/parse.js CHANGED
@@ -84,7 +84,9 @@ const parseHead = (headBuf) => {
84
84
  if (name === 'content-disposition') {
85
85
  const headCol = {};
86
86
  value.split(/;\s+/).forEach((kv) => {
87
- const [k, v] = kv.split('=');
87
+ const eqIndex = kv.indexOf('=');
88
+ const k = eqIndex !== -1 ? kv.substring(0, eqIndex) : kv;
89
+ const v = eqIndex !== -1 ? kv.substring(eqIndex + 1) : undefined;
88
90
  headCol[k] = v ? v.replace(/^"/, '').replace(/"$/, '') : v ?? true;
89
91
  });
90
92
  head[name] = headCol;
package/dist/utils.d.ts CHANGED
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Readable } from 'stream';
3
2
  export declare const autoRemoveUploadTmpFile: (tmpDir: string, cleanTimeout: number) => Promise<void>;
4
3
  export declare const stopAutoRemoveUploadTmpFile: () => Promise<void>;
package/dist/utils.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.streamToAsyncIterator = exports.formatExt = exports.ensureDir = exports.checkExists = exports.stopAutoRemoveUploadTmpFile = exports.autoRemoveUploadTmpFile = void 0;
3
+ exports.formatExt = exports.ensureDir = exports.checkExists = exports.stopAutoRemoveUploadTmpFile = exports.autoRemoveUploadTmpFile = void 0;
4
+ exports.streamToAsyncIterator = streamToAsyncIterator;
4
5
  const fs_1 = require("fs");
5
6
  const path_1 = require("path");
6
7
  const { readdir, access, stat, unlink, mkdir } = fs_1.promises;
@@ -93,5 +94,4 @@ async function* streamToAsyncIterator(stream) {
93
94
  yield chunk;
94
95
  }
95
96
  }
96
- exports.streamToAsyncIterator = streamToAsyncIterator;
97
97
  //# sourceMappingURL=utils.js.map
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@midwayjs/busboy",
3
- "version": "4.0.0-alpha.1",
4
- "description": "Midway Component for upload",
3
+ "version": "4.0.0-beta.10",
4
+ "description": "Midway Component for Busboy (multipart form data parser)",
5
5
  "main": "dist/index.js",
6
6
  "typings": "index.d.ts",
7
7
  "scripts": {
@@ -18,7 +18,7 @@
18
18
  "index.d.ts"
19
19
  ],
20
20
  "engines": {
21
- "node": ">=12"
21
+ "node": ">=20"
22
22
  },
23
23
  "license": "MIT",
24
24
  "dependencies": {
@@ -27,14 +27,17 @@
27
27
  "file-type": "16.5.4"
28
28
  },
29
29
  "devDependencies": {
30
- "@midwayjs/core": "^4.0.0-alpha.1",
31
- "@midwayjs/express": "^4.0.0-alpha.1",
32
- "@midwayjs/faas": "^4.0.0-alpha.1",
33
- "@midwayjs/fc-starter": "^4.0.0-alpha.1",
34
- "@midwayjs/koa": "^4.0.0-alpha.1",
35
- "@midwayjs/mock": "^4.0.0-alpha.1",
36
- "@midwayjs/web": "^4.0.0-alpha.1",
37
- "fs-extra": "11.2.0"
30
+ "@midwayjs/core": "^4.0.0-beta.10",
31
+ "@midwayjs/express": "^4.0.0-beta.10",
32
+ "@midwayjs/faas": "^4.0.0-beta.10",
33
+ "@midwayjs/fc-starter": "^4.0.0-beta.10",
34
+ "@midwayjs/koa": "^4.0.0-beta.10",
35
+ "@midwayjs/mock": "^4.0.0-beta.10",
36
+ "@midwayjs/validation": "^4.0.0-beta.10",
37
+ "@midwayjs/validation-zod": "^4.0.0-beta.10",
38
+ "@midwayjs/web": "^4.0.0-beta.10",
39
+ "fs-extra": "11.3.3",
40
+ "zod": "3.25.76"
38
41
  },
39
- "gitHead": "14bb4da91805a1cf52f190c0d37a74b395dd6372"
42
+ "gitHead": "1b1856629913703f67304155aaf611ec936a81ac"
40
43
  }