Use XO ESLint config

master
Michał Górny 2024-01-10 22:58:43 +01:00
rodzic 20b64d8cd9
commit 3d2f7d6744
13 zmienionych plików z 105 dodań i 165 usunięć

Wyświetl plik

@ -1,49 +1,36 @@
{
"env": {
"browser": true,
"node": true,
"es6": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".ts"]
}
}
},
"parserOptions": {"project": ["./tsconfig.json"]},
"plugins": ["@typescript-eslint"],
"extends": "airbnb-base",
"extends": [
"xo/browser",
"xo-typescript"
],
"rules": {
"indent": ["error", "tab"],
"no-tabs": "off",
"object-curly-spacing": ["error", "never"],
"no-param-reassign": ["error", {"props": false}],
"import/extensions": ["error", "ignorePackages", {
"js": "never",
"ts": "never"
}]
},
"overrides": [
{
"files": ["*.ts"],
"parser": "@typescript-eslint/parser",
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended"
],
"rules": {
"indent": "off",
"max-len": [2, 120],
"import/prefer-default-export": "off",
"@typescript-eslint/indent": ["error", "tab"],
"@typescript-eslint/explicit-function-return-type": "off",
"@typescript-eslint/no-non-null-assertion": "off"
"arrow-parens": ["error", "always"],
"curly": ["error", "multi-line"],
"padding-line-between-statements": "off",
"object-shorthand": ["error", "properties"],
"@typescript-eslint/ban-types": ["error", {"extendDefaults": true}],
"@typescript-eslint/member-delimiter-style": ["error", {
"multiline": {
"delimiter": "comma",
"requireLast": true
},
"singleline": {
"delimiter": "comma",
"requireLast": false
}
}],
"@typescript-eslint/padding-line-between-statements": "off"
},
"overrides": [{
"files": ["test/*.ts"],
"rules": {
"@typescript-eslint/no-confusing-void-expression": "off"
}
]
}]
}

1
.gitignore vendored
Wyświetl plik

@ -1,2 +1,3 @@
dist
node_modules
.eslintcache

Wyświetl plik

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/naming-convention */
const reporters = ['default'];
module.exports = {

122
package-lock.json wygenerowano
Wyświetl plik

@ -16,7 +16,7 @@
"@babel/preset-env": "^7.22.10",
"@babel/preset-typescript": "^7.22.5",
"@testing-library/dom": "^9.3.1",
"@testing-library/jest-dom": "^6.0.1",
"@testing-library/jest-dom": "^6.1.6",
"@types/html-webpack-plugin": "^3.2.6",
"@types/jest": "^29.5.3",
"@types/pug": "^2.0.6",
@ -28,9 +28,9 @@
"css-loader": "^6.8.1",
"cssnano": "^6.0.1",
"eslint": "^8.47.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-xo": "^0.43.1",
"eslint-config-xo-typescript": "^1.0.1",
"eslint-plugin-import": "^2.28.1",
"eslint-webpack-plugin": "^4.0.1",
"gh-pages": "^6.0.0",
"html-webpack-plugin": "^5.5.3",
"jest": "^29.6.2",
@ -45,7 +45,6 @@
"pug": "^3.0.2",
"stylelint": "^14.16.1",
"stylelint-config-standard": "^29.0.0",
"stylelint-webpack-plugin": "^4.1.1",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.1.6",
@ -64,9 +63,9 @@
}
},
"node_modules/@adobe/css-tools": {
"version": "4.3.1",
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.1.tgz",
"integrity": "sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg==",
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz",
"integrity": "sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==",
"dev": true
},
"node_modules/@ampproject/remapping": {
@ -3786,12 +3785,12 @@
}
},
"node_modules/@testing-library/jest-dom": {
"version": "6.1.4",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.4.tgz",
"integrity": "sha512-wpoYrCYwSZ5/AxcrjLxJmCU6I5QAJXslEeSiMQqaWmP2Kzpd1LvF/qxmAIW2qposULGWq2gw30GgVNFLSc2Jnw==",
"version": "6.1.6",
"resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-6.1.6.tgz",
"integrity": "sha512-YwuiOdYEcxhfC2u5iNKlvg2Q5MgbutovP6drq7J1HrCbvR+G58BbtoCoq+L/kNlrNFsu2Kt3jaFAviLVxYHJZg==",
"dev": true,
"dependencies": {
"@adobe/css-tools": "^4.3.1",
"@adobe/css-tools": "^4.3.2",
"@babel/runtime": "^7.9.2",
"aria-query": "^5.0.0",
"chalk": "^3.0.0",
@ -7507,23 +7506,40 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-config-airbnb-base": {
"version": "15.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
"integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
"node_modules/eslint-config-xo": {
"version": "0.43.1",
"resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.43.1.tgz",
"integrity": "sha512-azv1L2PysRA0NkZOgbndUpN+581L7wPqkgJOgxxw3hxwXAbJgD6Hqb/SjHRiACifXt/AvxCzE/jIKFAlI7XjvQ==",
"dev": true,
"dependencies": {
"confusing-browser-globals": "^1.0.10",
"object.assign": "^4.1.2",
"object.entries": "^1.1.5",
"semver": "^6.3.0"
"confusing-browser-globals": "1.0.11"
},
"engines": {
"node": "^10.12.0 || >=12.0.0"
"node": ">=12"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
},
"peerDependencies": {
"eslint": "^7.32.0 || ^8.2.0",
"eslint-plugin-import": "^2.25.2"
"eslint": ">=8.27.0"
}
},
"node_modules/eslint-config-xo-typescript": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/eslint-config-xo-typescript/-/eslint-config-xo-typescript-1.0.1.tgz",
"integrity": "sha512-vPQssnRSUgBFOEfB/KY12CXwltwFSn4RSCfa+w7gjBC2PFQ7Yfgmyei+1XUZ3K+8LRGef2NMJUcxts7PldhDjg==",
"dev": true,
"engines": {
"node": ">=16"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
},
"peerDependencies": {
"@typescript-eslint/eslint-plugin": ">=6.0.0",
"@typescript-eslint/parser": ">=6.0.0",
"eslint": ">=8.0.0",
"typescript": ">=4.7"
}
},
"node_modules/eslint-import-resolver-node": {
@ -7652,30 +7668,6 @@
"url": "https://opencollective.com/eslint"
}
},
"node_modules/eslint-webpack-plugin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/eslint-webpack-plugin/-/eslint-webpack-plugin-4.0.1.tgz",
"integrity": "sha512-fUFcXpui/FftGx3NzvWgLZXlLbu+m74sUxGEgxgoxYcUtkIQbS6SdNNZkS99m5ycb23TfoNYrDpp1k/CK5j6Hw==",
"dev": true,
"dependencies": {
"@types/eslint": "^8.37.0",
"jest-worker": "^29.5.0",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"schema-utils": "^4.0.0"
},
"engines": {
"node": ">= 14.15.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"eslint": "^8.0.0",
"webpack": "^5.0.0"
}
},
"node_modules/eslint/node_modules/ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
@ -12701,20 +12693,6 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/object.entries": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.7.tgz",
"integrity": "sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
"define-properties": "^1.2.0",
"es-abstract": "^1.22.1"
},
"engines": {
"node": ">= 0.4"
}
},
"node_modules/object.fromentries": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz",
@ -16047,30 +16025,6 @@
"stylelint": "^14.14.0"
}
},
"node_modules/stylelint-webpack-plugin": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/stylelint-webpack-plugin/-/stylelint-webpack-plugin-4.1.1.tgz",
"integrity": "sha512-yOyd2AfrxfawxKDememazGVJX2vMq9o11E6HvBu4+SKvgK3ZulkjpYdI1muBTxItwoxH2UmfIZzQM+/M5V3kTQ==",
"dev": true,
"dependencies": {
"globby": "^11.1.0",
"jest-worker": "^29.5.0",
"micromatch": "^4.0.5",
"normalize-path": "^3.0.0",
"schema-utils": "^4.0.0"
},
"engines": {
"node": ">= 14.15.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/webpack"
},
"peerDependencies": {
"stylelint": "^13.0.0 || ^14.0.0 || ^15.0.0",
"webpack": "^5.0.0"
}
},
"node_modules/stylelint/node_modules/@csstools/selector-specificity": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.2.0.tgz",

