@amityco/ts-sdk-react-native 7.22.1-8d7f6ee6.0 → 7.22.1-c05e1197.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.
@@ -13,5 +13,5 @@
13
13
  * @category File API
14
14
  * @async
15
15
  */
16
- export declare const uploadAudio: (formData: FormData, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File<'audio'>[]>>;
16
+ export declare const uploadAudio: (inputFormData: FormData, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File<'audio'>[]>>;
17
17
  //# sourceMappingURL=uploadAudio.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploadAudio.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadAudio.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,aACZ,QAAQ,0BACK,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAmC7C,CAAC"}
1
+ {"version":3,"file":"uploadAudio.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadAudio.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,WAAW,kBACP,QAAQ,0BACA,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAsC7C,CAAC"}
@@ -13,5 +13,5 @@
13
13
  * @category File API
14
14
  * @async
15
15
  */
16
- export declare const uploadClip: (formData: FormData, feedType?: Amity.ContentFeedType, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File<'clip'>[]>>;
16
+ export declare const uploadClip: (inputFormData: FormData, feedType?: Amity.ContentFeedType, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File<'clip'>[]>>;
17
17
  //# sourceMappingURL=uploadClip.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploadClip.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadClip.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,aACX,QAAQ,aACP,MAAM,eAAe,0BACT,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAsC5C,CAAC"}
1
+ {"version":3,"file":"uploadClip.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadClip.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,kBACN,QAAQ,aACZ,MAAM,eAAe,0BACT,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAyC5C,CAAC"}
@@ -13,5 +13,5 @@
13
13
  * @category File API
14
14
  * @async
15
15
  */
16
- export declare const uploadFile: <T extends Amity.FileType = any>(formData: FormData, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File[]>>;
16
+ export declare const uploadFile: <T extends Amity.FileType = any>(inputFormData: FormData, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File[]>>;
17
17
  //# sourceMappingURL=uploadFile.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploadFile.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadFile.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,6CACX,QAAQ,0BACK,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC,CA8BpC,CAAC"}
1
+ {"version":3,"file":"uploadFile.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadFile.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,UAAU,kDACN,QAAQ,0BACA,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC,CAiCpC,CAAC"}
@@ -14,5 +14,5 @@
14
14
  * @category File API
15
15
  * @async
16
16
  */
17
- export declare const uploadImage: (formData: FormData, onProgress?: ((percent: number) => void) | undefined, altText?: string) => Promise<Amity.Cached<Amity.File<'image'>[]>>;
17
+ export declare const uploadImage: (inputFormData: FormData, onProgress?: ((percent: number) => void) | undefined, altText?: string) => Promise<Amity.Cached<Amity.File<'image'>[]>>;
18
18
  //# sourceMappingURL=uploadImage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploadImage.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadImage.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,WAAW,aACZ,QAAQ,0BACK,MAAM,KAAK,IAAI,yBAC5B,MAAM,KACf,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAkD7C,CAAC"}
1
+ {"version":3,"file":"uploadImage.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadImage.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;GAeG;AAEH,eAAO,MAAM,WAAW,kBACP,QAAQ,0BACA,MAAM,KAAK,IAAI,yBAC5B,MAAM,KACf,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAsD7C,CAAC"}
@@ -14,5 +14,5 @@
14
14
  * @category File API
15
15
  * @async
16
16
  */
17
- export declare const uploadVideo: (formData: FormData, feedType?: Amity.ContentFeedType, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File<'video'>[]>>;
17
+ export declare const uploadVideo: (inputFormData: FormData, feedType?: Amity.ContentFeedType, onProgress?: ((percent: number) => void) | undefined) => Promise<Amity.Cached<Amity.File<'video'>[]>>;
18
18
  //# sourceMappingURL=uploadVideo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"uploadVideo.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadVideo.ts"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,aACZ,QAAQ,aACP,MAAM,eAAe,0BACT,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAsC7C,CAAC"}
1
+ {"version":3,"file":"uploadVideo.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/api/uploadVideo.ts"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,WAAW,kBACP,QAAQ,aACZ,MAAM,eAAe,0BACT,MAAM,KAAK,IAAI,kBACrC,QAAQ,MAAM,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAyC7C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"getUploadRequestConfig.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/utils/getUploadRequestConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,sBAAsB,aAAc,QAAQ,KAAG,kBAa3D,CAAC"}
1
+ {"version":3,"file":"getUploadRequestConfig.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/utils/getUploadRequestConfig.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAEhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,eAAO,MAAM,sBAAsB,aAAc,QAAQ,KAAG,kBA0B3D,CAAC"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Rebuilds a multipart `FormData` inside the SDK's own module realm.
3
+ *
4
+ * ## Why this is required (React Native 0.83 New Architecture)
5
+ *
6
+ * When the app/UIKit constructs `new FormData()` from a *different* module realm
7
+ * than the SDK (which happens with `.tgz`/duplicate-`react-native` setups, and
8
+ * is common under the New Architecture), the resulting instance is NOT an
9
+ * `instanceof` the `FormData` that the SDK's axios — and React Native's native
10
+ * `XMLHttpRequest` — reference.
11
+ *
12
+ * As a result `axios.isFormData()` returns `false`, so axios:
13
+ * - serializes the body as a plain object → it goes out as `"[object Object]"`, and
14
+ * - applies its default POST content-type (`application/x-www-form-urlencoded`),
15
+ * which the upload server rejects with
16
+ * `"multipart != application/x-www-form-urlencoded"`.
17
+ *
18
+ * Re-creating the FormData here, with the SDK's own `new FormData()`, produces an
19
+ * instance both axios and RN's XHR recognize, so the file is sent as a real
20
+ * multipart body.
21
+ *
22
+ * We also backfill the file part's MIME `type` (via the file name/URI) because
23
+ * React Native on Android does not set it by default, and the backend rejects
24
+ * file parts without a content type.
25
+ *
26
+ * Only React Native's `FormData` exposes `getParts()`. For Node's `form-data`
27
+ * package or a spec-compliant `FormData`, there is nothing to normalize and the
28
+ * original instance is returned unchanged.
29
+ *
30
+ * @param formData The FormData passed in by the caller.
31
+ * @returns A FormData safe to hand to the upload transport.
32
+ *
33
+ * @category File Util
34
+ * @hidden
35
+ */
36
+ export declare const recreateUploadFormData: (formData: FormData) => FormData;
37
+ //# sourceMappingURL=recreateUploadFormData.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recreateUploadFormData.d.ts","sourceRoot":"","sources":["../../../src/fileRepository/utils/recreateUploadFormData.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,eAAO,MAAM,sBAAsB,aAAc,QAAQ,KAAG,QAoC3D,CAAC"}
package/dist/index.cjs.js CHANGED
@@ -12,6 +12,7 @@ var uuid$1 = require('react-native-uuid');
12
12
  var jwtDecode = require('jwt-decode');
13
13
  var reactNative = require('react-native');
14
14
  var hash = require('object-hash');
15
+ var mime = require('mime');
15
16
  var Hls = require('hls.js');
16
17
 
17
18
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -42,6 +43,7 @@ var AsyncStorage__default = /*#__PURE__*/_interopDefaultLegacy(AsyncStorage);
42
43
  var uuid__default = /*#__PURE__*/_interopDefaultLegacy(uuid$1);
43
44
  var jwtDecode__default = /*#__PURE__*/_interopDefaultLegacy(jwtDecode);
44
45
  var hash__default = /*#__PURE__*/_interopDefaultLegacy(hash);
46
+ var mime__default = /*#__PURE__*/_interopDefaultLegacy(mime);
45
47
  var Hls__default = /*#__PURE__*/_interopDefaultLegacy(Hls);
46
48
 
47
49
  exports.MembershipAcceptanceTypeEnum = void 0;
@@ -16897,15 +16899,94 @@ const getUploadRequestConfig = (formData) => {
16897
16899
  if ('getHeaders' in formData) {
16898
16900
  return { headers: formData.getHeaders() };
16899
16901
  }
16900
- // React Native / browser: let XMLHttpRequest build the multipart body and set
16901
- // `multipart/form-data; boundary=…`. Passing `null` removes any inherited
16902
- // content-type so axios does not force `application/json`.
16902
+ // React Native / browser.
16903
+ //
16904
+ // Set `multipart/form-data` explicitly. We must NOT omit it: when omitted,
16905
+ // axios applies its default POST content-type (`application/x-www-form-urlencoded`)
16906
+ // and the server rejects the upload (`multipart != application/x-www-form-urlencoded`).
16907
+ // React Native's native networking layer appends the real `boundary=…` to this
16908
+ // header when it serializes a (recognized) FormData body.
16909
+ //
16910
+ // `adapter: 'xhr'` pins axios to React Native's XMLHttpRequest (which
16911
+ // understands RN file parts) instead of the `fetch` adapter the New
16912
+ // Architecture also exposes.
16913
+ //
16914
+ // NOTE: this only works if the FormData instance is recognized as multipart.
16915
+ // See `recreateUploadFormData` — the upload APIs rebuild the FormData in the
16916
+ // SDK's own module realm first, otherwise axios/XHR treat it as a plain object
16917
+ // and send `[object Object]`.
16903
16918
  return {
16904
- headers: { 'Content-Type': null },
16919
+ headers: { 'content-type': 'multipart/form-data' },
16905
16920
  adapter: 'xhr',
16906
16921
  };
16907
16922
  };
16908
16923
 
16924
+ /**
16925
+ * Rebuilds a multipart `FormData` inside the SDK's own module realm.
16926
+ *
16927
+ * ## Why this is required (React Native 0.83 New Architecture)
16928
+ *
16929
+ * When the app/UIKit constructs `new FormData()` from a *different* module realm
16930
+ * than the SDK (which happens with `.tgz`/duplicate-`react-native` setups, and
16931
+ * is common under the New Architecture), the resulting instance is NOT an
16932
+ * `instanceof` the `FormData` that the SDK's axios — and React Native's native
16933
+ * `XMLHttpRequest` — reference.
16934
+ *
16935
+ * As a result `axios.isFormData()` returns `false`, so axios:
16936
+ * - serializes the body as a plain object → it goes out as `"[object Object]"`, and
16937
+ * - applies its default POST content-type (`application/x-www-form-urlencoded`),
16938
+ * which the upload server rejects with
16939
+ * `"multipart != application/x-www-form-urlencoded"`.
16940
+ *
16941
+ * Re-creating the FormData here, with the SDK's own `new FormData()`, produces an
16942
+ * instance both axios and RN's XHR recognize, so the file is sent as a real
16943
+ * multipart body.
16944
+ *
16945
+ * We also backfill the file part's MIME `type` (via the file name/URI) because
16946
+ * React Native on Android does not set it by default, and the backend rejects
16947
+ * file parts without a content type.
16948
+ *
16949
+ * Only React Native's `FormData` exposes `getParts()`. For Node's `form-data`
16950
+ * package or a spec-compliant `FormData`, there is nothing to normalize and the
16951
+ * original instance is returned unchanged.
16952
+ *
16953
+ * @param formData The FormData passed in by the caller.
16954
+ * @returns A FormData safe to hand to the upload transport.
16955
+ *
16956
+ * @category File Util
16957
+ * @hidden
16958
+ */
16959
+ const recreateUploadFormData = (formData) => {
16960
+ const source = formData;
16961
+ if (typeof source.getParts !== 'function') {
16962
+ return formData;
16963
+ }
16964
+ const rebuilt = new FormData();
16965
+ source.getParts().forEach(part => {
16966
+ var _a;
16967
+ const { fieldName } = part;
16968
+ // String fields (accessType, preferredFilename, feedType, altText, …).
16969
+ if (typeof part.string === 'string') {
16970
+ rebuilt.append(fieldName, part.string);
16971
+ return;
16972
+ }
16973
+ // File parts are represented as `{ uri, name?, type? }` in React Native.
16974
+ if (part.uri) {
16975
+ const type = part.type ||
16976
+ ((_a = part.headers) === null || _a === void 0 ? void 0 : _a['content-type']) ||
16977
+ (part.name && mime__default["default"].getType(part.name)) ||
16978
+ mime__default["default"].getType(part.uri) ||
16979
+ undefined;
16980
+ rebuilt.append(fieldName, {
16981
+ uri: part.uri,
16982
+ name: part.name,
16983
+ type,
16984
+ });
16985
+ }
16986
+ });
16987
+ return rebuilt;
16988
+ };
16989
+
16909
16990
  /* begin_public_function
16910
16991
  id: file.upload.file
16911
16992
  */
@@ -16924,8 +17005,10 @@ const getUploadRequestConfig = (formData) => {
16924
17005
  * @category File API
16925
17006
  * @async
16926
17007
  */
16927
- const uploadFile = async (formData, onProgress) => {
17008
+ const uploadFile = async (inputFormData, onProgress) => {
16928
17009
  const client = getActiveClient();
17010
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17011
+ const formData = recreateUploadFormData(inputFormData);
16929
17012
  client.log('file/uploadFile', formData);
16930
17013
  const files = formData.getAll('files');
16931
17014
  if (!files.length)
@@ -17005,8 +17088,10 @@ const fileUrlWithSize = (fileUrl, size) => {
17005
17088
  * @category File API
17006
17089
  * @async
17007
17090
  */
17008
- const uploadVideo = async (formData, feedType, onProgress) => {
17091
+ const uploadVideo = async (inputFormData, feedType, onProgress) => {
17009
17092
  const client = getActiveClient();
17093
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17094
+ const formData = recreateUploadFormData(inputFormData);
17010
17095
  client.log('file/uploadVideo', formData);
17011
17096
  const files = formData.getAll('files');
17012
17097
  if (!files.length)
@@ -17051,8 +17136,11 @@ const uploadVideo = async (formData, feedType, onProgress) => {
17051
17136
  * @category File API
17052
17137
  * @async
17053
17138
  */
17054
- const uploadImage = async (formData, onProgress, altText) => {
17139
+ const uploadImage = async (inputFormData, onProgress, altText) => {
17055
17140
  const client = getActiveClient();
17141
+ // Rebuild the FormData in the SDK's realm so axios/XHR serialize it as real
17142
+ // multipart (otherwise it is sent as "[object Object]"). See helper for details.
17143
+ const formData = recreateUploadFormData(inputFormData);
17056
17144
  client.log('file/uploadImage', formData);
17057
17145
  const files = formData.getAll('files');
17058
17146
  if (files === null || files === void 0 ? void 0 : files.length) {
@@ -17136,8 +17224,10 @@ const updateAltText = async (fileId, altText) => {
17136
17224
  * @category File API
17137
17225
  * @async
17138
17226
  */
17139
- const uploadClip = async (formData, feedType, onProgress) => {
17227
+ const uploadClip = async (inputFormData, feedType, onProgress) => {
17140
17228
  const client = getActiveClient();
17229
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17230
+ const formData = recreateUploadFormData(inputFormData);
17141
17231
  client.log('file/uploadClip', formData);
17142
17232
  const file = formData.get('files');
17143
17233
  if (!file)
@@ -17181,8 +17271,10 @@ const uploadClip = async (formData, feedType, onProgress) => {
17181
17271
  * @category File API
17182
17272
  * @async
17183
17273
  */
17184
- const uploadAudio = async (formData, onProgress) => {
17274
+ const uploadAudio = async (inputFormData, onProgress) => {
17185
17275
  const client = getActiveClient();
17276
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
17277
+ const formData = recreateUploadFormData(inputFormData);
17186
17278
  client.log('file/uploadAudio', formData);
17187
17279
  const files = formData.getAll('file');
17188
17280
  if (files.length === 0)
package/dist/index.esm.js CHANGED
@@ -8,6 +8,7 @@ import uuid$1 from 'react-native-uuid';
8
8
  import jwtDecode from 'jwt-decode';
9
9
  import { Platform } from 'react-native';
10
10
  import hash from 'object-hash';
11
+ import mime from 'mime';
11
12
  import Hls from 'hls.js';
12
13
 
13
14
  var MembershipAcceptanceTypeEnum;
@@ -32970,15 +32971,94 @@ const getUploadRequestConfig = (formData) => {
32970
32971
  if ('getHeaders' in formData) {
32971
32972
  return { headers: formData.getHeaders() };
32972
32973
  }
32973
- // React Native / browser: let XMLHttpRequest build the multipart body and set
32974
- // `multipart/form-data; boundary=…`. Passing `null` removes any inherited
32975
- // content-type so axios does not force `application/json`.
32974
+ // React Native / browser.
32975
+ //
32976
+ // Set `multipart/form-data` explicitly. We must NOT omit it: when omitted,
32977
+ // axios applies its default POST content-type (`application/x-www-form-urlencoded`)
32978
+ // and the server rejects the upload (`multipart != application/x-www-form-urlencoded`).
32979
+ // React Native's native networking layer appends the real `boundary=…` to this
32980
+ // header when it serializes a (recognized) FormData body.
32981
+ //
32982
+ // `adapter: 'xhr'` pins axios to React Native's XMLHttpRequest (which
32983
+ // understands RN file parts) instead of the `fetch` adapter the New
32984
+ // Architecture also exposes.
32985
+ //
32986
+ // NOTE: this only works if the FormData instance is recognized as multipart.
32987
+ // See `recreateUploadFormData` — the upload APIs rebuild the FormData in the
32988
+ // SDK's own module realm first, otherwise axios/XHR treat it as a plain object
32989
+ // and send `[object Object]`.
32976
32990
  return {
32977
- headers: { 'Content-Type': null },
32991
+ headers: { 'content-type': 'multipart/form-data' },
32978
32992
  adapter: 'xhr',
32979
32993
  };
32980
32994
  };
32981
32995
 
32996
+ /**
32997
+ * Rebuilds a multipart `FormData` inside the SDK's own module realm.
32998
+ *
32999
+ * ## Why this is required (React Native 0.83 New Architecture)
33000
+ *
33001
+ * When the app/UIKit constructs `new FormData()` from a *different* module realm
33002
+ * than the SDK (which happens with `.tgz`/duplicate-`react-native` setups, and
33003
+ * is common under the New Architecture), the resulting instance is NOT an
33004
+ * `instanceof` the `FormData` that the SDK's axios — and React Native's native
33005
+ * `XMLHttpRequest` — reference.
33006
+ *
33007
+ * As a result `axios.isFormData()` returns `false`, so axios:
33008
+ * - serializes the body as a plain object → it goes out as `"[object Object]"`, and
33009
+ * - applies its default POST content-type (`application/x-www-form-urlencoded`),
33010
+ * which the upload server rejects with
33011
+ * `"multipart != application/x-www-form-urlencoded"`.
33012
+ *
33013
+ * Re-creating the FormData here, with the SDK's own `new FormData()`, produces an
33014
+ * instance both axios and RN's XHR recognize, so the file is sent as a real
33015
+ * multipart body.
33016
+ *
33017
+ * We also backfill the file part's MIME `type` (via the file name/URI) because
33018
+ * React Native on Android does not set it by default, and the backend rejects
33019
+ * file parts without a content type.
33020
+ *
33021
+ * Only React Native's `FormData` exposes `getParts()`. For Node's `form-data`
33022
+ * package or a spec-compliant `FormData`, there is nothing to normalize and the
33023
+ * original instance is returned unchanged.
33024
+ *
33025
+ * @param formData The FormData passed in by the caller.
33026
+ * @returns A FormData safe to hand to the upload transport.
33027
+ *
33028
+ * @category File Util
33029
+ * @hidden
33030
+ */
33031
+ const recreateUploadFormData = (formData) => {
33032
+ const source = formData;
33033
+ if (typeof source.getParts !== 'function') {
33034
+ return formData;
33035
+ }
33036
+ const rebuilt = new FormData();
33037
+ source.getParts().forEach(part => {
33038
+ var _a;
33039
+ const { fieldName } = part;
33040
+ // String fields (accessType, preferredFilename, feedType, altText, …).
33041
+ if (typeof part.string === 'string') {
33042
+ rebuilt.append(fieldName, part.string);
33043
+ return;
33044
+ }
33045
+ // File parts are represented as `{ uri, name?, type? }` in React Native.
33046
+ if (part.uri) {
33047
+ const type = part.type ||
33048
+ ((_a = part.headers) === null || _a === void 0 ? void 0 : _a['content-type']) ||
33049
+ (part.name && mime.getType(part.name)) ||
33050
+ mime.getType(part.uri) ||
33051
+ undefined;
33052
+ rebuilt.append(fieldName, {
33053
+ uri: part.uri,
33054
+ name: part.name,
33055
+ type,
33056
+ });
33057
+ }
33058
+ });
33059
+ return rebuilt;
33060
+ };
33061
+
32982
33062
  /* begin_public_function
32983
33063
  id: file.upload.file
32984
33064
  */
@@ -32997,8 +33077,10 @@ const getUploadRequestConfig = (formData) => {
32997
33077
  * @category File API
32998
33078
  * @async
32999
33079
  */
33000
- const uploadFile = async (formData, onProgress) => {
33080
+ const uploadFile = async (inputFormData, onProgress) => {
33001
33081
  const client = getActiveClient();
33082
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
33083
+ const formData = recreateUploadFormData(inputFormData);
33002
33084
  client.log('file/uploadFile', formData);
33003
33085
  const files = formData.getAll('files');
33004
33086
  if (!files.length)
@@ -33078,8 +33160,10 @@ const fileUrlWithSize = (fileUrl, size) => {
33078
33160
  * @category File API
33079
33161
  * @async
33080
33162
  */
33081
- const uploadVideo = async (formData, feedType, onProgress) => {
33163
+ const uploadVideo = async (inputFormData, feedType, onProgress) => {
33082
33164
  const client = getActiveClient();
33165
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
33166
+ const formData = recreateUploadFormData(inputFormData);
33083
33167
  client.log('file/uploadVideo', formData);
33084
33168
  const files = formData.getAll('files');
33085
33169
  if (!files.length)
@@ -33124,8 +33208,11 @@ const uploadVideo = async (formData, feedType, onProgress) => {
33124
33208
  * @category File API
33125
33209
  * @async
33126
33210
  */
33127
- const uploadImage = async (formData, onProgress, altText) => {
33211
+ const uploadImage = async (inputFormData, onProgress, altText) => {
33128
33212
  const client = getActiveClient();
33213
+ // Rebuild the FormData in the SDK's realm so axios/XHR serialize it as real
33214
+ // multipart (otherwise it is sent as "[object Object]"). See helper for details.
33215
+ const formData = recreateUploadFormData(inputFormData);
33129
33216
  client.log('file/uploadImage', formData);
33130
33217
  const files = formData.getAll('files');
33131
33218
  if (files === null || files === void 0 ? void 0 : files.length) {
@@ -33209,8 +33296,10 @@ const updateAltText = async (fileId, altText) => {
33209
33296
  * @category File API
33210
33297
  * @async
33211
33298
  */
33212
- const uploadClip = async (formData, feedType, onProgress) => {
33299
+ const uploadClip = async (inputFormData, feedType, onProgress) => {
33213
33300
  const client = getActiveClient();
33301
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
33302
+ const formData = recreateUploadFormData(inputFormData);
33214
33303
  client.log('file/uploadClip', formData);
33215
33304
  const file = formData.get('files');
33216
33305
  if (!file)
@@ -33254,8 +33343,10 @@ const uploadClip = async (formData, feedType, onProgress) => {
33254
33343
  * @category File API
33255
33344
  * @async
33256
33345
  */
33257
- const uploadAudio = async (formData, onProgress) => {
33346
+ const uploadAudio = async (inputFormData, onProgress) => {
33258
33347
  const client = getActiveClient();
33348
+ // Rebuild in the SDK's realm so axios/XHR serialize it as real multipart.
33349
+ const formData = recreateUploadFormData(inputFormData);
33259
33350
  client.log('file/uploadAudio', formData);
33260
33351
  const files = formData.getAll('file');
33261
33352
  if (files.length === 0)