Fix lint and type errors

This commit is contained in:
Kuba Orlik 2024-11-17 11:20:33 +01:00
parent 9147982a83
commit 9a1c9a6b2c
13 changed files with 103 additions and 25 deletions

8
package-lock.json generated
View File

@ -44,6 +44,7 @@
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@sealcode/ansi-html-stream": "^1.0.1", "@sealcode/ansi-html-stream": "^1.0.1",
"@types/hotwired__turbo": "^8.0.2",
"@types/koa__router": "^12.0.4", "@types/koa__router": "^12.0.4",
"@types/node": "^20.8.4", "@types/node": "^20.8.4",
"@types/object-path": "^0.11.4", "@types/object-path": "^0.11.4",
@ -1149,6 +1150,13 @@
"version": "7946.0.14", "version": "7946.0.14",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@types/hotwired__turbo": {
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@types/hotwired__turbo/-/hotwired__turbo-8.0.2.tgz",
"integrity": "sha512-fFWI/JNSTVKTPliSOV4fdeC3Kt3FUTbRYkvtF7QPCkqR51+AJWIiX0T5sJXwUnjL9j43tzfBXPZ2jEsBqw8/Bg==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/http-assert": { "node_modules/@types/http-assert": {
"version": "1.5.5", "version": "1.5.5",
"license": "MIT" "license": "MIT"

View File

@ -109,6 +109,7 @@
"devDependencies": { "devDependencies": {
"@playwright/test": "^1.44.1", "@playwright/test": "^1.44.1",
"@sealcode/ansi-html-stream": "^1.0.1", "@sealcode/ansi-html-stream": "^1.0.1",
"@types/hotwired__turbo": "^8.0.2",
"@types/koa__router": "^12.0.4", "@types/koa__router": "^12.0.4",
"@types/node": "^20.8.4", "@types/node": "^20.8.4",
"@types/object-path": "^0.11.4", "@types/object-path": "^0.11.4",

View File

@ -1,5 +1,5 @@
import { Collection, FieldTypes, Policies } from "sealious"; import { Collection, FieldTypes, Policies } from "sealious";
import { CRUDRoles, Roles } from "../policy-types/roles.js"; import { CRUDRoles } from "../policy-types/roles.js";
export default class Redirects extends Collection { export default class Redirects extends Collection {
fields = { fields = {

View File

@ -5,7 +5,7 @@ import { Roles } from "../policy-types/roles.js";
export default class UserRoles extends Collection { export default class UserRoles extends Collection {
name = "user-roles"; name = "user-roles";
fields = { fields = {
role: new FieldTypes.Text(), role: new FieldTypes.Text().setRequired(true),
user: new FieldTypes.SingleReference("users"), user: new FieldTypes.SingleReference("users"),
}; };

View File

@ -56,9 +56,11 @@ export default class AutoscrollingImages extends Controller {
const nextButtonID = const nextButtonID =
radioButtonIdPrefix + "-autoscrolling-images__radio-" + nextIndex; radioButtonIdPrefix + "-autoscrolling-images__radio-" + nextIndex;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const nextButton = this.element.querySelector("#" + nextButtonID); const nextButton: HTMLInputElement = this.element.querySelector(
"#" + nextButtonID
);
if (nextButton) { if (nextButton) {
(nextButton as HTMLInputElement).checked = true; nextButton.checked = true;
this.currentIndex = nextIndex; this.currentIndex = nextIndex;
this.handleRadioChange(); this.handleRadioChange();
} }

View File

@ -23,8 +23,8 @@ function parseCoords(s: string): [number, number] {
return s.split(", ").map((x) => parseFloat(x)) as [number, number]; return s.split(", ").map((x) => parseFloat(x)) as [number, number];
} }
function decodeHTMLEntities(text) { function decodeHTMLEntities(text: string) {
var entities = [ const entities = [
["amp", "&"], ["amp", "&"],
["apos", "'"], ["apos", "'"],
["#x27", "'"], ["#x27", "'"],
@ -37,7 +37,7 @@ function decodeHTMLEntities(text) {
["quot", '"'], ["quot", '"'],
]; ];
for (var i = 0, max = entities.length; i < max; ++i) for (let i = 0, max = entities.length; i < max; ++i)
text = text.replace(new RegExp("&" + entities[i][0] + ";", "g"), entities[i][1]); text = text.replace(new RegExp("&" + entities[i][0] + ";", "g"), entities[i][1]);
return text; return text;
@ -101,9 +101,7 @@ export default class MapWithPins extends Controller {
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions // 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 // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-argument
decodeHTMLEntities( decodeHTMLEntities(this.element.getAttribute("data-map-with-pins-pins-value"))
this.element.attributes["data-map-with-pins-pins-value"].value
)
) as Pin[]; ) as Pin[];
pins.forEach((pin) => this.addPin(pin)); pins.forEach((pin) => this.addPin(pin));
this.initiated = true; this.initiated = true;

View File

@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-for-in-array */
/* eslint-disable @typescript-eslint/consistent-type-assertions */
import { Controller } from "stimulus"; import { Controller } from "stimulus";
async function sleep(time: number) { async function sleep(time: number) {
@ -21,7 +23,7 @@ export default class Sortable extends Controller {
setIndex(node: HTMLDivElement, index: number) { setIndex(node: HTMLDivElement, index: number) {
node.setAttribute("data-index", String(index)); node.setAttribute("data-index", String(index));
(node as HTMLDivElement).style.setProperty("--index", String(index)); node.style.setProperty("--index", String(index));
} }
setupHoleListeners(hole: HTMLDivElement) { setupHoleListeners(hole: HTMLDivElement) {
@ -70,7 +72,7 @@ export default class Sortable extends Controller {
this.setIndex(node as HTMLDivElement, index_of_drop_target); this.setIndex(node as HTMLDivElement, index_of_drop_target);
last_node_of_target_index = node; last_node_of_target_index = node;
} }
let next_to_correct = nodes_of_dropped_element_index[0].previousSibling; const next_to_correct = nodes_of_dropped_element_index[0].previousSibling;
const children = Array.from(next_to_correct.parentNode.childNodes); const children = Array.from(next_to_correct.parentNode.childNodes);
const children_to_correct = children.slice(2); const children_to_correct = children.slice(2);
for (const dom_index in children_to_correct) { for (const dom_index in children_to_correct) {
@ -104,15 +106,18 @@ export default class Sortable extends Controller {
.querySelectorAll(".edge-detector") .querySelectorAll(".edge-detector")
.forEach((detector: HTMLDivElement) => { .forEach((detector: HTMLDivElement) => {
let is_hovered = false; let is_hovered = false;
detector.addEventListener("dragenter", async (e) => { detector.addEventListener("dragenter", (e) => {
e.preventDefault(); e.preventDefault();
const target = e.target as HTMLDivElement; const target = e.target as HTMLDivElement;
const step = parseInt(target.getAttribute("data-step")); const step = parseInt(target.getAttribute("data-step"));
is_hovered = true; is_hovered = true;
while (is_hovered && this.dragged_element) { void (async () => {
window.scrollTo(window.scrollX, window.scrollY + step); while (is_hovered && this.dragged_element) {
await sleep(16); window.scrollTo(window.scrollX, window.scrollY + step);
} // eslint-disable-next-line no-await-in-loop
await sleep(16);
}
})();
}); });
detector.addEventListener("dragover ", (e) => { detector.addEventListener("dragover ", (e) => {
@ -121,7 +126,6 @@ export default class Sortable extends Controller {
}); });
detector.addEventListener("dragleave", (e) => { detector.addEventListener("dragleave", (e) => {
const target = e.target as HTMLDivElement;
e.preventDefault(); e.preventDefault();
is_hovered = false; is_hovered = false;
}); });

View File

@ -0,0 +1,24 @@
import type { Context } from "koa";
import { TempstreamJSX } from "tempstream";
import { Page } from "@sealcode/sealgen";
import html from "src/back/html.js";
export const actionName = "HelloPage";
export default new (class HelloPagePage extends Page {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
async canAccess(_: Context) {
return { canAccess: true, message: "" };
}
async render(ctx: Context) {
return html({
ctx: ctx,
title: "HelloPage",
body: <div>Hello world</div>,
description: "",
css_clumps: ["default", "forms"],
});
}
})();

View File

@ -0,0 +1,40 @@
import { withProdApp } from "../test_utils/with-prod-app.js";
import { VERY_LONG_TEST_TIMEOUT, webhintURL } from "../test_utils/webhint.js";
import { HelloPageURL } from "./urls.js";
import { getBrowser } from "../test_utils/browser-creator.js";
import type { Browser, BrowserContext, Page } from "@playwright/test";
describe("HelloPage webhint", () => {
it("doesn't crash", async function () {
return withProdApp(async ({ base_url, rest_api }) => {
await rest_api.get(HelloPageURL);
await webhintURL(base_url + HelloPageURL);
// alternatively you can use webhintHTML for faster but less precise scans
// or for scanning responses of requests that use some form of authorization:
// const response = await rest_api.get(HelloPageURL);
// await webhintHTML(response);
});
}).timeout(VERY_LONG_TEST_TIMEOUT);
});
describe("HelloPage", () => {
let page: Page;
let browser: Browser;
let context: BrowserContext;
beforeEach(async () => {
browser = await getBrowser();
context = await browser.newContext();
page = await context.newPage();
});
afterEach(async () => {
await context.close();
});
it("works as expected", async function () {
return withProdApp(async ({ base_url }) => {
await page.goto(base_url + HelloPageURL);
});
}).timeout(VERY_LONG_TEST_TIMEOUT);
});

View File

@ -38,7 +38,6 @@ export default new (class LoginForm extends Form<typeof fields, void> {
async onSubmit(ctx: Context) { async onSubmit(ctx: Context) {
const body = ctx.$body; const body = ctx.$body;
console.log(body);
if ( if (
!hasShape({ username: predicates.string, password: predicates.string }, body) !hasShape({ username: predicates.string, password: predicates.string }, body)
) { ) {

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/consistent-type-assertions */
import type { Context } from "koa"; import type { Context } from "koa";
import { MeiliSearch } from "meilisearch"; import { MeiliSearch } from "meilisearch";
import type { CollectionItem } from "sealious"; import type { CollectionItem } from "sealious";
@ -31,10 +32,10 @@ export const createIndex = async (name: string) => {
} }
}; };
const indexes = {} as Record< const indexes: Record<
string, string,
{ getItems: (ctx: Context, ids: string[]) => CollectionItem[] } { getItems: (ctx: Context, ids: string[]) => Promise<CollectionItem[]> }
>; > = {};
export async function search( export async function search(
ctx: Context, ctx: Context,
@ -55,9 +56,9 @@ export async function search(
const result = Object.fromEntries( const result = Object.fromEntries(
await Promise.all( await Promise.all(
use_indexes.map(async (index_name, key) => { use_indexes.map(async (index_name, key) => {
const ids = results[key]!.hits.map((e) => e.id); const ids = results[key]!.hits.map((e) => e.id as string);
const items = await indexes[index_name]?.getItems(ctx, ids); const items = await indexes[index_name]?.getItems(ctx, ids);
return [index_name, items]; return <const>[index_name, items];
}) })
) )
); );

View File

@ -2,7 +2,6 @@
/* eslint-disable @typescript-eslint/consistent-type-assertions */ /* eslint-disable @typescript-eslint/consistent-type-assertions */
import type { Context } from "koa"; import type { Context } from "koa";
import qs from "qs"; import qs from "qs";
import { MEILISEARCH_HOST } from "./config.js";
export async function sleep(time: number) { export async function sleep(time: number) {
return new Promise((resolve) => setTimeout(resolve, time)); return new Promise((resolve) => setTimeout(resolve, time));

View File

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/consistent-type-assertions */
export * from "./controllers.js"; export * from "./controllers.js";
(function enableScrollPreservation() { (function enableScrollPreservation() {
@ -23,6 +24,7 @@ export * from "./controllers.js";
addEventListener("turbo:visit", () => { addEventListener("turbo:visit", () => {
/* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */ /* eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any */
if (shouldPreserveScroll) { if (shouldPreserveScroll) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-explicit-any
(window as any).Turbo.navigator.currentVisit.scrolled = true; (window as any).Turbo.navigator.currentVisit.scrolled = true;
document.documentElement.scrollTop = scrollTop; document.documentElement.scrollTop = scrollTop;
} }