mirror of
https://github.com/sern-handler/gui
synced 2026-06-05 17:06:52 +00:00
refactor: move to vite + ts + swc
This commit is contained in:
27
.eslintrc.cjs
Normal file
27
.eslintrc.cjs
Normal file
@@ -0,0 +1,27 @@
|
||||
/* eslint-env node */
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
env: { browser: true, es2020: true },
|
||||
extends: [
|
||||
'eslint:recommended',
|
||||
'plugin:@typescript-eslint/recommended',
|
||||
'plugin:@typescript-eslint/recommended-requiring-type-checking',
|
||||
'plugin:react-hooks/recommended',
|
||||
],
|
||||
parser: '@typescript-eslint/parser',
|
||||
parserOptions: {
|
||||
ecmaVersion: 'latest',
|
||||
sourceType: 'module',
|
||||
project: true,
|
||||
tsconfigRootDir: __dirname,
|
||||
},
|
||||
plugins: ['react-refresh'],
|
||||
rules: {
|
||||
'react-refresh/only-export-components': [
|
||||
'warn',
|
||||
{ allowConstantExport: true },
|
||||
],
|
||||
'@typescript-eslint/no-non-null-assertion': 'off',
|
||||
},
|
||||
}
|
||||
44
.gitignore
vendored
44
.gitignore
vendored
@@ -1,25 +1,27 @@
|
||||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||
|
||||
# dependencies
|
||||
/node_modules
|
||||
/.pnp
|
||||
.pnp.js
|
||||
|
||||
# testing
|
||||
/coverage
|
||||
|
||||
# production
|
||||
/build
|
||||
|
||||
# misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
# Logs
|
||||
logs
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
pnpm-debug.log*
|
||||
lerna-debug.log*
|
||||
|
||||
dist/
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
*.local
|
||||
|
||||
# Editor directories and files
|
||||
.vscode/*
|
||||
!.vscode/extensions.json
|
||||
.idea
|
||||
.DS_Store
|
||||
*.suo
|
||||
*.ntvs*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw?
|
||||
|
||||
# some random thing from electron (it doesnt compile in a dist folder for some reason
|
||||
./electron/index.js
|
||||
@@ -1,9 +1,9 @@
|
||||
const path = require('path');
|
||||
const { app, BrowserWindow, dialog, ipcMain } = require('electron');
|
||||
const isDev = require('electron-is-dev');
|
||||
const fs = require('fs');
|
||||
const colorette = require('colorette')
|
||||
const { exec } = require('node:child_process')
|
||||
import * as path from 'node:path'
|
||||
import { app, BrowserWindow, dialog, ipcMain } from 'electron';
|
||||
import * as isDev from 'electron-is-dev';
|
||||
import * as fs from 'fs';
|
||||
import * as colorette from 'colorette';
|
||||
import { exec } from 'node:child_process';
|
||||
|
||||
function createWindow() {
|
||||
const mainWindow = new BrowserWindow({
|
||||
@@ -19,7 +19,7 @@ function createWindow() {
|
||||
title: 'sern',
|
||||
});
|
||||
if (isDev) {
|
||||
mainWindow.loadURL('http://localhost:3000');
|
||||
mainWindow.loadURL('http://localhost:5173');
|
||||
} else {
|
||||
mainWindow.loadFile(path.join(__dirname, '../build/index.html'));
|
||||
}
|
||||
@@ -32,7 +32,7 @@ function createWindow() {
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
ipcMain.on('openFolder', (event, arg) => {
|
||||
ipcMain.on('openFolder', (event, _arg) => {
|
||||
dialog
|
||||
.showOpenDialog({
|
||||
properties: ['openDirectory'],
|
||||
@@ -52,7 +52,7 @@ function createWindow() {
|
||||
console.log(data);
|
||||
console.log(`${colorette.cyan('🛈')} Current OS: ${currentOS}`)
|
||||
|
||||
let packageManagerCommand
|
||||
let packageManagerCommand: string
|
||||
switch (data.chosenPackageManager) {
|
||||
case 'npm':
|
||||
packageManagerCommand = `npm create @sern/bot@latest -- --template=${data.chosenTemplate} --name="${data.projectName}" --install=npm`
|
||||
@@ -67,7 +67,7 @@ function createWindow() {
|
||||
packageManagerCommand = `npm create @sern/bot@latest -- --template=${data.chosenTemplate} --name="${data.projectName}"`
|
||||
break;
|
||||
}
|
||||
let commandToRun
|
||||
let commandToRun: string
|
||||
switch (currentOS) {
|
||||
case 'linux':
|
||||
commandToRun = `cd ${data.selectedPath};${packageManagerCommand}`
|
||||
@@ -87,11 +87,11 @@ function createWindow() {
|
||||
console.log(`${colorette.cyan('🛈')} About to execute command: ${commandToRun}`)
|
||||
const cmd = exec(commandToRun)
|
||||
|
||||
cmd.stdout.on('data', (data) => {
|
||||
cmd.stdout!.on('data', (data) => {
|
||||
console.log(`${colorette.cyan('🛈')} Command stdout: ${data}`);
|
||||
});
|
||||
|
||||
cmd.stderr.on('data', (data) => {
|
||||
cmd.stderr!.on('data', (data) => {
|
||||
console.error(`${colorette.red('×')} Command stderr: ${data}`);
|
||||
});
|
||||
|
||||
@@ -116,7 +116,7 @@ app.on('activate', () => {
|
||||
}
|
||||
});
|
||||
|
||||
let currentOS
|
||||
let currentOS: string
|
||||
switch (process.platform) {
|
||||
case 'linux':
|
||||
currentOS = 'linux'
|
||||
@@ -133,4 +133,21 @@ switch (process.platform) {
|
||||
break;
|
||||
}
|
||||
|
||||
console.log(fs.readFileSync(__dirname + '/ascii.txt', 'utf-8'))
|
||||
const asciiart = ` .:-=-:.
|
||||
.:=+++++++++=-.
|
||||
:-=+++++++++++++++++=-:
|
||||
=++++++++++++++++++++=:.
|
||||
=+++++++++++++++=-:
|
||||
=++++++++++++-. ###### ######## ######## ## ## ###### ## ## ####
|
||||
=++++++++++++*+=:. ## ## ## ## ## ### ## ## ## ## ## ##
|
||||
=++++++++++++******=-. ## ## ## ## #### ## ## ## ## ##
|
||||
:=+++++++++++**********+- ###### ###### ######## ## ## ## ## #### ## ## ##
|
||||
.:-+++++++********###* ## ## ## ## ## #### ## ## ## ## ##
|
||||
:-=++***########* ## ## ## ## ## ## ### ## ## ## ## ##
|
||||
.-*###########* ###### ######## ## ## ## ## ###### ####### ####
|
||||
:=+###############*
|
||||
.-=*###################*
|
||||
.:=*#################*=-.
|
||||
:=+#########+=:
|
||||
`
|
||||
console.log(asciiart)
|
||||
26
electron/tsconfig.json
Normal file
26
electron/tsconfig.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./dist",
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "node",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"esModuleInterop": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
}
|
||||
|
||||
13
index.html
Normal file
13
index.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>Vite + React + TS</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
<script type="module" src="/src/main.tsx"></script>
|
||||
</body>
|
||||
</html>
|
||||
70
package.json
70
package.json
@@ -1,10 +1,20 @@
|
||||
{
|
||||
"name": "sern-gui",
|
||||
"productName": "sern-gui",
|
||||
"version": "0.1.0-alpha",
|
||||
"main": "./electron/index.js",
|
||||
"private": true,
|
||||
"version": "0.1.0-alpha",
|
||||
"main": "./dist/index.js",
|
||||
"homepage": "./",
|
||||
"scripts": {
|
||||
"start": "vite",
|
||||
"dev": "concurrently -k \"yarn:start\" \"yarn:electron\"",
|
||||
"build": "tsc && vite build",
|
||||
"lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview",
|
||||
"electron": "tsc-watch ./electron/index.ts --outDir \"./dist\" --onSuccess \"electron .\"",
|
||||
"build-electron": "yarn build && electron-builder --linux --windows",
|
||||
"build-electron-linux": "yarn build && electron-builder --linux",
|
||||
"build-electron-win": "yarn build && electron-builder --windows"
|
||||
},
|
||||
"dependencies": {
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
@@ -17,19 +27,24 @@
|
||||
"colorette": "^2.0.20",
|
||||
"electron-is-dev": "^2.0.0",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-scripts": "5.0.1"
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject",
|
||||
"dev": "concurrently -k \"BROWSER=none yarn start\" \"yarn:electron\"",
|
||||
"electron": "electron .",
|
||||
"build-electron": "yarn build && electron-builder --linux --windows",
|
||||
"build-electron-linux": "yarn build && electron-builder --linux",
|
||||
"build-electron-win": "yarn build && electron-builder --windows"
|
||||
"devDependencies": {
|
||||
"@types/react": "^18.2.14",
|
||||
"@types/react-dom": "^18.2.6",
|
||||
"@typescript-eslint/eslint-plugin": "^5.61.0",
|
||||
"@typescript-eslint/parser": "^5.61.0",
|
||||
"@vitejs/plugin-react-swc": "^3.3.2",
|
||||
"concurrently": "^8.2.0",
|
||||
"electron": "^25.2.0",
|
||||
"electron-builder": "^24.4.0",
|
||||
"eslint": "^8.44.0",
|
||||
"eslint-plugin-react-hooks": "^4.6.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.1",
|
||||
"tsc-watch": "^6.0.4",
|
||||
"typescript": "^5.0.2",
|
||||
"vite": "^4.4.0",
|
||||
"wait-on": "^7.0.1"
|
||||
},
|
||||
"build": {
|
||||
"extends": null,
|
||||
@@ -43,30 +58,5 @@
|
||||
"icon": "./icons/icon.ico",
|
||||
"publisherName": "sern"
|
||||
}
|
||||
},
|
||||
"eslintConfig": {
|
||||
"extends": [
|
||||
"react-app",
|
||||
"react-app/jest"
|
||||
]
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-private-property-in-object": "^7.21.11",
|
||||
"concurrently": "^8.2.0",
|
||||
"electron": "^25.2.0",
|
||||
"electron-builder": "^24.4.0",
|
||||
"wait-on": "^7.0.1"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
@font-face {
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap');
|
||||
|
||||
/* @font-face {
|
||||
font-family: 'Classic Console Neue';
|
||||
src: local('Classic Console Neue'),
|
||||
url('https://fonts.srizan.dev/clacon2.ttf') format('truetype');
|
||||
}
|
||||
|
||||
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono&display=swap');
|
||||
} */
|
||||
|
||||
.titleHeader {
|
||||
color: #4af626;
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import * as React from 'react';
|
||||
import Card from '@mui/material/Card';
|
||||
import CardActions from '@mui/material/CardActions';
|
||||
import CardContent from '@mui/material/CardContent';
|
||||
@@ -6,7 +5,7 @@ import Typography from '@mui/material/Typography';
|
||||
import InitModal from './InitModal.js';
|
||||
import PluginsModal from './PluginsModal.js';
|
||||
|
||||
function cardChooser(command) {
|
||||
function cardChooser(command: string) {
|
||||
switch (command) {
|
||||
case 'init':
|
||||
return <InitModal />
|
||||
@@ -17,7 +16,8 @@ function cardChooser(command) {
|
||||
}
|
||||
}
|
||||
|
||||
export default function FunctionalityCard({ command, description }) {
|
||||
export default function FunctionalityCard(props: Props) {
|
||||
const { command, description } = props
|
||||
return (
|
||||
<Card sx={{ width: window.innerWidth / 2 }} variant='outlined'>
|
||||
<CardContent>
|
||||
@@ -34,4 +34,9 @@ export default function FunctionalityCard({ command, description }) {
|
||||
</CardActions>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
interface Props {
|
||||
command: string
|
||||
description: string
|
||||
}
|
||||
@@ -6,16 +6,16 @@ import Modal from '@mui/material/Modal';
|
||||
import InputLabel from '@mui/material/InputLabel';
|
||||
import MenuItem from '@mui/material/MenuItem';
|
||||
import FormControl from '@mui/material/FormControl';
|
||||
import Select from '@mui/material/Select';
|
||||
import Select, { SelectChangeEvent } from '@mui/material/Select';
|
||||
import TextField from '@mui/material/TextField';
|
||||
import Checkbox from '@mui/material/Checkbox';
|
||||
import FormGroup from '@mui/material/FormGroup';
|
||||
import FormControlLabel from '@mui/material/FormControlLabel';
|
||||
import type { IpcRendererEvent } from 'electron'
|
||||
import './InitModal.css';
|
||||
const { ipcRenderer } = window.require('electron');
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const style = {
|
||||
/* const style = {
|
||||
position: 'absolute',
|
||||
top: '50%',
|
||||
left: '50%',
|
||||
@@ -26,7 +26,7 @@ const style = {
|
||||
boxShadow: 24,
|
||||
padding: '20px',
|
||||
color: 'white',
|
||||
};
|
||||
}; */
|
||||
|
||||
export default function InitModal() {
|
||||
const [open, setOpen] = React.useState(false);
|
||||
@@ -34,21 +34,21 @@ export default function InitModal() {
|
||||
const handleClose = () => setOpen(false);
|
||||
|
||||
const [chosenTemplate, setChosenTemplate] = React.useState('');
|
||||
const handleTemplateChange = (event) => {
|
||||
const handleTemplateChange = (event: SelectChangeEvent) => {
|
||||
setChosenTemplate(event.target.value);
|
||||
};
|
||||
|
||||
const [installPackages, setInstallPackages] = React.useState(true);
|
||||
const handlePackagesChange = (event) => {
|
||||
const handlePackagesChange = (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
setInstallPackages(event.target.checked);
|
||||
};
|
||||
|
||||
const [chosenPackageManager, setChosenPackageManager] = React.useState('');
|
||||
const handlePackageManagerChange = (event) => {
|
||||
const handlePackageManagerChange = (event: SelectChangeEvent<string>) => {
|
||||
setChosenPackageManager(event.target.value);
|
||||
};
|
||||
|
||||
const [templates, setTemplates] = React.useState([]);
|
||||
const [templates, setTemplates] = React.useState<Array<TemplateList>>([]);
|
||||
React.useEffect(() => {
|
||||
fetch('https://raw.githubusercontent.com/sern-handler/create-bot/main/metadata/templateChoices.json')
|
||||
.then((res) => res.json())
|
||||
@@ -71,7 +71,7 @@ export default function InitModal() {
|
||||
};
|
||||
|
||||
const [projectName, setProjectName] = React.useState('');
|
||||
const handleProjectNameChange = (event) => {
|
||||
const handleProjectNameChange = (event: any) => {
|
||||
setProjectName(event.target.value);
|
||||
};
|
||||
|
||||
@@ -83,7 +83,7 @@ export default function InitModal() {
|
||||
};
|
||||
}, []);
|
||||
|
||||
const handleFolderData = (event, paths) => {
|
||||
const handleFolderData = (_event: IpcRendererEvent, paths: string[]) => {
|
||||
const selectedPath = paths && paths.length > 0 ? paths[0] : '';
|
||||
setSelectedPath(selectedPath);
|
||||
};
|
||||
@@ -169,7 +169,6 @@ export default function InitModal() {
|
||||
onChange={handlePackagesChange}
|
||||
/>
|
||||
}
|
||||
fullWidth
|
||||
label="Install packages while you're at it"
|
||||
/>
|
||||
</FormGroup>
|
||||
@@ -240,3 +239,8 @@ export default function InitModal() {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
interface TemplateList {
|
||||
title: string
|
||||
value: string
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
import React from 'react';
|
||||
import ReactDOM from 'react-dom/client';
|
||||
import './index.css';
|
||||
import './main.css';
|
||||
import App from './App';
|
||||
|
||||
const root = ReactDOM.createRoot(document.getElementById('root'));
|
||||
const root = ReactDOM.createRoot(document.getElementById('root')!);
|
||||
root.render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
@@ -1,13 +0,0 @@
|
||||
const reportWebVitals = onPerfEntry => {
|
||||
if (onPerfEntry && onPerfEntry instanceof Function) {
|
||||
import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
|
||||
getCLS(onPerfEntry);
|
||||
getFID(onPerfEntry);
|
||||
getFCP(onPerfEntry);
|
||||
getLCP(onPerfEntry);
|
||||
getTTFB(onPerfEntry);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default reportWebVitals;
|
||||
1
src/vite-env.d.ts
vendored
Normal file
1
src/vite-env.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
||||
26
tsconfig.electron.json
Normal file
26
tsconfig.electron.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./dist",
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "node",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["electron"]
|
||||
}
|
||||
|
||||
26
tsconfig.json
Normal file
26
tsconfig.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
||||
"module": "ESNext",
|
||||
"skipLibCheck": true,
|
||||
"outDir": "./dist",
|
||||
|
||||
/* Bundler mode */
|
||||
"moduleResolution": "bundler",
|
||||
"allowImportingTsExtensions": true,
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"noEmit": true,
|
||||
"jsx": "react-jsx",
|
||||
|
||||
/* Linting */
|
||||
"strict": true,
|
||||
"noUnusedLocals": true,
|
||||
"noUnusedParameters": true,
|
||||
"noFallthroughCasesInSwitch": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"references": [{ "path": "./tsconfig.node.json" }]
|
||||
}
|
||||
10
tsconfig.node.json
Normal file
10
tsconfig.node.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"composite": true,
|
||||
"skipLibCheck": true,
|
||||
"module": "ESNext",
|
||||
"moduleResolution": "bundler",
|
||||
"allowSyntheticDefaultImports": true
|
||||
},
|
||||
"include": ["vite.config.ts"]
|
||||
}
|
||||
7
vite.config.ts
Normal file
7
vite.config.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
import { defineConfig } from 'vite'
|
||||
import react from '@vitejs/plugin-react-swc'
|
||||
|
||||
// https://vitejs.dev/config/
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
})
|
||||
Reference in New Issue
Block a user