payload 3.89.0-internal.95c9cba → 3.90.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (468) 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 +123 -23
  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 +82 -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 +146 -48
  255. package/dist/index.d.ts +4 -1
  256. package/dist/index.d.ts.map +1 -1
  257. package/dist/index.js +3 -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/collection.d.ts.map +1 -1
  266. package/dist/queues/config/collection.js +6 -0
  267. package/dist/queues/config/collection.js.map +1 -1
  268. package/dist/queues/config/types/index.d.ts +4 -1
  269. package/dist/queues/config/types/index.d.ts.map +1 -1
  270. package/dist/queues/config/types/index.js.map +1 -1
  271. package/dist/queues/endpoints/handleSchedules.d.ts.map +1 -1
  272. package/dist/queues/endpoints/handleSchedules.js +2 -1
  273. package/dist/queues/endpoints/handleSchedules.js.map +1 -1
  274. package/dist/queues/endpoints/run.d.ts.map +1 -1
  275. package/dist/queues/endpoints/run.js +2 -1
  276. package/dist/queues/endpoints/run.js.map +1 -1
  277. package/dist/uploads/assertClientUploadAccess.d.ts +7 -0
  278. package/dist/uploads/assertClientUploadAccess.d.ts.map +1 -0
  279. package/dist/uploads/assertClientUploadAccess.js +27 -0
  280. package/dist/uploads/assertClientUploadAccess.js.map +1 -0
  281. package/dist/uploads/assertClientUploadAllowed.d.ts +11 -0
  282. package/dist/uploads/assertClientUploadAllowed.d.ts.map +1 -0
  283. package/dist/uploads/assertClientUploadAllowed.js +46 -0
  284. package/dist/uploads/assertClientUploadAllowed.js.map +1 -0
  285. package/dist/uploads/assertClientUploadAllowed.spec.js +91 -0
  286. package/dist/uploads/assertClientUploadAllowed.spec.js.map +1 -0
  287. package/dist/uploads/checkFileRestrictions.d.ts +4 -1
  288. package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
  289. package/dist/uploads/checkFileRestrictions.js +66 -26
  290. package/dist/uploads/checkFileRestrictions.js.map +1 -1
  291. package/dist/uploads/clientUploadReceipt.d.ts +23 -0
  292. package/dist/uploads/clientUploadReceipt.d.ts.map +1 -0
  293. package/dist/uploads/clientUploadReceipt.js +55 -0
  294. package/dist/uploads/clientUploadReceipt.js.map +1 -0
  295. package/dist/uploads/deleteAssociatedFiles.d.ts.map +1 -1
  296. package/dist/uploads/deleteAssociatedFiles.js +33 -8
  297. package/dist/uploads/deleteAssociatedFiles.js.map +1 -1
  298. package/dist/uploads/deleteAssociatedFiles.spec.js +124 -0
  299. package/dist/uploads/deleteAssociatedFiles.spec.js.map +1 -0
  300. package/dist/uploads/detectSvgFromXml.d.ts +1 -3
  301. package/dist/uploads/detectSvgFromXml.d.ts.map +1 -1
  302. package/dist/uploads/detectSvgFromXml.js +3 -40
  303. package/dist/uploads/detectSvgFromXml.js.map +1 -1
  304. package/dist/uploads/endpoints/getFile.d.ts.map +1 -1
  305. package/dist/uploads/endpoints/getFile.js +5 -3
  306. package/dist/uploads/endpoints/getFile.js.map +1 -1
  307. package/dist/uploads/fetchAPI-multipart/handlers.d.ts +2 -2
  308. package/dist/uploads/fetchAPI-multipart/handlers.d.ts.map +1 -1
  309. package/dist/uploads/fetchAPI-multipart/handlers.js +18 -5
  310. package/dist/uploads/fetchAPI-multipart/handlers.js.map +1 -1
  311. package/dist/uploads/fetchAPI-multipart/index.d.ts.map +1 -1
  312. package/dist/uploads/fetchAPI-multipart/index.js +24 -2
  313. package/dist/uploads/fetchAPI-multipart/index.js.map +1 -1
  314. package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts +0 -6
  315. package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts.map +1 -1
  316. package/dist/uploads/fetchAPI-multipart/processMultipart.js +146 -126
  317. package/dist/uploads/fetchAPI-multipart/processMultipart.js.map +1 -1
  318. package/dist/uploads/fetchAPI-multipart/processMultipart.spec.js +663 -0
  319. package/dist/uploads/fetchAPI-multipart/processMultipart.spec.js.map +1 -0
  320. package/dist/uploads/generateFileData.d.ts +3 -1
  321. package/dist/uploads/generateFileData.d.ts.map +1 -1
  322. package/dist/uploads/generateFileData.js +29 -16
  323. package/dist/uploads/generateFileData.js.map +1 -1
  324. package/dist/uploads/getBaseFields.d.ts.map +1 -1
  325. package/dist/uploads/getBaseFields.js +3 -1
  326. package/dist/uploads/getBaseFields.js.map +1 -1
  327. package/dist/uploads/getExternalFile.d.ts +1 -1
  328. package/dist/uploads/getExternalFile.d.ts.map +1 -1
  329. package/dist/uploads/getExternalFile.js +60 -15
  330. package/dist/uploads/getExternalFile.js.map +1 -1
  331. package/dist/uploads/getFileFromClientUpload.d.ts +2 -2
  332. package/dist/uploads/getFileFromClientUpload.d.ts.map +1 -1
  333. package/dist/uploads/getFileFromClientUpload.js +4 -4
  334. package/dist/uploads/getFileFromClientUpload.js.map +1 -1
  335. package/dist/uploads/getFileFromClientUpload.spec.js +62 -0
  336. package/dist/uploads/getFileFromClientUpload.spec.js.map +1 -1
  337. package/dist/uploads/getFileTypeFallback.d.ts.map +1 -1
  338. package/dist/uploads/getFileTypeFallback.js +3 -1
  339. package/dist/uploads/getFileTypeFallback.js.map +1 -1
  340. package/dist/uploads/getFileTypeIdentity.d.ts +19 -0
  341. package/dist/uploads/getFileTypeIdentity.d.ts.map +1 -0
  342. package/dist/uploads/getFileTypeIdentity.js +34 -0
  343. package/dist/uploads/getFileTypeIdentity.js.map +1 -0
  344. package/dist/uploads/getFileTypeIdentity.spec.js +43 -0
  345. package/dist/uploads/getFileTypeIdentity.spec.js.map +1 -0
  346. package/dist/uploads/isProcessableImage.d.ts +2 -0
  347. package/dist/uploads/isProcessableImage.d.ts.map +1 -0
  348. package/dist/uploads/isProcessableImage.js +7 -0
  349. package/dist/uploads/isProcessableImage.js.map +1 -0
  350. package/dist/uploads/safeFetch.d.ts.map +1 -1
  351. package/dist/uploads/safeFetch.js +3 -2
  352. package/dist/uploads/safeFetch.js.map +1 -1
  353. package/dist/uploads/sanitizeUploadData.d.ts +26 -0
  354. package/dist/uploads/sanitizeUploadData.d.ts.map +1 -0
  355. package/dist/uploads/sanitizeUploadData.js +159 -0
  356. package/dist/uploads/sanitizeUploadData.js.map +1 -0
  357. package/dist/uploads/sanitizeUploadData.spec.js +255 -0
  358. package/dist/uploads/sanitizeUploadData.spec.js.map +1 -0
  359. package/dist/uploads/types.d.ts +11 -3
  360. package/dist/uploads/types.d.ts.map +1 -1
  361. package/dist/uploads/types.js.map +1 -1
  362. package/dist/uploads/unlinkClientUploadTempFile.d.ts +20 -0
  363. package/dist/uploads/unlinkClientUploadTempFile.d.ts.map +1 -0
  364. package/dist/uploads/unlinkClientUploadTempFile.js +30 -0
  365. package/dist/uploads/unlinkClientUploadTempFile.js.map +1 -0
  366. package/dist/uploads/unlinkTempFiles.d.ts.map +1 -1
  367. package/dist/uploads/unlinkTempFiles.js +7 -9
  368. package/dist/uploads/unlinkTempFiles.js.map +1 -1
  369. package/dist/uploads/unlinkTempFiles.spec.js +61 -1
  370. package/dist/uploads/unlinkTempFiles.spec.js.map +1 -1
  371. package/dist/uploads/uploadContentSecurityPolicy.d.ts +2 -0
  372. package/dist/uploads/uploadContentSecurityPolicy.d.ts.map +1 -0
  373. package/dist/uploads/uploadContentSecurityPolicy.js +3 -0
  374. package/dist/uploads/uploadContentSecurityPolicy.js.map +1 -0
  375. package/dist/uploads/validateISOBaseMediaFile.d.ts +4 -0
  376. package/dist/uploads/validateISOBaseMediaFile.d.ts.map +1 -0
  377. package/dist/uploads/validateISOBaseMediaFile.js +91 -0
  378. package/dist/uploads/validateISOBaseMediaFile.js.map +1 -0
  379. package/dist/uploads/validateISOBaseMediaFile.spec.js +130 -0
  380. package/dist/uploads/validateISOBaseMediaFile.spec.js.map +1 -0
  381. package/dist/uploads/validateSvg.d.ts +10 -4
  382. package/dist/uploads/validateSvg.d.ts.map +1 -1
  383. package/dist/uploads/validateSvg.js +280 -40
  384. package/dist/uploads/validateSvg.js.map +1 -1
  385. package/dist/uploads/validateSvg.spec.js +123 -0
  386. package/dist/uploads/validateSvg.spec.js.map +1 -0
  387. package/dist/uploads/validateUploadFilename.d.ts +3 -0
  388. package/dist/uploads/validateUploadFilename.d.ts.map +1 -0
  389. package/dist/uploads/validateUploadFilename.js +13 -0
  390. package/dist/uploads/validateUploadFilename.js.map +1 -0
  391. package/dist/uploads/validateUploadFilename.spec.js +24 -0
  392. package/dist/uploads/validateUploadFilename.spec.js.map +1 -0
  393. package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
  394. package/dist/utilities/addDataAndFileToRequest.js +28 -1
  395. package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
  396. package/dist/utilities/addDataAndFileToRequest.spec.js +158 -0
  397. package/dist/utilities/addDataAndFileToRequest.spec.js.map +1 -1
  398. package/dist/utilities/createPayloadRequest.d.ts.map +1 -1
  399. package/dist/utilities/createPayloadRequest.js +2 -1
  400. package/dist/utilities/createPayloadRequest.js.map +1 -1
  401. package/dist/utilities/deepCopyObject.d.ts.map +1 -1
  402. package/dist/utilities/deepCopyObject.js +110 -19
  403. package/dist/utilities/deepCopyObject.js.map +1 -1
  404. package/dist/utilities/deepCopyObject.spec.js +216 -0
  405. package/dist/utilities/deepCopyObject.spec.js.map +1 -0
  406. package/dist/utilities/fieldPath.d.ts +13 -0
  407. package/dist/utilities/fieldPath.d.ts.map +1 -0
  408. package/dist/utilities/fieldPath.js +51 -0
  409. package/dist/utilities/fieldPath.js.map +1 -0
  410. package/dist/utilities/fieldPath.spec.js +155 -0
  411. package/dist/utilities/fieldPath.spec.js.map +1 -0
  412. package/dist/utilities/getEntityPermissions/getEntityPermissions.d.ts.map +1 -1
  413. package/dist/utilities/getEntityPermissions/getEntityPermissions.js +2 -0
  414. package/dist/utilities/getEntityPermissions/getEntityPermissions.js.map +1 -1
  415. package/dist/utilities/getObjectDotNotation.d.ts.map +1 -1
  416. package/dist/utilities/getObjectDotNotation.js +7 -1
  417. package/dist/utilities/getObjectDotNotation.js.map +1 -1
  418. package/dist/utilities/getObjectDotNotation.spec.js +33 -0
  419. package/dist/utilities/getObjectDotNotation.spec.js.map +1 -0
  420. package/dist/utilities/getSafeRedirect.spec.js +14 -0
  421. package/dist/utilities/getSafeRedirect.spec.js.map +1 -1
  422. package/dist/utilities/getTopLevelFieldNames.d.ts +2 -0
  423. package/dist/utilities/getTopLevelFieldNames.d.ts.map +1 -0
  424. package/dist/utilities/getTopLevelFieldNames.js +3 -0
  425. package/dist/utilities/getTopLevelFieldNames.js.map +1 -0
  426. package/dist/utilities/getTopLevelFieldNames.spec.js +18 -0
  427. package/dist/utilities/getTopLevelFieldNames.spec.js.map +1 -0
  428. package/dist/utilities/handleEndpoints.js +1 -1
  429. package/dist/utilities/handleEndpoints.js.map +1 -1
  430. package/dist/utilities/parseParams/index.d.ts.map +1 -1
  431. package/dist/utilities/parseParams/index.js +3 -1
  432. package/dist/utilities/parseParams/index.js.map +1 -1
  433. package/dist/utilities/parseParams/index.spec.js +8 -0
  434. package/dist/utilities/parseParams/index.spec.js.map +1 -1
  435. package/dist/utilities/traverseFields.d.ts.map +1 -1
  436. package/dist/utilities/traverseFields.js +5 -14
  437. package/dist/utilities/traverseFields.js.map +1 -1
  438. package/dist/utilities/unflatten.d.ts.map +1 -1
  439. package/dist/utilities/unflatten.js +21 -9
  440. package/dist/utilities/unflatten.js.map +1 -1
  441. package/dist/utilities/unflatten.spec.js +38 -0
  442. package/dist/utilities/unflatten.spec.js.map +1 -0
  443. package/dist/utilities/wrapInternalEndpoints.d.ts.map +1 -1
  444. package/dist/utilities/wrapInternalEndpoints.js +10 -3
  445. package/dist/utilities/wrapInternalEndpoints.js.map +1 -1
  446. package/dist/utilities/wrapInternalEndpoints.spec.js +124 -0
  447. package/dist/utilities/wrapInternalEndpoints.spec.js.map +1 -0
  448. package/dist/versions/allLocalesPublicationStatus.d.ts +38 -0
  449. package/dist/versions/allLocalesPublicationStatus.d.ts.map +1 -0
  450. package/dist/versions/allLocalesPublicationStatus.js +57 -0
  451. package/dist/versions/allLocalesPublicationStatus.js.map +1 -0
  452. package/dist/versions/getLatestGlobalVersion.d.ts.map +1 -1
  453. package/dist/versions/getLatestGlobalVersion.js +10 -2
  454. package/dist/versions/getLatestGlobalVersion.js.map +1 -1
  455. package/dist/versions/getRestoredStatusesToAuthorize.d.ts +9 -0
  456. package/dist/versions/getRestoredStatusesToAuthorize.d.ts.map +1 -0
  457. package/dist/versions/getRestoredStatusesToAuthorize.js +22 -0
  458. package/dist/versions/getRestoredStatusesToAuthorize.js.map +1 -0
  459. package/dist/versions/getRestoredStatusesToAuthorize.spec.js +50 -0
  460. package/dist/versions/getRestoredStatusesToAuthorize.spec.js.map +1 -0
  461. package/dist/versions/schedule/job.d.ts +2 -2
  462. package/dist/versions/schedule/job.d.ts.map +1 -1
  463. package/dist/versions/schedule/job.js +11 -7
  464. package/dist/versions/schedule/job.js.map +1 -1
  465. package/dist/versions/schedule/types.d.ts +5 -1
  466. package/dist/versions/schedule/types.d.ts.map +1 -1
  467. package/dist/versions/schedule/types.js.map +1 -1
  468. package/package.json +4 -2
