@gcmdev/faxios 0.2.1 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/dist/index.d.ts +3 -3
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/adapters/fetch-helpers.d.ts +1 -1
  6. package/dist/lib/adapters/fetch-helpers.d.ts.map +1 -1
  7. package/dist/lib/adapters/fetch.d.ts +4 -1
  8. package/dist/lib/adapters/fetch.d.ts.map +1 -1
  9. package/dist/lib/adapters/fetch.js +210 -92
  10. package/dist/lib/adapters/fetch.js.map +1 -1
  11. package/dist/lib/cancel/CanceledError.d.ts +1 -1
  12. package/dist/lib/cancel/CanceledError.d.ts.map +1 -1
  13. package/dist/lib/core/Faxios.d.ts +3 -3
  14. package/dist/lib/core/Faxios.d.ts.map +1 -1
  15. package/dist/lib/core/Faxios.js +8 -4
  16. package/dist/lib/core/Faxios.js.map +1 -1
  17. package/dist/lib/core/FaxiosError.d.ts +2 -2
  18. package/dist/lib/core/FaxiosError.d.ts.map +1 -1
  19. package/dist/lib/core/FaxiosHeaders.d.ts +8 -8
  20. package/dist/lib/core/FaxiosHeaders.d.ts.map +1 -1
  21. package/dist/lib/core/FaxiosHeaders.js +31 -7
  22. package/dist/lib/core/FaxiosHeaders.js.map +1 -1
  23. package/dist/lib/core/define.d.ts +3 -3
  24. package/dist/lib/core/define.d.ts.map +1 -1
  25. package/dist/lib/core/dispatchRequest.d.ts +1 -1
  26. package/dist/lib/core/dispatchRequest.d.ts.map +1 -1
  27. package/dist/lib/core/dispatchRequest.js +6 -1
  28. package/dist/lib/core/dispatchRequest.js.map +1 -1
  29. package/dist/lib/core/mergeConfig.d.ts +2 -2
  30. package/dist/lib/core/mergeConfig.d.ts.map +1 -1
  31. package/dist/lib/core/mergeConfig.js +40 -2
  32. package/dist/lib/core/mergeConfig.js.map +1 -1
  33. package/dist/lib/core/route.d.ts +1 -1
  34. package/dist/lib/core/route.d.ts.map +1 -1
  35. package/dist/lib/core/route.js +2 -5
  36. package/dist/lib/core/route.js.map +1 -1
  37. package/dist/lib/core/transformData.d.ts +2 -2
  38. package/dist/lib/core/transformData.d.ts.map +1 -1
  39. package/dist/lib/core/validateSchema.d.ts +2 -2
  40. package/dist/lib/core/validateSchema.d.ts.map +1 -1
  41. package/dist/lib/env/data.d.ts +1 -1
  42. package/dist/lib/env/data.js +1 -1
  43. package/dist/lib/faxios.d.ts +50 -50
  44. package/dist/lib/faxios.d.ts.map +1 -1
  45. package/dist/lib/helpers/cloneConfig.d.ts +0 -1
  46. package/dist/lib/helpers/cloneConfig.d.ts.map +1 -1
  47. package/dist/lib/helpers/cloneConfig.js +2 -2
  48. package/dist/lib/helpers/cloneConfig.js.map +1 -1
  49. package/dist/lib/helpers/cookies.d.ts +1 -1
  50. package/dist/lib/helpers/cookies.d.ts.map +1 -1
  51. package/dist/lib/helpers/formDataToJSON.d.ts +1 -1
  52. package/dist/lib/helpers/formDataToJSON.d.ts.map +1 -1
  53. package/dist/lib/helpers/formDataToJSON.js +1 -1
  54. package/dist/lib/helpers/formDataToJSON.js.map +1 -1
  55. package/dist/lib/helpers/parseHeaders.d.ts +1 -1
  56. package/dist/lib/helpers/parseHeaders.d.ts.map +1 -1
  57. package/dist/lib/helpers/progressEventReducer.d.ts.map +1 -1
  58. package/dist/lib/helpers/progressEventReducer.js +14 -1
  59. package/dist/lib/helpers/progressEventReducer.js.map +1 -1
  60. package/dist/lib/helpers/substitutePathParams.d.ts.map +1 -1
  61. package/dist/lib/helpers/substitutePathParams.js +11 -3
  62. package/dist/lib/helpers/substitutePathParams.js.map +1 -1
  63. package/dist/lib/helpers/toFormData.d.ts.map +1 -1
  64. package/dist/lib/helpers/toFormData.js +16 -20
  65. package/dist/lib/helpers/toFormData.js.map +1 -1
  66. package/dist/lib/helpers/trackStream.d.ts.map +1 -1
  67. package/dist/lib/helpers/trackStream.js +27 -3
  68. package/dist/lib/helpers/trackStream.js.map +1 -1
  69. package/dist/lib/helpers/validator.d.ts +1 -1
  70. package/dist/lib/helpers/validator.d.ts.map +1 -1
  71. package/dist/lib/platform.d.ts.map +1 -1
  72. package/dist/lib/plugins/authBearer.d.ts +9 -5
  73. package/dist/lib/plugins/authBearer.d.ts.map +1 -1
  74. package/dist/lib/plugins/authBearer.js +6 -0
  75. package/dist/lib/plugins/authBearer.js.map +1 -1
  76. package/dist/lib/plugins/definePlugin.d.ts +3 -3
  77. package/dist/lib/plugins/definePlugin.d.ts.map +1 -1
  78. package/dist/lib/plugins/retry.d.ts +23 -23
  79. package/dist/lib/plugins/retry.d.ts.map +1 -1
  80. package/dist/lib/plugins/timing.d.ts +8 -8
  81. package/dist/lib/plugins/timing.d.ts.map +1 -1
  82. package/dist/lib/types/standard-schema.d.ts +6 -6
  83. package/dist/lib/types/standard-schema.d.ts.map +1 -1
  84. package/dist/lib/types.d.ts +106 -92
  85. package/dist/lib/types.d.ts.map +1 -1
  86. package/dist/lib/utils.d.ts +4 -3
  87. package/dist/lib/utils.d.ts.map +1 -1
  88. package/dist/lib/utils.js +18 -5
  89. package/dist/lib/utils.js.map +1 -1
  90. package/package.json +7 -4
  91. package/skills/configure-requests/SKILL.md +14 -8
  92. package/skills/configure-requests/references/axios-differences.md +1 -1
  93. package/skills/configure-requests/references/plugins.md +37 -6
  94. package/src/index.ts +15 -15
  95. package/src/lib/adapters/fetch-helpers.ts +3 -3
  96. package/src/lib/adapters/fetch.ts +263 -144
  97. package/src/lib/cancel/CanceledError.ts +1 -1
  98. package/src/lib/core/Faxios.ts +17 -13
  99. package/src/lib/core/FaxiosError.ts +3 -3
  100. package/src/lib/core/FaxiosHeaders.ts +50 -23
  101. package/src/lib/core/define.ts +7 -7
  102. package/src/lib/core/dispatchRequest.ts +8 -3
  103. package/src/lib/core/mergeConfig.ts +42 -4
  104. package/src/lib/core/prepareRequest.ts +1 -1
  105. package/src/lib/core/route.ts +3 -6
  106. package/src/lib/core/transformData.ts +2 -2
  107. package/src/lib/core/validateSchema.ts +4 -4
  108. package/src/lib/defaults/index.ts +1 -1
  109. package/src/lib/env/data.ts +1 -1
  110. package/src/lib/faxios.ts +55 -55
  111. package/src/lib/helpers/HttpStatusCode.ts +1 -1
  112. package/src/lib/helpers/cloneConfig.ts +2 -3
  113. package/src/lib/helpers/composeSignals.ts +4 -4
  114. package/src/lib/helpers/cookies.ts +3 -3
  115. package/src/lib/helpers/formDataToJSON.ts +4 -4
  116. package/src/lib/helpers/parseHeaders.ts +2 -2
  117. package/src/lib/helpers/progressEventReducer.ts +15 -2
  118. package/src/lib/helpers/sanitizeHeaderValue.ts +1 -1
  119. package/src/lib/helpers/substitutePathParams.ts +13 -3
  120. package/src/lib/helpers/throttle.ts +1 -1
  121. package/src/lib/helpers/toFormData.ts +26 -28
  122. package/src/lib/helpers/trackStream.ts +40 -12
  123. package/src/lib/helpers/validator.ts +3 -3
  124. package/src/lib/platform.ts +4 -4
  125. package/src/lib/plugins/authBearer.ts +14 -9
  126. package/src/lib/plugins/definePlugin.ts +3 -3
  127. package/src/lib/plugins/retry.ts +27 -27
  128. package/src/lib/plugins/timing.ts +5 -5
  129. package/src/lib/types/standard-schema.ts +6 -6
  130. package/src/lib/types.ts +139 -125
  131. package/src/lib/utils.ts +30 -15
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import type { CreateFaxiosDefaults } from "./lib/types.js";
4
4
  export { default as Faxios } from "./lib/core/Faxios.js";
