mirror of
https://github.com/C4illin/ConvertX.git
synced 2025-11-05 06:23:18 +00:00
Compare commits
211 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
883fad806b | ||
|
|
feacd1b816 | ||
|
|
094e7a0d1c | ||
|
|
72636c5059 | ||
|
|
291cfc80c6 | ||
|
|
ae1dfafc9d | ||
|
|
6caa583c35 | ||
|
|
2057167576 | ||
|
|
1c9e67fc32 | ||
|
|
d3af9688c6 | ||
|
|
7d0cbb9844 | ||
|
|
88173891ba | ||
|
|
2b4b8f9551 | ||
|
|
63a4328d4a | ||
|
|
413f5dc7b4 | ||
|
|
ebccdf9169 | ||
|
|
47139a550b | ||
|
|
fa5446c446 | ||
|
|
8772e582b0 | ||
|
|
45922ed3a3 | ||
|
|
4c747e8908 | ||
|
|
e573997aa9 | ||
|
|
c57b69991c | ||
|
|
eee983a56a | ||
|
|
22f823c535 | ||
|
|
ed59cd7aa4 | ||
|
|
b28977ffe2 | ||
|
|
a47bb682a5 | ||
|
|
a17eca0a09 | ||
|
|
ea9250543e | ||
|
|
317c932c2a | ||
|
|
5b1703db68 | ||
|
|
60ba7c93fb | ||
|
|
22227130dd | ||
|
|
5daf66f5d0 | ||
|
|
aee1962607 | ||
|
|
0d42762b36 | ||
|
|
b97b12b449 | ||
|
|
bdf651df82 | ||
|
|
267ef14789 | ||
|
|
905adc5e1c | ||
|
|
52ed7274e9 | ||
|
|
a29238c265 | ||
|
|
48c6fb79fc | ||
|
|
8358396656 | ||
|
|
b30e5800c3 | ||
|
|
21a1b50ed8 | ||
|
|
e6a94fb21d | ||
|
|
bef1710e33 | ||
|
|
16b322d4e6 | ||
|
|
9bf64e42d5 | ||
|
|
5988fe8212 | ||
|
|
5df9c0b751 | ||
|
|
136a8b2d74 | ||
|
|
ccfb574d5d | ||
|
|
ad6eedea69 | ||
|
|
c3082db8f7 | ||
|
|
a1f8cbae66 | ||
|
|
bb34bdee87 | ||
|
|
11fcbc3f96 | ||
|
|
f7344e4c65 | ||
|
|
781310f3dc | ||
|
|
3f063644f2 | ||
|
|
081634b610 | ||
|
|
cf3da08c73 | ||
|
|
5f7234d6c1 | ||
|
|
6597c1d7ca | ||
|
|
ecb2c75008 | ||
|
|
d5eeef9f68 | ||
|
|
7456174022 | ||
|
|
bc4ad49285 | ||
|
|
f0d0e43929 | ||
|
|
8ca4f1587d | ||
|
|
1535377bfe | ||
|
|
83bf78fd57 | ||
|
|
4d9c4d64aa | ||
|
|
53fff594fc | ||
|
|
fe4aeaff03 | ||
|
|
2078cb0ee0 | ||
|
|
86a61d35d7 | ||
|
|
96fa7e2f55 | ||
|
|
7d2af46b0b | ||
|
|
57e2999866 | ||
|
|
6fb8ca4d82 | ||
|
|
c295e546bd | ||
|
|
f7abb9389c | ||
|
|
d7de154eda | ||
|
|
20bd111765 | ||
|
|
eadd0da291 | ||
|
|
52294465fb | ||
|
|
049e9163ce | ||
|
|
d466d2dbbc | ||
|
|
3f79ccaa2a | ||
|
|
1e9bde18c7 | ||
|
|
9af23346bf | ||
|
|
d310341fca | ||
|
|
d88a755c13 | ||
|
|
7c6085c685 | ||
|
|
7ed1ad21f2 | ||
|
|
8a2237fbd9 | ||
|
|
0e363f0731 | ||
|
|
4074647b67 | ||
|
|
c84968be50 | ||
|
|
0e53a99d43 | ||
|
|
bdd0cf556f | ||
|
|
2483274388 | ||
|
|
4c5129910a | ||
|
|
fe13a1b736 | ||
|
|
f1ac71b397 | ||
|
|
1b1067a03f | ||
|
|
8674557e42 | ||
|
|
87052ce105 | ||
|
|
98ee26f6e2 | ||
|
|
96e2c88465 | ||
|
|
d55ba218ff | ||
|
|
ae2455e73e | ||
|
|
b9fe32053c | ||
|
|
5cf3d74e03 | ||
|
|
2b92778f37 | ||
|
|
27d4da8941 | ||
|
|
2384e22c22 | ||
|
|
6690caeb1e | ||
|
|
c714ade3e2 | ||
|
|
e9e95c61e9 | ||
|
|
b1e0e68d9c | ||
|
|
5ce3706550 | ||
|
|
57e47e95c0 | ||
|
|
6d6bc6cfdd | ||
|
|
b44eb22e77 | ||
|
|
6edfbaa27d | ||
|
|
d669baeff4 | ||
|
|
ec1a7bc015 | ||
|
|
0805241a19 | ||
|
|
83f041daa2 | ||
|
|
55331a4496 | ||
|
|
b53f07e7a7 | ||
|
|
0eb89ae712 | ||
|
|
7dd153b02c | ||
|
|
6ccafeb3b0 | ||
|
|
b703903b22 | ||
|
|
9e66eab0a2 | ||
|
|
b272bf9504 | ||
|
|
56632f3500 | ||
|
|
2d9d8f8b4f | ||
|
|
65d4e0fbbe | ||
|
|
8182d12ea0 | ||
|
|
1c241d4cad | ||
|
|
874ff6ee00 | ||
|
|
e9f1219ad9 | ||
|
|
4811452aec | ||
|
|
382ebad35a | ||
|
|
85945256e7 | ||
|
|
c504692569 | ||
|
|
64a16036be | ||
|
|
b9f038386f | ||
|
|
945775e52b | ||
|
|
e7f3466736 | ||
|
|
ee80eeb18d | ||
|
|
34c7e0bd25 | ||
|
|
492dbd5617 | ||
|
|
0935bf66ce | ||
|
|
7389e0a059 | ||
|
|
c512b45f91 | ||
|
|
3ae2db5d9b | ||
|
|
0945b40a9c | ||
|
|
20b958e547 | ||
|
|
e7e146c6c9 | ||
|
|
005ad2d66b | ||
|
|
e5c3a8acc4 | ||
|
|
87ecbabd1f | ||
|
|
991c4e4ba8 | ||
|
|
87ccd8b44c | ||
|
|
83e6699ca6 | ||
|
|
c91523c038 | ||
|
|
1f73f036b2 | ||
|
|
1223fabfca | ||
|
|
8a42a39e69 | ||
|
|
22023bad25 | ||
|
|
db2f2d8f0a | ||
|
|
d0fa9ac408 | ||
|
|
776a97289b | ||
|
|
95340dd0eb | ||
|
|
7dcd74cc5f | ||
|
|
c5efac9423 | ||
|
|
cceca9a924 | ||
|
|
4d4c13a8d8 | ||
|
|
f8f90ebd69 | ||
|
|
648d5070e2 | ||
|
|
801cf28d1e | ||
|
|
fae2ba9c54 | ||
|
|
10d20a8786 | ||
|
|
c9bc1e237e | ||
|
|
48a76a46b3 | ||
|
|
4dcb796e1b | ||
|
|
5952103bcd | ||
|
|
fd05ee5cd5 | ||
|
|
7e7d238c7a | ||
|
|
755a4170f2 | ||
|
|
263ba415f5 | ||
|
|
317260098a | ||
|
|
5304e94b4e | ||
|
|
aab2b311cf | ||
|
|
baa7ea40e6 | ||
|
|
481a11b610 | ||
|
|
c09fe296b1 | ||
|
|
f023aae753 | ||
|
|
5cd9544b55 | ||
|
|
97c23ba65c | ||
|
|
0ffda40ac8 | ||
|
|
cb639907ee | ||
|
|
0166842b78 |
7
.deepsource.toml
Normal file
7
.deepsource.toml
Normal file
@@ -0,0 +1,7 @@
|
||||
version = 1
|
||||
|
||||
[[analyzers]]
|
||||
name = "javascript"
|
||||
|
||||
[analyzers.meta]
|
||||
environment = ["nodejs"]
|
||||
@@ -1,55 +0,0 @@
|
||||
/** @type {import("eslint").Linter.Config} */
|
||||
const config = {
|
||||
root: true,
|
||||
parser: "@typescript-eslint/parser",
|
||||
plugins: ["isaacscript", "import"],
|
||||
extends: [
|
||||
"plugin:@typescript-eslint/recommended-type-checked",
|
||||
"plugin:@typescript-eslint/stylistic-type-checked",
|
||||
"plugin:prettier/recommended",
|
||||
],
|
||||
parserOptions: {
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
tsconfigRootDir: __dirname,
|
||||
project: [
|
||||
"./tsconfig.json",
|
||||
"./cli/tsconfig.eslint.json", // separate eslint config for the CLI since we want to lint and typecheck differently due to template files
|
||||
"./upgrade/tsconfig.json",
|
||||
"./www/tsconfig.json",
|
||||
],
|
||||
},
|
||||
overrides: [
|
||||
// Template files don't have reliable type information
|
||||
{
|
||||
files: ["./cli/template/**/*.{ts,tsx}"],
|
||||
extends: ["plugin:@typescript-eslint/disable-type-checked"],
|
||||
},
|
||||
],
|
||||
rules: {
|
||||
// These off/not-configured-the-way-we-want lint rules we like & opt into
|
||||
"@typescript-eslint/no-explicit-any": "error",
|
||||
"@typescript-eslint/no-unused-vars": [
|
||||
"error",
|
||||
{ argsIgnorePattern: "^_", destructuredArrayIgnorePattern: "^_" },
|
||||
],
|
||||
"@typescript-eslint/consistent-type-imports": [
|
||||
"error",
|
||||
{ prefer: "type-imports", fixStyle: "inline-type-imports" },
|
||||
],
|
||||
"import/consistent-type-specifier-style": ["error", "prefer-inline"],
|
||||
|
||||
// For educational purposes we format our comments/jsdoc nicely
|
||||
"isaacscript/complete-sentences-jsdoc": "warn",
|
||||
"isaacscript/format-jsdoc-comments": "warn",
|
||||
|
||||
// These lint rules don't make sense for us but are enabled in the preset configs
|
||||
"@typescript-eslint/no-confusing-void-expression": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
|
||||
// This rule doesn't seem to be working properly
|
||||
"@typescript-eslint/prefer-nullish-coalescing": "off",
|
||||
},
|
||||
};
|
||||
|
||||
module.exports = config;
|
||||
23
.github/dependabot.yml
vendored
23
.github/dependabot.yml
vendored
@@ -1,23 +0,0 @@
|
||||
# To get started with Dependabot version updates, you'll need to specify which
|
||||
# package ecosystems to update and where the package manifests are located.
|
||||
# Please see the documentation for all configuration options:
|
||||
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
|
||||
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: npm
|
||||
versioning-strategy: increase
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: daily
|
||||
commit-message:
|
||||
prefix: "build"
|
||||
include: "scope"
|
||||
open-pull-requests-limit: 10
|
||||
- package-ecosystem: github-actions
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: weekly
|
||||
commit-message:
|
||||
prefix: "build"
|
||||
include: "scope"
|
||||
28
.github/workflows/bun-dependabot.yml
vendored
28
.github/workflows/bun-dependabot.yml
vendored
@@ -1,28 +0,0 @@
|
||||
name: 'Dependabot: Update bun.lockb'
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "package.json"
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
jobs:
|
||||
update-bun-lockb:
|
||||
name: "Update bun.lockb"
|
||||
if: github.actor == 'dependabot[bot]'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: oven-sh/setup-bun@v1
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
- run: |
|
||||
bun install
|
||||
git add bun.lockb
|
||||
git config --global user.name 'dependabot[bot]'
|
||||
git config --global user.email 'dependabot[bot]@users.noreply.github.com'
|
||||
git commit --amend --no-edit
|
||||
git push --force
|
||||
3
.github/workflows/docker-publish.yml
vendored
3
.github/workflows/docker-publish.yml
vendored
@@ -58,9 +58,10 @@ jobs:
|
||||
# https://github.com/docker/build-push-action
|
||||
- name: Build and push Docker image
|
||||
id: build-and-push
|
||||
uses: docker/build-push-action@v5
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: .
|
||||
platforms: linux/amd64,linux/arm64
|
||||
push: ${{ github.event_name != 'pull_request' }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
4
.github/workflows/release-please.yml
vendored
4
.github/workflows/release-please.yml
vendored
@@ -18,8 +18,8 @@ jobs:
|
||||
# this assumes that you have created a personal access token
|
||||
# (PAT) and configured it as a GitHub action secret named
|
||||
# `MY_RELEASE_PLEASE_TOKEN` (this secret name is not important).
|
||||
# token: ${{ secrets.MY_RELEASE_PLEASE_TOKEN }}
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
token: ${{ secrets.MY_RELEASE_PLEASE_TOKEN }}
|
||||
# token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# this is a built-in strategy in release-please, see "Action Inputs"
|
||||
# for more options
|
||||
release-type: node
|
||||
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -46,4 +46,6 @@ package-lock.json
|
||||
/output
|
||||
/db
|
||||
/data
|
||||
/Bruno
|
||||
/Bruno
|
||||
/tsconfig.tsbuildinfo
|
||||
/src/public/generated.css
|
||||
4
.vscode/settings.json
vendored
Normal file
4
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"typescript.tsdk": "node_modules/typescript/lib",
|
||||
"typescript.enablePromptUseWorkspaceTsdk": true
|
||||
}
|
||||
104
CHANGELOG.md
104
CHANGELOG.md
@@ -1,5 +1,109 @@
|
||||
# Changelog
|
||||
|
||||
## [0.8.0](https://github.com/C4illin/ConvertX/compare/v0.7.0...v0.8.0) (2024-09-30)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add light theme, fixes [#156](https://github.com/C4illin/ConvertX/issues/156) ([72636c5](https://github.com/C4illin/ConvertX/commit/72636c5059ebf09c8fece2e268293650b2f8ccf6))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add support for usd for assimp, [#144](https://github.com/C4illin/ConvertX/issues/144) ([2057167](https://github.com/C4illin/ConvertX/commit/20571675766209ad1251f07e687d29a6791afc8b))
|
||||
* cleanup formats and add opus, fixes [#159](https://github.com/C4illin/ConvertX/issues/159) ([ae1dfaf](https://github.com/C4illin/ConvertX/commit/ae1dfafc9d9116a57b08c2f7fc326990e00824b0))
|
||||
* support .awb and clean up, fixes [#153](https://github.com/C4illin/ConvertX/issues/153), [#92](https://github.com/C4illin/ConvertX/issues/92) ([1c9e67f](https://github.com/C4illin/ConvertX/commit/1c9e67fc3201e0e5dee91e8981adf34daaabf33a))
|
||||
|
||||
## [0.7.0](https://github.com/C4illin/ConvertX/compare/v0.6.0...v0.7.0) (2024-09-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* Add support for 3d assets through assimp converter ([63a4328](https://github.com/C4illin/ConvertX/commit/63a4328d4a1e01df3e0ec4a877bad8c8ffe71129))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* wrong layout on search with few options ([8817389](https://github.com/C4illin/ConvertX/commit/88173891ba2d69da46eda46f3f598a9b54f26f96))
|
||||
|
||||
## [0.6.0](https://github.com/C4illin/ConvertX/compare/v0.5.0...v0.6.0) (2024-09-25)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* ui remake with tailwind ([22f823c](https://github.com/C4illin/ConvertX/commit/22f823c535b20382981f86a13616b830a1f3392f))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* rename css file to force update cache, fixes [#141](https://github.com/C4illin/ConvertX/issues/141) ([47139a5](https://github.com/C4illin/ConvertX/commit/47139a550bd3d847da288c61bf8f88953b79c673))
|
||||
|
||||
## [0.5.0](https://github.com/C4illin/ConvertX/compare/v0.4.1...v0.5.0) (2024-09-20)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add option to customize how often files are automatically deleted ([317c932](https://github.com/C4illin/ConvertX/commit/317c932c2a26280bf37ed3d3bf9b879413590f5a))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* improve file name replacement logic ([60ba7c9](https://github.com/C4illin/ConvertX/commit/60ba7c93fbdc961f3569882fade7cc13dee7a7a5))
|
||||
|
||||
## [0.4.1](https://github.com/C4illin/ConvertX/compare/v0.4.0...v0.4.1) (2024-09-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow non lowercase true and false values, fixes [#122](https://github.com/C4illin/ConvertX/issues/122) ([bef1710](https://github.com/C4illin/ConvertX/commit/bef1710e3376baa7e25c107ded20a40d18b8c6b0))
|
||||
|
||||
## [0.4.0](https://github.com/C4illin/ConvertX/compare/v0.3.3...v0.4.0) (2024-08-26)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add option for unauthenticated file conversions [#114](https://github.com/C4illin/ConvertX/issues/114) ([f0d0e43](https://github.com/C4illin/ConvertX/commit/f0d0e4392983c3e4c530304ea88e023fda9bcac0))
|
||||
* add resvg converter ([d5eeef9](https://github.com/C4illin/ConvertX/commit/d5eeef9f6884b2bb878508bed97ea9ceaa662995))
|
||||
* add robots.txt ([6597c1d](https://github.com/C4illin/ConvertX/commit/6597c1d7caeb4dfb6bc47b442e4dfc9840ad12b7))
|
||||
* Add search bar for formats ([53fff59](https://github.com/C4illin/ConvertX/commit/53fff594fc4d69306abcb2a5cad890fcd0953a58))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* keep unauthenticated user logged in if allowed [#114](https://github.com/C4illin/ConvertX/issues/114) ([bc4ad49](https://github.com/C4illin/ConvertX/commit/bc4ad492852fad8cb832a0c03485cccdd7f7b117))
|
||||
* pdf support in vips ([8ca4f15](https://github.com/C4illin/ConvertX/commit/8ca4f1587df7f358893941c656d78d75f04dac93))
|
||||
* Slow click on conversion popup does not work ([4d9c4d6](https://github.com/C4illin/ConvertX/commit/4d9c4d64aa0266f3928935ada68d91ac81f638aa))
|
||||
|
||||
## [0.3.3](https://github.com/C4illin/ConvertX/compare/v0.3.2...v0.3.3) (2024-07-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* downgrade @elysiajs/html dependency to version 1.0.2 ([c714ade](https://github.com/C4illin/ConvertX/commit/c714ade3e23865ba6cfaf76c9e7259df1cda222c))
|
||||
|
||||
## [0.3.2](https://github.com/C4illin/ConvertX/compare/v0.3.1...v0.3.2) (2024-07-09)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* increase max request body to support large uploads ([3ae2db5](https://github.com/C4illin/ConvertX/commit/3ae2db5d9b36fe3dcd4372ddcd32aa573ea59aa6)), closes [#64](https://github.com/C4illin/ConvertX/issues/64)
|
||||
|
||||
## [0.3.1](https://github.com/C4illin/ConvertX/compare/v0.3.0...v0.3.1) (2024-06-27)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* release releases ([4d4c13a](https://github.com/C4illin/ConvertX/commit/4d4c13a8d85ec7c9209ad41cdbea7d4380b0edbf))
|
||||
|
||||
## [0.3.0](https://github.com/C4illin/ConvertX/compare/v0.2.0...v0.3.0) (2024-06-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add version number to log ([4dcb796](https://github.com/C4illin/ConvertX/commit/4dcb796e1bd27badc078d0638076cd9f1e81c4a4)), closes [#44](https://github.com/C4illin/ConvertX/issues/44)
|
||||
* change to xelatex ([fae2ba9](https://github.com/C4illin/ConvertX/commit/fae2ba9c54461dccdccd1bfb5e76398540d11d0b))
|
||||
* print version of installed converters to log ([801cf28](https://github.com/C4illin/ConvertX/commit/801cf28d1e5edac9353b0b16be75a4fb48470b8a))
|
||||
|
||||
## [0.2.0](https://github.com/C4illin/ConvertX/compare/v0.1.2...v0.2.0) (2024-06-20)
|
||||
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
FROM oven/bun:1-debian as base
|
||||
WORKDIR /app
|
||||
|
||||
# install dependencies into temp directory
|
||||
# this will cache them and speed up future builds
|
||||
FROM base AS install
|
||||
RUN mkdir -p /temp/dev
|
||||
COPY package.json bun.lockb /temp/dev/
|
||||
RUN cd /temp/dev && bun install --frozen-lockfile
|
||||
|
||||
# install with --production (exclude devDependencies)
|
||||
RUN mkdir -p /temp/prod
|
||||
COPY package.json bun.lockb /temp/prod/
|
||||
RUN cd /temp/prod && bun install --frozen-lockfile --production
|
||||
|
||||
# FROM base AS install-libjxl-tools
|
||||
# download
|
||||
|
||||
|
||||
|
||||
# copy node_modules from temp directory
|
||||
# then copy all (non-ignored) project files into the image
|
||||
# FROM base AS prerelease
|
||||
# COPY --from=install /temp/dev/node_modules node_modules
|
||||
# COPY . .
|
||||
|
||||
# # [optional] tests & build
|
||||
# ENV NODE_ENV=production
|
||||
# RUN bun test
|
||||
# RUN bun run build
|
||||
|
||||
# copy production dependencies and source code into final image
|
||||
FROM base AS release
|
||||
LABEL maintainer="Emrik Östling (C4illin)"
|
||||
LABEL description="ConvertX: self-hosted online file converter supporting 700+ file formats."
|
||||
LABEL repo="https://github.com/C4illin/ConvertX"
|
||||
|
||||
# install additional dependencies
|
||||
RUN rm -rf /var/lib/apt/lists/partial && apt-get update -o Acquire::CompressionTypes::Order::=gz \
|
||||
&& apt-get install -y \
|
||||
pandoc \
|
||||
texlive-latex-recommended \
|
||||
texlive-fonts-recommended \
|
||||
texlive-latex-extra \
|
||||
ffmpeg \
|
||||
graphicsmagick \
|
||||
ghostscript \
|
||||
libvips-tools
|
||||
|
||||
# # libjxl is not available in the official debian repositories
|
||||
# RUN wget https://github.com/libjxl/libjxl/releases/download/v0.10.2/jxl-debs-amd64-debian-bullseye-v0.10.2.tar.gz -O /tmp/jxl-debs-amd64-debian-bullseye-v0.10.2.tar.gz \
|
||||
# && mkdir -p /tmp/libjxl \
|
||||
# && tar -xvf /tmp/jxl-debs-amd64-debian-bullseye-v0.10.2.tar.gz -C /tmp/libjxl \
|
||||
# && dpkg -i /tmp/libjxl/libjxl_0.10.2_amd64.deb /tmp/libjxl/jxl_0.10.2_amd64.deb \
|
||||
# && rm -rf /tmp/jxl-debs-amd64-debian-bullseye-v0.10.2.tar.gz /tmp/libjxl
|
||||
|
||||
COPY --from=install /temp/prod/node_modules node_modules
|
||||
# COPY --from=prerelease /app/src/index.tsx /app/src/
|
||||
# COPY --from=prerelease /app/package.json .
|
||||
COPY . .
|
||||
|
||||
EXPOSE 3000/tcp
|
||||
ENTRYPOINT [ "bun", "run", "./src/index.tsx" ]
|
||||
28
Dockerfile
28
Dockerfile
@@ -1,4 +1,5 @@
|
||||
FROM oven/bun:1-alpine as base
|
||||
FROM oven/bun:1.1.29-alpine AS base
|
||||
LABEL org.opencontainers.image.source="https://github.com/C4illin/ConvertX"
|
||||
WORKDIR /app
|
||||
|
||||
# install dependencies into temp directory
|
||||
@@ -13,16 +14,22 @@ RUN mkdir -p /temp/prod
|
||||
COPY package.json bun.lockb /temp/prod/
|
||||
RUN cd /temp/prod && bun install --frozen-lockfile --production
|
||||
|
||||
FROM base AS builder
|
||||
RUN apk --no-cache add curl gcc
|
||||
ENV PATH=/root/.cargo/bin:$PATH
|
||||
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
||||
RUN cargo install resvg
|
||||
|
||||
# copy node_modules from temp directory
|
||||
# then copy all (non-ignored) project files into the image
|
||||
# FROM base AS prerelease
|
||||
# COPY --from=install /temp/dev/node_modules node_modules
|
||||
# COPY . .
|
||||
FROM base AS prerelease
|
||||
COPY --from=install /temp/dev/node_modules node_modules
|
||||
COPY . .
|
||||
|
||||
# # [optional] tests & build
|
||||
# ENV NODE_ENV=production
|
||||
ENV NODE_ENV=production
|
||||
# RUN bun test
|
||||
# RUN bun run build
|
||||
RUN bun run build
|
||||
|
||||
# copy production dependencies and source code into final image
|
||||
FROM base AS release
|
||||
@@ -34,20 +41,27 @@ LABEL repo="https://github.com/C4illin/ConvertX"
|
||||
RUN apk --no-cache add \
|
||||
pandoc \
|
||||
texlive \
|
||||
texlive-xetex \
|
||||
texmf-dist-latexextra \
|
||||
ffmpeg \
|
||||
graphicsmagick \
|
||||
ghostscript \
|
||||
vips-tools \
|
||||
libjxl-tools
|
||||
vips-poppler \
|
||||
vips-jxl \
|
||||
libjxl-tools \
|
||||
assimp
|
||||
|
||||
# this might be needed for some latex use cases, will add it if needed.
|
||||
# texmf-dist-fontsextra \
|
||||
|
||||
COPY --from=install /temp/prod/node_modules node_modules
|
||||
COPY --from=builder /root/.cargo/bin/resvg /usr/local/bin/resvg
|
||||
COPY --from=prerelease /app/src/public/generated.css /app/src/public/
|
||||
# COPY --from=prerelease /app/src/index.tsx /app/src/
|
||||
# COPY --from=prerelease /app/package.json .
|
||||
COPY . .
|
||||
|
||||
EXPOSE 3000/tcp
|
||||
ENV NODE_ENV=production
|
||||
ENTRYPOINT [ "bun", "run", "./src/index.tsx" ]
|
||||
40
README.md
40
README.md
@@ -7,11 +7,12 @@
|
||||

|
||||

|
||||
|
||||
A self-hosted online file converter. Supports 831 different formats. Written with TypeScript, Bun and Elysia.
|
||||
A self-hosted online file converter. Supports over a thousand different formats. Written with TypeScript, Bun and Elysia.
|
||||
|
||||
## Features
|
||||
|
||||
- Convert files to different formats
|
||||
- Process multiple files at once
|
||||
- Password protection
|
||||
- Multiple accounts
|
||||
|
||||
@@ -20,14 +21,18 @@ A self-hosted online file converter. Supports 831 different formats. Written wit
|
||||
| Converter | Use case | Converts from | Converts to |
|
||||
|------------------------------------------------------------------------------|---------------|---------------|-------------|
|
||||
| [libjxl](https://github.com/libjxl/libjxl) | JPEG XL | 11 | 11 |
|
||||
| [resvg](https://github.com/RazrFalcon/resvg) | SVG | 1 | 1 |
|
||||
| [Vips](https://github.com/libvips/libvips) | Images | 45 | 23 |
|
||||
| [PDFLaTeX](https://www.math.rug.nl/~trentelman/jacob/pdflatex/pdflatex.html) | Documents | 1 | 1 |
|
||||
| [Assimp](https://github.com/assimp/assimp) | 3D Assets | 70 | 24 |
|
||||
| [XeLaTeX](https://tug.org/xetex/) | LaTeX | 1 | 1 |
|
||||
| [Pandoc](https://pandoc.org/) | Documents | 43 | 65 |
|
||||
| [GraphicsMagick](http://www.graphicsmagick.org/) | Images | 166 | 133 |
|
||||
| [FFmpeg](https://ffmpeg.org/) | Video | ~473 | ~280 |
|
||||
|
||||
<!-- many ffmpeg fileformats are duplicates -->
|
||||
|
||||
Any missing converter? Open an issue or pull request!
|
||||
|
||||
## Deployment
|
||||
|
||||
```yml
|
||||
@@ -35,21 +40,25 @@ A self-hosted online file converter. Supports 831 different formats. Written wit
|
||||
services:
|
||||
convertx:
|
||||
image: ghcr.io/c4illin/convertx
|
||||
container_name: convertx
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
- "3000:3000"
|
||||
environment: # Defaults are listed below. All are optional.
|
||||
- ACCOUNT_REGISTRATION=false # 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
|
||||
- ALLOW_UNAUTHENTICATED=false # allows anyone to use the service without logging in, only set this to true locally
|
||||
- AUTO_DELETE_EVERY_N_HOURS=24 # checks every n hours for files older then n hours and deletes them, set to 0 to disable
|
||||
volumes:
|
||||
- convertx:/app/data
|
||||
```
|
||||
|
||||
<!-- or
|
||||
or
|
||||
|
||||
```bash
|
||||
docker run ghcr.io/c4illin/convertx:master -p 3000:3000 -e ACCOUNT_REGISTRATION=false -v /path/you/want:/app/data
|
||||
``` -->
|
||||
docker run -p 3000:3000 -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.
|
||||
|
||||
@@ -59,14 +68,31 @@ If you get unable to open database file run `chown -R $USER:$USER path` on the p
|
||||
|
||||
Tutorial in french: https://belginux.com/installer-convertx-avec-docker/
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||
|
||||
## Development
|
||||
|
||||
0. Install [Bun](https://bun.sh/) and Git
|
||||
1. Clone the repository
|
||||
2. `bun install`
|
||||
3. `bun run dev`
|
||||
|
||||
Pull requests are welcome! See below and open issues for the list of todos.
|
||||
|
||||
## Todo
|
||||
- [x] Add messages for errors in converters
|
||||
- [x] Add searchable list of formats
|
||||
- [ ] Add options for converters
|
||||
- [ ] Add more converters
|
||||
- [ ] Divide index.tsx into smaller components
|
||||
- [ ] Add tests
|
||||
- [ ] Add searchable list of formats
|
||||
- [ ] Make the upload button nicer and more easy to drop files on. Support copy paste as well if possible.
|
||||
- [ ] Make errors logs visible from the web ui
|
||||
- [ ] Add more converters:
|
||||
- [ ] [deark](https://github.com/jsummers/deark)
|
||||
- [ ] LibreOffice
|
||||
- [ ] [dvisvgm](https://github.com/mgieseki/dvisvgm)
|
||||
|
||||
## Contributors
|
||||
|
||||
|
||||
23
biome.json
23
biome.json
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "https://biomejs.dev/schemas/1.7.3/schema.json",
|
||||
"$schema": "./node_modules/@biomejs/biome/configuration_schema.json",
|
||||
"formatter": {
|
||||
"enabled": true,
|
||||
"formatWithErrors": true,
|
||||
@@ -9,7 +9,15 @@
|
||||
"lineWidth": 80,
|
||||
"attributePosition": "auto"
|
||||
},
|
||||
"organizeImports": { "enabled": true },
|
||||
"files": {
|
||||
"ignore": [
|
||||
"**/node_modules/**",
|
||||
"**/pico.lime.min.css"
|
||||
]
|
||||
},
|
||||
"organizeImports": {
|
||||
"enabled": true
|
||||
},
|
||||
"linter": {
|
||||
"enabled": true,
|
||||
"rules": {
|
||||
@@ -22,7 +30,11 @@
|
||||
"useLiteralKeys": "error",
|
||||
"useOptionalChain": "error"
|
||||
},
|
||||
"correctness": { "noPrecisionLoss": "error", "noUnusedVariables": "off" },
|
||||
"correctness": {
|
||||
"noPrecisionLoss": "error",
|
||||
"noUnusedVariables": "off",
|
||||
"useJsxKeyInIterable": "off"
|
||||
},
|
||||
"style": {
|
||||
"noInferrableTypes": "error",
|
||||
"noNamespace": "error",
|
||||
@@ -42,6 +54,9 @@
|
||||
"noUnsafeDeclarationMerging": "error",
|
||||
"useAwait": "error",
|
||||
"useNamespaceKeyword": "error"
|
||||
},
|
||||
"nursery": {
|
||||
"useSortedClasses": "error"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -57,4 +72,4 @@
|
||||
"attributePosition": "auto"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,8 +5,11 @@ services:
|
||||
# dockerfile: Debian.Dockerfile
|
||||
volumes:
|
||||
- ./data:/app/data
|
||||
environment:
|
||||
- ACCOUNT_REGISTRATION=true
|
||||
- JWT_SECRET=aLongAndSecretStringUsedToSignTheJSONWebToken1234
|
||||
environment: # Defaults are listed below. All are optional.
|
||||
- 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=true # setting this to true is unsafe, only set this to true locally
|
||||
- ALLOW_UNAUTHENTICATED=true # allows anyone to use the service without logging in, only set this to true locally
|
||||
- AUTO_DELETE_EVERY_N_HOURS=1 # checks every n hours for files older then n hours and deletes them, set to 0 to disable
|
||||
ports:
|
||||
- 3000:3000
|
||||
|
||||
55
eslint.config.js
Normal file
55
eslint.config.js
Normal file
@@ -0,0 +1,55 @@
|
||||
import comments from "@eslint-community/eslint-plugin-eslint-comments/configs";
|
||||
import { fixupPluginRules } from "@eslint/compat";
|
||||
import js from "@eslint/js";
|
||||
import deprecationPlugin from "eslint-plugin-deprecation";
|
||||
import importPlugin from "eslint-plugin-import";
|
||||
import simpleImportSortPlugin from "eslint-plugin-simple-import-sort";
|
||||
import tailwind from "eslint-plugin-tailwindcss";
|
||||
import globals from "globals";
|
||||
import tseslint from "typescript-eslint";
|
||||
|
||||
export default tseslint.config(
|
||||
js.configs.recommended,
|
||||
importPlugin.flatConfigs.recommended,
|
||||
comments.recommended,
|
||||
...tseslint.configs.recommended,
|
||||
...tailwind.configs["flat/recommended"],
|
||||
{
|
||||
plugins: {
|
||||
"@typescript-eslint": tseslint.plugin,
|
||||
deprecation: fixupPluginRules(deprecationPlugin),
|
||||
import: fixupPluginRules(importPlugin),
|
||||
"simple-import-sort": simpleImportSortPlugin,
|
||||
},
|
||||
ignores: ["**/node_modules/**", "**/public/**"],
|
||||
languageOptions: {
|
||||
parserOptions: {
|
||||
projectService: true,
|
||||
tsconfigRootDir: import.meta.dirname,
|
||||
ecmaVersion: "latest",
|
||||
sourceType: "module",
|
||||
project: ["./tsconfig.json"],
|
||||
},
|
||||
globals: {
|
||||
...globals.node,
|
||||
},
|
||||
},
|
||||
files: ["**/*.{js,mjs,cjs}"],
|
||||
rules: {
|
||||
"tailwindcss/no-custom-classname": [
|
||||
"error",
|
||||
{
|
||||
config: "./tailwind.config.js",
|
||||
whitelist: [
|
||||
"select_container",
|
||||
"convert_to_popup",
|
||||
"convert_to_group",
|
||||
"target",
|
||||
"convert_to_target",
|
||||
],
|
||||
},
|
||||
],
|
||||
"import/no-named-as-default": "off",
|
||||
},
|
||||
},
|
||||
);
|
||||
BIN
images/preview.png
Normal file
BIN
images/preview.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 53 KiB |
67
package.json
67
package.json
@@ -1,42 +1,67 @@
|
||||
{
|
||||
"name": "convertx-frontend",
|
||||
"version": "0.2.0",
|
||||
"version": "0.8.0",
|
||||
"scripts": {
|
||||
"dev": "bun run --watch src/index.tsx",
|
||||
"hot": "bun run --hot src/index.tsx",
|
||||
"format": "biome format --write ./src",
|
||||
"css": "cpy 'node_modules/@picocss/pico/css/pico.lime.min.css' 'src/public/' --flat"
|
||||
"build": "postcss ./src/main.css -o ./src/public/generated.css",
|
||||
"lint": "run-p 'lint:*'",
|
||||
"lint:tsc": "tsc --noEmit",
|
||||
"lint:knip": "knip",
|
||||
"lint:biome": "biome lint --error-on-warnings ./src"
|
||||
},
|
||||
"dependencies": {
|
||||
"@elysiajs/cookie": "^0.8.0",
|
||||
"@elysiajs/html": "^1.0.2",
|
||||
"@elysiajs/jwt": "^1.0.2",
|
||||
"@elysiajs/static": "^1.0.3",
|
||||
"elysia": "^1.0.24"
|
||||
"@elysiajs/html": "1.0.2",
|
||||
"@elysiajs/jwt": "^1.1.1",
|
||||
"@elysiajs/static": "1.0.3",
|
||||
"elysia": "^1.1.17"
|
||||
},
|
||||
"module": "src/index.tsx",
|
||||
"type": "module",
|
||||
"bun-create": {
|
||||
"start": "bun run src/index.tsx"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "1.8.1",
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.2.1",
|
||||
"@kitajs/ts-html-plugin": "^4.0.1",
|
||||
"@biomejs/biome": "1.9.2",
|
||||
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.0",
|
||||
"@eslint/compat": "^1.1.1",
|
||||
"@eslint/js": "^9.11.1",
|
||||
"@ianvs/prettier-plugin-sort-imports": "^4.3.1",
|
||||
"@kitajs/ts-html-plugin": "^4.1.0",
|
||||
"@picocss/pico": "^2.0.6",
|
||||
"@total-typescript/ts-reset": "^0.5.1",
|
||||
"@types/bun": "^1.1.5",
|
||||
"@types/eslint": "^8.56.10",
|
||||
"@types/node": "^20.14.6",
|
||||
"@types/ws": "^8.5.10",
|
||||
"@typescript-eslint/eslint-plugin": "^7.13.1",
|
||||
"@typescript-eslint/parser": "^7.13.1",
|
||||
"cpy-cli": "^5.0.0",
|
||||
"@total-typescript/ts-reset": "^0.6.1",
|
||||
"@types/bun": "^1.1.10",
|
||||
"@types/eslint": "^9.6.1",
|
||||
"@types/eslint-plugin-tailwindcss": "^3.17.0",
|
||||
"@types/eslint__js": "^8.42.3",
|
||||
"@types/node": "^22.7.4",
|
||||
"@typescript-eslint/eslint-plugin": "^8.7.0",
|
||||
"@typescript-eslint/parser": "^8.7.0",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"cssnano": "^7.0.6",
|
||||
"eslint": "^9.11.1",
|
||||
"eslint-config-prettier": "^9.1.0",
|
||||
"eslint-plugin-prettier": "^5.1.3",
|
||||
"prettier": "^3.3.2",
|
||||
"typescript": "^5.5.2"
|
||||
"eslint-plugin-deprecation": "^3.0.0",
|
||||
"eslint-plugin-import": "^2.30.0",
|
||||
"eslint-plugin-isaacscript": "^4.0.0",
|
||||
"eslint-plugin-prettier": "^5.2.1",
|
||||
"eslint-plugin-simple-import-sort": "^12.1.1",
|
||||
"eslint-plugin-tailwindcss": "^3.17.4",
|
||||
"globals": "^15.9.0",
|
||||
"knip": "^5.30.6",
|
||||
"npm-run-all2": "^6.2.3",
|
||||
"postcss": "^8.4.47",
|
||||
"postcss-cli": "^11.0.0",
|
||||
"postcss-lightningcss": "^1.0.1",
|
||||
"prettier": "^3.3.3",
|
||||
"tailwind-scrollbar": "^3.1.0",
|
||||
"tailwindcss": "^3.4.13",
|
||||
"typescript": "^5.6.2",
|
||||
"typescript-eslint": "^8.7.0"
|
||||
},
|
||||
"trustedDependencies": [
|
||||
"@biomejs/biome"
|
||||
]
|
||||
}
|
||||
}
|
||||
9
postcss.config.cjs
Normal file
9
postcss.config.cjs
Normal file
@@ -0,0 +1,9 @@
|
||||
// eslint-disable-next-line no-undef
|
||||
module.exports = {
|
||||
plugins: {
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
// eslint-disable-next-line no-undef
|
||||
...(process.env.NODE_ENV === 'production' ? { cssnano: {} } : {})
|
||||
}
|
||||
}
|
||||
6
renovate.json
Normal file
6
renovate.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
||||
"extends": [
|
||||
"config:recommended"
|
||||
]
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
export const BaseHtml = ({ children, title = "ConvertX" }) => (
|
||||
export const BaseHtml = ({
|
||||
children,
|
||||
title = "ConvertX",
|
||||
}: { children: JSX.Element; title?: string }) => (
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title safe>{title}</title>
|
||||
<link rel="stylesheet" href="/pico.lime.min.css" />
|
||||
<link rel="stylesheet" href="/style.css" />
|
||||
<link rel="stylesheet" href="/generated.css" />
|
||||
<link
|
||||
rel="apple-touch-icon"
|
||||
sizes="180x180"
|
||||
@@ -25,6 +27,6 @@ export const BaseHtml = ({ children, title = "ConvertX" }) => (
|
||||
/>
|
||||
<link rel="manifest" href="/site.webmanifest" />
|
||||
</head>
|
||||
<body>{children}</body>
|
||||
<body class="w-full bg-neutral-900 text-neutral-200">{children}</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
@@ -5,44 +5,53 @@ export const Header = ({
|
||||
let rightNav: JSX.Element;
|
||||
if (loggedIn) {
|
||||
rightNav = (
|
||||
<ul>
|
||||
<ul class="flex gap-4 ">
|
||||
<li>
|
||||
<a href="/history">History</a>
|
||||
<a
|
||||
class="text-accent-600 transition-all hover:text-accent-500 hover:underline"
|
||||
href="/history">
|
||||
History
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/logoff">Logout</a>
|
||||
<a
|
||||
class="text-accent-600 transition-all hover:text-accent-500 hover:underline"
|
||||
href="/logoff">
|
||||
Logout
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
);
|
||||
} else {
|
||||
rightNav = (
|
||||
<ul>
|
||||
<ul class="flex gap-4">
|
||||
<li>
|
||||
<a href="/login">Login</a>
|
||||
<a
|
||||
class="text-accent-600 transition-all hover:text-accent-500 hover:underline"
|
||||
href="/login">
|
||||
Login
|
||||
</a>
|
||||
</li>
|
||||
{accountRegistration && (
|
||||
{accountRegistration ? (
|
||||
<li>
|
||||
<a href="/register">Register</a>
|
||||
<a
|
||||
class="text-accent-600 transition-all hover:text-accent-500 hover:underline"
|
||||
href="/register">
|
||||
Register
|
||||
</a>
|
||||
</li>
|
||||
)}
|
||||
) : null}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<header className="container">
|
||||
<nav>
|
||||
<header class="w-full p-4">
|
||||
<nav class="mx-auto flex max-w-4xl justify-between rounded bg-neutral-900 p-4">
|
||||
<ul>
|
||||
<li>
|
||||
<strong>
|
||||
<a
|
||||
href="/"
|
||||
style={{
|
||||
textDecoration: "none",
|
||||
color: "inherit",
|
||||
}}>
|
||||
ConvertX
|
||||
</a>
|
||||
<a href="/">ConvertX</a>
|
||||
</strong>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
143
src/converters/assimp.ts
Normal file
143
src/converters/assimp.ts
Normal file
@@ -0,0 +1,143 @@
|
||||
import { exec } from "node:child_process";
|
||||
|
||||
// This could be done dynamically by running `ffmpeg -formats` and parsing the output
|
||||
export const properties = {
|
||||
from: {
|
||||
muxer: [
|
||||
"3d",
|
||||
"3ds",
|
||||
"3mf",
|
||||
"ac",
|
||||
"ac3d",
|
||||
"acc",
|
||||
"amf",
|
||||
"ase",
|
||||
"ask",
|
||||
"assbin",
|
||||
"b3d",
|
||||
"blend",
|
||||
"bsp",
|
||||
"bvh",
|
||||
"cob",
|
||||
"csm",
|
||||
"dae",
|
||||
"dxf",
|
||||
"enff",
|
||||
"fbx",
|
||||
"glb",
|
||||
"gltf",
|
||||
"hmp",
|
||||
"ifc",
|
||||
"ifczip",
|
||||
"iqm",
|
||||
"irr",
|
||||
"irrmesh",
|
||||
"lwo",
|
||||
"lws",
|
||||
"lxo",
|
||||
"md2",
|
||||
"md3",
|
||||
"md5anim",
|
||||
"md5camera",
|
||||
"md5mesh",
|
||||
"mdc",
|
||||
"mdl",
|
||||
"mesh.xml",
|
||||
"mesh",
|
||||
"mot",
|
||||
"ms3d",
|
||||
"ndo",
|
||||
"nff",
|
||||
"obj",
|
||||
"off",
|
||||
"ogex",
|
||||
"pk3",
|
||||
"ply",
|
||||
"pmx",
|
||||
"prj",
|
||||
"q3o",
|
||||
"q3s",
|
||||
"raw",
|
||||
"scn",
|
||||
"sib",
|
||||
"smd",
|
||||
"step",
|
||||
"stl",
|
||||
"stp",
|
||||
"ter",
|
||||
"uc",
|
||||
"usd",
|
||||
"usda",
|
||||
"usdc",
|
||||
"usdz",
|
||||
"vta",
|
||||
"x",
|
||||
"x3d",
|
||||
"x3db",
|
||||
"xgl",
|
||||
"xml",
|
||||
"zae",
|
||||
"zgl",
|
||||
],
|
||||
},
|
||||
to: {
|
||||
muxer: [
|
||||
"3ds",
|
||||
"3mf",
|
||||
"assbin",
|
||||
"assjson",
|
||||
"assxml",
|
||||
"collada",
|
||||
"dae",
|
||||
"fbx",
|
||||
"fbxa",
|
||||
"glb",
|
||||
"glb2",
|
||||
"gltf",
|
||||
"gltf2",
|
||||
"m3d",
|
||||
"m3da",
|
||||
"obj",
|
||||
"objnomtl",
|
||||
"pbrt",
|
||||
"ply",
|
||||
"plyb",
|
||||
"stl",
|
||||
"stlb",
|
||||
"stp",
|
||||
"x",
|
||||
"x3d",
|
||||
],
|
||||
},
|
||||
};
|
||||
|
||||
export async function convert(
|
||||
filePath: string,
|
||||
fileType: string,
|
||||
convertTo: string,
|
||||
targetPath: string,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
options?: any,
|
||||
): Promise<string> {
|
||||
// let command = "ffmpeg";
|
||||
|
||||
const command = `assimp export "${filePath}" "${targetPath}"`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(command, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`error: ${error}`);
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`stdout: ${stdout}`);
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
console.error(`stderr: ${stderr}`);
|
||||
}
|
||||
|
||||
resolve("success");
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
import { exec } from "node:child_process";
|
||||
|
||||
|
||||
// This could be done dynamically by running `ffmpeg -formats` and parsing the output
|
||||
export const properties = {
|
||||
from: {
|
||||
muxer: [
|
||||
"264",
|
||||
"265",
|
||||
"266",
|
||||
"302",
|
||||
"3dostr",
|
||||
"3g2",
|
||||
@@ -18,6 +20,7 @@ export const properties = {
|
||||
"aac",
|
||||
"aax",
|
||||
"ac3",
|
||||
"ac4",
|
||||
"ace",
|
||||
"acm",
|
||||
"act",
|
||||
@@ -48,7 +51,6 @@ export const properties = {
|
||||
"apng",
|
||||
"aptx",
|
||||
"aptxhd",
|
||||
"aptx_hd",
|
||||
"aqt",
|
||||
"aqtitle",
|
||||
"argo_asf",
|
||||
@@ -63,10 +65,12 @@ export const properties = {
|
||||
"av1",
|
||||
"avc",
|
||||
"avi",
|
||||
"avif",
|
||||
"avr",
|
||||
"avs",
|
||||
"avs2",
|
||||
"avs3",
|
||||
"awb",
|
||||
"bcstm",
|
||||
"bethsoftvid",
|
||||
"bfi",
|
||||
@@ -75,8 +79,10 @@ export const properties = {
|
||||
"bink",
|
||||
"binka",
|
||||
"bit",
|
||||
"bmp_pipe",
|
||||
"bitpacked",
|
||||
"bmv",
|
||||
"bmp",
|
||||
"bonk",
|
||||
"boa",
|
||||
"brender_pix",
|
||||
"brstm",
|
||||
@@ -93,7 +99,7 @@ export const properties = {
|
||||
"codec2",
|
||||
"codec2raw",
|
||||
"concat",
|
||||
"cri_pipe",
|
||||
"cri",
|
||||
"dash",
|
||||
"dat",
|
||||
"data",
|
||||
@@ -101,8 +107,9 @@ export const properties = {
|
||||
"dav",
|
||||
"dbm",
|
||||
"dcstr",
|
||||
"dds_pipe",
|
||||
"dds",
|
||||
"derf",
|
||||
"dfpwm",
|
||||
"dfa",
|
||||
"dhav",
|
||||
"dif",
|
||||
@@ -131,6 +138,8 @@ export const properties = {
|
||||
"exr_pipe",
|
||||
"f32be",
|
||||
"f32le",
|
||||
"ec3",
|
||||
"evc",
|
||||
"f4v",
|
||||
"f64be",
|
||||
"f64le",
|
||||
@@ -157,13 +166,13 @@ export const properties = {
|
||||
"gdv",
|
||||
"genh",
|
||||
"gif",
|
||||
"gif_pipe",
|
||||
"gsm",
|
||||
"gxf",
|
||||
"h261",
|
||||
"h263",
|
||||
"h264",
|
||||
"h265",
|
||||
"h266",
|
||||
"h26l",
|
||||
"hca",
|
||||
"hcom",
|
||||
@@ -180,7 +189,6 @@ export const properties = {
|
||||
"ifv",
|
||||
"ilbc",
|
||||
"image2",
|
||||
"image2pipe",
|
||||
"imf",
|
||||
"imx",
|
||||
"ingenient",
|
||||
@@ -197,21 +205,17 @@ export const properties = {
|
||||
"ivr",
|
||||
"j2b",
|
||||
"j2k",
|
||||
"j2k_pipe",
|
||||
"jack",
|
||||
"jacosub",
|
||||
"jpegls_pipe",
|
||||
"jpeg_pipe",
|
||||
"jv",
|
||||
"jpegls",
|
||||
"jpeg",
|
||||
"jxl",
|
||||
"kmsgrab",
|
||||
"kux",
|
||||
"kvag",
|
||||
"lavfi",
|
||||
"libcdio",
|
||||
"libdc1394",
|
||||
"libgme",
|
||||
"libopenmpt",
|
||||
"live_flv",
|
||||
"laf",
|
||||
"lmlm4",
|
||||
"loas",
|
||||
"lrc",
|
||||
@@ -224,16 +228,13 @@ export const properties = {
|
||||
"m4b",
|
||||
"m4v",
|
||||
"mac",
|
||||
"matroska",
|
||||
"mca",
|
||||
"mcc",
|
||||
"mdl",
|
||||
"med",
|
||||
"mgsts",
|
||||
"microdvd",
|
||||
"mj2",
|
||||
"mjpeg",
|
||||
"mjpeg_2000",
|
||||
"mjpg",
|
||||
"mk3d",
|
||||
"mka",
|
||||
@@ -257,9 +258,7 @@ export const properties = {
|
||||
"mpc",
|
||||
"mpc8",
|
||||
"mpeg",
|
||||
"mpegts",
|
||||
"mpegtsraw",
|
||||
"mpegvideo",
|
||||
"mpg",
|
||||
"mpjpeg",
|
||||
"mpl2",
|
||||
"mpo",
|
||||
@@ -293,25 +292,27 @@ export const properties = {
|
||||
"okt",
|
||||
"oma",
|
||||
"omg",
|
||||
"opus",
|
||||
"openal",
|
||||
"oss",
|
||||
"osq",
|
||||
"paf",
|
||||
"pam_pipe",
|
||||
"pbm_pipe",
|
||||
"pcx_pipe",
|
||||
"pgmyuv_pipe",
|
||||
"pgm_pipe",
|
||||
"pgx_pipe",
|
||||
"photocd_pipe",
|
||||
"pictor_pipe",
|
||||
"pdv",
|
||||
"pam",
|
||||
"pbm",
|
||||
"pcx",
|
||||
"pgmyuv",
|
||||
"pgm",
|
||||
"pgx",
|
||||
"photocd",
|
||||
"pictor",
|
||||
"pjs",
|
||||
"plm",
|
||||
"pmp",
|
||||
"png_pipe",
|
||||
"png",
|
||||
"ppm",
|
||||
"ppm_pipe",
|
||||
"pp_bnk",
|
||||
"psd_pipe",
|
||||
"pp",
|
||||
"psd",
|
||||
"psm",
|
||||
"psp",
|
||||
"psxstr",
|
||||
@@ -322,7 +323,7 @@ export const properties = {
|
||||
"pvf",
|
||||
"qcif",
|
||||
"qcp",
|
||||
"qdraw_pipe",
|
||||
"qdraw",
|
||||
"r3d",
|
||||
"rawvideo",
|
||||
"rco",
|
||||
@@ -334,6 +335,7 @@ export const properties = {
|
||||
"rm",
|
||||
"roq",
|
||||
"rpl",
|
||||
"rka",
|
||||
"rsd",
|
||||
"rso",
|
||||
"rt",
|
||||
@@ -354,6 +356,7 @@ export const properties = {
|
||||
"sbc",
|
||||
"sbg",
|
||||
"scc",
|
||||
"sdns",
|
||||
"sdp",
|
||||
"sdr2",
|
||||
"sds",
|
||||
@@ -363,10 +366,9 @@ export const properties = {
|
||||
"sfx",
|
||||
"sfx2",
|
||||
"sga",
|
||||
"sgi_pipe",
|
||||
"sgi",
|
||||
"shn",
|
||||
"siff",
|
||||
"simbiosis_imx",
|
||||
"sln",
|
||||
"smi",
|
||||
"smjpeg",
|
||||
@@ -388,12 +390,9 @@ export const properties = {
|
||||
"stp",
|
||||
"str",
|
||||
"sub",
|
||||
"subviewer",
|
||||
"subviewer1",
|
||||
"sunrast_pipe",
|
||||
"sup",
|
||||
"svag",
|
||||
"svg_pipe",
|
||||
"svg",
|
||||
"svs",
|
||||
"sw",
|
||||
"swf",
|
||||
@@ -403,7 +402,8 @@ export const properties = {
|
||||
"thd",
|
||||
"thp",
|
||||
"tiertexseq",
|
||||
"tiff_pipe",
|
||||
"tif",
|
||||
"tiff",
|
||||
"tmv",
|
||||
"truehd",
|
||||
"tta",
|
||||
@@ -423,6 +423,7 @@ export const properties = {
|
||||
"ul",
|
||||
"ult",
|
||||
"umx",
|
||||
"usm",
|
||||
"uw",
|
||||
"v",
|
||||
"v210",
|
||||
@@ -446,12 +447,14 @@ export const properties = {
|
||||
"vql",
|
||||
"vt",
|
||||
"vtt",
|
||||
"vvc",
|
||||
"w64",
|
||||
"wa",
|
||||
"wav",
|
||||
"way",
|
||||
"wc3movie",
|
||||
"webm",
|
||||
"webm_dash_manifest",
|
||||
"webp_pipe",
|
||||
"webp",
|
||||
"webvtt",
|
||||
"wow",
|
||||
"wsaud",
|
||||
@@ -463,32 +466,31 @@ export const properties = {
|
||||
"x11grab",
|
||||
"xa",
|
||||
"xbin",
|
||||
"xbm_pipe",
|
||||
"xl",
|
||||
"xm",
|
||||
"xmd",
|
||||
"xmv",
|
||||
"xpk",
|
||||
"xpm_pipe",
|
||||
"xvag",
|
||||
"xwd_pipe",
|
||||
"xwma",
|
||||
"y4m",
|
||||
"yop",
|
||||
"yuv",
|
||||
"yuv10",
|
||||
"yuv4mpegpipe",
|
||||
],
|
||||
},
|
||||
to: {
|
||||
muxer: [
|
||||
"264",
|
||||
"265",
|
||||
"266",
|
||||
"302",
|
||||
"3g2",
|
||||
"3gp",
|
||||
"a64",
|
||||
"aac",
|
||||
"ac3",
|
||||
"ac4",
|
||||
"adts",
|
||||
"adx",
|
||||
"afc",
|
||||
@@ -496,43 +498,32 @@ export const properties = {
|
||||
"aifc",
|
||||
"aiff",
|
||||
"al",
|
||||
"alaw",
|
||||
"alp",
|
||||
"alsa",
|
||||
"amr",
|
||||
"amv",
|
||||
"apm",
|
||||
"apng",
|
||||
"aptx",
|
||||
"aptxhd",
|
||||
"aptx_hd",
|
||||
"argo_asf",
|
||||
"asf",
|
||||
"asf_stream",
|
||||
"ass",
|
||||
"ast",
|
||||
"au",
|
||||
"aud",
|
||||
"av1",
|
||||
"avi",
|
||||
"avm2",
|
||||
"avif",
|
||||
"avs",
|
||||
"avs2",
|
||||
"avs3",
|
||||
"bit",
|
||||
"bmp",
|
||||
"c2",
|
||||
"caca",
|
||||
"caf",
|
||||
"cavs",
|
||||
"cavsvideo",
|
||||
"chk",
|
||||
"chromaprint",
|
||||
"codec2",
|
||||
"codec2raw",
|
||||
"cpk",
|
||||
"crc",
|
||||
"dash",
|
||||
"data",
|
||||
"daud",
|
||||
"dirac",
|
||||
"cvg",
|
||||
"dfpwm",
|
||||
"dnxhd",
|
||||
"dnxhr",
|
||||
"dpx",
|
||||
@@ -541,30 +532,16 @@ export const properties = {
|
||||
"dv",
|
||||
"dvd",
|
||||
"eac3",
|
||||
"ec3",
|
||||
"evc",
|
||||
"exr",
|
||||
"f32be",
|
||||
"f32le",
|
||||
"f4v",
|
||||
"f64be",
|
||||
"f64le",
|
||||
"fbdev",
|
||||
"ffmeta",
|
||||
"ffmetadata",
|
||||
"fifo",
|
||||
"fifo_test",
|
||||
"filmstrip",
|
||||
"film_cpk",
|
||||
"fits",
|
||||
"flac",
|
||||
"flm",
|
||||
"flv",
|
||||
"framecrc",
|
||||
"framehash",
|
||||
"framemd5",
|
||||
"g722",
|
||||
"g723_1",
|
||||
"g726",
|
||||
"g726le",
|
||||
"gif",
|
||||
"gsm",
|
||||
"gxf",
|
||||
@@ -572,32 +549,26 @@ export const properties = {
|
||||
"h263",
|
||||
"h264",
|
||||
"h265",
|
||||
"hash",
|
||||
"hds",
|
||||
"h266",
|
||||
"hdr",
|
||||
"hevc",
|
||||
"hls",
|
||||
"ico",
|
||||
"ilbc",
|
||||
"im1",
|
||||
"im24",
|
||||
"im8",
|
||||
"image2",
|
||||
"image2pipe",
|
||||
"ipod",
|
||||
"ircam",
|
||||
"isma",
|
||||
"ismv",
|
||||
"ivf",
|
||||
"j2c",
|
||||
"j2k",
|
||||
"jacosub",
|
||||
"jls",
|
||||
"jp2",
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"js",
|
||||
"jss",
|
||||
"kvag",
|
||||
"jxl",
|
||||
"latm",
|
||||
"lbc",
|
||||
"ljpg",
|
||||
@@ -612,13 +583,9 @@ export const properties = {
|
||||
"m4a",
|
||||
"m4b",
|
||||
"m4v",
|
||||
"matroska",
|
||||
"md5",
|
||||
"microdvd",
|
||||
"mjpeg",
|
||||
"mjpg",
|
||||
"mkv",
|
||||
"mkvtimestamp_v2",
|
||||
"mlp",
|
||||
"mmf",
|
||||
"mov",
|
||||
@@ -628,26 +595,17 @@ export const properties = {
|
||||
"mpa",
|
||||
"mpd",
|
||||
"mpeg",
|
||||
"mpeg1video",
|
||||
"mpeg2video",
|
||||
"mpegts",
|
||||
"mpg",
|
||||
"mpjpeg",
|
||||
"msbc",
|
||||
"mts",
|
||||
"mulaw",
|
||||
"mxf",
|
||||
"mxf_d10",
|
||||
"mxf_opatom",
|
||||
"null",
|
||||
"nut",
|
||||
"obu",
|
||||
"oga",
|
||||
"ogg",
|
||||
"ogv",
|
||||
"oma",
|
||||
"opengl",
|
||||
"opus",
|
||||
"oss",
|
||||
"pam",
|
||||
"pbm",
|
||||
"pcm",
|
||||
@@ -655,14 +613,14 @@ export const properties = {
|
||||
"pfm",
|
||||
"pgm",
|
||||
"pgmyuv",
|
||||
"phm",
|
||||
"pix",
|
||||
"png",
|
||||
"ppm",
|
||||
"psp",
|
||||
"pulse",
|
||||
"qoi",
|
||||
"ra",
|
||||
"ras",
|
||||
"rawvideo",
|
||||
"rco",
|
||||
"rcv",
|
||||
"rgb",
|
||||
@@ -670,84 +628,47 @@ export const properties = {
|
||||
"roq",
|
||||
"rs",
|
||||
"rso",
|
||||
"rtp",
|
||||
"rtp_mpegts",
|
||||
"rtsp",
|
||||
"s16be",
|
||||
"s16le",
|
||||
"s24be",
|
||||
"s24le",
|
||||
"s32be",
|
||||
"s32le",
|
||||
"s8",
|
||||
"sap",
|
||||
"sb",
|
||||
"sbc",
|
||||
"scc",
|
||||
"sdl",
|
||||
"sdl2",
|
||||
"segment",
|
||||
"sf",
|
||||
"sgi",
|
||||
"singlejpeg",
|
||||
"smjpeg",
|
||||
"smoothstreaming",
|
||||
"sndio",
|
||||
"sox",
|
||||
"spdif",
|
||||
"spx",
|
||||
"srt",
|
||||
"ssa",
|
||||
"ssegment",
|
||||
"streamhash",
|
||||
"stream_segment",
|
||||
"sub",
|
||||
"sun",
|
||||
"sunras",
|
||||
"sup",
|
||||
"svcd",
|
||||
"sw",
|
||||
"swf",
|
||||
"tco",
|
||||
"tee",
|
||||
"tga",
|
||||
"thd",
|
||||
"tif",
|
||||
"tiff",
|
||||
"truehd",
|
||||
"ts",
|
||||
"tta",
|
||||
"ttml",
|
||||
"tun",
|
||||
"u16be",
|
||||
"u16le",
|
||||
"u24be",
|
||||
"u24le",
|
||||
"u32be",
|
||||
"u32le",
|
||||
"u8",
|
||||
"ub",
|
||||
"ul",
|
||||
"uncodedframecrc",
|
||||
"uw",
|
||||
"v4l2",
|
||||
"vag",
|
||||
"vbn",
|
||||
"vc1",
|
||||
"vc1test",
|
||||
"vc2",
|
||||
"vcd",
|
||||
"vidc",
|
||||
"video4linux2",
|
||||
"vob",
|
||||
"voc",
|
||||
"vtt",
|
||||
"vvc",
|
||||
"w64",
|
||||
"wav",
|
||||
"wbmp",
|
||||
"webm",
|
||||
"webm_chunk",
|
||||
"webm_dash_manifest",
|
||||
"webp",
|
||||
"webvtt",
|
||||
"wma",
|
||||
"wmv",
|
||||
"wtv",
|
||||
@@ -755,12 +676,10 @@ export const properties = {
|
||||
"xbm",
|
||||
"xface",
|
||||
"xml",
|
||||
"xv",
|
||||
"xwd",
|
||||
"y",
|
||||
"y4m",
|
||||
"yuv",
|
||||
"yuv4mpegpipe",
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -773,38 +692,6 @@ export async function convert(
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
options?: any,
|
||||
): Promise<string> {
|
||||
// let command = "ffmpeg";
|
||||
|
||||
// these are containers that can contain multiple formats
|
||||
// const autoDetect = [
|
||||
// "mp4",
|
||||
// "mkv",
|
||||
// "avi",
|
||||
// "mov",
|
||||
// "m4a",
|
||||
// "3gp",
|
||||
// "3g2",
|
||||
// "mj2",
|
||||
// "psp",
|
||||
// "m4b",
|
||||
// "ism",
|
||||
// "ismv",
|
||||
// "isma",
|
||||
// "f4v",
|
||||
// ];
|
||||
|
||||
// if (!(fileType in autoDetect)) {
|
||||
// command += ` -f "${fileType}"`;
|
||||
// }
|
||||
|
||||
// command += ` -i "${filePath}"`;
|
||||
|
||||
// if (!(convertTo in autoDetect)) {
|
||||
// command += ` -f "${convertTo}"`;
|
||||
// }
|
||||
|
||||
// command += ` "${targetPath}"`;
|
||||
|
||||
const command = `ffmpeg -i "${filePath}" "${targetPath}"`;
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -824,4 +711,4 @@ export async function convert(
|
||||
resolve("success");
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -143,6 +143,7 @@ export const properties = {
|
||||
"svgz",
|
||||
"text",
|
||||
"tga",
|
||||
"tif",
|
||||
"tiff",
|
||||
"tile",
|
||||
"tim",
|
||||
@@ -227,7 +228,6 @@ export const properties = {
|
||||
"jbig",
|
||||
"jng",
|
||||
"jpeg",
|
||||
"jpg",
|
||||
"k",
|
||||
"m",
|
||||
"m2v",
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
import { convert as convertImage, properties as propertiesImage } from "./vips";
|
||||
import {
|
||||
convert as convertImage,
|
||||
properties as propertiesImage
|
||||
} from "./vips";
|
||||
|
||||
import {
|
||||
convert as convertPandoc,
|
||||
@@ -16,33 +19,38 @@ import {
|
||||
} from "./graphicsmagick";
|
||||
|
||||
import {
|
||||
convert as convertPdflatex,
|
||||
properties as propertiesPdflatex,
|
||||
} from "./pdflatex";
|
||||
convert as convertxelatex,
|
||||
properties as propertiesxelatex,
|
||||
} from "./xelatex";
|
||||
|
||||
import {
|
||||
convert as convertLibjxl,
|
||||
properties as propertiesLibjxl,
|
||||
} from "./libjxl";
|
||||
|
||||
import {
|
||||
convert as convertresvg,
|
||||
properties as propertiesresvg,
|
||||
} from "./resvg";
|
||||
|
||||
import {
|
||||
convert as convertassimp,
|
||||
properties as propertiesassimp,
|
||||
} from "./assimp";
|
||||
|
||||
import { normalizeFiletype } from "../helpers/normalizeFiletype";
|
||||
|
||||
// This should probably be reconstructed so that the functions are not imported instead the functions hook into this to make the converters more modular
|
||||
|
||||
const properties: {
|
||||
[key: string]: {
|
||||
const properties: Record<string, {
|
||||
properties: {
|
||||
from: { [key: string]: string[] };
|
||||
to: { [key: string]: string[] };
|
||||
options?: {
|
||||
[key: string]: {
|
||||
[key: string]: {
|
||||
from: Record<string, string[]>;
|
||||
to: Record<string, string[]>;
|
||||
options?: Record<string, Record<string, {
|
||||
description: string;
|
||||
type: string;
|
||||
default: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
}>>;
|
||||
};
|
||||
converter: (
|
||||
filePath: string,
|
||||
@@ -53,19 +61,22 @@ const properties: {
|
||||
options?: any,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
) => any;
|
||||
};
|
||||
} = {
|
||||
}> = {
|
||||
libjxl: {
|
||||
properties: propertiesLibjxl,
|
||||
converter: convertLibjxl,
|
||||
},
|
||||
resvg: {
|
||||
properties: propertiesresvg,
|
||||
converter: convertresvg,
|
||||
},
|
||||
vips: {
|
||||
properties: propertiesImage,
|
||||
converter: convertImage,
|
||||
},
|
||||
pdflatex: {
|
||||
properties: propertiesPdflatex,
|
||||
converter: convertPdflatex,
|
||||
xelatex: {
|
||||
properties: propertiesxelatex,
|
||||
converter: convertxelatex,
|
||||
},
|
||||
pandoc: {
|
||||
properties: propertiesPandoc,
|
||||
@@ -75,6 +86,10 @@ const properties: {
|
||||
properties: propertiesGraphicsmagick,
|
||||
converter: convertGraphicsmagick,
|
||||
},
|
||||
assimp: {
|
||||
properties: propertiesassimp,
|
||||
converter: convertassimp,
|
||||
},
|
||||
ffmpeg: {
|
||||
properties: propertiesFFmpeg,
|
||||
converter: convertFFmpeg,
|
||||
@@ -111,9 +126,8 @@ export async function mainConverter(
|
||||
|
||||
for (const key in converterObj.properties.from) {
|
||||
if (
|
||||
// HOW??
|
||||
converterObj.properties.from[key].includes(fileType) &&
|
||||
converterObj.properties.to[key].includes(convertTo)
|
||||
converterObj?.properties?.from[key]?.includes(fileType) &&
|
||||
converterObj?.properties?.to[key]?.includes(convertTo)
|
||||
) {
|
||||
converterFunc = converterObj.converter;
|
||||
break;
|
||||
@@ -151,7 +165,7 @@ export async function mainConverter(
|
||||
}
|
||||
}
|
||||
|
||||
const possibleTargets: { [key: string]: { [key: string]: string[] } } = {};
|
||||
const possibleTargets: Record<string, Record<string, string[]>> = {};
|
||||
|
||||
for (const converterName in properties) {
|
||||
const converterProperties = properties[converterName]?.properties;
|
||||
@@ -178,7 +192,7 @@ for (const converterName in properties) {
|
||||
|
||||
export const getPossibleTargets = (
|
||||
from: string,
|
||||
): { [key: string]: string[] } => {
|
||||
): Record<string, string[]> => {
|
||||
const fromClean = normalizeFiletype(from);
|
||||
|
||||
return possibleTargets[fromClean] || {};
|
||||
@@ -202,11 +216,11 @@ for (const converterName in properties) {
|
||||
}
|
||||
possibleInputs.sort();
|
||||
|
||||
export const getPossibleInputs = () => {
|
||||
const getPossibleInputs = () => {
|
||||
return possibleInputs;
|
||||
};
|
||||
|
||||
const allTargets: { [key: string]: string[] } = {};
|
||||
const allTargets: Record<string, string[]> = {};
|
||||
|
||||
for (const converterName in properties) {
|
||||
const converterProperties = properties[converterName]?.properties;
|
||||
@@ -217,9 +231,9 @@ for (const converterName in properties) {
|
||||
|
||||
for (const key in converterProperties.to) {
|
||||
if (allTargets[converterName]) {
|
||||
allTargets[converterName].push(...converterProperties.to[key]);
|
||||
allTargets[converterName].push(...(converterProperties.to[key] || []));
|
||||
} else {
|
||||
allTargets[converterName] = converterProperties.to[key];
|
||||
allTargets[converterName] = converterProperties.to[key] || [];
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -228,7 +242,7 @@ export const getAllTargets = () => {
|
||||
return allTargets;
|
||||
};
|
||||
|
||||
const allInputs: { [key: string]: string[] } = {};
|
||||
const allInputs: Record<string, string[]> = {};
|
||||
for (const converterName in properties) {
|
||||
const converterProperties = properties[converterName]?.properties;
|
||||
|
||||
@@ -238,9 +252,9 @@ for (const converterName in properties) {
|
||||
|
||||
for (const key in converterProperties.from) {
|
||||
if (allInputs[converterName]) {
|
||||
allInputs[converterName].push(...converterProperties.from[key]);
|
||||
allInputs[converterName].push(...(converterProperties.from[key] || []));
|
||||
} else {
|
||||
allInputs[converterName] = converterProperties.from[key];
|
||||
allInputs[converterName] = converterProperties.from[key] || [];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,119 +0,0 @@
|
||||
import sharp from "sharp";
|
||||
import type { FormatEnum } from "sharp";
|
||||
|
||||
// declare possible conversions
|
||||
export const properties = {
|
||||
from: {
|
||||
images: [
|
||||
"avif",
|
||||
"bif",
|
||||
"csv",
|
||||
"exr",
|
||||
"fits",
|
||||
"gif",
|
||||
"hdr.gz",
|
||||
"hdr",
|
||||
"heic",
|
||||
"heif",
|
||||
"img.gz",
|
||||
"img",
|
||||
"j2c",
|
||||
"j2k",
|
||||
"jp2",
|
||||
"jpeg",
|
||||
"jpx",
|
||||
"jxl",
|
||||
"mat",
|
||||
"mrxs",
|
||||
"ndpi",
|
||||
"nia.gz",
|
||||
"nia",
|
||||
"nii.gz",
|
||||
"nii",
|
||||
"pdf",
|
||||
"pfm",
|
||||
"pgm",
|
||||
"pic",
|
||||
"png",
|
||||
"ppm",
|
||||
"raw",
|
||||
"scn",
|
||||
"svg",
|
||||
"svs",
|
||||
"svslide",
|
||||
"szi",
|
||||
"tif",
|
||||
"tiff",
|
||||
"v",
|
||||
"vips",
|
||||
"vms",
|
||||
"vmu",
|
||||
"webp",
|
||||
"zip",
|
||||
],
|
||||
},
|
||||
to: {
|
||||
images: [
|
||||
"avif",
|
||||
"dzi",
|
||||
"fits",
|
||||
"gif",
|
||||
"hdr.gz",
|
||||
"heic",
|
||||
"heif",
|
||||
"img.gz",
|
||||
"j2c",
|
||||
"j2k",
|
||||
"jp2",
|
||||
"jpeg",
|
||||
"jpx",
|
||||
"jxl",
|
||||
"mat",
|
||||
"nia.gz",
|
||||
"nia",
|
||||
"nii.gz",
|
||||
"nii",
|
||||
"png",
|
||||
"tiff",
|
||||
"vips",
|
||||
"webp",
|
||||
],
|
||||
},
|
||||
options: {
|
||||
svg: {
|
||||
scale: {
|
||||
description: "Scale the image up or down",
|
||||
type: "number",
|
||||
default: 1,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export async function convert(
|
||||
filePath: string,
|
||||
fileType: string,
|
||||
convertTo: keyof FormatEnum,
|
||||
targetPath: string,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
options?: any,
|
||||
) {
|
||||
if (fileType === "svg") {
|
||||
const scale = options.scale || 1;
|
||||
const metadata = await sharp(filePath).metadata();
|
||||
|
||||
if (!metadata || !metadata.width || !metadata.height) {
|
||||
throw new Error("Could not get metadata from image");
|
||||
}
|
||||
|
||||
const newWidth = Math.round(metadata.width * scale);
|
||||
const newHeight = Math.round(metadata.height * scale);
|
||||
|
||||
return await sharp(filePath)
|
||||
.resize(newWidth, newHeight)
|
||||
.toFormat(convertTo)
|
||||
.toFile(targetPath);
|
||||
}
|
||||
|
||||
return await sharp(filePath).toFormat(convertTo).toFile(targetPath);
|
||||
}
|
||||
@@ -127,9 +127,15 @@ export function convert(
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
options?: any,
|
||||
): Promise<string> {
|
||||
// set xelatex here
|
||||
const xelatex = ["pdf", "latex"];
|
||||
let option = "";
|
||||
if (xelatex.includes(convertTo)) {
|
||||
option = "--pdf-engine=xelatex";
|
||||
}
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(
|
||||
`pandoc "${filePath}" -f ${fileType} -t ${convertTo} -o "${targetPath}"`,
|
||||
`pandoc ${option} "${filePath}" -f ${fileType} -t ${convertTo} -o "${targetPath}"`,
|
||||
(error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`error: ${error}`);
|
||||
|
||||
37
src/converters/resvg.ts
Normal file
37
src/converters/resvg.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { exec } from "node:child_process";
|
||||
|
||||
export const properties = {
|
||||
from: {
|
||||
images: ["svg"],
|
||||
},
|
||||
to: {
|
||||
images: ["png"],
|
||||
},
|
||||
};
|
||||
|
||||
export function convert(
|
||||
filePath: string,
|
||||
fileType: string,
|
||||
convertTo: string,
|
||||
targetPath: string,
|
||||
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
|
||||
options?: any,
|
||||
): Promise<string> {
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(`resvg "${filePath}" "${targetPath}"`, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`error: ${error}`);
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`stdout: ${stdout}`);
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
console.error(`stderr: ${stderr}`);
|
||||
}
|
||||
|
||||
resolve("success");
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -113,22 +113,29 @@ export function convert(
|
||||
// .toFormat(convertTo)
|
||||
// .toFile(targetPath);
|
||||
// }
|
||||
let action = "copy";
|
||||
if (fileType === "pdf") {
|
||||
action = "pdfload";
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
exec(`vips copy "${filePath}" "${targetPath}"`, (error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`error: ${error}`);
|
||||
}
|
||||
exec(
|
||||
`vips ${action} "${filePath}" "${targetPath}"`,
|
||||
(error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`error: ${error}`);
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`stdout: ${stdout}`);
|
||||
}
|
||||
if (stdout) {
|
||||
console.log(`stdout: ${stdout}`);
|
||||
}
|
||||
|
||||
if (stderr) {
|
||||
console.error(`stderr: ${stderr}`);
|
||||
}
|
||||
if (stderr) {
|
||||
console.error(`stderr: ${stderr}`);
|
||||
}
|
||||
|
||||
resolve("success");
|
||||
});
|
||||
resolve("success");
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ export function convert(
|
||||
.join("/")
|
||||
.replace("./", "");
|
||||
exec(
|
||||
`pdflatex -interaction=nonstopmode -output-directory="${outputPath}" "${filePath}"`,
|
||||
`latexmk -xelatex -interaction=nonstopmode -output-directory="${outputPath}" "${filePath}"`,
|
||||
(error, stdout, stderr) => {
|
||||
if (error) {
|
||||
reject(`error: ${error}`);
|
||||
@@ -23,6 +23,9 @@ export const normalizeOutputFiletype = (filetype: string): string => {
|
||||
return "jpg";
|
||||
case "latex":
|
||||
return "tex";
|
||||
case "markdown_phpextra":
|
||||
case "markdown_strict":
|
||||
case "markdown_mmd":
|
||||
case "markdown":
|
||||
return "md";
|
||||
default:
|
||||
|
||||
105
src/helpers/printVersions.ts
Normal file
105
src/helpers/printVersions.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import { exec } from "node:child_process";
|
||||
import { version } from "../../package.json";
|
||||
console.log(`ConvertX v${version}`);
|
||||
|
||||
if (process.env.NODE_ENV === "production") {
|
||||
exec("cat /etc/os-release", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Not running on docker, this is not supported.");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split('PRETTY_NAME="')[1]?.split('"')[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("pandoc -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Pandoc is not installed.");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("ffmpeg -version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("FFmpeg is not installed.");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("vips -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Vips is not installed.");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("gm version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("GraphicsMagick is not installed.");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("djxl --version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("libjxl-tools is not installed.");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("xelatex -version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Tex Live with XeTeX is not installed.");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(stdout.split("\n")[0]);
|
||||
}
|
||||
});
|
||||
|
||||
exec("resvg -V", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("resvg is not installed");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`resvg v${stdout.split("\n")[0]}`);
|
||||
}
|
||||
});
|
||||
|
||||
exec("assimp version", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("assimp is not installed");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`assimp v${stdout.split("\n")[5]}`);
|
||||
}
|
||||
});
|
||||
|
||||
exec("bun -v", (error, stdout) => {
|
||||
if (error) {
|
||||
console.error("Bun is not installed. wait what");
|
||||
}
|
||||
|
||||
if (stdout) {
|
||||
console.log(`Bun v${stdout.split("\n")[0]}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
17
src/helpers/tailwind.ts
Normal file
17
src/helpers/tailwind.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import tw from "tailwindcss";
|
||||
import postcss from "postcss";
|
||||
|
||||
export const generateTailwind = async () => {
|
||||
const result = await Bun.file("./src/main.css")
|
||||
.text()
|
||||
.then((sourceText) => {
|
||||
const config = "./tailwind.config.js";
|
||||
|
||||
return postcss([tw(config)]).process(sourceText, {
|
||||
from: "./src/main.css",
|
||||
to: "./public/generated.css",
|
||||
});
|
||||
});
|
||||
|
||||
return result;
|
||||
};
|
||||
948
src/index.tsx
948
src/index.tsx
File diff suppressed because it is too large
Load Diff
45
src/main.css
Normal file
45
src/main.css
Normal file
@@ -0,0 +1,45 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer components {
|
||||
.article {
|
||||
@apply p-4 mb-4 bg-neutral-800/40 w-full mx-auto max-w-4xl rounded;
|
||||
}
|
||||
.btn-primary {
|
||||
@apply bg-accent-500 text-contrast rounded p-4 hover:bg-accent-400 cursor-pointer transition-colors;
|
||||
}
|
||||
}
|
||||
|
||||
:root {
|
||||
--contrast: 255, 255, 255;
|
||||
--neutral-900: 243, 244, 246;
|
||||
--neutral-800: 229, 231, 235;
|
||||
--neutral-700: 209, 213, 219;
|
||||
--neutral-600: 156, 163, 175;
|
||||
--neutral-500: 180, 180, 180;
|
||||
--neutral-400: 75, 85, 99;
|
||||
--neutral-300: 55, 65, 81;
|
||||
--neutral-200: 31, 41, 55;
|
||||
--neutral-100: 17, 24, 39;
|
||||
--accent-400: 132, 204, 22;
|
||||
--accent-500: 101, 163, 13;
|
||||
--accent-600: 77, 124, 15;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--contrast: 0, 0, 0;
|
||||
--neutral-900: 17, 24, 39;
|
||||
--neutral-800: 31, 41, 55;
|
||||
--neutral-700: 55, 65, 81;
|
||||
--neutral-600: 75, 85, 99;
|
||||
--neutral-500: 107, 114, 128;
|
||||
--neutral-300: 209, 213, 219;
|
||||
--neutral-400: 156, 163, 175;
|
||||
--neutral-200: 229, 231, 235;
|
||||
--accent-600: 101, 163, 13;
|
||||
--accent-500: 132, 204, 22;
|
||||
--accent-400: 163, 230, 53;
|
||||
}
|
||||
}
|
||||
4
src/public/pico.lime.min.css
vendored
4
src/public/pico.lime.min.css
vendored
File diff suppressed because one or more lines are too long
2
src/public/robots.txt
Normal file
2
src/public/robots.txt
Normal file
@@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow: /
|
||||
@@ -1,9 +1,91 @@
|
||||
// Select the file input element
|
||||
const fileInput = document.querySelector('input[type="file"]');
|
||||
const dropZone = document.getElementById("dropzone");
|
||||
const fileNames = [];
|
||||
let fileType;
|
||||
|
||||
const selectContainer = document.querySelector("form > article");
|
||||
dropZone.addEventListener("dragover", (e) => {
|
||||
dropZone.classList.add("dragover");
|
||||
});
|
||||
|
||||
dropZone.addEventListener("dragleave", (e) => {
|
||||
dropZone.classList.remove("dragover");
|
||||
});
|
||||
|
||||
const selectContainer = document.querySelector("form .select_container");
|
||||
|
||||
const updateSearchBar = () => {
|
||||
const convertToInput = document.querySelector(
|
||||
"input[name='convert_to_search']",
|
||||
);
|
||||
const convertToPopup = document.querySelector(".convert_to_popup");
|
||||
const convertToGroupElements = document.querySelectorAll(".convert_to_group");
|
||||
const convertToGroups = {};
|
||||
const convertToElement = document.querySelector("select[name='convert_to']");
|
||||
|
||||
const showMatching = (search) => {
|
||||
for (const [targets, groupElement] of Object.values(convertToGroups)) {
|
||||
let matchingTargetsFound = 0;
|
||||
for (const target of targets) {
|
||||
if (target.dataset.target.includes(search)) {
|
||||
matchingTargetsFound++;
|
||||
target.classList.remove("hidden");
|
||||
target.classList.add("flex");
|
||||
} else {
|
||||
target.classList.add("hidden");
|
||||
target.classList.remove("flex");
|
||||
}
|
||||
}
|
||||
|
||||
if (matchingTargetsFound === 0) {
|
||||
groupElement.classList.add("hidden");
|
||||
groupElement.classList.remove("flex");
|
||||
} else {
|
||||
groupElement.classList.remove("hidden");
|
||||
groupElement.classList.add("flex");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
for (const groupElement of convertToGroupElements) {
|
||||
const groupName = groupElement.dataset.converter;
|
||||
|
||||
const targetElements = groupElement.querySelectorAll(".target");
|
||||
const targets = Array.from(targetElements);
|
||||
|
||||
for (const target of targets) {
|
||||
target.onmousedown = () => {
|
||||
convertToElement.value = target.dataset.value;
|
||||
convertToInput.value = `${target.dataset.target} using ${target.dataset.converter}`;
|
||||
showMatching("");
|
||||
};
|
||||
}
|
||||
|
||||
convertToGroups[groupName] = [targets, groupElement];
|
||||
}
|
||||
|
||||
convertToInput.addEventListener("input", (e) => {
|
||||
showMatching(e.target.value.toLowerCase());
|
||||
});
|
||||
|
||||
convertToInput.addEventListener("blur", (e) => {
|
||||
// Keep the popup open even when clicking on a target button
|
||||
// for a split second to allow the click to go through
|
||||
if (e?.relatedTarget?.classList?.contains("target")) {
|
||||
convertToPopup.classList.add("hidden");
|
||||
convertToPopup.classList.remove("flex");
|
||||
return;
|
||||
}
|
||||
|
||||
convertToPopup.classList.add("hidden");
|
||||
convertToPopup.classList.remove("flex");
|
||||
});
|
||||
|
||||
convertToInput.addEventListener("focus", () => {
|
||||
convertToPopup.classList.remove("hidden");
|
||||
convertToPopup.classList.add("flex");
|
||||
});
|
||||
};
|
||||
|
||||
// const convertFromSelect = document.querySelector("select[name='convert_from']");
|
||||
|
||||
@@ -28,6 +110,7 @@ fileInput.addEventListener("change", (e) => {
|
||||
|
||||
if (!fileType) {
|
||||
fileType = file.name.split(".").pop();
|
||||
console.log("fileType", fileType);
|
||||
fileInput.setAttribute("accept", `.${fileType}`);
|
||||
setTitle();
|
||||
|
||||
@@ -49,6 +132,7 @@ fileInput.addEventListener("change", (e) => {
|
||||
.then((res) => res.text())
|
||||
.then((html) => {
|
||||
selectContainer.innerHTML = html;
|
||||
updateSearchBar();
|
||||
})
|
||||
.catch((err) => console.log(err));
|
||||
}
|
||||
@@ -123,3 +207,5 @@ formConvert.addEventListener("submit", (e) => {
|
||||
const hiddenInput = document.querySelector("input[name='file_names']");
|
||||
hiddenInput.value = JSON.stringify(fileNames);
|
||||
});
|
||||
|
||||
updateSearchBar();
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
div.icon {
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
}
|
||||
|
||||
button[type="submit"] {
|
||||
width: 50%
|
||||
}
|
||||
|
||||
div.center {
|
||||
width: 100%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
25
tailwind.config.js
Normal file
25
tailwind.config.js
Normal file
@@ -0,0 +1,25 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
// eslint-disable-next-line no-undef
|
||||
module.exports = {
|
||||
content: ["./src/**/*.{html,js,tsx,jsx,cjs,mjs}"],
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
contrast: "rgba(var(--contrast))",
|
||||
"neutral-900": "rgba(var(--neutral-900))",
|
||||
"neutral-800": "rgba(var(--neutral-800))",
|
||||
"neutral-700": "rgba(var(--neutral-700))",
|
||||
"neutral-600": "rgba(var(--neutral-600))",
|
||||
"neutral-500": "rgba(var(--neutral-500))",
|
||||
"neutral-400": "rgba(var(--neutral-400))",
|
||||
"neutral-300": "rgba(var(--neutral-300))",
|
||||
"neutral-200": "rgba(var(--neutral-200))",
|
||||
"neutral-100": "rgba(var(--neutral-100))",
|
||||
"accent-600": "rgba(var(--accent-600))",
|
||||
"accent-500": "rgba(var(--accent-500))",
|
||||
"accent-400": "rgba(var(--accent-400))",
|
||||
},
|
||||
},
|
||||
},
|
||||
plugins: [require("tailwind-scrollbar")],
|
||||
};
|
||||
@@ -1,8 +1,8 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"lib": ["ESNext"],
|
||||
"module": "esnext",
|
||||
"target": "esnext",
|
||||
"module": "ESNext",
|
||||
"target": "ES2021",
|
||||
"moduleResolution": "bundler",
|
||||
"moduleDetection": "force",
|
||||
"allowImportingTsExtensions": true,
|
||||
@@ -17,9 +17,6 @@
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"allowJs": true,
|
||||
"types": [
|
||||
"bun-types" // add Bun global
|
||||
],
|
||||
// non bun init
|
||||
"plugins": [{ "name": "@kitajs/ts-html-plugin" }],
|
||||
"noUncheckedIndexedAccess": true,
|
||||
|
||||
Reference in New Issue
Block a user