chore(code): integrate ESLint

This commit is contained in:
Elian Doran 2025-05-11 15:18:42 +03:00
parent fade41ff65
commit 38fbaabfbc
No known key found for this signature in database
12 changed files with 324 additions and 377 deletions

View File

@ -29,7 +29,6 @@
"dayjs-plugin-utc": "0.1.2",
"debounce": "2.2.0",
"draggabilly": "3.0.0",
"eslint-linter-browserify": "9.26.0",
"force-graph": "1.49.5",
"globals": "16.1.0",
"i18next": "25.1.2",

View File

@ -1,74 +0,0 @@
// CodeMirror, copyright (c) by Marijn Haverbeke and others
// Distributed under an MIT license: http://codemirror.net/LICENSE
(function(mod) {
if (typeof exports == "object" && typeof module == "object") // CommonJS
mod(require("../../lib/codemirror"));
else if (typeof define == "function" && define.amd) // AMD
define(["../../lib/codemirror"], mod);
else // Plain browser env
mod(CodeMirror);
})(function(CodeMirror) {
"use strict";
async function validatorHtml(text, options) {
const result = /<script[^>]*>([\s\S]+)<\/script>/ig.exec(text);
if (result !== null) {
// preceding code is copied over but any (non-newline) character is replaced with space
// this will preserve line numbers etc.
const prefix = text.substr(0, result.index).replace(/./g, " ");
const js = prefix + result[1];
return await validatorJavaScript(js, options);
}
return [];
}
async function validatorJavaScript(text, options) {
if (glob.isMobile()
|| glob.getActiveContextNote() == null
|| glob.getActiveContextNote().mime === 'application/json') {
// eslint doesn't seem to validate pure JSON well
return [];
}
if (text.length > 20000) {
console.log("Skipping linting because of large size: ", text.length);
return [];
}
const errors = await glob.linter(text, glob.getActiveContextNote().mime);
console.log(errors);
const result = [];
if (errors) {
parseErrors(errors, result);
}
return result;
}
CodeMirror.registerHelper("lint", "javascript", validatorJavaScript);
CodeMirror.registerHelper("lint", "html", validatorHtml);
function parseErrors(errors, output) {
for (const error of errors) {
const startLine = error.line - 1;
const endLine = error.endLine !== undefined ? error.endLine - 1 : startLine;
const startCol = error.column - 1;
const endCol = error.endColumn !== undefined ? error.endColumn - 1 : startCol + 1;
output.push({
message: error.message,
severity: error.severity === 1 ? "warning" : "error",
from: CodeMirror.Pos(startLine, startCol),
to: CodeMirror.Pos(endLine, endCol)
});
}
}
});

View File

@ -5,7 +5,6 @@ import libraryLoader from "./library_loader.js";
import ws from "./ws.js";
import froca from "./froca.js";
import linkService from "./link.js";
import { lint } from "./eslint.js";
function setupGlobs() {
window.glob.isDesktop = utils.isDesktop;
@ -19,7 +18,6 @@ function setupGlobs() {
// required for ESLint plugin and CKEditor
window.glob.getActiveContextNote = () => appContext.tabManager.getActiveContextNote();
window.glob.requireLibrary = libraryLoader.requireLibrary;
window.glob.linter = lint;
window.glob.appContext = appContext; // for debugging
window.glob.froca = froca;
window.glob.treeCache = froca; // compatibility for CKEditor builds for a while

View File

@ -22,8 +22,7 @@ const CODE_MIRROR: Library = {
"node_modules/codemirror/addon/mode/simple.js",
"node_modules/codemirror/addon/search/match-highlighter.js",
"node_modules/codemirror/mode/meta.js",
"node_modules/codemirror/keymap/vim.js",
"libraries/codemirror/eslint.js"
"node_modules/codemirror/keymap/vim.js"
];
const mimeTypes = mimeTypesService.getMimeTypes();

View File

@ -32,6 +32,7 @@
"@codemirror/view": "6.36.7",
"@ssddanbrown/codemirror-lang-smarty": "1.0.0",
"@ssddanbrown/codemirror-lang-twig": "1.0.0",
"codemirror-lang-hcl": "0.1.0"
"codemirror-lang-hcl": "0.1.0",
"eslint-linter-browserify": "9.26.0"
}
}