5
5
  export { default as FaxiosError, isSchemaValidationError } from "./lib/core/FaxiosError.js";
6
6
  export type { SchemaValidationError } from "./lib/core/FaxiosError.js";
7
- export { default as CanceledError, default as Cancel } from "./lib/cancel/CanceledError.js";
7
+ export { default as Cancel, default as CanceledError } from "./lib/cancel/CanceledError.js";
8
8
  export { default as isCancel } from "./lib/cancel/isCancel.js";
9
9
  export { default as isFaxiosError } from "./lib/helpers/isFaxiosError.js";
10
10
  export { default as toFormData } from "./lib/helpers/toFormData.js";
@@ -15,8 +15,8 @@ export { VERSION } from "./lib/env/data.js";
15
15
  export type { FaxiosInstance, FaxiosStatic } from "./lib/faxios.js";
16
16
  export type { StandardSchemaV1 } from "./lib/types/standard-schema.js";
17
17
  export type { BasePerCallConfig, DefineConfig, DefinedEndpoint, FaxiosLike, PerCallConfig } from "./lib/core/define.js";
18
- export type { RouteConfig, RouteMethodConfig, RouteBuilder } from "./lib/core/route.js";
19
- export type { FaxiosRequestConfig, InternalFaxiosRequestConfig, FaxiosResponse, FaxiosRequestHeaders, FaxiosResponseHeadersLike, FaxiosHeaderValue, Method, ResponseType, GenericHTMLFormElement, RawFaxiosRequestConfig, FaxiosPromise, CreateFaxiosDefaults, FaxiosConfigHeaders, RawFaxiosRequestHeaders, HeadersDefaults, FaxiosContext, FaxiosNext, FaxiosMiddleware, FaxiosPlugin } from "./lib/types.js";
18
+ export type { RouteBuilder, RouteConfig, RouteMethodConfig } from "./lib/core/route.js";
19
+ export type { CreateFaxiosDefaults, FaxiosConfigHeaders, FaxiosContext, FaxiosHeaderValue, FaxiosMiddleware, FaxiosNext, FaxiosPlugin, FaxiosPromise, FaxiosRequestConfig, FaxiosRequestHeaders, FaxiosResponse, FaxiosResponseHeadersLike, GenericHTMLFormElement, HeadersDefaults, InternalFaxiosRequestConfig, Method, RawFaxiosRequestConfig, RawFaxiosRequestHeaders, ResponseType } from "./lib/types.js";
20
20
  export declare const all: FaxiosStatic["all"];
21
21
  export declare const formToJSON: FaxiosStatic["formToJSON"];
