Slave/metadata pipeline #6

Merged
nobswebdev merged 9 commits from slave/metadata-pipeline into master 2026-10-18 16:57:39 +00:00
5 changed files with 115 additions and 1 deletions
Showing only changes of commit e89f76a673 - Show all commits
+1
View File
@@ -3,6 +3,7 @@ FROM node:22-alpine
WORKDIR /frontend
COPY package*.json .
COPY patches ./patches
RUN npm ci
+34
View File
@@ -7,8 +7,10 @@
"": {
"name": "frontend",
"version": "0.0.0",
"hasInstallScript": true,
"dependencies": {
"@tailwindcss/vite": "^4.3.3",
"@uswriting/exiftool": "1.0.9",
"axios": "^1.20.0",
"pinia": "^4.0.3",
"tailwindcss": "^4.3.3",
@@ -24,6 +26,12 @@
"vue-tsc": "^3.2.6"
}
},
"node_modules/@6over3/zeroperl-ts": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/@6over3/zeroperl-ts/-/zeroperl-ts-1.0.10.tgz",
"integrity": "sha512-d7fBgN1UaP9BR6kZMyNsjIrxPd0QLqqx29VSprhK66m1csm/7E/anr+rEfp3gJDSne5FfDpM6aKtDGHyXG/vYQ==",
"license": "Apache-2.0"
},
"node_modules/@babel/helper-string-parser": {
"version": "7.29.7",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.29.7.tgz",
@@ -886,6 +894,15 @@
"undici-types": "~6.21.0"
}
},
"node_modules/@uswriting/exiftool": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/@uswriting/exiftool/-/exiftool-1.0.9.tgz",
"integrity": "sha512-tziE5oH/Wf4gJ/g/ZVGBxCjnoHz27SxXRZ4KoFa4c0qN/6uBfvBFEQ272dq7LxbzhXkvGqHdmDyNJe/WUZCV5A==",
"license": "Apache-2.0",
"dependencies": {
"@6over3/zeroperl-ts": "1.0.10"
}
},
"node_modules/@vitejs/plugin-vue": {
"version": "6.0.9",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-vue/-/plugin-vue-6.0.9.tgz",
@@ -2156,6 +2173,23 @@
"peerDependencies": {
"typescript": ">=5.0.0"
}
},
"node_modules/yaml": {
"version": "2.9.1",
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.9.1.tgz",
"integrity": "sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==",
"license": "ISC",
"optional": true,
"peer": true,
"bin": {
"yaml": "bin.mjs"
},
"engines": {
"node": ">= 14.6"
},
"funding": {
"url": "https://github.com/sponsors/eemeli"
}
}
}
}
+3 -1
View File
@@ -6,10 +6,12 @@
"scripts": {
"dev": "vite --host 0.0.0.0",
"build": "vue-tsc -b && vite build",
"preview": "vite preview"
"preview": "vite preview",
"postinstall": "node patches/patch-exiftool-stderr.mjs"
},
"dependencies": {
"@tailwindcss/vite": "^4.3.3",
"@uswriting/exiftool": "1.0.9",
"axios": "^1.20.0",
"pinia": "^4.0.3",
"tailwindcss": "^4.3.3",
+16
View File
@@ -0,0 +1,16 @@
# Dependency patches
## `@uswriting/exiftool@1.0.9` — stderr vs warnings
We do **not** use a `patch-package` diff here: the published `dist/*.js` files are one minified line each, so unified diffs are huge and hard to review.
Instead, `patches/patch-exiftool-stderr.mjs` runs on `postinstall` and removes two **documented** guard strings:
| Guard | Role |
| ----- | ---- |
| `READ_STDERR_GUARD` | After exit 0 on **read**, fail if stderr is non-empty |
| `WRITE_STDERR_GUARD` | After exit 0 on **write**, fail if stderr is non-empty |
See the script for exact literals and upstream context.
When upgrading `@uswriting/exiftool`, run `npm install` and confirm the script still finds both guards (or update the script for the new bundle).
@@ -0,0 +1,61 @@
/**
* Patch @uswriting/exiftool@1.0.9 after install.
*
* Problem: parseMetadata / writeMetadata fail when ExifTool prints warnings to stderr
* even if exit code is 0 (no stdout / no strip bytes returned).
*
* Fix: remove the two stderr early-return checks in the published bundle.
* Upload safety still relies on post-strip re-read + isCleanAfterStrip (app code).
*
* Upstream: https://github.com/6over3/exiftool (issue: warnings incorrectly treated as errors)
*
* Re-verify when bumping @uswriting/exiftool: search dist for these exact snippets.
*/
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const READ_STDERR_GUARD =
'if(o&&o.trim())return{success:!1,data:void 0,error:o,exitCode:0};';
const WRITE_STDERR_GUARD =
'if(d&&d.trim())return{success:!1,data:void 0,error:d,exitCode:0};';
const packageRoot = path.resolve(
path.dirname(fileURLToPath(import.meta.url)),
'../node_modules/@uswriting/exiftool/dist'
);
const targets = ['esm/index.js', 'cjs/index.cjs'];
const patchFile = (relativePath) => {
const filePath = path.join(packageRoot, relativePath);
if (!fs.existsSync(filePath)) {
throw new Error(`patch-exiftool-stderr: missing ${filePath} (is @uswriting/exiftool installed?)`);
}
const original = fs.readFileSync(filePath, 'utf8');
const alreadyPatched =
!original.includes(READ_STDERR_GUARD) && !original.includes(WRITE_STDERR_GUARD);
if (alreadyPatched) {
return;
}
if (!original.includes(READ_STDERR_GUARD) || !original.includes(WRITE_STDERR_GUARD)) {
throw new Error(
`patch-exiftool-stderr: ${relativePath} does not match @uswriting/exiftool@1.0.9; update or remove this script`
);
}
const patched = original
.replaceAll(READ_STDERR_GUARD, '')
.replaceAll(WRITE_STDERR_GUARD, '');
fs.writeFileSync(filePath, patched);
};
for (const relativePath of targets) {
patchFile(relativePath);
}