exiftool-vendored 36.0.0 → 37.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +64 -5
- package/CLAUDE.md +2 -1
- package/README.md +128 -35
- package/RELEASE.md +1 -1
- package/data/TagMetadata.json +10 -3
- package/dist/DateTime.d.ts +2 -2
- package/dist/DateTime.js +1 -1
- package/dist/DateTime.js.map +1 -1
- package/dist/ExifTool.d.ts +45 -8
- package/dist/ExifTool.dispose.spec.js +3 -3
- package/dist/ExifTool.dispose.spec.js.map +1 -1
- package/dist/ExifTool.js +54 -10
- package/dist/ExifTool.js.map +1 -1
- package/dist/ExifToolOptions.d.ts +15 -2
- package/dist/ExifToolOptions.js.map +1 -1
- package/dist/ExifToolVendoredTags.d.ts +11 -1
- package/dist/ExifToolVendoredTags.js +1 -1
- package/dist/ExifToolVendoredTags.js.map +1 -1
- package/dist/ExiftoolPath.js +1 -1
- package/dist/ExiftoolPath.js.map +1 -1
- package/dist/InvalidUtf8Bytes.d.ts +20 -0
- package/dist/InvalidUtf8Bytes.js +106 -0
- package/dist/InvalidUtf8Bytes.js.map +1 -0
- package/dist/InvalidUtf8Bytes.spec.d.ts +1 -0
- package/dist/InvalidUtf8Bytes.spec.js +75 -0
- package/dist/InvalidUtf8Bytes.spec.js.map +1 -0
- package/dist/InvalidUtf8Xml.spec.d.ts +1 -0
- package/dist/InvalidUtf8Xml.spec.js +156 -0
- package/dist/InvalidUtf8Xml.spec.js.map +1 -0
- package/dist/JSON.d.ts +1 -0
- package/dist/JSON.js +6 -1
- package/dist/JSON.js.map +1 -1
- package/dist/RawTags.d.ts +9 -2
- package/dist/ReadRawTask.d.ts +1 -0
- package/dist/ReadRawTask.js +16 -3
- package/dist/ReadRawTask.js.map +1 -1
- package/dist/ReadRawTask.spec.js +191 -0
- package/dist/ReadRawTask.spec.js.map +1 -1
- package/dist/ReadTask.js +24 -2
- package/dist/ReadTask.js.map +1 -1
- package/dist/ReadTask.spec.js +52 -0
- package/dist/ReadTask.spec.js.map +1 -1
- package/dist/TagEdit.d.ts +62 -0
- package/dist/TagEdit.js +224 -0
- package/dist/TagEdit.js.map +1 -0
- package/dist/TagEdit.spec.d.ts +1 -0
- package/dist/TagEdit.spec.js +863 -0
- package/dist/TagEdit.spec.js.map +1 -0
- package/dist/Tags.d.ts +56 -38
- package/dist/Tags.js +3 -3
- package/dist/Tags.js.map +1 -1
- package/dist/Tags.spec.js +8 -0
- package/dist/Tags.spec.js.map +1 -1
- package/dist/Timezones.js.map +1 -1
- package/dist/Utf8JsonFilter.d.ts +7 -0
- package/dist/Utf8JsonFilter.js +85 -0
- package/dist/Utf8JsonFilter.js.map +1 -0
- package/dist/WriteTask.d.ts +6 -0
- package/dist/WriteTask.js +58 -18
- package/dist/WriteTask.js.map +1 -1
- package/dist/WriteTask.spec.js +17 -0
- package/dist/WriteTask.spec.js.map +1 -1
- package/dist/update/mktags.js +19 -1
- package/dist/update/mktags.js.map +1 -1
- package/package.json +15 -47
package/CHANGELOG.md
CHANGED
|
@@ -35,6 +35,65 @@ vendored versions of ExifTool match the version that they vendor.
|
|
|
35
35
|
|
|
36
36
|
## History
|
|
37
37
|
|
|
38
|
+
### v37.0.0
|
|
39
|
+
|
|
40
|
+
- 💔 **BREAKING: malformed UTF-8 in ExifTool JSON output is now marked with
|
|
41
|
+
Unicode replacement character U+FFFD (`�`) instead of ASCII question mark
|
|
42
|
+
(`?`).** For example, malformed bytes `dc 4b` previously surfaced as `?K`
|
|
43
|
+
and now surface as `�K`. This applies to both `read()` and `readRaw()`,
|
|
44
|
+
including scalar and list values and calls that override `readArgs`. Valid
|
|
45
|
+
Unicode and authored question marks are unchanged.
|
|
46
|
+
- The original malformed string bytes are available without rereading the
|
|
47
|
+
media through an optional sparse `invalidUtf8Bytes` sidecar. It mirrors tag
|
|
48
|
+
paths, uses numeric object keys for damaged list items, stores each leaf as
|
|
49
|
+
a `Uint8Array`, and is absent when no malformed strings were found:
|
|
50
|
+
|
|
51
|
+
```js
|
|
52
|
+
const tags = await exiftool.read(file);
|
|
53
|
+
tags.City; // "�K"
|
|
54
|
+
tags.invalidUtf8Bytes?.City; // Uint8Array([0xdc, 0x4b])
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
`exiftool-vendored` does not guess a legacy charset. Consumers may decode
|
|
58
|
+
only these captured bytes using camera, tag, locale, or user-specific
|
|
59
|
+
evidence while retaining the U+FFFD value as a deterministic fallback.
|
|
60
|
+
|
|
61
|
+
- Nested structures mirror the paths ExifTool returns for the selected
|
|
62
|
+
`struct` mode. XML element text, attribute values, CDATA, opaque XML string
|
|
63
|
+
values, and leaves parsed from embedded binary XML packets are supported.
|
|
64
|
+
The captured bytes are the extracted value after XML parsing, not the
|
|
65
|
+
original XML token. Malformed XML element and attribute names are outside
|
|
66
|
+
this mechanism: value filters never receive names, and ExifTool's JSON
|
|
67
|
+
output repairs or canonicalizes them before the library sees them.
|
|
68
|
+
|
|
69
|
+
- The change affects new metadata reads only. Upgrading does not rewrite
|
|
70
|
+
values that applications have already persisted. Applications that use
|
|
71
|
+
extracted metadata as identifiers, facets, or tags may want to rescan or
|
|
72
|
+
reindex existing files.
|
|
73
|
+
- Consumers may replace ambiguous `?` corruption heuristics with explicit
|
|
74
|
+
U+FFFD checks where their data flow preserves the marker. Whether to
|
|
75
|
+
reject, display, or retain a marked value remains application policy.
|
|
76
|
+
- To restore the previous rendering, replace the marker in the string values
|
|
77
|
+
you consume (it never appears in numbers, dates, or binary fields). This is
|
|
78
|
+
a one-way transform — the reverse is impossible once malformed bytes have
|
|
79
|
+
collapsed to `?`, which is why the marker is preserved by default:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
typeof value === "string" ? value.replace(/\uFFFD/g, "?") : value;
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
- Advanced callers that provide their own non-empty ExifTool
|
|
86
|
+
`-api Filter=...` through `readArgs` retain ownership of the complete
|
|
87
|
+
filtering pipeline. A custom filter must perform its own UTF-8 repair and
|
|
88
|
+
byte capture if those behaviors are desired; `invalidUtf8Bytes` will be
|
|
89
|
+
absent.
|
|
90
|
+
|
|
91
|
+
- 📦 Corrected resource-cleanup documentation to distinguish normal shutdown, non-blocking `using`, awaited `await using`, and best-effort disposal timeouts.
|
|
92
|
+
|
|
93
|
+
### v36.1.0
|
|
94
|
+
|
|
95
|
+
- ✨ Added `ExifTool.editTags()` for validated exact list-value additions/removals, MWG Collection additions/predicate removals, and audited scalar or flattened person-name removals without replacing unrelated metadata. See the [usage examples](docs/USAGE-EXAMPLES.md#editing-individual-tag-values).
|
|
96
|
+
|
|
38
97
|
### v36.0.0
|
|
39
98
|
|
|
40
99
|
- 🏚️ **Dropped Node.js 20 from the supported engines and CI matrix.** Node.js 20 ("Iron") has reached [end-of-life](https://github.com/nodejs/release#release-schedule), so the minimum supported runtime is now Node.js 22 (`engines.node` is `>=22`). The CI test matrix is now Node.js 22, 24, and 26.
|
|
@@ -152,7 +211,7 @@ vendored versions of ExifTool match the version that they vendor.
|
|
|
152
211
|
|
|
153
212
|
**Previously**, even though child processes were unreferenced, the stdio streams kept the parent Node.js process alive, requiring explicit `.end()` calls.
|
|
154
213
|
|
|
155
|
-
**Now**, stdio streams are unreferenced by default, so scripts can exit naturally without calling `.end()`.
|
|
214
|
+
**Now**, stdio streams are unreferenced by default, so scripts can exit naturally without calling `.end()`. During normal shutdown, child-process cleanup is attempted automatically. Exit cleanup was strengthened further in v35.2.0 and v35.10.1; abrupt termination such as `SIGKILL` cannot run cleanup handlers.
|
|
156
215
|
|
|
157
216
|
To restore the previous behavior (parent process stays alive until `.end()` is called):
|
|
158
217
|
|
|
@@ -277,12 +336,12 @@ vendored versions of ExifTool match the version that they vendor.
|
|
|
277
336
|
|
|
278
337
|
- ✨ Added **Disposable interface support** for automatic resource cleanup:
|
|
279
338
|
- `ExifTool` now implements both `Disposable` and `AsyncDisposable` interfaces
|
|
280
|
-
- Use `using et = new ExifTool()`
|
|
281
|
-
- Use `await using et = new ExifTool()`
|
|
339
|
+
- Use `using et = new ExifTool()` to initiate cleanup when a scope exits (TypeScript 5.2+)
|
|
340
|
+
- Use `await using et = new ExifTool()` to await asynchronous cleanup
|
|
282
341
|
- Synchronous disposal initiates graceful cleanup with configurable timeout fallback
|
|
283
|
-
- Asynchronous disposal
|
|
342
|
+
- Asynchronous disposal requests forceful cleanup after its configured timeout; the timeout is not a hard completion deadline
|
|
284
343
|
- New options: `disposalTimeoutMs` (default: 1000ms) and `asyncDisposalTimeoutMs` (default: 5000ms)
|
|
285
|
-
-
|
|
344
|
+
- Disposal errors are logged; asynchronous disposal may reject if cleanup fails
|
|
286
345
|
- Maintains backward compatibility - existing `.end()` method unchanged
|
|
287
346
|
|
|
288
347
|
- ✨ **Enhanced JSDoc annotations** for Tags interface with emoji-based visual hierarchy:
|
package/CLAUDE.md
CHANGED
|
@@ -53,7 +53,8 @@ npm run release # Run release process (requires proper permissions)
|
|
|
53
53
|
## Important Notes
|
|
54
54
|
|
|
55
55
|
- Always run `npm run compile` before testing
|
|
56
|
-
-
|
|
56
|
+
- With default settings, `.end()` is optional after awaited script work, but it
|
|
57
|
+
should be awaited when cleanup must finish before the application continues or exits
|
|
57
58
|
- Tag interfaces not comprehensive - less common tags may exist in returned objects
|
|
58
59
|
- Uses batch processing with automatic process pool management
|
|
59
60
|
- TypeScript union type limits require careful tag selection
|
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# exiftool-vendored
|
|
1
|
+
# 📸 exiftool-vendored
|
|
2
2
|
|
|
3
3
|
**Fast, cross-platform [Node.js](https://nodejs.org/) access to [ExifTool](https://exiftool.org/). Built and supported by [PhotoStructure](https://photostructure.com).**
|
|
4
4
|
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
[](https://github.com/photostructure/exiftool-vendored.js/actions/workflows/build.yml)
|
|
7
7
|
[](https://github.com/photostructure/exiftool-vendored.js/issues)
|
|
8
8
|
|
|
9
|
-
## Installation & Quick Start
|
|
9
|
+
## 🚀 Installation & Quick Start
|
|
10
10
|
|
|
11
11
|
**Requirements**: Node.js Active LTS or Maintenance LTS versions only
|
|
12
12
|
|
|
@@ -35,7 +35,7 @@ await exiftool.extractThumbnail("photo.jpg", "thumb.jpg");
|
|
|
35
35
|
await exiftool.end();
|
|
36
36
|
```
|
|
37
37
|
|
|
38
|
-
## Why exiftool-vendored?
|
|
38
|
+
## 🤔 Why exiftool-vendored?
|
|
39
39
|
|
|
40
40
|
### ⚡ **Performance**
|
|
41
41
|
|
|
@@ -53,7 +53,7 @@ Order of magnitude faster than other Node.js ExifTool modules. Powers [PhotoStru
|
|
|
53
53
|
- **Smart dates**: Timezone-aware `ExifDateTime` classes
|
|
54
54
|
- **Auto-generated tags**: Based on 10,000+ real camera samples
|
|
55
55
|
|
|
56
|
-
## Core Features
|
|
56
|
+
## ✨ Core Features
|
|
57
57
|
|
|
58
58
|
### Reading Metadata
|
|
59
59
|
|
|
@@ -96,6 +96,10 @@ await exiftool.write("photo.jpg", {
|
|
|
96
96
|
});
|
|
97
97
|
```
|
|
98
98
|
|
|
99
|
+
For targeted list-value and supported structured edits, use `editTags()`. See
|
|
100
|
+
[Editing Individual Tag Values](docs/USAGE-EXAMPLES.md#editing-individual-tag-values)
|
|
101
|
+
for examples, supported tags, and safety constraints.
|
|
102
|
+
|
|
99
103
|
### Extracting Images
|
|
100
104
|
|
|
101
105
|
```javascript
|
|
@@ -109,7 +113,7 @@ await exiftool.extractPreview("photo.jpg", "preview.jpg");
|
|
|
109
113
|
await exiftool.extractJpgFromRaw("photo.cr2", "processed.jpg");
|
|
110
114
|
```
|
|
111
115
|
|
|
112
|
-
## Understanding Tags
|
|
116
|
+
## 🏷️ Understanding Tags
|
|
113
117
|
|
|
114
118
|
The `Tags` interface contains **thousands of metadata fields** from an auto-generated TypeScript file. Each tag has JSDoc annotations:
|
|
115
119
|
|
|
@@ -135,17 +139,86 @@ LensSpec?: string;
|
|
|
135
139
|
- **@groups** = Metadata categories (EXIF, GPS, IPTC, XMP, etc.)
|
|
136
140
|
- **@example** = Representative values
|
|
137
141
|
|
|
138
|
-
|
|
142
|
+
## 🛡️ Code defensively!
|
|
143
|
+
|
|
144
|
+
The generated `Tags` interface is a deliberately bounded, best-effort model of
|
|
145
|
+
what ExifTool extracts.
|
|
146
|
+
|
|
147
|
+
### Declared fields may be missing
|
|
148
|
+
|
|
149
|
+
Formats, cameras, and editing software write different subsets of metadata,
|
|
150
|
+
and later tools may strip fields. Treat every property as optional, even when
|
|
151
|
+
it is common for the files you currently handle.
|
|
152
|
+
|
|
153
|
+
### Undeclared fields may be included
|
|
154
|
+
|
|
155
|
+
The interface favors the most common and useful fields. Without tag pruning,
|
|
156
|
+
TypeScript fails with `TS2590: Expression produces a union type that is too
|
|
157
|
+
complex to represent`.
|
|
139
158
|
|
|
140
|
-
-
|
|
141
|
-
|
|
142
|
-
|
|
159
|
+
Rare, vendor-specific, and custom tags may still appear at runtime. If your app
|
|
160
|
+
needs arbitrary tags, intersect `Tags` with `Record<string, unknown>`; if a tag
|
|
161
|
+
would be useful to others, please open a PR to add it to the generated
|
|
162
|
+
interface.
|
|
163
|
+
|
|
164
|
+
### Value types may vary
|
|
165
|
+
|
|
166
|
+
ExifTool may return unexpected representations for malformed, ambiguous, or
|
|
167
|
+
format-specific values. Validate values at runtime and handle strings in
|
|
168
|
+
nominally numeric fields gracefully.
|
|
143
169
|
|
|
144
170
|
📖 **[Complete Tags Documentation →](docs/TAGS.md)**
|
|
145
171
|
|
|
146
|
-
##
|
|
172
|
+
## 🪤 Parsing gotchas
|
|
173
|
+
|
|
174
|
+
### Timezones may be inferred
|
|
175
|
+
|
|
176
|
+
Media metadata often omits its timezone, so this library uses several heuristics
|
|
177
|
+
to infer one. See [Dates & Timezones](#timezones) for the inference order and
|
|
178
|
+
configuration options.
|
|
179
|
+
|
|
180
|
+
### Malformed UTF-8 is marked and preserved
|
|
181
|
+
|
|
182
|
+
Malformed UTF-8 bytes are marked with the Unicode replacement character
|
|
183
|
+
U+FFFD, not ASCII `?`, so byte corruption stays distinguishable from
|
|
184
|
+
authored punctuation. The original bytes are preserved without another file
|
|
185
|
+
read in the sparse `invalidUtf8Bytes` sidecar:
|
|
147
186
|
|
|
148
|
-
|
|
187
|
+
```ts
|
|
188
|
+
const tags = await exiftool.read(file);
|
|
189
|
+
tags.ImageDescription; // "Arch Enemy\rG�teborg, 19.07.2007"
|
|
190
|
+
|
|
191
|
+
const bytes = tags.invalidUtf8Bytes?.ImageDescription;
|
|
192
|
+
if (bytes instanceof Uint8Array) {
|
|
193
|
+
// Camera/tag-specific evidence identifies this Kodak value as MacRoman:
|
|
194
|
+
const recovered = new TextDecoder("macintosh").decode(bytes);
|
|
195
|
+
recovered; // "Arch Enemy\rGöteborg, 19.07.2007"
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The `macintosh` charset is justified by evidence for this specific Kodak
|
|
200
|
+
value; it is not a default for every damaged field.
|
|
201
|
+
|
|
202
|
+
Nested metadata mirrors the representation selected by ExifTool's `struct`
|
|
203
|
+
option. Extracted XML element text, attribute values, CDATA, and parsed
|
|
204
|
+
embedded XML values are captured at their returned paths. These are the
|
|
205
|
+
bytes of ExifTool's extracted value after XML parsing, not the original XML
|
|
206
|
+
token: entity spellings and CDATA delimiters are not retained. Value filters
|
|
207
|
+
never receive XML element or attribute _names_, and ExifTool's JSON output
|
|
208
|
+
repairs or canonicalizes malformed names before the library sees them, so
|
|
209
|
+
their exact bytes cannot be exposed by this sidecar.
|
|
210
|
+
|
|
211
|
+
The library deliberately does not guess a legacy charset: files assembled
|
|
212
|
+
over many years may contain several encodings, and readable alternatives are
|
|
213
|
+
not necessarily correct. Consumers can decode only the sidecar entries using
|
|
214
|
+
their own camera/tag/user context. An explicit custom ExifTool `Filter`
|
|
215
|
+
disables both built-in repair and byte capture. To restore the pre-v37
|
|
216
|
+
display, guard on the value type first:
|
|
217
|
+
`typeof value === "string" ? value.replace(/\uFFFD/g, "?") : value`.
|
|
218
|
+
|
|
219
|
+
## ⚠️ Important Notes
|
|
220
|
+
|
|
221
|
+
### Configuration
|
|
149
222
|
|
|
150
223
|
exiftool-vendored provides two levels of configuration:
|
|
151
224
|
|
|
@@ -172,7 +245,9 @@ const exiftool = new ExifTool({
|
|
|
172
245
|
|
|
173
246
|
📖 **[Complete Configuration Guide →](docs/CONFIGURATION.md)**
|
|
174
247
|
|
|
175
|
-
|
|
248
|
+
<a id="timezones"></a>
|
|
249
|
+
|
|
250
|
+
### Dates & Timezones
|
|
176
251
|
|
|
177
252
|
Images rarely specify timezones. This library infers them using several heuristics:
|
|
178
253
|
|
|
@@ -190,53 +265,71 @@ if (dt instanceof ExifDateTime) {
|
|
|
190
265
|
|
|
191
266
|
📖 **[Date & Timezone Guide →](docs/DATES.md)**
|
|
192
267
|
|
|
193
|
-
###
|
|
268
|
+
### Resource Cleanup
|
|
194
269
|
|
|
195
|
-
|
|
270
|
+
With the default settings, ExifTool workers no longer keep Node.js alive after
|
|
271
|
+
awaited work finishes. During normal shutdown, the library attempts to clean up
|
|
272
|
+
workers automatically. Abrupt termination, such as `SIGKILL` or an operating-
|
|
273
|
+
system crash, cannot run cleanup handlers.
|
|
196
274
|
|
|
197
|
-
|
|
275
|
+
Call and await `.end()` when cleanup must finish before your application
|
|
276
|
+
continues or exits. For servers and daemons, make this one part of the
|
|
277
|
+
application's complete shutdown procedure:
|
|
198
278
|
|
|
199
279
|
```javascript
|
|
200
280
|
import { exiftool } from "exiftool-vendored";
|
|
201
281
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
282
|
+
async function shutdown(signal) {
|
|
283
|
+
try {
|
|
284
|
+
await closeApplicationResources(); // Server, sockets, database, etc.
|
|
285
|
+
await exiftool.end();
|
|
286
|
+
} finally {
|
|
287
|
+
// A signal listener disables Node's default termination behavior. Re-send
|
|
288
|
+
// the signal after cleanup so the process terminates normally.
|
|
289
|
+
process.kill(process.pid, signal);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
process.once("SIGINT", (signal) => void shutdown(signal));
|
|
294
|
+
process.once("SIGTERM", (signal) => void shutdown(signal));
|
|
205
295
|
```
|
|
206
296
|
|
|
207
297
|
#### Automatic Cleanup with Disposable Interfaces
|
|
208
298
|
|
|
209
|
-
For **TypeScript 5.2+** projects
|
|
299
|
+
For **TypeScript 5.2+** projects configured for explicit resource management,
|
|
300
|
+
you can bind an instance's lifecycle to a scope:
|
|
210
301
|
|
|
211
302
|
```javascript
|
|
212
303
|
import { ExifTool } from "exiftool-vendored";
|
|
213
304
|
|
|
214
|
-
//
|
|
305
|
+
// Starts cleanup when the scope exits, but does not wait for it
|
|
215
306
|
{
|
|
216
307
|
using et = new ExifTool();
|
|
217
308
|
const tags = await et.read("photo.jpg");
|
|
218
|
-
// ExifTool
|
|
309
|
+
// ExifTool cleanup is initiated when the block exits
|
|
219
310
|
}
|
|
220
311
|
|
|
221
|
-
//
|
|
312
|
+
// Waits for cleanup when the scope exits (recommended)
|
|
222
313
|
{
|
|
223
314
|
await using et = new ExifTool();
|
|
224
315
|
const tags = await et.read("photo.jpg");
|
|
225
|
-
// ExifTool
|
|
316
|
+
// ExifTool cleanup is awaited when the block exits
|
|
226
317
|
}
|
|
227
318
|
```
|
|
228
319
|
|
|
229
320
|
**Benefits:**
|
|
230
321
|
|
|
231
|
-
- **
|
|
232
|
-
- **
|
|
233
|
-
- **
|
|
322
|
+
- **Scope-bound disposal**: Disposal runs on ordinary scope exit, including exceptions
|
|
323
|
+
- **Awaited cleanup**: `await using` waits for asynchronous disposal
|
|
324
|
+
- **Less boilerplate**: No manual `try`/`finally` cleanup block
|
|
234
325
|
|
|
235
326
|
**Caution:**
|
|
236
327
|
|
|
237
|
-
- **Operating-system startup lag**:
|
|
328
|
+
- **Operating-system startup lag**: Startup time varies widely with the OS,
|
|
329
|
+
hardware, and security software, and can take several seconds on some
|
|
330
|
+
systems. Don't dispose an instance until you're really done with it.
|
|
238
331
|
|
|
239
|
-
###
|
|
332
|
+
### Tag Completeness
|
|
240
333
|
|
|
241
334
|
The `Tags` interface shows the most common fields, but ExifTool can extract many more. Cast to access unlisted fields:
|
|
242
335
|
|
|
@@ -245,9 +338,9 @@ const tags = await exiftool.read("photo.jpg");
|
|
|
245
338
|
const customField = (tags as any).UncommonTag;
|
|
246
339
|
```
|
|
247
340
|
|
|
248
|
-
## Documentation
|
|
341
|
+
## 📚 Documentation
|
|
249
342
|
|
|
250
|
-
###
|
|
343
|
+
### **Guides**
|
|
251
344
|
|
|
252
345
|
- **[Installation Guide](docs/INSTALLATION.md)** - Electron, Docker, platform setup
|
|
253
346
|
- **[Usage Examples](docs/USAGE-EXAMPLES.md)** - Comprehensive API examples
|
|
@@ -255,16 +348,16 @@ const customField = (tags as any).UncommonTag;
|
|
|
255
348
|
- **[Tags Reference](docs/TAGS.md)** - Understanding the 2,500+ metadata fields
|
|
256
349
|
- **[Electron Integration](docs/ELECTRON.md)** - Electron-specific setup
|
|
257
350
|
|
|
258
|
-
###
|
|
351
|
+
### **Troubleshooting**
|
|
259
352
|
|
|
260
353
|
- **[Debugging Guide](docs/DEBUGGING.md)** - Debug logging and common issues
|
|
261
354
|
- **[Temporal Migration](docs/TEMPORAL-MIGRATION.md)** - Future JavaScript Temporal API
|
|
262
355
|
|
|
263
|
-
###
|
|
356
|
+
### **API Reference**
|
|
264
357
|
|
|
265
358
|
- **[TypeDoc Documentation](https://photostructure.github.io/exiftool-vendored.js/)** - Complete API reference
|
|
266
359
|
|
|
267
|
-
## Performance
|
|
360
|
+
## ⚡ Performance
|
|
268
361
|
|
|
269
362
|
The default singleton is throttled for stability. For high-throughput processing:
|
|
270
363
|
|
|
@@ -285,13 +378,13 @@ await exiftool.end();
|
|
|
285
378
|
|
|
286
379
|
**Benchmarks**: 20+ files/second/thread, 500+ files/second using all CPU cores.
|
|
287
380
|
|
|
288
|
-
## Support & Community
|
|
381
|
+
## 🤝 Support & Community
|
|
289
382
|
|
|
290
383
|
- **📋 Issues**: [GitHub Issues](https://github.com/photostructure/exiftool-vendored.js/issues)
|
|
291
384
|
- **📖 Changelog**: [CHANGELOG.md](CHANGELOG.md)
|
|
292
385
|
- **🔒 Security**: [SECURITY.md](SECURITY.md)
|
|
293
386
|
- **📄 License**: [MIT](LICENSE)
|
|
294
387
|
|
|
295
|
-
### Contributors
|
|
388
|
+
### Contributors
|
|
296
389
|
|
|
297
390
|
[Matthew McEachen](https://github.com/mceachen), [Joshua Harris](https://github.com/Circuit8), [Anton Mokrushin](https://github.com/amokrushin), [Luca Ban](https://github.com/mesqueeb), [Demiurga](https://github.com/apolkingg8), [David Randler](https://github.com/draity)
|
package/RELEASE.md
CHANGED
|
@@ -47,7 +47,7 @@ For development and testing:
|
|
|
47
47
|
1. `git clone` this repo
|
|
48
48
|
2. `npm install`
|
|
49
49
|
3. `npm run mktags ../test-images` # < assumes `../test-images` has the full ExifTool sample image suite
|
|
50
|
-
4. `npm run
|
|
50
|
+
4. `npm run all` (look for lint or documentation generation issues)
|
|
51
51
|
5. `npm run test`
|
|
52
52
|
6. Verify diffs are reasonable, `git commit` and `git push`
|
|
53
53
|
7. Follow the Automatic Release steps above
|
package/data/TagMetadata.json
CHANGED
|
@@ -7394,7 +7394,7 @@
|
|
|
7394
7394
|
"FirmwareVersion": {
|
|
7395
7395
|
"frequency": 0.07,
|
|
7396
7396
|
"mainstream": true,
|
|
7397
|
-
"groups": ["APP", "MakerNotes", "QuickTime"],
|
|
7397
|
+
"groups": ["APP", "MakerNotes", "QuickTime", "RAF"],
|
|
7398
7398
|
"type": "string",
|
|
7399
7399
|
"typed": true
|
|
7400
7400
|
},
|
|
@@ -11899,7 +11899,7 @@
|
|
|
11899
11899
|
"Location": {
|
|
11900
11900
|
"frequency": 0.02,
|
|
11901
11901
|
"mainstream": true,
|
|
11902
|
-
"groups": ["MakerNotes"],
|
|
11902
|
+
"groups": ["Composite", "MakerNotes", "XMP"],
|
|
11903
11903
|
"type": "string",
|
|
11904
11904
|
"typed": true
|
|
11905
11905
|
},
|
|
@@ -19753,7 +19753,7 @@
|
|
|
19753
19753
|
},
|
|
19754
19754
|
"Transform": {
|
|
19755
19755
|
"frequency": 0.01,
|
|
19756
|
-
"mainstream":
|
|
19756
|
+
"mainstream": true,
|
|
19757
19757
|
"groups": ["MakerNotes"],
|
|
19758
19758
|
"type": "string",
|
|
19759
19759
|
"typed": true
|
|
@@ -21006,6 +21006,13 @@
|
|
|
21006
21006
|
"type": "string",
|
|
21007
21007
|
"typed": true
|
|
21008
21008
|
},
|
|
21009
|
+
"invalidUtf8Bytes": {
|
|
21010
|
+
"frequency": 0,
|
|
21011
|
+
"mainstream": true,
|
|
21012
|
+
"groups": ["Library"],
|
|
21013
|
+
"type": "InvalidUtf8Bytes",
|
|
21014
|
+
"typed": true
|
|
21015
|
+
},
|
|
21009
21016
|
"tz": {
|
|
21010
21017
|
"frequency": 0,
|
|
21011
21018
|
"mainstream": true,
|
package/dist/DateTime.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DateTime } from "luxon";
|
|
1
|
+
import { DateTime, DateTimeMaybeValid } from "luxon";
|
|
2
2
|
import { ExifDate } from "./ExifDate";
|
|
3
3
|
import { ExifDateTime } from "./ExifDateTime";
|
|
4
4
|
import { ExifTime } from "./ExifTime";
|
|
@@ -8,7 +8,7 @@ export declare const SecondMs = 1000;
|
|
|
8
8
|
export declare const MinuteMs: number;
|
|
9
9
|
export declare const HourMs: number;
|
|
10
10
|
export declare const DayMs: number;
|
|
11
|
-
export type DateOrTime = ExifDateTime | ExifDate | ExifTime |
|
|
11
|
+
export type DateOrTime = ExifDateTime | ExifDate | ExifTime | DateTimeMaybeValid;
|
|
12
12
|
export declare function isDateOrTime(o: unknown): o is DateOrTime;
|
|
13
13
|
export declare function dateTimeToExif(d: DateTime, opts?: {
|
|
14
14
|
includeOffset?: boolean;
|
package/dist/DateTime.js
CHANGED
package/dist/DateTime.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DateTime.js","sourceRoot":"","sources":["../src/DateTime.ts"],"names":[],"mappings":";;;AAMA,sCAEC;
|
|
1
|
+
{"version":3,"file":"DateTime.js","sourceRoot":"","sources":["../src/DateTime.ts"],"names":[],"mappings":";;;AAMA,sCAEC;AAUD,oCAOC;AAED,wCASC;AAED,oCAMC;AAED,kBAOC;AArDD,iCAAqD;AACrD,yCAAsC;AACtC,iDAA8C;AAC9C,yCAAsC;AAGtC,SAAgB,aAAa,CAAC,EAAmB;IAC/C,OAAO,EAAE,EAAE,OAAO,KAAK,IAAI,CAAC;AAC9B,CAAC;AAEY,QAAA,QAAQ,GAAG,IAAI,CAAC;AAChB,QAAA,QAAQ,GAAG,EAAE,GAAG,gBAAQ,CAAC;AACzB,QAAA,MAAM,GAAG,EAAE,GAAG,gBAAQ,CAAC;AACvB,QAAA,KAAK,GAAG,EAAE,GAAG,cAAM,CAAC;AAKjC,SAAgB,YAAY,CAAC,CAAU;IACrC,OAAO,CACL,CAAC,YAAY,2BAAY;QACzB,CAAC,YAAY,mBAAQ;QACrB,CAAC,YAAY,mBAAQ;QACrB,gBAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,CACvB,CAAC;AACJ,CAAC;AAED,SAAgB,cAAc,CAC5B,CAAW,EACX,IAAiE;IAEjE,OAAO,CAAC,CAAC,QAAQ,CACf,kBAAkB;QAChB,CAAC,IAAI,EAAE,mBAAmB,KAAK,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,CAAC,IAAI,EAAE,aAAa,KAAK,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAC9C,CAAC;AACJ,CAAC;AAED,SAAgB,YAAY,CAAC,CAAa;IACxC,IAAI,gBAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3B,OAAO,cAAc,CAAC,CAAC,CAAC,CAAC;IAC3B,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,SAAgB,GAAG,CACjB,CAAW,EACX,IAAwC;IAExC,OAAO,CAAC,CAAC,QAAQ,CACf,UAAU,GAAG,CAAC,IAAI,EAAE,mBAAmB,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAChE,CAAC;AACJ,CAAC"}
|
package/dist/ExifTool.d.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { ExifToolTask, ExifToolTaskOptions } from "./ExifToolTask";
|
|
|
5
5
|
import { PreviewTag } from "./PreviewTag";
|
|
6
6
|
import { ReadRawTaskOptions } from "./ReadRawTask";
|
|
7
7
|
import { ReadTaskOptions } from "./ReadTask";
|
|
8
|
+
import { TagEdit } from "./TagEdit";
|
|
8
9
|
import { Tags } from "./Tags";
|
|
9
10
|
import { WriteTags } from "./WriteTags";
|
|
10
11
|
import { WriteTaskOptions, WriteTaskResult } from "./WriteTask";
|
|
@@ -44,6 +45,7 @@ export type { GeolocationTags } from "./GeolocationTags";
|
|
|
44
45
|
export type { ICCProfileTags } from "./ICCProfileTags";
|
|
45
46
|
export type { IPTCApplicationRecordTags as ApplicationRecordTags, IPTCApplicationRecordTags, } from "./IPTCApplicationRecordTags";
|
|
46
47
|
export type { ImageDataHashTag } from "./ImageDataHashTag";
|
|
48
|
+
export type { InvalidUtf8Bytes } from "./InvalidUtf8Bytes";
|
|
47
49
|
export type { Json, Literal } from "./JSON";
|
|
48
50
|
export type { CollectionInfo, KeywordInfoStruct, KeywordStruct, MWGCollectionsTags, MWGKeywordTags, } from "./MWGTags";
|
|
49
51
|
export type { Maybe, Nullable } from "./Maybe";
|
|
@@ -56,6 +58,8 @@ export type { UnsubscribeFunction } from "./Settings";
|
|
|
56
58
|
export type { ShortcutTags } from "./ShortcutTags";
|
|
57
59
|
export type { Struct } from "./Struct";
|
|
58
60
|
export type { TagDescription, TagDescriptionsOptions } from "./TagDescriptions";
|
|
61
|
+
export { CollectionEditTagName, RegionNameEditTagName, TagEditAddTagNames, TagEditRemoveOnlyTagNames, TagEditTagNames, TagEditValueTagNames, } from "./TagEdit";
|
|
62
|
+
export type { AddCollectionEdit, AddTagEdit, CollectionPredicate, RemoveCollectionEdit, RemoveTagEdit, TagEdit, TagEditAddTagName, TagEditRemoveOnlyTagName, TagEditTagName, TagEditValueTagName, } from "./TagEdit";
|
|
59
63
|
export type { APPTags, CompositeTags, EXIFTags, ExifToolTags, FileTags, FlashPixTags, IPTCTags, JFIFTags, MakerNotesTags, MetaTags, MPFTags, PanasonicRawTags, PhotoshopTags, PrintIMTags, QuickTimeTags, RAFTags, RIFFTags, Tags, XMPTags, } from "./Tags";
|
|
60
64
|
export type { Version } from "./Version";
|
|
61
65
|
export type { AdditionalWriteTags, EXIFStrictDateTags, ExpandedDateTags, GroupPrefixedTags, MutableTags, StructAppendTags, WritableGPSRefs, WriteTags, XMPPartialDateTags, } from "./WriteTags";
|
|
@@ -118,7 +122,9 @@ export declare class ExifTool {
|
|
|
118
122
|
* use `readRaw`.** Note that the default is `["-fast"]`, so if you want
|
|
119
123
|
* ExifTool to read the entire file for metadata, you should pass an empty
|
|
120
124
|
* array as the second parameter. See https://exiftool.org/#performance for
|
|
121
|
-
* more information about `-fast` and `-fast2`.
|
|
125
|
+
* more information about `-fast` and `-fast2`. The wrapper still adds its
|
|
126
|
+
* malformed UTF-8 repair/byte-capture filter unless these arguments provide
|
|
127
|
+
* a custom ExifTool `Filter`, in which case that filter owns both behaviors.
|
|
122
128
|
*
|
|
123
129
|
* @param options overrides to the default ExifTool options provided to the
|
|
124
130
|
* ExifTool constructor.
|
|
@@ -145,9 +151,12 @@ export declare class ExifTool {
|
|
|
145
151
|
* worse if you don't include `-fast` or `-fast2` (as the most expensive bits
|
|
146
152
|
* are the perl interpreter and scanning the file on disk).
|
|
147
153
|
*
|
|
148
|
-
* @param options any additional
|
|
149
|
-
*
|
|
150
|
-
* filename=utf8
|
|
154
|
+
* @param options read options, including any additional `readArgs` other than
|
|
155
|
+
* the file path. `-json`, the Windows Unicode filename handler flags,
|
|
156
|
+
* `-charset filename=utf8`, malformed UTF-8 repair with U+FFFD, and original
|
|
157
|
+
* malformed-string byte capture in `invalidUtf8Bytes` are added
|
|
158
|
+
* automatically. An explicit custom ExifTool `Filter` in `readArgs` replaces
|
|
159
|
+
* the wrapper's filter and owns both repair and byte capture.
|
|
151
160
|
*
|
|
152
161
|
* @return Note that the return value will be similar to `Tags`, but with no
|
|
153
162
|
* date, time, or other rich type parsing that you get from `.read()`. The
|
|
@@ -210,6 +219,33 @@ export declare class ExifTool {
|
|
|
210
219
|
* instead: move `writeArgs` into your `options` hash.
|
|
211
220
|
*/
|
|
212
221
|
write(file: string, tags: WriteTags, writeArgs?: string[], options?: WriteTaskOptions): Promise<WriteTaskResult>;
|
|
222
|
+
/**
|
|
223
|
+
* Add or remove individual metadata values without replacing unrelated list
|
|
224
|
+
* items. Arguments are emitted in the provided order in one non-retriable
|
|
225
|
+
* ExifTool write command, but ExifTool applies removals before additions for
|
|
226
|
+
* the same tag.
|
|
227
|
+
*
|
|
228
|
+
* Tag names must be entries in {@link TagEditTagNames}. The primitive subset
|
|
229
|
+
* is {@link TagEditValueTagNames}; {@link TagEditAddTagNames} and
|
|
230
|
+
* {@link TagEditRemoveOnlyTagNames} distinguish add-capable lists from
|
|
231
|
+
* audited scalar and flattened structure fields. Structured values and
|
|
232
|
+
* predicates are supported only for the closed schemas explicitly typed by
|
|
233
|
+
* {@link TagEdit}. Each primitive operation accepts one non-empty, exactly
|
|
234
|
+
* preservable string value; repeat operations to preserve duplicate
|
|
235
|
+
* additions. A remove operation deletes every exact matching value. Values
|
|
236
|
+
* are literal text and HTML entity sequences are not decoded, unlike the
|
|
237
|
+
* legacy behavior of {@link ExifTool.write}.
|
|
238
|
+
*
|
|
239
|
+
* This API does not set, clear, or force-write empty tags. Continue using
|
|
240
|
+
* {@link ExifTool.write} for whole-tag writes and deletion with `null`.
|
|
241
|
+
*
|
|
242
|
+
* @param file an existing file or writable sidecar path
|
|
243
|
+
* @param edits one or more ordered add/remove operations
|
|
244
|
+
* @param options overrides to the configured write-task options. `-api` and
|
|
245
|
+
* `-sep`/`-separator` write arguments are rejected because they can alter
|
|
246
|
+
* edit semantics.
|
|
247
|
+
*/
|
|
248
|
+
editTags(file: string, edits: readonly TagEdit[], options?: WriteTaskOptions): Promise<WriteTaskResult>;
|
|
213
249
|
/**
|
|
214
250
|
* This will strip `file` of all metadata tags. The original file (with the
|
|
215
251
|
* name `${FILENAME}_original`) will be retained. Note that some tags, like
|
|
@@ -371,8 +407,8 @@ export declare class ExifTool {
|
|
|
371
407
|
* This allows ExifTool instances to be automatically cleaned up when they go out of scope.
|
|
372
408
|
*
|
|
373
409
|
* Note: This is a synchronous disposal method that initiates graceful cleanup but doesn't
|
|
374
|
-
* wait for completion. If graceful cleanup times out, forceful cleanup is
|
|
375
|
-
*
|
|
410
|
+
* wait for completion. If graceful cleanup times out, forceful cleanup is requested.
|
|
411
|
+
* Use `await using` when the caller must wait for the cleanup attempt to settle.
|
|
376
412
|
*
|
|
377
413
|
* @example
|
|
378
414
|
* ```typescript
|
|
@@ -388,8 +424,9 @@ export declare class ExifTool {
|
|
|
388
424
|
* Implements the AsyncDisposable interface for automatic async cleanup with the `await using` keyword.
|
|
389
425
|
* This allows ExifTool instances to be automatically cleaned up when they go out of scope.
|
|
390
426
|
*
|
|
391
|
-
* This method
|
|
392
|
-
*
|
|
427
|
+
* This method waits for graceful cleanup. If the configured timeout elapses,
|
|
428
|
+
* forceful cleanup is requested. Cleanup is best-effort and the timeout is not
|
|
429
|
+
* a hard completion deadline.
|
|
393
430
|
*
|
|
394
431
|
* @example
|
|
395
432
|
* ```typescript
|
|
@@ -83,7 +83,7 @@ describe("ExifTool disposal", () => {
|
|
|
83
83
|
await et[Symbol.asyncDispose]();
|
|
84
84
|
(0, chai_1.expect)(et.ended).to.be.true;
|
|
85
85
|
});
|
|
86
|
-
it("should
|
|
86
|
+
it("should request forceful cleanup after an async disposal timeout", async () => {
|
|
87
87
|
const et = new ExifTool_1.ExifTool();
|
|
88
88
|
// Mock a slow .end() method by stubbing it
|
|
89
89
|
const originalEnd = et.end.bind(et);
|
|
@@ -98,11 +98,11 @@ describe("ExifTool disposal", () => {
|
|
|
98
98
|
}
|
|
99
99
|
else {
|
|
100
100
|
forcefulEndCalled = true;
|
|
101
|
-
//
|
|
101
|
+
// Model a forceful cleanup request that settles quickly
|
|
102
102
|
return originalEnd(false);
|
|
103
103
|
}
|
|
104
104
|
};
|
|
105
|
-
// The async
|
|
105
|
+
// The async disposer should request forceful cleanup after its timeout
|
|
106
106
|
await et[Symbol.asyncDispose]();
|
|
107
107
|
(0, chai_1.expect)(endCalled).to.be.true;
|
|
108
108
|
(0, chai_1.expect)(forcefulEndCalled).to.be.true;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ExifTool.dispose.spec.js","sourceRoot":"","sources":["../src/ExifTool.dispose.spec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+BAA8B;AAC9B,yCAAsC;AAEtC,QAAQ,CAAC,mBAAmB,EAAE,GAAG,EAAE;IACjC,EAAE,CAAC,+BAA+B,EAAE,GAAG,EAAE;QACvC,MAAM,EAAE,GAAG,IAAI,mBAAQ,EAAE,CAAC;QAC1B,IAAA,aAAM,EAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACjD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,EAAE,GAAG,IAAI,mBAAQ,EAAE,CAAC;QAC1B,IAAA,aAAM,EAAC,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;IACtD,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+CAA+C,EAAE,GAAG,EAAE;QACvD,MAAM,EAAE,GAAG,IAAI,mBAAQ,EAAE,CAAC;QAC1B,IAAA,aAAM,EAAC,GAAG,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAClD,6EAA6E;QAC7E,wDAAwD;QACxD,IAAA,aAAM,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,+BAA+B,EAAE,KAAK,IAAI,EAAE;QAC7C,MAAM,EAAE,GAAG,IAAI,mBAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,IAAA,aAAM,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sBAAsB,EAAE,KAAK,IAAI,EAAE;QACpC,MAAM,EAAE,GAAG,IAAI,mBAAQ,EAAE,CAAC;QAC1B,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,IAAA,aAAM,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;QAC5B,kCAAkC;QAClC,MAAM,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC;QAChC,IAAA,aAAM,EAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC;IAC9B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,
|
|
1
|
+
{"version":3,"file":"ExifTool.dispose.spec.js","sourceRoot":"","sources":["../src/ExifTool.dispose.spec.ts"],"names":[],"mappings":"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"}
|