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.
- package/dist/admin/forms/Field.d.ts +2 -0
- package/dist/admin/forms/Field.d.ts.map +1 -1
- package/dist/admin/forms/Field.js.map +1 -1
- package/dist/admin/forms/Form.d.ts +2 -0
- package/dist/admin/forms/Form.d.ts.map +1 -1
- package/dist/admin/forms/Form.js.map +1 -1
- package/dist/admin/functions/index.d.ts +3 -1
- package/dist/admin/functions/index.d.ts.map +1 -1
- package/dist/admin/functions/index.js.map +1 -1
- package/dist/admin/views/dashboard.d.ts +1 -1
- package/dist/admin/views/dashboard.d.ts.map +1 -1
- package/dist/admin/views/dashboard.js.map +1 -1
- package/dist/auth/applyUserReadAccess.d.ts +15 -0
- package/dist/auth/applyUserReadAccess.d.ts.map +1 -0
- package/dist/auth/applyUserReadAccess.js +41 -0
- package/dist/auth/applyUserReadAccess.js.map +1 -0
- package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.d.ts +4 -0
- package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.d.ts.map +1 -0
- package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.js +20 -0
- package/dist/auth/baseFields/apiKey/canCreateOrUpdateAPIKey.js.map +1 -0
- package/dist/auth/baseFields/apiKey/encryptAPIKey.d.ts +4 -0
- package/dist/auth/baseFields/apiKey/encryptAPIKey.d.ts.map +1 -0
- package/dist/auth/baseFields/apiKey/encryptAPIKey.js +16 -0
- package/dist/auth/baseFields/apiKey/encryptAPIKey.js.map +1 -0
- package/dist/auth/baseFields/apiKey/index.d.ts +6 -0
- package/dist/auth/baseFields/apiKey/index.d.ts.map +1 -0
- package/dist/auth/baseFields/apiKey/index.js +112 -0
- package/dist/auth/baseFields/apiKey/index.js.map +1 -0
- package/dist/auth/baseFields/apiKey/omitAPIKey.d.ts +4 -0
- package/dist/auth/baseFields/apiKey/omitAPIKey.d.ts.map +1 -0
- package/dist/auth/baseFields/apiKey/omitAPIKey.js +8 -0
- package/dist/auth/baseFields/apiKey/omitAPIKey.js.map +1 -0
- package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.d.ts +4 -0
- package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.d.ts.map +1 -0
- package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.js +5 -0
- package/dist/auth/baseFields/apiKey/omitAPIKeyIndex.js.map +1 -0
- package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.d.ts +4 -0
- package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.d.ts.map +1 -0
- package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.js +5 -0
- package/dist/auth/baseFields/apiKey/omitEncryptedAPIKey.js.map +1 -0
- package/dist/auth/baseFields/apiKey/setAPIKeyIndex.d.ts +4 -0
- package/dist/auth/baseFields/apiKey/setAPIKeyIndex.d.ts.map +1 -0
- package/dist/auth/baseFields/apiKey/setAPIKeyIndex.js +17 -0
- package/dist/auth/baseFields/apiKey/setAPIKeyIndex.js.map +1 -0
- package/dist/auth/baseFields/auth.d.ts +1 -0
- package/dist/auth/baseFields/auth.d.ts.map +1 -1
- package/dist/auth/baseFields/auth.js +9 -0
- package/dist/auth/baseFields/auth.js.map +1 -1
- package/dist/auth/defaultUnlockAccess.d.ts +3 -0
- package/dist/auth/defaultUnlockAccess.d.ts.map +1 -0
- package/dist/auth/defaultUnlockAccess.js +8 -0
- package/dist/auth/defaultUnlockAccess.js.map +1 -0
- package/dist/auth/endpoints/index.d.ts +1 -0
- package/dist/auth/endpoints/index.d.ts.map +1 -1
- package/dist/auth/endpoints/index.js +8 -0
- package/dist/auth/endpoints/index.js.map +1 -1
- package/dist/auth/endpoints/revealAPIKey.d.ts +7 -0
- package/dist/auth/endpoints/revealAPIKey.d.ts.map +1 -0
- package/dist/auth/endpoints/revealAPIKey.js +120 -0
- package/dist/auth/endpoints/revealAPIKey.js.map +1 -0
- package/dist/auth/executeAccess.d.ts +3 -1
- package/dist/auth/executeAccess.d.ts.map +1 -1
- package/dist/auth/executeAccess.js +2 -1
- package/dist/auth/executeAccess.js.map +1 -1
- package/dist/auth/getAuthFields.d.ts +1 -1
- package/dist/auth/getAuthFields.d.ts.map +1 -1
- package/dist/auth/getAuthFields.js +7 -4
- package/dist/auth/getAuthFields.js.map +1 -1
- package/dist/auth/getFieldsToSign.d.ts.map +1 -1
- package/dist/auth/getFieldsToSign.js +17 -10
- package/dist/auth/getFieldsToSign.js.map +1 -1
- package/dist/auth/getFieldsToSign.spec.js +114 -0
- package/dist/auth/getFieldsToSign.spec.js.map +1 -0
- package/dist/auth/jwt.d.ts.map +1 -1
- package/dist/auth/jwt.js +2 -0
- package/dist/auth/jwt.js.map +1 -1
- package/dist/auth/jwt.spec.js +24 -0
- package/dist/auth/jwt.spec.js.map +1 -0
- package/dist/auth/jwtAuth.d.ts +9 -0
- package/dist/auth/jwtAuth.d.ts.map +1 -0
- package/dist/auth/jwtAuth.js +8 -0
- package/dist/auth/jwtAuth.js.map +1 -0
- package/dist/auth/operations/auth.d.ts.map +1 -1
- package/dist/auth/operations/auth.js +2 -1
- package/dist/auth/operations/auth.js.map +1 -1
- package/dist/auth/operations/forgotPassword.d.ts.map +1 -1
- package/dist/auth/operations/forgotPassword.js +95 -7
- package/dist/auth/operations/forgotPassword.js.map +1 -1
- package/dist/auth/operations/local/auth.js +3 -1
- package/dist/auth/operations/local/auth.js.map +1 -1
- package/dist/auth/operations/login.d.ts.map +1 -1
- package/dist/auth/operations/login.js +48 -26
- package/dist/auth/operations/login.js.map +1 -1
- package/dist/auth/operations/refresh.d.ts.map +1 -1
- package/dist/auth/operations/refresh.js +32 -9
- package/dist/auth/operations/refresh.js.map +1 -1
- package/dist/auth/operations/registerFirstUser.d.ts.map +1 -1
- package/dist/auth/operations/registerFirstUser.js +3 -4
- package/dist/auth/operations/registerFirstUser.js.map +1 -1
- package/dist/auth/operations/resetPassword.d.ts.map +1 -1
- package/dist/auth/operations/resetPassword.js +31 -22
- package/dist/auth/operations/resetPassword.js.map +1 -1
- package/dist/auth/operations/unlock.d.ts.map +1 -1
- package/dist/auth/operations/unlock.js +1 -0
- package/dist/auth/operations/unlock.js.map +1 -1
- package/dist/auth/strategies/apiKey.d.ts.map +1 -1
- package/dist/auth/strategies/apiKey.js +15 -1
- package/dist/auth/strategies/apiKey.js.map +1 -1
- package/dist/auth/strategies/jwt.d.ts.map +1 -1
- package/dist/auth/strategies/jwt.js +61 -10
- package/dist/auth/strategies/jwt.js.map +1 -1
- package/dist/auth/strategies/jwt.spec.js +281 -0
- package/dist/auth/strategies/jwt.spec.js.map +1 -0
- package/dist/auth/strategies/local/authenticate.d.ts +5 -1
- package/dist/auth/strategies/local/authenticate.d.ts.map +1 -1
- package/dist/auth/strategies/local/authenticate.js +8 -3
- package/dist/auth/strategies/local/authenticate.js.map +1 -1
- package/dist/auth/strategies/local/authenticate.spec.js +37 -10
- package/dist/auth/strategies/local/authenticate.spec.js.map +1 -1
- package/dist/auth/strategies/local/generatePasswordSaltHash.d.ts +9 -1
- package/dist/auth/strategies/local/generatePasswordSaltHash.d.ts.map +1 -1
- package/dist/auth/strategies/local/generatePasswordSaltHash.js +61 -34
- package/dist/auth/strategies/local/generatePasswordSaltHash.js.map +1 -1
- package/dist/auth/types.d.ts +16 -1
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/types.js.map +1 -1
- package/dist/collections/config/client.d.ts +1 -0
- package/dist/collections/config/client.d.ts.map +1 -1
- package/dist/collections/config/client.js +3 -0
- package/dist/collections/config/client.js.map +1 -1
- package/dist/collections/config/defaults.d.ts.map +1 -1
- package/dist/collections/config/defaults.js +4 -2
- package/dist/collections/config/defaults.js.map +1 -1
- package/dist/collections/config/sanitize.d.ts.map +1 -1
- package/dist/collections/config/sanitize.js +17 -6
- package/dist/collections/config/sanitize.js.map +1 -1
- package/dist/collections/endpoints/index.d.ts +1 -0
- package/dist/collections/endpoints/index.d.ts.map +1 -1
- package/dist/collections/endpoints/index.js +6 -5
- package/dist/collections/endpoints/index.js.map +1 -1
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +105 -8
- package/dist/collections/operations/create.js.map +1 -1
- package/dist/collections/operations/deleteByID.js +13 -13
- package/dist/collections/operations/deleteByID.js.map +1 -1
- package/dist/collections/operations/findDistinct.d.ts.map +1 -1
- package/dist/collections/operations/findDistinct.js +96 -18
- package/dist/collections/operations/findDistinct.js.map +1 -1
- package/dist/collections/operations/restoreVersion.d.ts.map +1 -1
- package/dist/collections/operations/restoreVersion.js +47 -13
- package/dist/collections/operations/restoreVersion.js.map +1 -1
- package/dist/collections/operations/update.d.ts.map +1 -1
- package/dist/collections/operations/update.js +118 -18
- package/dist/collections/operations/update.js.map +1 -1
- package/dist/collections/operations/updateByID.d.ts.map +1 -1
- package/dist/collections/operations/updateByID.js +62 -2
- package/dist/collections/operations/updateByID.js.map +1 -1
- package/dist/collections/operations/utilities/update.d.ts.map +1 -1
- package/dist/collections/operations/utilities/update.js +71 -15
- package/dist/collections/operations/utilities/update.js.map +1 -1
- package/dist/config/orderable/index.d.ts.map +1 -1
- package/dist/config/orderable/index.js +67 -14
- package/dist/config/orderable/index.js.map +1 -1
- package/dist/config/sanitize.d.ts.map +1 -1
- package/dist/config/sanitize.js +1 -1
- package/dist/config/sanitize.js.map +1 -1
- package/dist/config/types.d.ts +13 -1
- package/dist/config/types.d.ts.map +1 -1
- package/dist/config/types.js.map +1 -1
- package/dist/database/getLocalizedPaths.d.ts +2 -1
- package/dist/database/getLocalizedPaths.d.ts.map +1 -1
- package/dist/database/getLocalizedPaths.js +12 -3
- package/dist/database/getLocalizedPaths.js.map +1 -1
- package/dist/database/isNestedRelationshipQuery.d.ts +9 -0
- package/dist/database/isNestedRelationshipQuery.d.ts.map +1 -0
- package/dist/database/isNestedRelationshipQuery.js +14 -0
- package/dist/database/isNestedRelationshipQuery.js.map +1 -0
- package/dist/database/prefixWherePaths.d.ts +6 -0
- package/dist/database/prefixWherePaths.d.ts.map +1 -0
- package/dist/database/prefixWherePaths.js +19 -0
- package/dist/database/prefixWherePaths.js.map +1 -0
- package/dist/database/prefixWherePaths.spec.js +46 -0
- package/dist/database/prefixWherePaths.spec.js.map +1 -0
- package/dist/database/queryValidation/validateQueryPaths.d.ts +2 -1
- package/dist/database/queryValidation/validateQueryPaths.d.ts.map +1 -1
- package/dist/database/queryValidation/validateQueryPaths.js +4 -1
- package/dist/database/queryValidation/validateQueryPaths.js.map +1 -1
- package/dist/database/queryValidation/validateSearchParams.d.ts +2 -1
- package/dist/database/queryValidation/validateSearchParams.d.ts.map +1 -1
- package/dist/database/queryValidation/validateSearchParams.js +87 -4
- package/dist/database/queryValidation/validateSearchParams.js.map +1 -1
- package/dist/database/types.d.ts +5 -0
- package/dist/database/types.d.ts.map +1 -1
- package/dist/database/types.js.map +1 -1
- package/dist/email/normalizeSendEmailOptions.js.map +1 -1
- package/dist/email/types.d.ts +4 -1
- package/dist/email/types.d.ts.map +1 -1
- package/dist/email/types.js.map +1 -1
- package/dist/exports/internal.d.ts +7 -0
- package/dist/exports/internal.d.ts.map +1 -1
- package/dist/exports/internal.js +7 -1
- package/dist/exports/internal.js.map +1 -1
- package/dist/exports/shared.d.ts +3 -0
- package/dist/exports/shared.d.ts.map +1 -1
- package/dist/exports/shared.js +3 -0
- package/dist/exports/shared.js.map +1 -1
- package/dist/fields/config/types.d.ts +7 -5
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/config/types.js.map +1 -1
- package/dist/fields/hooks/beforeChange/index.d.ts +7 -1
- package/dist/fields/hooks/beforeChange/index.d.ts.map +1 -1
- package/dist/fields/hooks/beforeChange/index.js +4 -2
- package/dist/fields/hooks/beforeChange/index.js.map +1 -1
- package/dist/fields/hooks/beforeChange/index.spec.js +206 -0
- package/dist/fields/hooks/beforeChange/index.spec.js.map +1 -0
- package/dist/fields/hooks/beforeChange/promise.d.ts +2 -1
- package/dist/fields/hooks/beforeChange/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeChange/promise.js +51 -9
- package/dist/fields/hooks/beforeChange/promise.js.map +1 -1
- package/dist/fields/hooks/beforeChange/traverseFields.d.ts +2 -1
- package/dist/fields/hooks/beforeChange/traverseFields.d.ts.map +1 -1
- package/dist/fields/hooks/beforeChange/traverseFields.js +3 -2
- package/dist/fields/hooks/beforeChange/traverseFields.js.map +1 -1
- package/dist/fields/hooks/beforeDuplicate/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeDuplicate/promise.js +4 -0
- package/dist/fields/hooks/beforeDuplicate/promise.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/getFallbackValue.d.ts +2 -1
- package/dist/fields/hooks/beforeValidate/getFallbackValue.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/getFallbackValue.js +2 -2
- package/dist/fields/hooks/beforeValidate/getFallbackValue.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/index.d.ts +6 -1
- package/dist/fields/hooks/beforeValidate/index.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/index.js +3 -1
- package/dist/fields/hooks/beforeValidate/index.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/index.spec.js +90 -0
- package/dist/fields/hooks/beforeValidate/index.spec.js.map +1 -0
- package/dist/fields/hooks/beforeValidate/promise.d.ts +6 -1
- package/dist/fields/hooks/beforeValidate/promise.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/promise.js +23 -8
- package/dist/fields/hooks/beforeValidate/promise.js.map +1 -1
- package/dist/fields/hooks/beforeValidate/traverseFields.d.ts +6 -1
- package/dist/fields/hooks/beforeValidate/traverseFields.d.ts.map +1 -1
- package/dist/fields/hooks/beforeValidate/traverseFields.js +3 -1
- package/dist/fields/hooks/beforeValidate/traverseFields.js.map +1 -1
- package/dist/fields/validations.d.ts.map +1 -1
- package/dist/fields/validations.js +3 -1
- package/dist/fields/validations.js.map +1 -1
- package/dist/globals/operations/restoreVersion.d.ts.map +1 -1
- package/dist/globals/operations/restoreVersion.js +45 -11
- package/dist/globals/operations/restoreVersion.js.map +1 -1
- package/dist/globals/operations/update.d.ts.map +1 -1
- package/dist/globals/operations/update.js +95 -16
- package/dist/globals/operations/update.js.map +1 -1
- package/dist/index.bundled.d.ts +102 -24
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/preferences/config.d.ts.map +1 -1
- package/dist/preferences/config.js +2 -1
- package/dist/preferences/config.js.map +1 -1
- package/dist/query-presets/access.d.ts.map +1 -1
- package/dist/query-presets/access.js +2 -1
- package/dist/query-presets/access.js.map +1 -1
- package/dist/queues/config/types/index.d.ts +2 -1
- package/dist/queues/config/types/index.d.ts.map +1 -1
- package/dist/queues/config/types/index.js.map +1 -1
- package/dist/uploads/assertClientUploadAccess.d.ts +7 -0
- package/dist/uploads/assertClientUploadAccess.d.ts.map +1 -0
- package/dist/uploads/assertClientUploadAccess.js +27 -0
- package/dist/uploads/assertClientUploadAccess.js.map +1 -0
- package/dist/uploads/assertClientUploadAllowed.d.ts +11 -0
- package/dist/uploads/assertClientUploadAllowed.d.ts.map +1 -0
- package/dist/uploads/assertClientUploadAllowed.js +46 -0
- package/dist/uploads/assertClientUploadAllowed.js.map +1 -0
- package/dist/uploads/assertClientUploadAllowed.spec.js +91 -0
- package/dist/uploads/assertClientUploadAllowed.spec.js.map +1 -0
- package/dist/uploads/checkFileRestrictions.d.ts +4 -1
- package/dist/uploads/checkFileRestrictions.d.ts.map +1 -1
- package/dist/uploads/checkFileRestrictions.js +66 -26
- package/dist/uploads/checkFileRestrictions.js.map +1 -1
- package/dist/uploads/clientUploadReceipt.d.ts +23 -0
- package/dist/uploads/clientUploadReceipt.d.ts.map +1 -0
- package/dist/uploads/clientUploadReceipt.js +55 -0
- package/dist/uploads/clientUploadReceipt.js.map +1 -0
- package/dist/uploads/deleteAssociatedFiles.d.ts.map +1 -1
- package/dist/uploads/deleteAssociatedFiles.js +33 -8
- package/dist/uploads/deleteAssociatedFiles.js.map +1 -1
- package/dist/uploads/deleteAssociatedFiles.spec.js +124 -0
- package/dist/uploads/deleteAssociatedFiles.spec.js.map +1 -0
- package/dist/uploads/detectSvgFromXml.d.ts +1 -3
- package/dist/uploads/detectSvgFromXml.d.ts.map +1 -1
- package/dist/uploads/detectSvgFromXml.js +3 -40
- package/dist/uploads/detectSvgFromXml.js.map +1 -1
- package/dist/uploads/endpoints/getFile.d.ts.map +1 -1
- package/dist/uploads/endpoints/getFile.js +5 -3
- package/dist/uploads/endpoints/getFile.js.map +1 -1
- package/dist/uploads/fetchAPI-multipart/handlers.d.ts +2 -2
- package/dist/uploads/fetchAPI-multipart/handlers.d.ts.map +1 -1
- package/dist/uploads/fetchAPI-multipart/handlers.js +18 -5
- package/dist/uploads/fetchAPI-multipart/handlers.js.map +1 -1
- package/dist/uploads/fetchAPI-multipart/index.d.ts.map +1 -1
- package/dist/uploads/fetchAPI-multipart/index.js +24 -2
- package/dist/uploads/fetchAPI-multipart/index.js.map +1 -1
- package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts +0 -6
- package/dist/uploads/fetchAPI-multipart/processMultipart.d.ts.map +1 -1
- package/dist/uploads/fetchAPI-multipart/processMultipart.js +146 -126
- package/dist/uploads/fetchAPI-multipart/processMultipart.js.map +1 -1
- package/dist/uploads/fetchAPI-multipart/processMultipart.spec.js +663 -0
- package/dist/uploads/fetchAPI-multipart/processMultipart.spec.js.map +1 -0
- package/dist/uploads/generateFileData.d.ts +3 -1
- package/dist/uploads/generateFileData.d.ts.map +1 -1
- package/dist/uploads/generateFileData.js +29 -16
- package/dist/uploads/generateFileData.js.map +1 -1
- package/dist/uploads/getBaseFields.d.ts.map +1 -1
- package/dist/uploads/getBaseFields.js +3 -1
- package/dist/uploads/getBaseFields.js.map +1 -1
- package/dist/uploads/getExternalFile.d.ts +1 -1
- package/dist/uploads/getExternalFile.d.ts.map +1 -1
- package/dist/uploads/getExternalFile.js +60 -15
- package/dist/uploads/getExternalFile.js.map +1 -1
- package/dist/uploads/getFileTypeFallback.d.ts.map +1 -1
- package/dist/uploads/getFileTypeFallback.js +3 -1
- package/dist/uploads/getFileTypeFallback.js.map +1 -1
- package/dist/uploads/getFileTypeIdentity.d.ts +19 -0
- package/dist/uploads/getFileTypeIdentity.d.ts.map +1 -0
- package/dist/uploads/getFileTypeIdentity.js +34 -0
- package/dist/uploads/getFileTypeIdentity.js.map +1 -0
- package/dist/uploads/getFileTypeIdentity.spec.js +43 -0
- package/dist/uploads/getFileTypeIdentity.spec.js.map +1 -0
- package/dist/uploads/isProcessableImage.d.ts +2 -0
- package/dist/uploads/isProcessableImage.d.ts.map +1 -0
- package/dist/uploads/isProcessableImage.js +7 -0
- package/dist/uploads/isProcessableImage.js.map +1 -0
- package/dist/uploads/safeFetch.d.ts.map +1 -1
- package/dist/uploads/safeFetch.js +3 -2
- package/dist/uploads/safeFetch.js.map +1 -1
- package/dist/uploads/sanitizeUploadData.d.ts +26 -0
- package/dist/uploads/sanitizeUploadData.d.ts.map +1 -0
- package/dist/uploads/sanitizeUploadData.js +159 -0
- package/dist/uploads/sanitizeUploadData.js.map +1 -0
- package/dist/uploads/sanitizeUploadData.spec.js +255 -0
- package/dist/uploads/sanitizeUploadData.spec.js.map +1 -0
- package/dist/uploads/types.d.ts +11 -3
- package/dist/uploads/types.d.ts.map +1 -1
- package/dist/uploads/types.js.map +1 -1
- package/dist/uploads/uploadContentSecurityPolicy.d.ts +2 -0
- package/dist/uploads/uploadContentSecurityPolicy.d.ts.map +1 -0
- package/dist/uploads/uploadContentSecurityPolicy.js +3 -0
- package/dist/uploads/uploadContentSecurityPolicy.js.map +1 -0
- package/dist/uploads/validateISOBaseMediaFile.d.ts +4 -0
- package/dist/uploads/validateISOBaseMediaFile.d.ts.map +1 -0
- package/dist/uploads/validateISOBaseMediaFile.js +91 -0
- package/dist/uploads/validateISOBaseMediaFile.js.map +1 -0
- package/dist/uploads/validateISOBaseMediaFile.spec.js +130 -0
- package/dist/uploads/validateISOBaseMediaFile.spec.js.map +1 -0
- package/dist/uploads/validateSvg.d.ts +10 -4
- package/dist/uploads/validateSvg.d.ts.map +1 -1
- package/dist/uploads/validateSvg.js +280 -40
- package/dist/uploads/validateSvg.js.map +1 -1
- package/dist/uploads/validateSvg.spec.js +123 -0
- package/dist/uploads/validateSvg.spec.js.map +1 -0
- package/dist/uploads/validateUploadFilename.d.ts +3 -0
- package/dist/uploads/validateUploadFilename.d.ts.map +1 -0
- package/dist/uploads/validateUploadFilename.js +13 -0
- package/dist/uploads/validateUploadFilename.js.map +1 -0
- package/dist/uploads/validateUploadFilename.spec.js +24 -0
- package/dist/uploads/validateUploadFilename.spec.js.map +1 -0
- package/dist/utilities/addDataAndFileToRequest.d.ts.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.js +28 -1
- package/dist/utilities/addDataAndFileToRequest.js.map +1 -1
- package/dist/utilities/addDataAndFileToRequest.spec.js +158 -0
- package/dist/utilities/addDataAndFileToRequest.spec.js.map +1 -1
- package/dist/utilities/createPayloadRequest.d.ts.map +1 -1
- package/dist/utilities/createPayloadRequest.js +2 -1
- package/dist/utilities/createPayloadRequest.js.map +1 -1
- package/dist/utilities/deepCopyObject.d.ts.map +1 -1
- package/dist/utilities/deepCopyObject.js +110 -19
- package/dist/utilities/deepCopyObject.js.map +1 -1
- package/dist/utilities/deepCopyObject.spec.js +216 -0
- package/dist/utilities/deepCopyObject.spec.js.map +1 -0
- package/dist/utilities/fieldPath.d.ts +13 -0
- package/dist/utilities/fieldPath.d.ts.map +1 -0
- package/dist/utilities/fieldPath.js +51 -0
- package/dist/utilities/fieldPath.js.map +1 -0
- package/dist/utilities/fieldPath.spec.js +155 -0
- package/dist/utilities/fieldPath.spec.js.map +1 -0
- package/dist/utilities/getEntityPermissions/getEntityPermissions.d.ts.map +1 -1
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js +2 -0
- package/dist/utilities/getEntityPermissions/getEntityPermissions.js.map +1 -1
- package/dist/utilities/getObjectDotNotation.d.ts.map +1 -1
- package/dist/utilities/getObjectDotNotation.js +7 -1
- package/dist/utilities/getObjectDotNotation.js.map +1 -1
- package/dist/utilities/getObjectDotNotation.spec.js +33 -0
- package/dist/utilities/getObjectDotNotation.spec.js.map +1 -0
- package/dist/utilities/getSafeRedirect.spec.js +14 -0
- package/dist/utilities/getSafeRedirect.spec.js.map +1 -1
- package/dist/utilities/getTopLevelFieldNames.d.ts +2 -0
- package/dist/utilities/getTopLevelFieldNames.d.ts.map +1 -0
- package/dist/utilities/getTopLevelFieldNames.js +3 -0
- package/dist/utilities/getTopLevelFieldNames.js.map +1 -0
- package/dist/utilities/getTopLevelFieldNames.spec.js +18 -0
- package/dist/utilities/getTopLevelFieldNames.spec.js.map +1 -0
- package/dist/utilities/handleEndpoints.js +1 -1
- package/dist/utilities/handleEndpoints.js.map +1 -1
- package/dist/utilities/parseParams/index.d.ts.map +1 -1
- package/dist/utilities/parseParams/index.js +3 -1
- package/dist/utilities/parseParams/index.js.map +1 -1
- package/dist/utilities/parseParams/index.spec.js +8 -0
- package/dist/utilities/parseParams/index.spec.js.map +1 -1
- package/dist/utilities/telemetry/featureInfo/getFeatureInfo.d.ts +4 -0
- package/dist/utilities/telemetry/featureInfo/getFeatureInfo.d.ts.map +1 -0
- package/dist/utilities/telemetry/featureInfo/getFeatureInfo.js +248 -0
- package/dist/utilities/telemetry/featureInfo/getFeatureInfo.js.map +1 -0
- package/dist/utilities/telemetry/featureInfo/types.d.ts +62 -0
- package/dist/utilities/telemetry/featureInfo/types.d.ts.map +1 -0
- package/dist/utilities/telemetry/featureInfo/types.js +3 -0
- package/dist/utilities/telemetry/featureInfo/types.js.map +1 -0
- package/dist/utilities/telemetry/getProjectContext.d.ts +14 -0
- package/dist/utilities/telemetry/getProjectContext.d.ts.map +1 -0
- package/dist/utilities/telemetry/getProjectContext.js +36 -0
- package/dist/utilities/telemetry/getProjectContext.js.map +1 -0
- package/dist/utilities/telemetry/index.d.ts +7 -1
- package/dist/utilities/telemetry/index.d.ts.map +1 -1
- package/dist/utilities/telemetry/index.js +22 -0
- package/dist/utilities/telemetry/index.js.map +1 -1
- package/dist/utilities/traverseFields.d.ts.map +1 -1
- package/dist/utilities/traverseFields.js +5 -14
- package/dist/utilities/traverseFields.js.map +1 -1
- package/dist/utilities/unflatten.d.ts.map +1 -1
- package/dist/utilities/unflatten.js +21 -9
- package/dist/utilities/unflatten.js.map +1 -1
- package/dist/utilities/unflatten.spec.js +38 -0
- package/dist/utilities/unflatten.spec.js.map +1 -0
- package/dist/versions/allLocalesPublicationStatus.d.ts +38 -0
- package/dist/versions/allLocalesPublicationStatus.d.ts.map +1 -0
- package/dist/versions/allLocalesPublicationStatus.js +57 -0
- package/dist/versions/allLocalesPublicationStatus.js.map +1 -0
- package/dist/versions/getLatestGlobalVersion.d.ts.map +1 -1
- package/dist/versions/getLatestGlobalVersion.js +10 -2
- package/dist/versions/getLatestGlobalVersion.js.map +1 -1
- package/dist/versions/getRestoredStatusesToAuthorize.d.ts +9 -0
- package/dist/versions/getRestoredStatusesToAuthorize.d.ts.map +1 -0
- package/dist/versions/getRestoredStatusesToAuthorize.js +22 -0
- package/dist/versions/getRestoredStatusesToAuthorize.js.map +1 -0
- package/dist/versions/getRestoredStatusesToAuthorize.spec.js +50 -0
- package/dist/versions/getRestoredStatusesToAuthorize.spec.js.map +1 -0
- package/dist/versions/schedule/job.d.ts +2 -2
- package/dist/versions/schedule/job.d.ts.map +1 -1
- package/dist/versions/schedule/job.js +11 -7
- package/dist/versions/schedule/job.js.map +1 -1
- package/dist/versions/schedule/types.d.ts +5 -1
- package/dist/versions/schedule/types.d.ts.map +1 -1
- package/dist/versions/schedule/types.js.map +1 -1
- package/package.json +4 -2
- package/dist/auth/baseFields/apiKey.d.ts +0 -3
- package/dist/auth/baseFields/apiKey.d.ts.map +0 -1
- package/dist/auth/baseFields/apiKey.js +0 -59
- 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:
|
|
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
|
|
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,
|
|
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,
|
|
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
|
-
|
|
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
|
|
15
|
+
const headers = {};
|
|
32
16
|
request.headers.forEach((value, name)=>{
|
|
33
|
-
|
|
17
|
+
headers[name] = value;
|
|
34
18
|
});
|
|
35
|
-
const reader = request.body?.getReader();
|
|
36
19
|
const busboy = Busboy({
|
|
37
|
-
...
|
|
38
|
-
headers
|
|
20
|
+
...busboyOptions,
|
|
21
|
+
headers
|
|
39
22
|
});
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
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
|
-
|
|
52
|
-
|
|
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
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
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
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
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
|
-
|
|
87
|
-
|
|
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
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
|
133
|
+
buffer,
|
|
105
134
|
encoding,
|
|
106
|
-
hash: getHash(),
|
|
107
|
-
mimetype
|
|
135
|
+
hash: handler.getHash(),
|
|
136
|
+
mimetype,
|
|
108
137
|
size,
|
|
109
|
-
tempFilePath: getFilePath(),
|
|
110
|
-
truncated: Boolean(
|
|
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
|
-
|
|
127
|
-
debugLog(options, `New upload started ${field}->${filename}, bytes:${getFileSize()}`);
|
|
128
|
-
uploadTimer.set();
|
|
142
|
+
timer.set();
|
|
129
143
|
});
|
|
130
|
-
busboy.on('finish',
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
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
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
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
|
-
|
|
159
|
-
|
|
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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"}
|