payload 3.89.0 → 3.90.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 (459) hide show
  1. package/dist/admin/forms/Field.d.ts +2 -0
  2. package/dist/admin/forms/Field.d.ts.map +1 -1
  3. package/dist/admin/forms/Field.js.map +1 -1
  4. package/dist/admin/forms/Form.d.ts +2 -0
  5. package/dist/admin/forms/Form.d.ts.map +1 -1
  6. package/dist/admin/forms/Form.js.map +1 -1
  7. package/dist/admin/functions/index.d.ts +3 -1
  8. package/dist/admin/functions/index.d.ts.map +1 -1
  9. package/dist/admin/functions/index.js.map +1 -1
  10. package/dist/admin/views/dashboard.d.ts +1 -1
  11. package/dist/admin/views/dashboard.d.ts.map +1 -1
  12. package/dist/admin/views/dashboard.js.map +1 -1
  13. package/dist/auth/applyUserReadAccess.d.ts +15 -0
  14. package/dist/auth/applyUserReadAccess.d.ts.map +1 -0
  15. package/dist/auth/applyUserReadAccess.js +41 -0
  16. package/dist/auth/applyUserReadAccess.js.map +1 -0
  17. package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.d.ts +4 -0
  18. package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.d.ts.map +1 -0
  19. package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.js +20 -0
  20. package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.js.map +1 -0
  21. package/dist/auth/baseFields/apiKey/encryptAPIKey.d.ts +4 -0
  22. package/dist/auth/baseFields/apiKey/encryptAPIKey.d.ts.map +1 -0
  23. package/dist/auth/baseFields/apiKey/encryptAPIKey.js +16 -0
  24. package/dist/auth/baseFields/apiKey/encryptAPIKey.js.map +1 -0
  25. package/dist/auth/baseFields/apiKey/index.d.ts +6 -0
  26. package/dist/auth/baseFields/apiKey/index.d.ts.map +1 -0
  27. package/dist/auth/baseFields/apiKey/index.js +112 -0
  28. package/dist/auth/baseFields/apiKey/index.js.map +1 -0
  29. package/dist/auth/baseFields/apiKey/omitAPIKey.d.ts +4 -0
  30. package/dist/auth/baseFields/apiKey/omitAPIKey.d.ts.map +1 -0
  31. package/dist/auth/baseFields/apiKey/omitAPIKey.js +8 -0
  32. package/dist/auth/baseFields/apiKey/omitAPIKey.js.map +1 -0
  33. package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.d.ts +4 -0
  34. package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.d.ts.map +1 -0
  35. package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.js +5 -0
  36. package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.js.map +1 -0
  37. package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.d.ts +4 -0
  38. package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.d.ts.map +1 -0
  39. package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.js +5 -0
  40. package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.js.map +1 -0
  41. package/dist/auth/baseFields/apiKey/setAPIKeyIndex.d.ts +4 -0
  42. package/dist/auth/baseFields/apiKey/setAPIKeyIndex.d.ts.map +1 -0
  43. package/dist/auth/baseFields/apiKey/setAPIKeyIndex.js +17 -0
  44. package/dist/auth/baseFields/apiKey/setAPIKeyIndex.js.map +1 -0
  45. package/dist/auth/baseFields/auth.d.ts +1 -0
  46. package/dist/auth/baseFields/auth.d.ts.map +1 -1
  47. package/dist/auth/baseFields/auth.js +9 -0
  48. package/dist/auth/baseFields/auth.js.map +1 -1
  49. package/dist/auth/defaultUnlockAccess.d.ts +3 -0
  50. package/dist/auth/defaultUnlockAccess.d.ts.map +1 -0
  51. package/dist/auth/defaultUnlockAccess.js +8 -0
  52. package/dist/auth/defaultUnlockAccess.js.map +1 -0
  53. package/dist/auth/endpoints/index.d.ts +1 -0
  54. package/dist/auth/endpoints/index.d.ts.map +1 -1
  55. package/dist/auth/endpoints/index.js +8 -0
  56. package/dist/auth/endpoints/index.js.map +1 -1
  57. package/dist/auth/endpoints/revealAPIKey.d.ts +7 -0
  58. package/dist/auth/endpoints/revealAPIKey.d.ts.map +1 -0
  59. package/dist/auth/endpoints/revealAPIKey.js +120 -0
  60. package/dist/auth/endpoints/revealAPIKey.js.map +1 -0
  61. package/dist/auth/executeAccess.d.ts +3 -1
  62. package/dist/auth/executeAccess.d.ts.map +1 -1
  63. package/dist/auth/executeAccess.js +2 -1
  64. package/dist/auth/executeAccess.js.map +1 -1
  65. package/dist/auth/getAuthFields.d.ts +1 -1
  66. package/dist/auth/getAuthFields.d.ts.map +1 -1
  67. package/dist/auth/getAuthFields.js +7 -4
  68. package/dist/auth/getAuthFields.js.map +1 -1
  69. package/dist/auth/getFieldsToSign.d.ts.map +1 -1
  70. package/dist/auth/getFieldsToSign.js +17 -10
  71. package/dist/auth/getFieldsToSign.js.map +1 -1
  72. package/dist/auth/getFieldsToSign.spec.js +114 -0
  73. package/dist/auth/getFieldsToSign.spec.js.map +1 -0
  74. package/dist/auth/jwt.d.ts.map +1 -1
  75. package/dist/auth/jwt.js +2 -0
  76. package/dist/auth/jwt.js.map +1 -1
  77. package/dist/auth/jwt.spec.js +24 -0
  78. package/dist/auth/jwt.spec.js.map +1 -0
  79. package/dist/auth/jwtAuth.d.ts +9 -0
  80. package/dist/auth/jwtAuth.d.ts.map +1 -0
  81. package/dist/auth/jwtAuth.js +8 -0
  82. package/dist/auth/jwtAuth.js.map +1 -0
  83. package/dist/auth/operations/auth.d.ts.map +1 -1
  84. package/dist/auth/operations/auth.js +2 -1
  85. package/dist/auth/operations/auth.js.map +1 -1
  86. package/dist/auth/operations/forgotPassword.d.ts.map +1 -1
  87. package/dist/auth/operations/forgotPassword.js +95 -7
  88. package/dist/auth/operations/forgotPassword.js.map +1 -1
  89. package/dist/auth/operations/local/auth.js +3 -1
  90. package/dist/auth/operations/local/auth.js.map +1 -1
  91. package/dist/auth/operations/login.d.ts.map +1 -1
  92. package/dist/auth/operations/login.js +48 -26
  93. package/dist/auth/operations/login.js.map +1 -1
  94. package/dist/auth/operations/refresh.d.ts.map +1 -1
  95. package/dist/auth/operations/refresh.js +32 -9
  96. package/dist/auth/operations/refresh.js.map +1 -1
  97. package/dist/auth/operations/registerFirstUser.d.ts.map +1 -1
  98. package/dist/auth/operations/registerFirstUser.js +3 -4
  99. package/dist/auth/operations/registerFirstUser.js.map +1 -1
  100. package/dist/auth/operations/resetPassword.d.ts.map +1 -1
  101. package/dist/auth/operations/resetPassword.js +31 -22
  102. package/dist/auth/operations/resetPassword.js.map +1 -1
  103. package/dist/auth/operations/unlock.d.ts.map +1 -1
  104. package/dist/auth/operations/unlock.js +1 -0
  105. package/dist/auth/operations/unlock.js.map +1 -1
  106. package/dist/auth/strategies/apiKey.d.ts.map +1 -1
  107. package/dist/auth/strategies/apiKey.js +15 -1
  108. package/dist/auth/strategies/apiKey.js.map +1 -1
  109. package/dist/auth/strategies/jwt.d.ts.map +1 -1
  110. package/dist/auth/strategies/jwt.js +61 -10
  111. package/dist/auth/strategies/jwt.js.map +1 -1
  112. package/dist/auth/strategies/jwt.spec.js +281 -0
  113. package/dist/auth/strategies/jwt.spec.js.map +1 -0
  114. package/dist/auth/strategies/local/authenticate.d.ts +5 -1
  115. package/dist/auth/strategies/local/authenticate.d.ts.map +1 -1
  116. package/dist/auth/strategies/local/authenticate.js +8 -3
  117. package/dist/auth/strategies/local/authenticate.js.map +1 -1
  118. package/dist/auth/strategies/local/authenticate.spec.js +37 -10
  119. package/dist/auth/strategies/local/authenticate.spec.js.map +1 -1
  120. package/dist/auth/strategies/local/generatePasswordSaltHash.d.ts +9 -1
  121. package/dist/auth/strategies/local/generatePasswordSaltHash.d.ts.map +1 -1
  122. package/dist/auth/strategies/local/generatePasswordSaltHash.js +61 -34
  123. package/dist/auth/strategies/local/generatePasswordSaltHash.js.map +1 -1
  124. package/dist/auth/types.d.ts +16 -1
  125. package/dist/auth/types.d.ts.map +1 -1
  126. package/dist/auth/types.js.map +1 -1
  127. package/dist/collections/config/client.d.ts +1 -0
  128. package/dist/collections/config/client.d.ts.map +1 -1
  129. package/dist/collections/config/client.js +3 -0
  130. package/dist/collections/config/client.js.map +1 -1
  131. package/dist/collections/config/defaults.d.ts.map +1 -1
  132. package/dist/collections/config/defaults.js +4 -2
  133. package/dist/collections/config/defaults.js.map +1 -1
  134. package/dist/collections/config/sanitize.d.ts.map +1 -1
  135. package/dist/collections/config/sanitize.js +17 -6
  136. package/dist/collections/config/sanitize.js.map +1 -1
  137. package/dist/collections/endpoints/index.d.ts +1 -0
  138. package/dist/collections/endpoints/index.d.ts.map +1 -1
  139. package/dist/collections/endpoints/index.js +6 -5
  140. package/dist/collections/endpoints/index.js.map +1 -1
  141. package/dist/collections/operations/create.d.ts.map +1 -1
  142. package/dist/collections/operations/create.js +105 -8
  143. package/dist/collections/operations/create.js.map +1 -1
  144. package/dist/collections/operations/deleteByID.js +13 -13
  145. package/dist/collections/operations/deleteByID.js.map +1 -1
  146. package/dist/collections/operations/findDistinct.d.ts.map +1 -1
  147. package/dist/collections/operations/findDistinct.js +96 -18
  148. package/dist/collections/operations/findDistinct.js.map +1 -1
  149. package/dist/collections/operations/restoreVersion.d.ts.map +1 -1
  150. package/dist/collections/operations/restoreVersion.js +47 -13
  151. package/dist/collections/operations/restoreVersion.js.map +1 -1
  152. package/dist/collections/operations/update.d.ts.map +1 -1
  153. package/dist/collections/operations/update.js +118 -18
  154. package/dist/collections/operations/update.js.map +1 -1
  155. package/dist/collections/operations/updateByID.d.ts.map +1 -1
  156. package/dist/collections/operations/updateByID.js +62 -2
  157. package/dist/collections/operations/updateByID.js.map +1 -1
  158. package/dist/collections/operations/utilities/update.d.ts.map +1 -1
  159. package/dist/collections/operations/utilities/update.js +71 -15
  160. package/dist/collections/operations/utilities/update.js.map +1 -1
  161. package/dist/config/orderable/index.d.ts.map +1 -1
  162. package/dist/config/orderable/index.js +67 -14
  163. package/dist/config/orderable/index.js.map +1 -1
  164. package/dist/config/sanitize.d.ts.map +1 -1
  165. package/dist/config/sanitize.js +1 -1
  166. package/dist/config/sanitize.js.map +1 -1
  167. package/dist/config/types.d.ts +13 -1
  168. package/dist/config/types.d.ts.map +1 -1
  169. package/dist/config/types.js.map +1 -1
  170. package/dist/database/getLocalizedPaths.d.ts +2 -1
  171. package/dist/database/getLocalizedPaths.d.ts.map +1 -1
  172. package/dist/database/getLocalizedPaths.js +12 -3
  173. package/dist/database/getLocalizedPaths.js.map +1 -1
  174. package/dist/database/isNestedRelationshipQuery.d.ts +9 -0
  175. package/dist/database/isNestedRelationshipQuery.d.ts.map +1 -0
  176. package/dist/database/isNestedRelationshipQuery.js +14 -0
  177. package/dist/database/isNestedRelationshipQuery.js.map +1 -0
  178. package/dist/database/prefixWherePaths.d.ts +6 -0
  179. package/dist/database/prefixWherePaths.d.ts.map +1 -0
  180. package/dist/database/prefixWherePaths.js +19 -0
  181. package/dist/database/prefixWherePaths.js.map +1 -0
  182. package/dist/database/prefixWherePaths.spec.js +46 -0
  183. package/dist/database/prefixWherePaths.spec.js.map +1 -0
  184. package/dist/database/queryValidation/validateQueryPaths.d.ts +2 -1
  185. package/dist/database/queryValidation/validateQueryPaths.d.ts.map +1 -1
  186. package/dist/database/queryValidation/validateQueryPaths.js +4 -1
  187. package/dist/database/queryValidation/validateQueryPaths.js.map +1 -1
  188. package/dist/database/queryValidation/validateSearchParams.d.ts +2 -1
  189. package/dist/database/queryValidation/validateSearchParams.d.ts.map +1 -1
  190. package/dist/database/queryValidation/validateSearchParams.js +87 -4
  191. package/dist/database/queryValidation/validateSearchParams.js.map +1 -1
  192. package/dist/database/types.d.ts +5 -0
  193. package/dist/database/types.d.ts.map +1 -1
  194. package/dist/database/types.js.map +1 -1
  195. package/dist/email/normalizeSendEmailOptions.js.map +1 -1
  196. package/dist/email/types.d.ts +4 -1
  197. package/dist/email/types.d.ts.map +1 -1
  198. package/dist/email/types.js.map +1 -1
  199. package/dist/exports/internal.d.ts +7 -0
  200. package/dist/exports/internal.d.ts.map +1 -1
  201. package/dist/exports/internal.js +7 -1
  202. package/dist/exports/internal.js.map +1 -1
  203. package/dist/exports/shared.d.ts +3 -0
  204. package/dist/exports/shared.d.ts.map +1 -1
  205. package/dist/exports/shared.js +3 -0
  206. package/dist/exports/shared.js.map +1 -1
  207. package/dist/fields/config/types.d.ts +7 -5
  208. package/dist/fields/config/types.d.ts.map +1 -1
  209. package/dist/fields/config/types.js.map +1 -1
  210. package/dist/fields/hooks/beforeChange/index.d.ts +7 -1
  211. package/dist/fields/hooks/beforeChange/index.d.ts.map +1 -1
  212. package/dist/fields/hooks/beforeChange/index.js +4 -2
  213. package/dist/fields/hooks/beforeChange/index.js.map +1 -1
  214. package/dist/fields/hooks/beforeChange/index.spec.js +206 -0
  215. package/dist/fields/hooks/beforeChange/index.spec.js.map +1 -0
  216. package/dist/fields/hooks/beforeChange/promise.d.ts +2 -1
  217. package/dist/fields/hooks/beforeChange/promise.d.ts.map +1 -1
  218. package/dist/fields/hooks/beforeChange/promise.js +51 -9
  219. package/dist/fields/hooks/beforeChange/promise.js.map +1 -1
  220. package/dist/fields/hooks/beforeChange/traverseFields.d.ts +2 -1
  221. package/dist/fields/hooks/beforeChange/traverseFields.d.ts.map +1 -1
  222. package/dist/fields/hooks/beforeChange/traverseFields.js +3 -2
  223. package/dist/fields/hooks/beforeChange/traverseFields.js.map +1 -1
  224. package/dist/fields/hooks/beforeDuplicate/promise.d.ts.map +1 -1
  225. package/dist/fields/hooks/beforeDuplicate/promise.js +4 -0
  226. package/dist/fields/hooks/beforeDuplicate/promise.js.map +1 -1
  227. package/dist/fields/hooks/beforeValidate/getFallbackValue.d.ts +2 -1
  228. package/dist/fields/hooks/beforeValidate/getFallbackValue.d.ts.map +1 -1
  229. package/dist/fields/hooks/beforeValidate/getFallbackValue.js +2 -2
  230. package/dist/fields/hooks/beforeValidate/getFallbackValue.js.map +1 -1
  231. package/dist/fields/hooks/beforeValidate/index.d.ts +6 -1
  232. package/dist/fields/hooks/beforeValidate/index.d.ts.map +1 -1
  233. package/dist/fields/hooks/beforeValidate/index.js +3 -1
  234. package/dist/fields/hooks/beforeValidate/index.js.map +1 -1
  235. package/dist/fields/hooks/beforeValidate/index.spec.js +90 -0
  236. package/dist/fields/hooks/beforeValidate/index.spec.js.map +1 -0
  237. package/dist/fields/hooks/beforeValidate/promise.d.ts +6 -1
  238. package/dist/fields/hooks/beforeValidate/promise.d.ts.map +1 -1
  239. package/dist/fields/hooks/beforeValidate/promise.js +23 -8
  240. package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
  241. package/dist/fields/hooks/beforeValidate/traverseFields.d.ts +6 -1
  242. package/dist/fields/hooks/beforeValidate/traverseFields.d.ts.map +1 -1
  243. package/dist/fields/hooks/beforeValidate/traverseFields.js +3 -1
  244. package/dist/fields/hooks/beforeValidate/traverseFields.js.map +1 -1
  245. package/dist/fields/validations.d.ts.map +1 -1
  246. package/dist/fields/validations.js +3 -1
  247. package/dist/fields/validations.js.map +1 -1
  248. package/dist/globals/operations/restoreVersion.d.ts.map +1 -1
  249. package/dist/globals/operations/restoreVersion.js +45 -11
  250. package/dist/globals/operations/restoreVersion.js.map +1 -1
  251. package/dist/globals/operations/update.d.ts.map +1 -1
  252. package/dist/globals/operations/update.js +95 -16
  253. package/dist/globals/operations/update.js.map +1 -1
  254. package/dist/index.bundled.d.ts +102 -24
  255. package/dist/index.d.ts +3 -1
  256. package/dist/index.d.ts.map +1 -1
  257. package/dist/index.js +2 -2
  258. package/dist/index.js.map +1 -1
  259. package/dist/preferences/config.d.ts.map +1 -1
  260. package/dist/preferences/config.js +2 -1
  261. package/dist/preferences/config.js.map +1 -1
  262. package/dist/query-presets/access.d.ts.map +1 -1
  263. package/dist/query-presets/access.js +2 -1
  264. package/dist/query-presets/access.js.map +1 -1
  265. package/dist/queues/config/types/index.d.ts +2 -1
  266. package/dist/queues/config/types/index.d.ts.map +1 -1
  267. package/dist/queues/config/types/index.js.map +1 -1
  268. package/dist/uploads/assertClientUploadAccess.d.ts +7 -0
  269. package/dist/uploads/assertClientUploadAccess.d.ts.map +1 -0
  270. package/dist/uploads/assertClientUploadAccess.js +27 -0
  271. package/dist/uploads/assertClientUploadAccess.js.map +1 -0
  272. package/dist/uploads/assertClientUploadAllowed.d.ts +11 -0
  273. package/dist/uploads/assertClientUploadAllowed.d.ts.map +1 -0
  274. package/dist/uploads/assertClientUploadAllowed.js +46 -0
  275. package/dist/uploads/assertClientUploadAllowed.js.map +1 -0
  276. package/dist/uploads/assertClientUploadAllowed.spec.js +91 -0
  277. package/dist/uploads/assertClientUploadAllowed.spec.js.map +1 -0
  278. package/dist/uploads/checkFileRestrictions.d.ts +4 -1
  279. package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
  280. package/dist/uploads/checkFileRestrictions.js +66 -26
  281. package/dist/uploads/checkFileRestrictions.js.map +1 -1
  282. package/dist/uploads/clientUploadReceipt.d.ts +23 -0
  283. package/dist/uploads/clientUploadReceipt.d.ts.map +1 -0
  284. package/dist/uploads/clientUploadReceipt.js +55 -0
  285. package/dist/uploads/clientUploadReceipt.js.map +1 -0
  286. package/dist/uploads/deleteAssociatedFiles.d.ts.map +1 -1
  287. package/dist/uploads/deleteAssociatedFiles.js +33 -8
  288. package/dist/uploads/deleteAssociatedFiles.js.map +1 -1
  289. package/dist/uploads/deleteAssociatedFiles.spec.js +124 -0
  290. package/dist/uploads/deleteAssociatedFiles.spec.js.map +1 -0
  291. package/dist/uploads/detectSvgFromXml.d.ts +1 -3
  292. package/dist/uploads/detectSvgFromXml.d.ts.map +1 -1
  293. package/dist/uploads/detectSvgFromXml.js +3 -40
  294. package/dist/uploads/detectSvgFromXml.js.map +1 -1
  295. package/dist/uploads/endpoints/getFile.d.ts.map +1 -1
  296. package/dist/uploads/endpoints/getFile.js +5 -3
  297. package/dist/uploads/endpoints/getFile.js.map +1 -1
  298. package/dist/uploads/fetchAPI-multipart/handlers.d.ts +2 -2
  299. package/dist/uploads/fetchAPI-multipart/handlers.d.ts.map +1 -1
  300. package/dist/uploads/fetchAPI-multipart/handlers.js +18 -5
  301. package/dist/uploads/fetchAPI-multipart/handlers.js.map +1 -1
  302. package/dist/uploads/fetchAPI-multipart/index.d.ts.map +1 -1
  303. package/dist/uploads/fetchAPI-multipart/index.js +24 -2
  304. package/dist/uploads/fetchAPI-multipart/index.js.map +1 -1
  305. package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts +0 -6
  306. package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts.map +1 -1
  307. package/dist/uploads/fetchAPI-multipart/processMultipart.js +146 -126
  308. package/dist/uploads/fetchAPI-multipart/processMultipart.js.map +1 -1
  309. package/dist/uploads/fetchAPI-multipart/processMultipart.spec.js +663 -0
  310. package/dist/uploads/fetchAPI-multipart/processMultipart.spec.js.map +1 -0
  311. package/dist/uploads/generateFileData.d.ts +3 -1
  312. package/dist/uploads/generateFileData.d.ts.map +1 -1
  313. package/dist/uploads/generateFileData.js +29 -16
  314. package/dist/uploads/generateFileData.js.map +1 -1
  315. package/dist/uploads/getBaseFields.d.ts.map +1 -1
  316. package/dist/uploads/getBaseFields.js +3 -1
  317. package/dist/uploads/getBaseFields.js.map +1 -1
  318. package/dist/uploads/getExternalFile.d.ts +1 -1
  319. package/dist/uploads/getExternalFile.d.ts.map +1 -1
  320. package/dist/uploads/getExternalFile.js +60 -15
  321. package/dist/uploads/getExternalFile.js.map +1 -1
  322. package/dist/uploads/getFileTypeFallback.d.ts.map +1 -1
  323. package/dist/uploads/getFileTypeFallback.js +3 -1
  324. package/dist/uploads/getFileTypeFallback.js.map +1 -1
  325. package/dist/uploads/getFileTypeIdentity.d.ts +19 -0
  326. package/dist/uploads/getFileTypeIdentity.d.ts.map +1 -0
  327. package/dist/uploads/getFileTypeIdentity.js +34 -0
  328. package/dist/uploads/getFileTypeIdentity.js.map +1 -0
  329. package/dist/uploads/getFileTypeIdentity.spec.js +43 -0
  330. package/dist/uploads/getFileTypeIdentity.spec.js.map +1 -0
  331. package/dist/uploads/isProcessableImage.d.ts +2 -0
  332. package/dist/uploads/isProcessableImage.d.ts.map +1 -0
  333. package/dist/uploads/isProcessableImage.js +7 -0
  334. package/dist/uploads/isProcessableImage.js.map +1 -0
  335. package/dist/uploads/safeFetch.d.ts.map +1 -1
  336. package/dist/uploads/safeFetch.js +3 -2
  337. package/dist/uploads/safeFetch.js.map +1 -1
  338. package/dist/uploads/sanitizeUploadData.d.ts +26 -0
  339. package/dist/uploads/sanitizeUploadData.d.ts.map +1 -0
  340. package/dist/uploads/sanitizeUploadData.js +159 -0
  341. package/dist/uploads/sanitizeUploadData.js.map +1 -0
  342. package/dist/uploads/sanitizeUploadData.spec.js +255 -0
  343. package/dist/uploads/sanitizeUploadData.spec.js.map +1 -0
  344. package/dist/uploads/types.d.ts +11 -3
  345. package/dist/uploads/types.d.ts.map +1 -1
  346. package/dist/uploads/types.js.map +1 -1
  347. package/dist/uploads/uploadContentSecurityPolicy.d.ts +2 -0
  348. package/dist/uploads/uploadContentSecurityPolicy.d.ts.map +1 -0
  349. package/dist/uploads/uploadContentSecurityPolicy.js +3 -0
  350. package/dist/uploads/uploadContentSecurityPolicy.js.map +1 -0
  351. package/dist/uploads/validateISOBaseMediaFile.d.ts +4 -0
  352. package/dist/uploads/validateISOBaseMediaFile.d.ts.map +1 -0
  353. package/dist/uploads/validateISOBaseMediaFile.js +91 -0
  354. package/dist/uploads/validateISOBaseMediaFile.js.map +1 -0
  355. package/dist/uploads/validateISOBaseMediaFile.spec.js +130 -0
  356. package/dist/uploads/validateISOBaseMediaFile.spec.js.map +1 -0
  357. package/dist/uploads/validateSvg.d.ts +10 -4
  358. package/dist/uploads/validateSvg.d.ts.map +1 -1
  359. package/dist/uploads/validateSvg.js +280 -40
  360. package/dist/uploads/validateSvg.js.map +1 -1
  361. package/dist/uploads/validateSvg.spec.js +123 -0
  362. package/dist/uploads/validateSvg.spec.js.map +1 -0
  363. package/dist/uploads/validateUploadFilename.d.ts +3 -0
  364. package/dist/uploads/validateUploadFilename.d.ts.map +1 -0
  365. package/dist/uploads/validateUploadFilename.js +13 -0
  366. package/dist/uploads/validateUploadFilename.js.map +1 -0
  367. package/dist/uploads/validateUploadFilename.spec.js +24 -0
  368. package/dist/uploads/validateUploadFilename.spec.js.map +1 -0
  369. package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
  370. package/dist/utilities/addDataAndFileToRequest.js +28 -1
  371. package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
  372. package/dist/utilities/addDataAndFileToRequest.spec.js +158 -0
  373. package/dist/utilities/addDataAndFileToRequest.spec.js.map +1 -1
  374. package/dist/utilities/createPayloadRequest.d.ts.map +1 -1
  375. package/dist/utilities/createPayloadRequest.js +2 -1
  376. package/dist/utilities/createPayloadRequest.js.map +1 -1
  377. package/dist/utilities/deepCopyObject.d.ts.map +1 -1
  378. package/dist/utilities/deepCopyObject.js +110 -19
  379. package/dist/utilities/deepCopyObject.js.map +1 -1
  380. package/dist/utilities/deepCopyObject.spec.js +216 -0
  381. package/dist/utilities/deepCopyObject.spec.js.map +1 -0
  382. package/dist/utilities/fieldPath.d.ts +13 -0
  383. package/dist/utilities/fieldPath.d.ts.map +1 -0
  384. package/dist/utilities/fieldPath.js +51 -0
  385. package/dist/utilities/fieldPath.js.map +1 -0
  386. package/dist/utilities/fieldPath.spec.js +155 -0
  387. package/dist/utilities/fieldPath.spec.js.map +1 -0
  388. package/dist/utilities/getEntityPermissions/getEntityPermissions.d.ts.map +1 -1
  389. package/dist/utilities/getEntityPermissions/getEntityPermissions.js +2 -0
  390. package/dist/utilities/getEntityPermissions/getEntityPermissions.js.map +1 -1
  391. package/dist/utilities/getObjectDotNotation.d.ts.map +1 -1
  392. package/dist/utilities/getObjectDotNotation.js +7 -1
  393. package/dist/utilities/getObjectDotNotation.js.map +1 -1
  394. package/dist/utilities/getObjectDotNotation.spec.js +33 -0
  395. package/dist/utilities/getObjectDotNotation.spec.js.map +1 -0
  396. package/dist/utilities/getSafeRedirect.spec.js +14 -0
  397. package/dist/utilities/getSafeRedirect.spec.js.map +1 -1
  398. package/dist/utilities/getTopLevelFieldNames.d.ts +2 -0
  399. package/dist/utilities/getTopLevelFieldNames.d.ts.map +1 -0
  400. package/dist/utilities/getTopLevelFieldNames.js +3 -0
  401. package/dist/utilities/getTopLevelFieldNames.js.map +1 -0
  402. package/dist/utilities/getTopLevelFieldNames.spec.js +18 -0
  403. package/dist/utilities/getTopLevelFieldNames.spec.js.map +1 -0
  404. package/dist/utilities/handleEndpoints.js +1 -1
  405. package/dist/utilities/handleEndpoints.js.map +1 -1
  406. package/dist/utilities/parseParams/index.d.ts.map +1 -1
  407. package/dist/utilities/parseParams/index.js +3 -1
  408. package/dist/utilities/parseParams/index.js.map +1 -1
  409. package/dist/utilities/parseParams/index.spec.js +8 -0
  410. package/dist/utilities/parseParams/index.spec.js.map +1 -1
  411. package/dist/utilities/telemetry/featureInfo/getFeatureInfo.d.ts +4 -0
  412. package/dist/utilities/telemetry/featureInfo/getFeatureInfo.d.ts.map +1 -0
  413. package/dist/utilities/telemetry/featureInfo/getFeatureInfo.js +248 -0
  414. package/dist/utilities/telemetry/featureInfo/getFeatureInfo.js.map +1 -0
  415. package/dist/utilities/telemetry/featureInfo/types.d.ts +62 -0
  416. package/dist/utilities/telemetry/featureInfo/types.d.ts.map +1 -0
  417. package/dist/utilities/telemetry/featureInfo/types.js +3 -0
  418. package/dist/utilities/telemetry/featureInfo/types.js.map +1 -0
  419. package/dist/utilities/telemetry/getProjectContext.d.ts +14 -0
  420. package/dist/utilities/telemetry/getProjectContext.d.ts.map +1 -0
  421. package/dist/utilities/telemetry/getProjectContext.js +36 -0
  422. package/dist/utilities/telemetry/getProjectContext.js.map +1 -0
  423. package/dist/utilities/telemetry/index.d.ts +7 -1
  424. package/dist/utilities/telemetry/index.d.ts.map +1 -1
  425. package/dist/utilities/telemetry/index.js +22 -0
  426. package/dist/utilities/telemetry/index.js.map +1 -1
  427. package/dist/utilities/traverseFields.d.ts.map +1 -1
  428. package/dist/utilities/traverseFields.js +5 -14
  429. package/dist/utilities/traverseFields.js.map +1 -1
  430. package/dist/utilities/unflatten.d.ts.map +1 -1
  431. package/dist/utilities/unflatten.js +21 -9
  432. package/dist/utilities/unflatten.js.map +1 -1
  433. package/dist/utilities/unflatten.spec.js +38 -0
  434. package/dist/utilities/unflatten.spec.js.map +1 -0
  435. package/dist/versions/allLocalesPublicationStatus.d.ts +38 -0
  436. package/dist/versions/allLocalesPublicationStatus.d.ts.map +1 -0
  437. package/dist/versions/allLocalesPublicationStatus.js +57 -0
  438. package/dist/versions/allLocalesPublicationStatus.js.map +1 -0
  439. package/dist/versions/getLatestGlobalVersion.d.ts.map +1 -1
  440. package/dist/versions/getLatestGlobalVersion.js +10 -2
  441. package/dist/versions/getLatestGlobalVersion.js.map +1 -1
  442. package/dist/versions/getRestoredStatusesToAuthorize.d.ts +9 -0
  443. package/dist/versions/getRestoredStatusesToAuthorize.d.ts.map +1 -0
  444. package/dist/versions/getRestoredStatusesToAuthorize.js +22 -0
  445. package/dist/versions/getRestoredStatusesToAuthorize.js.map +1 -0
  446. package/dist/versions/getRestoredStatusesToAuthorize.spec.js +50 -0
  447. package/dist/versions/getRestoredStatusesToAuthorize.spec.js.map +1 -0
  448. package/dist/versions/schedule/job.d.ts +2 -2
  449. package/dist/versions/schedule/job.d.ts.map +1 -1
  450. package/dist/versions/schedule/job.js +11 -7
  451. package/dist/versions/schedule/job.js.map +1 -1
  452. package/dist/versions/schedule/types.d.ts +5 -1
  453. package/dist/versions/schedule/types.d.ts.map +1 -1
  454. package/dist/versions/schedule/types.js.map +1 -1
  455. package/package.json +4 -2
  456. package/dist/auth/baseFields/apiKey.d.ts +0 -3
  457. package/dist/auth/baseFields/apiKey.d.ts.map +0 -1
  458. package/dist/auth/baseFields/apiKey.js +0 -59
  459. package/dist/auth/baseFields/apiKey.js.map +0 -1
