New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

exiftool-vendored

Package Overview
Dependencies
Maintainers
1
Versions
252
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

exiftool-vendored - npm Package Compare versions

Comparing version 23.1.0 to 23.2.0

dist/DefaultCreateDateTagNames.d.ts

14

CHANGELOG.md

@@ -29,2 +29,15 @@ # Changelog/Versioning

### v23.2.0
- ✨ Timezone parsing improvements:
- Added [`ExifToolOptions.inferTimezoneFromDatestampTags`](https://photostructure.github.io/exiftool-vendored.js/interfaces/ExifToolOptions.html#inferTimezoneFromDatestampTags).
- Timezone inference from datestamps now skips over UTC values, as Google
Takeout (and several other applications) may spuriously set "+00:00" to
datestamps.
- ReadTask.parse in prior versions had to scan all tags twice to set the
timezone. Code was refactored to do this in a single pass.
- Timezone extraction and normalization was improved.
- 📦 Add `creationDate` to [CapturedAtTagNames](https://photostructure.github.io/exiftool-vendored.js/variables/CapturedAtTagNames.html). [See PR#159](https://github.com/photostructure/exiftool-vendored.js/pull/159).
### v23.1.0

@@ -36,3 +49,2 @@

#157](https://github.com/photostructure/exiftool-vendored.js/issues/157).
- 📦 `ExifDateTime`, `ExifTime`, and `ExifDate` are now [only allowed to try

@@ -39,0 +51,0 @@ to parse keys that includes `date` or

2

dist/CapturedAtTagNames.d.ts

@@ -1,1 +0,1 @@

export declare const CapturedAtTagNames: readonly ["SubSecDateTimeOriginal", "DateTimeOriginal", "SubSecCreateDate", "CreateDate", "SubSecMediaCreateDate", "MediaCreateDate", "DateTimeCreated"];
export declare const CapturedAtTagNames: readonly ["SubSecDateTimeOriginal", "SubSecCreateDate", "SubSecMediaCreateDate", "DateTimeOriginal", "CreateDate", "MediaCreateDate", "CreationDate", "DateTimeCreated", "TimeCreated"];

@@ -6,9 +6,11 @@ "use strict";

"SubSecDateTimeOriginal",
"SubSecCreateDate",
"SubSecMediaCreateDate",
"DateTimeOriginal",
"SubSecCreateDate",
"CreateDate",
"SubSecMediaCreateDate",
"MediaCreateDate",
"CreationDate",
"DateTimeCreated",
"TimeCreated", // < may not have the date
];
//# sourceMappingURL=CapturedAtTagNames.js.map

@@ -28,2 +28,3 @@ "use strict";

const bc = __importStar(require("batch-cluster"));
const CapturedAtTagNames_1 = require("./CapturedAtTagNames");
const DefaultExiftoolArgs_1 = require("./DefaultExiftoolArgs");

@@ -73,2 +74,3 @@ const DefaultMaxProcs_1 = require("./DefaultMaxProcs");

inferTimezoneFromDatestamps: false,
inferTimezoneFromDatestampTags: [...CapturedAtTagNames_1.CapturedAtTagNames],
geoTz: GeoTz_1.geoTz,

@@ -75,0 +77,0 @@ isIgnorableError: IgnorableError_1.isIgnorableWarning,

@@ -112,5 +112,5 @@ "use strict";

}, _ExifTime_shortZone = function _ExifTime_shortZone() {
var _a, _b, _c;
return (__classPrivateFieldSet(this, _ExifTime_z, (_a = __classPrivateFieldGet(this, _ExifTime_z, "f")) !== null && _a !== void 0 ? _a : ((_c = (_b = (0, Timezones_1.normalizeZone)(this.zone)) === null || _b === void 0 ? void 0 : _b.formatOffset(Date.now(), "short")) !== null && _c !== void 0 ? _c : ""), "f"));
var _a;
return (__classPrivateFieldSet(this, _ExifTime_z, (_a = __classPrivateFieldGet(this, _ExifTime_z, "f")) !== null && _a !== void 0 ? _a : (0, Timezones_1.zoneToShortOffset)(this.zone), "f"));
};
//# sourceMappingURL=ExifTime.js.map

@@ -22,2 +22,3 @@ /// <reference types="node" />

export { BinaryField } from "./BinaryField";
export { CapturedAtTagNames } from "./CapturedAtTagNames";
export { DefaultExifToolOptions } from "./DefaultExifToolOptions";

@@ -69,6 +70,6 @@ export { DefaultExiftoolArgs } from "./DefaultExiftoolArgs";

/**
* Manages delegating calls to a vendored running instance of ExifTool.
* Manages delegating calls to a cluster of ExifTool child processes.
*
* Instances should be shared: consider using the exported singleton
* instance of this class, `exiftool`.
* Instances should be shared: consider using the exported singleton instance
* of this class, {@link exiftool}.
*/

@@ -291,12 +292,18 @@ export declare class ExifTool {

/**
* Use this singleton rather than instantiating new ExifTool instances in order
* to leverage a single running ExifTool process. As of v3.0, its `maxProcs` is
* set to the number of CPUs on the current system; no more than `maxProcs`
* instances of `exiftool` will be spawned. You may want to experiment with
* smaller or larger values for `maxProcs`, depending on CPU and disk speed of
* your system and performance tradeoffs.
* Use this singleton rather than instantiating new {@link ExifTool} instances
* in order to leverage a single running ExifTool process.
*
* As of v3.0, its {@link ExifToolOptions.maxProcs} is set to the number of
* CPUs on the current system; no more than `maxProcs` instances of `exiftool`
* will be spawned. You may want to experiment with smaller or larger values
* for `maxProcs`, depending on CPU and disk speed of your system and
* performance tradeoffs.
*
* Note that each child process consumes between 10 and 50 MB of RAM. If you
* have limited system resources you may want to use a smaller `maxProcs` value.
* have limited system resources you may want to use a smaller `maxProcs`
* value.
*
* See the source of {@link DefaultExifToolOptions} for more details about how
* this instance is configured.
*/
export declare const exiftool: ExifTool;

@@ -35,3 +35,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.exiftool = exports.ExifTool = exports.DefaultWriteTaskOptions = exports.offsetMinutesToZoneName = exports.defaultVideosToUTC = exports.UnsetZoneOffsetMinutes = exports.UnsetZoneName = exports.UnsetZone = exports.DefaultReadTaskOptions = exports.parseJSON = exports.isIgnorableWarning = exports.ExifToolTask = exports.ExifTime = exports.ExifDateTime = exports.ExifDate = exports.DefaultMaxProcs = exports.DefaultExiftoolArgs = exports.DefaultExifToolOptions = exports.BinaryField = void 0;
exports.exiftool = exports.ExifTool = exports.DefaultWriteTaskOptions = exports.offsetMinutesToZoneName = exports.defaultVideosToUTC = exports.UnsetZoneOffsetMinutes = exports.UnsetZoneName = exports.UnsetZone = exports.DefaultReadTaskOptions = exports.parseJSON = exports.isIgnorableWarning = exports.ExifToolTask = exports.ExifTime = exports.ExifDateTime = exports.ExifDate = exports.DefaultMaxProcs = exports.DefaultExiftoolArgs = exports.DefaultExifToolOptions = exports.CapturedAtTagNames = exports.BinaryField = void 0;
const bc = __importStar(require("batch-cluster"));

@@ -59,2 +59,4 @@ const _cp = __importStar(require("child_process"));

Object.defineProperty(exports, "BinaryField", { enumerable: true, get: function () { return BinaryField_1.BinaryField; } });
var CapturedAtTagNames_1 = require("./CapturedAtTagNames");
Object.defineProperty(exports, "CapturedAtTagNames", { enumerable: true, get: function () { return CapturedAtTagNames_1.CapturedAtTagNames; } });
var DefaultExifToolOptions_2 = require("./DefaultExifToolOptions");

@@ -90,6 +92,6 @@ Object.defineProperty(exports, "DefaultExifToolOptions", { enumerable: true, get: function () { return DefaultExifToolOptions_2.DefaultExifToolOptions; } });

/**
* Manages delegating calls to a vendored running instance of ExifTool.
* Manages delegating calls to a cluster of ExifTool child processes.
*
* Instances should be shared: consider using the exported singleton
* instance of this class, `exiftool`.
* Instances should be shared: consider using the exported singleton instance
* of this class, {@link exiftool}.
*/

@@ -409,13 +411,19 @@ class ExifTool {

/**
* Use this singleton rather than instantiating new ExifTool instances in order
* to leverage a single running ExifTool process. As of v3.0, its `maxProcs` is
* set to the number of CPUs on the current system; no more than `maxProcs`
* instances of `exiftool` will be spawned. You may want to experiment with
* smaller or larger values for `maxProcs`, depending on CPU and disk speed of
* your system and performance tradeoffs.
* Use this singleton rather than instantiating new {@link ExifTool} instances
* in order to leverage a single running ExifTool process.
*
* As of v3.0, its {@link ExifToolOptions.maxProcs} is set to the number of
* CPUs on the current system; no more than `maxProcs` instances of `exiftool`
* will be spawned. You may want to experiment with smaller or larger values
* for `maxProcs`, depending on CPU and disk speed of your system and
* performance tradeoffs.
*
* Note that each child process consumes between 10 and 50 MB of RAM. If you
* have limited system resources you may want to use a smaller `maxProcs` value.
* have limited system resources you may want to use a smaller `maxProcs`
* value.
*
* See the source of {@link DefaultExifToolOptions} for more details about how
* this instance is configured.
*/
exports.exiftool = new ExifTool();
//# sourceMappingURL=ExifTool.js.map

@@ -5,2 +5,8 @@ /// <reference types="node" />

import { IgnorableError } from "./IgnorableError";
import { Tags } from "./Tags";
/**
* Options for the {@link ExifTool} constructor.
*
* Defaults are defined in {@link DefaultExifToolOptions}.
*/
export interface ExifToolOptions extends bc.BatchClusterOptions, bc.BatchProcessOptions, bc.ChildProcessFactory {

@@ -14,4 +20,4 @@ /**

/**
* The maximum number of requests a given ExifTool process will service before
* being retired.
* The maximum number of requests a given ExifTool process will service
* before being retired.
*

@@ -23,6 +29,6 @@ * Defaults to 500, to balance performance with memory usage.

* Spawning new ExifTool processes must not take longer than
* `spawnTimeoutMillis` millis before it times out and a new attempt is made.
* Be pessimistic here--windows can regularly take several seconds to spin up
* a process, thanks to antivirus shenanigans. This can't be set to a value
* less than 100ms.
* {@link spawnTimeoutMillis} milliseconds before the child process is timed
* out and a new attempt is made. Be pessimistic here--windows can regularly
* take several seconds to spin up a process, thanks to antivirus
* shenanigans. This can't be set to a value less than 100ms.
*

@@ -33,7 +39,7 @@ * Defaults to 30 seconds, to accommodate slow Windows machines.

/**
* If requests to ExifTool take longer than this,
* presume the underlying process is dead and we should restart the task. This
* can't be set to a value less than 10ms, and really should be set to at more
* than a second unless `taskRetries` is sufficiently large or all writes will
* be to a fast local disk. Defaults to 10 seconds.
* If requests to ExifTool take longer than this, presume the underlying
* process is dead and we should restart the task. This can't be set to a
* value less than 10ms, and really should be set to at more than a second
* unless `taskRetries` is sufficiently large or all writes will be to a
* fast local disk. Defaults to 10 seconds.
*/

@@ -55,4 +61,5 @@ taskTimeoutMillis: number;

/**
* Allows for non-standard paths to ExifTool. Defaults to the perl or windows
* binaries provided by `exiftool-vendored.pl` or `exiftool-vendored.exe`.
* Allows for non-standard paths to ExifTool. Defaults to the perl or
* windows binaries provided by `exiftool-vendored.pl` or
* `exiftool-vendored.exe`.
*/

@@ -72,3 +79,4 @@ exiftoolPath: string;

*
* ExifTool recommends this to be set to true.
* ExifTool recommends this to be set to true. This defaults to `false` to
* maintain consistency with prior versions.
*

@@ -89,4 +97,5 @@ * Note that this can result in many tag value differences from

*
* The default includes "*Duration*", "GPSAltitude", "GPSLatitude",
* "GPSLongitude", "GPSPosition", and "Orientation".
* The default includes "*Duration*", {@link Tags.GPSAltitude},
* {@link Tags.GPSLatitude}, {@link Tags.GPSLongitude},
* {@link Tags.GPSPosition}, and {@link Tags.Orientation}.
*/

@@ -118,10 +127,11 @@ numericTags: string[];

* Should we try to backfill timezones for date-times that don't have them?
* If set to `true`, and `defaultVideosToUTC` is also `true`, we'll try
* backfilling timezones for date-times that are UTC, as well.
* If set to `true`, and {@link defaultVideosToUTC} is also `true`, we'll
* try backfilling timezones for date-times that are UTC, as well.
*
* Setting this to `false` removes **all** timezone inference--only those
* date-times with an explicit offset will have a defined timezone. Prior
* versions of exiftool-vendored would use the file's `.tz` as a backstop
* even if this was set to `false`.
* date-times with an explicit offset will have a defined timezone.
*
* Prior versions of exiftool-vendored would use the file's `.tz` as a
* backstop even if this was set to `false`.
*
* As of version 23, this now defaults to `true`, as it's more likely to be

@@ -132,8 +142,9 @@ * what people expect.

/**
* We always look at TimeZone, OffsetTime, TimeZoneOffset, and GPS metadata
* to infer the timezone.
* We always look at {@link Tags.TimeZone}, {@link Tags.OffsetTime},
* {@link Tags.TimeZoneOffset}, {@link Tags.OffsetTimeOriginal},
* {@link Tags.OffsetTimeDigitized}, and GPS metadata to infer the timezone.
*
* If these strategies fail, can we infer a timezone from any non-UTC
* datestamp whose tag starts with "Creat" and includes an offset? (This
* means CreateDateSubSec, CreateDate, and CreationDate will be considered).
* If these strategies fail, and this is enabled, we'll try to infer the
* timezone from non-UTC datestamps included in the
* {@link inferTimezoneFromDatestampTags} value.
*

@@ -145,2 +156,14 @@ * This defaults to false as it both retains prior behavior and means fewer

/**
* This is the list of tag names that will be used to infer the timezone as
* a backstop, if no explicit timezone is found in metadata. Note that
* datestamps with UTC offsets are ignored, as they are frequently
* incorrectly set.
*
* This setting is only in play if {@link inferTimezoneFromDatestamps} has
* been overridden to be `true`.
*
* This defaults to {@link CapturedAtTagNames}
*/
inferTimezoneFromDatestampTags: (keyof Tags)[];
/**
* `ExifTool` has a shebang line that assumes a valid `perl` is installed at

@@ -147,0 +170,0 @@ * `/usr/bin/perl`.

export type Maybe<T> = T | undefined;
export type MaybeNull<T> = Maybe<T> | null;
export declare function map<T, U>(maybeT: MaybeNull<T>, f: (t: T) => U): Maybe<U>;
export declare function map2<A, B, U>(a: MaybeNull<A>, b: MaybeNull<B>, f: (a: A, b: B) => U): Maybe<U>;
export declare function first<T, U>(iter: Iterable<Maybe<T>>, f: (t: T) => Maybe<U>): Maybe<U>;

@@ -5,0 +6,0 @@ export declare function firstDefinedThunk<T>(iter: Iterable<() => Maybe<T>>): Maybe<T>;

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.denull = exports.firstDefinedThunk = exports.first = exports.map = void 0;
exports.denull = exports.firstDefinedThunk = exports.first = exports.map2 = exports.map = void 0;
function map(maybeT, f) {

@@ -8,2 +8,6 @@ return maybeT == null ? undefined : f(maybeT);

exports.map = map;
function map2(a, b, f) {
return a == null || b == null ? undefined : f(a, b);
}
exports.map2 = map2;
function first(iter, f) {

@@ -10,0 +14,0 @@ for (const t of iter) {

@@ -12,2 +12,3 @@ import { ExifToolTask } from "./ExifToolTask";

readonly inferTimezoneFromDatestamps: boolean;
readonly inferTimezoneFromDatestampTags: (keyof Tags)[];
readonly geoTz: typeof import("./GeoTz").geoTz;

@@ -14,0 +15,0 @@ readonly optionalArgs: string[];

@@ -30,3 +30,3 @@ "use strict";

};
var _ReadTask_instances, _ReadTask_isVideo, _ReadTask_defaultToUTC, _ReadTask_tagName, _ReadTask_maybeSetZone, _ReadTask_parseTags, _ReadTask_extractLatLon, _ReadTask_latlon, _ReadTask_geoTz, _ReadTask_extractTzOffset, _ReadTask_parseTag;
var _ReadTask_instances, _ReadTask_isVideo, _ReadTask_defaultToUTC, _ReadTask_tagName, _ReadTask_parseTags, _ReadTask_extractLatLon, _ReadTask_latlon, _ReadTask_geoTz, _ReadTask_extractTzOffset, _ReadTask_parseTag;
Object.defineProperty(exports, "__esModule", { value: true });

@@ -45,3 +45,2 @@ exports.ReadTask = exports.DefaultReadTaskOptions = exports.nullish = void 0;

const FilenameCharsetArgs_1 = require("./FilenameCharsetArgs");
const FirstDateTime_1 = require("./FirstDateTime");
const Lazy_1 = require("./Lazy");

@@ -71,3 +70,3 @@ const Maybe_1 = require("./Maybe");

optionalArgs: [],
...(0, Pick_1.pick)(DefaultExifToolOptions_1.DefaultExifToolOptions, "numericTags", "useMWG", "includeImageDataMD5", "imageHashType", "defaultVideosToUTC", "backfillTimezones", "inferTimezoneFromDatestamps", "geoTz"),
...(0, Pick_1.pick)(DefaultExifToolOptions_1.DefaultExifToolOptions, "numericTags", "useMWG", "includeImageDataMD5", "imageHashType", "defaultVideosToUTC", "backfillTimezones", "inferTimezoneFromDatestamps", "inferTimezoneFromDatestampTags", "geoTz"),
};

@@ -186,16 +185,3 @@ const MaybeDateOrTimeRe = /when|date|time|subsec|creat|modif/i;

return this.degroup ? (_a = k.split(":")[1]) !== null && _a !== void 0 ? _a : k : k;
}, _ReadTask_maybeSetZone = function _ReadTask_maybeSetZone(edt, candidates) {
if (!edt.inferredZone && edt.hasZone)
return edt;
if (this.tz != null)
return edt.setZone(this.tz);
for (const src of candidates) {
const result = edt.maybeMatchZone(src);
if (result != null) {
return result;
}
}
return;
}, _ReadTask_parseTags = function _ReadTask_parseTags() {
var _a;
__classPrivateFieldGet(this, _ReadTask_extractLatLon, "f").call(this);

@@ -207,39 +193,8 @@ __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_extractTzOffset).call(this);

const tags = this.tags;
const datesWithTz = [];
// two passes: one to parse dates, and the next to possibly set timezones.
for (const [key, value] of Object.entries(this._raw)) {
const k = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_tagName).call(this, key);
const v = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_parseTag).call(this, k, value);
if (v instanceof ExifDateTime_1.ExifDateTime &&
// Don't backfill from `stat()` dates, as they may include the system
// zone:
!key.startsWith("File") &&
v.hasZone &&
// Don't backfill from inferred zones:
v.inferredZone !== true &&
// Don't backfill from UTC tags:
!isUtcTagName(key)) {
datesWithTz.push(v);
}
// Note that we set `key` (which may include a group prefix):
tags[key] = v;
}
if (this.options.backfillTimezones === true) {
// prefer non-UTC offsets (UTC may be incorrect):
const candidates = (0, Array_1.sortBy)(datesWithTz, (ea) => { var _a; return -Math.abs((_a = ea.tzoffsetMinutes) !== null && _a !== void 0 ? _a : 0); });
for (const [key, value] of Object.entries(tags)) {
if (
// we don't backfill ExifTime zones, as we don't know for sure what
// day they are for, and if the zone isn't fixed, that would be an
// issue. (We _could_ set ExifTime zones if we knew the zone was
// fixed, but that's a later, low-priority TODO).
value instanceof ExifDateTime_1.ExifDateTime &&
// Don't backfill dates from `stat`:
!key.startsWith("File") &&
// Don't backfill UTC tags:
!isUtcTagName(key)) {
tags[key] = (_a = __classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_maybeSetZone).call(this, value, candidates)) !== null && _a !== void 0 ? _a : value;
}
}
}
if (this.errors.length > 0)

@@ -276,28 +231,3 @@ this.tags.errors = this.errors;

// before defaulting to UTC for videos:
() => {
const tz = (0, Timezones_1.extractTzOffsetFromTags)(this._rawDegrouped, this.options);
// If this tz offset matches the GPS zone, use the GPS zone name (like "America/Los_Angeles") instead of the offset.
const z = (0, Timezones_1.normalizeZone)(tz === null || tz === void 0 ? void 0 : tz.tz);
if (tz != null && z != null) {
const geoTz = __classPrivateFieldGet(this, _ReadTask_geoTz, "f").call(this);
if (geoTz != null) {
const edt = (0, FirstDateTime_1.firstDateTime)(this._rawDegrouped);
if (edt != null) {
const ts = edt.toMillis();
const zOffset = z.offset(ts);
const geoTzOffset = geoTz.offset(ts);
if (zOffset === geoTzOffset) {
return {
tz: geoTz.name,
src: tz.src + " & GPSLatitude/GPSLongitude",
};
}
}
}
}
// nope, no GPS, just use the minutes-offset zone format:
return tz;
},
// If lat/lon is valid, use the tzlookup library, as it will be a proper
// Zone name (like "America/New_York"), rather than just an hour offset.
() => (0, Timezones_1.extractTzOffsetFromTags)(this._rawDegrouped),
() => (0, Maybe_1.map)(__classPrivateFieldGet(this, _ReadTask_geoTz, "f").call(this), (ea) => ({

@@ -307,2 +237,3 @@ tz: ea.name,

})),
() => (0, Timezones_1.extractTzOffsetFromDatestamps)(this._rawDegrouped, this.options),
// See https://github.com/photostructure/exiftool-vendored.js/issues/113

@@ -365,5 +296,15 @@ // and https://github.com/photostructure/exiftool-vendored.js/issues/156

const keyIncludesDate = /date/i.test(tagName);
return ((_c = (_b = (_a = (keyIncludesTime || keyIncludesDate
const result = (_c = (_b = (_a = (keyIncludesTime || keyIncludesDate
? ExifDateTime_1.ExifDateTime.from(value, tz)
: undefined)) !== null && _a !== void 0 ? _a : (keyIncludesTime ? ExifTime_1.ExifTime.fromEXIF(value) : undefined)) !== null && _b !== void 0 ? _b : (keyIncludesDate ? ExifDate_1.ExifDate.from(value) : undefined)) !== null && _c !== void 0 ? _c : value);
: undefined)) !== null && _a !== void 0 ? _a : (keyIncludesTime ? ExifTime_1.ExifTime.fromEXIF(value) : undefined)) !== null && _b !== void 0 ? _b : (keyIncludesDate ? ExifDate_1.ExifDate.from(value) : undefined)) !== null && _c !== void 0 ? _c : value;
if (this.options.backfillTimezones &&
result != null &&
this.tz != null &&
result instanceof ExifDateTime_1.ExifDateTime &&
__classPrivateFieldGet(this, _ReadTask_instances, "m", _ReadTask_defaultToUTC).call(this) &&
!isUtcTagName(tagName) &&
true === result.inferredZone) {
return result.setZone(this.tz);
}
return result;
}

@@ -370,0 +311,0 @@ }

@@ -14,1 +14,2 @@ import { ExifDate } from "./ExifDate";

}
export declare function isResourceEvent(obj: any): obj is ResourceEvent;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isResourceEvent = void 0;
const fields = [
"Action",
"Changed",
"InstanceID",
"Parameters",
"SoftwareAgent",
"When",
];
function isResourceEvent(obj) {
return obj != null && typeof obj === "object" && fields.every((f) => f in obj);
}
exports.isResourceEvent = isResourceEvent;
//# sourceMappingURL=ResourceEvent.js.map

@@ -6,4 +6,5 @@ "use strict";

function isStruct(o) {
var _a;
return (o != null &&
!Array.isArray(o) &&
((_a = o.constructor) === null || _a === void 0 ? void 0 : _a.name) === "Object" &&
Object.values(o).every((v) => {

@@ -10,0 +11,0 @@ const t = typeof v;

@@ -16,2 +16,3 @@ "use strict";

var _a;
const inferredZone = (0, String_1.notBlank)(args.defaultZone);
for (const prefix of (_a = args.formatPrefixes) !== null && _a !== void 0 ? _a : [""]) {

@@ -23,3 +24,3 @@ for (const timeFmt of TimeFmts) {

unsetMilliseconds: timeFmt.unsetMilliseconds,
inferredZone: true,
inferredZone,
};

@@ -26,0 +27,0 @@ }

import { Zone } from "luxon";
import { ExifDateTime } from "./ExifDateTime";
import { ExifTime } from "./ExifTime";
import { CapturedAtTagNames } from "./CapturedAtTagNames";
import { ExifToolOptions } from "./ExifToolOptions";

@@ -22,2 +21,4 @@ import { Maybe } from "./Maybe";

export declare const UnsetZoneName: string;
export declare function isUTC(zone: Maybe<Zone | string | number>): boolean;
export declare function isZoneValid(zone: Maybe<Zone>): zone is Zone;
/**

@@ -29,3 +30,13 @@ * If `tzSource` matches this value, the tags are from a video, and we had to

export declare const defaultVideosToUTC = "defaultVideosToUTC";
export declare function normalizeZone(z: Maybe<string | number | Zone>): Maybe<Zone>;
/**
* @param input must be either a number, which is the offset in minutes, or a
* string in the format "UTC+H" or "UTC+HH:mm"
*/
export declare function normalizeZone(input: Maybe<string | number | Zone>): Maybe<Zone>;
/**
* @param ts must be provided if the zone is not a fixed offset
* @return the zone offset (in "±HH:MM" format) for the given zone, or "" if
* the zone is invalid
*/
export declare function zoneToShortOffset(zone: Maybe<string | number | Zone>, ts?: number): string;
export declare function validTzOffsetMinutes(tzOffsetMinutes: Maybe<number>): tzOffsetMinutes is number;

@@ -48,23 +59,9 @@ /**

*/
export declare function extractZone(value: Maybe<string | number | number[] | ExifDateTime | ExifTime>, opts?: {
export declare function extractZone(value: Tags[keyof Tags], opts?: {
stripTZA?: boolean;
}): Maybe<TzSrc>;
declare const TimezoneOffsetTagnames: readonly ["TimeZone", "OffsetTime", "OffsetTimeOriginal", "OffsetTimeDigitized", "TimeZoneOffset"];
declare const CreateDateTagnames: readonly ["SubSecCreateDate", "CreateDate", "SubSecDateTimeOriginal", "DateTimeOriginal", "SubSecMediaCreateDate", "MediaCreateDate", "CreationDate", "TimeCreated"];
export declare function extractTzOffsetFromTags(t: Pick<Tags, (typeof TimezoneOffsetTagnames)[number] | (typeof CreateDateTagnames)[number]>, opts?: Partial<Pick<ExifToolOptions, "inferTimezoneFromDatestamps">>): Maybe<TzSrc>;
export declare function extractTzOffsetFromTags(t: Tags): Maybe<TzSrc>;
export declare function extractTzOffsetFromDatestamps(t: Tags, opts: Partial<Pick<ExifToolOptions, "inferTimezoneFromDatestamps" | "inferTimezoneFromDatestampTags">>): Maybe<TzSrc>;
export declare function inferLikelyOffsetMinutes(deltaMinutes: number): number;
export declare function extractTzOffsetFromUTCOffset(t: {
DateTimeUTC?: string;
GPSDateTime?: string;
GPSDateStamp?: string;
GPSTimeStamp?: string;
GPSDateTimeStamp?: string;
SubSecDateTimeOriginal?: string;
DateTimeOriginal?: string;
SubSecCreateDate?: string;
CreateDate?: string;
SubSecMediaCreateDate?: string;
MediaCreateDate?: string;
DateTimeCreated?: string;
}): Maybe<TzSrc>;
export declare function extractTzOffsetFromUTCOffset(t: Pick<Tags, (typeof CapturedAtTagNames)[number] | "GPSDateTime" | "DateTimeUTC" | "GPSDateStamp" | "GPSTimeStamp">): Maybe<TzSrc>;
export declare function equivalentZones(a: Maybe<string | number | Zone>, b: Maybe<string | number | Zone>): boolean;

@@ -71,0 +68,0 @@ export declare function getZoneName(args?: {

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getZoneName = exports.equivalentZones = exports.extractTzOffsetFromUTCOffset = exports.inferLikelyOffsetMinutes = exports.extractTzOffsetFromTags = exports.extractZone = exports.offsetMinutesToZoneName = exports.validTzOffsetMinutes = exports.normalizeZone = exports.defaultVideosToUTC = exports.UnsetZoneName = exports.UnsetZone = exports.UnsetZoneOffsetMinutes = void 0;
exports.getZoneName = exports.equivalentZones = exports.extractTzOffsetFromUTCOffset = exports.inferLikelyOffsetMinutes = exports.extractTzOffsetFromDatestamps = exports.extractTzOffsetFromTags = exports.extractZone = exports.offsetMinutesToZoneName = exports.validTzOffsetMinutes = exports.zoneToShortOffset = exports.normalizeZone = exports.defaultVideosToUTC = exports.isZoneValid = exports.isUTC = exports.UnsetZoneName = exports.UnsetZone = exports.UnsetZoneOffsetMinutes = void 0;
const luxon_1 = require("luxon");
const Array_1 = require("./Array");
const BinaryField_1 = require("./BinaryField");
const CapturedAtTagNames_1 = require("./CapturedAtTagNames");
const ExifDate_1 = require("./ExifDate");
const ExifDateTime_1 = require("./ExifDateTime");

@@ -12,2 +13,3 @@ const ExifTime_1 = require("./ExifTime");

const Number_1 = require("./Number");
const Pick_1 = require("./Pick");
const String_1 = require("./String");

@@ -97,2 +99,26 @@ // Unique values from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

exports.UnsetZoneName = exports.UnsetZone.name;
const Zulus = [
luxon_1.FixedOffsetZone.utcInstance,
0,
-0,
"UTC",
"GMT",
"Z",
"+0",
"+00:00",
"UTC+0",
"GMT+0",
"UTC+00:00",
// ...sigh, so much for "normalizeZone"...
];
function isUTC(zone) {
var _a;
const z = zone;
return (zone != null && (Zulus.includes(z) || Zulus.includes((_a = z.zoneName) !== null && _a !== void 0 ? _a : z.fixed)));
}
exports.isUTC = isUTC;
function isZoneValid(zone) {
return (zone != null && zone.isValid && Math.abs(zone.offset(Date.now())) < 14 * 60);
}
exports.isZoneValid = isZoneValid;
/**

@@ -104,11 +130,37 @@ * If `tzSource` matches this value, the tags are from a video, and we had to

exports.defaultVideosToUTC = "defaultVideosToUTC";
function normalizeZone(z) {
// https://en.wikipedia.org/wiki/List_of_tz_database_time_zones -- not that
// "WET" and "W-SU" are full TZs
const IanaFormatRE = /^\w{2,15}(?:\/\w{3,15})?$/;
// Luxon requires fixed-offset zones to look like "UTC+H", "UTC-H",
// "UTC+H:mm", "UTC-H:mm":
const FixedFormatRE = /^UTC[+-]\d{1,2}(?::\d\d)?$/;
/**
* @param input must be either a number, which is the offset in minutes, or a
* string in the format "UTC+H" or "UTC+HH:mm"
*/
function normalizeZone(input) {
// wrapped in a try/catch as Luxon.settings.throwOnInvalid may be true:
try {
// Info.normalizeZone returns the system zone if the input is null or
// blank (!!!), but we want to return undefined instead--we don't want to introduce the system zone by accident!
if (z == null || (0, String_1.blank)(String(z)))
// blank (!!!), but we want to return undefined instead:
// Info.normalizeZone(null) returns the system zone, which isn't what we
// (ever!) want.
if (input == null)
return;
const zone = luxon_1.Info.normalizeZone(z);
return zone != null && zone.isValid && zone.name !== exports.UnsetZoneName
? zone
if (input instanceof luxon_1.Zone) {
return isZoneValid(input) ? input : undefined;
}
let z = input;
if (typeof z === "string") {
z = z.replace(/^(Zulu|Z|GMT)(\b|$)/, "UTC");
// Info.normalizeZone("") returns the system zone, which we never want.
// We also don't need to tease Info.normalizeZone with obviously
// non-offset inputs:
if ((0, String_1.blank)(z) || (!IanaFormatRE.test(z) && !FixedFormatRE.test(z))) {
return;
}
}
const result = luxon_1.Info.normalizeZone(z);
return isZoneValid(result) && result.name !== exports.UnsetZoneName
? result
: undefined;

@@ -121,2 +173,12 @@ }

exports.normalizeZone = normalizeZone;
/**
* @param ts must be provided if the zone is not a fixed offset
* @return the zone offset (in "±HH:MM" format) for the given zone, or "" if
* the zone is invalid
*/
function zoneToShortOffset(zone, ts) {
var _a, _b;
return (_b = (_a = normalizeZone(zone)) === null || _a === void 0 ? void 0 : _a.formatOffset(ts !== null && ts !== void 0 ? ts : Date.now(), "short")) !== null && _b !== void 0 ? _b : "";
}
exports.zoneToShortOffset = zoneToShortOffset;
function validTzOffsetMinutes(tzOffsetMinutes) {

@@ -169,3 +231,13 @@ return (tzOffsetMinutes != null &&

function extractZone(value, opts) {
var _a, _b, _c;
var _a, _b;
if (value == null ||
typeof value === "boolean" ||
value instanceof BinaryField_1.BinaryField ||
value instanceof ExifDate_1.ExifDate) {
return;
}
if (Array.isArray(value)) {
// we only ever care about the first non-null value
return extractZone(value.find((ea) => ea != null));
}
if (value instanceof ExifDateTime_1.ExifDateTime || value instanceof ExifTime_1.ExifTime) {

@@ -176,10 +248,13 @@ return value.zone == null

}
if ((0, Number_1.isNumber)(value) || Array.isArray(value)) {
if ((0, Number_1.isNumber)(value)) {
return extractOffsetFromHours(value);
}
let str = (_a = value.rawValue) !== null && _a !== void 0 ? _a : (0, String_1.toS)(value);
if (typeof value !== "string" || (0, String_1.blank)(value)) {
// don't accept ExifDate, boolean, BinaryField, ResourceEvent, Struct, or
// Version instances:
return;
}
{
if ((0, String_1.blank)(str))
return;
const z = normalizeZone(str);
// If value is a proper timezone name, this may be easy!
const z = normalizeZone(value);
if (z != null) {

@@ -189,2 +264,3 @@ return { tz: z.name, src: "normalizeZone" };

}
let str = value.trim();
// Some EXIF datetime will "over-specify" and include both the utc offset

@@ -207,14 +283,15 @@ // *and* the "time zone abbreviation"/TZA, like "PST" or "PDT". TZAs are

}
const m = tzRe.exec(str);
const g = m === null || m === void 0 ? void 0 : m.groups;
if (m != null && g != null) {
const leftovers = str.slice(0, m.index);
if (g.Z === "Z")
const match = tzRe.exec(str);
const capturedGroups = match === null || match === void 0 ? void 0 : match.groups;
if (match != null && capturedGroups != null) {
const leftovers = str.slice(0, match.index);
if (capturedGroups.Z === "Z")
return {
tz: luxon_1.FixedOffsetZone.utcInstance.name,
tz: "UTC",
src: "Z",
leftovers,
};
const offsetMinutes = (g.sign === "-" ? -1 : 1) *
(parseInt((_b = g.hours) !== null && _b !== void 0 ? _b : "0") * 60 + parseInt((_c = g.minutes) !== null && _c !== void 0 ? _c : "0"));
const offsetMinutes = (capturedGroups.sign === "-" ? -1 : 1) *
(parseInt((_a = capturedGroups.hours) !== null && _a !== void 0 ? _a : "0") * 60 +
parseInt((_b = capturedGroups.minutes) !== null && _b !== void 0 ? _b : "0"));
const tz = offsetMinutesToZoneName(offsetMinutes);

@@ -242,24 +319,7 @@ if (tz != null) {

];
// The following are a hail-mary to try to get the offset from a
// created-at tag, and only examined if `inferTimezoneFromDatestamps` is
// true.
const CreateDateTagnames = [
"SubSecCreateDate",
"CreateDate",
"SubSecDateTimeOriginal",
"DateTimeOriginal",
"SubSecMediaCreateDate",
"MediaCreateDate",
"CreationDate",
"TimeCreated", // < IPTC tag
];
function extractTzOffsetFromTags(t, opts) {
var _a;
for (const tagName of [
...TimezoneOffsetTagnames,
...(((_a = opts === null || opts === void 0 ? void 0 : opts.inferTimezoneFromDatestamps) !== null && _a !== void 0 ? _a : false) ? CreateDateTagnames : []),
]) {
// don't adopt FileCreateDate or FileModifyDate offsets--those are just
// the system timezone:
if (t[tagName] != null && !tagName.startsWith("File")) {
function extractTzOffsetFromTags(t) {
// We have to iterate twice: if it's from a timezone offset tag, we can
// trust it, even if it's UTC.
for (const tagName of TimezoneOffsetTagnames) {
if (t[tagName] != null) {
const offset = extractZone(t[tagName]);

@@ -271,13 +331,23 @@ if (offset != null) {

}
if (t.TimeZoneOffset != null) {
const tz = tzHourToOffset(Array.isArray(t.TimeZoneOffset) ? t.TimeZoneOffset[0] : t.TimeZoneOffset);
if (tz != null)
return {
tz,
src: "TimeZoneOffset",
};
return;
}
exports.extractTzOffsetFromTags = extractTzOffsetFromTags;
function extractTzOffsetFromDatestamps(t, opts) {
var _a;
if ((opts === null || opts === void 0 ? void 0 : opts.inferTimezoneFromDatestamps) === true) {
for (const tagName of (_a = opts.inferTimezoneFromDatestampTags) !== null && _a !== void 0 ? _a : []) {
if (t[tagName] != null) {
const offset = extractZone(t[tagName]);
// Some applications (looking at you, Google Takeout) will add a
// spurious "+00:00" timezone offset to random datestamp tags, so
// ignore UTC offsets here.
if (offset != null && !isUTC(offset.tz)) {
return { tz: offset.tz, src: tagName };
}
}
}
}
return;
}
exports.extractTzOffsetFromTags = extractTzOffsetFromTags;
exports.extractTzOffsetFromDatestamps = extractTzOffsetFromDatestamps;
// timezone offsets may be on a 15 minute boundary, but if GPS acquisition is

@@ -292,13 +362,21 @@ // old, this can be spurious. We get less mistakes with a larger multiple, so

exports.inferLikelyOffsetMinutes = inferLikelyOffsetMinutes;
/**
* Convert blank strings to undefined.
*/
function blankToNull(x) {
return x == null || (typeof x === "string" && (0, String_1.blank)(x)) ? undefined : x;
}
function extractTzOffsetFromUTCOffset(t) {
var _a;
const gpsStamps = (0, Array_1.compact)([t.GPSDateStamp, t.GPSTimeStamp]);
if (gpsStamps.length === 2) {
(_a = t.GPSDateTimeStamp) !== null && _a !== void 0 ? _a : (t.GPSDateTimeStamp = gpsStamps.join(" "));
}
const utcSources = {
...(0, Pick_1.pick)(t, "GPSDateTime", "DateTimeUTC"),
GPSDateTimeStamp: (0, Maybe_1.map2)(blankToNull(t.GPSDateStamp), // Example: "2022:04:13"
blankToNull(t.GPSTimeStamp), // Example: "23:59:41.001"
(a, b) => a + " " + b),
};
// We can always assume these are in UTC:
const utc = (0, Maybe_1.first)(["GPSDateTime", "DateTimeUTC", "GPSDateTimeStamp"], (tagName) => {
var _a;
const edt = ExifDateTime_1.ExifDateTime.fromExifStrict(t[tagName]);
const s = edt != null && (edt.zone == null || edt.zone === "UTC")
const v = utcSources[tagName];
const edt = v instanceof ExifDateTime_1.ExifDateTime ? v : ExifDateTime_1.ExifDateTime.fromExifStrict(v);
const s = edt != null && (edt.zone == null || isUTC(edt.zone))
? (_a = edt.setZone("UTC", { keepLocalTime: true })) === null || _a === void 0 ? void 0 : _a.toEpochSeconds()

@@ -305,0 +383,0 @@ : undefined;

@@ -14,1 +14,2 @@ import { ExifDate } from "./ExifDate";

}
export declare function isVersion(obj: any): obj is Version;
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.isVersion = void 0;
const fields = ["Comments", "Event", "Modifier", "ModifyDate", "Version"];
function isVersion(obj) {
return obj != null && typeof obj === "object" && fields.every((f) => f in obj);
}
exports.isVersion = isVersion;
//# sourceMappingURL=Version.js.map
{
"name": "exiftool-vendored",
"version": "23.1.0",
"version": "23.2.0",
"description": "Efficient, cross-platform access to ExifTool",

@@ -76,8 +76,8 @@ "main": "./dist/ExifTool.js",

"@types/mocha": "^10.0.2",
"@types/node": "^20.8.0",
"@types/node": "^20.8.2",
"@types/progress": "^2.0.5",
"@types/tmp": "^0.2.4",
"@types/xmldom": "^0.1.32",
"@typescript-eslint/eslint-plugin": "^6.7.3",
"@typescript-eslint/parser": "^6.7.3",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"@xmldom/xmldom": "^0.8.10",

@@ -84,0 +84,0 @@ "chai": "^4.3.10",

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc