Linter fixes (partial)

This commit is contained in:
Kuba Orlik 2024-03-30 17:01:53 +01:00
parent 148c533b5b
commit 7da39a140c
12 changed files with 467 additions and 659 deletions

View File

@ -1,7 +1,7 @@
module.exports = { module.exports = {
env: { node: true }, env: { node: true },
parser: "@typescript-eslint/parser", parser: "@typescript-eslint/parser",
plugins: ["@typescript-eslint", "prettier", "with-tsc-error"], plugins: ["@typescript-eslint", "prettier"],
extends: [ extends: [
"eslint:recommended", "eslint:recommended",
"plugin:@typescript-eslint/recommended", "plugin:@typescript-eslint/recommended",
@ -13,20 +13,17 @@ module.exports = {
ecmaFeatures: { ecmaFeatures: {
modules: true, modules: true,
}, },
project: [ project: ["./tsconfig.json", "./tsconfig-back.json"],
"./src/back/tsconfig.json",
"./src/front/tsconfig.json",
],
}, },
rules: { rules: {
"@typescript-eslint/no-unused-vars": [2, { "varsIgnorePattern": "TempstreamJSX" }], "@typescript-eslint/no-unused-vars": [2, { varsIgnorePattern: "TempstreamJSX" }],
"@typescript-eslint/require-await": 0, "@typescript-eslint/require-await": 0,
/* "jsdoc/require-description": 2, */ /* "jsdoc/require-description": 2, */
"no-await-in-loop": 2, "no-await-in-loop": 2,
"@typescript-eslint/consistent-type-assertions": [1, { assertionStyle: "never" }], "@typescript-eslint/consistent-type-assertions": [1, { assertionStyle: "never" }],
"no-console": [1, { "allow": ["error"] }] "no-console": [1, { allow: ["error"] }],
}, },
"ignorePatterns": ["dist/*", "public/dist/*", "coverage/*", "webhint/*"], ignorePatterns: ["dist/*", "public/dist/*", "coverage/*", "webhint/*"],
settings: { jsdoc: { mode: "typescript" } }, settings: { jsdoc: { mode: "typescript" } },
overrides: [ overrides: [
{ {

975
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -61,16 +61,15 @@
"@types/object-path": "^0.11.4", "@types/object-path": "^0.11.4",
"@types/tedious": "^4.0.7", "@types/tedious": "^4.0.7",
"@types/uuid": "^9.0.8", "@types/uuid": "^9.0.8",
"@typescript-eslint/eslint-plugin": "^5.10.0", "@typescript-eslint/eslint-plugin": "7.4",
"@typescript-eslint/parser": "^5.10.2", "@typescript-eslint/parser": "7.4",
"@vitest/coverage-istanbul": "^1.1.0", "@vitest/coverage-istanbul": "^1.1.0",
"@vitest/coverage-v8": "^1.1.0", "@vitest/coverage-v8": "^1.1.0",
"@vitest/ui": "^1.1.0", "@vitest/ui": "^1.1.0",
"axios": "^1.6.2", "axios": "^1.6.2",
"eslint": "^7.19.0", "eslint": "8.57",
"eslint-config-prettier": "^7.2.0", "eslint-config-prettier": "^7.2.0",
"eslint-plugin-prettier": "^3.3.1", "eslint-plugin-prettier": "^3.3.1",
"eslint-plugin-with-tsc-error": "^0.0.7",
"kill-port": "^1.6.1", "kill-port": "^1.6.1",
"mri": "^1.1.6", "mri": "^1.1.6",
"nyc": "^15.1.0", "nyc": "^15.1.0",

View File

@ -7,9 +7,10 @@ const sleep = (time: number) =>
setTimeout(resolve, time); setTimeout(resolve, time);
}); });
async function get_status() { async function get_status(): Promise<{ started_at: number; status: string }> {
const r = await fetch("/status.json"); const r = await fetch("/status.json");
return await r.json(); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return (await r.json()) as { started_at: number; status: string };
} }
async function wait_for_run_id_to_change() { async function wait_for_run_id_to_change() {
@ -26,25 +27,32 @@ async function wait_for_run_id_to_change() {
throw new Error(APP_DOWN_ERROR_MESSAGE); throw new Error(APP_DOWN_ERROR_MESSAGE);
} }
// eslint-disable-next-line no-constant-condition
while (true) { while (true) {
// eslint-disable-next-line no-await-in-loop
const { started_at } = await get_status().catch(() => ({ const { started_at } = await get_status().catch(() => ({
started_at: first_timestamp, started_at: first_timestamp,
})); }));
if (started_at !== first_timestamp) { if (started_at !== first_timestamp) {
return; return;
} }
// eslint-disable-next-line no-await-in-loop
await sleep(100); await sleep(100);
} }
} }
async function wait_for_app_to_be_stable(n = 3) { async function wait_for_app_to_be_stable(n = 3) {
// eslint-disable-next-line no-console
console.log("Waiting for app to be stable...."); console.log("Waiting for app to be stable....");
let counter = 0; let counter = 0;
// eslint-disable-next-line no-constant-condition
while (true) { while (true) {
// eslint-disable-next-line no-await-in-loop
const { status } = await get_status().catch(() => ({ const { status } = await get_status().catch(() => ({
status: "down", status: "down",
})); }));
if (status == "running") { if (status == "running") {
// eslint-disable-next-line no-console
console.log(counter); console.log(counter);
counter++; counter++;
} else { } else {
@ -53,6 +61,7 @@ async function wait_for_app_to_be_stable(n = 3) {
if (counter == n) { if (counter == n) {
return; return;
} }
// eslint-disable-next-line no-await-in-loop
await sleep(100); await sleep(100);
} }
} }
@ -61,6 +70,7 @@ async function wait_for_app_restart() {
try { try {
await wait_for_run_id_to_change(); await wait_for_run_id_to_change();
} catch (e) { } catch (e) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
if (e.message !== APP_DOWN_ERROR_MESSAGE) { if (e.message !== APP_DOWN_ERROR_MESSAGE) {
throw e; throw e;
} }
@ -72,8 +82,12 @@ export default class RefreshOnTSChanges extends Controller {
socket: WebSocket; socket: WebSocket;
async connect() { async connect() {
const { port, watch } = await fetch("/dist/notifier.json").then((r) => r.json()); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const { port, watch } = (await fetch("/dist/notifier.json").then((r) =>
r.json()
)) as { port: number; watch: boolean };
if (!watch) { if (!watch) {
// eslint-disable-next-line no-console
console.warn( console.warn(
"Not running auto refresh on watch because the build process is not running in watch mode" "Not running auto refresh on watch because the build process is not running in watch mode"
); );
@ -81,7 +95,9 @@ export default class RefreshOnTSChanges extends Controller {
} }
const socket = new WebSocket(`ws://localhost:${port}`); const socket = new WebSocket(`ws://localhost:${port}`);
socket.onmessage = async (message) => { socket.onmessage = async (message) => {
if (message.data.endsWith("-ts")) { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const data = message.data as unknown;
if (typeof data === "string" && data.endsWith("-ts")) {
document.documentElement.classList.add("restarting"); document.documentElement.classList.add("restarting");
await wait_for_app_restart(); await wait_for_app_restart();
document.documentElement.dispatchEvent(new Event("ts-rebuilt")); document.documentElement.dispatchEvent(new Event("ts-rebuilt"));

View File

@ -15,7 +15,6 @@ function getStyles() {
} }
function cleanup_css() { function cleanup_css() {
console.log("clearing styles");
getStyles() getStyles()
.slice(0, -1) .slice(0, -1)
.forEach((style) => { .forEach((style) => {
@ -27,8 +26,10 @@ export default class RefreshStyles extends Controller {
socket: WebSocket; socket: WebSocket;
async connect() { async connect() {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const { port } = await fetch("/dist/notifier.json").then((r) => r.json()); const { port } = await fetch("/dist/notifier.json").then((r) => r.json());
this.socket = new WebSocket(`ws://localhost:${port}`); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
this.socket = new WebSocket(`ws://localhost:${port as number}`);
this.socket.onmessage = async (message) => { this.socket.onmessage = async (message) => {
if (message.data === "css") { if (message.data === "css") {
const new_link = make_new_link(); const new_link = make_new_link();

View File

@ -1,9 +1,9 @@
import { FlatTemplatable, Templatable, tempstream } from "tempstream"; import { FlatTemplatable, Templatable, tempstream } from "tempstream";
import { Readable } from "stream"; import { Readable } from "stream";
import { BaseContext } from "koa"; import { BaseContext } from "koa";
import { default as default_navbar } from "./routes/common/navbar.js";
import { toKebabCase } from "js-convert-case"; import { toKebabCase } from "js-convert-case";
import { DEFAULT_HTML_LANG } from "./config.js"; import { DEFAULT_HTML_LANG } from "./config.js";
import { default_navbar } from "./routes/common/navbar.js";
export const defaultHead = ( export const defaultHead = (
ctx: BaseContext, ctx: BaseContext,
@ -60,7 +60,7 @@ export default function html(
${makeHead(ctx, title, htmlOptions)} ${makeHead(ctx, title, htmlOptions)}
</head> </head>
<body data-controller="${controllers.join(" ")}"> <body data-controller="${controllers.join(" ")}">
${(htmlOptions.navbar || default_navbar)(ctx)} ${body} ${(htmlOptions?.navbar || default_navbar)(ctx)} ${body}
${htmlOptions.disableCopyEvent ${htmlOptions.disableCopyEvent
? /* HTML */ "<script>document.addEventListener('copy', (e) => e.preventDefault());</script>" ? /* HTML */ "<script>document.addEventListener('copy', (e) => e.preventDefault());</script>"
: ""} : ""}

View File

@ -1,17 +1,35 @@
import { Controller } from "stimulus"; import { Controller } from "stimulus";
declare const L: any; // eslint-disable-next-line @typescript-eslint/no-explicit-any
declare global {
interface Window {
L: typeof import("leaflet");
}
}
type Pin = {
title: string;
address: string;
coordinates: string;
button: { link: string; text: string };
};
function parseCoords(s: string): [number, number] {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return s.split(", ").map((x) => parseFloat(x)) as [number, number];
}
export default class MapWithPins extends Controller { export default class MapWithPins extends Controller {
id: string; id: string;
map: any; map: L.Map;
initiated: boolean = false; initiated = false;
resizeObserver: ResizeObserver; resizeObserver: ResizeObserver;
static values = { static values = {
pins: String, pins: String,
}; };
connect() { async connect() {
if (this.initiated) { if (this.initiated) {
this.map.remove(); this.map.remove();
} }
@ -34,57 +52,59 @@ export default class MapWithPins extends Controller {
} }
initiateMap() { initiateMap() {
this.map = L.map(this.element); // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
this.map = window.L.map(this.element as HTMLElement);
this.resizeObserver = new ResizeObserver(() => { this.resizeObserver = new ResizeObserver(() => {
this.map.invalidateSize(); this.map.invalidateSize();
}); });
this.resizeObserver.observe(this.element); this.resizeObserver.observe(this.element);
L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", { // eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-member-access
window.L.tileLayer("https://tile.openstreetmap.org/{z}/{x}/{y}.png", {
maxZoom: 19, maxZoom: 19,
attribution: attribution:
'&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>', '&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>',
}).addTo(this.map); }).addTo(this.map);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const pins = JSON.parse( const pins = JSON.parse(
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
this.element.attributes["data-map-with-pins-pins-value"].value this.element.attributes["data-map-with-pins-pins-value"].value
); ) as Pin[];
pins.forEach((pin) => this.addPin(pin)); pins.forEach((pin) => this.addPin(pin));
this.initiated = true; this.initiated = true;
} }
pinsValueChanged() { async pinsValueChanged() {
if (this.initiated) { if (this.initiated) {
this.connect(); await this.connect();
} }
} }
addPin(pin) { addPin(pin: Pin) {
var pinIcon = L.icon({ const pinIcon = window.L.icon({
iconUrl: "/pin-icon.svg", iconUrl: "/pin-icon.svg",
iconSize: [29, 41], iconSize: [29, 41],
iconAnchor: [14, 40], iconAnchor: [14, 40],
popupAnchor: [-3, 14], popupAnchor: [-3, 14],
}); });
var marker = L.marker( // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
pin.coordinates.split(", ").map((x) => parseFloat(x)), window.L.marker(parseCoords(pin.coordinates), {
{ icon: pinIcon,
icon: pinIcon, }).addTo(this.map);
}
).addTo(this.map);
var popup = L.popup({ window.L.popup({
closeButton: false, closeButton: false,
autoClose: false, autoClose: false,
closeOnEscapeKey: false, closeOnEscapeKey: false,
closeOnClick: false, closeOnClick: false,
className: "popup", className: "popup",
offset: [0, -32], offset: [0, -32],
maxWidth: "auto",
}) })
.setLatLng(pin.coordinates.split(", ").map((x) => parseFloat(x))) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
.setLatLng(parseCoords(pin.coordinates))
.setContent( .setContent(
/* HTML */ `<div class="popup-content"> /* HTML */ `<div class="popup-content">
<p class="title">${pin.title}</p> <p class="title">${pin.title}</p>
@ -93,9 +113,6 @@ export default class MapWithPins extends Controller {
</div> ` </div> `
) )
.addTo(this.map); .addTo(this.map);
this.map.setView( this.map.setView(parseCoords(pin.coordinates), 13);
pin.coordinates.split(", ").map((x) => parseFloat(x)),
13
);
} }
} }

View File

@ -1,3 +1,3 @@
.nice-box { .nice-box {
background-color: white; background-color: white;
} }

View File

@ -1,7 +1,8 @@
import { BaseContext } from "koa"; import { BaseContext } from "koa";
import { FlatTemplatable } from "tempstream";
import { SignUpURL, SignInURL, TodoURL, LogoutURL } from "../urls.js"; import { SignUpURL, SignInURL, TodoURL, LogoutURL } from "../urls.js";
export default async function navbar(ctx: BaseContext) { export async function default_navbar(ctx: BaseContext): Promise<FlatTemplatable> {
const isLoggedIn = !!ctx.$context.session_id; const isLoggedIn = !!ctx.$context.session_id;
const linkData = isLoggedIn const linkData = isLoggedIn

View File

@ -3,7 +3,7 @@ import { Controller } from "stimulus";
export default class ComponentDebugger extends Controller { export default class ComponentDebugger extends Controller {
id: string; id: string;
main_form: HTMLFormElement; main_form: HTMLFormElement;
is_resizing: boolean = false; is_resizing = false;
origin_x: number; origin_x: number;
origin_width: number; origin_width: number;
@ -25,13 +25,15 @@ export default class ComponentDebugger extends Controller {
}); });
document.addEventListener("turbo:render", () => this.update_width_display()); document.addEventListener("turbo:render", () => this.update_width_display());
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const gutter = this.targets.find("gutter") as HTMLDivElement; const gutter = this.targets.find("gutter") as HTMLDivElement;
gutter.addEventListener("mousedown", (e) => { gutter.addEventListener("mousedown", (e) => {
this.is_resizing = true; this.is_resizing = true;
this.origin_x = e.clientX; this.origin_x = e.clientX;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const resizable = this.targets.find("preview") as HTMLSpanElement; const resizable = this.targets.find("preview") as HTMLSpanElement;
this.origin_width = resizable.getBoundingClientRect().width; this.origin_width = resizable.getBoundingClientRect().width;
const handler = this.resizeHandler.bind(this); const handler = (e: MouseEvent) => this.resizeHandler(e);
document.addEventListener("mousemove", handler); document.addEventListener("mousemove", handler);
document.addEventListener("mouseup", () => { document.addEventListener("mouseup", () => {
document.removeEventListener("mousemove", handler); document.removeEventListener("mousemove", handler);
@ -41,11 +43,15 @@ export default class ComponentDebugger extends Controller {
} }
update_width_display() { update_width_display() {
const component_width = (this.targets.find("preview") as HTMLSpanElement) // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
.offsetWidth; const preview = this.targets.find("preview") as HTMLSpanElement;
( // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
this.targets.find("component-width") as HTMLSpanElement const component_width_element = this.targets.find(
).innerHTML = `(width: ${component_width}px)`; "component-width"
) as HTMLSpanElement;
const component_width = preview.offsetWidth;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
component_width_element.innerHTML = `(width: ${component_width}px)`;
} }
resizeHandler(e: MouseEvent) { resizeHandler(e: MouseEvent) {
@ -54,7 +60,7 @@ export default class ComponentDebugger extends Controller {
const new_width = Math.max(this.origin_width + width_offset, 1); const new_width = Math.max(this.origin_width + width_offset, 1);
document document
.getElementById("component-debugger") .getElementById("component-debugger")
.style.setProperty("--resizable-column-width", new_width + "px"); .style.setProperty("--resizable-column-width", new_width.toString() + "px");
this.update_width_display(); this.update_width_display();
} }
} }

View File

@ -4,10 +4,10 @@ import * as Turbo from "@hotwired/turbo";
import { Application } from "stimulus"; import { Application } from "stimulus";
const application = Application.start(); const application = Application.start();
import { default as RefreshOnTsChanges } from "./../back/html/refresh-on-ts-changes.stimulus.js"; import { default as RefreshOnTsChanges } from "./../back/html-controllers/refresh-on-ts-changes.stimulus.js";
application.register("refresh-on-ts-changes", RefreshOnTsChanges); application.register("refresh-on-ts-changes", RefreshOnTsChanges);
import { default as RefreshStyles } from "./../back/html/refresh-styles.stimulus.js"; import { default as RefreshStyles } from "./../back/html-controllers/refresh-styles.stimulus.js";
application.register("refresh-styles", RefreshStyles); application.register("refresh-styles", RefreshStyles);
import { default as MapWithPins } from "./../back/jdd-components/map-with-pins/map-with-pins.stimulus.js"; import { default as MapWithPins } from "./../back/jdd-components/map-with-pins/map-with-pins.stimulus.js";

View File

@ -19,7 +19,7 @@
"skipLibCheck": true, "skipLibCheck": true,
"types": ["vitest/globals"] "types": ["vitest/globals"]
}, },
"include": ["./src/back/*", "./src/back/**/*"], "include": ["./src/back/*", "./src/back/**/*", "./src/back/routes/common/navbar.ts"],
"exclude": ["./src/front", "./src/**/*.stimulus.ts"], "exclude": ["./src/front", "./src/**/*.stimulus.ts"],
"ts-node": { "experimentalResolver": true, "esm": true } "ts-node": { "experimentalResolver": true, "esm": true }
} }