22
22
  export declare const create: (instanceConfig?: CreateFaxiosDefaults) => FaxiosInstance;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,MAAM,wBAAwB;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,wBAAwB;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB;AAM3D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,6BAA6B;AACzD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,uBAAuB,EAAE,kCAAkC;AAC5F,YAAY,EAAE,qBAAqB,EAAE,kCAAkC;AACvE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,OAAO,IAAI,MAAM,EAAE,sCAAsC;AAC5F,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,iCAAiC;AAC/D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,uCAAuC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,oCAAoC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,oCAAoC;AACvE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,wCAAwC;AAC5E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,kCAAkC;AACnE,OAAO,EAAE,OAAO,EAAE,0BAA0B;AAE5C,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,wBAAwB;AACpE,YAAY,EAAE,gBAAgB,EAAE,uCAAuC;AACvE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,6BAA6B;AACxH,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,YAAY,EAAE,4BAA4B;AAExF,YAAY,EACV,mBAAmB,EACnB,2BAA2B,EAC3B,cAAc,EACd,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,EACjB,MAAM,EACN,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,aAAa,EACb,oBAAoB,EACpB,mBAAmB,EACnB,uBAAuB,EACvB,eAAe,EACf,aAAa,EACb,UAAU,EACV,gBAAgB,EAChB,YAAY,EACb,uBAAuB;AAKxB,eAAO,MAAM,GAAG,EAAE,YAAY,CAAC,KAAK,CAAc,CAAC;AACnD,eAAO,MAAM,UAAU,EAAE,YAAY,CAAC,YAAY,CAAqB,CAAC;AACxE,eAAO,MAAM,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,oBAAoB,KAAK,cAA8B,CAAC;AAE/F,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,MAAM,wBAAwB;AACrC,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,wBAAwB;AACpE,OAAO,KAAK,EAAE,oBAAoB,EAAE,uBAAuB;AAM3D,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,6BAA6B;AACzD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,uBAAuB,EAAE,kCAAkC;AAC5F,YAAY,EAAE,qBAAqB,EAAE,kCAAkC;AACvE,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,OAAO,IAAI,aAAa,EAAE,sCAAsC;AAC5F,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,iCAAiC;AAC/D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,uCAAuC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,oCAAoC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,oCAAoC;AACvE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,wCAAwC;AAC5E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,kCAAkC;AACnE,OAAO,EAAE,OAAO,EAAE,0BAA0B;AAE5C,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,wBAAwB;AACpE,YAAY,EAAE,gBAAgB,EAAE,uCAAuC;AACvE,YAAY,EAAE,iBAAiB,EAAE,YAAY,EAAE,eAAe,EAAE,UAAU,EAAE,aAAa,EAAE,6BAA6B;AACxH,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,4BAA4B;AAExF,YAAY,EACV,oBAAoB,EACpB,mBAAmB,EACnB,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACV,YAAY,EACZ,aAAa,EACb,mBAAmB,EACnB,oBAAoB,EACpB,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,eAAe,EACf,2BAA2B,EAC3B,MAAM,EACN,sBAAsB,EACtB,uBAAuB,EACvB,YAAY,EACb,uBAAuB;AAKxB,eAAO,MAAM,GAAG,EAAE,YAAY,CAAC,KAAK,CAAc,CAAC;AACnD,eAAO,MAAM,UAAU,EAAE,YAAY,CAAC,YAAY,CAAqB,CAAC;AACxE,eAAO,MAAM,MAAM,EAAE,CAAC,cAAc,CAAC,EAAE,oBAAoB,KAAK,cAA8B,CAAC;AAE/F,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,CAAC"}
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import faxios from "./lib/faxios.js";
7
7
  // runtime instance forced TS to emit the broken inline `import("./x.ts")` form.
8
8
  export { default as Faxios } from "./lib/core/Faxios.js";
9
9
  export { default as FaxiosError, isSchemaValidationError } from "./lib/core/FaxiosError.js";
10
- export { default as CanceledError, default as Cancel } from "./lib/cancel/CanceledError.js";
10
+ export { default as Cancel, default as CanceledError } from "./lib/cancel/CanceledError.js";
11
11
  export { default as isCancel } from "./lib/cancel/isCancel.js";
12
12
  export { default as isFaxiosError } from "./lib/helpers/isFaxiosError.js";
13
13
  export { default as toFormData } from "./lib/helpers/toFormData.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,oDAAoD;AACpD,OAAO,MAAM,wBAAwB;AAIrC,oEAAoE;AACpE,wEAAwE;AACxE,0EAA0E;AAC1E,gFAAgF;AAChF,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,6BAA6B;AACzD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,uBAAuB,EAAE,kCAAkC;AAE5F,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,OAAO,IAAI,MAAM,EAAE,sCAAsC;AAC5F,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,iCAAiC;AAC/D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,uCAAuC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,oCAAoC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,oCAAoC;AACvE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,wCAAwC;AAC5E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,kCAAkC;AACnE,OAAO,EAAE,OAAO,EAAE,0BAA0B;AA6B5C,gFAAgF;AAChF,+EAA+E;AAC/E,yFAAyF;AACzF,MAAM,CAAC,MAAM,GAAG,GAAwB,MAAM,CAAC,GAAG,CAAC;AACnD,MAAM,CAAC,MAAM,UAAU,GAA+B,MAAM,CAAC,UAAU,CAAC;AACxE,MAAM,CAAC,MAAM,MAAM,GAA8D,MAAM,CAAC,MAAM,CAAC;AAE/F,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gCAAgC;AAChC,oDAAoD;AACpD,OAAO,MAAM,wBAAwB;AAIrC,oEAAoE;AACpE,wEAAwE;AACxE,0EAA0E;AAC1E,gFAAgF;AAChF,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,6BAA6B;AACzD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,uBAAuB,EAAE,kCAAkC;AAE5F,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,OAAO,IAAI,aAAa,EAAE,sCAAsC;AAC5F,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,iCAAiC;AAC/D,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,uCAAuC;AAC1E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,oCAAoC;AACpE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,oCAAoC;AACvE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,wCAAwC;AAC5E,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,kCAAkC;AACnE,OAAO,EAAE,OAAO,EAAE,0BAA0B;AA6B5C,gFAAgF;AAChF,+EAA+E;AAC/E,yFAAyF;AACzF,MAAM,CAAC,MAAM,GAAG,GAAwB,MAAM,CAAC,GAAG,CAAC;AACnD,MAAM,CAAC,MAAM,UAAU,GAA+B,MAAM,CAAC,UAAU,CAAC;AACxE,MAAM,CAAC,MAAM,MAAM,GAA8D,MAAM,CAAC,MAAM,CAAC;AAE/F,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import FaxiosError from "../core/FaxiosError.js";
2
2
  import type FaxiosHeaders from "../core/FaxiosHeaders.js";