Wyświetl plik

@ -9,6 +9,10 @@
"scripts": {
"start": "webpack-dev-server --mode=development",
"test": "jest",
"typecheck": "npx tsc",
"lint:js": "npx eslint . --ext .ts --cache",
"lint:css": "npx stylelint \"src/**/*.css\"",
"lint": "npm run lint:js; npm run lint:css",
"build": "webpack --mode=production",
"deploy": "gh-pages -d dist"
},
@ -26,7 +30,7 @@
"@babel/preset-env": "^7.22.10",
"@babel/preset-typescript": "^7.22.5",
"@testing-library/dom": "^9.3.1",
"@testing-library/jest-dom": "^6.0.1",
"@testing-library/jest-dom": "^6.1.6",
"@types/html-webpack-plugin": "^3.2.6",
"@types/jest": "^29.5.3",
"@types/pug": "^2.0.6",
@ -38,9 +42,9 @@
"css-loader": "^6.8.1",
"cssnano": "^6.0.1",
"eslint": "^8.47.0",
"eslint-config-airbnb-base": "^15.0.0",
"eslint-config-xo": "^0.43.1",
"eslint-config-xo-typescript": "^1.0.1",
"eslint-plugin-import": "^2.28.1",
"eslint-webpack-plugin": "^4.0.1",
"gh-pages": "^6.0.0",
"html-webpack-plugin": "^5.5.3",
"jest": "^29.6.2",
@ -55,7 +59,6 @@
"pug": "^3.0.2",
"stylelint": "^14.16.1",
"stylelint-config-standard": "^29.0.0",
"stylelint-webpack-plugin": "^4.1.1",
"ts-jest": "^29.1.1",
"ts-node": "^10.9.1",
"typescript": "^5.1.6",

Wyświetl plik

