@nocobase/plugin-field-sort 1.5.0-alpha.1

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 (142) hide show
  1. package/LICENSE.txt +159 -0
  2. package/README.md +1 -0
  3. package/client.d.ts +2 -0
  4. package/client.js +1 -0
  5. package/dist/client/index.d.ts +15 -0
  6. package/dist/client/index.js +10 -0
  7. package/dist/client/locale.d.ts +10 -0
  8. package/dist/client/sort-interface.d.ts +131 -0
  9. package/dist/externalVersion.js +18 -0
  10. package/dist/index.d.ts +10 -0
  11. package/dist/index.js +48 -0
  12. package/dist/locale/en-US.json +1 -0
  13. package/dist/locale/zh-CN.json +1 -0
  14. package/dist/node_modules/@nocobase/lock-manager/LICENSE +661 -0
  15. package/dist/node_modules/@nocobase/lock-manager/lib/index.d.ts +10 -0
  16. package/dist/node_modules/@nocobase/lock-manager/lib/index.js +1 -0
  17. package/dist/node_modules/@nocobase/lock-manager/lib/lock-manager.d.ts +46 -0
  18. package/dist/node_modules/@nocobase/lock-manager/lib/lock-manager.js +171 -0
  19. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/client.js +12 -0
  20. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/assign.d.ts +17 -0
  21. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/assign.js +143 -0
  22. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/client.d.ts +30 -0
  23. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/client.js +88 -0
  24. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/collections-graph.d.ts +24 -0
  25. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/collections-graph.js +107 -0
  26. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/common.d.ts +14 -0
  27. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/common.js +87 -0
  28. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/date.d.ts +38 -0
  29. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/date.js +214 -0
  30. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/dayjs.d.ts +10 -0
  31. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/dayjs.js +72 -0
  32. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/forEach.d.ts +9 -0
  33. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/forEach.js +45 -0
  34. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/fs-exists.d.ts +9 -0
  35. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/fs-exists.js +46 -0
  36. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/getValuesByPath.d.ts +9 -0
  37. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/getValuesByPath.js +71 -0
  38. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/handlebars.d.ts +10 -0
  39. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/handlebars.js +73 -0
  40. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/i18n.d.ts +10 -0
  41. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/i18n.js +43 -0
  42. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/index.d.ts +38 -0
  43. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/index.js +105 -0
  44. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/isPortalInBody.d.ts +13 -0
  45. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/isPortalInBody.js +54 -0
  46. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/isValidFilter.d.ts +9 -0
  47. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/isValidFilter.js +63 -0
  48. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/json-templates.d.ts +9 -0
  49. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/json-templates.js +141 -0
  50. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/koa-multer.d.ts +15 -0
  51. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/koa-multer.js +92 -0
  52. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/log.d.ts +9 -0
  53. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/log.js +39 -0
  54. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/measure-execution-time.d.ts +9 -0
  55. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/measure-execution-time.js +44 -0
  56. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/merge.d.ts +9 -0
  57. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/merge.js +55 -0
  58. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/mixin/AsyncEmitter.d.ts +11 -0
  59. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/mixin/AsyncEmitter.js +80 -0
  60. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/mixin/index.d.ts +9 -0
  61. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/mixin/index.js +48 -0
  62. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/notification.d.ts +9 -0
  63. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/notification.js +43 -0
  64. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/number.d.ts +9 -0
  65. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/number.js +45 -0
  66. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/parse-date.d.ts +15 -0
  67. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/parse-date.js +262 -0
  68. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/parse-filter.d.ts +67 -0
  69. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/parse-filter.js +320 -0
  70. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/parseHTML.d.ts +15 -0
  71. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/parseHTML.js +42 -0
  72. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/perf-hooks.d.ts +14 -0
  73. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/perf-hooks.js +69 -0
  74. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/registry.d.ts +22 -0
  75. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/registry.js +69 -0
  76. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/requireModule.d.ts +12 -0
  77. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/requireModule.js +90 -0
  78. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/server.d.ts +19 -0
  79. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/server.js +50 -0
  80. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/toposort.d.ts +18 -0
  81. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/toposort.js +83 -0
  82. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/uid.d.ts +9 -0
  83. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/uid.js +44 -0
  84. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/url.d.ts +14 -0
  85. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/url.js +46 -0
  86. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/wrap-middleware.d.ts +1 -0
  87. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/lib/wrap-middleware.js +63 -0
  88. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/package.json +20 -0
  89. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/plugin-symlink.d.ts +6 -0
  90. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/plugin-symlink.js +102 -0
  91. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/server.d.ts +2 -0
  92. package/dist/node_modules/@nocobase/lock-manager/node_modules/@nocobase/utils/server.js +12 -0
  93. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/.eslintrc.js +5 -0
  94. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/.github/workflows/ci.yml +24 -0
  95. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/.github/workflows/lint.yml +23 -0
  96. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/bench/bench-multipart-fields-100mb-big.js +149 -0
  97. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/bench/bench-multipart-fields-100mb-small.js +143 -0
  98. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/bench/bench-multipart-files-100mb-big.js +154 -0
  99. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/bench/bench-multipart-files-100mb-small.js +148 -0
  100. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/bench/bench-urlencoded-fields-100pairs-small.js +101 -0
  101. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/bench/bench-urlencoded-fields-900pairs-small-alt.js +84 -0
  102. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/lib/index.js +57 -0
  103. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/lib/types/multipart.js +653 -0
  104. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/lib/types/urlencoded.js +350 -0
  105. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/lib/utils.js +596 -0
  106. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/package.json +22 -0
  107. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/test/common.js +109 -0
  108. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/test/test-types-multipart-charsets.js +94 -0
  109. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/test/test-types-multipart-stream-pause.js +102 -0
  110. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/test/test-types-multipart.js +1053 -0
  111. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/test/test-types-urlencoded.js +488 -0
  112. package/dist/node_modules/@nocobase/lock-manager/node_modules/busboy/test/test.js +20 -0
  113. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/index.js +104 -0
  114. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/lib/counter.js +28 -0
  115. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/lib/file-appender.js +67 -0
  116. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/lib/make-middleware.js +173 -0
  117. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/lib/multer-error.js +24 -0
  118. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/lib/remove-uploaded-files.js +28 -0
  119. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/package.json +52 -0
  120. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/storage/disk.js +66 -0
  121. package/dist/node_modules/@nocobase/lock-manager/node_modules/multer/storage/memory.js +21 -0
  122. package/dist/node_modules/@nocobase/lock-manager/node_modules/streamsearch/.eslintrc.js +5 -0
  123. package/dist/node_modules/@nocobase/lock-manager/node_modules/streamsearch/.github/workflows/ci.yml +24 -0
  124. package/dist/node_modules/@nocobase/lock-manager/node_modules/streamsearch/.github/workflows/lint.yml +23 -0
  125. package/dist/node_modules/@nocobase/lock-manager/node_modules/streamsearch/lib/sbmh.js +267 -0
  126. package/dist/node_modules/@nocobase/lock-manager/node_modules/streamsearch/package.json +34 -0
  127. package/dist/node_modules/@nocobase/lock-manager/node_modules/streamsearch/test/test.js +70 -0
  128. package/dist/node_modules/@nocobase/lock-manager/package.json +1 -0
  129. package/dist/node_modules/@nocobase/lock-manager/src/__tests__/lock-manager.test.ts +169 -0
  130. package/dist/node_modules/@nocobase/lock-manager/src/index.ts +11 -0
  131. package/dist/node_modules/@nocobase/lock-manager/src/lock-manager.ts +169 -0
  132. package/dist/server/action.d.ts +26 -0
  133. package/dist/server/action.js +168 -0
  134. package/dist/server/index.d.ts +10 -0
  135. package/dist/server/index.js +48 -0
  136. package/dist/server/plugin.d.ts +19 -0
  137. package/dist/server/plugin.js +69 -0
  138. package/dist/server/sort-field.d.ts +24 -0
  139. package/dist/server/sort-field.js +197 -0
  140. package/package.json +16 -0
  141. package/server.d.ts +2 -0
  142. package/server.js +1 -0