3
- import type { InternalFaxiosRequestConfig, FaxiosRequestHeaders } from "../types.js";
3
+ import type { FaxiosRequestHeaders, InternalFaxiosRequestConfig } from "../types.js";
4
4
  export type ComposedSignal = AbortSignal & {
5
5
  unsubscribe?: () => void;
6
6
  };
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/fetch-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,WAAW,+BAA+B;AACjD,OAAO,KAAK,aAAa,iCAAiC;AAC1D,OAAO,KAAK,EACV,2BAA2B,EAC3B,oBAAoB,EAErB,oBAAoB;AAGrB,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAAE,CAAC;AACzE,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,CAAC,WAAW,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;KAAE,CAAC,GAAG,IAAI,CAAC;CAAE,CAAC;AAM5F,eAAO,MAAM,0BAA0B,GACrC,iBAAiB,aAAa,EAC9B,qBAAqB,OAAO,EAC5B,kBAAkB,MAAM,EACxB,QAAQ,2BAA2B,EACnC,SAAS,OAAO,KACf,IAaF,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAChC,cAAc,OAAO,EACrB,qBAAqB,OAAO,EAC5B,kBAAkB,MAAM,EACxB,kBAAkB,OAAO,EACzB,wBAAwB,OAAO,EAC/B,QAAQ,2BAA2B,EACnC,SAAS,OAAO,KACf,IAwBF,CAAC;AAGF,eAAO,MAAM,sBAAsB,GACjC,KAAK,OAAO,EACZ,gBAAgB,cAAc,GAAG,SAAS,EAC1C,qBAAqB,mBAAmB,EACxC,QAAQ,2BAA2B,EACnC,SAAS,OAAO,KACf,KAyDF,CAAC;AAGF,eAAO,MAAM,wBAAwB,GACnC,MAAM,OAAO,EACb,SAAS,oBAAoB,KAC5B,IAWF,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,EACb,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,KACxD,OAAO,CAAC,OAAO,CAAC,GAAG,OAIrB,CAAC"}
1
+ {"version":3,"file":"fetch-helpers.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/fetch-helpers.ts"],"names":[],"mappings":"AAEA,OAAO,WAAW,+BAA+B;AACjD,OAAO,KAAK,aAAa,iCAAiC;AAC1D,OAAO,KAAK,EACV,oBAAoB,EAEpB,2BAA2B,EAC5B,oBAAoB;AAGrB,MAAM,MAAM,cAAc,GAAG,WAAW,GAAG;IAAE,WAAW,CAAC,EAAE,MAAM,IAAI,CAAC;CAAE,CAAC;AACzE,MAAM,MAAM,mBAAmB,GAAG;IAAE,KAAK,EAAE,CAAC,WAAW,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;KAAE,CAAC,GAAG,IAAI,CAAC;CAAE,CAAC;AAM5F,eAAO,MAAM,0BAA0B,GACrC,iBAAiB,aAAa,EAC9B,qBAAqB,OAAO,EAC5B,kBAAkB,MAAM,EACxB,QAAQ,2BAA2B,EACnC,SAAS,OAAO,KACf,IAaF,CAAC;AAGF,eAAO,MAAM,qBAAqB,GAChC,cAAc,OAAO,EACrB,qBAAqB,OAAO,EAC5B,kBAAkB,MAAM,EACxB,kBAAkB,OAAO,EACzB,wBAAwB,OAAO,EAC/B,QAAQ,2BAA2B,EACnC,SAAS,OAAO,KACf,IAwBF,CAAC;AAGF,eAAO,MAAM,sBAAsB,GACjC,KAAK,OAAO,EACZ,gBAAgB,cAAc,GAAG,SAAS,EAC1C,qBAAqB,mBAAmB,EACxC,QAAQ,2BAA2B,EACnC,SAAS,OAAO,KACf,KAyDF,CAAC;AAGF,eAAO,MAAM,wBAAwB,GACnC,MAAM,OAAO,EACb,SAAS,oBAAoB,KAC5B,IAWF,CAAC;AAGF,eAAO,MAAM,kBAAkB,GAC7B,MAAM,OAAO,EACb,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAChC,QAAQ,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,CAAC,GAAG,UAAU,KACxD,OAAO,CAAC,OAAO,CAAC,GAAG,OAIrB,CAAC"}
@@ -1,4 +1,7 @@
1
+ import type { InternalFaxiosRequestConfig } from "../types.js";
2
+ type FetchAdapter = (config: InternalFaxiosRequestConfig) => Promise<unknown>;
1
3
  export declare const getFetch: (config?: {
2
4
  env?: Record<string, unknown>;
3
- }) => unknown;
5
+ }) => false | FetchAdapter;
6
+ export {};
4
7
  //# sourceMappingURL=fetch.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/fetch.ts"],"names":[],"mappings":"AA2wBA,eAAO,MAAM,QAAQ,GAAI,SAAS;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAAE,YA4BnE,CAAC"}
1
+ {"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/lib/adapters/fetch.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAEV,2BAA2B,EAC5B,oBAAoB;AA6JrB,KAAK,YAAY,GAAG,CAAC,MAAM,EAAE,2BAA2B,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAytB9E,eAAO,MAAM,QAAQ,GAAI,SAAS;IAAE,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAAE,KAAG,KAAK,GAAG,YAsB9E,CAAC"}
@@ -5,20 +5,37 @@ import { settle } from "../core/settle.js";
5
5
  import { VERSION } from "../env/data.js";
6
6
  import composeSignals from "../helpers/composeSignals.js";
7
7
  import estimateDataURLDecodedBytes from "../helpers/estimateDataURLDecodedBytes.js";
8
- import { progressEventReducer, progressEventDecorator, asyncDecorator } from "../helpers/progressEventReducer.js";
8
+ import { asyncDecorator, progressEventDecorator, progressEventReducer } from "../helpers/progressEventReducer.js";
9
9
  import { toByteStringHeaderObject } from "../helpers/sanitizeHeaderValue.js";
10
10
  import { trackStream } from "../helpers/trackStream.js";
11
11
  import platform from "../platform.js";
12
12
  import utils from "../utils.js";
13
- import { checkDeclaredContentLength, checkMaterializedSize, handleFetchCaughtError, cleanFormDataContentType, encodeBodyIfNeeded } from "./fetch-helpers.js";
13
+ import { checkDeclaredContentLength, checkMaterializedSize, cleanFormDataContentType, encodeBodyIfNeeded, handleFetchCaughtError } from "./fetch-helpers.js";
14
14
  // btoa is a global in Node 16+ and browsers; accessed via globalThis for no-DOM lib compat
15
15
  const _btoa = globalThis["btoa"];
16
16
  const DEFAULT_CHUNK_SIZE = 64 * 1024;
17
17
  const { isFunction } = utils;
