Merge branch 'main' into AddUnitTests

This commit is contained in:
Emrik Östling 2025-08-11 14:10:42 +02:00 committed by GitHub
commit c3d461f102
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
22 changed files with 160 additions and 80 deletions

View file

@ -1,10 +1,9 @@
--- ---
name: Bug report name: Bug report
about: Create a report to help us improve about: Create a report to help us improve
title: '' title: ""
labels: bug labels: bug
assignees: '' assignees: ""
--- ---
**Describe the bug** **Describe the bug**
@ -12,10 +11,12 @@ A clear and concise description of what the bug is.
**To Reproduce** **To Reproduce**
Steps to reproduce the behavior: Steps to reproduce the behavior:
1. Go to '...' 1. Go to '...'
2. Click on '....' 2. Click on '....'
3. Scroll down to '....' 3. Scroll down to '....'
4. See error 4. See error
**Checklist:** **Checklist:**
- [ ] I am accessing ConvertX over HTTPS or have `HTTP_ALLOWED=true` - [ ] I am accessing ConvertX over HTTPS or have `HTTP_ALLOWED=true`

View file

@ -0,0 +1,26 @@
---
name: Converter request
about: Suggest a converter for this project
title: "[Converter Request]"
labels: "converter request"
assignees: ""
---
**What file formats are missing?**
<!-- Provide an example of what you would like to convert -->
**What converter should be added**
<!-- It has to be free and preferably open source -->
**Are you willing to add it?**
<!-- Adding a converter is very easy just copy one of the existing and modify it -->
- [ ] Yes
- [ ] No
**Additional context**
<!-- Add any other context or screenshots about the feature request here. -->

View file

@ -3,8 +3,7 @@ name: Feature request
about: Suggest an idea for this project about: Suggest an idea for this project
title: "[Feature Request]" title: "[Feature Request]"
labels: enhancement labels: enhancement
assignees: '' assignees: ""
--- ---
**Describe the solution you'd like** **Describe the solution you'd like**

31
.github/workflows/check-lint.yml vendored Normal file
View file

@ -0,0 +1,31 @@
name: Check Lint
on:
push:
branches: ["main"]
pull_request:
branches: ["main"]
workflow_dispatch:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
lint:
name: Run linting checks
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Node.js
uses: oven-sh/setup-bun@v2
with:
bun-version: 1.2.2
- name: Install dependencies
run: bun install
- name: Run lint
run: bun run lint

View file

