Skip to content

Commit 4a71179

Browse files
committed
initial source
1 parent 8e4074d commit 4a71179

File tree

23 files changed

+3297
-0
lines changed

23 files changed

+3297
-0
lines changed

.github/workflows/publish.yml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
name: Publish to NPM
2+
on:
3+
push:
4+
tags:
5+
- 'v*'
6+
jobs:
7+
publish:
8+
runs-on: ubuntu-latest
9+
10+
permissions:
11+
contents: read
12+
id-token: write
13+
steps:
14+
- name: Checkout repository
15+
uses: actions/checkout@v4
16+
- uses: actions/setup-node@v4
17+
with:
18+
node-version: '20.x'
19+
registry-url: 'https://registry.npmjs.org'
20+
- run: npm ci
21+
22+
- name: Install dependencies
23+
run: npm i
24+
25+
- name: Build package
26+
run: npm run build
27+
28+
- name: Publish package to NPM
29+
run: npm publish --provenance --access public --tag latest
30+
env:
31+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
dist
2+
node_modules
3+
.DS_Store
4+
*.wasm
5+
*.esm.js
6+
*.map

README.md

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# @uswriting/exiftool
2+
3+
ExifTool powered by WebAssembly to extract metadata from files in browsers and Node.js environments using [zeroperl](https://github.com/uswriting/zeroperl).
4+
5+
## Installation
6+
7+
```
8+
npm install @uswriting/exiftool
9+
```
10+
11+
## Description
12+
13+
This package provides a WebAssembly-based implementation of ExifTool that works in both browser and Node.js environments. It leverages [zeroperl](https://github.com/uswriting/zeroperl) to execute ExifTool without requiring any native binaries or system dependencies.
14+
15+
## Usage
16+
17+
### Basic Usage
18+
19+
```typescript
20+
import { parseMetadata } from '@uswriting/exiftool';
21+
22+
// Browser usage with File API
23+
document.querySelector('input[type="file"]').addEventListener('change', async (event) => {
24+
const file = event.target.files[0];
25+
const result = await parseMetadata(file);
26+
27+
if (result.success) {
28+
console.log(result.data);
29+
} else {
30+
console.error('Error:', result.error);
31+
}
32+
});
33+
```
34+
35+
### Extracting Specific Metadata
36+
37+
```typescript
38+
import { parseMetadata } from '@uswriting/exiftool';
39+
40+
const result = await parseMetadata(file, {
41+
args: ['-Author', '-CreateDate', '-Make', '-Model']
42+
});
43+
44+
if (result.success) {
45+
console.log(result.data);
46+
}
47+
```
48+
49+
### JSON Output
50+
51+
```typescript
52+
import { parseMetadata } from '@uswriting/exiftool';
53+
54+
const result = await parseMetadata(file, {
55+
args: ['-json', '-n'],
56+
transform: (data) => JSON.parse(data)
57+
});
58+
59+
if (result.success) {
60+
// Typed access to properties
61+
console.log(result.data); // { ... }
62+
}
63+
```
64+
65+
## Important Notes
66+
67+
- In browser environments, pass the `File` object directly from file inputs. Do not convert it to an ArrayBuffer or Uint8Array.
68+
- This package uses asynchronous web APIs for file processing which allows handling files over 2GB without loading them entirely into memory.
69+
- ExifTool is executed entirely within the browser or Node.js environment - no server requests are made for metadata extraction.
70+
71+
## API Reference
72+
73+
### parseMetadata()
74+
75+
```typescript
76+
async function parseMetadata<TReturn = string>(
77+
file: Binaryfile | File,
78+
options: ExifToolOptions<TReturn> = {}
79+
): Promise<ExifToolOutput<TReturn>>
80+
```
81+
82+
#### Parameters
83+
84+
- `file`: Either a browser `File` object or a `Binaryfile` object with `name` and `data` properties.
85+
- `options`: Configuration options for the metadata extraction.
86+
87+
#### Options
88+
89+
```typescript
90+
interface ExifToolOptions<TReturn> {
91+
// Additional command-line arguments to pass to ExifTool
92+
args?: string[];
93+
94+
// Custom fetch implementation for loading the WASM module
95+
fetch?: (...args: any[]) => Promise<Response>;
96+
97+
// Transform the raw ExifTool output into a different format
98+
transform?: (data: string) => TReturn;
99+
}
100+
```
101+
102+
#### Return Value
103+
104+
Returns a Promise that resolves to an `ExifToolOutput` object:
105+
106+
```typescript
107+
type ExifToolOutput<TOutput> =
108+
| {
109+
success: true;
110+
data: TOutput;
111+
error: string;
112+
exitCode: 0;
113+
}
114+
| {
115+
success: false;
116+
data: undefined;
117+
error: string;
118+
exitCode: number | undefined;
119+
};
120+
```
121+
122+
## License
123+
124+
Apache License, Version 2.0

build.mjs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { build } from 'esbuild';
2+
import { raw } from "esbuild-raw-plugin";
3+
4+
const prod = build({
5+
entryPoints: ['src/index.ts'],
6+
bundle: true,
7+
format: 'esm',
8+
outfile: 'dist/esm/index.esm.js',
9+
sourcemap: true,
10+
minify: true,
11+
plugins: [raw()],
12+
target: ['ESNext'],
13+
});
14+
15+
const demo = build({
16+
entryPoints: ['src/index.ts'],
17+
bundle: true,
18+
format: 'esm',
19+
outfile: 'demo/index.esm.js',
20+
sourcemap: true,
21+
minify: false,
22+
plugins: [raw()],
23+
});
24+
25+
26+
Promise.all([prod, demo]).catch(() => process.exit(1));

0 commit comments

Comments
 (0)