18
+ // Web stream bodies this adapter has sent. fetch can read a stream without leaving it locked,
19
+ // and there's no portable "disturbed" check, so a second send is caught here.
20
+ const sentStreamBodies = new WeakSet();
21
+ // A stream body can be read once. Middleware that calls next() again after a try read it
22
+ // would send an empty body (Node stream) or get an uncoded TypeError from fetch (web stream).
23
+ const rejectUsedStreamBody = (data, config) => {
24
+ const body = data;
25
+ const isWebStream = utils.isReadableStream(data);
26
+ if ((isWebStream && (body.locked === true || sentStreamBodies.has(body))) ||
27
+ ((utils.isRequest(data) || utils.isResponse(data)) && body.bodyUsed === true) ||
28
+ (utils.isStream(data) && (body.readableDidRead === true || body.readableEnded === true || body.destroyed === true))) {
29
+ throw new FaxiosError("Request body stream was already used and can't be sent again; pass a new body for each try", FaxiosError.ERR_BAD_REQUEST, config);
30
+ }
31
+ if (isWebStream)
32
+ sentStreamBodies.add(body);
33
+ };
34
+ const isBrowserRuntime = platform.hasStandardBrowserEnv || platform.hasStandardBrowserWebWorkerEnv;
18
35
  // Server runtimes default User-Agent to their own (e.g. "node"), so name faxios there.
19
36
  // Browsers send their own User-Agent; setting one makes every cross-origin request
20
37
  // need a CORS preflight that most APIs don't allow.
21
- const setsUserAgent = !platform.hasStandardBrowserEnv && !platform.hasStandardBrowserWebWorkerEnv;
38
+ const setsUserAgent = !isBrowserRuntime;
22
39
  const applyDefaultUserAgent = (headers) => {
23
40
  if (setsUserAgent)
24
41
  headers.set("User-Agent", "faxios/" + VERSION, false);
@@ -61,28 +78,68 @@ const maybeWithAuthCredentials = (url) => {
61
78
  // Only `@` indicates credentials in the authority; `:` alone is a port separator.
62
79
  return urlToCheck.includes("@");
63
80
  };
64
- // eslint-disable-next-line sonarjs/function-return-type
81
+ // RequestInit members faxios sets itself; the same keys in `fetchOptions` are ignored.
82
+ const FAXIOS_INIT_KEYS = {
83
+ body: true,
84
+ credentials: true,
85
+ duplex: true,
86
+ headers: true,
87
+ method: true,
88
+ signal: true,
89
+ };
90
+ // Spec defaults written as own init members when the caller sets none. undici converts the init
91
+ // into a plain dictionary and reads absent members from it, so an absent member still picks up a
92
+ // polluted Object.prototype value; an own default leaves nothing to inherit.
93
+ const REQUEST_INIT_DEFAULTS = {
94
+ cache: "default",
95
+ integrity: "",
96
+ keepalive: false,
97
+ mode: "cors",
98
+ redirect: "follow",
99
+ referrer: "about:client",
100
+ referrerPolicy: "",
101
+ };
102
+ // Where undici (Node's fetch) keeps its global dispatcher.
103
+ const UNDICI_GLOBAL_DISPATCHER = Symbol.for("undici.globalDispatcher.1");
104
+ // Own reads only: a polluted Object.prototype.fetch must never become the transport.
105
+ const readOwn = (obj, key) => typeof obj === "object" && obj !== null && utils.hasOwnProp(obj, key) ? Reflect.get(obj, key) : undefined;
106
+ const ownEnv = (config, key) => readOwn(readOwn(config, "env"), key);
107
+ // Feature detection depends only on the Request and Response constructors, so one adapter
108
+ // serves every `env.fetch`. `env.fetch` is read for each request.
65
109
  const factory = (env) => {
66
110
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
67
111
  const globalObject = utils.global ?? globalThis;
68
112
  const ReadableStream = globalObject["ReadableStream"];
69
113
  const TextEncoder = globalObject["TextEncoder"];
70
- env = utils.merge.call({
71
- skipUndefined: true,
72
- }, {
73
- Request: globalObject["Request"],
74
- Response: globalObject["Response"],
75
- }, env);
76
- const { fetch: envFetch, Request, Response, } = env;
77
- const _globalFetch = globalThis["fetch"];
78
- const isFetchSupported = envFetch
79
- ? isFunction(envFetch)
80
- : isFunction(_globalFetch);
114
+ // `undefined` falls back to the global constructor; `null` disables it.
115
+ const Request = (env.Request === undefined ? globalObject["Request"] : env.Request);
116
+ const Response = (env.Response === undefined ? globalObject["Response"] : env.Response);
81
117
  const isRequestSupported = isFunction(Request);
82
118
  const isResponseSupported = isFunction(Response);
83
- if (!isFetchSupported) {
84
- return false;
85
- }
119
+ // Only members this runtime's Request exposes, so an engine that rejects members it doesn't
120
+ // implement (Cloudflare Workers) is never sent one.
121
+ const requestInitDefaults = Object.entries(REQUEST_INIT_DEFAULTS).filter(([key]) => isRequestSupported && utils.hasOwnInPrototypeChain(Request.prototype, key));
122
+ // Null prototype: WebIDL reads every RequestInit member with Get, which walks the prototype
123
+ // chain, so a plain object literal would let a polluted Object.prototype.redirect, .integrity,
124
+ // .mode or undici .dispatcher apply to every request. Every own enumerable key of fetchOptions
125
+ // is copied, so runtime extensions (Next.js `next`, Workers `cf`, Bun `tls`) still pass through;
126
+ // inherited keys never do. The caller sets signal, method, headers, body, duplex, credentials.
127
+ const initFromFetchOptions = (fetchOptions, envFetch) => {
128
+ const init = Object.create(null);
129
+ for (const [key, value] of requestInitDefaults)
130
+ init[key] = value;
131
+ // Node's global fetch reads `dispatcher` the same way; pin it to undici's own global one.
132
+ if (!envFetch && utils.hasOwnProp(globalThis, UNDICI_GLOBAL_DISPATCHER)) {
133
+ init["dispatcher"] = globalThis[UNDICI_GLOBAL_DISPATCHER];
134
+ }
135
+ if (utils.isObject(fetchOptions)) {
136
+ for (const key of Object.keys(fetchOptions)) {
137
+ if (!utils.hasOwnProp(FAXIOS_INIT_KEYS, key))
138
+ init[key] = fetchOptions[key];
139
+ }
140
+ }
141
+ return init;
142
+ };
86
143
  const isReadableStreamSupported = isFunction(ReadableStream);
87
144
  const encodeText = typeof TextEncoder === "function"
88
145
  ? ((encoder) => (str) => encoder.encode(str))(new TextEncoder())
@@ -119,26 +176,27 @@ const factory = (env) => {
119
176
  // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
120
177
  return duplexAccessed && !hasContentType;
121
178
  });
179
+ // Outside browsers a FormData body under maxBodyLength is streamed and counted as fetch reads it;
180
+ // browsers can't send a stream body (see buildUploadStream).
181
+ const countsFormDataWhileSent = !isBrowserRuntime && supportsRequestStream;
182
+ // Bodies counted as fetch reads them when maxBodyLength is set.
183
+ const isCountedWhileSent = (body) => utils.isReadableStream(body) || utils.isStream(body) || (countsFormDataWhileSent && utils.isSpecCompliantForm(body));
122
184
  const supportsResponseStream = isResponseSupported &&
123
185
  isReadableStreamSupported &&
124
186
  test(() => utils.isReadableStream(new Response("").body));
125
187
  const resolvers = {
126
188
  stream: supportsResponseStream && ((res) => res.body),
127
189
  };
128
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
129
- isFetchSupported &&
130
- (() => {
131
- ["text", "arrayBuffer", "blob", "formData", "stream"].forEach(type => {
132
- !resolvers[type] &&
133
- (resolvers[type] = (res, config) => {
134
- const method = res[type];
135
- if (method) {
136
- return method.call(res);
137
- }
138
- throw new FaxiosError(`Response type '${type}' is not supported`, FaxiosError.ERR_NOT_SUPPORT, config);
139
- });
190
+ ["text", "arrayBuffer", "blob", "formData", "stream"].forEach(type => {
191
+ !resolvers[type] &&
192
+ (resolvers[type] = (res, config) => {
193
+ const method = res[type];
194
+ if (method) {
195
+ return method.call(res);
196
+ }
197
+ throw new FaxiosError(`Response type '${type}' is not supported`, FaxiosError.ERR_NOT_SUPPORT, config);
140
198
  });
141
- })();
199
+ });
142
200
  const getBodyLength = async (body) => {
143
201
  if (body == null) {
144
202
  return 0;
@@ -146,13 +204,6 @@ const factory = (env) => {
146
204
  if (utils.isBlob(body)) {
147
205
  return body.size;
148
206
  }
149
- if (utils.isSpecCompliantForm(body)) {
150
- const _request = new Request(platform.origin, {
151
- method: "POST",
152
- body,
153
- });
154
- return (await _request.arrayBuffer()).byteLength;
155
- }
156
207
  if (utils.isArrayBufferView(body) || utils.isArrayBuffer(body)) {
157
208
  return body.byteLength;
158
209
  }
@@ -164,6 +215,22 @@ const factory = (env) => {
164
215
  }
165
216
  return undefined;
166
217
  };
218
+ // The bytes of a FormData body's field values and files, from their sizes, without reading the
219
+ // body. A lower bound: the multipart body adds boundaries and part headers. Undefined for any
220
+ // other body.
221
+ const getFormDataFieldsLength = async (body) => {
222
+ if (!utils.isSpecCompliantForm(body)) {
223
+ return undefined;
224
+ }
225
+ let length = 0;
226
+ for (const [, value] of body) {
227
+ // A FormData value is a string or a File.
228
+ const size = utils.isString(value) ? undefined : utils.getSafeProp(value, "size");
229
+ // eslint-disable-next-line no-await-in-loop
230
+ length += typeof size === "number" ? size : (await encodeText(String(value))).byteLength;
231
+ }
232
+ return length;
233
+ };
167
234
  const resolveBodyLength = async (headers, body) => {
168
235
  const length = utils.toFiniteNumber(headers.getContentLength());
169
236
  return length == null ? getBodyLength(body) : length;
@@ -220,10 +287,13 @@ const factory = (env) => {
220
287
  }
221
288
  // Enforce maxBodyLength against known-size bodies before dispatch using
222
289
  // the body's actual size — never a caller-declared Content-Length.
290
+ // A FormData body isn't measured, since that buffers it whole: its values alone over the limit
291
+ // reject it here, and where it's streamed the byte counter covers the multipart framing too.
223
292
  if (hasMaxBodyLength && method !== "get" && method !== "head") {
224
293
  const outboundLength = await getBodyLength(data);
225
- if (typeof outboundLength === "number" && isFinite(outboundLength)) {
226
- if (outboundLength > maxBodyLength) {
294
+ const checkedLength = outboundLength ?? await getFormDataFieldsLength(data);
295
+ if (typeof checkedLength === "number" && isFinite(checkedLength)) {
296
+ if (checkedLength > maxBodyLength) {
227
297
  throw new FaxiosError("Request body larger than maxBodyLength limit", FaxiosError.ERR_BAD_REQUEST, config, request);
228
298
  }
229
299
  return outboundLength;
@@ -248,6 +318,10 @@ const factory = (env) => {
248
318
  };
249
319
  // Set up request body streaming with upload progress and/or maxBodyLength enforcement.
250
320
  const buildUploadStream = async (data, url, method, headers, onUploadProgress, mustEnforceStreamBody, requestContentLength, hasMaxBodyLength, maxBodyLength, config, request, pendingBodyErrorRef) => {
321
+ // Browsers can't be given a stream body for upload progress: Chromium sends one only over
322
+ // HTTP/2 or later and WebKit not at all, so the upload would fail. onUploadProgress isn't
323
+ // called there (#209).
324
+ const uploadProgress = isBrowserRuntime ? undefined : onUploadProgress;
251
325
  const _makeBodyLengthError = () => new FaxiosError("Request body larger than maxBodyLength limit", FaxiosError.ERR_BAD_REQUEST, config, request);
252
326
  const _trackStream = (stream, onProgress, flush) => trackStream(stream, DEFAULT_CHUNK_SIZE, (loadedBytes) => {
253
327
  if (hasMaxBodyLength && loadedBytes > maxBodyLength) {
@@ -255,11 +329,18 @@ const factory = (env) => {
255
329
  throw pendingBodyErrorRef.value;
256
330
  }
257
331
  onProgress && onProgress(loadedBytes);
258
- }, flush);
332
+ }, (err) => {
333
+ // A chunk trackStream rejected (not bytes) surfaces as the coded error, not ERR_NETWORK.
334
+ if (err instanceof FaxiosError && !pendingBodyErrorRef.value) {
335
+ err.config = config;
336
+ pendingBodyErrorRef.value = err;
337
+ }
338
+ flush && flush();
339
+ });
259
340
  if (supportsRequestStream &&
260
341
  method !== "get" &&
261
342
  method !== "head" &&
262
- (onUploadProgress || mustEnforceStreamBody)) {
343
+ (uploadProgress || mustEnforceStreamBody)) {
263
344
  requestContentLength =
264
345
  requestContentLength == null
265
346
  ? await resolveBodyLength(headers, data)
@@ -272,7 +353,7 @@ const factory = (env) => {
272
353
  body: data,
273
354
  duplex: "half",
274
355
  });
275
- data = applyUploadProgress(_request, data, headers, requestContentLength, onUploadProgress, _trackStream);
356
+ data = applyUploadProgress(_request, data, headers, requestContentLength, uploadProgress, _trackStream);
276
357
  }
277
358
  }
278
359
  else if (mustEnforceStreamBody &&
@@ -292,8 +373,8 @@ const factory = (env) => {
292
373
  return { data, requestContentLength };
293
374
  };
294
375
  // Wrap the response body stream with download progress tracking and maxContentLength enforcement.
295
- const buildDownloadStream = (response, responseHeaders, onDownloadProgress, hasMaxContentLength, maxContentLength, isStreamResponse, unsubscribe, config, request) => {
296
- const needsWrapping = onDownloadProgress || hasMaxContentLength || (isStreamResponse && unsubscribe);
376
+ const buildDownloadStream = (response, responseHeaders, onDownloadProgress, hasMaxContentLength, maxContentLength, isStreamResponse, release, config, request) => {
377
+ const needsWrapping = !!onDownloadProgress || hasMaxContentLength || isStreamResponse;
297
378
  if (!supportsResponseStream || !response.body || !needsWrapping) {
298
379
  return response;
299
380
  }
@@ -301,7 +382,13 @@ const factory = (env) => {
301
382
  ["status", "statusText", "headers"].forEach(prop => {
302
383
  options[prop] = response[prop];
303
384
  });
304
- const responseContentLength = utils.toFiniteNumber(responseHeaders.getContentLength());
385
+ // Content-Length is the encoded size; the stream yields decoded bytes, so
386
+ // the total is unknown when the body is content-encoded.
387
+ const contentEncoding = String(responseHeaders.get("content-encoding") ?? "").trim()
388
+ .toLowerCase();
389
+ const responseContentLength = contentEncoding && contentEncoding !== "identity"
390
+ ? undefined
391
+ : utils.toFiniteNumber(responseHeaders.getContentLength());
305
392
  const [onProgress, flush] = onDownloadProgress
306
393
  ? progressEventDecorator(responseContentLength, progressEventReducer(asyncDecorator(onDownloadProgress), true))
307
394
  : [];
@@ -315,14 +402,15 @@ const factory = (env) => {
315
402
  }
316
403
  onProgress && onProgress(loadedBytes);
317
404
  };
318
- return new Response(trackStream(response.body, DEFAULT_CHUNK_SIZE, onChunkProgress, () => {
405
+ return new Response(trackStream(response.body, DEFAULT_CHUNK_SIZE, onChunkProgress, (err) => {
319
406
  flush && flush();
320
- unsubscribe && unsubscribe();
407
+ release(err);
321
408
  }), options);
322
409
  };
323
- const unsubscribeOnComplete = (isStreamResponse, unsubscribe) => {
324
- if (!isStreamResponse)
325
- unsubscribe?.();
410
+ // A stream body releases the request when it ends; a response without a body has nothing to wait for.
411
+ const unsubscribeOnComplete = (isStreamResponse, response, unsubscribe) => {
412
+ if (!isStreamResponse || response.body == null)
413
+ unsubscribe();
326
414
  };
327
415
  return async (config) => {
328
416
  const _resolved = prepareRequest(config);
@@ -334,22 +422,26 @@ const factory = (env) => {
334
422
  const own = (key) => utils.hasOwnProp(config, key)
335
423
  ? config[key]
336
424
  : undefined;
425
+ const envFetch = ownEnv(config, "fetch");
337
426
  const _fetch = (envFetch || globalThis["fetch"]);
338
427
  if (timeout != null && !Number.isFinite(Number(timeout))) {
339
428
  throw new FaxiosError("error trying to parse `config.timeout` to int", FaxiosError.ERR_BAD_OPTION_VALUE, config);
340
429
  }
341
430
  responseType = (responseType ? (responseType + "").toLowerCase() : "text");
342
- const composedSignal = composeSignals([signal], timeout, timeoutErrorMessage);
343
- const unsubscribe = composedSignal?.unsubscribe?.bind(composedSignal);
431
+ // Owns the request's cleanup: aborting it on a failure aborts fetch, which releases the
432
+ // connection and any body still being sent or received.
433
+ const requestController = new AbortController();
434
+ const composedSignal = composeSignals([signal, requestController.signal], timeout, timeoutErrorMessage);
435
+ const unsubscribe = composedSignal.unsubscribe.bind(composedSignal);
344
436
  let request = null;
345
437
  const pendingBodyErrorRef = { value: null };
346
438
  try {
439
+ rejectUsedStreamBody(data, config);
347
440
  url = applyAuthToRequest(url, headers, own);
348
441
  const preflightContentLength = await checkPreflightLimits(url, data, method, hasMaxContentLength, maxContentLength, hasMaxBodyLength, maxBodyLength, config, request);
349
442
  // A streamed body under maxBodyLength must be counted as fetch consumes
350
443
  // it; its size is never trusted from a caller-declared Content-Length.
351
- const isStreamLike = utils.isReadableStream(data) || utils.isStream(data);
352
- const mustEnforceStreamBody = hasMaxBodyLength && isStreamLike;
444
+ const mustEnforceStreamBody = hasMaxBodyLength && isCountedWhileSent(data);
353
445
  ({ data } = await buildUploadStream(data, url, method, headers, onUploadProgress, mustEnforceStreamBody, preflightContentLength, hasMaxBodyLength, maxBodyLength, config, request, pendingBodyErrorRef));
354
446
  withCredentials = normalizeCredentials(withCredentials);
355
447
  // Cloudflare Workers throws when credentials are defined
@@ -364,23 +456,18 @@ const factory = (env) => {
364
456
  // Encoding as Uint8Array prevents the browser from injecting a content-type.
365
457
  // Case-insensitive check: toByteStringHeaderObject may normalize to lowercase.
366
458
  data = toWebStream(await encodeBodyIfNeeded(data, serializedHeaders, encodeText));
367
- const resolvedOptions = {
368
- ...fetchOptions,
369
- signal: composedSignal,
370
- method: method.toUpperCase(),
371
- headers: serializedHeaders,
372
- body: data,
373
- duplex: "half",
374
- credentials: isCredentialsSupported ? withCredentials : undefined,
375
- };
459
+ const resolvedOptions = initFromFetchOptions(fetchOptions, envFetch);
460
+ resolvedOptions["signal"] = composedSignal;
461
+ resolvedOptions["method"] = method.toUpperCase();
462
+ resolvedOptions["headers"] = serializedHeaders;
463
+ resolvedOptions["body"] = data;
464
+ resolvedOptions["duplex"] = "half";
465
+ resolvedOptions["credentials"] = isCredentialsSupported ? withCredentials : undefined;
376
466
  request = isRequestSupported
377
467
  ? new Request(url, resolvedOptions)
378
468
  : null;
379
- // Pass resolvedOptions (all own-properties) as the fetch init even when a
380
- // Request object is supplied: undici re-reads RequestInit fields (method,
381
- // headers, body, credentials) off Object.prototype when init is absent,
382
- // so a polluted Object.prototype.method would override the Request's verb.
383
- // An explicit own-property init neutralizes every such gadget.
469
+ // Pass resolvedOptions as the fetch init even when a Request object is supplied, so the
470
+ // same null-prototype members apply to both calls.
384
471
  let response = await (isRequestSupported
385
472
  ? _fetch(request, resolvedOptions)
386
473
  : _fetch(url, resolvedOptions));
@@ -388,17 +475,26 @@ const factory = (env) => {
388
475
  checkDeclaredContentLength(responseHeaders, hasMaxContentLength, maxContentLength, config, request);
389
476
  const isStreamResponse = supportsResponseStream &&
390
477
  (responseType === "stream" || responseType === "response");
391
- response = buildDownloadStream(response, responseHeaders, onDownloadProgress, hasMaxContentLength, maxContentLength, isStreamResponse, unsubscribe, config, request);
478
+ // A stream body outlives this call, so its end, error or cancel releases the request.
479
+ // A buffered body is released below, or by the catch on failure.
480
+ const releaseStreamBody = (bodyErr) => {
481
+ if (!isStreamResponse)
482
+ return;
483
+ if (bodyErr !== undefined)
484
+ requestController.abort(bodyErr);
485
+ unsubscribe();
486
+ };
487
+ response = buildDownloadStream(response, responseHeaders, onDownloadProgress, hasMaxContentLength, maxContentLength, isStreamResponse, releaseStreamBody, config, request);
392
488
  responseType = responseType || "text";
393
489
  const resolverKey = utils.findKey(resolvers, responseType) || "text";
394
490
  const resolver = resolvers[resolverKey];
395
491
  const responseData = await (resolver && resolver(response, config));
396
492
  checkMaterializedSize(responseData, hasMaxContentLength, maxContentLength, isStreamResponse, supportsResponseStream, config, request);
397
- unsubscribeOnComplete(isStreamResponse, unsubscribe);
493
+ unsubscribeOnComplete(isStreamResponse, response, unsubscribe);
398
494
  return await new Promise((resolve, reject) => {
399
495
  settle(resolve, reject, {
400
496
  data: responseData,
401
- headers: FaxiosHeaders.from(response.headers),
497
+ headers: responseHeaders,
402
498
  status: response.status,
403
499
  statusText: response.statusText,
404
500
  config,
@@ -407,31 +503,53 @@ const factory = (env) => {
407
503
  });
408
504
  }
409
505
  catch (err) {
410
- unsubscribe && unsubscribe();
411
- throw handleFetchCaughtError(err, composedSignal, pendingBodyErrorRef, config, request);
506
+ let error = err;
507
+ try {
508
+ handleFetchCaughtError(err, composedSignal, pendingBodyErrorRef, config, request);
509
+ }
510
+ catch (classified) {
511
+ error = classified;
512
+ }
513
+ // Classify first: the abort below sets the composed signal's reason.
514
+ requestController.abort(error);
515
+ unsubscribe();
516
+ throw error;
412
517
  }
413
518
  };
414
519
  };
415
- const seedCache = new Map();
520
+ // One adapter per Request/Response pair. Weak keys let a per-request `env.Request` or
521
+ // `env.Response` be collected. `undefined` (use the global) and any non-function (disabled)
522
+ // get stand-in keys.
523
+ const GLOBAL_CTOR = {};
524
+ const NO_CTOR = {};
525
+ const adapters = new WeakMap();
526
+ const ctorKey = (ctor) => {
527
+ if (ctor === undefined)
528
+ return GLOBAL_CTOR;
529
+ return isFunction(ctor) ? ctor : NO_CTOR;
530
+ };
531
+ // `false` tells dispatchRequest that this runtime has no fetch.
532
+ // eslint-disable-next-line sonarjs/function-return-type
416
533
  export const getFetch = (config) => {
417
- const env = (config && config.env) || {};
418
- const { fetch, Request, Response } = env;
419
- const seeds = [Request, Response, fetch];
420
- const len = seeds.length;
421
- let i = len;
422
- let seed;
423
- let target;
424
- let map = seedCache;
425
- while (i--) {
426
- seed = seeds[i];
427
- target = map.get(seed);
428
- if (target === undefined) {
429
- target = i ? new Map() : factory(env);
430
- map.set(seed, target);
431
- }
432
- map = target;
534
+ const fetch = ownEnv(config, "fetch");
535
+ if (!isFunction(fetch || globalThis["fetch"])) {
536
+ return false;
537
+ }
538
+ const Request = ownEnv(config, "Request");
539
+ const Response = ownEnv(config, "Response");
540
+ const requestKey = ctorKey(Request);
541
+ const responseKey = ctorKey(Response);
542
+ let byResponse = adapters.get(requestKey);
543
+ if (!byResponse) {
544
+ byResponse = new WeakMap();
545
+ adapters.set(requestKey, byResponse);
546
+ }
547
+ let adapter = byResponse.get(responseKey);
548
+ if (!adapter) {
549
+ adapter = factory({ Request, Response });
550
+ byResponse.set(responseKey, adapter);
433
551
  }
434
- return target;
552
+ return adapter;
435
553
  };
436
554
  getFetch();
437
555
  //# sourceMappingURL=fetch.js.map