Upgrade wms-core and add eslint

This commit is contained in:
Alice Gaudon 2020-10-05 13:38:03 +02:00
parent d91110fb67
commit a8bad1c8c1
11 changed files with 181 additions and 40 deletions

114
.eslintrc.json Normal file
View File

@ -0,0 +1,114 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"parserOptions": {
"project": [
"./tsconfig.json",
"./tsconfig.test.json",
"./tsconfig.frontend.json"
]
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"indent": [
"error",
4,
{
"SwitchCase": 1
}
],
"no-trailing-spaces": "error",
"max-len": [
"error",
{
"code": 120,
"ignoreStrings": true,
"ignoreTemplateLiterals": true,
"ignoreRegExpLiterals": true
}
],
"semi": "off",
"@typescript-eslint/semi": [
"error"
],
"no-extra-semi": "error",
"eol-last": "error",
"comma-dangle": "off",
"@typescript-eslint/comma-dangle": [
"error",
{
"arrays": "always-multiline",
"objects": "always-multiline",
"imports": "always-multiline",
"exports": "always-multiline",
"functions": "always-multiline",
"enums": "always-multiline",
"generics": "always-multiline",
"tuples": "always-multiline"
}
],
"no-extra-parens": "off",
"@typescript-eslint/no-extra-parens": [
"error"
],
"no-nested-ternary": "error",
"@typescript-eslint/no-inferrable-types": "off",
"@typescript-eslint/explicit-module-boundary-types": "error",
"@typescript-eslint/no-unnecessary-condition": "error",
"@typescript-eslint/no-unused-vars": [
"error",
{
"argsIgnorePattern": "^_"
}
],
"@typescript-eslint/no-non-null-assertion": "error",
"no-useless-return": "error",
"no-useless-constructor": "off",
"@typescript-eslint/no-useless-constructor": [
"error"
],
"no-return-await": "off",
"@typescript-eslint/return-await": [
"error",
"always"
],
"@typescript-eslint/explicit-member-accessibility": [
"error",
{
"accessibility": "explicit"
}
],
"@typescript-eslint/no-floating-promises": "error"
},
"ignorePatterns": [
"jest.config.js",
"webpack.config.js",
"dist/**/*",
"public/**/*",
"config/**/*"
],
"overrides": [
{
"files": [
"test/**/*"
],
"rules": {
"max-len": [
"error",
{
"code": 120,
"ignoreTemplateLiterals": true,
"ignoreRegExpLiterals": true,
"ignoreStrings": true
}
]
}
}
]
}

View File

@ -8,13 +8,13 @@ export default class PersistentWebsocket {
) {
}
public run() {
this.webSocket = new WebSocket(this.url);
this.webSocket.addEventListener('open', (e) => {
public run(): void {
const _webSocket = this.webSocket = new WebSocket(this.url);
this.webSocket.addEventListener('open', () => {
console.debug('Websocket connected');
});
this.webSocket.addEventListener('message', (e) => {
this.handler(this.webSocket!, e);
this.handler(_webSocket, e);
});
this.webSocket.addEventListener('error', (e) => {
console.error('Websocket error', e);
@ -29,7 +29,7 @@ export default class PersistentWebsocket {
});
}
public send(data: string) {
public send(data: string): void {
if (!this.webSocket) throw new Error('WebSocket not connected');
this.webSocket.send(data);

View File

@ -1,7 +1,9 @@
/*
* For labels to update their state (css selectors based on the value attribute)
*/
export function updateInputs() {
import {ValidationError} from "wms-core/db/Validator";
export function updateInputs(): void {
document.querySelectorAll<HTMLInputElement | HTMLTextAreaElement>('input, textarea').forEach(el => {
if (!el.dataset.inputSetup) {
el.dataset.inputSetup = 'true';
@ -19,7 +21,10 @@ document.addEventListener('DOMContentLoaded', () => {
updateInputs();
});
export function applyFormMessages(formElement: HTMLFormElement, messages: { [p: string]: any }) {
export function applyFormMessages(
formElement: HTMLFormElement,
messages: { [p: string]: ValidationError<unknown> },
): void {
for (const fieldName of Object.keys(messages)) {
const field = formElement.querySelector('#field-' + fieldName);
if (!field) continue;
@ -27,14 +32,12 @@ export function applyFormMessages(formElement: HTMLFormElement, messages: { [p:
let parent = field.parentElement;
while (parent && !parent.classList.contains('form-field')) parent = parent.parentElement;
if (field) {
let err = field.querySelector('.error');
if (!err) {
err = document.createElement('div');
err.classList.add('error');
parent?.insertBefore(err, parent.querySelector('.hint') || parent);
}
err.innerHTML = `<i data-feather="x-circle"></i> ${messages[fieldName].message}`;
let err = field.querySelector('.error');
if (!err) {
err = document.createElement('div');
err.classList.add('error');
parent?.insertBefore(err, parent.querySelector('.hint') || parent);
}
err.innerHTML = `<i data-feather="x-circle"></i> ${messages[fieldName].message}`;
}
}

View File

@ -1,4 +1,4 @@
export function updateTooltips() {
export function updateTooltips(): void {
console.debug('Updating tooltips');
const elements = document.querySelectorAll<HTMLElement>('.tip, .dropdown');

View File

@ -9,9 +9,12 @@
"scripts": {
"test": "jest --verbose --runInBand",
"dist-webpack": "webpack --mode production",
"dist": "(test ! -d dist || rm -r dist) && tsc && npm run dist-webpack",
"dist": "yarn compile && yarn dist-webpack",
"clean": "(test ! -d dist || rm -r dist)",
"compile": "yarn clean && tsc && mv dist/src/* dist/",
"dev": "concurrently -k -n \"Typescript,Node,Webpack,Maildev\" -p \"[{name}]\" -c \"blue,green,red,yellow\" \"tsc --watch\" \"nodemon\" \"webpack --watch --mode development\" \"maildev\"",
"start": "yarn dist && node dist/main.js"
"start": "yarn dist && node dist/main.js",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx"
},
"devDependencies": {
"@babel/core": "^7.9.0",
@ -28,9 +31,12 @@
"@types/nodemailer": "^6.4.0",
"@types/nunjucks": "^3.1.3",
"@types/ws": "^7.2.6",
"@typescript-eslint/eslint-plugin": "^4.3.0",
"@typescript-eslint/parser": "^4.3.0",
"babel-loader": "^8.1.0",
"concurrently": "^5.1.0",
"css-loader": "^4.2.2",
"eslint": "^7.10.0",
"feather-icons": "^4.28.0",
"file-loader": "^6.0.0",
"imagemin": "^7.0.1",
@ -55,6 +61,6 @@
"dependencies": {
"config": "^3.3.1",
"express": "^4.17.1",
"wms-core": "^0.21.7"
"wms-core": "^0.22.0-rc.24"
}
}

View File

@ -1,6 +1,5 @@
import Application from "wms-core/Application";
import {Type} from "wms-core/Utils";
import Migration from "wms-core/db/Migration";
import Migration, {MigrationType} from "wms-core/db/Migration";
import CreateMigrationsTable from "wms-core/migrations/CreateMigrationsTable";
import CreateLogsTable from "wms-core/migrations/CreateLogsTable";
import ExpressAppComponent from "wms-core/components/ExpressAppComponent";
@ -18,16 +17,17 @@ import CsrfProtectionComponent from "wms-core/components/CsrfProtectionComponent
import WebSocketServerComponent from "wms-core/components/WebSocketServerComponent";
import HomeController from "./controllers/HomeController";
import AutoUpdateComponent from "wms-core/components/AutoUpdateComponent";
import packageJson = require('../package.json');
export default class App extends Application {
private readonly port: number;
constructor(port: number) {
super(require('../package.json').version);
this.port = port;
public constructor(
private readonly addr: string,
private readonly port: number,
) {
super(packageJson.version);
}
protected getMigrations(): Type<Migration>[] {
protected getMigrations(): MigrationType<Migration>[] {
return [
CreateMigrationsTable,
CreateLogsTable,
@ -44,7 +44,7 @@ export default class App extends Application {
const redisComponent = new RedisComponent();
const mysqlComponent = new MysqlComponent();
const expressAppComponent = new ExpressAppComponent(this.port);
const expressAppComponent = new ExpressAppComponent(this.addr, this.port);
this.use(expressAppComponent);
this.use(new NunjucksComponent());
this.use(new LogRequestsComponent());
@ -79,9 +79,10 @@ export default class App extends Application {
}
private registerWebSocketListeners() {
// WebSocket listeners
}
private registerControllers() {
this.use(new HomeController());
}
}
}

View File

@ -2,24 +2,24 @@ import Controller from "wms-core/Controller";
import {Request, Response} from "express";
export default class HomeController extends Controller {
routes(): void {
public routes(): void {
this.get('/', this.getHome, 'home');
this.get('/about', this.getAbout, 'about');
this.get('/back', this.goBack, 'about');
}
private async getHome(req: Request, res: Response) {
protected async getHome(req: Request, res: Response): Promise<void> {
res.render('home');
}
private async getAbout(req: Request, res: Response) {
protected async getAbout(req: Request, res: Response): Promise<void> {
res.render('about');
}
/**
* This is to test and assert that wms-core extended types are available
*/
private async goBack(req: Request, res: Response) {
protected async goBack(req: Request, res: Response): Promise<void> {
res.redirectBack();
}
}
}

View File

@ -1,7 +1,9 @@
import {delimiter} from "path";
// Load config from specified path or default + wms-core/config (default defaults)
process.env['NODE_CONFIG_DIR'] =
__dirname + '/../node_modules/wms-core/config/'
+ require('path').delimiter
+ delimiter
+ (process.env['NODE_CONFIG_DIR'] || __dirname + '/../config/');
import Logger from "wms-core/Logger";
@ -11,8 +13,8 @@ import config from "config";
(async () => {
Logger.debug('Config path:', process.env['NODE_CONFIG_DIR']);
const app = new App(config.get<number>('port'));
const app = new App(config.get<string>('listen_addr'), config.get<number>('port'));
await app.start();
})().catch(err => {
Logger.error(err);
});
});

View File

@ -2,4 +2,4 @@ describe('Write your tests', () => {
test('Remove this when you have some tests', () => {
expect(false).toBe(true);
});
});
});

View File

@ -11,10 +11,11 @@
],
"typeRoots": [
"./node_modules/@types"
]
],
"resolveJsonModule": true
},
"include": [
"src/**/*",
"node_modules/wms-core/types"
]
}
}

14
tsconfig.test.json Normal file
View File

@ -0,0 +1,14 @@
{
"extends": "./tsconfig.json",
"compilerOptions": {
"typeRoots": [
"node_modules/@types",
"src/types",
"test/types"
]
},
"include": [
"src/types/**/*",
"test/**/*"
]
}