@@ -1,43 +1,6 @@
1
- /**
2
- * Securely detect if an XML buffer contains a valid SVG document
3
- */ export function detectSvgFromXml(buffer) {
4
- try {
5
- // Limit buffer size to prevent processing large malicious files
6
- const maxSize = 2048;
7
- const content = buffer.toString('utf8', 0, Math.min(buffer.length, maxSize));
8
- // Check for XML declaration and extract encoding if present
9
- const xmlDeclMatch = content.match(/^<\?xml[^>]*encoding=["']([^"']+)["']/i);
10
- const declaredEncoding = xmlDeclMatch?.[1]?.toLowerCase();
11
- // Only support safe encodings
12
- if (declaredEncoding && ![
13
- 'ascii',
14
- 'utf-8',
15
- 'utf8'
16
- ].includes(declaredEncoding)) {
17
- return false;
18
- }
19
- // Remove XML declarations, comments, and processing instructions
20
- const cleanContent = content.replace(/<\?xml[^>]*\?>/gi, '').replace(/<!--[\s\S]*?-->/g, '').replace(/<\?[^>]*\?>/g, '').trim();
21
- // Find the first actual element (root element)
22
- const rootElementMatch = cleanContent.match(/^<(\w+)(?:\s|>)/);
23
- if (!rootElementMatch || rootElementMatch[1] !== 'svg') {
24
- return false;
25
- }
26
- // Validate SVG namespace - must be present for valid SVG
27
- const svgNamespaceRegex = /xmlns=["']http:\/\/www\.w3\.org\/2000\/svg["']/;
28
- if (!svgNamespaceRegex.test(content)) {
29
- return false;
30
- }
31
- // Additional validation: ensure it's not malformed
32
- const svgOpenTag = content.match(/<svg[\s>]/);
33
- if (!svgOpenTag) {
34
- return false;
35
- }
36
- return true;
37
- } catch (_error) {
38
- // If any error occurs during parsing, treat as not SVG
39
- return false;
40
- }
1
+ import { inspectSvg } from './validateSvg.js';
2
+ /** Detect whether an XML document's root element is namespaced SVG. */ export function detectSvgFromXml(buffer) {
3
+ return inspectSvg(buffer).isSvg;
41
4
  }
42
5
 
43
6
  //# sourceMappingURL=detectSvgFromXml.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/uploads/detectSvgFromXml.ts"],"sourcesContent":["/**\n * Securely detect if an XML buffer contains a valid SVG document\n */\nexport function detectSvgFromXml(buffer: Buffer): boolean {\n try {\n // Limit buffer size to prevent processing large malicious files\n const maxSize = 2048\n const content = buffer.toString('utf8', 0, Math.min(buffer.length, maxSize))\n\n // Check for XML declaration and extract encoding if present\n const xmlDeclMatch = content.match(/^<\\?xml[^>]*encoding=[\"']([^\"']+)[\"']/i)\n const declaredEncoding = xmlDeclMatch?.[1]?.toLowerCase()\n\n // Only support safe encodings\n if (declaredEncoding && !['ascii', 'utf-8', 'utf8'].includes(declaredEncoding)) {\n return false\n }\n\n // Remove XML declarations, comments, and processing instructions\n const cleanContent = content\n .replace(/<\\?xml[^>]*\\?>/gi, '')\n .replace(/<!--[\\s\\S]*?-->/g, '')\n .replace(/<\\?[^>]*\\?>/g, '')\n .trim()\n\n // Find the first actual element (root element)\n const rootElementMatch = cleanContent.match(/^<(\\w+)(?:\\s|>)/)\n if (!rootElementMatch || rootElementMatch[1] !== 'svg') {\n return false\n }\n\n // Validate SVG namespace - must be present for valid SVG\n const svgNamespaceRegex = /xmlns=[\"']http:\\/\\/www\\.w3\\.org\\/2000\\/svg[\"']/\n if (!svgNamespaceRegex.test(content)) {\n return false\n }\n\n // Additional validation: ensure it's not malformed\n const svgOpenTag = content.match(/<svg[\\s>]/)\n if (!svgOpenTag) {\n return false\n }\n\n return true\n } catch (_error) {\n // If any error occurs during parsing, treat as not SVG\n return false\n }\n}\n"],"names":["detectSvgFromXml","buffer","maxSize","content","toString","Math","min","length","xmlDeclMatch","match","declaredEncoding","toLowerCase","includes","cleanContent","replace","trim","rootElementMatch","svgNamespaceRegex","test","svgOpenTag","_error"],"mappings":"AAAA;;CAEC,GACD,OAAO,SAASA,iBAAiBC,MAAc;IAC7C,IAAI;QACF,gEAAgE;QAChE,MAAMC,UAAU;QAChB,MAAMC,UAAUF,OAAOG,QAAQ,CAAC,QAAQ,GAAGC,KAAKC,GAAG,CAACL,OAAOM,MAAM,EAAEL;QAEnE,4DAA4D;QAC5D,MAAMM,eAAeL,QAAQM,KAAK,CAAC;QACnC,MAAMC,mBAAmBF,cAAc,CAAC,EAAE,EAAEG;QAE5C,8BAA8B;QAC9B,IAAID,oBAAoB,CAAC;YAAC;YAAS;YAAS;SAAO,CAACE,QAAQ,CAACF,mBAAmB;YAC9E,OAAO;QACT;QAEA,iEAAiE;QACjE,MAAMG,eAAeV,QAClBW,OAAO,CAAC,oBAAoB,IAC5BA,OAAO,CAAC,oBAAoB,IAC5BA,OAAO,CAAC,gBAAgB,IACxBC,IAAI;QAEP,+CAA+C;QAC/C,MAAMC,mBAAmBH,aAAaJ,KAAK,CAAC;QAC5C,IAAI,CAACO,oBAAoBA,gBAAgB,CAAC,EAAE,KAAK,OAAO;YACtD,OAAO;QACT;QAEA,yDAAyD;QACzD,MAAMC,oBAAoB;QAC1B,IAAI,CAACA,kBAAkBC,IAAI,CAACf,UAAU;YACpC,OAAO;QACT;QAEA,mDAAmD;QACnD,MAAMgB,aAAahB,QAAQM,KAAK,CAAC;QACjC,IAAI,CAACU,YAAY;YACf,OAAO;QACT;QAEA,OAAO;IACT,EAAE,OAAOC,QAAQ;QACf,uDAAuD;QACvD,OAAO;IACT;AACF"}
1
+ {"version":3,"sources":["../../src/uploads/detectSvgFromXml.ts"],"sourcesContent":["import { inspectSvg } from './validateSvg.js'\n\n/** Detect whether an XML document's root element is namespaced SVG. */\nexport function detectSvgFromXml(buffer: Buffer): boolean {\n return inspectSvg(buffer).isSvg\n}\n"],"names":["inspectSvg","detectSvgFromXml","buffer","isSvg"],"mappings":"AAAA,SAASA,UAAU,QAAQ,mBAAkB;AAE7C,qEAAqE,GACrE,OAAO,SAASC,iBAAiBC,MAAc;IAC7C,OAAOF,WAAWE,QAAQC,KAAK;AACjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../../../src/uploads/endpoints/getFile.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAU3D,eAAO,MAAM,cAAc,EAAE,cA6J5B,CAAA"}
1
+ {"version":3,"file":"getFile.d.ts","sourceRoot":"","sources":["../../../src/uploads/endpoints/getFile.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAY3D,eAAO,MAAM,cAAc,EAAE,cAgK5B,CAAA"}
@@ -6,7 +6,9 @@ import { APIError } from '../../errors/APIError.js';
6
6
  import { checkFileAccess } from '../../uploads/checkFileAccess.js';
7
7
  import { streamFile } from '../../uploads/fetchAPI-stream-file/index.js';
8
8
  import { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js';
9
+ import { getFileExtension, isXmlMimeType } from '../../uploads/getFileTypeIdentity.js';
9
10
  import { parseRangeHeader } from '../../uploads/parseRangeHeader.js';
11
+ import { UPLOAD_CONTENT_SECURITY_POLICY } from '../../uploads/uploadContentSecurityPolicy.js';
10
12
  import { getRequestCollection } from '../../utilities/getRequestEntity.js';
11
13
  import { headersWithCors } from '../../utilities/headersWithCors.js';
12
14
  export const getFileHandler = async (req)=>{
@@ -80,7 +82,7 @@ export const getFileHandler = async (req)=>{
80
82
  }
81
83
  const fileTypeResult = await fileTypeFromFile(filePath) || getFileTypeFallback(filePath);
82
84
  let mimeType = fileTypeResult.mime;
83
- if (filePath.endsWith('.svg') && fileTypeResult.mime === 'application/xml') {
85
+ if (getFileExtension(filePath).toLowerCase() === 'svg' && fileTypeResult.mime === 'application/xml') {
84
86
  mimeType = 'image/svg+xml';
85
87
  }
86
88
  // Parse Range header for byte range requests
@@ -106,8 +108,8 @@ export const getFileHandler = async (req)=>{
106
108
  let headers = new Headers();
107
109
  headers.set('Content-Type', mimeType);
108
110
  headers.set('Accept-Ranges', 'bytes');
109
- if (mimeType === 'image/svg+xml') {
110
- headers.set('Content-Security-Policy', "script-src 'none'");
111
+ if (isXmlMimeType(mimeType)) {
112
+ headers.set('Content-Security-Policy', UPLOAD_CONTENT_SECURITY_POLICY);
111
113
  }
112
114
  let data;
113
115
  let status;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/uploads/endpoints/getFile.ts"],"sourcesContent":["import type { Stats } from 'fs'\n\nimport { fileTypeFromFile } from 'file-type'\nimport fsPromises from 'fs/promises'\nimport { status as httpStatus } from 'http-status'\nimport path from 'path'\n\nimport type { PayloadHandler } from '../../config/types.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { checkFileAccess } from '../../uploads/checkFileAccess.js'\nimport { streamFile } from '../../uploads/fetchAPI-stream-file/index.js'\nimport { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js'\nimport { parseRangeHeader } from '../../uploads/parseRangeHeader.js'\nimport { getRequestCollection } from '../../utilities/getRequestEntity.js'\nimport { headersWithCors } from '../../utilities/headersWithCors.js'\n\nexport const getFileHandler: PayloadHandler = async (req) => {\n const collection = getRequestCollection(req)\n\n const filename = req.routeParams?.filename as string\n const prefix = req.searchParams?.get('prefix') ?? undefined\n\n if (!collection.config.upload) {\n throw new APIError(\n `This collection is not an upload collection: ${collection.config.slug}`,\n httpStatus.BAD_REQUEST,\n )\n }\n\n const accessResult = (await checkFileAccess({\n collection,\n filename,\n prefix,\n req,\n }))!\n\n if (accessResult instanceof Response) {\n return accessResult\n }\n\n if (collection.config.upload.handlers?.length) {\n let customResponse: null | Response | void = null\n const headers = new Headers()\n\n for (const handler of collection.config.upload.handlers) {\n customResponse = await handler(req, {\n doc: accessResult,\n headers,\n params: {\n collection: collection.config.slug,\n filename,\n prefix,\n },\n })\n if (customResponse && customResponse instanceof Response) {\n break\n }\n }\n\n if (customResponse instanceof Response) {\n return customResponse\n }\n }\n\n // Local filesystem fallback — cloud storage handlers return a Response above\n // and have their own filename validation via sanitizeFilename.\n const fileDir = collection.config.upload?.staticDir || collection.config.slug\n const resolvedDir = path.resolve(fileDir)\n const filePath = path.resolve(resolvedDir, filename)\n\n if (!filePath.startsWith(resolvedDir + path.sep)) {\n throw new APIError('Invalid filename.', httpStatus.BAD_REQUEST)\n }\n\n let stats: Stats\n\n try {\n stats = await fsPromises.stat(filePath)\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n req.payload.logger.error(\n `File ${filename} for collection ${collection.config.slug} is missing on the disk. Expected path: ${filePath}`,\n )\n\n // Omit going to the routeError handler by returning response instead of\n // throwing an error to cut down log noise. The response still matches what you get with APIError to not leak details to the user.\n return Response.json(\n {\n errors: [\n {\n message: 'Something went wrong.',\n },\n ],\n },\n {\n headers: headersWithCors({\n headers: new Headers(),\n req,\n }),\n status: 500,\n },\n )\n }\n\n throw err\n }\n\n const fileTypeResult = (await fileTypeFromFile(filePath)) || getFileTypeFallback(filePath)\n let mimeType = fileTypeResult.mime\n\n if (filePath.endsWith('.svg') && fileTypeResult.mime === 'application/xml') {\n mimeType = 'image/svg+xml'\n }\n\n // Parse Range header for byte range requests\n const rangeHeader = req.headers.get('range')\n const rangeResult = parseRangeHeader({\n fileSize: stats.size,\n rangeHeader,\n })\n\n if (rangeResult.type === 'invalid') {\n let headers = new Headers()\n headers.set('Content-Range', `bytes */${stats.size}`)\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(null, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status: httpStatus.REQUESTED_RANGE_NOT_SATISFIABLE,\n })\n }\n\n let headers = new Headers()\n headers.set('Content-Type', mimeType)\n headers.set('Accept-Ranges', 'bytes')\n\n if (mimeType === 'image/svg+xml') {\n headers.set('Content-Security-Policy', \"script-src 'none'\")\n }\n\n let data: ReadableStream\n let status: number\n const isPartial = rangeResult.type === 'partial'\n const range = rangeResult.range\n\n if (isPartial && range) {\n const contentLength = range.end - range.start + 1\n headers.set('Content-Length', String(contentLength))\n headers.set('Content-Range', `bytes ${range.start}-${range.end}/${stats.size}`)\n data = streamFile({ filePath, options: { end: range.end, start: range.start } })\n status = httpStatus.PARTIAL_CONTENT\n } else {\n headers.set('Content-Length', String(stats.size))\n data = streamFile({ filePath })\n status = httpStatus.OK\n }\n\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(data, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status,\n })\n}\n"],"names":["fileTypeFromFile","fsPromises","status","httpStatus","path","APIError","checkFileAccess","streamFile","getFileTypeFallback","parseRangeHeader","getRequestCollection","headersWithCors","getFileHandler","req","collection","filename","routeParams","prefix","searchParams","get","undefined","config","upload","slug","BAD_REQUEST","accessResult","Response","handlers","length","customResponse","headers","Headers","handler","doc","params","fileDir","staticDir","resolvedDir","resolve","filePath","startsWith","sep","stats","stat","err","code","payload","logger","error","json","errors","message","fileTypeResult","mimeType","mime","endsWith","rangeHeader","rangeResult","fileSize","size","type","set","modifyResponseHeaders","REQUESTED_RANGE_NOT_SATISFIABLE","data","isPartial","range","contentLength","end","start","String","options","PARTIAL_CONTENT","OK"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/uploads/endpoints/getFile.ts"],"sourcesContent":["import type { Stats } from 'fs'\n\nimport { fileTypeFromFile } from 'file-type'\nimport fsPromises from 'fs/promises'\nimport { status as httpStatus } from 'http-status'\nimport path from 'path'\n\nimport type { PayloadHandler } from '../../config/types.js'\n\nimport { APIError } from '../../errors/APIError.js'\nimport { checkFileAccess } from '../../uploads/checkFileAccess.js'\nimport { streamFile } from '../../uploads/fetchAPI-stream-file/index.js'\nimport { getFileTypeFallback } from '../../uploads/getFileTypeFallback.js'\nimport { getFileExtension, isXmlMimeType } from '../../uploads/getFileTypeIdentity.js'\nimport { parseRangeHeader } from '../../uploads/parseRangeHeader.js'\nimport { UPLOAD_CONTENT_SECURITY_POLICY } from '../../uploads/uploadContentSecurityPolicy.js'\nimport { getRequestCollection } from '../../utilities/getRequestEntity.js'\nimport { headersWithCors } from '../../utilities/headersWithCors.js'\n\nexport const getFileHandler: PayloadHandler = async (req) => {\n const collection = getRequestCollection(req)\n\n const filename = req.routeParams?.filename as string\n const prefix = req.searchParams?.get('prefix') ?? undefined\n\n if (!collection.config.upload) {\n throw new APIError(\n `This collection is not an upload collection: ${collection.config.slug}`,\n httpStatus.BAD_REQUEST,\n )\n }\n\n const accessResult = (await checkFileAccess({\n collection,\n filename,\n prefix,\n req,\n }))!\n\n if (accessResult instanceof Response) {\n return accessResult\n }\n\n if (collection.config.upload.handlers?.length) {\n let customResponse: null | Response | void = null\n const headers = new Headers()\n\n for (const handler of collection.config.upload.handlers) {\n customResponse = await handler(req, {\n doc: accessResult,\n headers,\n params: {\n collection: collection.config.slug,\n filename,\n prefix,\n },\n })\n if (customResponse && customResponse instanceof Response) {\n break\n }\n }\n\n if (customResponse instanceof Response) {\n return customResponse\n }\n }\n\n // Local filesystem fallback — cloud storage handlers return a Response above\n // and have their own filename validation via sanitizeFilename.\n const fileDir = collection.config.upload?.staticDir || collection.config.slug\n const resolvedDir = path.resolve(fileDir)\n const filePath = path.resolve(resolvedDir, filename)\n\n if (!filePath.startsWith(resolvedDir + path.sep)) {\n throw new APIError('Invalid filename.', httpStatus.BAD_REQUEST)\n }\n\n let stats: Stats\n\n try {\n stats = await fsPromises.stat(filePath)\n } catch (err) {\n if ((err as { code?: string }).code === 'ENOENT') {\n req.payload.logger.error(\n `File ${filename} for collection ${collection.config.slug} is missing on the disk. Expected path: ${filePath}`,\n )\n\n // Omit going to the routeError handler by returning response instead of\n // throwing an error to cut down log noise. The response still matches what you get with APIError to not leak details to the user.\n return Response.json(\n {\n errors: [\n {\n message: 'Something went wrong.',\n },\n ],\n },\n {\n headers: headersWithCors({\n headers: new Headers(),\n req,\n }),\n status: 500,\n },\n )\n }\n\n throw err\n }\n\n const fileTypeResult = (await fileTypeFromFile(filePath)) || getFileTypeFallback(filePath)\n let mimeType = fileTypeResult.mime\n\n if (\n getFileExtension(filePath).toLowerCase() === 'svg' &&\n fileTypeResult.mime === 'application/xml'\n ) {\n mimeType = 'image/svg+xml'\n }\n\n // Parse Range header for byte range requests\n const rangeHeader = req.headers.get('range')\n const rangeResult = parseRangeHeader({\n fileSize: stats.size,\n rangeHeader,\n })\n\n if (rangeResult.type === 'invalid') {\n let headers = new Headers()\n headers.set('Content-Range', `bytes */${stats.size}`)\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(null, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status: httpStatus.REQUESTED_RANGE_NOT_SATISFIABLE,\n })\n }\n\n let headers = new Headers()\n headers.set('Content-Type', mimeType)\n headers.set('Accept-Ranges', 'bytes')\n\n if (isXmlMimeType(mimeType)) {\n headers.set('Content-Security-Policy', UPLOAD_CONTENT_SECURITY_POLICY)\n }\n\n let data: ReadableStream\n let status: number\n const isPartial = rangeResult.type === 'partial'\n const range = rangeResult.range\n\n if (isPartial && range) {\n const contentLength = range.end - range.start + 1\n headers.set('Content-Length', String(contentLength))\n headers.set('Content-Range', `bytes ${range.start}-${range.end}/${stats.size}`)\n data = streamFile({ filePath, options: { end: range.end, start: range.start } })\n status = httpStatus.PARTIAL_CONTENT\n } else {\n headers.set('Content-Length', String(stats.size))\n data = streamFile({ filePath })\n status = httpStatus.OK\n }\n\n headers = collection.config.upload?.modifyResponseHeaders\n ? collection.config.upload.modifyResponseHeaders({ headers }) || headers\n : headers\n\n return new Response(data, {\n headers: headersWithCors({\n headers,\n req,\n }),\n status,\n })\n}\n"],"names":["fileTypeFromFile","fsPromises","status","httpStatus","path","APIError","checkFileAccess","streamFile","getFileTypeFallback","getFileExtension","isXmlMimeType","parseRangeHeader","UPLOAD_CONTENT_SECURITY_POLICY","getRequestCollection","headersWithCors","getFileHandler","req","collection","filename","routeParams","prefix","searchParams","get","undefined","config","upload","slug","BAD_REQUEST","accessResult","Response","handlers","length","customResponse","headers","Headers","handler","doc","params","fileDir","staticDir","resolvedDir","resolve","filePath","startsWith","sep","stats","stat","err","code","payload","logger","error","json","errors","message","fileTypeResult","mimeType","mime","toLowerCase","rangeHeader","rangeResult","fileSize","size","type","set","modifyResponseHeaders","REQUESTED_RANGE_NOT_SATISFIABLE","data","isPartial","range","contentLength","end","start","String","options","PARTIAL_CONTENT","OK"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import type { FetchAPIFileUploadOptions } from '../../config/types.js';
2
2
  type Handler = (options: FetchAPIFileUploadOptions, fieldname: string, filename: string) => {
3
- cleanup: () => void;
3
+ cleanup: () => Promise<void> | void;
4
4
  complete: () => Buffer;
5
- dataHandler: (data: Buffer) => void;
5
+ dataHandler: (data: Buffer) => Promise<void> | void;
6
6
  getFilePath: () => string;
7
7
  getFileSize: () => number;
8
8
  getHash: () => string;
@@ -1 +1 @@
1
- {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/uploads/fetchAPI-multipart/handlers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAItE,KAAK,OAAO,GAAG,CACb,OAAO,EAAE,yBAAyB,EAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,KACb;IACH,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,QAAQ,EAAE,MAAM,MAAM,CAAA;IACtB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,WAAW,EAAE,MAAM,MAAM,CAAA;IACzB,WAAW,EAAE,MAAM,MAAM,CAAA;IACzB,OAAO,EAAE,MAAM,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACxC,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,OAuD7B,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,OAgCxB,CAAA"}
1
+ {"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../../src/uploads/fetchAPI-multipart/handlers.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAItE,KAAK,OAAO,GAAG,CACb,OAAO,EAAE,yBAAyB,EAClC,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,KACb;IACH,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACnC,QAAQ,EAAE,MAAM,MAAM,CAAA;IACtB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACnD,WAAW,EAAE,MAAM,MAAM,CAAA;IACzB,WAAW,EAAE,MAAM,MAAM,CAAA;IACzB,OAAO,EAAE,MAAM,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,OAAO,CAAC,OAAO,CAAC,CAAA;CACxC,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,OA6D7B,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,OAmCxB,CAAA"}
@@ -15,6 +15,7 @@ export const tempFileHandler = (options, fieldname, filename)=>{
15
15
  const writeStream = fs.createWriteStream(tempFilePath);
16
16
  const writePromise = new Promise((resolve, reject)=>{
17
17
  writeStream.on('finish', ()=>resolve(true));
18
+ writeStream.on('close', ()=>resolve(false));
18
19
  writeStream.on('error', (err)=>{
19
20
  debugLog(options, `Error write temp file: ${err}`);
20
21
  reject(err);
@@ -23,9 +24,15 @@ export const tempFileHandler = (options, fieldname, filename)=>{
23
24
  return {
24
25
  cleanup: ()=>{
25
26
  completed = true;
26
- debugLog(options, `Cleaning up temporary file ${tempFilePath}...`);
27
- writeStream.end();
28
- deleteFile(tempFilePath, (err)=>err ? debugLog(options, `Cleaning up temporary file ${tempFilePath} failed: ${err}`) : debugLog(options, `Cleaning up temporary file ${tempFilePath} done.`));
27
+ return new Promise((resolve)=>{
28
+ const remove = ()=>deleteFile(tempFilePath, ()=>resolve());
29
+ if (writeStream.closed) {
30
+ remove();
31
+ } else {
32
+ writeStream.once('close', remove);
33
+ writeStream.destroy();
34
+ }
35
+ });
29
36
  },
30
37
  complete: ()=>{
31
38
  completed = true;
@@ -41,10 +48,13 @@ export const tempFileHandler = (options, fieldname, filename)=>{
41
48
  debugLog(options, `Error: got ${fieldname}->${filename} data chunk for completed upload!`);
42
49
  return;
43
50
  }
44
- writeStream.write(data);
51
+ const ready = writeStream.write(data);
45
52
  hash.update(data);
46
53
  fileSize += data.length;
47
54
  debugLog(options, `Uploading ${fieldname}->${filename}, bytes:${fileSize}...`);
55
+ if (!ready) {
56
+ return new Promise((resolve)=>writeStream.once('drain', resolve));
57
+ }
48
58
  },
49
59
  getFilePath: ()=>tempFilePath,
50
60
  getFileSize: ()=>fileSize,
@@ -61,11 +71,14 @@ export const memHandler = (options, fieldname, filename)=>{
61
71
  return {
62
72
  cleanup: ()=>{
63
73
  completed = true;
74
+ buffers.length = 0;
64
75
  },
65
76
  complete: ()=>{
66
77
  debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`);
67
78
  completed = true;
68
- return getBuffer();
79
+ const buffer = getBuffer();
80
+ buffers.length = 0;
81
+ return buffer;
69
82
  },
70
83
  dataHandler: (data)=>{
71
84
  if (completed === true) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/uploads/fetchAPI-multipart/handlers.ts"],"sourcesContent":["import crypto from 'crypto'\nimport fs, { WriteStream } from 'fs'\nimport path from 'path'\n\nimport type { FetchAPIFileUploadOptions } from '../../config/types.js'\n\nimport { checkAndMakeDir, debugLog, deleteFile, getTempFilename } from './utilities.js'\n\ntype Handler = (\n options: FetchAPIFileUploadOptions,\n fieldname: string,\n filename: string,\n) => {\n cleanup: () => void\n complete: () => Buffer\n dataHandler: (data: Buffer) => void\n getFilePath: () => string\n getFileSize: () => number\n getHash: () => string\n getWritePromise: () => Promise<boolean>\n}\n\nexport const tempFileHandler: Handler = (options, fieldname, filename) => {\n const tempFilePath = path.resolve(options.tempFileDir!, getTempFilename())\n checkAndMakeDir({ createParentPath: true }, tempFilePath)\n\n debugLog(options, `Temporary file path is ${tempFilePath}`)\n\n const hash = crypto.createHash('md5')\n let fileSize = 0\n let completed = false\n\n debugLog(options, `Opening write stream for ${fieldname}->${filename}...`)\n const writeStream = fs.createWriteStream(tempFilePath)\n const writePromise = new Promise<boolean>((resolve, reject) => {\n writeStream.on('finish', () => resolve(true))\n writeStream.on('error', (err) => {\n debugLog(options, `Error write temp file: ${err}`)\n reject(err)\n })\n })\n\n return {\n cleanup: () => {\n completed = true\n debugLog(options, `Cleaning up temporary file ${tempFilePath}...`)\n writeStream.end()\n deleteFile(tempFilePath, (err) =>\n err\n ? debugLog(options, `Cleaning up temporary file ${tempFilePath} failed: ${err}`)\n : debugLog(options, `Cleaning up temporary file ${tempFilePath} done.`),\n )\n },\n complete: () => {\n completed = true\n debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`)\n if (writeStream instanceof WriteStream) {\n writeStream.end()\n }\n // Return empty buff since data was uploaded into a temp file.\n return Buffer.concat([])\n },\n dataHandler: (data) => {\n if (completed === true) {\n debugLog(options, `Error: got ${fieldname}->${filename} data chunk for completed upload!`)\n return\n }\n writeStream.write(data)\n hash.update(data)\n fileSize += data.length\n debugLog(options, `Uploading ${fieldname}->${filename}, bytes:${fileSize}...`)\n },\n getFilePath: () => tempFilePath,\n getFileSize: () => fileSize,\n getHash: () => hash.digest('hex'),\n getWritePromise: () => writePromise,\n }\n}\n\nexport const memHandler: Handler = (options, fieldname, filename) => {\n const buffers: Buffer[] = []\n const hash = crypto.createHash('md5')\n let fileSize = 0\n let completed = false\n\n const getBuffer = () => Buffer.concat(buffers, fileSize)\n\n return {\n cleanup: () => {\n completed = true\n },\n complete: () => {\n debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`)\n completed = true\n return getBuffer()\n },\n dataHandler: (data) => {\n if (completed === true) {\n debugLog(options, `Error: got ${fieldname}->${filename} data chunk for completed upload!`)\n return\n }\n buffers.push(data)\n hash.update(data)\n fileSize += data.length\n debugLog(options, `Uploading ${fieldname}->${filename}, bytes:${fileSize}...`)\n },\n getFilePath: () => '',\n getFileSize: () => fileSize,\n getHash: () => hash.digest('hex'),\n getWritePromise: () => Promise.resolve(true),\n }\n}\n"],"names":["crypto","fs","WriteStream","path","checkAndMakeDir","debugLog","deleteFile","getTempFilename","tempFileHandler","options","fieldname","filename","tempFilePath","resolve","tempFileDir","createParentPath","hash","createHash","fileSize","completed","writeStream","createWriteStream","writePromise","Promise","reject","on","err","cleanup","end","complete","Buffer","concat","dataHandler","data","write","update","length","getFilePath","getFileSize","getHash","digest","getWritePromise","memHandler","buffers","getBuffer","push"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/uploads/fetchAPI-multipart/handlers.ts"],"sourcesContent":["import crypto from 'crypto'\nimport fs, { WriteStream } from 'fs'\nimport path from 'path'\n\nimport type { FetchAPIFileUploadOptions } from '../../config/types.js'\n\nimport { checkAndMakeDir, debugLog, deleteFile, getTempFilename } from './utilities.js'\n\ntype Handler = (\n options: FetchAPIFileUploadOptions,\n fieldname: string,\n filename: string,\n) => {\n cleanup: () => Promise<void> | void\n complete: () => Buffer\n dataHandler: (data: Buffer) => Promise<void> | void\n getFilePath: () => string\n getFileSize: () => number\n getHash: () => string\n getWritePromise: () => Promise<boolean>\n}\n\nexport const tempFileHandler: Handler = (options, fieldname, filename) => {\n const tempFilePath = path.resolve(options.tempFileDir!, getTempFilename())\n checkAndMakeDir({ createParentPath: true }, tempFilePath)\n\n debugLog(options, `Temporary file path is ${tempFilePath}`)\n\n const hash = crypto.createHash('md5')\n let fileSize = 0\n let completed = false\n\n debugLog(options, `Opening write stream for ${fieldname}->${filename}...`)\n const writeStream = fs.createWriteStream(tempFilePath)\n const writePromise = new Promise<boolean>((resolve, reject) => {\n writeStream.on('finish', () => resolve(true))\n writeStream.on('close', () => resolve(false))\n writeStream.on('error', (err) => {\n debugLog(options, `Error write temp file: ${err}`)\n reject(err)\n })\n })\n\n return {\n cleanup: () => {\n completed = true\n return new Promise<void>((resolve) => {\n const remove = () => deleteFile(tempFilePath, () => resolve())\n if (writeStream.closed) {\n remove()\n } else {\n writeStream.once('close', remove)\n writeStream.destroy()\n }\n })\n },\n complete: () => {\n completed = true\n debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`)\n if (writeStream instanceof WriteStream) {\n writeStream.end()\n }\n // Return empty buff since data was uploaded into a temp file.\n return Buffer.concat([])\n },\n dataHandler: (data) => {\n if (completed === true) {\n debugLog(options, `Error: got ${fieldname}->${filename} data chunk for completed upload!`)\n return\n }\n const ready = writeStream.write(data)\n hash.update(data)\n fileSize += data.length\n debugLog(options, `Uploading ${fieldname}->${filename}, bytes:${fileSize}...`)\n if (!ready) {\n return new Promise<void>((resolve) => writeStream.once('drain', resolve))\n }\n },\n getFilePath: () => tempFilePath,\n getFileSize: () => fileSize,\n getHash: () => hash.digest('hex'),\n getWritePromise: () => writePromise,\n }\n}\n\nexport const memHandler: Handler = (options, fieldname, filename) => {\n const buffers: Buffer[] = []\n const hash = crypto.createHash('md5')\n let fileSize = 0\n let completed = false\n\n const getBuffer = () => Buffer.concat(buffers, fileSize)\n\n return {\n cleanup: () => {\n completed = true\n buffers.length = 0\n },\n complete: () => {\n debugLog(options, `Upload ${fieldname}->${filename} completed, bytes:${fileSize}.`)\n completed = true\n const buffer = getBuffer()\n buffers.length = 0\n return buffer\n },\n dataHandler: (data) => {\n if (completed === true) {\n debugLog(options, `Error: got ${fieldname}->${filename} data chunk for completed upload!`)\n return\n }\n buffers.push(data)\n hash.update(data)\n fileSize += data.length\n debugLog(options, `Uploading ${fieldname}->${filename}, bytes:${fileSize}...`)\n },\n getFilePath: () => '',\n getFileSize: () => fileSize,\n getHash: () => hash.digest('hex'),\n getWritePromise: () => Promise.resolve(true),\n }\n}\n"],"names":["crypto","fs","WriteStream","path","checkAndMakeDir","debugLog","deleteFile","getTempFilename","tempFileHandler","options","fieldname","filename","tempFilePath","resolve","tempFileDir","createParentPath","hash","createHash","fileSize","completed","writeStream","createWriteStream","writePromise","Promise","reject","on","err","cleanup","remove","closed","once","destroy","complete","end","Buffer","concat","dataHandler","data","ready","write","update","length","getFilePath","getFileSize","getHash","digest","getWritePromise","memHandler","buffers","getBuffer","buffer","push"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/uploads/fetchAPI-multipart/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAqBnD,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACpE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,KAAK,8BAA8B,GAAG;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAA;CACtD,CAAA;AAED,KAAK,kBAAkB,GAAG,CAAC,IAAI,EAAE;IAC/B,OAAO,CAAC,EAAE,yBAAyB,CAAA;IACnC,OAAO,EAAE,OAAO,CAAA;CACjB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAA;AAEzC,eAAO,MAAM,wBAAwB,EAAE,kBAiBtC,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/uploads/fetchAPI-multipart/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,uBAAuB,CAAA;AAEtE,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAA;AAyBnD,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,EAAE,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACpE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED,KAAK,8BAA8B,GAAG;IACpC,IAAI,EAAE,MAAM,CAAA;IACZ,QAAQ,EAAE,MAAM,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACvC,KAAK,CAAC,EAAE,QAAQ,CAAA;IAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAA;CACtD,CAAA;AAED,KAAK,kBAAkB,GAAG,CAAC,IAAI,EAAE;IAC/B,OAAO,CAAC,EAAE,yBAAyB,CAAA;IACnC,OAAO,EAAE,OAAO,CAAA;CACjB,KAAK,OAAO,CAAC,0BAA0B,CAAC,CAAA;AAEzC,eAAO,MAAM,wBAAwB,EAAE,kBA2CtC,CAAA"}
@@ -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"}