@ -10,7 +10,6 @@ on:
branches: ["main"] branches: ["main"]
workflow_dispatch: workflow_dispatch:
env: env:
GHCR_IMAGE: ghcr.io/c4illin/convertx
IMAGE_NAME: ${{ github.repository }} IMAGE_NAME: ${{ github.repository }}
DOCKERHUB_USERNAME: c4illin DOCKERHUB_USERNAME: c4illin
@ -32,8 +31,7 @@ jobs:
contents: write contents: write
packages: write packages: write
attestations: write attestations: write
checks: write id-token: write
actions: read
runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-24.04' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }} runs-on: ${{ matrix.platform == 'linux/amd64' && 'ubuntu-24.04' || matrix.platform == 'linux/arm64' && 'ubuntu-24.04-arm' }}
@ -53,11 +51,15 @@ jobs:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: downcase REPO
run: |
echo "REPO=${GITHUB_REPOSITORY@L}" >> "${GITHUB_ENV}"
- name: Docker meta default - name: Docker meta default
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: ${{ env.GHCR_IMAGE }} images: ghcr.io/${{ env.REPO }}
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
@ -82,7 +84,8 @@ jobs:
platforms: ${{ matrix.platform }} platforms: ${{ matrix.platform }}
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
annotations: ${{ steps.meta.outputs.annotations }} annotations: ${{ steps.meta.outputs.annotations }}
outputs: type=image,name=${{ env.GHCR_IMAGE }},push-by-digest=true,name-canonical=true,push=true,oci-mediatypes=true outputs: type=image,name=ghcr.io/${{ env.REPO }},push-by-digest=true,name-canonical=true,oci-mediatypes=true
push: ${{ github.event.pull_request.head.repo.full_name == github.repository }}
cache-from: type=gha,scope=${{ matrix.platform }} cache-from: type=gha,scope=${{ matrix.platform }}
cache-to: type=gha,mode=max,scope=${{ matrix.platform }} cache-to: type=gha,mode=max,scope=${{ matrix.platform }}
@ -101,30 +104,36 @@ jobs:
retention-days: 1 retention-days: 1
merge: merge:
if: github.event.pull_request.head.repo.full_name == github.repository
name: Merge Docker manifests name: Merge Docker manifests
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
attestations: write contents: write
contents: read
packages: write packages: write
attestations: write
id-token: write
needs: needs:
- build - build
steps: steps:
- name: Download digests - name: Download digests
uses: actions/download-artifact@v4 uses: actions/download-artifact@v5
with: with:
path: /tmp/digests path: /tmp/digests
pattern: digests-* pattern: digests-*
merge-multiple: true merge-multiple: true
- name: downcase REPO
run: |
echo "REPO=${GITHUB_REPOSITORY@L}" >> "${GITHUB_ENV}"
- name: Extract Docker metadata - name: Extract Docker metadata
id: meta id: meta
uses: docker/metadata-action@v5 uses: docker/metadata-action@v5
with: with:
images: | images: |
${{ env.GHCR_IMAGE }} ghcr.io/${{ env.REPO }}
${{ env.IMAGE_NAME }} ${{ env.IMAGE_NAME }}
- name: Set up Docker Buildx - name: Set up Docker Buildx
@ -157,8 +166,8 @@ jobs:
--annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \ --annotation='index:org.opencontainers.image.created=${{ steps.timestamp.outputs.timestamp }}' \
--annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \ --annotation='index:org.opencontainers.image.url=${{ github.event.repository.url }}' \
--annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \ --annotation='index:org.opencontainers.image.source=${{ github.event.repository.url }}' \
$(printf '${{ env.GHCR_IMAGE }}@sha256:%s ' *) $(printf 'ghcr.io/${{ env.REPO }}@sha256:%s ' *)
- name: Inspect image - name: Inspect image
run: | run: |
docker buildx imagetools inspect '${{ env.GHCR_IMAGE }}:${{ steps.meta.outputs.version }}' docker buildx imagetools inspect 'ghcr.io/${{ env.REPO }}:${{ steps.meta.outputs.version }}'

1
.gitignore vendored
View file

@ -46,6 +46,7 @@ package-lock.json
/output /output
/db /db
/data /data
/dist
/Bruno /Bruno
/tsconfig.tsbuildinfo /tsconfig.tsbuildinfo
/public/generated.css /public/generated.css

View file