@@ -0,0 +1,1053 @@
1
+ 'use strict';
2
+
3
+ const assert = require('assert');
4
+ const { inspect } = require('util');
5
+
6
+ const busboy = require('..');
7
+
8
+ const active = new Map();
9
+
10
+ const tests = [
11
+ { source: [
12
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
13
+ 'Content-Disposition: form-data; name="file_name_0"',
14
+ '',
15
+ 'super alpha file',
16
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
17
+ 'Content-Disposition: form-data; name="file_name_1"',
18
+ '',
19
+ 'super beta file',
20
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
21
+ 'Content-Disposition: form-data; '
22
+ + 'name="upload_file_0"; filename="1k_a.dat"',
23
+ 'Content-Type: application/octet-stream',
24
+ '',
25
+ 'A'.repeat(1023),
26
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
27
+ 'Content-Disposition: form-data; '
28
+ + 'name="upload_file_1"; filename="1k_b.dat"',
29
+ 'Content-Type: application/octet-stream',
30
+ '',
31
+ 'B'.repeat(1023),
32
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
33
+ ].join('\r\n')
34
+ ],
35
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
36
+ expected: [
37
+ { type: 'field',
38
+ name: 'file_name_0',
39
+ val: 'super alpha file',
40
+ info: {
41
+ nameTruncated: false,
42
+ valueTruncated: false,
43
+ encoding: '7bit',
44
+ mimeType: 'text/plain',
45
+ },
46
+ },
47
+ { type: 'field',
48
+ name: 'file_name_1',
49
+ val: 'super beta file',
50
+ info: {
51
+ nameTruncated: false,
52
+ valueTruncated: false,
53
+ encoding: '7bit',
54
+ mimeType: 'text/plain',
55
+ },
56
+ },
57
+ { type: 'file',
58
+ name: 'upload_file_0',
59
+ data: Buffer.from('A'.repeat(1023)),
60
+ info: {
61
+ filename: '1k_a.dat',
62
+ encoding: '7bit',
63
+ mimeType: 'application/octet-stream',
64
+ },
65
+ limited: false,
66
+ },
67
+ { type: 'file',
68
+ name: 'upload_file_1',
69
+ data: Buffer.from('B'.repeat(1023)),
70
+ info: {
71
+ filename: '1k_b.dat',
72
+ encoding: '7bit',
73
+ mimeType: 'application/octet-stream',
74
+ },
75
+ limited: false,
76
+ },
77
+ ],
78
+ what: 'Fields and files'
79
+ },
80
+ { source: [
81
+ ['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
82
+ 'Content-Disposition: form-data; name="cont"',
83
+ '',
84
+ 'some random content',
85
+ '------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
86
+ 'Content-Disposition: form-data; name="pass"',
87
+ '',
88
+ 'some random pass',
89
+ '------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
90
+ 'Content-Disposition: form-data; name=bit',
91
+ '',
92
+ '2',
93
+ '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
94
+ ].join('\r\n')
95
+ ],
96
+ boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
97
+ expected: [
98
+ { type: 'field',
99
+ name: 'cont',
100
+ val: 'some random content',
101
+ info: {
102
+ nameTruncated: false,
103
+ valueTruncated: false,
104
+ encoding: '7bit',
105
+ mimeType: 'text/plain',
106
+ },
107
+ },
108
+ { type: 'field',
109
+ name: 'pass',
110
+ val: 'some random pass',
111
+ info: {
112
+ nameTruncated: false,
113
+ valueTruncated: false,
114
+ encoding: '7bit',
115
+ mimeType: 'text/plain',
116
+ },
117
+ },
118
+ { type: 'field',
119
+ name: 'bit',
120
+ val: '2',
121
+ info: {
122
+ nameTruncated: false,
123
+ valueTruncated: false,
124
+ encoding: '7bit',
125
+ mimeType: 'text/plain',
126
+ },
127
+ },
128
+ ],
129
+ what: 'Fields only'
130
+ },
131
+ { source: [
132
+ ''
133
+ ],
134
+ boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
135
+ expected: [
136
+ { error: 'Unexpected end of form' },
137
+ ],
138
+ what: 'No fields and no files'
139
+ },
140
+ { source: [
141
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
142
+ 'Content-Disposition: form-data; name="file_name_0"',
143
+ '',
144
+ 'super alpha file',
145
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
146
+ 'Content-Disposition: form-data; '
147
+ + 'name="upload_file_0"; filename="1k_a.dat"',
148
+ 'Content-Type: application/octet-stream',
149
+ '',
150
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
151
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
152
+ ].join('\r\n')
153
+ ],
154
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
155
+ limits: {
156
+ fileSize: 13,
157
+ fieldSize: 5
158
+ },
159
+ expected: [
160
+ { type: 'field',
161
+ name: 'file_name_0',
162
+ val: 'super',
163
+ info: {
164
+ nameTruncated: false,
165
+ valueTruncated: true,
166
+ encoding: '7bit',
167
+ mimeType: 'text/plain',
168
+ },
169
+ },
170
+ { type: 'file',
171
+ name: 'upload_file_0',
172
+ data: Buffer.from('ABCDEFGHIJKLM'),
173
+ info: {
174
+ filename: '1k_a.dat',
175
+ encoding: '7bit',
176
+ mimeType: 'application/octet-stream',
177
+ },
178
+ limited: true,
179
+ },
180
+ ],
181
+ what: 'Fields and files (limits)'
182
+ },
183
+ { source: [
184
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
185
+ 'Content-Disposition: form-data; name="file_name_0"',
186
+ '',
187
+ 'super alpha file',
188
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
189
+ 'Content-Disposition: form-data; '
190
+ + 'name="upload_file_0"; filename="1k_a.dat"',
191
+ 'Content-Type: application/octet-stream',
192
+ '',
193
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
194
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
195
+ ].join('\r\n')
196
+ ],
197
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
198
+ limits: {
199
+ files: 0
200
+ },
201
+ expected: [
202
+ { type: 'field',
203
+ name: 'file_name_0',
204
+ val: 'super alpha file',
205
+ info: {
206
+ nameTruncated: false,
207
+ valueTruncated: false,
208
+ encoding: '7bit',
209
+ mimeType: 'text/plain',
210
+ },
211
+ },
212
+ 'filesLimit',
213
+ ],
214
+ what: 'Fields and files (limits: 0 files)'
215
+ },
216
+ { source: [
217
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
218
+ 'Content-Disposition: form-data; name="file_name_0"',
219
+ '',
220
+ 'super alpha file',
221
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
222
+ 'Content-Disposition: form-data; name="file_name_1"',
223
+ '',
224
+ 'super beta file',
225
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
226
+ 'Content-Disposition: form-data; '
227
+ + 'name="upload_file_0"; filename="1k_a.dat"',
228
+ 'Content-Type: application/octet-stream',
229
+ '',
230
+ 'A'.repeat(1023),
231
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
232
+ 'Content-Disposition: form-data; '
233
+ + 'name="upload_file_1"; filename="1k_b.dat"',
234
+ 'Content-Type: application/octet-stream',
235
+ '',
236
+ 'B'.repeat(1023),
237
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
238
+ ].join('\r\n')
239
+ ],
240
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
241
+ expected: [
242
+ { type: 'field',
243
+ name: 'file_name_0',
244
+ val: 'super alpha file',
245
+ info: {
246
+ nameTruncated: false,
247
+ valueTruncated: false,
248
+ encoding: '7bit',
249
+ mimeType: 'text/plain',
250
+ },
251
+ },
252
+ { type: 'field',
253
+ name: 'file_name_1',
254
+ val: 'super beta file',
255
+ info: {
256
+ nameTruncated: false,
257
+ valueTruncated: false,
258
+ encoding: '7bit',
259
+ mimeType: 'text/plain',
260
+ },
261
+ },
262
+ ],
263
+ events: ['field'],
264
+ what: 'Fields and (ignored) files'
265
+ },
266
+ { source: [
267
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
268
+ 'Content-Disposition: form-data; '
269
+ + 'name="upload_file_0"; filename="/tmp/1k_a.dat"',
270
+ 'Content-Type: application/octet-stream',
271
+ '',
272
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
273
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
274
+ 'Content-Disposition: form-data; '
275
+ + 'name="upload_file_1"; filename="C:\\files\\1k_b.dat"',
276
+ 'Content-Type: application/octet-stream',
277
+ '',
278
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
279
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
280
+ 'Content-Disposition: form-data; '
281
+ + 'name="upload_file_2"; filename="relative/1k_c.dat"',
282
+ 'Content-Type: application/octet-stream',
283
+ '',
284
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
285
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
286
+ ].join('\r\n')
287
+ ],
288
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
289
+ expected: [
290
+ { type: 'file',
291
+ name: 'upload_file_0',
292
+ data: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
293
+ info: {
294
+ filename: '1k_a.dat',
295
+ encoding: '7bit',
296
+ mimeType: 'application/octet-stream',
297
+ },
298
+ limited: false,
299
+ },
300
+ { type: 'file',
301
+ name: 'upload_file_1',
302
+ data: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
303
+ info: {
304
+ filename: '1k_b.dat',
305
+ encoding: '7bit',
306
+ mimeType: 'application/octet-stream',
307
+ },
308
+ limited: false,
309
+ },
310
+ { type: 'file',
311
+ name: 'upload_file_2',
312
+ data: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
313
+ info: {
314
+ filename: '1k_c.dat',
315
+ encoding: '7bit',
316
+ mimeType: 'application/octet-stream',
317
+ },
318
+ limited: false,
319
+ },
320
+ ],
321
+ what: 'Files with filenames containing paths'
322
+ },
323
+ { source: [
324
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
325
+ 'Content-Disposition: form-data; '
326
+ + 'name="upload_file_0"; filename="/absolute/1k_a.dat"',
327
+ 'Content-Type: application/octet-stream',
328
+ '',
329
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
330
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
331
+ 'Content-Disposition: form-data; '
332
+ + 'name="upload_file_1"; filename="C:\\absolute\\1k_b.dat"',
333
+ 'Content-Type: application/octet-stream',
334
+ '',
335
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
336
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
337
+ 'Content-Disposition: form-data; '
338
+ + 'name="upload_file_2"; filename="relative/1k_c.dat"',
339
+ 'Content-Type: application/octet-stream',
340
+ '',
341
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
342
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
343
+ ].join('\r\n')
344
+ ],
345
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
346
+ preservePath: true,
347
+ expected: [
348
+ { type: 'file',
349
+ name: 'upload_file_0',
350
+ data: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
351
+ info: {
352
+ filename: '/absolute/1k_a.dat',
353
+ encoding: '7bit',
354
+ mimeType: 'application/octet-stream',
355
+ },
356
+ limited: false,
357
+ },
358
+ { type: 'file',
359
+ name: 'upload_file_1',
360
+ data: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
361
+ info: {
362
+ filename: 'C:\\absolute\\1k_b.dat',
363
+ encoding: '7bit',
364
+ mimeType: 'application/octet-stream',
365
+ },
366
+ limited: false,
367
+ },
368
+ { type: 'file',
369
+ name: 'upload_file_2',
370
+ data: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
371
+ info: {
372
+ filename: 'relative/1k_c.dat',
373
+ encoding: '7bit',
374
+ mimeType: 'application/octet-stream',
375
+ },
376
+ limited: false,
377
+ },
378
+ ],
379
+ what: 'Paths to be preserved through the preservePath option'
380
+ },
381
+ { source: [
382
+ ['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
383
+ 'Content-Disposition: form-data; name="cont"',
384
+ 'Content-Type: ',
385
+ '',
386
+ 'some random content',
387
+ '------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
388
+ 'Content-Disposition: ',
389
+ '',
390
+ 'some random pass',
391
+ '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--'
392
+ ].join('\r\n')
393
+ ],
394
+ boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
395
+ expected: [
396
+ { type: 'field',
397
+ name: 'cont',
398
+ val: 'some random content',
399
+ info: {
400
+ nameTruncated: false,
401
+ valueTruncated: false,
402
+ encoding: '7bit',
403
+ mimeType: 'text/plain',
404
+ },
405
+ },
406
+ ],
407
+ what: 'Empty content-type and empty content-disposition'
408
+ },
409
+ { source: [
410
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
411
+ 'Content-Disposition: form-data; '
412
+ + 'name="file"; filename*=utf-8\'\'n%C3%A4me.txt',
413
+ 'Content-Type: application/octet-stream',
414
+ '',
415
+ 'ABCDEFGHIJKLMNOPQRSTUVWXYZ',
416
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--'
417
+ ].join('\r\n')
418
+ ],
419
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
420
+ expected: [
421
+ { type: 'file',
422
+ name: 'file',
423
+ data: Buffer.from('ABCDEFGHIJKLMNOPQRSTUVWXYZ'),
424
+ info: {
425
+ filename: 'näme.txt',
426
+ encoding: '7bit',
427
+ mimeType: 'application/octet-stream',
428
+ },
429
+ limited: false,
430
+ },
431
+ ],
432
+ what: 'Unicode filenames'
433
+ },
434
+ { source: [
435
+ ['--asdasdasdasd\r\n',
436
+ 'Content-Type: text/plain\r\n',
437
+ 'Content-Disposition: form-data; name="foo"\r\n',
438
+ '\r\n',
439
+ 'asd\r\n',
440
+ '--asdasdasdasd--'
441
+ ].join(':)')
442
+ ],
443
+ boundary: 'asdasdasdasd',
444
+ expected: [
445
+ { error: 'Malformed part header' },
446
+ { error: 'Unexpected end of form' },
447
+ ],
448
+ what: 'Stopped mid-header'
449
+ },
450
+ { source: [
451
+ ['------WebKitFormBoundaryTB2MiQ36fnSJlrhY',
452
+ 'Content-Disposition: form-data; name="cont"',
453
+ 'Content-Type: application/json',
454
+ '',
455
+ '{}',
456
+ '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--',
457
+ ].join('\r\n')
458
+ ],
459
+ boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
460
+ expected: [
461
+ { type: 'field',
462
+ name: 'cont',
463
+ val: '{}',
464
+ info: {
465
+ nameTruncated: false,
466
+ valueTruncated: false,
467
+ encoding: '7bit',
468
+ mimeType: 'application/json',
469
+ },
470
+ },
471
+ ],
472
+ what: 'content-type for fields'
473
+ },
474
+ { source: [
475
+ '------WebKitFormBoundaryTB2MiQ36fnSJlrhY--',
476
+ ],
477
+ boundary: '----WebKitFormBoundaryTB2MiQ36fnSJlrhY',
478
+ expected: [],
479
+ what: 'empty form'
480
+ },
481
+ { source: [
482
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
483
+ 'Content-Disposition: form-data; '
484
+ + 'name=upload_file_0; filename="1k_a.dat"',
485
+ 'Content-Type: application/octet-stream',
486
+ 'Content-Transfer-Encoding: binary',
487
+ '',
488
+ '',
489
+ ].join('\r\n')
490
+ ],
491
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
492
+ expected: [
493
+ { type: 'file',
494
+ name: 'upload_file_0',
495
+ data: Buffer.alloc(0),
496
+ info: {
497
+ filename: '1k_a.dat',
498
+ encoding: 'binary',
499
+ mimeType: 'application/octet-stream',
500
+ },
501
+ limited: false,
502
+ err: 'Unexpected end of form',
503
+ },
504
+ { error: 'Unexpected end of form' },
505
+ ],
506
+ what: 'Stopped mid-file #1'
507
+ },
508
+ { source: [
509
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
510
+ 'Content-Disposition: form-data; '
511
+ + 'name=upload_file_0; filename="1k_a.dat"',
512
+ 'Content-Type: application/octet-stream',
513
+ '',
514
+ 'a',
515
+ ].join('\r\n')
516
+ ],
517
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
518
+ expected: [
519
+ { type: 'file',
520
+ name: 'upload_file_0',
521
+ data: Buffer.from('a'),
522
+ info: {
523
+ filename: '1k_a.dat',
524
+ encoding: '7bit',
525
+ mimeType: 'application/octet-stream',
526
+ },
527
+ limited: false,
528
+ err: 'Unexpected end of form',
529
+ },
530
+ { error: 'Unexpected end of form' },
531
+ ],
532
+ what: 'Stopped mid-file #2'
533
+ },
534
+ { source: [
535
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
536
+ 'Content-Disposition: form-data; '
537
+ + 'name="upload_file_0"; filename="notes.txt"',
538
+ 'Content-Type: text/plain; charset=utf8',
539
+ '',
540
+ 'a',
541
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
542
+ ].join('\r\n')
543
+ ],
544
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
545
+ expected: [
546
+ { type: 'file',
547
+ name: 'upload_file_0',
548
+ data: Buffer.from('a'),
549
+ info: {
550
+ filename: 'notes.txt',
551
+ encoding: '7bit',
552
+ mimeType: 'text/plain',
553
+ },
554
+ limited: false,
555
+ },
556
+ ],
557
+ what: 'Text file with charset'
558
+ },
559
+ { source: [
560
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
561
+ 'Content-Disposition: form-data; '
562
+ + 'name="upload_file_0"; filename="notes.txt"',
563
+ 'Content-Type: ',
564
+ ' text/plain; charset=utf8',
565
+ '',
566
+ 'a',
567
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
568
+ ].join('\r\n')
569
+ ],
570
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
571
+ expected: [
572
+ { type: 'file',
573
+ name: 'upload_file_0',
574
+ data: Buffer.from('a'),
575
+ info: {
576
+ filename: 'notes.txt',
577
+ encoding: '7bit',
578
+ mimeType: 'text/plain',
579
+ },
580
+ limited: false,
581
+ },
582
+ ],
583
+ what: 'Folded header value'
584
+ },
585
+ { source: [
586
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
587
+ 'Content-Type: text/plain; charset=utf8',
588
+ '',
589
+ 'a',
590
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
591
+ ].join('\r\n')
592
+ ],
593
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
594
+ expected: [],
595
+ what: 'No Content-Disposition'
596
+ },
597
+ { source: [
598
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
599
+ 'Content-Disposition: form-data; name="file_name_0"',
600
+ '',
601
+ 'a'.repeat(64 * 1024),
602
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
603
+ 'Content-Disposition: form-data; '
604
+ + 'name="upload_file_0"; filename="notes.txt"',
605
+ 'Content-Type: ',
606
+ ' text/plain; charset=utf8',
607
+ '',
608
+ 'bc',
609
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
610
+ ].join('\r\n')
611
+ ],
612
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
613
+ limits: {
614
+ fieldSize: Infinity,
615
+ },
616
+ expected: [
617
+ { type: 'file',
618
+ name: 'upload_file_0',
619
+ data: Buffer.from('bc'),
620
+ info: {
621
+ filename: 'notes.txt',
622
+ encoding: '7bit',
623
+ mimeType: 'text/plain',
624
+ },
625
+ limited: false,
626
+ },
627
+ ],
628
+ events: [ 'file' ],
629
+ what: 'Skip field parts if no listener'
630
+ },
631
+ { source: [
632
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
633
+ 'Content-Disposition: form-data; name="file_name_0"',
634
+ '',
635
+ 'a',
636
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
637
+ 'Content-Disposition: form-data; '
638
+ + 'name="upload_file_0"; filename="notes.txt"',
639
+ 'Content-Type: ',
640
+ ' text/plain; charset=utf8',
641
+ '',
642
+ 'bc',
643
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
644
+ ].join('\r\n')
645
+ ],
646
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
647
+ limits: {
648
+ parts: 1,
649
+ },
650
+ expected: [
651
+ { type: 'field',
652
+ name: 'file_name_0',
653
+ val: 'a',
654
+ info: {
655
+ nameTruncated: false,
656
+ valueTruncated: false,
657
+ encoding: '7bit',
658
+ mimeType: 'text/plain',
659
+ },
660
+ },
661
+ 'partsLimit',
662
+ ],
663
+ what: 'Parts limit'
664
+ },
665
+ { source: [
666
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
667
+ 'Content-Disposition: form-data; name="file_name_0"',
668
+ '',
669
+ 'a',
670
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
671
+ 'Content-Disposition: form-data; name="file_name_1"',
672
+ '',
673
+ 'b',
674
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
675
+ ].join('\r\n')
676
+ ],
677
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
678
+ limits: {
679
+ fields: 1,
680
+ },
681
+ expected: [
682
+ { type: 'field',
683
+ name: 'file_name_0',
684
+ val: 'a',
685
+ info: {
686
+ nameTruncated: false,
687
+ valueTruncated: false,
688
+ encoding: '7bit',
689
+ mimeType: 'text/plain',
690
+ },
691
+ },
692
+ 'fieldsLimit',
693
+ ],
694
+ what: 'Fields limit'
695
+ },
696
+ { source: [
697
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
698
+ 'Content-Disposition: form-data; '
699
+ + 'name="upload_file_0"; filename="notes.txt"',
700
+ 'Content-Type: text/plain; charset=utf8',
701
+ '',
702
+ 'ab',
703
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
704
+ 'Content-Disposition: form-data; '
705
+ + 'name="upload_file_1"; filename="notes2.txt"',
706
+ 'Content-Type: text/plain; charset=utf8',
707
+ '',
708
+ 'cd',
709
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
710
+ ].join('\r\n')
711
+ ],
712
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
713
+ limits: {
714
+ files: 1,
715
+ },
716
+ expected: [
717
+ { type: 'file',
718
+ name: 'upload_file_0',
719
+ data: Buffer.from('ab'),
720
+ info: {
721
+ filename: 'notes.txt',
722
+ encoding: '7bit',
723
+ mimeType: 'text/plain',
724
+ },
725
+ limited: false,
726
+ },
727
+ 'filesLimit',
728
+ ],
729
+ what: 'Files limit'
730
+ },
731
+ { source: [
732
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
733
+ 'Content-Disposition: form-data; '
734
+ + `name="upload_file_0"; filename="${'a'.repeat(64 * 1024)}.txt"`,
735
+ 'Content-Type: text/plain; charset=utf8',
736
+ '',
737
+ 'ab',
738
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
739
+ 'Content-Disposition: form-data; '
740
+ + 'name="upload_file_1"; filename="notes2.txt"',
741
+ 'Content-Type: text/plain; charset=utf8',
742
+ '',
743
+ 'cd',
744
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
745
+ ].join('\r\n')
746
+ ],
747
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
748
+ expected: [
749
+ { error: 'Malformed part header' },
750
+ { type: 'file',
751
+ name: 'upload_file_1',
752
+ data: Buffer.from('cd'),
753
+ info: {
754
+ filename: 'notes2.txt',
755
+ encoding: '7bit',
756
+ mimeType: 'text/plain',
757
+ },
758
+ limited: false,
759
+ },
760
+ ],
761
+ what: 'Oversized part header'
762
+ },
763
+ { source: [
764
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
765
+ 'Content-Disposition: form-data; '
766
+ + 'name="upload_file_0"; filename="notes.txt"',
767
+ 'Content-Type: text/plain; charset=utf8',
768
+ '',
769
+ 'a'.repeat(31) + '\r',
770
+ ].join('\r\n'),
771
+ 'b'.repeat(40),
772
+ '\r\n-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
773
+ ],
774
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
775
+ fileHwm: 32,
776
+ expected: [
777
+ { type: 'file',
778
+ name: 'upload_file_0',
779
+ data: Buffer.from('a'.repeat(31) + '\r' + 'b'.repeat(40)),
780
+ info: {
781
+ filename: 'notes.txt',
782
+ encoding: '7bit',
783
+ mimeType: 'text/plain',
784
+ },
785
+ limited: false,
786
+ },
787
+ ],
788
+ what: 'Lookbehind data should not stall file streams'
789
+ },
790
+ { source: [
791
+ ['-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
792
+ 'Content-Disposition: form-data; '
793
+ + `name="upload_file_0"; filename="${'a'.repeat(8 * 1024)}.txt"`,
794
+ 'Content-Type: text/plain; charset=utf8',
795
+ '',
796
+ 'ab',
797
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
798
+ 'Content-Disposition: form-data; '
799
+ + `name="upload_file_1"; filename="${'b'.repeat(8 * 1024)}.txt"`,
800
+ 'Content-Type: text/plain; charset=utf8',
801
+ '',
802
+ 'cd',
803
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
804
+ 'Content-Disposition: form-data; '
805
+ + `name="upload_file_2"; filename="${'c'.repeat(8 * 1024)}.txt"`,
806
+ 'Content-Type: text/plain; charset=utf8',
807
+ '',
808
+ 'ef',
809
+ '-----------------------------paZqsnEHRufoShdX6fh0lUhXBP4k--',
810
+ ].join('\r\n')
811
+ ],
812
+ boundary: '---------------------------paZqsnEHRufoShdX6fh0lUhXBP4k',
813
+ expected: [
814
+ { type: 'file',
815
+ name: 'upload_file_0',
816
+ data: Buffer.from('ab'),
817
+ info: {
818
+ filename: `${'a'.repeat(8 * 1024)}.txt`,
819
+ encoding: '7bit',
820
+ mimeType: 'text/plain',
821
+ },
822
+ limited: false,
823
+ },
824
+ { type: 'file',
825
+ name: 'upload_file_1',
826
+ data: Buffer.from('cd'),
827
+ info: {
828
+ filename: `${'b'.repeat(8 * 1024)}.txt`,
829
+ encoding: '7bit',
830
+ mimeType: 'text/plain',
831
+ },
832
+ limited: false,
833
+ },
834
+ { type: 'file',
835
+ name: 'upload_file_2',
836
+ data: Buffer.from('ef'),
837
+ info: {
838
+ filename: `${'c'.repeat(8 * 1024)}.txt`,
839
+ encoding: '7bit',
840
+ mimeType: 'text/plain',
841
+ },
842
+ limited: false,
843
+ },
844
+ ],
845
+ what: 'Header size limit should be per part'
846
+ },
847
+ { source: [
848
+ '\r\n--d1bf46b3-aa33-4061-b28d-6c5ced8b08ee\r\n',
849
+ 'Content-Type: application/gzip\r\n'
850
+ + 'Content-Encoding: gzip\r\n'
851
+ + 'Content-Disposition: form-data; name=batch-1; filename=batch-1'
852
+ + '\r\n\r\n',
853
+ '\r\n--d1bf46b3-aa33-4061-b28d-6c5ced8b08ee--',
854
+ ],
855
+ boundary: 'd1bf46b3-aa33-4061-b28d-6c5ced8b08ee',
856
+ expected: [
857
+ { type: 'file',
858
+ name: 'batch-1',
859
+ data: Buffer.alloc(0),
860
+ info: {
861
+ filename: 'batch-1',
862
+ encoding: '7bit',
863
+ mimeType: 'application/gzip',
864
+ },
865
+ limited: false,
866
+ },
867
+ ],
868
+ what: 'Empty part'
869
+ },
870
+ ];
871
+
872
+ for (const test of tests) {
873
+ active.set(test, 1);
874
+
875
+ const { what, boundary, events, limits, preservePath, fileHwm } = test;
876
+ const bb = busboy({
877
+ fileHwm,
878
+ limits,
879
+ preservePath,
880
+ headers: {
881
+ 'content-type': `multipart/form-data; boundary=${boundary}`,
882
+ }
883
+ });
884
+ const results = [];
885
+
886
+ if (events === undefined || events.includes('field')) {
887
+ bb.on('field', (name, val, info) => {
888
+ results.push({ type: 'field', name, val, info });
889
+ });
890
+ }
891
+
892
+ if (events === undefined || events.includes('file')) {
893
+ bb.on('file', (name, stream, info) => {
894
+ const data = [];
895
+ let nb = 0;
896
+ const file = {
897
+ type: 'file',
898
+ name,
899
+ data: null,
900
+ info,
901
+ limited: false,
902
+ };
903
+ results.push(file);
904
+ stream.on('data', (d) => {
905
+ data.push(d);
906
+ nb += d.length;
907
+ }).on('limit', () => {
908
+ file.limited = true;
909
+ }).on('close', () => {
910
+ file.data = Buffer.concat(data, nb);
911
+ assert.strictEqual(stream.truncated, file.limited);
912
+ }).once('error', (err) => {
913
+ file.err = err.message;
914
+ });
915
+ });
916
+ }
917
+
918
+ bb.on('error', (err) => {
919
+ results.push({ error: err.message });
920
+ });
921
+
922
+ bb.on('partsLimit', () => {
923
+ results.push('partsLimit');
924
+ });
925
+
926
+ bb.on('filesLimit', () => {
927
+ results.push('filesLimit');
928
+ });
929
+
930
+ bb.on('fieldsLimit', () => {
931
+ results.push('fieldsLimit');
932
+ });
933
+
934
+ bb.on('close', () => {
935
+ active.delete(test);
936
+
937
+ assert.deepStrictEqual(
938
+ results,
939
+ test.expected,
940
+ `[${what}] Results mismatch.\n`
941
+ + `Parsed: ${inspect(results)}\n`
942
+ + `Expected: ${inspect(test.expected)}`
943
+ );
944
+ });
945
+
946
+ for (const src of test.source) {
947
+ const buf = (typeof src === 'string' ? Buffer.from(src, 'utf8') : src);
948
+ bb.write(buf);
949
+ }
950
+ bb.end();
951
+ }
952
+
953
+ // Byte-by-byte versions
954
+ for (let test of tests) {
955
+ test = { ...test };
956
+ test.what += ' (byte-by-byte)';
957
+ active.set(test, 1);
958
+
959
+ const { what, boundary, events, limits, preservePath, fileHwm } = test;
960
+ const bb = busboy({
961
+ fileHwm,
962
+ limits,
963
+ preservePath,
964
+ headers: {
965
+ 'content-type': `multipart/form-data; boundary=${boundary}`,
966
+ }
967
+ });
968
+ const results = [];
969
+
970
+ if (events === undefined || events.includes('field')) {
971
+ bb.on('field', (name, val, info) => {
972
+ results.push({ type: 'field', name, val, info });
973
+ });
974
+ }
975
+
976
+ if (events === undefined || events.includes('file')) {
977
+ bb.on('file', (name, stream, info) => {
978
+ const data = [];
979
+ let nb = 0;
980
+ const file = {
981
+ type: 'file',
982
+ name,
983
+ data: null,
984
+ info,
985
+ limited: false,
986
+ };
987
+ results.push(file);
988
+ stream.on('data', (d) => {
989
+ data.push(d);
990
+ nb += d.length;
991
+ }).on('limit', () => {
992
+ file.limited = true;
993
+ }).on('close', () => {
994
+ file.data = Buffer.concat(data, nb);
995
+ assert.strictEqual(stream.truncated, file.limited);
996
+ }).once('error', (err) => {
997
+ file.err = err.message;
998
+ });
999
+ });
1000
+ }
1001
+
1002
+ bb.on('error', (err) => {
1003
+ results.push({ error: err.message });
1004
+ });
1005
+
1006
+ bb.on('partsLimit', () => {
1007
+ results.push('partsLimit');
1008
+ });
1009
+
1010
+ bb.on('filesLimit', () => {
1011
+ results.push('filesLimit');
1012
+ });
1013
+
1014
+ bb.on('fieldsLimit', () => {
1015
+ results.push('fieldsLimit');
1016
+ });
1017
+
1018
+ bb.on('close', () => {
1019
+ active.delete(test);
1020
+
1021
+ assert.deepStrictEqual(
1022
+ results,
1023
+ test.expected,
1024
+ `[${what}] Results mismatch.\n`
1025
+ + `Parsed: ${inspect(results)}\n`
1026
+ + `Expected: ${inspect(test.expected)}`
1027
+ );
1028
+ });
1029
+
1030
+ for (const src of test.source) {
1031
+ const buf = (typeof src === 'string' ? Buffer.from(src, 'utf8') : src);
1032
+ for (let i = 0; i < buf.length; ++i)
1033
+ bb.write(buf.slice(i, i + 1));
1034
+ }
1035
+ bb.end();
1036
+ }
1037
+
1038
+ {
1039
+ let exception = false;
1040
+ process.once('uncaughtException', (ex) => {
1041
+ exception = true;
1042
+ throw ex;
1043
+ });
1044
+ process.on('exit', () => {
1045
+ if (exception || active.size === 0)
1046
+ return;
1047
+ process.exitCode = 1;
1048
+ console.error('==========================');
1049
+ console.error(`${active.size} test(s) did not finish:`);
1050
+ console.error('==========================');
1051
+ console.error(Array.from(active.keys()).map((v) => v.what).join('\n'));
1052
+ });
1053
+ }