Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,6 @@ module.exports = {
'@typescript-eslint/no-use-before-define': 'warn',
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
'@typescript-eslint/ban-ts-comment': ['error', { 'ts-expect-error': 'allow-with-description' }],
'react/no-unknown-property': ['error', { ignore: ['css'] }],
},
};
8 changes: 4 additions & 4 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ jobs:
strategy:
fail-fast: false
matrix:
node-version: [16]
node-version: [22]
steps:
- name: Code Checkout
uses: actions/checkout@v4
Expand All @@ -32,6 +32,6 @@ jobs:

- name: Install dependencies
run: yarn install --frozen-lockfile

- name: Build
run: yarn build:production
- run: yarn tsc
- run: yarn lint
- run: yarn build:production
4 changes: 3 additions & 1 deletion .github/workflows/release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ jobs:
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 16
node-version: 22
cache: yarn

- name: Install dependencies
run: yarn install --frozen-lockfile

- run: yarn tsc
- run: yarn lint
- name: Build
run: yarn build:production

Expand Down
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Build the assets that are needed for the frontend. This build stage is then discarded
# since we won't need NodeJS anymore in the future. This Docker image ships a final production
# level distribution of Pterodactyl.
FROM --platform=$TARGETOS/$TARGETARCH mhart/alpine-node:14
FROM --platform=$TARGETOS/$TARGETARCH node:22-alpine
WORKDIR /app
COPY . ./
RUN yarn install --frozen-lockfile \
Expand Down
67 changes: 33 additions & 34 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "pterodactyl-panel",
"engines": {
"node": ">=14"
"node": ">=22"
},
"dependencies": {
"@floating-ui/react-dom-interactions": "^0.6.6",
Expand All @@ -14,7 +14,7 @@
"@preact/signals-react": "^1.2.1",
"@tailwindcss/forms": "^0.5.2",
"@tailwindcss/line-clamp": "^0.4.0",
"axios": "^0.27.2",
"axios": "^1.13.2",
"boring-avatars": "^1.7.0",
"chart.js": "^3.8.0",
"classnames": "^2.3.1",
Expand All @@ -30,6 +30,7 @@
"i18next": "^21.8.9",
"i18next-http-backend": "^1.4.1",
"i18next-multiload-backend-adapter": "^1.0.0",
"pathe": "^2.0.3",
"qrcode.react": "^1.0.1",
"react": "^16.14.0",
"react-chartjs-2": "^4.2.0",
Expand All @@ -41,12 +42,12 @@
"react-transition-group": "^4.4.1",
"reaptcha": "^1.7.2",
"sockette": "^2.0.6",
"styled-components": "^5.2.1",
"styled-components": "^5.3.0",
"styled-components-breakpoint": "^3.0.0-preview.20",
"swr": "^0.2.3",
"tailwindcss": "^3.0.24",
"use-fit-text": "^2.4.0",
"uuid": "^8.3.2",
"uuid": "^13.0.0",
"xterm": "^4.19.0",
"xterm-addon-fit": "^0.5.0",
"xterm-addon-search": "^0.9.0",
Expand Down Expand Up @@ -76,7 +77,8 @@
"@types/debounce": "^1.2.0",
"@types/events": "^3.0.0",
"@types/jest": "^28.1.3",
"@types/node": "^14.11.10",
"@types/node": "^22.0.0",
"@types/path-browserify": "^1.0.3",
"@types/qrcode.react": "^1.0.1",
"@types/react": "^16.14.0",
"@types/react-copy-to-clipboard": "^4.3.0",
Expand All @@ -85,58 +87,55 @@
"@types/react-router": "^5.1.3",
"@types/react-router-dom": "^5.1.3",
"@types/react-transition-group": "^4.4.0",
"@types/styled-components": "^5.1.7",
"@types/styled-components": "5.1.7",
"@types/uuid": "^3.4.5",
"@types/webpack-env": "^1.15.2",
"@types/webpack-env": "^1.18.8",
"@types/yup": "^0.29.3",
"@typescript-eslint/eslint-plugin": "^5.29.0",
"@typescript-eslint/parser": "^5.29.0",
"@typescript-eslint/eslint-plugin": "^5",
"@typescript-eslint/parser": "^5",
"autoprefixer": "^10.4.7",
"babel-jest": "^28.1.1",
"babel-loader": "^8.2.5",
"babel-loader": "^10.0.0",
"babel-plugin-styled-components": "^2.0.7",
"cross-env": "^7.0.2",
"css-loader": "^5.2.7",
"eslint": "^8.18.0",
"eslint-config-prettier": "^8.5.0",
"css-loader": "^7.1.2",
"eslint": "^8",
"eslint-config-prettier": "^8",
"eslint-plugin-jest-dom": "^4.0.2",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.30.1",
"eslint-plugin-react-hooks": "^4.6.0",
"fork-ts-checker-webpack-plugin": "^6.2.10",
"eslint-plugin-prettier": "^4",
"eslint-plugin-react": "^7",
"eslint-plugin-react-hooks": "^4",
"identity-obj-proxy": "^3.0.0",
"jest": "^28.1.1",
"postcss": "^8.4.14",
"postcss": "^8.5.6",
"postcss-import": "^14.1.0",
"postcss-loader": "^4.0.0",
"postcss-nesting": "^10.1.8",
"postcss-preset-env": "^7.7.1",
"postcss-loader": "^8.2.0",
"postcss-nesting": "^13.0.2",
"postcss-preset-env": "^10.4.0",
"prettier": "^2.7.1",
"redux-devtools-extension": "^2.13.8",
"source-map-loader": "^1.1.3",
"style-loader": "^2.0.0",
"svg-url-loader": "^7.1.1",
"terser-webpack-plugin": "^4.2.3",
"source-map-loader": "^5.0.0",
"style-loader": "^4.0.0",
"svg-url-loader": "^8.0.0",
"terser-webpack-plugin": "^5.3.14",
"ts-essentials": "^9.1.2",
"ts-jest": "^28.0.5",
"twin.macro": "^2.8.2",
"typescript": "^4.7.3",
"webpack": "^4.43.0",
"webpack-assets-manifest": "^3.1.1",
"webpack-bundle-analyzer": "^3.8.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0",
"yarn-deduplicate": "^1.1.1"
"typescript": "~5.1.0",
"webpack": "^5.103.0",
"webpack-assets-manifest": "^6.4.0",
"webpack-cli": "^6.0.1",
"webpack-dev-server": "^5.2.2"
},
"scripts": {
"clean": "cd public/assets && find . \\( -name \"*.js\" -o -name \"*.map\" \\) -type f -delete",
"test": "jest",
"tsc": "tsc --noEmit",
"lint": "eslint ./resources/scripts/**/*.{ts,tsx} --ext .ts,.tsx",
"watch": "cross-env NODE_ENV=development ./node_modules/.bin/webpack --watch --progress",
"build": "cross-env NODE_ENV=development ./node_modules/.bin/webpack --progress",
"build:production": "yarn run clean && cross-env NODE_ENV=production ./node_modules/.bin/webpack --mode production",
"serve": "yarn run clean && cross-env WEBPACK_PUBLIC_PATH=/webpack@hmr/ NODE_ENV=development webpack-dev-server --host 0.0.0.0 --port 8080 --public https://pterodactyl.test --hot"
"serve": "yarn run clean && cross-env NODE_ENV=development WEBPACK_PUBLIC_PATH=https://localhost:5173/ webpack serve --progress --hot --server-type https"
},
"browserslist": [
"> 0.5%",
Expand Down
1 change: 1 addition & 0 deletions resources/scripts/components/elements/CopyOnClick.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const CopyOnClick = ({ text, showInNotification = true, children }: CopyOnClickP
const child = !text
? React.Children.only(children)
: React.cloneElement(React.Children.only(children), {
// @ts-expect-error todo: check on this
className: classNames(children.props.className || '', 'cursor-pointer'),
onClick: (e: React.MouseEvent<HTMLElement>) => {
copy(String(text));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
} from '@fortawesome/free-solid-svg-icons';
import RenameFileModal from '@/components/server/files/RenameFileModal';
import { ServerContext } from '@/state/server';
import { join } from 'path';
import { join } from 'pathe';
import deleteFiles from '@/api/server/files/deleteFiles';
import SpinnerOverlay from '@/components/elements/SpinnerOverlay';
import copyFile from '@/api/server/files/copyFile';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import useFlash from '@/plugins/useFlash';
import { ServerContext } from '@/state/server';
import ErrorBoundary from '@/components/elements/ErrorBoundary';
import { encodePathSegments, hashToPath } from '@/helpers';
import { dirname } from 'path';
import { dirname } from 'pathe';
import CodemirrorEditor from '@/components/elements/CodemirrorEditor';

export default () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Form, Formik, FormikHelpers } from 'formik';
import { object, string } from 'yup';
import Field from '@/components/elements/Field';
import { ServerContext } from '@/state/server';
import { join } from 'path';
import { join } from 'pathe';
import tw from 'twin.macro';
import Button from '@/components/elements/Button';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import tw from 'twin.macro';
import isEqual from 'react-fast-compare';
import SelectFileCheckbox from '@/components/server/files/SelectFileCheckbox';
import { usePermissions } from '@/plugins/usePermissions';
import { join } from 'path';
import { join } from 'pathe';
import { bytesToString } from '@/lib/formatters';
import styles from './style.module.css';

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useContext, useEffect, useState } from 'react';
import { ServerContext } from '@/state/server';
import { Form, Formik, FormikHelpers } from 'formik';
import Field from '@/components/elements/Field';
import { join } from 'path';
import { join } from 'pathe';
import { object, string } from 'yup';
import createDirectory from '@/api/server/files/createDirectory';
import tw from 'twin.macro';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react';
import Modal, { RequiredModalProps } from '@/components/elements/Modal';
import { Form, Formik, FormikHelpers } from 'formik';
import Field from '@/components/elements/Field';
import { join } from 'path';
import { join } from 'pathe';
import renameFiles from '@/api/server/files/renameFiles';
import { ServerContext } from '@/state/server';
import tw from 'twin.macro';
Expand Down
4 changes: 2 additions & 2 deletions resources/scripts/components/server/files/UploadButton.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import axios from 'axios';
import axios, { AxiosProgressEvent } from 'axios';
import getFileUploadUrl from '@/api/server/files/getFileUploadUrl';
import tw from 'twin.macro';
import { Button } from '@/components/elements/button/index';
Expand Down Expand Up @@ -57,7 +57,7 @@ export default ({ className }: WithClassname) => {
return () => timeouts.value.forEach(clearTimeout);
}, []);

const onUploadProgress = (data: ProgressEvent, name: string) => {
const onUploadProgress = (data: AxiosProgressEvent, name: string) => {
setUploadProgress({ name, loaded: data.loaded });
};

Expand Down
10 changes: 4 additions & 6 deletions resources/scripts/components/server/startup/VariableBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,15 @@ const VariableBox = ({ variable }: Props) => {
return (
<TitledGreyBox
title={
<p className="text-sm uppercase">
<p className='text-sm uppercase'>
{!variable.isEditable && (
<span className="bg-neutral-700 text-xs py-1 px-2 rounded-full mr-2 mb-1">Read Only</span>
<span className='bg-neutral-700 text-xs py-1 px-2 rounded-full mr-2 mb-1'>Read Only</span>
)}
{variable.name}
</p>
}
>
<FlashMessageRender byKey={FLASH_KEY} className="mb-2 md:mb-4" />
<FlashMessageRender byKey={FLASH_KEY} className='mb-2 md:mb-4' />
<InputSpinner visible={loading}>
{useSwitch ? (
<>
Expand Down Expand Up @@ -128,9 +128,7 @@ const VariableBox = ({ variable }: Props) => {
)}
</InputSpinner>

<p className="mt-1 text-xs text-neutral-300">
{variable.description}
</p>
<p className='mt-1 text-xs text-neutral-300'>{variable.description}</p>
</TitledGreyBox>
);
};
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"baseUrl": ".",
"importsNotUsedAsValues": "preserve",
"verbatimModuleSyntax": false,
"paths": {
"@/*": [
"./resources/scripts/*"
Expand Down
47 changes: 17 additions & 30 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
const path = require('path');
const path = require('node:path');
const webpack = require('webpack');
const AssetsManifestPlugin = require('webpack-assets-manifest');
const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin');
const { WebpackAssetsManifest } = require('webpack-assets-manifest');
const TerserPlugin = require('terser-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

const isProduction = process.env.NODE_ENV === 'production';

module.exports = {
cache: true,
target: 'web',
mode: process.env.NODE_ENV,
devtool: isProduction ? false : (process.env.DEVTOOL || 'eval-source-map'),
mode: isProduction ? 'production' : 'development',
devtool: process.env.DEVTOOL || (isProduction ? false : 'eval-source-map'),
performance: {
hints: false,
},
entry: ['react-hot-loader/patch', './resources/scripts/index.tsx'],
output: {
path: path.join(__dirname, '/public/assets'),
filename: isProduction ? 'bundle.[chunkhash:8].js' : 'bundle.[hash:8].js',
chunkFilename: isProduction ? '[name].[chunkhash:8].js' : '[name].[hash:8].js',
filename: isProduction ? 'bundle.[chunkhash:8].js' : 'bundle.[fullhash:8].js',
chunkFilename: isProduction ? '[name].[chunkhash:8].js' : '[name].[fullhash:8].js',
publicPath: (process.env.WEBPACK_PUBLIC_PATH || '/assets/'),
crossOriginLoading: 'anonymous',
},
Expand All @@ -44,6 +42,9 @@ module.exports = {
options: {
modules: {
auto: true,
// https://github.com/webpack/css-loader/blob/main/CHANGELOG.md#700-2024-04-04
namedExport: false,
exportLocalsConvention: 'as-is',
localIdentName: isProduction ? '[name]_[hash:base64:8]' : '[path][name]__[local]',
localIdentContext: path.join(__dirname, 'resources/scripts/components'),
},
Expand Down Expand Up @@ -96,28 +97,12 @@ module.exports = {
},
plugins: [
new webpack.EnvironmentPlugin({
NODE_ENV: 'development',
NODE_ENV: process.env.NODE_ENV || 'development',
DEBUG: process.env.NODE_ENV !== 'production',
WEBPACK_BUILD_HASH: Date.now().toString(16),
}),
new AssetsManifestPlugin({ writeToDisk: true, publicPath: true, integrity: true, integrityHashes: ['sha384'] }),
new ForkTsCheckerWebpackPlugin({
typescript: {
mode: 'write-references',
diagnosticOptions: {
semantic: true,
syntactic: true,
},
},
eslint: isProduction ? undefined : {
files: `${path.join(__dirname, '/resources/scripts')}/**/*.{ts,tsx}`,
}
}),
process.env.ANALYZE_BUNDLE ? new BundleAnalyzerPlugin({
analyzerHost: '0.0.0.0',
analyzerPort: 8081,
}) : null
].filter(p => p),
new WebpackAssetsManifest({ output: 'manifest.json', writeToDisk: true, publicPath: true, integrity: true, integrityHashes: ['sha384'] }),
],
optimization: {
usedExports: true,
sideEffects: false,
Expand All @@ -126,7 +111,6 @@ module.exports = {
minimize: isProduction,
minimizer: [
new TerserPlugin({
cache: isProduction,
parallel: true,
extractComments: false,
terserOptions: {
Expand All @@ -144,8 +128,11 @@ module.exports = {
},
devServer: {
compress: true,
contentBase: path.join(__dirname, '/public'),
publicPath: process.env.WEBPACK_PUBLIC_PATH || '/assets/',
port: 5173,
static: {
directory: path.join(__dirname, '/public'),
publicPath: process.env.WEBPACK_PUBLIC_PATH || '/assets/',
},
allowedHosts: [
'.pterodactyl.test',
],
Expand Down
Loading
Loading