@ -1,4 +1,4 @@
import {
import type {
PastSupport,
Committee,
Constituency,

Wyświetl plik

@ -61,7 +61,7 @@ const displayUrl = (support: number[]) => {
if (s > 0) searchParams.append(committees[i].id, s.toString());
});
const urlWithoutSearchString = location.href.split('?')[0];
const url = `${urlWithoutSearchString}?${searchParams}`;
const url = `${urlWithoutSearchString}?${searchParams.toString()}`;
document.getElementById('url')!.innerHTML = `Link do wyników: ${url.link(url)}`;
}
};
@ -147,7 +147,7 @@ const displayConstituencyResults = () => {
const data = (constituency.mandates && constituency.support)
? constituency.mandates.map((mandates, committeeIndex) => ({
committee: committees[committeeIndex],
support: (constituency.support as number[])[committeeIndex],
support: (constituency.support!)[committeeIndex],
mandates,
}))
: [];
@ -164,7 +164,7 @@ const displayConstituencyResults = () => {
const pathElement = event.target as SVGPathElement;
pathElement.style.stroke = '#444';
constituencyNumber.innerHTML = `Okręg nr ${pathElement.dataset.cid}`;
constituencyName.innerHTML = pathElement.dataset.cname as string;
constituencyName.innerHTML = pathElement.dataset.cname!;
});
path.addEventListener('mouseout', (event) => {
const pathElement = event.target as SVGPathElement;
@ -187,7 +187,9 @@ const displayConstituencyResults = () => {
};
const validate = (form: HTMLFormElement, inputs: NodeListOf<HTMLInputElement>, support: number[]) => {
inputs.forEach((input) => input.setCustomValidity(''));
inputs.forEach((input) => {
input.setCustomValidity('');
});
support.some((inputValue, index) => {
if (inputValue < 0) {
@ -225,9 +227,11 @@ export const calculate = (): void => {
pieChart = displayPieChart(mandates);
displayConstituencyResults();
inputs.forEach((input) => input.addEventListener('input', () => {
clearResults();
}));
inputs.forEach((input) => {
input.addEventListener('input', () => {
clearResults();
});
});
};
export const generateTable = (): void => {

Wyświetl plik

@ -1,5 +1,5 @@
import {committees, constituencies, pastSupport} from './data';
import {Constituency} from './types';
import type {Constituency} from './types';
const calculateLocalSupport = (
support: number[],
@ -31,7 +31,7 @@ export default (support: number[]): number[] => {
.map((pastCommittee) => pastSupport[pastCommittee[0]] * pastCommittee[1])
.reduce((a, b) => a + b, 0)
));
const mandates: number[] = new Array(support.length + 1).fill(0);
const mandates = new Array(support.length + 1).fill(0) as number[];
constituencies.forEach((constituency) => {
const localSupport = calculateLocalSupport(support, pastSupportProjection, constituency);
constituency.support = localSupport;
@ -40,7 +40,7 @@ export default (support: number[]): number[] => {
if (support[index] < committees[index].threshold) return 0;
return localCommitteeSupport;
});
const quotients: {quotient: number; committeeIndex: number}[] = [];
const quotients: Array<{quotient: number, committeeIndex: number}> = [];
for (let divisor = 1; divisor <= constituency.size; divisor += 1) {
for (let committeeIndex = 0; committeeIndex < localSupport.length; committeeIndex += 1) {
quotients.push({

Wyświetl plik

@ -1,5 +1,5 @@
declare module '*.pug' {
import pug = require('pug');
import type pug from 'pug';
const content: pug.compileTemplate;
export = content;

Wyświetl plik

@ -1,21 +1,21 @@
type PastCommiteeId = 'pis' | 'ko' | 'td' | 'lewica' | 'konfederacja'
type PastCommiteeId = 'pis' | 'ko' | 'td' | 'lewica' | 'konfederacja';
export type PastSupport = {
[pastCommitteeId in PastCommiteeId]: number;
}
};
export type Committee = {
id: string;
name: string;
shortName: string;
threshold: number;
pastSupportEquivalence: [PastCommiteeId, number][];
}
id: string,
name: string,
shortName: string,
threshold: number,
pastSupportEquivalence: Array<[PastCommiteeId, number]>,
};
export type Constituency = {
name: string;
size: number;
pastSupport: PastSupport;
support?: number[];
mandates?: number[];
}
name: string,
size: number,
pastSupport: PastSupport,
support?: number[],
mandates?: number[],
};

Wyświetl plik

@ -1,4 +1,4 @@
window.matchMedia = jest.fn().mockImplementation((query) => ({
window.matchMedia = jest.fn().mockImplementation((query: string) => ({
matches: false,
media: query,
onchange: null,

Wyświetl plik

@ -5,6 +5,7 @@
"moduleResolution": "node",
"outDir": "./dist/",
"removeComments": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"target": "ES5"

Wyświetl plik

@ -1,9 +1,6 @@
/* eslint-disable import/no-extraneous-dependencies */
import path from 'path';
import ESLintPlugin from 'eslint-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import MiniCssExtractPlugin from 'mini-css-extract-plugin';
import StyleLintPlugin from 'stylelint-webpack-plugin';
export default {
target: 'web',
@ -63,14 +60,6 @@ export default {
filename: '[name].css',
chunkFilename: '[id].css',
}),
new ESLintPlugin({
files: ['./*.[jt]s', './src/**/*.[jt]s'],
}),
new StyleLintPlugin({
configFile: path.resolve(__dirname, '.stylelintrc.json'),
context: path.resolve(__dirname, './src'),
files: '**/*.css',
}),
],
devServer: {
watchFiles: ['src/**/*'],