View File

@ -1,4 +1,4 @@
export async function lint(code: string, mimeType: string) {
export async function lint(mimeType: string) {
const Linter = (await import("eslint-linter-browserify")).Linter;
const js = (await import("@eslint/js"));
@ -22,7 +22,9 @@ export async function lint(code: string, mimeType: string) {
}
return new Linter().verify(code, [
return {
linter: new Linter(),
config: [
js.configs.recommended,
{
languageOptions: {
@ -35,6 +37,6 @@ export async function lint(code: string, mimeType: string) {
"no-unused-vars": [ "warn", { vars: "local", args: "after-used" }]
}
}
]);
]
}
}

View File

@ -1,7 +1,7 @@
import { defaultKeymap, history, historyKeymap, indentWithTab } from "@codemirror/commands";
import { EditorView, highlightActiveLine, keymap, lineNumbers, placeholder, ViewUpdate, type EditorViewConfig } from "@codemirror/view";
import { defaultHighlightStyle, StreamLanguage, syntaxHighlighting, indentUnit, bracketMatching } from "@codemirror/language";
import { Compartment } from "@codemirror/state";
import { Compartment, type Extension } from "@codemirror/state";
import { highlightSelectionMatches } from "@codemirror/search";
import byMimeType from "./syntax_highlighting.js";
@ -97,7 +97,7 @@ export default class CodeMirror extends EditorView {
}
async setMimeType(mime: string) {
const newExtension = [];
let newExtension: Extension[] = [];
const correspondingSyntax = byMimeType[mime];
if (correspondingSyntax) {
@ -106,6 +106,8 @@ export default class CodeMirror extends EditorView {
if ("token" in resolvedSyntax) {
const extension = StreamLanguage.define(resolvedSyntax);
newExtension.push(extension);
} else if (Array.isArray(resolvedSyntax)) {
newExtension = [ ...newExtension, ...resolvedSyntax ];
} else {
newExtension.push(resolvedSyntax);
}

View File

@ -1,17 +1,29 @@
import { LanguageSupport, type StreamParser } from "@codemirror/language"
import { LanguageSupport, type StreamParser } from "@codemirror/language";
import {linter as linterExtension, lintGutter } from "@codemirror/lint";
import type { Extension } from "@codemirror/state";
async function buildJavaScript() {
const { javascript } = await import('@codemirror/lang-javascript');
return javascript();
async function buildJavaScript(mimeType: string) {
const { javascript, esLint } = await import('@codemirror/lang-javascript');
const lint = (await import("./eslint.js")).lint;
const extensions: Extension[] = [ javascript() ];
const result = await lint(mimeType);
if ("linter" in result) {
const { linter, config } = result;
extensions.push(linterExtension(esLint(linter, config)));
extensions.push(lintGutter())
}
return extensions;
}
const byMimeType: Record<string, (() => Promise<StreamParser<unknown> | LanguageSupport>) | null> = {
const byMimeType: Record<string, (() => Promise<StreamParser<unknown> | LanguageSupport | Extension[]>) | null> = {
"text/plain": null,
"application/dart": async () => (await import('@codemirror/legacy-modes/mode/clike')).dart,
"application/edn": async () => (await import('@codemirror/legacy-modes/mode/clojure')).clojure,
"application/javascript;env=backend": buildJavaScript,
"application/javascript;env=frontend": buildJavaScript,
"application/javascript;env=backend": async () => buildJavaScript("application/javascript;env=backend"),
"application/javascript;env=frontend": async () => buildJavaScript("application/javascript;env=frontend"),
"application/json": async () => (await import('@codemirror/legacy-modes/mode/javascript')).json,
"application/ld+json": async () => (await import('@codemirror/legacy-modes/mode/javascript')).jsonld,
"application/mbox": async () => (await import('@codemirror/legacy-modes/mode/mbox')).mbox,

View File

@ -3,6 +3,9 @@
"files": [],
"include": [],
"references": [
{
"path": "../commons"
},
{
"path": "./tsconfig.lib.json"
}

View File

@ -17,5 +17,9 @@
"include": [
"src/**/*.ts"
],
"references": []
"references": [
{
"path": "../commons/tsconfig.lib.json"
}
]
}

567
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff