happy-dom 8.9.0 → 9.0.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.
Potentially problematic release.
This version of happy-dom might be problematic. Click here for more details.
- package/README.md +2 -2
- package/lib/cookie/CookieJar.js +1 -1
- package/lib/cookie/CookieJar.js.map +1 -1
- package/lib/dom-token-list/DOMTokenList.js +24 -20
- package/lib/dom-token-list/DOMTokenList.js.map +1 -1
- package/lib/event/EventTarget.js +6 -3
- package/lib/event/EventTarget.js.map +1 -1
- package/lib/exception/DOMExceptionNameEnum.d.ts +5 -1
- package/lib/exception/DOMExceptionNameEnum.js +4 -0
- package/lib/exception/DOMExceptionNameEnum.js.map +1 -1
- package/lib/fetch/AbortController.d.ts +19 -0
- package/lib/fetch/AbortController.js +30 -0
- package/lib/fetch/AbortController.js.map +1 -0
- package/lib/fetch/AbortSignal.d.ts +25 -0
- package/lib/fetch/AbortSignal.js +51 -0
- package/lib/fetch/AbortSignal.js.map +1 -0
- package/lib/fetch/Fetch.d.ts +117 -0
- package/lib/fetch/Fetch.js +530 -0
- package/lib/fetch/Fetch.js.map +1 -0
- package/lib/fetch/Headers.d.ts +81 -3
- package/lib/fetch/Headers.js +139 -24
- package/lib/fetch/Headers.js.map +1 -1
- package/lib/fetch/Request.d.ts +56 -32
- package/lib/fetch/Request.js +165 -110
- package/lib/fetch/Request.js.map +1 -1
- package/lib/fetch/{ResourceFetchHandler.d.ts → ResourceFetch.d.ts} +1 -1
- package/lib/fetch/{ResourceFetchHandler.js → ResourceFetch.js} +5 -5
- package/lib/fetch/ResourceFetch.js.map +1 -0
- package/lib/fetch/Response.d.ts +60 -26
- package/lib/fetch/Response.js +196 -104
- package/lib/fetch/Response.js.map +1 -1
- package/lib/fetch/data-uri/DataURIParser.d.ts +20 -0
- package/lib/fetch/data-uri/DataURIParser.js +60 -0
- package/lib/fetch/data-uri/DataURIParser.js.map +1 -0
- package/lib/fetch/multipart/MultipartFormDataParser.d.ts +40 -0
- package/lib/fetch/multipart/MultipartFormDataParser.js +81 -0
- package/lib/fetch/multipart/MultipartFormDataParser.js.map +1 -0
- package/lib/fetch/multipart/MultipartReader.d.ts +49 -0
- package/lib/fetch/multipart/MultipartReader.js +178 -0
- package/lib/fetch/multipart/MultipartReader.js.map +1 -0
- package/lib/fetch/types/IHeaders.d.ts +71 -0
- package/lib/fetch/{IHeaders.js.map → types/IHeaders.js.map} +1 -1
- package/lib/fetch/types/IHeadersInit.js.map +1 -0
- package/lib/fetch/types/IRequest.d.ts +60 -0
- package/lib/fetch/{IRequest.js.map → types/IRequest.js.map} +1 -1
- package/lib/fetch/types/IRequestBody.d.ts +7 -0
- package/lib/fetch/{IBody.js → types/IRequestBody.js} +1 -1
- package/lib/fetch/types/IRequestBody.js.map +1 -0
- package/lib/fetch/types/IRequestCredentials.d.ts +2 -0
- package/lib/fetch/types/IRequestCredentials.js +3 -0
- package/lib/fetch/types/IRequestCredentials.js.map +1 -0
- package/lib/fetch/{RequestInfo.d.ts → types/IRequestInfo.d.ts} +2 -2
- package/lib/fetch/types/IRequestInfo.js +3 -0
- package/lib/fetch/types/IRequestInfo.js.map +1 -0
- package/lib/fetch/types/IRequestInit.d.ts +21 -0
- package/lib/fetch/types/IRequestInit.js.map +1 -0
- package/lib/fetch/types/IRequestRedirect.d.ts +2 -0
- package/lib/fetch/types/IRequestRedirect.js +3 -0
- package/lib/fetch/types/IRequestRedirect.js.map +1 -0
- package/lib/fetch/types/IRequestReferrerPolicy.d.ts +2 -0
- package/lib/fetch/types/IRequestReferrerPolicy.js +3 -0
- package/lib/fetch/types/IRequestReferrerPolicy.js.map +1 -0
- package/lib/fetch/types/IResponse.d.ts +27 -0
- package/lib/fetch/{IResponse.js.map → types/IResponse.js.map} +1 -1
- package/lib/fetch/types/IResponseBody.d.ts +7 -0
- package/lib/fetch/types/IResponseBody.js +3 -0
- package/lib/fetch/types/IResponseBody.js.map +1 -0
- package/lib/fetch/types/IResponseInit.d.ts +9 -0
- package/lib/fetch/types/IResponseInit.js.map +1 -0
- package/lib/fetch/utilities/FetchBodyUtility.d.ts +44 -0
- package/lib/fetch/utilities/FetchBodyUtility.js +156 -0
- package/lib/fetch/utilities/FetchBodyUtility.js.map +1 -0
- package/lib/fetch/utilities/FetchCORSUtility.d.ts +12 -0
- package/lib/fetch/utilities/FetchCORSUtility.js +20 -0
- package/lib/fetch/utilities/FetchCORSUtility.js.map +1 -0
- package/lib/fetch/utilities/FetchRequestHeaderUtility.d.ts +12 -0
- package/lib/fetch/utilities/FetchRequestHeaderUtility.js +45 -0
- package/lib/fetch/utilities/FetchRequestHeaderUtility.js.map +1 -0
- package/lib/fetch/utilities/FetchRequestReferrerUtility.d.ts +55 -0
- package/lib/fetch/utilities/FetchRequestReferrerUtility.js +194 -0
- package/lib/fetch/utilities/FetchRequestReferrerUtility.js.map +1 -0
- package/lib/fetch/utilities/FetchRequestValidationUtility.d.ts +38 -0
- package/lib/fetch/utilities/FetchRequestValidationUtility.js +70 -0
- package/lib/fetch/utilities/FetchRequestValidationUtility.js.map +1 -0
- package/lib/file/Blob.d.ts +2 -2
- package/lib/file/Blob.js +1 -1
- package/lib/file/Blob.js.map +1 -1
- package/lib/file/File.d.ts +2 -1
- package/lib/file/File.js.map +1 -1
- package/lib/form-data/FormData.d.ts +98 -0
- package/lib/form-data/FormData.js +212 -0
- package/lib/form-data/FormData.js.map +1 -0
- package/lib/index.d.ts +14 -1
- package/lib/index.js +20 -2
- package/lib/index.js.map +1 -1
- package/lib/nodes/document/Document.d.ts +5 -17
- package/lib/nodes/document/Document.js +11 -54
- package/lib/nodes/document/Document.js.map +1 -1
- package/lib/nodes/document/IDocument.d.ts +1 -1
- package/lib/nodes/document-fragment/DocumentFragment.d.ts +3 -14
- package/lib/nodes/document-fragment/DocumentFragment.js +7 -51
- package/lib/nodes/document-fragment/DocumentFragment.js.map +1 -1
- package/lib/nodes/document-fragment/IDocumentFragment.d.ts +2 -1
- package/lib/nodes/element/Element.d.ts +8 -8
- package/lib/nodes/element/Element.js +28 -45
- package/lib/nodes/element/Element.js.map +1 -1
- package/lib/nodes/element/ElementUtility.d.ts +32 -0
- package/lib/nodes/element/ElementUtility.js +105 -0
- package/lib/nodes/element/ElementUtility.js.map +1 -0
- package/lib/nodes/element/HTMLCollection.d.ts +26 -3
- package/lib/nodes/element/HTMLCollection.js +51 -0
- package/lib/nodes/element/HTMLCollection.js.map +1 -1
- package/lib/nodes/element/IHTMLCollection.d.ts +9 -2
- package/lib/nodes/html-anchor-element/HTMLAnchorElement.js +24 -24
- package/lib/nodes/html-anchor-element/HTMLAnchorElement.js.map +1 -1
- package/lib/nodes/html-base-element/HTMLBaseElement.js +4 -4
- package/lib/nodes/html-base-element/HTMLBaseElement.js.map +1 -1
- package/lib/nodes/html-button-element/HTMLButtonElement.d.ts +79 -3
- package/lib/nodes/html-button-element/HTMLButtonElement.js +158 -10
- package/lib/nodes/html-button-element/HTMLButtonElement.js.map +1 -1
- package/lib/nodes/html-button-element/IHTMLButtonElement.d.ts +28 -2
- package/lib/nodes/html-dialog-element/HTMLDialogElement.js +3 -3
- package/lib/nodes/html-dialog-element/HTMLDialogElement.js.map +1 -1
- package/lib/nodes/html-element/HTMLElement.js +12 -12
- package/lib/nodes/html-element/HTMLElement.js.map +1 -1
- package/lib/nodes/html-form-element/HTMLFormControlsCollection.d.ts +32 -0
- package/lib/nodes/html-form-element/HTMLFormControlsCollection.js +58 -0
- package/lib/nodes/html-form-element/HTMLFormControlsCollection.js.map +1 -0
- package/lib/nodes/html-form-element/HTMLFormElement.d.ts +37 -17
- package/lib/nodes/html-form-element/HTMLFormElement.js +128 -37
- package/lib/nodes/html-form-element/HTMLFormElement.js.map +1 -1
- package/lib/nodes/html-form-element/IHTMLFormControlsCollection.d.ts +25 -0
- package/lib/nodes/html-form-element/IHTMLFormControlsCollection.js +3 -0
- package/lib/nodes/html-form-element/IHTMLFormControlsCollection.js.map +1 -0
- package/lib/nodes/html-form-element/IHTMLFormElement.d.ts +16 -6
- package/lib/nodes/html-form-element/IRadioNodeList.d.ts +15 -0
- package/lib/nodes/html-form-element/IRadioNodeList.js +3 -0
- package/lib/nodes/html-form-element/IRadioNodeList.js.map +1 -0
- package/lib/nodes/html-form-element/RadioNodeList.d.ts +16 -0
- package/lib/nodes/html-form-element/RadioNodeList.js +28 -0
- package/lib/nodes/html-form-element/RadioNodeList.js.map +1 -0
- package/lib/nodes/html-image-element/HTMLImageElement.js +19 -19
- package/lib/nodes/html-image-element/HTMLImageElement.js.map +1 -1
- package/lib/nodes/html-input-element/HTMLInputElement.d.ts +43 -19
- package/lib/nodes/html-input-element/HTMLInputElement.js +206 -111
- package/lib/nodes/html-input-element/HTMLInputElement.js.map +1 -1
- package/lib/nodes/html-input-element/IHTMLInputElement.d.ts +14 -1
- package/lib/nodes/html-label-element/HTMLLabelElement.js +3 -7
- package/lib/nodes/html-label-element/HTMLLabelElement.js.map +1 -1
- package/lib/nodes/html-link-element/HTMLLinkElement.js +21 -21
- package/lib/nodes/html-link-element/HTMLLinkElement.js.map +1 -1
- package/lib/nodes/html-media-element/HTMLMediaElement.js +21 -21
- package/lib/nodes/html-media-element/HTMLMediaElement.js.map +1 -1
- package/lib/nodes/html-meta-element/HTMLMetaElement.js +8 -8
- package/lib/nodes/html-meta-element/HTMLMetaElement.js.map +1 -1
- package/lib/nodes/html-opt-group-element/HTMLOptGroupElement.js +6 -6
- package/lib/nodes/html-opt-group-element/HTMLOptGroupElement.js.map +1 -1
- package/lib/nodes/html-option-element/HTMLOptionElement.d.ts +3 -4
- package/lib/nodes/html-option-element/HTMLOptionElement.js +26 -29
- package/lib/nodes/html-option-element/HTMLOptionElement.js.map +1 -1
- package/lib/nodes/html-script-element/HTMLScriptElement.js +16 -16
- package/lib/nodes/html-script-element/HTMLScriptElement.js.map +1 -1
- package/lib/nodes/html-script-element/ScriptUtility.js +5 -5
- package/lib/nodes/html-script-element/ScriptUtility.js.map +1 -1
- package/lib/nodes/{html-option-element → html-select-element}/HTMLOptionsCollection.d.ts +5 -6
- package/lib/nodes/{html-option-element → html-select-element}/HTMLOptionsCollection.js.map +1 -1
- package/lib/nodes/html-select-element/HTMLSelectElement.d.ts +42 -41
- package/lib/nodes/html-select-element/HTMLSelectElement.js +134 -138
- package/lib/nodes/html-select-element/HTMLSelectElement.js.map +1 -1
- package/lib/nodes/{html-option-element → html-select-element}/IHTMLOptionsCollection.d.ts +4 -5
- package/lib/nodes/html-select-element/IHTMLOptionsCollection.js.map +1 -0
- package/lib/nodes/html-select-element/IHTMLSelectElement.d.ts +22 -2
- package/lib/nodes/html-slot-element/HTMLSlotElement.js +2 -2
- package/lib/nodes/html-slot-element/HTMLSlotElement.js.map +1 -1
- package/lib/nodes/html-style-element/HTMLStyleElement.js +7 -7
- package/lib/nodes/html-style-element/HTMLStyleElement.js.map +1 -1
- package/lib/nodes/html-text-area-element/HTMLTextAreaElement.d.ts +55 -2
- package/lib/nodes/html-text-area-element/HTMLTextAreaElement.js +150 -40
- package/lib/nodes/html-text-area-element/HTMLTextAreaElement.js.map +1 -1
- package/lib/nodes/html-text-area-element/IHTMLTextAreaElement.d.ts +16 -0
- package/lib/nodes/node/Node.d.ts +12 -1
- package/lib/nodes/node/Node.js +50 -4
- package/lib/nodes/node/Node.js.map +1 -1
- package/lib/nodes/node/NodeList.d.ts +2 -3
- package/lib/nodes/node/NodeList.js.map +1 -1
- package/lib/nodes/parent-node/IParentNode.d.ts +4 -4
- package/lib/nodes/parent-node/ParentNodeUtility.d.ts +3 -3
- package/lib/nodes/parent-node/ParentNodeUtility.js +13 -11
- package/lib/nodes/parent-node/ParentNodeUtility.js.map +1 -1
- package/lib/nodes/text/Text.d.ts +13 -0
- package/lib/nodes/text/Text.js +30 -0
- package/lib/nodes/text/Text.js.map +1 -1
- package/lib/query-selector/QuerySelector.js +2 -2
- package/lib/query-selector/QuerySelector.js.map +1 -1
- package/lib/query-selector/SelectorItem.js +2 -0
- package/lib/query-selector/SelectorItem.js.map +1 -1
- package/lib/validity-state/ValidityState.d.ts +87 -0
- package/lib/validity-state/ValidityState.js +171 -0
- package/lib/validity-state/ValidityState.js.map +1 -0
- package/lib/window/GlobalWindow.d.ts +0 -8
- package/lib/window/GlobalWindow.js +0 -2
- package/lib/window/GlobalWindow.js.map +1 -1
- package/lib/window/INodeJSGlobal.d.ts +71 -0
- package/lib/window/INodeJSGlobal.js +2 -0
- package/lib/window/INodeJSGlobal.js.map +1 -0
- package/lib/window/IWindow.d.ts +30 -10
- package/lib/window/Window.d.ts +36 -20
- package/lib/window/Window.js +16 -9
- package/lib/window/Window.js.map +1 -1
- package/lib/xml-http-request/XMLHttpRequest.js +20 -12
- package/lib/xml-http-request/XMLHttpRequest.js.map +1 -1
- package/lib/xml-parser/XMLParser.js +1 -1
- package/lib/xml-parser/XMLParser.js.map +1 -1
- package/package.json +2 -3
- package/src/cookie/CookieJar.ts +1 -1
- package/src/dom-token-list/DOMTokenList.ts +24 -20
- package/src/event/EventTarget.ts +7 -3
- package/src/exception/DOMExceptionNameEnum.ts +5 -1
- package/src/fetch/AbortController.ts +26 -0
- package/src/fetch/AbortSignal.ts +44 -0
- package/src/fetch/Fetch.ts +666 -0
- package/src/fetch/Headers.ts +151 -3
- package/src/fetch/Request.ts +226 -94
- package/src/fetch/{ResourceFetchHandler.ts → ResourceFetch.ts} +3 -3
- package/src/fetch/Response.ts +252 -89
- package/src/fetch/data-uri/DataURIParser.ts +66 -0
- package/src/fetch/multipart/MultipartFormDataParser.ts +113 -0
- package/src/fetch/multipart/MultipartReader.ts +217 -0
- package/src/fetch/types/IHeaders.ts +80 -0
- package/src/fetch/types/IRequest.ts +65 -0
- package/src/fetch/types/IRequestBody.ts +15 -0
- package/src/fetch/types/IRequestCredentials.ts +2 -0
- package/src/fetch/types/IRequestInfo.ts +6 -0
- package/src/fetch/types/IRequestInit.ts +21 -0
- package/src/fetch/types/IRequestRedirect.ts +3 -0
- package/src/fetch/types/IRequestReferrerPolicy.ts +11 -0
- package/src/fetch/types/IResponse.ts +27 -0
- package/src/fetch/types/IResponseBody.ts +15 -0
- package/src/fetch/types/IResponseInit.ts +10 -0
- package/src/fetch/utilities/FetchBodyUtility.ts +175 -0
- package/src/fetch/utilities/FetchCORSUtility.ts +18 -0
- package/src/fetch/utilities/FetchRequestHeaderUtility.ts +47 -0
- package/src/fetch/utilities/FetchRequestReferrerUtility.ts +241 -0
- package/src/fetch/utilities/FetchRequestValidationUtility.ts +82 -0
- package/src/file/Blob.ts +2 -2
- package/src/file/File.ts +5 -1
- package/src/form-data/FormData.ts +237 -0
- package/src/index.ts +27 -1
- package/src/nodes/document/Document.ts +23 -64
- package/src/nodes/document/IDocument.ts +1 -1
- package/src/nodes/document-fragment/DocumentFragment.ts +9 -59
- package/src/nodes/document-fragment/IDocumentFragment.ts +2 -1
- package/src/nodes/element/Element.ts +43 -56
- package/src/nodes/element/ElementUtility.ts +137 -0
- package/src/nodes/element/HTMLCollection.ts +60 -3
- package/src/nodes/element/IHTMLCollection.ts +10 -2
- package/src/nodes/html-anchor-element/HTMLAnchorElement.ts +24 -24
- package/src/nodes/html-base-element/HTMLBaseElement.ts +4 -4
- package/src/nodes/html-button-element/HTMLButtonElement.ts +184 -10
- package/src/nodes/html-button-element/IHTMLButtonElement.ts +31 -2
- package/src/nodes/html-dialog-element/HTMLDialogElement.ts +3 -3
- package/src/nodes/html-element/HTMLElement.ts +12 -12
- package/src/nodes/html-form-element/HTMLFormControlsCollection.ts +76 -0
- package/src/nodes/html-form-element/HTMLFormElement.ts +147 -41
- package/src/nodes/html-form-element/IHTMLFormControlsCollection.ts +45 -0
- package/src/nodes/html-form-element/IHTMLFormElement.ts +17 -6
- package/src/nodes/html-form-element/IRadioNodeList.ts +16 -0
- package/src/nodes/html-form-element/RadioNodeList.ts +24 -0
- package/src/nodes/html-image-element/HTMLImageElement.ts +19 -19
- package/src/nodes/html-input-element/HTMLInputElement.ts +232 -113
- package/src/nodes/html-input-element/IHTMLInputElement.ts +20 -1
- package/src/nodes/html-label-element/HTMLLabelElement.ts +3 -7
- package/src/nodes/html-link-element/HTMLLinkElement.ts +21 -21
- package/src/nodes/html-media-element/HTMLMediaElement.ts +21 -21
- package/src/nodes/html-meta-element/HTMLMetaElement.ts +8 -8
- package/src/nodes/html-opt-group-element/HTMLOptGroupElement.ts +6 -6
- package/src/nodes/html-option-element/HTMLOptionElement.ts +29 -30
- package/src/nodes/html-script-element/HTMLScriptElement.ts +16 -16
- package/src/nodes/html-script-element/ScriptUtility.ts +5 -5
- package/src/nodes/{html-option-element → html-select-element}/HTMLOptionsCollection.ts +5 -9
- package/src/nodes/html-select-element/HTMLSelectElement.ts +159 -170
- package/src/nodes/{html-option-element → html-select-element}/IHTMLOptionsCollection.ts +4 -8
- package/src/nodes/html-select-element/IHTMLSelectElement.ts +25 -2
- package/src/nodes/html-slot-element/HTMLSlotElement.ts +2 -2
- package/src/nodes/html-style-element/HTMLStyleElement.ts +7 -7
- package/src/nodes/html-text-area-element/HTMLTextAreaElement.ts +174 -41
- package/src/nodes/html-text-area-element/IHTMLTextAreaElement.ts +18 -0
- package/src/nodes/node/Node.ts +61 -6
- package/src/nodes/node/NodeList.ts +2 -3
- package/src/nodes/parent-node/IParentNode.ts +7 -4
- package/src/nodes/parent-node/ParentNodeUtility.ts +25 -15
- package/src/nodes/text/Text.ts +38 -0
- package/src/query-selector/QuerySelector.ts +2 -2
- package/src/query-selector/SelectorItem.ts +3 -0
- package/src/validity-state/ValidityState.ts +211 -0
- package/src/window/GlobalWindow.ts +0 -2
- package/src/window/INodeJSGlobal.ts +70 -0
- package/src/window/IWindow.ts +32 -10
- package/src/window/Window.ts +37 -20
- package/src/xml-http-request/XMLHttpRequest.ts +27 -26
- package/src/xml-parser/XMLParser.ts +1 -1
- package/lib/fetch/FetchHandler.d.ts +0 -18
- package/lib/fetch/FetchHandler.js +0 -83
- package/lib/fetch/FetchHandler.js.map +0 -1
- package/lib/fetch/IAbortSignal.d.ts +0 -16
- package/lib/fetch/IAbortSignal.js +0 -4
- package/lib/fetch/IAbortSignal.js.map +0 -1
- package/lib/fetch/IBody.d.ts +0 -17
- package/lib/fetch/IBody.js.map +0 -1
- package/lib/fetch/IHeaders.d.ts +0 -18
- package/lib/fetch/IHeadersInit.js.map +0 -1
- package/lib/fetch/IRequest.d.ts +0 -18
- package/lib/fetch/IRequestInit.d.ts +0 -16
- package/lib/fetch/IRequestInit.js.map +0 -1
- package/lib/fetch/IResponse.d.ts +0 -20
- package/lib/fetch/IResponseInit.d.ts +0 -9
- package/lib/fetch/IResponseInit.js.map +0 -1
- package/lib/fetch/RequestInfo.js +0 -3
- package/lib/fetch/RequestInfo.js.map +0 -1
- package/lib/fetch/ResourceFetchHandler.js.map +0 -1
- package/lib/form-data/IFormData.d.ts +0 -32
- package/lib/form-data/IFormData.js +0 -3
- package/lib/form-data/IFormData.js.map +0 -1
- package/lib/location/RelativeURL.d.ts +0 -15
- package/lib/location/RelativeURL.js +0 -19
- package/lib/location/RelativeURL.js.map +0 -1
- package/lib/nodes/element/HTMLCollectionFactory.d.ts +0 -21
- package/lib/nodes/element/HTMLCollectionFactory.js +0 -31
- package/lib/nodes/element/HTMLCollectionFactory.js.map +0 -1
- package/lib/nodes/html-option-element/IHTMLOptionsCollection.js.map +0 -1
- package/lib/nodes/node/NodeListFactory.d.ts +0 -21
- package/lib/nodes/node/NodeListFactory.js +0 -31
- package/lib/nodes/node/NodeListFactory.js.map +0 -1
- package/lib/nodes/validity-state/ValidityState.d.ts +0 -52
- package/lib/nodes/validity-state/ValidityState.js +0 -81
- package/lib/nodes/validity-state/ValidityState.js.map +0 -1
- package/src/fetch/FetchHandler.ts +0 -90
- package/src/fetch/IAbortSignal.ts +0 -34
- package/src/fetch/IBody.ts +0 -18
- package/src/fetch/IHeaders.ts +0 -18
- package/src/fetch/IRequest.ts +0 -59
- package/src/fetch/IRequestInit.ts +0 -41
- package/src/fetch/IResponse.ts +0 -22
- package/src/fetch/IResponseInit.ts +0 -10
- package/src/fetch/RequestInfo.ts +0 -6
- package/src/form-data/IFormData.ts +0 -33
- package/src/location/RelativeURL.ts +0 -17
- package/src/nodes/element/HTMLCollectionFactory.ts +0 -31
- package/src/nodes/node/NodeListFactory.ts +0 -31
- package/src/nodes/validity-state/ValidityState.ts +0 -84
- /package/lib/fetch/{IHeaders.js → types/IHeaders.js} +0 -0
- /package/lib/fetch/{IHeadersInit.d.ts → types/IHeadersInit.d.ts} +0 -0
- /package/lib/fetch/{IHeadersInit.js → types/IHeadersInit.js} +0 -0
- /package/lib/fetch/{IRequest.js → types/IRequest.js} +0 -0
- /package/lib/fetch/{IRequestInit.js → types/IRequestInit.js} +0 -0
- /package/lib/fetch/{IResponse.js → types/IResponse.js} +0 -0
- /package/lib/fetch/{IResponseInit.js → types/IResponseInit.js} +0 -0
- /package/lib/nodes/{html-option-element → html-select-element}/HTMLOptionsCollection.js +0 -0
- /package/lib/nodes/{html-option-element → html-select-element}/IHTMLOptionsCollection.js +0 -0
- /package/src/fetch/{IHeadersInit.ts → types/IHeadersInit.ts} +0 -0
package/src/fetch/Response.ts
CHANGED
@@ -1,25 +1,79 @@
|
|
1
|
-
import IResponse from './IResponse';
|
1
|
+
import IResponse from './types/IResponse';
|
2
2
|
import IBlob from '../file/IBlob';
|
3
3
|
import IDocument from '../nodes/document/IDocument';
|
4
|
-
import
|
4
|
+
import IResponseInit from './types/IResponseInit';
|
5
|
+
import IResponseBody from './types/IResponseBody';
|
6
|
+
import Headers from './Headers';
|
7
|
+
import IHeaders from './types/IHeaders';
|
8
|
+
import { URL, URLSearchParams } from 'url';
|
9
|
+
import Blob from '../file/Blob';
|
10
|
+
import Stream from 'stream';
|
11
|
+
import FormData from '../form-data/FormData';
|
12
|
+
import FetchBodyUtility from './utilities/FetchBodyUtility';
|
13
|
+
import DOMException from '../exception/DOMException';
|
14
|
+
import DOMExceptionNameEnum from '../exception/DOMExceptionNameEnum';
|
15
|
+
import { TextDecoder } from 'util';
|
16
|
+
import MultipartFormDataParser from './multipart/MultipartFormDataParser';
|
17
|
+
|
18
|
+
const REDIRECT_STATUS_CODES = [301, 302, 303, 307, 308];
|
5
19
|
|
6
20
|
/**
|
7
21
|
* Fetch response.
|
22
|
+
*
|
23
|
+
* Based on:
|
24
|
+
* https://github.com/node-fetch/node-fetch/blob/main/src/response.js (MIT)
|
25
|
+
*
|
26
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/API/Response/Response
|
8
27
|
*/
|
9
|
-
export default class Response
|
28
|
+
export default class Response implements IResponse {
|
10
29
|
// Owner document is set by a sub-class in the Window constructor
|
11
30
|
public static _ownerDocument: IDocument = null;
|
12
31
|
public readonly _ownerDocument: IDocument = null;
|
13
32
|
|
33
|
+
// Public properties
|
34
|
+
public readonly body: Stream.Readable | null = null;
|
35
|
+
public readonly bodyUsed = false;
|
36
|
+
public readonly redirected = false;
|
37
|
+
public readonly type: 'basic' | 'cors' | 'default' | 'error' | 'opaque' | 'opaqueredirect' =
|
38
|
+
'basic';
|
39
|
+
public readonly url: string = '';
|
40
|
+
public readonly status: number;
|
41
|
+
public readonly statusText: string;
|
42
|
+
public readonly ok: boolean;
|
43
|
+
public readonly headers: IHeaders;
|
44
|
+
|
14
45
|
/**
|
15
46
|
* Constructor.
|
16
47
|
*
|
17
|
-
* @param
|
18
|
-
* @param
|
48
|
+
* @param input Input.
|
49
|
+
* @param body
|
50
|
+
* @param [init] Init.
|
19
51
|
*/
|
20
|
-
constructor(body?:
|
21
|
-
super(body, init);
|
52
|
+
constructor(body?: IResponseBody, init?: IResponseInit) {
|
22
53
|
this._ownerDocument = (<typeof Response>this.constructor)._ownerDocument;
|
54
|
+
|
55
|
+
this.status = init?.status !== undefined ? init.status : 200;
|
56
|
+
this.statusText = init?.statusText || '';
|
57
|
+
this.ok = this.status >= 200 && this.status < 300;
|
58
|
+
this.headers = new Headers(init?.headers);
|
59
|
+
|
60
|
+
if (body) {
|
61
|
+
const { stream, contentType } = FetchBodyUtility.getBodyStream(body);
|
62
|
+
this.body = stream;
|
63
|
+
|
64
|
+
if (contentType && !this.headers.has('Content-Type')) {
|
65
|
+
this.headers.set('Content-Type', contentType);
|
66
|
+
}
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
/**
|
71
|
+
* Returns string tag.
|
72
|
+
*
|
73
|
+
* @returns String tag.
|
74
|
+
*/
|
75
|
+
public get [Symbol.toStringTag](): string {
|
76
|
+
return 'Response';
|
23
77
|
}
|
24
78
|
|
25
79
|
/**
|
@@ -27,14 +81,30 @@ export default class Response extends NodeFetch.Response implements IResponse {
|
|
27
81
|
*
|
28
82
|
* @returns Array buffer.
|
29
83
|
*/
|
30
|
-
public arrayBuffer(): Promise<ArrayBuffer> {
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
.
|
35
|
-
|
36
|
-
|
37
|
-
|
84
|
+
public async arrayBuffer(): Promise<ArrayBuffer> {
|
85
|
+
if (this.bodyUsed) {
|
86
|
+
throw new DOMException(
|
87
|
+
`Body has already been used for "${this.url}".`,
|
88
|
+
DOMExceptionNameEnum.invalidStateError
|
89
|
+
);
|
90
|
+
}
|
91
|
+
|
92
|
+
(<boolean>this.bodyUsed) = true;
|
93
|
+
|
94
|
+
const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
|
95
|
+
const taskID = taskManager.startTask();
|
96
|
+
let buffer: Buffer;
|
97
|
+
|
98
|
+
try {
|
99
|
+
buffer = await FetchBodyUtility.consumeBodyStream(this.body);
|
100
|
+
} catch (error) {
|
101
|
+
taskManager.endTask(taskID);
|
102
|
+
throw error;
|
103
|
+
}
|
104
|
+
|
105
|
+
taskManager.endTask(taskID);
|
106
|
+
|
107
|
+
return buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
|
38
108
|
}
|
39
109
|
|
40
110
|
/**
|
@@ -42,14 +112,11 @@ export default class Response extends NodeFetch.Response implements IResponse {
|
|
42
112
|
*
|
43
113
|
* @returns Blob.
|
44
114
|
*/
|
45
|
-
public blob(): Promise<IBlob> {
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
.then(this._handlePromiseEnd.bind(this, resolve, reject, taskID))
|
51
|
-
.catch(this._handlePromiseError.bind(this, reject));
|
52
|
-
});
|
115
|
+
public async blob(): Promise<IBlob> {
|
116
|
+
const type = this.headers.get('content-type') || '';
|
117
|
+
const buffer = await this.arrayBuffer();
|
118
|
+
|
119
|
+
return new Blob([buffer], { type });
|
53
120
|
}
|
54
121
|
|
55
122
|
/**
|
@@ -57,29 +124,61 @@ export default class Response extends NodeFetch.Response implements IResponse {
|
|
57
124
|
*
|
58
125
|
* @returns Buffer.
|
59
126
|
*/
|
60
|
-
public buffer(): Promise<Buffer> {
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
.
|
65
|
-
|
66
|
-
|
67
|
-
|
127
|
+
public async buffer(): Promise<Buffer> {
|
128
|
+
if (this.bodyUsed) {
|
129
|
+
throw new DOMException(
|
130
|
+
`Body has already been used for "${this.url}".`,
|
131
|
+
DOMExceptionNameEnum.invalidStateError
|
132
|
+
);
|
133
|
+
}
|
134
|
+
|
135
|
+
(<boolean>this.bodyUsed) = true;
|
136
|
+
|
137
|
+
const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
|
138
|
+
const taskID = taskManager.startTask();
|
139
|
+
let buffer: Buffer;
|
140
|
+
|
141
|
+
try {
|
142
|
+
buffer = await FetchBodyUtility.consumeBodyStream(this.body);
|
143
|
+
} catch (error) {
|
144
|
+
taskManager.endTask(taskID);
|
145
|
+
throw error;
|
146
|
+
}
|
147
|
+
|
148
|
+
taskManager.endTask(taskID);
|
149
|
+
|
150
|
+
return buffer;
|
68
151
|
}
|
69
152
|
|
70
153
|
/**
|
71
|
-
* Returns
|
154
|
+
* Returns text.
|
72
155
|
*
|
73
|
-
* @returns
|
156
|
+
* @returns Text.
|
74
157
|
*/
|
75
|
-
public
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
.
|
80
|
-
|
81
|
-
|
82
|
-
|
158
|
+
public async text(): Promise<string> {
|
159
|
+
if (this.bodyUsed) {
|
160
|
+
throw new DOMException(
|
161
|
+
`Body has already been used for "${this.url}".`,
|
162
|
+
DOMExceptionNameEnum.invalidStateError
|
163
|
+
);
|
164
|
+
}
|
165
|
+
|
166
|
+
(<boolean>this.bodyUsed) = true;
|
167
|
+
|
168
|
+
const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
|
169
|
+
const taskID = taskManager.startTask();
|
170
|
+
let buffer: Buffer;
|
171
|
+
|
172
|
+
try {
|
173
|
+
buffer = await FetchBodyUtility.consumeBodyStream(this.body);
|
174
|
+
} catch (error) {
|
175
|
+
taskManager.endTask(taskID);
|
176
|
+
throw error;
|
177
|
+
}
|
178
|
+
|
179
|
+
taskManager.endTask(taskID);
|
180
|
+
|
181
|
+
return new TextDecoder().decode(buffer);
|
83
182
|
}
|
84
183
|
|
85
184
|
/**
|
@@ -87,73 +186,137 @@ export default class Response extends NodeFetch.Response implements IResponse {
|
|
87
186
|
*
|
88
187
|
* @returns JSON.
|
89
188
|
*/
|
90
|
-
public
|
91
|
-
|
92
|
-
|
93
|
-
super
|
94
|
-
.text()
|
95
|
-
.then(this._handlePromiseEnd.bind(this, resolve, reject, taskID))
|
96
|
-
.catch(this._handlePromiseError.bind(this, reject));
|
97
|
-
});
|
189
|
+
public async json(): Promise<string> {
|
190
|
+
const text = await this.text();
|
191
|
+
return JSON.parse(text);
|
98
192
|
}
|
99
193
|
|
100
194
|
/**
|
101
|
-
* Returns
|
195
|
+
* Returns form data.
|
102
196
|
*
|
103
|
-
* @returns
|
197
|
+
* @returns Form data.
|
104
198
|
*/
|
105
|
-
public
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
199
|
+
public async formData(): Promise<FormData> {
|
200
|
+
const contentType = this.headers.get('content-type');
|
201
|
+
const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
|
202
|
+
const taskID = taskManager.startTask();
|
203
|
+
|
204
|
+
if (contentType.startsWith('application/x-www-form-urlencoded')) {
|
205
|
+
const formData = new FormData();
|
206
|
+
let text: string;
|
207
|
+
|
208
|
+
try {
|
209
|
+
text = await this.text();
|
210
|
+
} catch (error) {
|
211
|
+
taskManager.endTask(taskID);
|
212
|
+
throw error;
|
213
|
+
}
|
214
|
+
|
215
|
+
const parameters = new URLSearchParams(text);
|
216
|
+
|
217
|
+
for (const [name, value] of parameters) {
|
218
|
+
formData.append(name, value);
|
219
|
+
}
|
220
|
+
|
221
|
+
taskManager.endTask(taskID);
|
222
|
+
|
223
|
+
return formData;
|
224
|
+
}
|
225
|
+
|
226
|
+
let formData: FormData;
|
227
|
+
|
228
|
+
try {
|
229
|
+
formData = await MultipartFormDataParser.streamToFormData(this.body, contentType);
|
230
|
+
} catch (error) {
|
231
|
+
taskManager.endTask(taskID);
|
232
|
+
throw error;
|
233
|
+
}
|
234
|
+
|
235
|
+
taskManager.endTask(taskID);
|
236
|
+
|
237
|
+
return formData;
|
113
238
|
}
|
114
239
|
|
115
240
|
/**
|
116
|
-
*
|
241
|
+
* Clones request.
|
117
242
|
*
|
118
|
-
* @returns
|
243
|
+
* @returns Clone.
|
119
244
|
*/
|
120
|
-
|
121
|
-
const
|
122
|
-
|
123
|
-
|
245
|
+
public clone(): IResponse {
|
246
|
+
const response = new Response();
|
247
|
+
|
248
|
+
(<number>response.status) = this.status;
|
249
|
+
(<string>response.statusText) = this.statusText;
|
250
|
+
(<boolean>response.ok) = this.ok;
|
251
|
+
(<Headers>response.headers) = new Headers(this.headers);
|
252
|
+
(<Stream.Readable>response.body) = this.body;
|
253
|
+
(<boolean>response.bodyUsed) = this.bodyUsed;
|
254
|
+
(<boolean>response.redirected) = this.redirected;
|
255
|
+
(<string>response.type) = this.type;
|
256
|
+
(<string>response.url) = this.url;
|
124
257
|
|
258
|
+
return <IResponse>response;
|
259
|
+
}
|
125
260
|
/**
|
126
|
-
*
|
261
|
+
* Returns a redirect response.
|
127
262
|
*
|
128
|
-
* @param
|
129
|
-
* @param
|
130
|
-
* @
|
131
|
-
* @param response Response.
|
263
|
+
* @param url URL.
|
264
|
+
* @param status Status code.
|
265
|
+
* @returns Response.
|
132
266
|
*/
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
const taskManager = this._ownerDocument.defaultView.happyDOM.asyncTaskManager;
|
140
|
-
if (taskManager.getTaskCount() === 0) {
|
141
|
-
reject(new Error('Failed to complete fetch request. Task was canceled.'));
|
142
|
-
} else {
|
143
|
-
resolve(response);
|
144
|
-
taskManager.endTask(taskID);
|
267
|
+
public static redirect(url: string, status = 302): IResponse {
|
268
|
+
if (!REDIRECT_STATUS_CODES.includes(status)) {
|
269
|
+
throw new DOMException(
|
270
|
+
'Failed to create redirect response: Invalid redirect status code.',
|
271
|
+
DOMExceptionNameEnum.invalidStateError
|
272
|
+
);
|
145
273
|
}
|
274
|
+
|
275
|
+
return new Response(null, {
|
276
|
+
headers: {
|
277
|
+
location: new URL(url).toString()
|
278
|
+
},
|
279
|
+
status
|
280
|
+
});
|
146
281
|
}
|
147
282
|
|
148
283
|
/**
|
149
|
-
*
|
284
|
+
* Returns an error response.
|
150
285
|
*
|
151
|
-
* @param
|
152
|
-
* @param
|
286
|
+
* @param url URL.
|
287
|
+
* @param status Status code.
|
288
|
+
* @returns Response.
|
153
289
|
*/
|
154
|
-
|
155
|
-
const
|
156
|
-
|
157
|
-
|
290
|
+
public static error(): IResponse {
|
291
|
+
const response = new Response(null, { status: 0, statusText: '' });
|
292
|
+
(<string>response.type) = 'error';
|
293
|
+
return response;
|
294
|
+
}
|
295
|
+
|
296
|
+
/**
|
297
|
+
* Returns an JSON response.
|
298
|
+
*
|
299
|
+
* @param data Data.
|
300
|
+
* @param [init] Init.
|
301
|
+
* @returns Response.
|
302
|
+
*/
|
303
|
+
public static json(data: object, init?: IResponseInit): IResponse {
|
304
|
+
const body = JSON.stringify(data);
|
305
|
+
|
306
|
+
if (body === undefined) {
|
307
|
+
throw new TypeError('data is not JSON serializable');
|
308
|
+
}
|
309
|
+
|
310
|
+
const headers = new Headers(init && init.headers);
|
311
|
+
|
312
|
+
if (!headers.has('content-type')) {
|
313
|
+
headers.set('content-type', 'application/json');
|
314
|
+
}
|
315
|
+
|
316
|
+
return new Response(body, {
|
317
|
+
status: 200,
|
318
|
+
...init,
|
319
|
+
headers
|
320
|
+
});
|
158
321
|
}
|
159
322
|
}
|
@@ -0,0 +1,66 @@
|
|
1
|
+
/**
|
2
|
+
* Data URI parser.
|
3
|
+
*
|
4
|
+
* Based on:
|
5
|
+
* https://github.com/TooTallNate/node-data-uri-to-buffer/blob/main/src/index.ts (MIT)
|
6
|
+
*/
|
7
|
+
export default class DataURIParser {
|
8
|
+
/**
|
9
|
+
* Returns a Buffer instance from the given data URI `uri`.
|
10
|
+
*
|
11
|
+
* @param uri Data URI.
|
12
|
+
* @returns Buffer.
|
13
|
+
*/
|
14
|
+
public static parse(uri: string): {
|
15
|
+
type: string;
|
16
|
+
charset: string;
|
17
|
+
buffer: Buffer;
|
18
|
+
} {
|
19
|
+
if (!/^data:/i.test(uri)) {
|
20
|
+
throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")');
|
21
|
+
}
|
22
|
+
|
23
|
+
// Strip newlines
|
24
|
+
uri = uri.replace(/\r?\n/g, '');
|
25
|
+
|
26
|
+
// Split the URI up into the "metadata" and the "data" portions
|
27
|
+
const firstComma = uri.indexOf(',');
|
28
|
+
if (firstComma === -1 || firstComma <= 4) {
|
29
|
+
throw new TypeError('malformed data: URI');
|
30
|
+
}
|
31
|
+
|
32
|
+
// Remove the "data:" scheme and parse the metadata
|
33
|
+
const meta = uri.substring(5, firstComma).split(';');
|
34
|
+
let charset = '';
|
35
|
+
let base64 = false;
|
36
|
+
let type = meta[0] || 'text/plain';
|
37
|
+
|
38
|
+
for (let i = 1; i < meta.length; i++) {
|
39
|
+
if (meta[i] === 'base64') {
|
40
|
+
base64 = true;
|
41
|
+
} else if (meta[i]) {
|
42
|
+
type += `;${meta[i]}`;
|
43
|
+
if (meta[i].indexOf('charset=') === 0) {
|
44
|
+
charset = meta[i].substring(8);
|
45
|
+
}
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
// Defaults to US-ASCII only if type is not provided
|
50
|
+
if (!meta[0] && !charset.length) {
|
51
|
+
type += ';charset=US-ASCII';
|
52
|
+
charset = 'US-ASCII';
|
53
|
+
}
|
54
|
+
|
55
|
+
// Get the encoded data portion and decode URI-encoded chars
|
56
|
+
const encoding = base64 ? 'base64' : 'ascii';
|
57
|
+
const data = unescape(uri.substring(firstComma + 1));
|
58
|
+
const buffer = Buffer.from(data, encoding);
|
59
|
+
|
60
|
+
return {
|
61
|
+
type,
|
62
|
+
charset,
|
63
|
+
buffer
|
64
|
+
};
|
65
|
+
}
|
66
|
+
}
|
@@ -0,0 +1,113 @@
|
|
1
|
+
import FormData from '../../form-data/FormData';
|
2
|
+
import Stream from 'stream';
|
3
|
+
import MultipartReader from './MultipartReader';
|
4
|
+
import DOMException from '../../exception/DOMException';
|
5
|
+
import DOMExceptionNameEnum from '../../exception/DOMExceptionNameEnum';
|
6
|
+
|
7
|
+
/**
|
8
|
+
* Multipart form data factory.
|
9
|
+
*
|
10
|
+
* Based on:
|
11
|
+
* https://github.com/node-fetch/node-fetch/blob/main/src/utils/multipart-parser.js (MIT)
|
12
|
+
*/
|
13
|
+
export default class MultipartFormDataParser {
|
14
|
+
/**
|
15
|
+
* Returns form data.
|
16
|
+
*
|
17
|
+
* @param body Body.
|
18
|
+
* @param contentType Content type header value.
|
19
|
+
* @returns Form data.
|
20
|
+
*/
|
21
|
+
public static async streamToFormData(
|
22
|
+
body: Stream.Readable,
|
23
|
+
contentType: string
|
24
|
+
): Promise<FormData> {
|
25
|
+
if (!/multipart/i.test(contentType)) {
|
26
|
+
throw new DOMException(
|
27
|
+
`Failed to build FormData object: The "content-type" header isn't of type "multipart/form-data".`,
|
28
|
+
DOMExceptionNameEnum.invalidStateError
|
29
|
+
);
|
30
|
+
}
|
31
|
+
|
32
|
+
const match = contentType.match(/boundary=(?:"([^"]+)"|([^;]+))/i);
|
33
|
+
|
34
|
+
if (!match) {
|
35
|
+
throw new DOMException(
|
36
|
+
`Failed to build FormData object: The "content-type" header doesn't contain any multipart boundary.`,
|
37
|
+
DOMExceptionNameEnum.invalidStateError
|
38
|
+
);
|
39
|
+
}
|
40
|
+
|
41
|
+
const reader = new MultipartReader(match[1] || match[2]);
|
42
|
+
|
43
|
+
for await (const chunk of body) {
|
44
|
+
reader.write(chunk);
|
45
|
+
}
|
46
|
+
|
47
|
+
return reader.end();
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Converts a FormData object to a ReadableStream.
|
52
|
+
*
|
53
|
+
* @param formData FormData.
|
54
|
+
* @returns Stream and type.
|
55
|
+
*/
|
56
|
+
public static formDataToStream(formData: FormData): {
|
57
|
+
contentType: string;
|
58
|
+
contentLength: number;
|
59
|
+
buffer: Buffer;
|
60
|
+
stream: Stream.Readable;
|
61
|
+
} {
|
62
|
+
const boundary = '----HappyDOMFormDataBoundary' + Math.random().toString(36);
|
63
|
+
const chunks: Buffer[] = [];
|
64
|
+
const prefix = `--${boundary}\r\nContent-Disposition: form-data; name="`;
|
65
|
+
|
66
|
+
for (const [name, value] of formData) {
|
67
|
+
if (typeof value === 'string') {
|
68
|
+
chunks.push(
|
69
|
+
Buffer.from(
|
70
|
+
`${prefix}${this.escapeName(name)}"\r\n\r\n${value.replace(
|
71
|
+
/\r(?!\n)|(?<!\r)\n/g,
|
72
|
+
'\r\n'
|
73
|
+
)}\r\n`
|
74
|
+
)
|
75
|
+
);
|
76
|
+
} else {
|
77
|
+
chunks.push(
|
78
|
+
Buffer.from(
|
79
|
+
`${prefix}${this.escapeName(name)}"; filename="${this.escapeName(
|
80
|
+
value.name,
|
81
|
+
true
|
82
|
+
)}"\r\nContent-Type: ${value.type || 'application/octet-stream'}\r\n\r\n`
|
83
|
+
)
|
84
|
+
);
|
85
|
+
chunks.push(value._buffer);
|
86
|
+
chunks.push(Buffer.from('\r\n'));
|
87
|
+
}
|
88
|
+
}
|
89
|
+
|
90
|
+
const buffer = Buffer.concat(chunks);
|
91
|
+
|
92
|
+
return {
|
93
|
+
contentType: `multipart/form-data; boundary=${boundary}`,
|
94
|
+
contentLength: buffer.length,
|
95
|
+
buffer,
|
96
|
+
stream: Stream.Readable.from(buffer)
|
97
|
+
};
|
98
|
+
}
|
99
|
+
|
100
|
+
/**
|
101
|
+
* Escapes a form data entry name.
|
102
|
+
*
|
103
|
+
* @param name Name.
|
104
|
+
* @param filename Whether it is a filename.
|
105
|
+
* @returns Escaped name.
|
106
|
+
*/
|
107
|
+
private static escapeName(name: string, filename = false): string {
|
108
|
+
return (filename ? name : name.replace(/\r?\n|\r/g, '\r\n'))
|
109
|
+
.replace(/\n/g, '%0A')
|
110
|
+
.replace(/\r/g, '%0D')
|
111
|
+
.replace(/"/g, '%22');
|
112
|
+
}
|
113
|
+
}
|