Merge branch 'fosrl:main' into feat-add-test

This commit is contained in:
Marvin 2025-06-10 08:06:48 +02:00 committed by GitHub
commit 571db825ad
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 188 additions and 123 deletions

View file

@ -13,10 +13,6 @@ updates:
dependency-type: "development" dependency-type: "development"
update-types: update-types:
- "minor" - "minor"
dev-major-updates:
dependency-type: "development"
update-types:
- "major"
prod-patch-updates: prod-patch-updates:
dependency-type: "production" dependency-type: "production"
update-types: update-types:
@ -25,10 +21,6 @@ updates:
dependency-type: "production" dependency-type: "production"
update-types: update-types:
- "minor" - "minor"
prod-major-updates:
dependency-type: "production"
update-types:
- "major"
- package-ecosystem: "docker" - package-ecosystem: "docker"
directory: "/" directory: "/"
@ -41,6 +33,3 @@ updates:
minor-updates: minor-updates:
update-types: update-types:
- "minor" - "minor"
major-updates:
update-types:
- "major"

View file

@ -1,9 +1,12 @@
// eslint.config.js import tseslint from 'typescript-eslint';
export default [
export default tseslint.config(
tseslint.configs.recommended,
{ {
files: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
rules: { rules: {
semi: "error", semi: "error",
"prefer-const": "error" "prefer-const": "error"
} }
} }
]; );

View file

@ -35,7 +35,7 @@ services:
- 80:80 # Port for traefik because of the network_mode - 80:80 # Port for traefik because of the network_mode
{{end}} {{end}}
traefik: traefik:
image: traefik:v3.4.0 image: traefik:v3.4.1
container_name: traefik container_name: traefik
restart: unless-stopped restart: unless-stopped
{{if .InstallGerbil}} {{if .InstallGerbil}}

178
package-lock.json generated
View file