@ -2,10 +2,9 @@
## [0.14.1](https://github.com/C4illin/ConvertX/compare/v0.14.0...v0.14.1) (2025-06-04) ## [0.14.1](https://github.com/C4illin/ConvertX/compare/v0.14.0...v0.14.1) (2025-06-04)
### Bug Fixes ### Bug Fixes
* change to baseline build ([6ea3058](https://github.com/C4illin/ConvertX/commit/6ea3058e66262f7a14633bddcecd5573948f524a)), closes [#311](https://github.com/C4illin/ConvertX/issues/311) - change to baseline build ([6ea3058](https://github.com/C4illin/ConvertX/commit/6ea3058e66262f7a14633bddcecd5573948f524a)), closes [#311](https://github.com/C4illin/ConvertX/issues/311)
## [0.14.0](https://github.com/C4illin/ConvertX/compare/v0.13.0...v0.14.0) (2025-06-03) ## [0.14.0](https://github.com/C4illin/ConvertX/compare/v0.13.0...v0.14.0) (2025-06-03)

View file

@ -77,10 +77,13 @@ RUN apt-get update && apt-get install -y \
COPY --from=install /temp/prod/node_modules node_modules COPY --from=install /temp/prod/node_modules node_modules
COPY --from=prerelease /app/public/generated.css /app/public/ COPY --from=prerelease /app/public/generated.css /app/public/
COPY . . COPY --from=prerelease /app/dist /app/dist
# COPY . .
RUN mkdir data
EXPOSE 3000/tcp EXPOSE 3000/tcp
# used for calibre # used for calibre
ENV QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox" ENV QTWEBENGINE_CHROMIUM_FLAGS="--no-sandbox"
ENV NODE_ENV=production ENV NODE_ENV=production
ENTRYPOINT [ "bun", "run", "./src/index.tsx" ] ENTRYPOINT [ "bun", "run", "dist/src/index.js" ]

View file

@ -94,7 +94,6 @@ All are optional, JWT_SECRET is recommended to be set.
| LANGUAGE | en | Language to format date strings in, specified as a [BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag) | | LANGUAGE | en | Language to format date strings in, specified as a [BCP 47 language tag](https://en.wikipedia.org/wiki/IETF_language_tag) |
| UNAUTHENTICATED_USER_SHARING | false | Shares conversion history between all unauthenticated users | | UNAUTHENTICATED_USER_SHARING | false | Shares conversion history between all unauthenticated users |
### Docker images ### Docker images
There is a `:latest` tag that is updated with every release and a `:main` tag that is updated with every push to the main branch. `:latest` is recommended for normal use. There is a `:latest` tag that is updated with every release and a `:main` tag that is updated with every push to the main branch. `:latest` is recommended for normal use.
@ -133,19 +132,10 @@ Tutorial in chinese: <https://xzllll.com/24092901/>
2. `bun install` 2. `bun install`
3. `bun run dev` 3. `bun run dev`
Pull requests are welcome! See below and open issues for the list of todos. Pull requests are welcome! See open issues for the list of todos. The ones tagged with "converter request" are quite easy. Help with docs and cleaning up in issues are also very welcome!
Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) for commit messages. Use [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/#summary) for commit messages.
## Todo
- [ ] Add options for converters
- [ ] Add tests
- [ ] Make errors logs visible from the web ui
- [ ] Add more converters:
- [ ] [deark](https://github.com/jsummers/deark)
- [ ] LibreOffice
## Contributors ## Contributors
<a href="https://github.com/C4illin/ConvertX/graphs/contributors"> <a href="https://github.com/C4illin/ConvertX/graphs/contributors">

View file

@ -22,7 +22,6 @@
"@types/bun": "1.2.2", "@types/bun": "1.2.2",
"@types/node": "^24.0.0", "@types/node": "^24.0.0",
"@typescript-eslint/parser": "^8.34.0", "@typescript-eslint/parser": "^8.34.0",
"bun-types": "1.2.17",
"eslint": "^9.28.0", "eslint": "^9.28.0",
"eslint-plugin-better-tailwindcss": "^3.1.0", "eslint-plugin-better-tailwindcss": "^3.1.0",
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",
@ -275,7 +274,7 @@
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="], "braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
"bun-types": ["bun-types@1.2.17", "", { "dependencies": { "@types/node": "*" } }, "sha512-ElC7ItwT3SCQwYZDYoAH+q6KT4Fxjl8DtZ6qDulUFBmXA8YB4xo+l54J9ZJN+k2pphfn9vk7kfubeSd5QfTVJQ=="], "bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="],
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="], "callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
@ -655,8 +654,6 @@
"@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="], "@tailwindcss/oxide-wasm32-wasi/tslib": ["tslib@2.8.1", "", { "bundled": true }, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"@types/bun/bun-types": ["bun-types@1.2.2", "", { "dependencies": { "@types/node": "*", "@types/ws": "~8.5.10" } }, "sha512-RCbMH5elr9gjgDGDhkTTugA21XtJAy/9jkKe/G3WR2q17VPGhcquf9Sir6uay9iW+7P/BV0CAHA1XlHXMAVKHg=="],
"@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="], "@typescript-eslint/eslint-plugin/ignore": ["ignore@7.0.4", "", {}, "sha512-gJzzk+PQNznz8ysRrC0aOkBNVRBDtE1n53IqyqEf3PXrYwomFs5q4pGMizBMJF+ykh03insJ27hB8gSrD2Hn8A=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="], "@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],

View file

@ -1,12 +1,11 @@
import js from "@eslint/js"; import js from "@eslint/js";
import eslintParserTypeScript from "@typescript-eslint/parser"; import eslintParserTypeScript from "@typescript-eslint/parser";
import type { Linter } from "eslint";
import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss"; import eslintPluginBetterTailwindcss from "eslint-plugin-better-tailwindcss";
import simpleImportSortPlugin from "eslint-plugin-simple-import-sort"; import simpleImportSortPlugin from "eslint-plugin-simple-import-sort";
import globals from "globals"; import globals from "globals";
import tseslint from "typescript-eslint"; import tseslint from "typescript-eslint";
export default [ export default tseslint.config(
js.configs.recommended, js.configs.recommended,
...tseslint.configs.recommended, ...tseslint.configs.recommended,
// ...tailwind.configs["flat/recommended"], // ...tailwind.configs["flat/recommended"],
@ -15,7 +14,7 @@ export default [
"simple-import-sort": simpleImportSortPlugin, "simple-import-sort": simpleImportSortPlugin,
"better-tailwindcss": eslintPluginBetterTailwindcss, "better-tailwindcss": eslintPluginBetterTailwindcss,
}, },
ignores: ["**/node_modules/**"], ignores: ["**/node_modules/**", "eslint.config.ts"],
languageOptions: { languageOptions: {
parser: eslintParserTypeScript, parser: eslintParserTypeScript,
parserOptions: { parserOptions: {
@ -26,10 +25,9 @@ export default [
}, },
globals: { globals: {
...globals.node, ...globals.node,
...globals.browser,
}, },
}, },
files: ["**/*.{js,mjs,cjs,jsx,tsx,ts}"], files: ["**/*.{tsx,ts}"],
settings: { settings: {
"better-tailwindcss": { "better-tailwindcss": {
entryPoint: "src/main.css", entryPoint: "src/main.css",
@ -63,4 +61,13 @@ export default [
], ],
}, },
}, },
] as Linter.Config[]; {
files: ["**/*.{js,cjs,mjs,jsx}"],
extends: [tseslint.configs.disableTypeChecked],
languageOptions: {
globals: {
...globals.browser,
},
},
},
);

View file

@ -1,7 +1,6 @@
{ {
"$schema": "https://unpkg.com/knip@5/schema.json", "$schema": "https://unpkg.com/knip@5/schema.json",
"entry": ["src/index.tsx"], "project": ["src/**/*.ts", "src/**/*.tsx"],
"project": ["src/**/*.ts", "src/**/*.tsx", "src/main.css"],
"tailwind": { "tailwind": {
"entry": ["src/main.css"] "entry": ["src/main.css"]
}, },

View file

@ -7,7 +7,8 @@
"format": "run-p 'format:*'", "format": "run-p 'format:*'",
"format:eslint": "eslint --fix .", "format:eslint": "eslint --fix .",
"format:prettier": "prettier --write .", "format:prettier": "prettier --write .",
"build": "bun x @tailwindcss/cli -i ./src/main.css -o ./public/generated.css", "build:js": "tsc",
"build": "bun x @tailwindcss/cli -i ./src/main.css -o ./public/generated.css && bun run build:js",
"lint": "run-p 'lint:*'", "lint": "run-p 'lint:*'",
"lint:tsc": "tsc --noEmit", "lint:tsc": "tsc --noEmit",
"lint:knip": "knip", "lint:knip": "knip",
@ -38,7 +39,6 @@
"@types/bun": "1.2.2", "@types/bun": "1.2.2",
"@types/node": "^24.0.0", "@types/node": "^24.0.0",
"@typescript-eslint/parser": "^8.34.0", "@typescript-eslint/parser": "^8.34.0",
"bun-types": "1.2.17",
"eslint": "^9.28.0", "eslint": "^9.28.0",
"eslint-plugin-better-tailwindcss": "^3.1.0", "eslint-plugin-better-tailwindcss": "^3.1.0",
"eslint-plugin-simple-import-sort": "^12.1.1", "eslint-plugin-simple-import-sort": "^12.1.1",

View file

@ -4,5 +4,6 @@
"lockFileMaintenance": { "lockFileMaintenance": {
"enabled": true, "enabled": true,
"automerge": true "automerge": true
} },
"ignoreDeps": ["bun-types", "@types/bun"]
} }

View file

@ -1,3 +1,4 @@
import { Cookie } from "elysia";
import db from "../db/db"; import db from "../db/db";
import { MAX_CONVERT_PROCESS } from "../helpers/env"; import { MAX_CONVERT_PROCESS } from "../helpers/env";
import { normalizeFiletype, normalizeOutputFiletype } from "../helpers/normalizeFiletype"; import { normalizeFiletype, normalizeOutputFiletype } from "../helpers/normalizeFiletype";
@ -119,11 +120,11 @@ const properties: Record<
}; };
function chunks<T>(arr: T[], size: number): T[][] { function chunks<T>(arr: T[], size: number): T[][] {
if(size <= 0){ if (size <= 0) {
return [arr] return [arr];
} }
return Array.from({ length: Math.ceil(arr.length / size) }, (_: T, i: number) => return Array.from({ length: Math.ceil(arr.length / size) }, (_: T, i: number) =>
arr.slice(i * size, i * size + size) arr.slice(i * size, i * size + size),
); );
} }
@ -133,17 +134,15 @@ export async function handleConvert(
userOutputDir: string, userOutputDir: string,
convertTo: string, convertTo: string,
converterName: string, converterName: string,
jobId: any jobId: Cookie<string | undefined>,
) { ) {
const query = db.query( const query = db.query(
"INSERT INTO file_names (job_id, file_name, output_file_name, status) VALUES (?1, ?2, ?3, ?4)", "INSERT INTO file_names (job_id, file_name, output_file_name, status) VALUES (?1, ?2, ?3, ?4)",
); );
for (const chunk of chunks(fileNames, MAX_CONVERT_PROCESS)) { for (const chunk of chunks(fileNames, MAX_CONVERT_PROCESS)) {
const toProcess: Promise<string>[] = []; const toProcess: Promise<string>[] = [];
for(const fileName of chunk) { for (const fileName of chunk) {
const filePath = `${userUploadsDir}${fileName}`; const filePath = `${userUploadsDir}${fileName}`;
const fileTypeOrig = fileName.split(".").pop() ?? ""; const fileTypeOrig = fileName.split(".").pop() ?? "";
const fileType = normalizeFiletype(fileTypeOrig); const fileType = normalizeFiletype(fileTypeOrig);
@ -155,27 +154,22 @@ export async function handleConvert(
const targetPath = `${userOutputDir}${newFileName}`; const targetPath = `${userOutputDir}${newFileName}`;
toProcess.push( toProcess.push(
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
mainConverter( mainConverter(filePath, fileType, convertTo, targetPath, {}, converterName)
filePath, .then((r) => {
fileType,
convertTo,
targetPath,
{},
converterName,
).then(r => {
if (jobId.value) { if (jobId.value) {
query.run(jobId.value, fileName, newFileName, r); query.run(jobId.value, fileName, newFileName, r);
} }
resolve(r); resolve(r);
}).catch(c => reject(c));
}) })
.catch((c) => reject(c));
}),
); );
} }
await Promise.all(toProcess); await Promise.all(toProcess);
} }
} }
export async function mainConverter( async function mainConverter(
inputFilePath: string, inputFilePath: string,
fileTypeOriginal: string, fileTypeOriginal: string,
convertTo: string, convertTo: string,

View file

@ -16,7 +16,10 @@ export const WEBROOT = process.env.WEBROOT ?? "";
export const LANGUAGE = process.env.LANGUAGE?.toLowerCase() || "en"; export const LANGUAGE = process.env.LANGUAGE?.toLowerCase() || "en";
export const MAX_CONVERT_PROCESS = process.env.MAX_CONVERT_PROCESS && Number(process.env.MAX_CONVERT_PROCESS) > 0 ? Number(process.env.MAX_CONVERT_PROCESS) : 0 export const MAX_CONVERT_PROCESS =
process.env.MAX_CONVERT_PROCESS && Number(process.env.MAX_CONVERT_PROCESS) > 0
? Number(process.env.MAX_CONVERT_PROCESS)
: 0;
export const UNAUTHENTICATED_USER_SHARING = export const UNAUTHENTICATED_USER_SHARING =
process.env.UNAUTHENTICATED_USER_SHARING?.toLowerCase() === "true" || false; process.env.UNAUTHENTICATED_USER_SHARING?.toLowerCase() === "true" || false;

View file

@ -46,6 +46,11 @@ export const convert = new Elysia().use(userService).post(
const convertTo = normalizeFiletype(body.convert_to.split(",")[0] ?? ""); const convertTo = normalizeFiletype(body.convert_to.split(",")[0] ?? "");
const converterName = body.convert_to.split(",")[1]; const converterName = body.convert_to.split(",")[1];
if (!converterName) {
return redirect(`${WEBROOT}/`, 302);
}
const fileNames = JSON.parse(body.file_names) as string[]; const fileNames = JSON.parse(body.file_names) as string[];
for (let i = 0; i < fileNames.length; i++) { for (let i = 0; i < fileNames.length; i++) {

View file

@ -1,11 +1,11 @@
import path from "node:path";
import { Elysia } from "elysia"; import { Elysia } from "elysia";
import sanitize from "sanitize-filename"; import sanitize from "sanitize-filename";
import * as tar from "tar";
import { outputDir } from ".."; import { outputDir } from "..";
import db from "../db/db"; import db from "../db/db";
import { WEBROOT } from "../helpers/env"; import { WEBROOT } from "../helpers/env";
import { userService } from "./user"; import { userService } from "./user";
import path from "node:path";
import * as tar from "tar";
export const download = new Elysia() export const download = new Elysia()
.use(userService) .use(userService)
@ -58,8 +58,17 @@ export const download = new Elysia()
const userId = decodeURIComponent(params.userId); const userId = decodeURIComponent(params.userId);
const jobId = decodeURIComponent(params.jobId); const jobId = decodeURIComponent(params.jobId);
const outputPath = `${outputDir}${userId}/${jobId}`; const outputPath = `${outputDir}${userId}/${jobId}`;
const outputTar = path.join(outputPath, `converted_files_${jobId}.tar`) const outputTar = path.join(outputPath, `converted_files_${jobId}.tar`);
await tar.create({file: outputTar, cwd: outputPath, filter: (path) => { return !path.match(".*\\.tar"); }}, ["."]); await tar.create(
{
file: outputTar,
cwd: outputPath,
filter: (path) => {
return !path.match(".*\\.tar");
},
},
["."],
);
return Bun.file(outputTar); return Bun.file(outputTar);
}); });

View file

@ -1,4 +1,5 @@
import { Html } from "@elysiajs/html"; import { Html } from "@elysiajs/html";
import { JWTPayloadSpec } from "@elysiajs/jwt";
import { Elysia } from "elysia"; import { Elysia } from "elysia";
import { BaseHtml } from "../components/base"; import { BaseHtml } from "../components/base";
import { Header } from "../components/header"; import { Header } from "../components/header";
@ -6,7 +7,6 @@ import db from "../db/db";
import { Filename, Jobs } from "../db/types"; import { Filename, Jobs } from "../db/types";
import { ALLOW_UNAUTHENTICATED, WEBROOT } from "../helpers/env"; import { ALLOW_UNAUTHENTICATED, WEBROOT } from "../helpers/env";
import { userService } from "./user"; import { userService } from "./user";
import { JWTPayloadSpec } from "@elysiajs/jwt";
function ResultsArticle({ function ResultsArticle({
user, user,

View file

@ -34,7 +34,9 @@ export const root = new Elysia()
let user: ({ id: string } & JWTPayloadSpec) | false = false; let user: ({ id: string } & JWTPayloadSpec) | false = false;
if (ALLOW_UNAUTHENTICATED) { if (ALLOW_UNAUTHENTICATED) {
const newUserId = String( const newUserId = String(
UNAUTHENTICATED_USER_SHARING ? 0 : randomInt(2 ** 24, Math.min(2 ** 48 + 2 ** 24 - 1, Number.MAX_SAFE_INTEGER)), UNAUTHENTICATED_USER_SHARING
? 0
: randomInt(2 ** 24, Math.min(2 ** 48 + 2 ** 24 - 1, Number.MAX_SAFE_INTEGER)),
); );
const accessToken = await jwt.sign({ const accessToken = await jwt.sign({
id: newUserId, id: newUserId,

View file

@ -5,8 +5,9 @@
"target": "ES2021", "target": "ES2021",
"moduleResolution": "bundler", "moduleResolution": "bundler",
"moduleDetection": "force", "moduleDetection": "force",
"allowImportingTsExtensions": true, // "allowImportingTsExtensions": true,
"noEmit": true, "outDir": "dist",
"noEmit": false,
"composite": true, "composite": true,
"strict": true, "strict": true,
"downlevelIteration": true, "downlevelIteration": true,
@ -24,7 +25,10 @@
// "noUnusedParameters": true, // "noUnusedParameters": true,
"exactOptionalPropertyTypes": true, "exactOptionalPropertyTypes": true,
"noFallthroughCasesInSwitch": true, "noFallthroughCasesInSwitch": true,
"noImplicitOverride": true "noImplicitOverride": true,
"resolveJsonModule": true,
"esModuleInterop": true
// "noImplicitReturns": true // "noImplicitReturns": true
} },
"include": ["src", "package.json", "reset.d.ts"]
} }