@@ -2,14 +2,22 @@ import { APIError } from '../../errors/APIError.js';
2
2
  import { isEligibleRequest } from './isEligibleRequest.js';
3
3
  import { processMultipart } from './processMultipart.js';
4
4
  import { debugLog } from './utilities.js';
5
+ const DEFAULT_REQUEST_SIZE_LIMIT = 50 * 1024 * 1024;
5
6
  const DEFAULT_UPLOAD_OPTIONS = {
6
- abortOnLimit: false,
7
+ abortOnLimit: true,
7
8
  createParentPath: false,
8
9
  debug: false,
9
10
  defParamCharset: 'utf8',
10
11
  limitHandler: false,
12
+ limits: {
13
+ fields: 20,
14
+ fieldSize: 1024 * 1024,
15
+ files: 3,
16
+ fileSize: 20 * 1024 * 1024
17
+ },
11
18
  parseNested: false,
12
19
  preserveExtension: false,
20
+ requestSizeLimit: DEFAULT_REQUEST_SIZE_LIMIT,
13
21
  responseOnLimit: 'File size limit has been reached',
14
22
  safeFileNames: false,
15
23
  tempFileDir: 'tmp',
@@ -18,10 +26,24 @@ const DEFAULT_UPLOAD_OPTIONS = {
18
26
  useTempFiles: false
19
27
  };
20
28
  export const processMultipartFormdata = async ({ options: incomingOptions, request })=>{
29
+ const requestSizeLimit = incomingOptions?.requestSizeLimit === undefined ? DEFAULT_REQUEST_SIZE_LIMIT : incomingOptions.requestSizeLimit;
30
+ if (requestSizeLimit !== Infinity && (!Number.isSafeInteger(requestSizeLimit) || requestSizeLimit < 0)) {
31
+ throw new TypeError('requestSizeLimit must be Infinity or a non-negative safe integer representing bytes');
32
+ }
21
33
  const options = {
22
34
  ...DEFAULT_UPLOAD_OPTIONS,
23
- ...incomingOptions
35
+ ...incomingOptions,
36
+ abortOnLimit: incomingOptions?.abortOnLimit ?? DEFAULT_UPLOAD_OPTIONS.abortOnLimit,
37
+ limits: {
38
+ ...DEFAULT_UPLOAD_OPTIONS.limits
39
+ },
40
+ requestSizeLimit
24
41
  };
42
+ for (const [key, value] of Object.entries(incomingOptions?.limits || {})){
43
+ if (value !== undefined) {
44
+ options.limits[key] = value;
45
+ }
46
+ }
25
47
  if (!isEligibleRequest(request)) {
26
48
  debugLog(options, 'Request is not eligible for file upload!');
27
49
  return {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/uploads/fetchAPI-multipart/index.ts"],"sourcesContent":["import path from 'path'\n\nimport type { FetchAPIFileUploadOptions } from '../../config/types.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { isEligibleRequest } from './isEligibleRequest.js'\nimport { processMultipart } from './processMultipart.js'\nimport { debugLog } from './utilities.js'\n\nconst DEFAULT_UPLOAD_OPTIONS: FetchAPIFileUploadOptions = {\n abortOnLimit: false,\n createParentPath: false,\n debug: false,\n defParamCharset: 'utf8',\n limitHandler: false,\n parseNested: false,\n preserveExtension: false,\n responseOnLimit: 'File size limit has been reached',\n safeFileNames: false,\n tempFileDir: 'tmp', // Relative path is created inside current workdir.\n uploadTimeout: 60000,\n uriDecodeFileNames: false,\n useTempFiles: false,\n}\n\nexport type FileShape = {\n data: Buffer\n encoding: string\n md5: Buffer | string\n mimetype: string\n mv: (filePath: string, callback: () => void) => Promise<void> | void\n name: string\n size: number\n tempFilePath: string\n truncated: boolean\n}\n\ntype FetchAPIFileUploadResponseFile = {\n data: Buffer\n mimetype: string\n name: string\n size: number\n tempFilePath?: string\n}\n\nexport type FetchAPIFileUploadResponse = {\n error?: APIError\n fields: Record<string, string>\n files: Record<string, FetchAPIFileUploadResponseFile>\n}\n\ntype FetchAPIFileUpload = (args: {\n options?: FetchAPIFileUploadOptions\n request: Request\n}) => Promise<FetchAPIFileUploadResponse>\n\nexport const processMultipartFormdata: FetchAPIFileUpload = async ({\n options: incomingOptions,\n request,\n}) => {\n const options: FetchAPIFileUploadOptions = { ...DEFAULT_UPLOAD_OPTIONS, ...incomingOptions }\n\n if (!isEligibleRequest(request)) {\n debugLog(options, 'Request is not eligible for file upload!')\n\n return {\n error: new APIError('Request is not eligible for file upload', 500),\n fields: undefined!,\n files: undefined!,\n }\n } else {\n return processMultipart({ options, request })\n }\n}\n"],"names":["APIError","isEligibleRequest","processMultipart","debugLog","DEFAULT_UPLOAD_OPTIONS","abortOnLimit","createParentPath","debug","defParamCharset","limitHandler","parseNested","preserveExtension","responseOnLimit","safeFileNames","tempFileDir","uploadTimeout","uriDecodeFileNames","useTempFiles","processMultipartFormdata","options","incomingOptions","request","error","fields","undefined","files"],"mappings":"AAIA,SAASA,QAAQ,QAAQ,2BAA0B;AACnD,SAASC,iBAAiB,QAAQ,yBAAwB;AAC1D,SAASC,gBAAgB,QAAQ,wBAAuB;AACxD,SAASC,QAAQ,QAAQ,iBAAgB;AAEzC,MAAMC,yBAAoD;IACxDC,cAAc;IACdC,kBAAkB;IAClBC,OAAO;IACPC,iBAAiB;IACjBC,cAAc;IACdC,aAAa;IACbC,mBAAmB;IACnBC,iBAAiB;IACjBC,eAAe;IACfC,aAAa;IACbC,eAAe;IACfC,oBAAoB;IACpBC,cAAc;AAChB;AAiCA,OAAO,MAAMC,2BAA+C,OAAO,EACjEC,SAASC,eAAe,EACxBC,OAAO,EACR;IACC,MAAMF,UAAqC;QAAE,GAAGf,sBAAsB;QAAE,GAAGgB,eAAe;IAAC;IAE3F,IAAI,CAACnB,kBAAkBoB,UAAU;QAC/BlB,SAASgB,SAAS;QAElB,OAAO;YACLG,OAAO,IAAItB,SAAS,2CAA2C;YAC/DuB,QAAQC;YACRC,OAAOD;QACT;IACF,OAAO;QACL,OAAOtB,iBAAiB;YAAEiB;YAASE;QAAQ;IAC7C;AACF,EAAC"}
1
+ {"version":3,"sources":["../../../src/uploads/fetchAPI-multipart/index.ts"],"sourcesContent":["import type { FetchAPIFileUploadOptions } from '../../config/types.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { isEligibleRequest } from './isEligibleRequest.js'\nimport { processMultipart } from './processMultipart.js'\nimport { debugLog } from './utilities.js'\n\nconst DEFAULT_REQUEST_SIZE_LIMIT = 50 * 1024 * 1024\n\nconst DEFAULT_UPLOAD_OPTIONS: FetchAPIFileUploadOptions = {\n abortOnLimit: true,\n createParentPath: false,\n debug: false,\n defParamCharset: 'utf8',\n limitHandler: false,\n limits: { fields: 20, fieldSize: 1024 * 1024, files: 3, fileSize: 20 * 1024 * 1024 },\n parseNested: false,\n preserveExtension: false,\n requestSizeLimit: DEFAULT_REQUEST_SIZE_LIMIT,\n responseOnLimit: 'File size limit has been reached',\n safeFileNames: false,\n tempFileDir: 'tmp', // Relative path is created inside current workdir.\n uploadTimeout: 60000,\n uriDecodeFileNames: false,\n useTempFiles: false,\n}\n\nexport type FileShape = {\n data: Buffer\n encoding: string\n md5: Buffer | string\n mimetype: string\n mv: (filePath: string, callback: () => void) => Promise<void> | void\n name: string\n size: number\n tempFilePath: string\n truncated: boolean\n}\n\ntype FetchAPIFileUploadResponseFile = {\n data: Buffer\n mimetype: string\n name: string\n size: number\n tempFilePath?: string\n}\n\nexport type FetchAPIFileUploadResponse = {\n error?: APIError\n fields: Record<string, string>\n files: Record<string, FetchAPIFileUploadResponseFile>\n}\n\ntype FetchAPIFileUpload = (args: {\n options?: FetchAPIFileUploadOptions\n request: Request\n}) => Promise<FetchAPIFileUploadResponse>\n\nexport const processMultipartFormdata: FetchAPIFileUpload = async ({\n options: incomingOptions,\n request,\n}) => {\n const requestSizeLimit =\n incomingOptions?.requestSizeLimit === undefined\n ? DEFAULT_REQUEST_SIZE_LIMIT\n : incomingOptions.requestSizeLimit\n\n if (\n requestSizeLimit !== Infinity &&\n (!Number.isSafeInteger(requestSizeLimit) || requestSizeLimit < 0)\n ) {\n throw new TypeError(\n 'requestSizeLimit must be Infinity or a non-negative safe integer representing bytes',\n )\n }\n\n const options: FetchAPIFileUploadOptions = {\n ...DEFAULT_UPLOAD_OPTIONS,\n ...incomingOptions,\n abortOnLimit: incomingOptions?.abortOnLimit ?? DEFAULT_UPLOAD_OPTIONS.abortOnLimit,\n limits: { ...DEFAULT_UPLOAD_OPTIONS.limits },\n requestSizeLimit,\n }\n\n for (const [key, value] of Object.entries(incomingOptions?.limits || {})) {\n if (value !== undefined) {\n options.limits![key as keyof NonNullable<FetchAPIFileUploadOptions['limits']>] = value\n }\n }\n\n if (!isEligibleRequest(request)) {\n debugLog(options, 'Request is not eligible for file upload!')\n\n return {\n error: new APIError('Request is not eligible for file upload', 500),\n fields: undefined!,\n files: undefined!,\n }\n } else {\n return processMultipart({ options, request })\n }\n}\n"],"names":["APIError","isEligibleRequest","processMultipart","debugLog","DEFAULT_REQUEST_SIZE_LIMIT","DEFAULT_UPLOAD_OPTIONS","abortOnLimit","createParentPath","debug","defParamCharset","limitHandler","limits","fields","fieldSize","files","fileSize","parseNested","preserveExtension","requestSizeLimit","responseOnLimit","safeFileNames","tempFileDir","uploadTimeout","uriDecodeFileNames","useTempFiles","processMultipartFormdata","options","incomingOptions","request","undefined","Infinity","Number","isSafeInteger","TypeError","key","value","Object","entries","error"],"mappings":"AAEA,SAASA,QAAQ,QAAQ,2BAA0B;AACnD,SAASC,iBAAiB,QAAQ,yBAAwB;AAC1D,SAASC,gBAAgB,QAAQ,wBAAuB;AACxD,SAASC,QAAQ,QAAQ,iBAAgB;AAEzC,MAAMC,6BAA6B,KAAK,OAAO;AAE/C,MAAMC,yBAAoD;IACxDC,cAAc;IACdC,kBAAkB;IAClBC,OAAO;IACPC,iBAAiB;IACjBC,cAAc;IACdC,QAAQ;QAAEC,QAAQ;QAAIC,WAAW,OAAO;QAAMC,OAAO;QAAGC,UAAU,KAAK,OAAO;IAAK;IACnFC,aAAa;IACbC,mBAAmB;IACnBC,kBAAkBd;IAClBe,iBAAiB;IACjBC,eAAe;IACfC,aAAa;IACbC,eAAe;IACfC,oBAAoB;IACpBC,cAAc;AAChB;AAiCA,OAAO,MAAMC,2BAA+C,OAAO,EACjEC,SAASC,eAAe,EACxBC,OAAO,EACR;IACC,MAAMV,mBACJS,iBAAiBT,qBAAqBW,YAClCzB,6BACAuB,gBAAgBT,gBAAgB;IAEtC,IACEA,qBAAqBY,YACpB,CAAA,CAACC,OAAOC,aAAa,CAACd,qBAAqBA,mBAAmB,CAAA,GAC/D;QACA,MAAM,IAAIe,UACR;IAEJ;IAEA,MAAMP,UAAqC;QACzC,GAAGrB,sBAAsB;QACzB,GAAGsB,eAAe;QAClBrB,cAAcqB,iBAAiBrB,gBAAgBD,uBAAuBC,YAAY;QAClFK,QAAQ;YAAE,GAAGN,uBAAuBM,MAAM;QAAC;QAC3CO;IACF;IAEA,KAAK,MAAM,CAACgB,KAAKC,MAAM,IAAIC,OAAOC,OAAO,CAACV,iBAAiBhB,UAAU,CAAC,GAAI;QACxE,IAAIwB,UAAUN,WAAW;YACvBH,QAAQf,MAAM,AAAC,CAACuB,IAA8D,GAAGC;QACnF;IACF;IAEA,IAAI,CAAClC,kBAAkB2B,UAAU;QAC/BzB,SAASuB,SAAS;QAElB,OAAO;YACLY,OAAO,IAAItC,SAAS,2CAA2C;YAC/DY,QAAQiB;YACRf,OAAOe;QACT;IACF,OAAO;QACL,OAAO3B,iBAAiB;YAAEwB;YAASE;QAAQ;IAC7C;AACF,EAAC"}
@@ -1,11 +1,5 @@
1
1
  import type { FetchAPIFileUploadOptions } from '../../config/types.js';
2
2
  import type { FetchAPIFileUploadResponse } from './index.js';
3
- declare const waitFlushProperty: unique symbol;
4
- declare global {
5
- interface Request {
6
- [waitFlushProperty]?: Promise<any>[];
7
- }
8
- }
9
3
  type ProcessMultipart = (args: {
10
4
  options: FetchAPIFileUploadOptions;
11
5
  request: Request;
@@ -1 +1 @@
1
- {"version":3,"file":"processMultipart.d.ts","sourceRoot":"","sources":["../../../src/uploads/fetchAPI-multipart/processMultipart.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAS5D,QAAA,MAAM,iBAAiB,eAAuC,CAAA;AAE9D,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,OAAO;QACf,CAAC,iBAAiB,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,CAAC,EAAE,CAAA;KACrC;CACF;AAED,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE;IAC7B,OAAO,EAAE,yBAAyB,CAAA;IAClC,OAAO,EAAE,OAAO,CAAA;CACjB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAA;AACzC,eAAO,MAAM,gBAAgB,EAAE,gBAuN9B,CAAA"}
1
+ {"version":3,"file":"processMultipart.d.ts","sourceRoot":"","sources":["../../../src/uploads/fetchAPI-multipart/processMultipart.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AACtE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,YAAY,CAAA;AAS5D,KAAK,gBAAgB,GAAG,CAAC,IAAI,EAAE;IAC7B,OAAO,EAAE,yBAAyB,CAAA;IAClC,OAAO,EAAE,OAAO,CAAA;CACjB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAA;AAEzC,eAAO,MAAM,gBAAgB,EAAE,gBAgM9B,CAAA"}
@@ -5,167 +5,187 @@ import { fileFactory } from './fileFactory.js';
5
5
  import { memHandler, tempFileHandler } from './handlers.js';
6
6
  import { processNested } from './processNested.js';
7
7
  import { createUploadTimer } from './uploadTimer.js';
8
- import { buildFields, debugLog, isFunc, parseFileName } from './utilities.js';
9
- const waitFlushProperty = Symbol('wait flush property symbol');
8
+ import { buildFields, isFunc, parseFileName } from './utilities.js';
10
9
  export const processMultipart = async ({ options, request })=>{
11
- let parsingRequest = true;
12
- let shouldAbortProccessing = false;
13
- let fileCount = 0;
14
- let filesCompleted = 0;
15
- let allFilesHaveResolved;
16
- let failedResolvingFiles;
17
- let busboyFinishedResolve;
18
- let busboyFinishedReject;
19
- const allFilesComplete = new Promise((res, rej)=>{
20
- allFilesHaveResolved = res;
21
- failedResolvingFiles = rej;
22
- });
23
- const busboyFinished = new Promise((resolve, reject)=>{
24
- busboyFinishedResolve = resolve;
25
- busboyFinishedReject = reject;
26
- });
10
+ const { requestSizeLimit = Infinity, ...busboyOptions } = options;
27
11
  const result = {
28
12
  fields: undefined,
29
13
  files: undefined
30
14
  };
31
- const headersObject = {};
15
+ const headers = {};
32
16
  request.headers.forEach((value, name)=>{
33
- headersObject[name] = value;
17
+ headers[name] = value;
34
18
  });
35
- const reader = request.body?.getReader();
36
19
  const busboy = Busboy({
37
- ...options,
38
- headers: headersObject
20
+ ...busboyOptions,
21
+ headers
39
22
  });
40
- function abortAndDestroyFile(file, err) {
41
- file.destroy();
42
- shouldAbortProccessing = true;
43
- failedResolvingFiles(err);
44
- }
45
- // Build multipart req.body fields
46
- busboy.on('field', (field, val)=>{
47
- result.fields = buildFields(result.fields, field, val);
23
+ const reader = request.body.getReader();
24
+ const uploads = [];
25
+ const writes = [];
26
+ let failure;
27
+ let requestSize = 0;
28
+ let rejectFinished;
29
+ let resolveFinished;
30
+ const finished = new Promise((resolve, reject)=>{
31
+ resolveFinished = resolve;
32
+ rejectFinished = reject;
33
+ });
34
+ const fail = (err)=>{
35
+ if (failure) {
36
+ return;
37
+ }
38
+ failure = err;
39
+ rejectFinished(err);
40
+ // Busboy may still be updating its current file after emitting a limit event.
41
+ queueMicrotask(()=>{
42
+ for (const upload of uploads){
43
+ upload.clear();
44
+ upload.file.destroy();
45
+ }
46
+ busboy.destroy();
47
+ void reader.cancel(err).catch(()=>{});
48
+ });
49
+ };
50
+ const limitError = ()=>new APIError('Multipart limit has been reached', httpStatus.REQUEST_ENTITY_TOO_LARGE);
51
+ const requestSizeLimitError = ()=>new APIError('Multipart request size limit has been reached', httpStatus.REQUEST_ENTITY_TOO_LARGE);
52
+ busboy.on('filesLimit', ()=>fail(limitError()));
53
+ busboy.on('fieldsLimit', ()=>fail(limitError()));
54
+ busboy.on('partsLimit', ()=>fail(limitError()));
55
+ busboy.on('error', fail);
56
+ busboy.on('field', (field, value, info)=>{
57
+ if (info.valueTruncated || info.nameTruncated) {
58
+ fail(limitError());
59
+ } else if (!failure) {
60
+ result.fields = buildFields(result.fields, field, value);
61
+ }
48
62
  });
49
- // Build req.files fields
50
63
  busboy.on('file', (field, file, info)=>{
51
- fileCount += 1;
52
- // Parse file name(cutting huge names, decoding, etc..).
64
+ if (failure) {
65
+ file.resume();
66
+ return;
67
+ }
53
68
  const { encoding, filename: name, mimeType: mime } = info;
54
69
  const filename = parseFileName(options, name);
55
- const inferredMimeType = filename && filename.endsWith('.glb') && 'model/gltf-binary' || filename && filename.endsWith('.gltf') && 'model/gltf+json' || mime;
56
- // Define methods and handlers for upload process.
57
- const { cleanup, complete, dataHandler, getFilePath, getFileSize, getHash, getWritePromise } = options.useTempFiles ? tempFileHandler(options, field, filename) // Upload into temporary file.
58
- : memHandler(options, field, filename) // Upload into RAM.
59
- ;
60
- const writePromise = options.useTempFiles ? getWritePromise().catch(()=>{
61
- busboy.end();
62
- cleanup();
63
- }) : getWritePromise();
64
- const uploadTimer = createUploadTimer(options.uploadTimeout, ()=>{
65
- return abortAndDestroyFile(file, new APIError(`Upload timeout for ${field}->${filename}, bytes:${getFileSize()}`));
70
+ const mimetype = filename.endsWith('.glb') && 'model/gltf-binary' || filename.endsWith('.gltf') && 'model/gltf+json' || mime;
71
+ const handler = options.useTempFiles ? tempFileHandler(options, field, filename) : memHandler(options, field, filename);
72
+ const timer = createUploadTimer(options.uploadTimeout, ()=>{
73
+ fail(new APIError(`Upload timeout for ${field}->${filename}, bytes:${handler.getFileSize()}`));
74
+ });
75
+ uploads.push({
76
+ cleanup: handler.cleanup,
77
+ clear: timer.clear,
78
+ file
66
79
  });
80
+ // Observe write failures immediately, including failures before file end.
81
+ const write = handler.getWritePromise();
82
+ void write.catch(fail);
83
+ writes.push(write);
67
84
  file.on('limit', ()=>{
68
- debugLog(options, `Size limit reached for ${field}->${filename}, bytes:${getFileSize()}`);
69
- uploadTimer.clear();
70
- if (isFunc(options.limitHandler)) {
71
- options.limitHandler({
72
- request,
73
- size: getFileSize()
74
- });
75
- }
76
- // Return error and cleanup files if abortOnLimit set.
77
- if (options.abortOnLimit) {
78
- debugLog(options, `Upload file size limit reached ${field}->${filename}.`);
79
- cleanup();
80
- abortAndDestroyFile(file, new APIError(options.responseOnLimit, httpStatus.REQUEST_ENTITY_TOO_LARGE, {
81
- size: getFileSize()
82
- }));
85
+ timer.clear();
86
+ try {
87
+ if (isFunc(options.limitHandler)) {
88
+ options.limitHandler({
89
+ request,
90
+ size: handler.getFileSize()
91
+ });
92
+ }
93
+ if (options.abortOnLimit) {
94
+ fail(new APIError(options.responseOnLimit, httpStatus.REQUEST_ENTITY_TOO_LARGE, {
95
+ size: handler.getFileSize()
96
+ }));
97
+ }
98
+ } catch (err) {
99
+ fail(err);
83
100
  }
84
101
  });
85
102
  file.on('data', (data)=>{
86
- uploadTimer.set();
87
- dataHandler(data);
103
+ if (failure) {
104
+ return;
105
+ }
106
+ timer.set();
107
+ const pending = handler.dataHandler(data);
108
+ if (pending) {
109
+ file.pause();
110
+ void pending.then(()=>{
111
+ if (!failure) {
112
+ file.resume();
113
+ }
114
+ }, fail);
115
+ }
88
116
  });
117
+ file.on('error', fail);
89
118
  file.on('end', ()=>{
90
- const size = getFileSize();
91
- debugLog(options, `Upload finished ${field}->${filename}, bytes:${size}`);
92
- uploadTimer.clear();
119
+ timer.clear();
120
+ if (failure) {
121
+ return;
122
+ }
123
+ const size = handler.getFileSize();
124
+ const buffer = handler.complete();
93
125
  if (!name && size === 0) {
94
- fileCount -= 1;
95
- if (options.useTempFiles) {
96
- cleanup();
97
- debugLog(options, `Removing the empty file ${field}->${filename}`);
98
- }
99
- return debugLog(options, `Don't add file instance if original name and size are empty`);
126
+ const cleanup = Promise.resolve(handler.cleanup()).then(()=>true);
127
+ void cleanup.catch(fail);
128
+ writes.push(cleanup);
129
+ return;
100
130
  }
101
- filesCompleted += 1;
102
131
  result.files = buildFields(result.files, field, fileFactory({
103
132
  name: filename,
104
- buffer: complete(),
133
+ buffer,
105
134
  encoding,
106
- hash: getHash(),
107
- mimetype: inferredMimeType,
135
+ hash: handler.getHash(),
136
+ mimetype,
108
137
  size,
109
- tempFilePath: getFilePath(),
110
- truncated: Boolean('truncated' in file && file.truncated) || false
138
+ tempFilePath: handler.getFilePath(),
139
+ truncated: Boolean(file.truncated)
111
140
  }, options));
112
- if (!request[waitFlushProperty]) {
113
- request[waitFlushProperty] = [];
114
- }
115
- request[waitFlushProperty].push(writePromise);
116
- if (filesCompleted === fileCount) {
117
- allFilesHaveResolved();
118
- }
119
- });
120
- file.on('error', (err)=>{
121
- uploadTimer.clear();
122
- debugLog(options, `File Error: ${err.message}`);
123
- cleanup();
124
- failedResolvingFiles(err);
125
141
  });
126
- // Start upload process.
127
- debugLog(options, `New upload started ${field}->${filename}, bytes:${getFileSize()}`);
128
- uploadTimer.set();
142
+ timer.set();
129
143
  });
130
- busboy.on('finish', async ()=>{
131
- debugLog(options, `Busboy finished parsing request.`);
132
- if (options.parseNested) {
133
- result.fields = processNested(result.fields);
134
- result.files = processNested(result.files);
135
- }
136
- if (request[waitFlushProperty]) {
137
- try {
138
- await Promise.all(request[waitFlushProperty]).then(()=>{
139
- delete request[waitFlushProperty];
144
+ busboy.on('finish', ()=>{
145
+ void Promise.all(writes).then(()=>resolveFinished(), fail);
146
+ });
147
+ // Waiting for each write callback bounds the parser queue and respects its backpressure.
148
+ const pump = async ()=>{
149
+ try {
150
+ while(!failure){
151
+ const { done, value } = await reader.read();
152
+ if (failure) {
153
+ break;
154
+ }
155
+ if (done) {
156
+ busboy.end();
157
+ break;
158
+ }
159
+ requestSize += value.byteLength;
160
+ if (requestSize > requestSizeLimit) {
161
+ const err = requestSizeLimitError();
162
+ fail(err);
163
+ await reader.cancel(err).catch(()=>{});
164
+ break;
165
+ }
166
+ await new Promise((resolve, reject)=>{
167
+ busboy.write(value, (err)=>err ? reject(err) : resolve());
140
168
  });
141
- } catch (err) {
142
- debugLog(options, `Error waiting for file write promises: ${err}`);
143
169
  }
170
+ } finally{
171
+ reader.releaseLock();
144
172
  }
145
- busboyFinishedResolve();
146
- });
147
- busboy.on('error', (err = new APIError('Busboy error parsing multipart request', httpStatus.BAD_REQUEST))=>{
148
- debugLog(options, `Busboy error`);
149
- const busboyError = err instanceof Error ? err : new APIError('Busboy error parsing multipart request', httpStatus.BAD_REQUEST);
150
- busboyFinishedReject(busboyError);
151
- });
152
- while(parsingRequest){
153
- const { done, value } = await reader.read();
154
- if (done) {
155
- parsingRequest = false;
156
- busboy.end();
173
+ };
174
+ void pump().catch(fail);
175
+ try {
176
+ await finished;
177
+ if (options.parseNested) {
178
+ result.fields = processNested(result.fields);
179
+ result.files = processNested(result.files);
157
180
  }
158
- if (value && !shouldAbortProccessing) {
159
- busboy.write(value);
181
+ return result;
182
+ } catch (err) {
183
+ for (const upload of uploads){
184
+ upload.clear();
160
185
  }
186
+ await Promise.all(uploads.map(async ({ cleanup })=>cleanup()));
187
+ throw err;
161
188
  }
162
- if (fileCount !== 0) {
163
- await allFilesComplete.catch((e)=>{
164
- throw e;
165
- });
166
- }
167
- await busboyFinished;
168
- return result;
169
189
  };
170
190
 
171
191
  //# sourceMappingURL=processMultipart.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/uploads/fetchAPI-multipart/processMultipart.ts"],"sourcesContent":["import type { Readable } from 'stream'\n\nimport Busboy from 'busboy'\nimport { status as httpStatus } from 'http-status'\n\nimport type { FetchAPIFileUploadOptions } from '../../config/types.js'\nimport type { FetchAPIFileUploadResponse } from './index.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { fileFactory } from './fileFactory.js'\nimport { memHandler, tempFileHandler } from './handlers.js'\nimport { processNested } from './processNested.js'\nimport { createUploadTimer } from './uploadTimer.js'\nimport { buildFields, debugLog, isFunc, parseFileName } from './utilities.js'\n\nconst waitFlushProperty = Symbol('wait flush property symbol')\n\ndeclare global {\n interface Request {\n [waitFlushProperty]?: Promise<any>[]\n }\n}\n\ntype ProcessMultipart = (args: {\n options: FetchAPIFileUploadOptions\n request: Request\n}) => Promise<FetchAPIFileUploadResponse>\nexport const processMultipart: ProcessMultipart = async ({ options, request }) => {\n let parsingRequest = true\n\n let shouldAbortProccessing = false\n let fileCount = 0\n let filesCompleted = 0\n let allFilesHaveResolved: (value?: unknown) => void\n let failedResolvingFiles: (err: Error) => void\n let busboyFinishedResolve: () => void\n let busboyFinishedReject: (err: Error) => void\n\n const allFilesComplete = new Promise((res, rej) => {\n allFilesHaveResolved = res\n failedResolvingFiles = rej\n })\n\n const busboyFinished = new Promise<void>((resolve, reject) => {\n busboyFinishedResolve = resolve\n busboyFinishedReject = reject\n })\n\n const result: FetchAPIFileUploadResponse = {\n fields: undefined!,\n files: undefined!,\n }\n\n const headersObject: Record<string, string> = {}\n request.headers.forEach((value, name) => {\n headersObject[name] = value\n })\n\n const reader = request.body?.getReader()\n\n const busboy = Busboy({ ...options, headers: headersObject })\n\n function abortAndDestroyFile(file: Readable, err: APIError) {\n file.destroy()\n shouldAbortProccessing = true\n failedResolvingFiles(err)\n }\n\n // Build multipart req.body fields\n busboy.on('field', (field, val) => {\n result.fields = buildFields(result.fields, field, val)\n })\n\n // Build req.files fields\n busboy.on('file', (field, file, info) => {\n fileCount += 1\n // Parse file name(cutting huge names, decoding, etc..).\n const { encoding, filename: name, mimeType: mime } = info\n const filename = parseFileName(options, name)\n\n const inferredMimeType =\n (filename && filename.endsWith('.glb') && 'model/gltf-binary') ||\n (filename && filename.endsWith('.gltf') && 'model/gltf+json') ||\n mime\n\n // Define methods and handlers for upload process.\n const { cleanup, complete, dataHandler, getFilePath, getFileSize, getHash, getWritePromise } =\n options.useTempFiles\n ? tempFileHandler(options, field, filename) // Upload into temporary file.\n : memHandler(options, field, filename) // Upload into RAM.\n\n const writePromise = options.useTempFiles\n ? getWritePromise().catch(() => {\n busboy.end()\n cleanup()\n })\n : getWritePromise()\n\n const uploadTimer = createUploadTimer(options.uploadTimeout, () => {\n return abortAndDestroyFile(\n file,\n new APIError(`Upload timeout for ${field}->${filename}, bytes:${getFileSize()}`),\n )\n })\n\n file.on('limit', () => {\n debugLog(options, `Size limit reached for ${field}->${filename}, bytes:${getFileSize()}`)\n uploadTimer.clear()\n\n if (isFunc(options.limitHandler)) {\n options.limitHandler({ request, size: getFileSize() })\n }\n\n // Return error and cleanup files if abortOnLimit set.\n if (options.abortOnLimit) {\n debugLog(options, `Upload file size limit reached ${field}->${filename}.`)\n cleanup()\n abortAndDestroyFile(\n file,\n new APIError(options.responseOnLimit!, httpStatus.REQUEST_ENTITY_TOO_LARGE, {\n size: getFileSize(),\n }),\n )\n }\n })\n\n file.on('data', (data) => {\n uploadTimer.set()\n dataHandler(data)\n })\n\n file.on('end', () => {\n const size = getFileSize()\n debugLog(options, `Upload finished ${field}->${filename}, bytes:${size}`)\n uploadTimer.clear()\n\n if (!name && size === 0) {\n fileCount -= 1\n if (options.useTempFiles) {\n cleanup()\n debugLog(options, `Removing the empty file ${field}->${filename}`)\n }\n return debugLog(options, `Don't add file instance if original name and size are empty`)\n }\n\n filesCompleted += 1\n\n result.files = buildFields(\n result.files,\n field,\n fileFactory(\n {\n name: filename,\n buffer: complete(),\n encoding,\n hash: getHash(),\n mimetype: inferredMimeType,\n size,\n tempFilePath: getFilePath(),\n truncated: Boolean('truncated' in file && file.truncated) || false,\n },\n options,\n ),\n )\n\n if (!request[waitFlushProperty]) {\n request[waitFlushProperty] = []\n }\n request[waitFlushProperty].push(writePromise)\n\n if (filesCompleted === fileCount) {\n allFilesHaveResolved()\n }\n })\n\n file.on('error', (err) => {\n uploadTimer.clear()\n debugLog(options, `File Error: ${err.message}`)\n cleanup()\n failedResolvingFiles(err)\n })\n\n // Start upload process.\n debugLog(options, `New upload started ${field}->${filename}, bytes:${getFileSize()}`)\n uploadTimer.set()\n })\n\n busboy.on('finish', async () => {\n debugLog(options, `Busboy finished parsing request.`)\n if (options.parseNested) {\n result.fields = processNested(result.fields)\n result.files = processNested(result.files)\n }\n\n if (request[waitFlushProperty]) {\n try {\n await Promise.all(request[waitFlushProperty]).then(() => {\n delete request[waitFlushProperty]\n })\n } catch (err) {\n debugLog(options, `Error waiting for file write promises: ${err}`)\n }\n }\n\n busboyFinishedResolve()\n })\n\n busboy.on(\n 'error',\n (err = new APIError('Busboy error parsing multipart request', httpStatus.BAD_REQUEST)) => {\n debugLog(options, `Busboy error`)\n const busboyError =\n err instanceof Error\n ? err\n : new APIError('Busboy error parsing multipart request', httpStatus.BAD_REQUEST)\n\n busboyFinishedReject(busboyError)\n },\n )\n\n while (parsingRequest) {\n const { done, value } = await reader!.read()\n\n if (done) {\n parsingRequest = false\n busboy.end()\n }\n\n if (value && !shouldAbortProccessing) {\n busboy.write(value)\n }\n }\n\n if (fileCount !== 0) {\n await allFilesComplete.catch((e) => {\n throw e\n })\n }\n\n await busboyFinished\n\n return result\n}\n"],"names":["Busboy","status","httpStatus","APIError","fileFactory","memHandler","tempFileHandler","processNested","createUploadTimer","buildFields","debugLog","isFunc","parseFileName","waitFlushProperty","Symbol","processMultipart","options","request","parsingRequest","shouldAbortProccessing","fileCount","filesCompleted","allFilesHaveResolved","failedResolvingFiles","busboyFinishedResolve","busboyFinishedReject","allFilesComplete","Promise","res","rej","busboyFinished","resolve","reject","result","fields","undefined","files","headersObject","headers","forEach","value","name","reader","body","getReader","busboy","abortAndDestroyFile","file","err","destroy","on","field","val","info","encoding","filename","mimeType","mime","inferredMimeType","endsWith","cleanup","complete","dataHandler","getFilePath","getFileSize","getHash","getWritePromise","useTempFiles","writePromise","catch","end","uploadTimer","uploadTimeout","clear","limitHandler","size","abortOnLimit","responseOnLimit","REQUEST_ENTITY_TOO_LARGE","data","set","buffer","hash","mimetype","tempFilePath","truncated","Boolean","push","message","parseNested","all","then","BAD_REQUEST","busboyError","Error","done","read","write","e"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/uploads/fetchAPI-multipart/processMultipart.ts"],"sourcesContent":["import type { Readable } from 'stream'\n\nimport Busboy from 'busboy'\nimport { status as httpStatus } from 'http-status'\n\nimport type { FetchAPIFileUploadOptions } from '../../config/types.js'\nimport type { FetchAPIFileUploadResponse } from './index.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { fileFactory } from './fileFactory.js'\nimport { memHandler, tempFileHandler } from './handlers.js'\nimport { processNested } from './processNested.js'\nimport { createUploadTimer } from './uploadTimer.js'\nimport { buildFields, isFunc, parseFileName } from './utilities.js'\n\ntype ProcessMultipart = (args: {\n options: FetchAPIFileUploadOptions\n request: Request\n}) => Promise<FetchAPIFileUploadResponse>\n\nexport const processMultipart: ProcessMultipart = async ({ options, request }) => {\n const { requestSizeLimit = Infinity, ...busboyOptions } = options\n const result: FetchAPIFileUploadResponse = { fields: undefined!, files: undefined! }\n const headers: Record<string, string> = {}\n request.headers.forEach((value, name) => {\n headers[name] = value\n })\n const busboy = Busboy({ ...busboyOptions, headers })\n const reader = request.body!.getReader()\n const uploads: { cleanup: () => Promise<void> | void; clear: () => void; file: Readable }[] = []\n const writes: Promise<boolean>[] = []\n let failure: Error | undefined\n let requestSize = 0\n let rejectFinished: (err: Error) => void\n let resolveFinished: () => void\n const finished = new Promise<void>((resolve, reject) => {\n resolveFinished = resolve\n rejectFinished = reject\n })\n\n const fail = (err: Error) => {\n if (failure) {\n return\n }\n failure = err\n rejectFinished(err)\n // Busboy may still be updating its current file after emitting a limit event.\n queueMicrotask(() => {\n for (const upload of uploads) {\n upload.clear()\n upload.file.destroy()\n }\n busboy.destroy()\n void reader.cancel(err).catch(() => {})\n })\n }\n const limitError = () =>\n new APIError('Multipart limit has been reached', httpStatus.REQUEST_ENTITY_TOO_LARGE)\n const requestSizeLimitError = () =>\n new APIError(\n 'Multipart request size limit has been reached',\n httpStatus.REQUEST_ENTITY_TOO_LARGE,\n )\n\n busboy.on('filesLimit', () => fail(limitError()))\n busboy.on('fieldsLimit', () => fail(limitError()))\n busboy.on('partsLimit', () => fail(limitError()))\n busboy.on('error', fail)\n busboy.on('field', (field, value, info) => {\n if (info.valueTruncated || info.nameTruncated) {\n fail(limitError())\n } else if (!failure) {\n result.fields = buildFields(result.fields, field, value)\n }\n })\n\n busboy.on('file', (field, file, info) => {\n if (failure) {\n file.resume()\n return\n }\n const { encoding, filename: name, mimeType: mime } = info\n const filename = parseFileName(options, name)\n const mimetype =\n (filename.endsWith('.glb') && 'model/gltf-binary') ||\n (filename.endsWith('.gltf') && 'model/gltf+json') ||\n mime\n const handler = options.useTempFiles\n ? tempFileHandler(options, field, filename)\n : memHandler(options, field, filename)\n const timer = createUploadTimer(options.uploadTimeout, () => {\n fail(new APIError(`Upload timeout for ${field}->${filename}, bytes:${handler.getFileSize()}`))\n })\n uploads.push({ cleanup: handler.cleanup, clear: timer.clear, file })\n // Observe write failures immediately, including failures before file end.\n const write = handler.getWritePromise()\n void write.catch(fail)\n writes.push(write)\n\n file.on('limit', () => {\n timer.clear()\n try {\n if (isFunc(options.limitHandler)) {\n options.limitHandler({ request, size: handler.getFileSize() })\n }\n if (options.abortOnLimit) {\n fail(\n new APIError(options.responseOnLimit!, httpStatus.REQUEST_ENTITY_TOO_LARGE, {\n size: handler.getFileSize(),\n }),\n )\n }\n } catch (err) {\n fail(err as Error)\n }\n })\n file.on('data', (data: Buffer) => {\n if (failure) {\n return\n }\n timer.set()\n const pending = handler.dataHandler(data)\n if (pending) {\n file.pause()\n void pending.then(() => {\n if (!failure) {\n file.resume()\n }\n }, fail)\n }\n })\n file.on('error', fail)\n file.on('end', () => {\n timer.clear()\n if (failure) {\n return\n }\n const size = handler.getFileSize()\n const buffer = handler.complete()\n if (!name && size === 0) {\n const cleanup = Promise.resolve(handler.cleanup()).then(() => true)\n void cleanup.catch(fail)\n writes.push(cleanup)\n return\n }\n result.files = buildFields(\n result.files,\n field,\n fileFactory(\n {\n name: filename,\n buffer,\n encoding,\n hash: handler.getHash(),\n mimetype,\n size,\n tempFilePath: handler.getFilePath(),\n truncated: Boolean(file.truncated),\n },\n options,\n ),\n )\n })\n timer.set()\n })\n busboy.on('finish', () => {\n void Promise.all(writes).then(() => resolveFinished(), fail)\n })\n\n // Waiting for each write callback bounds the parser queue and respects its backpressure.\n const pump = async () => {\n try {\n while (!failure) {\n const { done, value } = await reader.read()\n if (failure) {\n break\n }\n if (done) {\n busboy.end()\n break\n }\n requestSize += value.byteLength\n if (requestSize > requestSizeLimit) {\n const err = requestSizeLimitError()\n fail(err)\n await reader.cancel(err).catch(() => {})\n break\n }\n await new Promise<void>((resolve, reject) => {\n busboy.write(value, (err?: Error | null) => (err ? reject(err) : resolve()))\n })\n }\n } finally {\n reader.releaseLock()\n }\n }\n void pump().catch(fail)\n\n try {\n await finished\n if (options.parseNested) {\n result.fields = processNested(result.fields)\n result.files = processNested(result.files)\n }\n return result\n } catch (err) {\n for (const upload of uploads) {\n upload.clear()\n }\n await Promise.all(uploads.map(async ({ cleanup }) => cleanup()))\n throw err\n }\n}\n"],"names":["Busboy","status","httpStatus","APIError","fileFactory","memHandler","tempFileHandler","processNested","createUploadTimer","buildFields","isFunc","parseFileName","processMultipart","options","request","requestSizeLimit","Infinity","busboyOptions","result","fields","undefined","files","headers","forEach","value","name","busboy","reader","body","getReader","uploads","writes","failure","requestSize","rejectFinished","resolveFinished","finished","Promise","resolve","reject","fail","err","queueMicrotask","upload","clear","file","destroy","cancel","catch","limitError","REQUEST_ENTITY_TOO_LARGE","requestSizeLimitError","on","field","info","valueTruncated","nameTruncated","resume","encoding","filename","mimeType","mime","mimetype","endsWith","handler","useTempFiles","timer","uploadTimeout","getFileSize","push","cleanup","write","getWritePromise","limitHandler","size","abortOnLimit","responseOnLimit","data","set","pending","dataHandler","pause","then","buffer","complete","hash","getHash","tempFilePath","getFilePath","truncated","Boolean","all","pump","done","read","end","byteLength","releaseLock","parseNested","map"],"mappings":"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"}