@ -87,7 +87,7 @@
"winston": "3.17.0", "winston": "3.17.0",
"winston-daily-rotate-file": "5.0.0", "winston-daily-rotate-file": "5.0.0",
"ws": "8.18.2", "ws": "8.18.2",
"zod": "3.25.46", "zod": "3.25.56",
"zod-validation-error": "3.4.1" "zod-validation-error": "3.4.1"
}, },
"devDependencies": { "devDependencies": {
@ -95,8 +95,8 @@
"@esbuild-plugins/tsconfig-paths": "0.1.2", "@esbuild-plugins/tsconfig-paths": "0.1.2",
"@tailwindcss/postcss": "^4.1.8", "@tailwindcss/postcss": "^4.1.8",
"@types/better-sqlite3": "7.6.12", "@types/better-sqlite3": "7.6.12",
"@types/cookie-parser": "1.4.8", "@types/cookie-parser": "1.4.9",
"@types/cors": "2.8.18", "@types/cors": "2.8.19",
"@types/crypto-js": "^4.2.2", "@types/crypto-js": "^4.2.2",
"@types/express": "5.0.0", "@types/express": "5.0.0",
"@types/jmespath": "^0.15.2", "@types/jmespath": "^0.15.2",
@ -104,8 +104,8 @@
"@types/jsonwebtoken": "^9.0.9", "@types/jsonwebtoken": "^9.0.9",
"@types/node": "^22", "@types/node": "^22",
"@types/nodemailer": "6.4.17", "@types/nodemailer": "6.4.17",
"@types/react": "19.1.6", "@types/react": "19.1.7",
"@types/react-dom": "19.1.5", "@types/react-dom": "19.1.6",
"@types/semver": "7.7.0", "@types/semver": "7.7.0",
"@types/swagger-ui-express": "^4.1.8", "@types/swagger-ui-express": "^4.1.8",
"@types/ws": "8.18.1", "@types/ws": "8.18.1",
@ -114,11 +114,12 @@
"esbuild": "0.25.5", "esbuild": "0.25.5",
"esbuild-node-externals": "1.18.0", "esbuild-node-externals": "1.18.0",
"postcss": "^8", "postcss": "^8",
"react-email": "4.0.15", "react-email": "4.0.16",
"tailwindcss": "^4.1.4", "tailwindcss": "^4.1.4",
"tsc-alias": "1.8.16", "tsc-alias": "1.8.16",
"tsx": "4.19.4", "tsx": "4.19.4",
"typescript": "^5", "typescript": "^5",
"typescript-eslint": "^8.34.0",
"yargs": "18.0.0" "yargs": "18.0.0"
} }
}, },
@ -4532,9 +4533,9 @@
} }
}, },
"node_modules/@types/cookie-parser": { "node_modules/@types/cookie-parser": {
"version": "1.4.8", "version": "1.4.9",
"resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.8.tgz", "resolved": "https://registry.npmjs.org/@types/cookie-parser/-/cookie-parser-1.4.9.tgz",
"integrity": "sha512-l37JqFrOJ9yQfRQkljb41l0xVphc7kg5JTjjr+pLRZ0IyZ49V4BQ8vbF4Ut2C2e+WH4al3xD3ZwYwIUfnbT4NQ==", "integrity": "sha512-tGZiZ2Gtc4m3wIdLkZ8mkj1T6CEHb35+VApbL2T14Dew8HA7c+04dmKqsKRNC+8RJPm16JEK0tFSwdZqubfc4g==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
@ -4542,9 +4543,9 @@
} }
}, },
"node_modules/@types/cors": { "node_modules/@types/cors": {
"version": "2.8.18", "version": "2.8.19",
"resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.18.tgz", "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.19.tgz",
"integrity": "sha512-nX3d0sxJW41CqQvfOzVG1NCTXfFDrDWIghCZncpHeWlVFd81zxB/DLhg7avFg6eHLCRX7ckBmoIIcqa++upvJA==", "integrity": "sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -4683,9 +4684,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/react": { "node_modules/@types/react": {
"version": "19.1.6", "version": "19.1.7",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz", "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.7.tgz",
"integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==", "integrity": "sha512-BnsPLV43ddr05N71gaGzyZ5hzkCmGwhMvYc8zmvI8Ci1bRkkDSzDDVfAXfN2tk748OwI7ediiPX6PfT9p0QGVg==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -4693,9 +4694,9 @@
} }
}, },
"node_modules/@types/react-dom": { "node_modules/@types/react-dom": {
"version": "19.1.5", "version": "19.1.6",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.5.tgz", "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.6.tgz",
"integrity": "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==", "integrity": "sha512-4hOiT/dwO8Ko0gV1m/TJZYk3y0KBnY9vzDh7W+DH17b2HFSOGgdj33dhihPeuy3l0q23+4e+hoXHV6hCC4dCXw==",
"devOptional": true, "devOptional": true,
"license": "MIT", "license": "MIT",
"peerDependencies": { "peerDependencies": {
@ -4777,16 +4778,16 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@typescript-eslint/eslint-plugin": { "node_modules/@typescript-eslint/eslint-plugin": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.0.tgz",
"integrity": "sha512-TDCXj+YxLgtvxvFlAvpoRv9MAncDLBV2oT9Bd7YBGC/b/sEURoOYuIwLI99rjWOfY3QtDzO+mk0n4AmdFExW8A==", "integrity": "sha512-QXwAlHlbcAwNlEEMKQS2RCgJsgXrTJdjXT08xEgbPFa2yYQgVjBymxP5DrfrE7X7iodSzd9qBUHUycdyVJTW1w==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/regexpp": "^4.10.0", "@eslint-community/regexpp": "^4.10.0",
"@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/scope-manager": "8.34.0",
"@typescript-eslint/type-utils": "8.33.1", "@typescript-eslint/type-utils": "8.34.0",
"@typescript-eslint/utils": "8.33.1", "@typescript-eslint/utils": "8.34.0",
"@typescript-eslint/visitor-keys": "8.33.1", "@typescript-eslint/visitor-keys": "8.34.0",
"graphemer": "^1.4.0", "graphemer": "^1.4.0",
"ignore": "^7.0.0", "ignore": "^7.0.0",
"natural-compare": "^1.4.0", "natural-compare": "^1.4.0",
@ -4800,7 +4801,7 @@
"url": "https://opencollective.com/typescript-eslint" "url": "https://opencollective.com/typescript-eslint"
}, },
"peerDependencies": { "peerDependencies": {
"@typescript-eslint/parser": "^8.33.1", "@typescript-eslint/parser": "^8.34.0",
"eslint": "^8.57.0 || ^9.0.0", "eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0" "typescript": ">=4.8.4 <5.9.0"
} }
@ -4815,15 +4816,15 @@
} }
}, },
"node_modules/@typescript-eslint/parser": { "node_modules/@typescript-eslint/parser": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.0.tgz",
"integrity": "sha512-qwxv6dq682yVvgKKp2qWwLgRbscDAYktPptK4JPojCwwi3R9cwrvIxS4lvBpzmcqzR4bdn54Z0IG1uHFskW4dA==", "integrity": "sha512-vxXJV1hVFx3IXz/oy2sICsJukaBrtDEQSBiV48/YIV5KWjX1dO+bcIr/kCPrW6weKXvsaGKFNlwH0v2eYdRRbA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/scope-manager": "8.34.0",
"@typescript-eslint/types": "8.33.1", "@typescript-eslint/types": "8.34.0",
"@typescript-eslint/typescript-estree": "8.33.1", "@typescript-eslint/typescript-estree": "8.34.0",
"@typescript-eslint/visitor-keys": "8.33.1", "@typescript-eslint/visitor-keys": "8.34.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -4839,13 +4840,13 @@
} }
}, },
"node_modules/@typescript-eslint/project-service": { "node_modules/@typescript-eslint/project-service": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.0.tgz",
"integrity": "sha512-DZR0efeNklDIHHGRpMpR5gJITQpu6tLr9lDJnKdONTC7vvzOlLAG/wcfxcdxEWrbiZApcoBCzXqU/Z458Za5Iw==", "integrity": "sha512-iEgDALRf970/B2YExmtPMPF54NenZUf4xpL3wsCRx/lgjz6ul/l13R81ozP/ZNuXfnLCS+oPmG7JIxfdNYKELw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/tsconfig-utils": "^8.33.1", "@typescript-eslint/tsconfig-utils": "^8.34.0",
"@typescript-eslint/types": "^8.33.1", "@typescript-eslint/types": "^8.34.0",
"debug": "^4.3.4" "debug": "^4.3.4"
}, },
"engines": { "engines": {
@ -4860,13 +4861,13 @@
} }
}, },
"node_modules/@typescript-eslint/scope-manager": { "node_modules/@typescript-eslint/scope-manager": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.0.tgz",
"integrity": "sha512-dM4UBtgmzHR9bS0Rv09JST0RcHYearoEoo3pG5B6GoTR9XcyeqX87FEhPo+5kTvVfKCvfHaHrcgeJQc6mrDKrA==", "integrity": "sha512-9Ac0X8WiLykl0aj1oYQNcLZjHgBojT6cW68yAgZ19letYu+Hxd0rE0veI1XznSSst1X5lwnxhPbVdwjDRIomRw==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.33.1", "@typescript-eslint/types": "8.34.0",
"@typescript-eslint/visitor-keys": "8.33.1" "@typescript-eslint/visitor-keys": "8.34.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4877,9 +4878,9 @@
} }
}, },
"node_modules/@typescript-eslint/tsconfig-utils": { "node_modules/@typescript-eslint/tsconfig-utils": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.0.tgz",
"integrity": "sha512-STAQsGYbHCF0/e+ShUQ4EatXQ7ceh3fBCXkNU7/MZVKulrlq1usH7t2FhxvCpuCi5O5oi1vmVaAjrGeL71OK1g==", "integrity": "sha512-+W9VYHKFIzA5cBeooqQxqNriAP0QeQ7xTiDuIOr71hzgffm3EL2hxwWBIIj4GuofIbKxGNarpKqIq6Q6YrShOA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4893,13 +4894,13 @@
} }
}, },
"node_modules/@typescript-eslint/type-utils": { "node_modules/@typescript-eslint/type-utils": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.0.tgz",
"integrity": "sha512-1cG37d9xOkhlykom55WVwG2QRNC7YXlxMaMzqw2uPeJixBFfKWZgaP/hjAObqMN/u3fr5BrTwTnc31/L9jQ2ww==", "integrity": "sha512-n7zSmOcUVhcRYC75W2pnPpbO1iwhJY3NLoHEtbJwJSNlVAZuwqu05zY3f3s2SDWWDSo9FdN5szqc73DCtDObAg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/typescript-estree": "8.33.1", "@typescript-eslint/typescript-estree": "8.34.0",
"@typescript-eslint/utils": "8.33.1", "@typescript-eslint/utils": "8.34.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"ts-api-utils": "^2.1.0" "ts-api-utils": "^2.1.0"
}, },
@ -4916,9 +4917,9 @@
} }
}, },
"node_modules/@typescript-eslint/types": { "node_modules/@typescript-eslint/types": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.0.tgz",
"integrity": "sha512-xid1WfizGhy/TKMTwhtVOgalHwPtV8T32MS9MaH50Cwvz6x6YqRIPdD2WvW0XaqOzTV9p5xdLY0h/ZusU5Lokg==", "integrity": "sha512-9V24k/paICYPniajHfJ4cuAWETnt7Ssy+R0Rbcqo5sSFr3QEZ/8TSoUi9XeXVBGXCaLtwTOKSLGcInCAvyZeMA==",
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -4929,15 +4930,15 @@
} }
}, },
"node_modules/@typescript-eslint/typescript-estree": { "node_modules/@typescript-eslint/typescript-estree": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.0.tgz",
"integrity": "sha512-+s9LYcT8LWjdYWu7IWs7FvUxpQ/DGkdjZeE/GGulHvv8rvYwQvVaUZ6DE+j5x/prADUgSbbCWZ2nPI3usuVeOA==", "integrity": "sha512-rOi4KZxI7E0+BMqG7emPSK1bB4RICCpF7QD3KCLXn9ZvWoESsOMlHyZPAHyG04ujVplPaHbmEvs34m+wjgtVtg==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/project-service": "8.33.1", "@typescript-eslint/project-service": "8.34.0",
"@typescript-eslint/tsconfig-utils": "8.33.1", "@typescript-eslint/tsconfig-utils": "8.34.0",
"@typescript-eslint/types": "8.33.1", "@typescript-eslint/types": "8.34.0",
"@typescript-eslint/visitor-keys": "8.33.1", "@typescript-eslint/visitor-keys": "8.34.0",
"debug": "^4.3.4", "debug": "^4.3.4",
"fast-glob": "^3.3.2", "fast-glob": "^3.3.2",
"is-glob": "^4.0.3", "is-glob": "^4.0.3",
@ -5009,15 +5010,15 @@
} }
}, },
"node_modules/@typescript-eslint/utils": { "node_modules/@typescript-eslint/utils": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.0.tgz",
"integrity": "sha512-52HaBiEQUaRYqAXpfzWSR2U3gxk92Kw006+xZpElaPMg3C4PgM+A5LqwoQI1f9E5aZ/qlxAZxzm42WX+vn92SQ==", "integrity": "sha512-8L4tWatGchV9A1cKbjaavS6mwYwp39jql8xUmIIKJdm+qiaeHy5KMKlBrf30akXAWBzn2SqKsNOtSENWUwg7XQ==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@eslint-community/eslint-utils": "^4.7.0", "@eslint-community/eslint-utils": "^4.7.0",
"@typescript-eslint/scope-manager": "8.33.1", "@typescript-eslint/scope-manager": "8.34.0",
"@typescript-eslint/types": "8.33.1", "@typescript-eslint/types": "8.34.0",
"@typescript-eslint/typescript-estree": "8.33.1" "@typescript-eslint/typescript-estree": "8.34.0"
}, },
"engines": { "engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0" "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
@ -5032,12 +5033,12 @@
} }
}, },
"node_modules/@typescript-eslint/visitor-keys": { "node_modules/@typescript-eslint/visitor-keys": {
"version": "8.33.1", "version": "8.34.0",
"resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.33.1.tgz", "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.0.tgz",
"integrity": "sha512-3i8NrFcZeeDHJ+7ZUuDkGT+UHq+XoFGsymNK2jZCOHcfEzRQ0BdpRtdpSx/Iyf3MHLWIcLS0COuOPibKQboIiQ==", "integrity": "sha512-qHV7pW7E85A0x6qyrFn+O+q1k1p3tQCsqIZ1KZ5ESLXY57aTvUd3/a4rdPTeXisvhXn2VQG0VSKUqs8KHF2zcA==",
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@typescript-eslint/types": "8.33.1", "@typescript-eslint/types": "8.34.0",
"eslint-visitor-keys": "^4.2.0" "eslint-visitor-keys": "^4.2.0"
}, },
"engines": { "engines": {
@ -13999,9 +14000,9 @@
"license": "0BSD" "license": "0BSD"
}, },
"node_modules/react-email": { "node_modules/react-email": {
"version": "4.0.15", "version": "4.0.16",
"resolved": "https://registry.npmjs.org/react-email/-/react-email-4.0.15.tgz", "resolved": "https://registry.npmjs.org/react-email/-/react-email-4.0.16.tgz",
"integrity": "sha512-UQR18Toi3TAasqcZal69rYZ9RiIKRvHRW69tN6k7hONJpEPeiC4uBtDwH5VxpllW591D+NOdpBF/V1pTansaKg==", "integrity": "sha512-auhFU+nQxAkKkP6lQhPyGsa9exwfUEzp2BwZnjHokCwphZlg30tu4t1LgdKRwGPYsi7XNGy6asbVLAUhOVpzzg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -15776,6 +15777,29 @@
"node": ">=14.17" "node": ">=14.17"
} }
}, },
"node_modules/typescript-eslint": {
"version": "8.34.0",
"resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.34.0.tgz",
"integrity": "sha512-MRpfN7uYjTrTGigFCt8sRyNqJFhjN0WwZecldaqhWm+wy0gaRt8Edb/3cuUy0zdq2opJWT6iXINKAtewnDOltQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@typescript-eslint/eslint-plugin": "8.34.0",
"@typescript-eslint/parser": "8.34.0",
"@typescript-eslint/utils": "8.34.0"
},
"engines": {
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
"eslint": "^8.57.0 || ^9.0.0",
"typescript": ">=4.8.4 <5.9.0"
}
},
"node_modules/unbox-primitive": { "node_modules/unbox-primitive": {
"version": "1.1.0", "version": "1.1.0",
"resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.1.0.tgz",
@ -16370,9 +16394,9 @@
} }
}, },
"node_modules/zod": { "node_modules/zod": {
"version": "3.25.46", "version": "3.25.56",
"resolved": "https://registry.npmjs.org/zod/-/zod-3.25.46.tgz", "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.56.tgz",
"integrity": "sha512-IqRxcHEIjqLd4LNS/zKffB3Jzg3NwqJxQQ0Ns7pdrvgGkwQsEBdEQcOHaBVqvvZArShRzI39+aMST3FBGmTrLQ==", "integrity": "sha512-rd6eEF3BTNvQnR2e2wwolfTmUTnp70aUTqr0oaGbHifzC3BKJsoV+Gat8vxUMR1hwOKBs6El+qWehrHbCpW6SQ==",
"license": "MIT", "license": "MIT",
"funding": { "funding": {
"url": "https://github.com/sponsors/colinhacks" "url": "https://github.com/sponsors/colinhacks"

View file

@ -104,7 +104,7 @@
"winston": "3.17.0", "winston": "3.17.0",
"winston-daily-rotate-file": "5.0.0", "winston-daily-rotate-file": "5.0.0",
"ws": "8.18.2", "ws": "8.18.2",
"zod": "3.25.46", "zod": "3.25.56",
"zod-validation-error": "3.4.1" "zod-validation-error": "3.4.1"
}, },
"devDependencies": { "devDependencies": {
@ -112,8 +112,8 @@
"@esbuild-plugins/tsconfig-paths": "0.1.2", "@esbuild-plugins/tsconfig-paths": "0.1.2",
"@tailwindcss/postcss": "^4.1.8", "@tailwindcss/postcss": "^4.1.8",
"@types/better-sqlite3": "7.6.12", "@types/better-sqlite3": "7.6.12",
"@types/cookie-parser": "1.4.8", "@types/cookie-parser": "1.4.9",
"@types/cors": "2.8.18", "@types/cors": "2.8.19",
"@types/crypto-js": "^4.2.2", "@types/crypto-js": "^4.2.2",
"@types/express": "5.0.0", "@types/express": "5.0.0",
"@types/jmespath": "^0.15.2", "@types/jmespath": "^0.15.2",
@ -121,8 +121,8 @@
"@types/jsonwebtoken": "^9.0.9", "@types/jsonwebtoken": "^9.0.9",
"@types/node": "^22", "@types/node": "^22",
"@types/nodemailer": "6.4.17", "@types/nodemailer": "6.4.17",
"@types/react": "19.1.6", "@types/react": "19.1.7",
"@types/react-dom": "19.1.5", "@types/react-dom": "19.1.6",
"@types/semver": "7.7.0", "@types/semver": "7.7.0",
"@types/swagger-ui-express": "^4.1.8", "@types/swagger-ui-express": "^4.1.8",
"@types/ws": "8.18.1", "@types/ws": "8.18.1",
@ -131,11 +131,12 @@
"esbuild": "0.25.5", "esbuild": "0.25.5",
"esbuild-node-externals": "1.18.0", "esbuild-node-externals": "1.18.0",
"postcss": "^8", "postcss": "^8",
"react-email": "4.0.15", "react-email": "4.0.16",
"tailwindcss": "^4.1.4", "tailwindcss": "^4.1.4",
"tsc-alias": "1.8.16", "tsc-alias": "1.8.16",
"tsx": "4.19.4", "tsx": "4.19.4",
"typescript": "^5", "typescript": "^5",
"typescript-eslint": "^8.34.0",
"yargs": "18.0.0" "yargs": "18.0.0"
}, },
"overrides": { "overrides": {

View file

@ -2,7 +2,7 @@ import path from "path";
import { fileURLToPath } from "url"; import { fileURLToPath } from "url";
// This is a placeholder value replaced by the build process // This is a placeholder value replaced by the build process
export const APP_VERSION = "1.5.0"; export const APP_VERSION = "1.5.1";
export const __FILENAME = fileURLToPath(import.meta.url); export const __FILENAME = fileURLToPath(import.meta.url);
export const __DIRNAME = path.dirname(__FILENAME); export const __DIRNAME = path.dirname(__FILENAME);

View file

@ -27,6 +27,7 @@ import { formatAxiosError } from "@app/lib/api";
import { createApiClient } from "@app/lib/api"; import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext"; import { useEnvContext } from "@app/hooks/useEnvContext";
import CreateSiteFormModal from "./CreateSiteModal"; import CreateSiteFormModal from "./CreateSiteModal";
import { parseDataSize } from '@app/lib/dataSize';
export type SiteRow = { export type SiteRow = {
id: number; id: number;
@ -197,7 +198,9 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
<ArrowUpDown className="ml-2 h-4 w-4" /> <ArrowUpDown className="ml-2 h-4 w-4" />
</Button> </Button>
); );
} },
sortingFn: (rowA, rowB) =>
parseDataSize(rowA.original.mbIn) - parseDataSize(rowB.original.mbIn)
}, },
{ {
accessorKey: "mbOut", accessorKey: "mbOut",
@ -213,7 +216,9 @@ export default function SitesTable({ sites, orgId }: SitesTableProps) {
<ArrowUpDown className="ml-2 h-4 w-4" /> <ArrowUpDown className="ml-2 h-4 w-4" />
</Button> </Button>
); );
} },
sortingFn: (rowA, rowB) =>
parseDataSize(rowA.original.mbOut) - parseDataSize(rowB.original.mbOut),
}, },
{ {
accessorKey: "type", accessorKey: "type",

View file

@ -32,6 +32,8 @@ import { createApiClient } from "@app/lib/api";
import { useEnvContext } from "@app/hooks/useEnvContext"; import { useEnvContext } from "@app/hooks/useEnvContext";
import { useState } from "react"; import { useState } from "react";
import { SwitchInput } from "@app/components/SwitchInput"; import { SwitchInput } from "@app/components/SwitchInput";
import Link from "next/link";
import { ArrowRight, ExternalLink } from "lucide-react";
const GeneralFormSchema = z.object({ const GeneralFormSchema = z.object({
name: z.string().nonempty("Name is required"), name: z.string().nonempty("Name is required"),
@ -151,8 +153,18 @@ export default function GeneralPage() {
<FormDescription> <FormDescription>
Enable Docker Socket Enable Docker Socket
discovery for populating discovery for populating
container information, container information.
useful in resource targets. Socket path must be provided
to Newt.{" "}
<a
href="https://docs.fossorial.io/Newt/overview#docker-socket-integration"
target="_blank"
rel="noopener noreferrer"
className="text-primary hover:underline inline-flex items-center"
>
Learn more
<ExternalLink className="ml-1 h-4 w-4" />
</a>
</FormDescription> </FormDescription>
</FormItem> </FormItem>
)} )}

View file

@ -82,7 +82,14 @@ export default function StepperForm() {
); );
const generateId = (name: string) => { const generateId = (name: string) => {
return name.toLowerCase().replace(/\s+/g, "-"); // Replace any character that is not a letter, number, space, or hyphen with a hyphen
// Also collapse multiple hyphens and trim
return name
.toLowerCase()
.replace(/[^a-z0-9\s-]/g, "-")
.replace(/\s+/g, "-")
.replace(/-+/g, "-")
.replace(/^-+|-+$/g, "");
}; };
async function orgSubmit(values: z.infer<typeof orgSchema>) { async function orgSubmit(values: z.infer<typeof orgSchema>) {
@ -207,23 +214,22 @@ export default function StepperForm() {
type="text" type="text"
{...field} {...field}
onChange={(e) => { onChange={(e) => {
const orgId = // Prevent "/" in orgName input
generateId( const sanitizedValue = e.target.value.replace(/\//g, "-");
e.target const orgId = generateId(sanitizedValue);
.value
);
orgForm.setValue( orgForm.setValue(
"orgId", "orgId",
orgId orgId
); );
orgForm.setValue( orgForm.setValue(
"orgName", "orgName",
e.target.value sanitizedValue
); );
debouncedCheckOrgIdAvailability( debouncedCheckOrgIdAvailability(
orgId orgId
); );
}} }}
value={field.value.replace(/\//g, "-")}
/> />
</FormControl> </FormControl>
<FormMessage /> <FormMessage />

View file

@ -95,7 +95,7 @@ export const ContainersSelector: FC<ContainerSelectorProps> = ({
<CredenzaTitle>Containers in {site.name}</CredenzaTitle> <CredenzaTitle>Containers in {site.name}</CredenzaTitle>
<CredenzaDescription> <CredenzaDescription>
Select any container to use as a hostname for this Select any container to use as a hostname for this
target. Click a port to use select a port. target. Click a port to use a port.
</CredenzaDescription> </CredenzaDescription>
</CredenzaHeader> </CredenzaHeader>
<CredenzaBody> <CredenzaBody>
@ -346,16 +346,19 @@ const DockerContainersTable: FC<{
{ {
id: "actions", id: "actions",
header: "Actions", header: "Actions",
cell: ({ row }) => ( cell: ({ row }) => {
const ports = getExposedPorts(row.original);
return (
<Button <Button
variant="default" variant="default"
size="sm" size="sm"
onClick={() => onContainerSelect(row.original)} onClick={() => onContainerSelect(row.original, ports[0])}
disabled={row.original.state !== "running"} disabled={row.original.state !== "running"}
> >
Select Select
</Button> </Button>
) );
}
} }
]; ];

View file

@ -21,7 +21,8 @@ export function useDockerSocket(site: Site) {
const api = createApiClient(useEnvContext()); const api = createApiClient(useEnvContext());
const { dockerSocketEnabled: isEnabled = true } = site || {}; const { dockerSocketEnabled: rawIsEnabled = true, type: siteType } = site || {};
const isEnabled = rawIsEnabled && siteType === "newt";
const { isAvailable = false, socketPath } = dockerSocket || {}; const { isAvailable = false, socketPath } = dockerSocket || {};
const checkDockerSocket = useCallback(async () => { const checkDockerSocket = useCallback(async () => {

21
src/lib/dataSize.ts Normal file
View file

@ -0,0 +1,21 @@
export function parseDataSize(sizeStr: string): number {
if (typeof sizeStr !== 'string') return 0;
const match = /^\s*([\d.]+)\s*([KMGT]?B)\s*$/i.exec(sizeStr);
if (!match) return 0;
const [ , numStr, unitRaw ] = match;
const num = parseFloat(numStr);
if (isNaN(num)) return 0;
const unit = unitRaw.toUpperCase();
const multipliers = {
B: 1,
KB: 1024,
MB: 1024 ** 2,
GB: 1024 ** 3,
TB: 1024 ** 4,
} as const;
return num * (multipliers[unit as keyof typeof multipliers] ?? 1);
}