mirror of
https://github.com/C4illin/ConvertX.git
synced 2026-10-27 23:30:55 +01:00
Merge remote-tracking branch 'origin/main' into chore/typescript-7
This commit is contained in:
+11
-3
@@ -45,6 +45,9 @@ RUN bun run build
|
||||
FROM base AS release
|
||||
|
||||
# install additional dependencies
|
||||
ENV PIPX_HOME=/opt/pipx
|
||||
ENV PIPX_BIN_DIR=/usr/local/bin
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
assimp-utils \
|
||||
calibre \
|
||||
@@ -53,6 +56,7 @@ RUN apt-get update && apt-get install -y \
|
||||
dvisvgm \
|
||||
ffmpeg \
|
||||
ghostscript \
|
||||
gosu \
|
||||
graphicsmagick \
|
||||
imagemagick-7.q16 \
|
||||
inkscape \
|
||||
@@ -84,8 +88,8 @@ RUN apt-get update && apt-get install -y \
|
||||
&& pipx install "markitdown[all]" \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Add pipx bin directory to PATH
|
||||
ENV PATH="/root/.local/bin:${PATH}"
|
||||
RUN groupadd -g 1000 convertx && \
|
||||
useradd -u 1000 -g convertx -d /home/convertx -m -s /bin/bash convertx
|
||||
|
||||
# Install VTracer binary
|
||||
RUN ARCH=$(uname -m) && \
|
||||
@@ -107,8 +111,12 @@ COPY --from=prerelease /app/dist /app/dist
|
||||
# COPY . .
|
||||
RUN mkdir data
|
||||
|
||||
COPY entrypoint.sh /entrypoint.sh
|
||||
RUN chmod +x /entrypoint.sh
|
||||
|
||||
EXPOSE 3000/tcp
|
||||
# used for calibre
|
||||
ENV QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox"
|
||||
ENV NODE_ENV=production
|
||||
ENTRYPOINT [ "bun", "run", "dist/src/index.js" ]
|
||||
ENTRYPOINT [ "/entrypoint.sh" ]
|
||||
CMD [ "bun", "run", "dist/src/index.js" ]
|
||||
|
||||
@@ -68,6 +68,7 @@ services:
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment:
|
||||
- PUID=1000 # user id for file permissions (should match your host user id)
|
||||
- JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() if unset
|
||||
# - HTTP_ALLOWED=true # uncomment this if accessing it over a non-https connection
|
||||
volumes:
|
||||
@@ -77,20 +78,26 @@ services:
|
||||
or
|
||||
|
||||
```bash
|
||||
docker run -p 3000:3000 -v ./data:/app/data ghcr.io/c4illin/convertx
|
||||
docker run -p 3000:3000 -e PUID=1000 -e PGID=1000 -v ./data:/app/data ghcr.io/c4illin/convertx
|
||||
```
|
||||
|
||||
Then visit `http://localhost:3000` in your browser and create your account. Don't leave it unconfigured and open, as anyone can register the first account.
|
||||
Ensure `PUID` and `PGID` match your host user (`id -u` and `id -g`) to avoid permission issues on the mapped `./data` volume. If you get unable to open database file, verify the directory permissions or run `chown -R $USER:$USER path` on the path you choose.
|
||||
|
||||
If you get unable to open database file run `chown -R $USER:$USER path` on the path you choose.
|
||||
Then visit `http://localhost:3000` in your browser and create your account. Don't leave it unconfigured and open, as anyone can register the first account.
|
||||
|
||||
### Environment variables
|
||||
|
||||
All are optional, JWT_SECRET is recommended to be set.
|
||||
|
||||
> [!WARNING]
|
||||
> Never expose the service to the internet with ALLOW_UNAUTHENTICATED or ACCOUNT_REGISTRATION true. Only allow users you trust to access the service.
|
||||
|
||||
| Name | Default | Description |
|
||||
| ---------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| JWT_SECRET | when unset it will use the value from randomUUID() | A long and secret string used to sign the JSON Web Token |
|
||||
| PUID | 0 (root) | User ID to run the application process as (it first uses root to chown the files) |
|
||||
| PGID | PUID if unset, root if both unset | Group ID to run the application process as |
|
||||
| UMASK | 002 (when PUID is set) | File creation mask for processes and created files |
|
||||
| ACCOUNT_REGISTRATION | false | Allow users to register accounts |
|
||||
| HTTP_ALLOWED | false | Allow HTTP connections, only set this to true locally |
|
||||
| ALLOW_UNAUTHENTICATED | false | Allow unauthenticated users to use the service, only set this to true locally |
|
||||
|
||||
@@ -19,15 +19,15 @@
|
||||
"@tailwindcss/cli": "^4.3.3",
|
||||
"@tailwindcss/postcss": "^4.3.3",
|
||||
"@types/bun": "1.3.14",
|
||||
"@types/node": "^24.13.6",
|
||||
"@types/node": "^24.19.0",
|
||||
"@typescript/native": "npm:typescript@^7.0.2",
|
||||
"eslint": "^10.11.0",
|
||||
"eslint-plugin-better-tailwindcss": "^4.7.0",
|
||||
"globals": "^17.12.0",
|
||||
"knip": "^6.37.0",
|
||||
"knip": "^6.38.0",
|
||||
"npm-run-all2": "^9.0.3",
|
||||
"postcss": "^8.5.28",
|
||||
"prettier": "^3.9.8",
|
||||
"prettier": "^3.9.9",
|
||||
"tailwind-scrollbar": "^4.0.2",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
||||
@@ -267,7 +267,7 @@
|
||||
|
||||
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
|
||||
|
||||
"@types/node": ["@types/node@24.13.6", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-SGrw/h3KPFshy3OE6ZL53LMBG5vGQQ8/gIpiqz/kRZhPJ7HgwCEs8LBuNtWLa8dvGZVpSF7+Bf+c11HUrCb/yg=="],
|
||||
"@types/node": ["@types/node@24.19.0", "", { "dependencies": { "undici-types": ">=7.24.0 <7.24.7" } }, "sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew=="],
|
||||
|
||||
"@types/prismjs": ["@types/prismjs@1.26.6", "", {}, "sha512-vqlvI7qlMvcCBbVe0AKAb4f97//Hy0EBTaiW8AalRnG/xAN5zOiWWyrNqNXeq8+KAuvRewjCVY1+IPxk4RdNYw=="],
|
||||
|
||||
@@ -483,7 +483,7 @@
|
||||
|
||||
"keyv": ["keyv@5.6.0", "", { "dependencies": { "@keyv/serialize": "^1.1.1" } }, "sha512-CYDD3SOtsHtyXeEORYRx2qBtpDJFjRTGXUtmNEMGyzYOKj1TE3tycdlho7kA1Ufx9OYWZzg52QFBGALTirzDSw=="],
|
||||
|
||||
"knip": ["knip@6.37.0", "", { "dependencies": { "fdir": "^6.5.0", "formatly": "^0.7.0", "get-tsconfig": "4.14.3", "jiti": "^2.7.0", "oxc-parser": "^0.150.0", "oxc-resolver": "11.24.2", "picomatch": "^4.0.7", "smol-toml": "^1.8.0", "strip-json-comments": "5.0.3", "tinyglobby": "^0.2.17", "unbash": "^4.0.11", "yaml": "^2.9.1", "zod": "^4.4.3" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-NKCYuoGKJ+o2AuoCuV1mDvfMYnSSWfDXqxwmzxeHyd8fftjNRl8TBUg3fbSrtJjhm7Vj6sc1PX3WZnZhECs9EQ=="],
|
||||
"knip": ["knip@6.38.0", "", { "dependencies": { "fdir": "^6.5.0", "formatly": "^0.7.0", "get-tsconfig": "4.14.3", "jiti": "^2.7.0", "oxc-parser": "^0.150.0", "oxc-resolver": "11.24.2", "picomatch": "^4.0.7", "smol-toml": "^1.8.0", "strip-json-comments": "5.0.3", "tinyglobby": "^0.2.17", "unbash": "^4.0.11", "yaml": "^2.9.1", "zod": "^4.4.3" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-umytiMCaZf02MV9SOO1FEDgbDf6h20VZk3ruJE0kh52kkGjYZFRUAXHJWYoLhvhoHGINO/7GXVJmQ2vxTBvl6A=="],
|
||||
|
||||
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
|
||||
|
||||
@@ -573,7 +573,7 @@
|
||||
|
||||
"prelude-ls": ["prelude-ls@1.2.1", "", {}, "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="],
|
||||
|
||||
"prettier": ["prettier@3.9.8", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-WRFq3Wn3WId7LLROfMLdH7xaFr2jR62wU8nLO6rQUOLOxNZUviyJQs1M0iIhLexSFy+L+w0ch66wtoO2jRjG0A=="],
|
||||
"prettier": ["prettier@3.9.9", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg=="],
|
||||
|
||||
"prism-react-renderer": ["prism-react-renderer@2.4.1", "", { "dependencies": { "@types/prismjs": "^1.26.0", "clsx": "^2.0.0" }, "peerDependencies": { "react": ">=16.0.0" } }, "sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig=="],
|
||||
|
||||
@@ -601,7 +601,7 @@
|
||||
|
||||
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
||||
|
||||
"string-width": ["string-width@8.2.2", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-GaPUh5gfdrYzqeVNZvUfT23vYYxXzKYidUcnMtJg/3rxRV63EFZy3k6xfKlmfeJD0176lnUV/Usr3XcwSvFzpg=="],
|
||||
"string-width": ["string-width@8.3.0", "", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ=="],
|
||||
|
||||
"strip-ansi": ["strip-ansi@7.2.0", "", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
|
||||
|
||||
@@ -651,7 +651,7 @@
|
||||
|
||||
"unbash": ["unbash@4.0.11", "", {}, "sha512-FoSOKV7NEofQSkAefMVHam4ZPKYMxjAydxiV72UFEDNV/YofxjGfiZ2A9pZjdL/lRJzTjcu4PABo1JYJX8N5iQ=="],
|
||||
|
||||
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
||||
"undici-types": ["undici-types@7.24.6", "", {}, "sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg=="],
|
||||
|
||||
"uri-js": ["uri-js@4.4.1", "", { "dependencies": { "punycode": "^2.1.0" } }, "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg=="],
|
||||
|
||||
@@ -683,11 +683,11 @@
|
||||
|
||||
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.3", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.3", "tslib": "^2.4.0" }, "bundled": true }, "sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg=="],
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/core": ["@emnapi/core@1.11.2", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.2", "tslib": "^2.4.0" }, "bundled": true }, "sha512-TC8MkTuZUtcTSiFeuC0ksCh9QIJ5+F21MvZ4Wn4ORfYaFJ/0dsiudv5tVkejgwZlwQ39jL9WWDe2lz8x0WglOA=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA=="],
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/runtime": ["@emnapi/runtime@1.11.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.3", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g=="],
|
||||
"@tailwindcss/oxide-wasm32-wasi/@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.2", "", { "dependencies": { "tslib": "^2.4.0" }, "bundled": true }, "sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA=="],
|
||||
|
||||
"@tailwindcss/oxide-wasm32-wasi/@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" }, "bundled": true }, "sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g=="],
|
||||
|
||||
@@ -697,7 +697,7 @@
|
||||
|
||||
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.10", "", {}, "sha512-HpbUakT7xp5miBUywCHf36ZEuAJNklBJDDsGpUIjMzOSmM8ELSfA9Sa/QDPeNeqeoN31u+UTCkL4klCOVvRm4Q=="],
|
||||
|
||||
"bun-types/@types/node": ["@types/node@26.6.2", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-X1P21scMv4zGKLYqjdGjaKa7COa0RKVYYZZN/NfvLQ1JegxFhdhpZG/Lyn8AXx6CDUavKAd11v6BvfpkDByK8g=="],
|
||||
"bun-types/@types/node": ["@types/node@26.6.3", "", { "dependencies": { "undici-types": "~8.9.0" } }, "sha512-dsqMQQoeTLqu9wynDD00q573mNzso3IdQOAfHRJqLCcmCFPoGo9A1bDpUcv/9tnKpErQWv9uKeGfl37EIS02Yg=="],
|
||||
|
||||
"cliui/string-width": ["string-width@7.2.0", "", { "dependencies": { "emoji-regex": "^10.3.0", "get-east-asian-width": "^1.0.0", "strip-ansi": "^7.1.0" } }, "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ=="],
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@ services:
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
environment: # Defaults are listed below. All are optional.
|
||||
- PUID=1000 # user ID for file permissions, defaults to 0
|
||||
- PGID=1000 # group ID for file permissions, defaults to 0
|
||||
- UMASK=002 # file creation mask, defaults to 002 when PUID is set
|
||||
- ACCOUNT_REGISTRATION=true # true or false, doesn't matter for the first account (e.g. keep this to false if you only want one account)
|
||||
- JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234 # will use randomUUID() by default
|
||||
- HTTP_ALLOWED=false # setting this to true is unsafe, only set this to true locally
|
||||
|
||||
Executable
+52
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
if [[ -n "$PUID" && ! "$PUID" =~ ^[0-9]+$ ]] || [[ -n "$PGID" && ! "$PGID" =~ ^[0-9]+$ ]] || [[ -z "$PUID" && -n "$PGID" ]]; then
|
||||
echo "[entrypoint] ERROR: PUID and PGID must be numeric integers or unset." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# If PUID is not set or is 0, run as root (backwards-compatible default)
|
||||
if [ -z "$PUID" ] || [ "$PUID" -eq 0 ]; then
|
||||
if [ -n "$UMASK" ]; then
|
||||
umask "$UMASK"
|
||||
fi
|
||||
if [ $# -eq 0 ]; then
|
||||
set -- bun run dist/src/index.js
|
||||
fi
|
||||
exec "$@"
|
||||
fi
|
||||
|
||||
PGID=${PGID:-$PUID}
|
||||
UMASK=${UMASK:-002}
|
||||
|
||||
umask "$UMASK"
|
||||
|
||||
if [ "$PGID" -ne "$(id -g convertx)" ]; then
|
||||
groupmod -o -g "$PGID" convertx
|
||||
fi
|
||||
|
||||
if [ "$PUID" -ne "$(id -u convertx)" ]; then
|
||||
usermod -o -u "$PUID" convertx
|
||||
fi
|
||||
|
||||
# Ensure home directory exists and is owned by convertx
|
||||
mkdir -p /home/convertx
|
||||
if [ "$(stat -c '%u:%g' /home/convertx)" != "$PUID:$PGID" ]; then
|
||||
chown -R convertx:convertx /home/convertx
|
||||
fi
|
||||
|
||||
# Ensure /app/data exists and fix permissions only if the mount point ownership differs
|
||||
mkdir -p /app/data
|
||||
if [ "$(stat -c '%u:%g' /app/data)" != "$PUID:$PGID" ]; then
|
||||
find /app/data \( ! -user "$PUID" -o ! -group "$PGID" \) -exec chown -h "$PUID:$PGID" '{}' +
|
||||
fi
|
||||
|
||||
export HOME=/home/convertx
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
set -- bun run dist/src/index.js
|
||||
fi
|
||||
|
||||
exec gosu convertx "$@"
|
||||
|
||||
@@ -18,7 +18,8 @@
|
||||
"heif-info",
|
||||
"potrace",
|
||||
"soffice",
|
||||
"perl"
|
||||
"perl",
|
||||
"markitdown"
|
||||
],
|
||||
"tailwind": {
|
||||
"entry": ["src/main.css"]
|
||||
|
||||
+4
-4
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "convertx-frontend",
|
||||
"version": "0.18.0",
|
||||
"version": "0.19.0",
|
||||
"scripts": {
|
||||
"dev": "bun run --watch src/index.tsx",
|
||||
"hot": "bun run --hot src/index.tsx",
|
||||
@@ -37,14 +37,14 @@
|
||||
"@tailwindcss/postcss": "^4.3.3",
|
||||
"@types/bun": "1.3.14",
|
||||
"@typescript/native": "npm:typescript@^7.0.2",
|
||||
"@types/node": "^24.13.6",
|
||||
"@types/node": "^24.19.0",
|
||||
"eslint": "^10.11.0",
|
||||
"eslint-plugin-better-tailwindcss": "^4.7.0",
|
||||
"globals": "^17.12.0",
|
||||
"knip": "^6.37.0",
|
||||
"knip": "^6.38.0",
|
||||
"npm-run-all2": "^9.0.3",
|
||||
"postcss": "^8.5.28",
|
||||
"prettier": "^3.9.8",
|
||||
"prettier": "^3.9.9",
|
||||
"tailwind-scrollbar": "^4.0.2",
|
||||
"tailwindcss": "^4.3.3",
|
||||
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
||||
|
||||
@@ -461,6 +461,11 @@ export function convert(
|
||||
}
|
||||
}
|
||||
|
||||
// Increase rasterization quality for PDF input
|
||||
if (fileType === "pdf") {
|
||||
inputArgs.push("-density", "300");
|
||||
}
|
||||
|
||||
// Handle EMF files specifically to avoid LibreOffice delegate issues
|
||||
if (fileType === "emf") {
|
||||
// Use direct conversion without delegates for EMF files
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import { Cookie } from "elysia";
|
||||
import db from "../db/db";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
import { MAX_CONVERT_PROCESS } from "../helpers/env";
|
||||
import { normalizeFiletype, normalizeOutputFiletype } from "../helpers/normalizeFiletype";
|
||||
import { convert as convertassimp, properties as propertiesassimp } from "./assimp";
|
||||
@@ -187,8 +189,32 @@ export async function handleConvert(
|
||||
mainConverter(filePath, fileType, convertTo, targetPath, {}, converterName)
|
||||
.then((r) => {
|
||||
if (jobId.value) {
|
||||
const dir = path.dirname(targetPath);
|
||||
const parsed = path.parse(targetPath);
|
||||
|
||||
const outputFiles = fs
|
||||
.readdirSync(dir)
|
||||
.filter((f) => {
|
||||
if (f === parsed.base) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (
|
||||
f.startsWith(`${parsed.name}-`) &&
|
||||
f.endsWith(parsed.ext) &&
|
||||
/^\d+$/.test(f.slice(parsed.name.length + 1, -parsed.ext.length))
|
||||
);
|
||||
})
|
||||
.sort((a, b) => a.localeCompare(b, undefined, { numeric: true }));
|
||||
|
||||
if (outputFiles.length > 0) {
|
||||
for (const outputFile of outputFiles) {
|
||||
query.run(jobId.value, fileName, outputFile, r);
|
||||
}
|
||||
} else {
|
||||
query.run(jobId.value, fileName, newFileName, r);
|
||||
}
|
||||
}
|
||||
resolve(r);
|
||||
})
|
||||
.catch((c) => reject(c));
|
||||
|
||||
@@ -3,7 +3,22 @@ import { ExecFileFn } from "./types";
|
||||
|
||||
export const properties = {
|
||||
from: {
|
||||
document: ["pdf", "powerpoint", "excel", "docx", "pptx", "html"],
|
||||
document: [
|
||||
"pdf",
|
||||
"pptx",
|
||||
"docx",
|
||||
"xlsx",
|
||||
"xls",
|
||||
"msg",
|
||||
"wav",
|
||||
"mp3",
|
||||
"epub",
|
||||
"html",
|
||||
"csv",
|
||||
"json",
|
||||
"xml",
|
||||
"zip",
|
||||
],
|
||||
},
|
||||
to: {
|
||||
document: ["md"],
|
||||
|
||||
@@ -197,6 +197,17 @@ if (process.env.NODE_ENV === "production") {
|
||||
},
|
||||
);
|
||||
|
||||
exec("markitdown -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("markitdown is not installed");
|
||||
return;
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`${stdout.split("\n")[0]}`);
|
||||
}
|
||||
});
|
||||
|
||||
exec("bun -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Bun is not installed. wait what");
|
||||
|
||||
@@ -101,7 +101,7 @@ test("prints system information and tool versions in production mode", async ()
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith("ConvertX v1.0.0-test");
|
||||
expect(consoleLogSpy).toHaveBeenCalledWith("Ubuntu 22.04 LTS");
|
||||
expect(readFile).toHaveBeenCalledTimes(1);
|
||||
expect(exec).toHaveBeenCalledTimes(17); // Corresponds exactly to the number of exec calls in the source code
|
||||
expect(exec).toHaveBeenCalledTimes(18); // Corresponds exactly to the number of exec calls in the source code
|
||||
});
|
||||
|
||||
test("logs error paths when tools are missing", async () => {
|
||||
|
||||
Reference in New Issue
Block a user