expo-document-picker 9.2.3 → 10.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -10,19 +10,32 @@
10
10
 
11
11
  ### 💡 Others
12
12
 
13
- ## 9.2.3 — 2021-06-24
13
+ ## 10.0.2 — 2021-10-15
14
14
 
15
15
  _This version does not introduce any user-facing changes._
16
16
 
17
- ## 9.2.2 — 2021-06-24
17
+ ## 10.0.1 — 2021-10-01
18
+
19
+ _This version does not introduce any user-facing changes._
20
+
21
+ ## 10.0.0 — 2021-09-28
22
+
23
+ ### 🛠 Breaking changes
24
+
25
+ - Dropped support for iOS 11.0 ([#14383](https://github.com/expo/expo/pull/14383) by [@cruzach](https://github.com/cruzach))
18
26
 
19
27
  ### 🐛 Bug fixes
20
28
 
21
29
  - Added `AndroidManifest.xml` queries for intent handling. ([#13388](https://github.com/expo/expo/pull/13388) by [@EvanBacon](https://github.com/EvanBacon))
30
+ - Added possibility to pass mimetypes array in order to set multiple mimetypes, fix bug with default mimetype. ([#13751](https://github.com/expo/expo/pull/13751) by [@mstach60161](https://github.com/mstach60161))
31
+ - Added mimetype to getDocumentAsync result. ([#13702](https://github.com/expo/expo/pull/13702) by [@mstach60161](https://github.com/mstach60161))
32
+ - Fixed file uri. ([#13678](https://github.com/expo/expo/pull/13678) by [@mstach60161](https://github.com/mstach60161))
33
+ - Fix building errors from use_frameworks! in Podfile. ([#14523](https://github.com/expo/expo/pull/14523) by [@kudo](https://github.com/kudo))
22
34
 
23
- ## 9.2.1 — 2021-06-22
35
+ ### 💡 Others
24
36
 
25
- _This version does not introduce any user-facing changes._
37
+ - Migrated from `@unimodules/core` to `expo-modules-core`. ([#13757](https://github.com/expo/expo/pull/13757) by [@tsapeta](https://github.com/tsapeta))
38
+ - Updated `@expo/config-plugins` ([#14443](https://github.com/expo/expo/pull/14443) by [@EvanBacon](https://github.com/EvanBacon))
26
39
 
27
40
  ## 9.2.0 — 2021-06-16
28
41
 
@@ -3,7 +3,7 @@ apply plugin: 'kotlin-android'
3
3
  apply plugin: 'maven'
4
4
 
5
5
  group = 'host.exp.exponent'
6
- version = '9.2.3'
6
+ version = '10.0.2'
7
7
 
8
8
  buildscript {
9
9
  // Simple helper that allows the root project to override versions declared by this library.
@@ -53,27 +53,23 @@ android {
53
53
  targetCompatibility JavaVersion.VERSION_1_8
54
54
  }
55
55
 
56
+ kotlinOptions {
57
+ jvmTarget = JavaVersion.VERSION_1_8
58
+ }
59
+
56
60
  defaultConfig {
57
61
  minSdkVersion safeExtGet("minSdkVersion", 21)
58
62
  targetSdkVersion safeExtGet("targetSdkVersion", 30)
59
63
  versionCode 17
60
- versionName '9.2.3'
64
+ versionName '10.0.2'
61
65
  }
62
66
  lintOptions {
63
67
  abortOnError false
64
68
  }
65
69
  }
66
70
 
67
- if (new File(rootProject.projectDir.parentFile, 'package.json').exists()) {
68
- apply from: project(':unimodules-core').file('../unimodules-core.gradle')
69
- } else {
70
- throw new GradleException(
71
- '\'unimodules-core.gradle\' was not found in the usual React Native dependency location. ' +
72
- 'This package can only be used in such projects. Are you sure you\'ve installed the dependencies properly?')
73
- }
74
-
75
71
  dependencies {
76
- unimodule 'unimodules-core'
72
+ implementation project(':expo-modules-core')
77
73
 
78
74
  api "androidx.annotation:annotation:1.0.0"
79
75
  api 'commons-io:commons-io:2.6'
@@ -1,4 +1,4 @@
1
- <manifest package="expo.modules.documentpicker">
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="expo.modules.documentpicker">
2
2
 
3
3
  <queries>
4
4
  <!-- Query open documents -->
@@ -4,7 +4,7 @@ import android.content.Context
4
4
  import android.net.Uri
5
5
  import android.provider.OpenableColumns
6
6
 
7
- data class DocumentDetails(val name: String, val uri: String, val size: Int?)
7
+ data class DocumentDetails(val name: String, val uri: String, val size: Int?, val mimeType: String?)
8
8
 
9
9
  class DocumentDetailsReader(private val context: Context) {
10
10
  fun read(uri: Uri): DocumentDetails? {
@@ -22,7 +22,8 @@ class DocumentDetailsReader(private val context: Context) {
22
22
  null
23
23
  }
24
24
  }
25
- return DocumentDetails(name, uriString, size)
25
+ val mimeType = context.contentResolver.getType(uri)
26
+ return DocumentDetails(name, uriString, size, mimeType)
26
27
  }
27
28
  return null
28
29
  }
@@ -7,15 +7,15 @@ import android.net.Uri
7
7
  import android.os.Bundle
8
8
  import org.apache.commons.io.FilenameUtils
9
9
  import org.apache.commons.io.IOUtils
10
- import org.unimodules.core.ExportedModule
11
- import org.unimodules.core.ModuleRegistry
12
- import org.unimodules.core.ModuleRegistryDelegate
13
- import org.unimodules.core.Promise
14
- import org.unimodules.core.interfaces.ActivityEventListener
15
- import org.unimodules.core.interfaces.ActivityProvider
16
- import org.unimodules.core.interfaces.ExpoMethod
17
- import org.unimodules.core.interfaces.services.UIManager
18
- import org.unimodules.core.utilities.FileUtilities
10
+ import expo.modules.core.ExportedModule
11
+ import expo.modules.core.ModuleRegistry
12
+ import expo.modules.core.ModuleRegistryDelegate
13
+ import expo.modules.core.Promise
14
+ import expo.modules.core.interfaces.ActivityEventListener
15
+ import expo.modules.core.interfaces.ActivityProvider
16
+ import expo.modules.core.interfaces.ExpoMethod
17
+ import expo.modules.core.interfaces.services.UIManager
18
+ import expo.modules.core.utilities.FileUtilities
19
19
  import java.io.File
20
20
  import java.io.FileOutputStream
21
21
  import java.io.IOException
@@ -25,7 +25,7 @@ private const val OPEN_DOCUMENT_CODE = 4137
25
25
 
26
26
  class DocumentPickerModule(
27
27
  mContext: Context,
28
- private val moduleRegistryDelegate: ModuleRegistryDelegate = ModuleRegistryDelegate(),
28
+ private val moduleRegistryDelegate: ModuleRegistryDelegate = ModuleRegistryDelegate()
29
29
  ) : ExportedModule(mContext), ActivityEventListener {
30
30
  private var mPromise: Promise? = null
31
31
  private var mCopyToCacheDirectory = true
@@ -48,17 +48,18 @@ class DocumentPickerModule(
48
48
  promise.reject("E_DOCUMENT_PICKER", "Different document picking in progress. Await other document picking first.")
49
49
  return
50
50
  }
51
-
52
51
  val pickerOptions = DocumentPickerOptions.optionsFromMap(options, promise) ?: return
53
-
54
52
  mPromise = promise
55
53
  mCopyToCacheDirectory = pickerOptions.copyToCacheDirectory
56
-
57
54
  val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
58
55
  addCategory(Intent.CATEGORY_OPENABLE)
59
- type = pickerOptions.type
56
+ type = if (pickerOptions.types.size > 1) {
57
+ putExtra(Intent.EXTRA_MIME_TYPES, pickerOptions.types)
58
+ "*/*"
59
+ } else {
60
+ pickerOptions.types[0]
61
+ }
60
62
  }
61
-
62
63
  mActivityProvider.currentActivity.startActivityForResult(intent, OPEN_DOCUMENT_CODE)
63
64
  }
64
65
 
@@ -88,7 +89,6 @@ class DocumentPickerModule(
88
89
  }
89
90
  }
90
91
  }
91
-
92
92
  if (documentDetails == null) {
93
93
  promise.reject("E_DOCUMENT_PICKER", "Failed to read the selected document.")
94
94
  } else {
@@ -96,9 +96,10 @@ class DocumentPickerModule(
96
96
  putString("type", "success")
97
97
  putString("uri", documentDetails.uri)
98
98
  putString("name", documentDetails.name)
99
- if (documentDetails.size == null) {
100
- putParcelable("size", null)
101
- } else {
99
+ documentDetails.mimeType?.let {
100
+ putString("mimeType", documentDetails.mimeType)
101
+ }
102
+ documentDetails.size?.let {
102
103
  putInt("size", documentDetails.size)
103
104
  }
104
105
  }
@@ -120,10 +121,10 @@ class DocumentPickerModule(
120
121
  "DocumentPicker",
121
122
  FilenameUtils.getExtension(name)
122
123
  )
123
-
124
+ val outputFile = File(outputFilePath)
124
125
  try {
125
126
  context.contentResolver.openInputStream(documentUri).use { inputStream ->
126
- FileOutputStream(File(outputFilePath)).use { outputStream ->
127
+ FileOutputStream(outputFile).use { outputStream ->
127
128
  IOUtils.copy(inputStream, outputStream)
128
129
  }
129
130
  }
@@ -131,7 +132,6 @@ class DocumentPickerModule(
131
132
  e.printStackTrace()
132
133
  return null
133
134
  }
134
-
135
- return outputFilePath
135
+ return Uri.fromFile(outputFile).toString()
136
136
  }
137
137
  }
@@ -1,19 +1,25 @@
1
1
  package expo.modules.documentpicker
2
2
 
3
- import org.unimodules.core.Promise
3
+ import expo.modules.core.Promise
4
4
 
5
- data class DocumentPickerOptions(val type: String, val copyToCacheDirectory: Boolean) {
5
+ data class DocumentPickerOptions(val copyToCacheDirectory: Boolean, val types: Array<String>) {
6
6
  companion object {
7
7
  fun optionsFromMap(options: Map<String, Any?>, promise: Promise): DocumentPickerOptions? {
8
- val type = options["type"]?.let {
9
- if (it is String) {
10
- return@let it
11
- }
12
-
13
- promise.reject("ERR_INVALID_OPTION", "type must be a string")
8
+ if (options.containsKey("type") && options["type"] == null) {
9
+ promise.reject("ERR_INVALID_OPTION", "type must be a list of strings")
14
10
  return null
15
- } ?: "*/*"
16
-
11
+ }
12
+ var mimeTypes = arrayListOf("*/*")
13
+ options["type"]?.let {
14
+ val types = it as ArrayList<*>
15
+ if (types.isEmpty() || types[0] !is String) {
16
+ promise.reject("ERR_INVALID_OPTION", "type must be a list of strings")
17
+ return null
18
+ } else {
19
+ @Suppress("UNCHECKED_CAST")
20
+ mimeTypes = types as ArrayList<String>
21
+ }
22
+ }
17
23
  val copyToCacheDirectory = options["copyToCacheDirectory"]?.let {
18
24
  if (it is Boolean) {
19
25
  return@let it
@@ -21,8 +27,25 @@ data class DocumentPickerOptions(val type: String, val copyToCacheDirectory: Boo
21
27
  promise.reject("ERR_INVALID_OPTION", "copyToCacheDirectory must be a boolean")
22
28
  return null
23
29
  } ?: true
24
-
25
- return DocumentPickerOptions(type, copyToCacheDirectory)
30
+ return DocumentPickerOptions(copyToCacheDirectory, mimeTypes.toTypedArray())
26
31
  }
27
32
  }
33
+
34
+ override fun equals(other: Any?): Boolean {
35
+ if (this === other) return true
36
+ if (javaClass != other?.javaClass) return false
37
+
38
+ other as DocumentPickerOptions
39
+
40
+ if (copyToCacheDirectory != other.copyToCacheDirectory) return false
41
+ if (!types.contentEquals(other.types)) return false
42
+
43
+ return true
44
+ }
45
+
46
+ override fun hashCode(): Int {
47
+ var result = copyToCacheDirectory.hashCode()
48
+ result = 31 * result + types.contentHashCode()
49
+ return result
50
+ }
28
51
  }
@@ -1,7 +1,7 @@
1
1
  package expo.modules.documentpicker
2
2
 
3
3
  import android.content.Context
4
- import org.unimodules.core.BasePackage
4
+ import expo.modules.core.BasePackage
5
5
 
6
6
  class DocumentPickerPackage : BasePackage() {
7
7
  override fun createExportedModules(context: Context) = listOf(DocumentPickerModule(context))
@@ -1,2 +1,2 @@
1
- declare const _default: import("@unimodules/core").ProxyNativeModule;
1
+ declare const _default: import("expo-modules-core").ProxyNativeModule;
2
2
  export default _default;
@@ -1,3 +1,3 @@
1
- import { NativeModulesProxy } from '@unimodules/core';
1
+ import { NativeModulesProxy } from 'expo-modules-core';
2
2
  export default NativeModulesProxy.ExpoDocumentPicker;
3
3
  //# sourceMappingURL=ExpoDocumentPicker.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoDocumentPicker.js","sourceRoot":"","sources":["../src/ExpoDocumentPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAEtD,eAAe,kBAAkB,CAAC,kBAAkB,CAAC","sourcesContent":["import { NativeModulesProxy } from '@unimodules/core';\n\nexport default NativeModulesProxy.ExpoDocumentPicker;\n"]}
1
+ {"version":3,"file":"ExpoDocumentPicker.js","sourceRoot":"","sources":["../src/ExpoDocumentPicker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,eAAe,kBAAkB,CAAC,kBAAkB,CAAC","sourcesContent":["import { NativeModulesProxy } from 'expo-modules-core';\n\nexport default NativeModulesProxy.ExpoDocumentPicker;\n"]}
@@ -1,4 +1,4 @@
1
- import { Platform } from '@unimodules/core';
1
+ import { Platform } from 'expo-modules-core';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
3
  export default {
4
4
  get name() {
@@ -12,7 +12,7 @@ export default {
12
12
  const input = document.createElement('input');
13
13
  input.style.display = 'none';
14
14
  input.setAttribute('type', 'file');
15
- input.setAttribute('accept', type);
15
+ input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type);
16
16
  input.setAttribute('id', uuidv4());
17
17
  if (multiple) {
18
18
  input.setAttribute('multiple', 'multiple');
@@ -22,6 +22,7 @@ export default {
22
22
  input.addEventListener('change', () => {
23
23
  if (input.files) {
24
24
  const targetFile = input.files[0];
25
+ const mimeType = targetFile.type;
25
26
  const reader = new FileReader();
26
27
  reader.onerror = () => {
27
28
  reject(new Error(`Failed to read the selected media because the operation failed.`));
@@ -31,6 +32,7 @@ export default {
31
32
  resolve({
32
33
  type: 'success',
33
34
  uri,
35
+ mimeType,
34
36
  name: targetFile.name,
35
37
  file: targetFile,
36
38
  lastModified: targetFile.lastModified,
@@ -1 +1 @@
1
- {"version":3,"file":"ExpoDocumentPicker.web.js","sourceRoot":"","sources":["../src/ExpoDocumentPicker.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAIpC,eAAe;IACb,IAAI,IAAI;QACN,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,EACrB,IAAI,GAAG,KAAK,EACZ,QAAQ,GAAG,KAAK,GACM;QACtB,YAAY;QACZ,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;YAC5B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;SAC3B;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC7B,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACnC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACnC,IAAI,QAAQ,EAAE;YACZ,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;SAC5C;QAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACpC,IAAI,KAAK,CAAC,KAAK,EAAE;oBACf,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAClC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;oBAChC,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;wBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC,CAAC;oBACvF,CAAC,CAAC;oBACF,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;wBAC7B,MAAM,GAAG,GAAI,MAAc,CAAC,MAAM,CAAC;wBACnC,OAAO,CAAC;4BACN,IAAI,EAAE,SAAS;4BACf,GAAG;4BACH,IAAI,EAAE,UAAU,CAAC,IAAI;4BACrB,IAAI,EAAE,UAAU;4BAChB,YAAY,EAAE,UAAU,CAAC,YAAY;4BACrC,IAAI,EAAE,UAAU,CAAC,IAAI;4BACrB,MAAM,EAAE,KAAK,CAAC,KAAK;yBACpB,CAAC,CAAC;oBACL,CAAC,CAAC;oBACF,6CAA6C;oBAC7C,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;iBAClC;qBAAM;oBACL,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;iBAC7B;gBAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;YACtC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC","sourcesContent":["import { Platform } from '@unimodules/core';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { DocumentPickerOptions, DocumentResult } from './types';\n\nexport default {\n get name(): string {\n return 'ExpoDocumentPicker';\n },\n\n async getDocumentAsync({\n type = '*/*',\n multiple = false,\n }: DocumentPickerOptions): Promise<DocumentResult> {\n // SSR guard\n if (!Platform.isDOMAvailable) {\n return { type: 'cancel' };\n }\n\n const input = document.createElement('input');\n input.style.display = 'none';\n input.setAttribute('type', 'file');\n input.setAttribute('accept', type);\n input.setAttribute('id', uuidv4());\n if (multiple) {\n input.setAttribute('multiple', 'multiple');\n }\n\n document.body.appendChild(input);\n\n return new Promise((resolve, reject) => {\n input.addEventListener('change', () => {\n if (input.files) {\n const targetFile = input.files[0];\n const reader = new FileReader();\n reader.onerror = () => {\n reject(new Error(`Failed to read the selected media because the operation failed.`));\n };\n reader.onload = ({ target }) => {\n const uri = (target as any).result;\n resolve({\n type: 'success',\n uri,\n name: targetFile.name,\n file: targetFile,\n lastModified: targetFile.lastModified,\n size: targetFile.size,\n output: input.files,\n });\n };\n // Read in the image file as a binary string.\n reader.readAsDataURL(targetFile);\n } else {\n resolve({ type: 'cancel' });\n }\n\n document.body.removeChild(input);\n });\n\n const event = new MouseEvent('click');\n input.dispatchEvent(event);\n });\n },\n};\n"]}
1
+ {"version":3,"file":"ExpoDocumentPicker.web.js","sourceRoot":"","sources":["../src/ExpoDocumentPicker.web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,EAAE,IAAI,MAAM,EAAE,MAAM,MAAM,CAAC;AAIpC,eAAe;IACb,IAAI,IAAI;QACN,OAAO,oBAAoB,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,gBAAgB,CAAC,EACrB,IAAI,GAAG,KAAK,EACZ,QAAQ,GAAG,KAAK,GACM;QACtB,YAAY;QACZ,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE;YAC5B,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;SAC3B;QAED,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QAC9C,KAAK,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAC7B,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QACnC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAC1E,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;QACnC,IAAI,QAAQ,EAAE;YACZ,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;SAC5C;QAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;QAEjC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,GAAG,EAAE;gBACpC,IAAI,KAAK,CAAC,KAAK,EAAE;oBACf,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;oBAClC,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC;oBACjC,MAAM,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;oBAChC,MAAM,CAAC,OAAO,GAAG,GAAG,EAAE;wBACpB,MAAM,CAAC,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC,CAAC;oBACvF,CAAC,CAAC;oBACF,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE;wBAC7B,MAAM,GAAG,GAAI,MAAc,CAAC,MAAM,CAAC;wBACnC,OAAO,CAAC;4BACN,IAAI,EAAE,SAAS;4BACf,GAAG;4BACH,QAAQ;4BACR,IAAI,EAAE,UAAU,CAAC,IAAI;4BACrB,IAAI,EAAE,UAAU;4BAChB,YAAY,EAAE,UAAU,CAAC,YAAY;4BACrC,IAAI,EAAE,UAAU,CAAC,IAAI;4BACrB,MAAM,EAAE,KAAK,CAAC,KAAK;yBACpB,CAAC,CAAC;oBACL,CAAC,CAAC;oBACF,6CAA6C;oBAC7C,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;iBAClC;qBAAM;oBACL,OAAO,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC;iBAC7B;gBAED,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;YACtC,KAAK,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAC7B,CAAC,CAAC,CAAC;IACL,CAAC;CACF,CAAC","sourcesContent":["import { Platform } from 'expo-modules-core';\nimport { v4 as uuidv4 } from 'uuid';\n\nimport { DocumentPickerOptions, DocumentResult } from './types';\n\nexport default {\n get name(): string {\n return 'ExpoDocumentPicker';\n },\n\n async getDocumentAsync({\n type = '*/*',\n multiple = false,\n }: DocumentPickerOptions): Promise<DocumentResult> {\n // SSR guard\n if (!Platform.isDOMAvailable) {\n return { type: 'cancel' };\n }\n\n const input = document.createElement('input');\n input.style.display = 'none';\n input.setAttribute('type', 'file');\n input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type);\n input.setAttribute('id', uuidv4());\n if (multiple) {\n input.setAttribute('multiple', 'multiple');\n }\n\n document.body.appendChild(input);\n\n return new Promise((resolve, reject) => {\n input.addEventListener('change', () => {\n if (input.files) {\n const targetFile = input.files[0];\n const mimeType = targetFile.type;\n const reader = new FileReader();\n reader.onerror = () => {\n reject(new Error(`Failed to read the selected media because the operation failed.`));\n };\n reader.onload = ({ target }) => {\n const uri = (target as any).result;\n resolve({\n type: 'success',\n uri,\n mimeType,\n name: targetFile.name,\n file: targetFile,\n lastModified: targetFile.lastModified,\n size: targetFile.size,\n output: input.files,\n });\n };\n // Read in the image file as a binary string.\n reader.readAsDataURL(targetFile);\n } else {\n resolve({ type: 'cancel' });\n }\n\n document.body.removeChild(input);\n });\n\n const event = new MouseEvent('click');\n input.dispatchEvent(event);\n });\n },\n};\n"]}
package/build/index.d.ts CHANGED
@@ -1,3 +1,14 @@
1
1
  import { DocumentPickerOptions, DocumentResult } from './types';
2
2
  export { DocumentPickerOptions, DocumentResult };
3
+ /**
4
+ * Display the system UI for choosing a document. By default, the chosen file is copied to [the app's internal cache directory](filesystem.md#filesystemcachedirectory).
5
+ * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).
6
+ * Therefore, calling `getDocumentAsync` in `componentDidMount`, for example, will **not** work as
7
+ * intended. The `cancel` event will not be returned in the browser due to platform restrictions and
8
+ * inconsistencies across browsers.
9
+ *
10
+ * @return On success returns a promise that fulfils with [`DocumentResult`](#documentresult) object.
11
+ *
12
+ * If the user cancelled the document picking, the promise resolves to `{ type: 'cancel' }`.
13
+ */
3
14
  export declare function getDocumentAsync({ type, copyToCacheDirectory, multiple, }?: DocumentPickerOptions): Promise<DocumentResult>;
package/build/index.js CHANGED
@@ -1,5 +1,20 @@
1
1
  import ExpoDocumentPicker from './ExpoDocumentPicker';
2
+ // @needsAudit
3
+ /**
4
+ * Display the system UI for choosing a document. By default, the chosen file is copied to [the app's internal cache directory](filesystem.md#filesystemcachedirectory).
5
+ * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).
6
+ * Therefore, calling `getDocumentAsync` in `componentDidMount`, for example, will **not** work as
7
+ * intended. The `cancel` event will not be returned in the browser due to platform restrictions and
8
+ * inconsistencies across browsers.
9
+ *
10
+ * @return On success returns a promise that fulfils with [`DocumentResult`](#documentresult) object.
11
+ *
12
+ * If the user cancelled the document picking, the promise resolves to `{ type: 'cancel' }`.
13
+ */
2
14
  export async function getDocumentAsync({ type = '*/*', copyToCacheDirectory = true, multiple = false, } = {}) {
15
+ if (typeof type === 'string') {
16
+ type = [type];
17
+ }
3
18
  return await ExpoDocumentPicker.getDocumentAsync({ type, copyToCacheDirectory, multiple });
4
19
  }
5
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAItD,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,IAAI,GAAG,KAAK,EACZ,oBAAoB,GAAG,IAAI,EAC3B,QAAQ,GAAG,KAAK,MACS,EAAE;IAC3B,OAAO,MAAM,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC7F,CAAC","sourcesContent":["import ExpoDocumentPicker from './ExpoDocumentPicker';\nimport { DocumentPickerOptions, DocumentResult } from './types';\nexport { DocumentPickerOptions, DocumentResult };\n\nexport async function getDocumentAsync({\n type = '*/*',\n copyToCacheDirectory = true,\n multiple = false,\n}: DocumentPickerOptions = {}): Promise<DocumentResult> {\n return await ExpoDocumentPicker.getDocumentAsync({ type, copyToCacheDirectory, multiple });\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,kBAAkB,MAAM,sBAAsB,CAAC;AAItD,cAAc;AACd;;;;;;;;;;GAUG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,EACrC,IAAI,GAAG,KAAK,EACZ,oBAAoB,GAAG,IAAI,EAC3B,QAAQ,GAAG,KAAK,MACS,EAAE;IAC3B,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE;QAC5B,IAAI,GAAG,CAAC,IAAI,CAAa,CAAC;KAC3B;IACD,OAAO,MAAM,kBAAkB,CAAC,gBAAgB,CAAC,EAAE,IAAI,EAAE,oBAAoB,EAAE,QAAQ,EAAE,CAAC,CAAC;AAC7F,CAAC","sourcesContent":["import ExpoDocumentPicker from './ExpoDocumentPicker';\nimport { DocumentPickerOptions, DocumentResult } from './types';\nexport { DocumentPickerOptions, DocumentResult };\n\n// @needsAudit\n/**\n * Display the system UI for choosing a document. By default, the chosen file is copied to [the app's internal cache directory](filesystem.md#filesystemcachedirectory).\n * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).\n * Therefore, calling `getDocumentAsync` in `componentDidMount`, for example, will **not** work as\n * intended. The `cancel` event will not be returned in the browser due to platform restrictions and\n * inconsistencies across browsers.\n *\n * @return On success returns a promise that fulfils with [`DocumentResult`](#documentresult) object.\n *\n * If the user cancelled the document picking, the promise resolves to `{ type: 'cancel' }`.\n */\nexport async function getDocumentAsync({\n type = '*/*',\n copyToCacheDirectory = true,\n multiple = false,\n}: DocumentPickerOptions = {}): Promise<DocumentResult> {\n if (typeof type === 'string') {\n type = [type] as string[];\n }\n return await ExpoDocumentPicker.getDocumentAsync({ type, copyToCacheDirectory, multiple });\n}\n"]}
package/build/types.d.ts CHANGED
@@ -1,15 +1,48 @@
1
+ /**
2
+ *
3
+ */
1
4
  export declare type DocumentPickerOptions = {
2
- type?: string;
5
+ /**
6
+ * The [MIME type(s)](https://en.wikipedia.org/wiki/Media_type) of the documents that are available
7
+ * to be picked. Is also supports wildcards like `'image/*'` to choose any image. To allow any type
8
+ * of document you can use `'&ast;/*'`.
9
+ * @default `'&ast;/*'`
10
+ */
11
+ type?: string | string[];
12
+ /**
13
+ * If `true`, the picked file is copied to [`FileSystem.CacheDirectory`](filesystem.md#filesystemcachedirectory),
14
+ * which allows other Expo APIs to read the file immediately. This may impact performance for
15
+ * large files, so you should consider setting this to `false` if you expect users to pick
16
+ * particularly large files and your app does not need immediate read access.
17
+ * @default `true`
18
+ */
3
19
  copyToCacheDirectory?: boolean;
20
+ /**
21
+ * __Web Only.__ Allows multiple files to be selected from the system UI.
22
+ * @default `false`
23
+ */
4
24
  multiple?: boolean;
5
25
  };
6
26
  export declare type DocumentResult = {
7
27
  type: 'cancel';
8
28
  } | {
9
29
  type: 'success';
30
+ /**
31
+ * Document original name.
32
+ */
10
33
  name: string;
11
- size: number;
34
+ /**
35
+ * Document size in bytes.
36
+ */
37
+ size?: number;
38
+ /**
39
+ * An URI to the local document file.
40
+ */
12
41
  uri: string;
42
+ /**
43
+ * Document MIME type.
44
+ */
45
+ mimeType?: string;
13
46
  lastModified?: number;
14
47
  file?: File;
15
48
  output?: FileList | null;
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["export type DocumentPickerOptions = {\n type?: string;\n copyToCacheDirectory?: boolean;\n multiple?: boolean;\n};\n\nexport type DocumentResult =\n | { type: 'cancel' }\n | {\n type: 'success';\n name: string;\n size: number;\n uri: string;\n lastModified?: number;\n file?: File;\n output?: FileList | null;\n };\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"","sourcesContent":["// @needsAudit\n/**\n *\n */\nexport type DocumentPickerOptions = {\n /**\n * The [MIME type(s)](https://en.wikipedia.org/wiki/Media_type) of the documents that are available\n * to be picked. Is also supports wildcards like `'image/*'` to choose any image. To allow any type\n * of document you can use `'&ast;/*'`.\n * @default `'&ast;/*'`\n */\n type?: string | string[];\n /**\n * If `true`, the picked file is copied to [`FileSystem.CacheDirectory`](filesystem.md#filesystemcachedirectory),\n * which allows other Expo APIs to read the file immediately. This may impact performance for\n * large files, so you should consider setting this to `false` if you expect users to pick\n * particularly large files and your app does not need immediate read access.\n * @default `true`\n */\n copyToCacheDirectory?: boolean;\n /**\n * __Web Only.__ Allows multiple files to be selected from the system UI.\n * @default `false`\n */\n multiple?: boolean;\n};\n\n// @needsAudit @docsMissing\nexport type DocumentResult =\n | { type: 'cancel' }\n | {\n type: 'success';\n /**\n * Document original name.\n */\n name: string;\n /**\n * Document size in bytes.\n */\n size?: number;\n /**\n * An URI to the local document file.\n */\n uri: string;\n /**\n * Document MIME type.\n */\n mimeType?: string;\n lastModified?: number;\n file?: File;\n output?: FileList | null;\n };\n"]}
@@ -1,7 +1,7 @@
1
1
  // Copyright © 2018 650 Industries. All rights reserved.
2
2
 
3
- #import <UMCore/UMExportedModule.h>
4
- #import <UMCore/UMModuleRegistryConsumer.h>
3
+ #import <ExpoModulesCore/EXExportedModule.h>
4
+ #import <ExpoModulesCore/EXModuleRegistryConsumer.h>
5
5
 
6
- @interface EXDocumentPickerModule : UMExportedModule <UMModuleRegistryConsumer>
6
+ @interface EXDocumentPickerModule : EXExportedModule <EXModuleRegistryConsumer>
7
7
  @end
@@ -2,7 +2,7 @@
2
2
 
3
3
 
4
4
  #import <EXDocumentPicker/EXDocumentPickerModule.h>
5
- #import <UMCore/UMUtilitiesInterface.h>
5
+ #import <ExpoModulesCore/EXUtilitiesInterface.h>
6
6
  #import <ExpoModulesCore/EXFileSystemInterface.h>
7
7
 
8
8
  #import <UIKit/UIKit.h>
@@ -20,7 +20,7 @@
20
20
  // UTType#typeWithMIMEType doesn't work with wildcard mimetypes
21
21
  // so support common top level types with wildcards here.
22
22
  if ([mimeType isEqualToString:@"*/*"]) {
23
- return UTTypeData;
23
+ return UTTypeItem;
24
24
  } else if ([mimeType isEqualToString:@"image/*"]) {
25
25
  return UTTypeImage;
26
26
  } else if ([mimeType isEqualToString:@"video/*"]) {
@@ -43,7 +43,7 @@ static NSString * EXConvertMimeTypeToUTI(NSString *mimeType)
43
43
  // UTTypeCreatePreferredIdentifierForTag doesn't work with wildcard mimetypes
44
44
  // so support common top level types with wildcards here.
45
45
  if ([mimeType isEqualToString:@"*/*"]) {
46
- uti = kUTTypeData;
46
+ uti = kUTTypeItem;
47
47
  } else if ([mimeType isEqualToString:@"image/*"]) {
48
48
  uti = kUTTypeImage;
49
49
  } else if ([mimeType isEqualToString:@"video/*"]) {
@@ -62,12 +62,12 @@ static NSString * EXConvertMimeTypeToUTI(NSString *mimeType)
62
62
 
63
63
  @interface EXDocumentPickerModule () <UIDocumentPickerDelegate, UIAdaptivePresentationControllerDelegate>
64
64
 
65
- @property (nonatomic, weak) UMModuleRegistry *moduleRegistry;
65
+ @property (nonatomic, weak) EXModuleRegistry *moduleRegistry;
66
66
  @property (nonatomic, weak) id<EXFileSystemInterface> fileSystem;
67
- @property (nonatomic, weak) id<UMUtilitiesInterface> utilities;
67
+ @property (nonatomic, weak) id<EXUtilitiesInterface> utilities;
68
68
 
69
- @property (nonatomic, strong) UMPromiseResolveBlock resolve;
70
- @property (nonatomic, strong) UMPromiseRejectBlock reject;
69
+ @property (nonatomic, strong) EXPromiseResolveBlock resolve;
70
+ @property (nonatomic, strong) EXPromiseRejectBlock reject;
71
71
 
72
72
  @property (nonatomic, assign) BOOL shouldCopyToCacheDirectory;
73
73
 
@@ -75,49 +75,60 @@ static NSString * EXConvertMimeTypeToUTI(NSString *mimeType)
75
75
 
76
76
  @implementation EXDocumentPickerModule
77
77
 
78
- UM_EXPORT_MODULE(ExpoDocumentPicker);
78
+ EX_EXPORT_MODULE(ExpoDocumentPicker);
79
79
 
80
- - (void)setModuleRegistry:(UMModuleRegistry *)moduleRegistry
80
+ - (void)setModuleRegistry:(EXModuleRegistry *)moduleRegistry
81
81
  {
82
82
  _moduleRegistry = moduleRegistry;
83
83
 
84
84
  if (_moduleRegistry != nil) {
85
85
  _fileSystem = [moduleRegistry getModuleImplementingProtocol:@protocol(EXFileSystemInterface)];
86
- _utilities = [moduleRegistry getModuleImplementingProtocol:@protocol(UMUtilitiesInterface)];
86
+ _utilities = [moduleRegistry getModuleImplementingProtocol:@protocol(EXUtilitiesInterface)];
87
87
  }
88
88
  }
89
89
 
90
- UM_EXPORT_METHOD_AS(getDocumentAsync,
90
+ EX_EXPORT_METHOD_AS(getDocumentAsync,
91
91
  options:(NSDictionary *)options
92
- resolve:(UMPromiseResolveBlock)resolve
93
- reject:(UMPromiseRejectBlock)reject)
92
+ resolve:(EXPromiseResolveBlock)resolve
93
+ reject:(EXPromiseRejectBlock)reject)
94
94
  {
95
95
  if (_resolve != nil) {
96
96
  return reject(@"E_DOCUMENT_PICKER", @"Different document picking in progress. Await other document picking first.", nil);
97
97
  }
98
98
  _resolve = resolve;
99
99
  _reject = reject;
100
-
101
- NSString *mimeType = options[@"type"] ?: @"*/*";
102
-
100
+
101
+ NSArray *mimeTypes = options[@"type"] ?: @[@"*/*"];
102
+ if (mimeTypes.count == 0) {
103
+ reject(@"E_DOCUMENT_PICKER", @"type must be a list of strings.", nil);
104
+ _resolve = nil;
105
+ _reject = nil;
106
+ return;
107
+ }
103
108
  _shouldCopyToCacheDirectory = options[@"copyToCacheDirectory"] && [options[@"copyToCacheDirectory"] boolValue] == YES;
104
109
 
105
- UM_WEAKIFY(self);
110
+ EX_WEAKIFY(self);
106
111
 
107
112
  dispatch_async(dispatch_get_main_queue(), ^{
108
- UM_ENSURE_STRONGIFY(self);
113
+ EX_ENSURE_STRONGIFY(self);
109
114
  UIDocumentPickerViewController *documentPickerVC;
110
115
 
111
116
  @try {
112
117
  // TODO: drop #if macro once Xcode is updated to 12
113
118
  #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
114
119
  if (@available(iOS 14, *)) {
115
- UTType* utType = EXConvertMimeTypeToUTType(mimeType);
116
- documentPickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:@[utType] asCopy:YES];
120
+ NSMutableArray *utTypes = [mimeTypes mutableCopy];
121
+ for (int i = 0; i < [mimeTypes count]; i++) {
122
+ utTypes[i] = (NSString *)EXConvertMimeTypeToUTType(mimeTypes[i]);
123
+ }
124
+ documentPickerVC = [[UIDocumentPickerViewController alloc] initForOpeningContentTypes:utTypes asCopy:true];
117
125
  } else {
118
126
  #endif
119
- NSString* type = EXConvertMimeTypeToUTI(mimeType);
120
- documentPickerVC = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[type]
127
+ NSMutableArray *utiTypes = [mimeTypes mutableCopy];
128
+ for (int i = 0; i < [mimeTypes count]; i++) {
129
+ utiTypes[i] = (NSString *)EXConvertMimeTypeToUTI(mimeTypes[i]);
130
+ }
131
+ documentPickerVC = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:utiTypes
121
132
  inMode:UIDocumentPickerModeImport];
122
133
  // TODO: drop #if macro once Xcode is updated to 12
123
134
  #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 140000
@@ -172,12 +183,16 @@ UM_EXPORT_METHOD_AS(getDocumentAsync,
172
183
  return;
173
184
  }
174
185
  }
186
+
187
+ NSString *extension = [url pathExtension];
188
+ NSString *mimeType = [EXDocumentPickerModule getMimeType:extension];
175
189
 
176
190
  _resolve(@{
177
191
  @"type": @"success",
178
192
  @"uri": [newUrl absoluteString],
179
193
  @"name": [url lastPathComponent],
180
194
  @"size": @(fileSize),
195
+ @"mimeType": mimeType
181
196
  });
182
197
  _resolve = nil;
183
198
  _reject = nil;
@@ -227,4 +242,10 @@ UM_EXPORT_METHOD_AS(getDocumentAsync,
227
242
  return folderSize;
228
243
  }
229
244
 
245
+ + (NSString *)getMimeType:(NSString *)fileExtension{
246
+ NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)fileExtension, NULL);
247
+ NSString *mimeType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType);
248
+ return mimeType;
249
+ }
250
+
230
251
  @end
@@ -10,10 +10,10 @@ Pod::Spec.new do |s|
10
10
  s.license = package['license']
11
11
  s.author = package['author']
12
12
  s.homepage = package['homepage']
13
- s.platform = :ios, '11.0'
13
+ s.platform = :ios, '12.0'
14
14
  s.source = { git: 'https://github.com/expo/expo.git' }
15
+ s.static_framework = true
15
16
 
16
- s.dependency 'UMCore'
17
17
  s.dependency 'ExpoModulesCore'
18
18
 
19
19
  if !$ExpoUseSources&.include?(package['name']) && ENV['EXPO_USE_SOURCE'].to_i == 0 && File.exist?("#{s.name}.xcframework") && Gem::Version.new(Pod::VERSION) >= Gem::Version.new('1.10.0')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "expo-document-picker",
3
- "version": "9.2.3",
3
+ "version": "10.0.2",
4
4
  "description": "Provides access to the system's UI for selecting documents from the available providers on the user's device.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -30,20 +30,17 @@
30
30
  },
31
31
  "author": "650 Industries, Inc.",
32
32
  "license": "MIT",
33
- "homepage": "https://docs.expo.io/versions/latest/sdk/document-picker/",
33
+ "homepage": "https://docs.expo.dev/versions/latest/sdk/document-picker/",
34
34
  "jest": {
35
35
  "preset": "expo-module-scripts/ios"
36
36
  },
37
37
  "dependencies": {
38
- "@expo/config-plugins": "^3.0.0",
39
- "expo-modules-core": "~0.2.0",
38
+ "@expo/config-plugins": "^3.1.0",
39
+ "expo-modules-core": "~0.4.3",
40
40
  "uuid": "^3.3.2"
41
41
  },
42
- "unimodulePeerDependencies": {
43
- "@unimodules/core": "*"
44
- },
45
42
  "devDependencies": {
46
43
  "expo-module-scripts": "^2.0.0"
47
44
  },
48
- "gitHead": "4fc9d282ff7ab2fa9040b775aeca7c30f5167b17"
45
+ "gitHead": "d23e1ac491da96b51c25eb2533efcd56499ee287"
49
46
  }
@@ -2,8 +2,8 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setICloudEntitlments = exports.withDocumentPickerIOS = void 0;
4
4
  const config_plugins_1 = require("@expo/config-plugins");
5
- exports.withDocumentPickerIOS = (config, { appleTeamId }) => {
6
- return config_plugins_1.withEntitlementsPlist(config, config => {
5
+ const withDocumentPickerIOS = (config, { appleTeamId }) => {
6
+ return config_plugins_1.withEntitlementsPlist(config, (config) => {
7
7
  if (appleTeamId) {
8
8
  config.modResults = setICloudEntitlments(config, appleTeamId, config.modResults);
9
9
  }
@@ -13,6 +13,7 @@ exports.withDocumentPickerIOS = (config, { appleTeamId }) => {
13
13
  return config;
14
14
  });
15
15
  };
16
+ exports.withDocumentPickerIOS = withDocumentPickerIOS;
16
17
  function setICloudEntitlments(config, appleTeamId, entitlements) {
17
18
  var _a;
18
19
  if ((_a = config.ios) === null || _a === void 0 ? void 0 : _a.usesIcloudStorage) {
@@ -5,7 +5,7 @@ export const withDocumentPickerIOS: ConfigPlugin<{ appleTeamId?: string }> = (
5
5
  config,
6
6
  { appleTeamId }
7
7
  ) => {
8
- return withEntitlementsPlist(config, config => {
8
+ return withEntitlementsPlist(config, (config) => {
9
9
  if (appleTeamId) {
10
10
  config.modResults = setICloudEntitlments(config, appleTeamId, config.modResults);
11
11
  } else {
@@ -1,3 +1,3 @@
1
- import { NativeModulesProxy } from '@unimodules/core';
1
+ import { NativeModulesProxy } from 'expo-modules-core';
2
2
 
3
3
  export default NativeModulesProxy.ExpoDocumentPicker;
@@ -1,4 +1,4 @@
1
- import { Platform } from '@unimodules/core';
1
+ import { Platform } from 'expo-modules-core';
2
2
  import { v4 as uuidv4 } from 'uuid';
3
3
 
4
4
  import { DocumentPickerOptions, DocumentResult } from './types';
@@ -20,7 +20,7 @@ export default {
20
20
  const input = document.createElement('input');
21
21
  input.style.display = 'none';
22
22
  input.setAttribute('type', 'file');
23
- input.setAttribute('accept', type);
23
+ input.setAttribute('accept', Array.isArray(type) ? type.join(',') : type);
24
24
  input.setAttribute('id', uuidv4());
25
25
  if (multiple) {
26
26
  input.setAttribute('multiple', 'multiple');
@@ -32,6 +32,7 @@ export default {
32
32
  input.addEventListener('change', () => {
33
33
  if (input.files) {
34
34
  const targetFile = input.files[0];
35
+ const mimeType = targetFile.type;
35
36
  const reader = new FileReader();
36
37
  reader.onerror = () => {
37
38
  reject(new Error(`Failed to read the selected media because the operation failed.`));
@@ -41,6 +42,7 @@ export default {
41
42
  resolve({
42
43
  type: 'success',
43
44
  uri,
45
+ mimeType,
44
46
  name: targetFile.name,
45
47
  file: targetFile,
46
48
  lastModified: targetFile.lastModified,
package/src/index.ts CHANGED
@@ -2,10 +2,25 @@ import ExpoDocumentPicker from './ExpoDocumentPicker';
2
2
  import { DocumentPickerOptions, DocumentResult } from './types';
3
3
  export { DocumentPickerOptions, DocumentResult };
4
4
 
5
+ // @needsAudit
6
+ /**
7
+ * Display the system UI for choosing a document. By default, the chosen file is copied to [the app's internal cache directory](filesystem.md#filesystemcachedirectory).
8
+ * > **Notes for Web:** The system UI can only be shown after user activation (e.g. a `Button` press).
9
+ * Therefore, calling `getDocumentAsync` in `componentDidMount`, for example, will **not** work as
10
+ * intended. The `cancel` event will not be returned in the browser due to platform restrictions and
11
+ * inconsistencies across browsers.
12
+ *
13
+ * @return On success returns a promise that fulfils with [`DocumentResult`](#documentresult) object.
14
+ *
15
+ * If the user cancelled the document picking, the promise resolves to `{ type: 'cancel' }`.
16
+ */
5
17
  export async function getDocumentAsync({
6
18
  type = '*/*',
7
19
  copyToCacheDirectory = true,
8
20
  multiple = false,
9
21
  }: DocumentPickerOptions = {}): Promise<DocumentResult> {
22
+ if (typeof type === 'string') {
23
+ type = [type] as string[];
24
+ }
10
25
  return await ExpoDocumentPicker.getDocumentAsync({ type, copyToCacheDirectory, multiple });
11
26
  }
package/src/types.ts CHANGED
@@ -1,16 +1,51 @@
1
+ // @needsAudit
2
+ /**
3
+ *
4
+ */
1
5
  export type DocumentPickerOptions = {
2
- type?: string;
6
+ /**
7
+ * The [MIME type(s)](https://en.wikipedia.org/wiki/Media_type) of the documents that are available
8
+ * to be picked. Is also supports wildcards like `'image/*'` to choose any image. To allow any type
9
+ * of document you can use `'&ast;/*'`.
10
+ * @default `'&ast;/*'`
11
+ */
12
+ type?: string | string[];
13
+ /**
14
+ * If `true`, the picked file is copied to [`FileSystem.CacheDirectory`](filesystem.md#filesystemcachedirectory),
15
+ * which allows other Expo APIs to read the file immediately. This may impact performance for
16
+ * large files, so you should consider setting this to `false` if you expect users to pick
17
+ * particularly large files and your app does not need immediate read access.
18
+ * @default `true`
19
+ */
3
20
  copyToCacheDirectory?: boolean;
21
+ /**
22
+ * __Web Only.__ Allows multiple files to be selected from the system UI.
23
+ * @default `false`
24
+ */
4
25
  multiple?: boolean;
5
26
  };
6
27
 
28
+ // @needsAudit @docsMissing
7
29
  export type DocumentResult =
8
30
  | { type: 'cancel' }
9
31
  | {
10
32
  type: 'success';
33
+ /**
34
+ * Document original name.
35
+ */
11
36
  name: string;
12
- size: number;
37
+ /**
38
+ * Document size in bytes.
39
+ */
40
+ size?: number;
41
+ /**
42
+ * An URI to the local document file.
43
+ */
13
44
  uri: string;
45
+ /**
46
+ * Document MIME type.
47
+ */
48
+ mimeType?: string;
14
49
  lastModified?: number;
15
50
  file?: File;
16
51
  output?: FileList | null;