Skip to content

Commit 4c86143

Browse files
authored
Merge pull request #11 from n1ru4l/feat-is-file-value-option
Add ability to customize what are extractable files. Fixes #10 .
2 parents 8eec821 + 2782ccd commit 4c86143

6 files changed

+217
-63
lines changed

changelog.md

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
### Minor
1010

11+
- Added the ability to customize what are extractable files, fixing [#10](https://github.com/jaydenseric/extract-files/issues/10) via [#11](https://github.com/jaydenseric/extract-files/pull/11):
12+
- Added a new third parameter to the `extractFiles` function, for specifying a custom extractable file matcher.
13+
- Export a new `isExtractableFile` function that is used as the default extractable file matcher for the `extractFiles` function. This can be used in a custom extractable file matcher implementation to match the default extractable files, along with additional custom files.
1114
- Setup [GitHub Sponsors funding](https://github.com/sponsors/jaydenseric):
1215
- Added `.github/funding.yml` to display a sponsor button in GitHub.
1316
- Added a `package.json` `funding` field to enable npm CLI funding features.

readme.md

+55
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,9 @@ See the [`extractFiles`](#function-extractfiles) documentation to get started.
2828

2929
- [class ReactNativeFile](#class-reactnativefile)
3030
- [function extractFiles](#function-extractfiles)
31+
- [function isExtractableFile](#function-isextractablefile)
3132
- [type ExtractableFile](#type-extractablefile)
33+
- [type ExtractableFileMatcher](#type-extractablefilematcher)
3234
- [type ExtractFilesResult](#type-extractfilesresult)
3335
- [type ObjectPath](#type-objectpath)
3436
- [type ReactNativeFileSubstitute](#type-reactnativefilesubstitute)
@@ -65,6 +67,7 @@ Clones a value, recursively extracting [`File`](https://developer.mozilla.org/do
6567
| :-- | :-- | :-- |
6668
| `value` | \* | Value (typically an object tree) to extract files from. |
6769
| `path` | [ObjectPath](#type-objectpath)? = `''` | Prefix for object paths for extracted files. |
70+
| `isExtractableFile` | [ExtractableFileMatcher](#type-extractablefilematcher)? = [isExtractableFile](#function-isextractablefile) | The function used to identify extractable files. |
6871
6972
**Returns:** [ExtractFilesResult](#type-extractfilesresult) — Result.
7073
@@ -107,6 +110,28 @@ _Extract files from an object._
107110
108111
---
109112
113+
### function isExtractableFile
114+
115+
Checks if a value is an [extractable file](#type-extractablefile).
116+
117+
**Type:** [ExtractableFileMatcher](#type-extractablefilematcher)
118+
119+
| Parameter | Type | Description |
120+
| :-------- | :--- | :-------------- |
121+
| `value` | \* | Value to check. |
122+
123+
**Returns:** boolean — Is the value an [extractable file](#type-extractablefile).
124+
125+
#### Examples
126+
127+
_How to import._
128+
129+
> ```js
130+
> import { isExtractableFile } from 'extract-files'
131+
> ```
132+
133+
---
134+
110135
### type ExtractableFile
111136
112137
An extractable file.
@@ -115,6 +140,36 @@ An extractable file.
115140
116141
---
117142
143+
### type ExtractableFileMatcher
144+
145+
A function that checks if a value is an extractable file.
146+
147+
**Type:** Function
148+
149+
| Parameter | Type | Description |
150+
| :-------- | :--- | :-------------- |
151+
| `value` | \* | Value to check. |
152+
153+
**Returns:** boolean — Is the value an extractable file.
154+
155+
#### See
156+
157+
- [`isExtractableFile`](#function-isextractablefile) is the default extractable file matcher.
158+
159+
#### Examples
160+
161+
_How to check for the default exactable files, as well as a custom type of file._
162+
163+
> ```js
164+
> import { isExtractableFile } from 'extract-files'
165+
>
166+
> const isExtractableFileEnhanced = value =>
167+
> isExtractableFile(value) ||
168+
> (typeof CustomFile !== 'undefined' && value instanceof CustomFile)
169+
> ```
170+
171+
---
172+
118173
### type ExtractFilesResult
119174
120175
What [`extractFiles`](#function-extractfiles) returns.

src/extractFiles.mjs

+14-9
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ReactNativeFile } from './ReactNativeFile.mjs'
1+
import { isExtractableFile as defaultIsExtractableFile } from './isExtractableFile.mjs'
22

33
/**
44
* Clones a value, recursively extracting
@@ -13,6 +13,7 @@ import { ReactNativeFile } from './ReactNativeFile.mjs'
1313
* @name extractFiles
1414
* @param {*} value Value (typically an object tree) to extract files from.
1515
* @param {ObjectPath} [path=''] Prefix for object paths for extracted files.
16+
* @param {ExtractableFileMatcher} [isExtractableFile=isExtractableFile] The function used to identify extractable files.
1617
* @returns {ExtractFilesResult} Result.
1718
* @example <caption>Extract files from an object.</caption>
1819
* For the following:
@@ -48,7 +49,11 @@ import { ReactNativeFile } from './ReactNativeFile.mjs'
4849
* | `file1` | `['prefix.a', 'prefix.b.0']` |
4950
* | `file2` | `['prefix.b.1']` |
5051
*/
51-
export function extractFiles(value, path = '') {
52+
export function extractFiles(
53+
value,
54+
path = '',
55+
isExtractableFile = defaultIsExtractableFile
56+
) {
5257
let clone
5358
const files = new Map()
5459

@@ -66,11 +71,7 @@ export function extractFiles(value, path = '') {
6671
else files.set(file, paths)
6772
}
6873

69-
if (
70-
(typeof File !== 'undefined' && value instanceof File) ||
71-
(typeof Blob !== 'undefined' && value instanceof Blob) ||
72-
value instanceof ReactNativeFile
73-
) {
74+
if (isExtractableFile(value)) {
7475
clone = null
7576
addFile([path], value)
7677
} else {
@@ -83,14 +84,18 @@ export function extractFiles(value, path = '') {
8384
})
8485
else if (Array.isArray(value))
8586
clone = value.map((child, i) => {
86-
const result = extractFiles(child, `${prefix}${i}`)
87+
const result = extractFiles(child, `${prefix}${i}`, isExtractableFile)
8788
result.files.forEach(addFile)
8889
return result.clone
8990
})
9091
else if (value && value.constructor === Object) {
9192
clone = {}
9293
for (const i in value) {
93-
const result = extractFiles(value[i], `${prefix}${i}`)
94+
const result = extractFiles(
95+
value[i],
96+
`${prefix}${i}`,
97+
isExtractableFile
98+
)
9499
result.files.forEach(addFile)
95100
clone[i] = result.clone
96101
}

src/index.mjs

+19
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export { extractFiles } from './extractFiles.mjs'
22
export { ReactNativeFile } from './ReactNativeFile.mjs'
3+
export { isExtractableFile } from './isExtractableFile.mjs'
34

45
/**
56
* An extractable file.
@@ -8,6 +9,24 @@ export { ReactNativeFile } from './ReactNativeFile.mjs'
89
* @type {File|Blob|ReactNativeFile}
910
*/
1011

12+
/**
13+
* A function that checks if a value is an extractable file.
14+
* @kind typedef
15+
* @name ExtractableFileMatcher
16+
* @type {Function}
17+
* @param {*} value Value to check.
18+
* @returns {boolean} Is the value an extractable file.
19+
* @see [`isExtractableFile`]{@link isExtractableFile} is the default extractable file matcher.
20+
* @example <caption>How to check for the default exactable files, as well as a custom type of file.</caption>
21+
* ```js
22+
* import { isExtractableFile } from 'extract-files'
23+
*
24+
* const isExtractableFileEnhanced = value =>
25+
* isExtractableFile(value) ||
26+
* (typeof CustomFile !== 'undefined' && value instanceof CustomFile)
27+
* ```
28+
*/
29+
1130
/**
1231
* What [`extractFiles`]{@link extractFiles} returns.
1332
* @kind typedef

src/isExtractableFile.mjs

+18
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { ReactNativeFile } from './ReactNativeFile.mjs'
2+
3+
/**
4+
* Checks if a value is an [extractable file]{@link ExtractableFile}.
5+
* @kind function
6+
* @name isExtractableFile
7+
* @type {ExtractableFileMatcher}
8+
* @param {*} value Value to check.
9+
* @returns {boolean} Is the value an [extractable file]{@link ExtractableFile}.
10+
* @example <caption>How to import.</caption>
11+
* ```js
12+
* import { isExtractableFile } from 'extract-files'
13+
* ```
14+
*/
15+
export const isExtractableFile = value =>
16+
(typeof File !== 'undefined' && value instanceof File) ||
17+
(typeof Blob !== 'undefined' && value instanceof Blob) ||
18+
value instanceof ReactNativeFile

0 commit comments

Comments
 (0)