{
- onEnter(view, false);
+ onEnter(view.state.sliceDoc(), false);
return true;
},
},
{
key: "Shift-Enter",
run: (view) => {
- onEnter(view, true);
+ onEnter(view.state.sliceDoc(), true);
return true;
},
},
{
key: "Escape",
run: (view) => {
- callbacksRef.current!.onEscape &&
- callbacksRef.current!.onEscape(view.state.sliceDoc());
+ callbacksRef.current!.onEscape?.(view.state.sliceDoc());
return true;
},
},
@@ -199,7 +194,7 @@ export function MiniEditor(
// Enter should be handled by the keymap, except when in Vim normal mode
// because then it's disabled
if (vimMode && vimModeRef.current === "normal") {
- onEnter(view, event.shiftKey);
+ onEnter(view.state.sliceDoc(), event.shiftKey);
return true;
}
return false;
@@ -210,7 +205,7 @@ export function MiniEditor(
return false;
},
blur: (_e, view) => {
- onBlur(view);
+ onBlur?.(view.state.sliceDoc());
},
}),
@@ -218,44 +213,12 @@ export function MiniEditor(
class {
update(update: ViewUpdate): void {
if (update.docChanged) {
- callbacksRef.current!.onChange &&
- callbacksRef.current!.onChange(update.state.sliceDoc());
+ callbacksRef.current!.onChange?.(update.state.sliceDoc());
}
}
},
),
],
});
-
- // Avoid double triggering these events (may happen due to onkeypress vs onkeyup delay)
- function onEnter(view: EditorView, shiftDown: boolean) {
- if (onEntered) {
- return;
- }
- onEntered = true;
- callbacksRef.current!.onEnter(view.state.sliceDoc(), shiftDown);
- // Event may occur again in 500ms
- setTimeout(() => {
- onEntered = false;
- }, 500);
- }
-
- function onBlur(view: EditorView) {
- if (onBlurred || onEntered) {
- return;
- }
- onBlurred = true;
- if (callbacksRef.current!.onBlur) {
- Promise.resolve(callbacksRef.current!.onBlur(view.state.sliceDoc()))
- .catch(() => {
- // Reset the state
- view.setState(buildEditorState());
- });
- }
- // Event may occur again in 500ms
- setTimeout(() => {
- onBlurred = false;
- }, 500);
- }
}
}
diff --git a/client/components/top_bar.tsx b/client/components/top_bar.tsx
index 392b2636..cf3d5769 100644
--- a/client/components/top_bar.tsx
+++ b/client/components/top_bar.tsx
@@ -66,7 +66,7 @@ export function TopBar({
: unsavedChanges
? "sb-unsaved"
: "sb-saved") +
- (cssClass ? " sb-decorated-object " + cssClass : "")}
+ (cssClass ? ` sb-decorated-object ${cssClass}` : "")}
>
{
- const tempPath = tempFilePath() + "_nonexistent";
+ const tempPath = `${tempFilePath()}_nonexistent`;
// Disable throttling for tests
const store = new MemoryKvPrimitives(tempPath, { throttleMs: 0 });
await store.init();
diff --git a/client/data/object_index.ts b/client/data/object_index.ts
index a3b89a1f..00398a30 100644
--- a/client/data/object_index.ts
+++ b/client/data/object_index.ts
@@ -130,7 +130,7 @@ export class ObjectIndex {
};
}
- getObjectByRef(page: string, tag: string, ref: string) {
+ getObjectByRef<_T>(page: string, tag: string, ref: string) {
return this.ds.get([indexKey, tag, this.cleanKey(ref, page), page]);
}
diff --git a/client/html/auth.html b/client/html/auth.html
index 0010f4bc..e6f009f9 100644
--- a/client/html/auth.html
+++ b/client/html/auth.html
@@ -152,7 +152,6 @@
autocapitalize="off"
autocomplete="off"
autocorrect="off"
- autofocus
id="username"
name="username"
type="text"
diff --git a/client/html/index.html b/client/html/index.html
index 52f857b0..bbfe8a98 100644
--- a/client/html/index.html
+++ b/client/html/index.html
@@ -41,7 +41,7 @@
},
},
env: {
- get(key) {
+ get(_key) {
// return undefined;
},
},
diff --git a/client/lib/logger.ts b/client/lib/logger.ts
index 187178fc..3cf5ae31 100644
--- a/client/lib/logger.ts
+++ b/client/lib/logger.ts
@@ -109,7 +109,7 @@ export class Logger {
}
// Global logger instance
-let globalLogger: Logger | undefined = undefined;
+let globalLogger: Logger | undefined ;
export function initLogger(prefix: string = ""): Logger {
globalLogger = new Logger(prefix);
diff --git a/client/lib/polyfills.ts b/client/lib/polyfills.ts
index 25d679dc..9650dccf 100644
--- a/client/lib/polyfills.ts
+++ b/client/lib/polyfills.ts
@@ -1,8 +1,8 @@
// Source: https://github.com/ungap/with-resolvers/blob/main/index.js
-// @ts-ignore This is fine
+// @ts-expect-error This is fine
Promise.withResolvers || (Promise.withResolvers = function withResolvers() {
let a, b;
- const c = new this(function (resolve, reject) {
+ const c = new this((resolve, reject) => {
a = resolve;
b = reject;
});
diff --git a/client/lib/util.ts b/client/lib/util.ts
index 2f829361..7c091b48 100644
--- a/client/lib/util.ts
+++ b/client/lib/util.ts
@@ -11,11 +11,11 @@ export function authCookieName(host: string) {
export function fileMetaToHeaders(fileMeta: FileMeta) {
return {
"Content-Type": fileMeta.contentType,
- "X-Last-Modified": "" + fileMeta.lastModified,
- "X-Created": "" + fileMeta.created,
+ "X-Last-Modified": `${fileMeta.lastModified}`,
+ "X-Created": `${fileMeta.created}`,
"Cache-Control": "no-cache",
"X-Permission": fileMeta.perm,
- "X-Content-Length": "" + fileMeta.size,
+ "X-Content-Length": `${fileMeta.size}`,
};
}
diff --git a/client/markdown_parser/constants.ts b/client/markdown_parser/constants.ts
index 250e70ae..69c85d5a 100644
--- a/client/markdown_parser/constants.ts
+++ b/client/markdown_parser/constants.ts
@@ -4,10 +4,10 @@ export const mdLinkRegex = /!?\[(?[^\]]*)\]\((?.+)\)/g;
export const tagRegex =
/#(?:(?:\d*[^\d\s!@#$%^&*(),.?":{}|<>\\][^\s!@#$%^&*(),.?":{}|<>\\]*)|(?:<[^>\n]+>))/;
export const nakedUrlRegex =
- /(^https?:\/\/([-a-zA-Z0-9@:%_\+~#=]|(?:[.](?!(\s|$)))){1,256})(([-a-zA-Z0-9(@:%_\+~#?&=\/]|(?:[.,:;)](?!(\s|$))))*)/;
+ /(^https?:\/\/([-a-zA-Z0-9@:%_+~#=]|(?:[.](?!(\s|$)))){1,256})(([-a-zA-Z0-9(@:%_+~#?&=/]|(?:[.,:;)](?!(\s|$))))*)/;
export const frontmatterQuotesRegex = /["'].*["']/g;
export const frontmatterUrlRegex = /([a-zA-Z][a-zA-Z0-9+.-]*:\/\/[^\s"']+)/g;
export const frontmatterWikiLinkRegex =
/(?!?\[\[)(?.*?)(?:\|(?.*?))?(?\]\])/g;
export const frontmatterMailtoRegex = /(mailto:[^@\s]+@[^@\s"']+)/ig;
-export const pWikiLinkRegex = new RegExp("^" + wikiLinkRegex.source); // Modified regex used only in parser
+export const pWikiLinkRegex = new RegExp(`^${wikiLinkRegex.source}`); // Modified regex used only in parser
diff --git a/client/markdown_parser/extended_task.ts b/client/markdown_parser/extended_task.ts
index 67e2f7be..ed39a26d 100644
--- a/client/markdown_parser/extended_task.ts
+++ b/client/markdown_parser/extended_task.ts
@@ -52,7 +52,7 @@ export const TaskList: MarkdownConfig = {
// Note: task states cannot contain : to avoid ambiguity with attribute syntax
const match = /^\[([^\]:]+)\][ \t]/.exec(leaf.content);
return match &&
- cx.parentType().name == "ListItem"
+ cx.parentType().name === "ListItem"
? new MultiStatusTaskParser(match[1])
: null;
},
diff --git a/client/markdown_parser/parser.ts b/client/markdown_parser/parser.ts
index 130a1ca3..c3220e93 100644
--- a/client/markdown_parser/parser.ts
+++ b/client/markdown_parser/parser.ts
@@ -30,7 +30,7 @@ const WikiLink: MarkdownConfig = {
name: "WikiLink",
parse(cx, next, pos) {
// Do a preliminary check for performance
- if (next != 91 /* '[' */ && next != 33 /* '!' */) {
+ if (next !== 91 /* '[' */ && next !== 33 /* '!' */) {
return -1;
}
@@ -68,7 +68,7 @@ const WikiLink: MarkdownConfig = {
]);
// If inline image
- if (next == 33) {
+ if (next === 33) {
allElts = cx.elt("Image", pos, endPos, [allElts]);
}
@@ -171,7 +171,7 @@ export const Highlight: MarkdownConfig = {
{
name: "Highlight",
parse(cx, next, pos) {
- if (next != 61 /* '=' */ || cx.char(pos + 1) != 61) return -1;
+ if (next !== 61 /* '=' */ || cx.char(pos + 1) !== 61) return -1;
return cx.addDelimiter(HighlightDelim, pos, pos + 2, true, true);
},
after: "Emphasis",
@@ -179,7 +179,7 @@ export const Highlight: MarkdownConfig = {
],
};
-export const attributeStartRegex = /^\[([\w\$]+)(::?\s*)/;
+export const attributeStartRegex = /^\[([\w$]+)(::?\s*)/;
export const Attribute: MarkdownConfig = {
defineNodes: [
@@ -196,7 +196,7 @@ export const Attribute: MarkdownConfig = {
let match: RegExpMatchArray | null;
const textFromPos = cx.slice(pos, cx.end);
if (
- next != 91 /* '[' */ ||
+ next !== 91 /* '[' */ ||
// and match the whole thing
!(match = attributeStartRegex.exec(textFromPos))
) {
@@ -332,7 +332,7 @@ export const FrontMatter: MarkdownConfig = {
let text = "";
let lastPos = cx.parsedPos;
do {
- text += line.text + "\n";
+ text += `${line.text}\n`;
endPos += line.text.length + 1;
cx.nextLine();
if (cx.parsedPos === lastPos) {
diff --git a/client/markdown_parser/table_parser.ts b/client/markdown_parser/table_parser.ts
index 61b22b97..99d33ae1 100644
--- a/client/markdown_parser/table_parser.ts
+++ b/client/markdown_parser/table_parser.ts
@@ -59,7 +59,7 @@ function parseRow(
}
}
- if (next == 124 /* '|' */ && !esc && !inWikilink && !inCommandButton) {
+ if (next === 124 /* '|' */ && !esc && !inWikilink && !inCommandButton) {
if (!first || cellStart > -1) count++;
first = false;
if (elts) {
@@ -67,11 +67,11 @@ function parseRow(
elts.push(cx.elt("TableDelimiter", i + offset, i + offset + 1));
}
cellStart = cellEnd = -1;
- } else if (esc || next != 32 && next != 9) {
+ } else if (esc || next !== 32 && next !== 9) {
if (cellStart < 0) cellStart = i;
cellEnd = i + 1;
}
- esc = !esc && next == 92;
+ esc = !esc && next === 92;
}
if (cellStart > -1) {
count++;
@@ -83,8 +83,8 @@ function parseRow(
function hasPipe(str: string, start: number) {
for (let i = start; i < str.length; i++) {
const next = str.charCodeAt(i);
- if (next == 124 /* '|' */) return true;
- if (next == 92 /* '\\' */) i++;
+ if (next === 124 /* '|' */) return true;
+ if (next === 92 /* '\\' */) i++;
}
return false;
}
@@ -102,12 +102,12 @@ class TableParser implements LeafBlockParser {
this.rows = false;
let lineText;
if (
- (line.next == 45 || line.next == 58 || line.next == 124 /* '-:|' */) &&
+ (line.next === 45 || line.next === 58 || line.next === 124 /* '-:|' */) &&
delimiterLine.test(lineText = line.text.slice(line.pos))
) {
const firstRow: Element[] = [],
firstCount = parseRow(cx, leaf.content, 0, firstRow, leaf.start);
- if (firstCount == parseRow(cx, lineText, line.pos)) {
+ if (firstCount === parseRow(cx, lineText, line.pos)) {
this.rows = [
cx.elt(
"TableHeader",
@@ -180,10 +180,10 @@ export const Table: MarkdownConfig = {
leaf.parsers.some((p) => p instanceof TableParser) ||
!hasPipe(line.text, line.basePos)
) return false;
- // @ts-ignore: internal
+ // @ts-expect-error: internal
const next = cx.scanLine(cx.absoluteLineEnd + 1).text;
return delimiterLine.test(next) &&
- parseRow(cx, line.text, line.basePos) ==
+ parseRow(cx, line.text, line.basePos) ===
parseRow(cx, next, line.basePos);
},
before: "SetextHeading",
diff --git a/client/markdown_renderer/html_render.ts b/client/markdown_renderer/html_render.ts
index b50d7a27..ad00af46 100644
--- a/client/markdown_renderer/html_render.ts
+++ b/client/markdown_renderer/html_render.ts
@@ -33,11 +33,11 @@ export function renderHtml(t: Tag | null): string {
return htmlEscape(t);
}
const attrs = t.attrs
- ? " " + Object.entries(t.attrs)
+ ? ` ${Object.entries(t.attrs)
.filter(([, value]) => value !== undefined)
.map(([k, v]) => `${k}="${htmlEscape(v!)}"`).join(
" ",
- )
+ )}`
: "";
const body = typeof t.body === "string"
? htmlEscape(t.body)
diff --git a/client/markdown_renderer/inline.ts b/client/markdown_renderer/inline.ts
index b3e22771..407d9242 100644
--- a/client/markdown_renderer/inline.ts
+++ b/client/markdown_renderer/inline.ts
@@ -208,7 +208,7 @@ export function inlineContentFromURL(
// If the URL is a local, prefix it with /.fs and encode the : so that it's not interpreted as a protocol
const sanitizedFsUrl = isLocalURL(transclusion.url)
- ? fsEndpoint.slice(1) + "/" + transclusion.url.replace(":", "%3A")
+ ? `${fsEndpoint.slice(1)}/${transclusion.url.replace(":", "%3A")}`
: transclusion.url;
if (mimeType.startsWith("image/")) {
diff --git a/client/markdown_renderer/markdown_render.ts b/client/markdown_renderer/markdown_render.ts
index 4a47c368..170bf02b 100644
--- a/client/markdown_renderer/markdown_render.ts
+++ b/client/markdown_renderer/markdown_render.ts
@@ -84,7 +84,7 @@ function posPreservingRender(
if (!tag.attrs) {
tag.attrs = {};
}
- tag.attrs["data-pos"] = "" + t.from;
+ tag.attrs["data-pos"] = `${t.from}`;
}
return tag;
}
diff --git a/client/markdown_renderer/result_render.ts b/client/markdown_renderer/result_render.ts
index 36496f86..d830ca3a 100644
--- a/client/markdown_renderer/result_render.ts
+++ b/client/markdown_renderer/result_render.ts
@@ -19,7 +19,7 @@ export function defaultTransformer(v: any, _k: string): Promise {
if (typeof v === "number") {
return Promise.resolve(luaFormatNumber(v));
}
- return Promise.resolve("" + v);
+ return Promise.resolve(`${v}`);
}
export function refCellTransformer(v: any, k: string) {
@@ -43,18 +43,18 @@ function escapeRegularPipes(s: string) {
let isInCommandButton = false;
for (let i = 0; i < s.length; i++) {
- if (s[i] == "[" && s[i + 1] == "[") {
+ if (s[i] === "[" && s[i + 1] === "[") {
isInWikiLink = true;
- } else if (s[i] == "]" && s[i + 1] == "]" && isInWikiLink) {
+ } else if (s[i] === "]" && s[i + 1] === "]" && isInWikiLink) {
isInWikiLink = false;
}
- if (s[i] == "{" && s[i + 1] == "[") {
+ if (s[i] === "{" && s[i + 1] === "[") {
isInCommandButton = true;
} else if (
- (s[i] == "]" || s[i] == ")") && s[i + 1] == "}" && isInCommandButton
+ (s[i] === "]" || s[i] === ")") && s[i + 1] === "}" && isInCommandButton
) {
isInCommandButton = false;
- } else if (s[i] == "|" && !isInWikiLink && !isInCommandButton) {
+ } else if (s[i] === "|" && !isInWikiLink && !isInCommandButton) {
result += "\\";
}
@@ -77,7 +77,7 @@ export async function jsonToMDTable(
}
// Handle empty case manually, instead of three lines of ||
- if (headers.size == 0) {
+ if (headers.size === 0) {
return "*(empty table)*";
}
@@ -105,7 +105,7 @@ export async function jsonToMDTable(
const s = await valueTransformer(val[prop], prop);
el.push(s);
}
- lines.push("|" + el.join("|") + "|");
+ lines.push(`|${el.join("|")}|`);
}
return lines.join("\n");
}
@@ -145,7 +145,7 @@ export function renderExpressionResult(result: any): Promise {
// Not-object array, let's render it as a Markdown list
return Promise.resolve(result.map((item) => `- ${item}`).join("\n"));
} else {
- return Promise.resolve("" + result);
+ return Promise.resolve(`${result}`);
}
}
@@ -158,5 +158,5 @@ export function isBlockMarkdown(s: string) {
return true;
}
// If it contains something resembling a list
- return !!s.match(/[\-\*]\s+/);
+ return !!s.match(/[-*]\s+/);
}
diff --git a/client/plugos/hooks/code_widget.ts b/client/plugos/hooks/code_widget.ts
index c921cabb..1ed3752e 100644
--- a/client/plugos/hooks/code_widget.ts
+++ b/client/plugos/hooks/code_widget.ts
@@ -7,9 +7,6 @@ export class CodeWidgetHook implements Hook {
codeWidgetCallbacks = new Map();
codeWidgetModes = new Map();
- constructor() {
- }
-
collectAllCodeWidgets(system: System) {
this.codeWidgetCallbacks.clear();
for (const plug of system.loadedPlugs.values()) {
diff --git a/client/plugos/hooks/document_editor.ts b/client/plugos/hooks/document_editor.ts
index ac78aa19..82492fd4 100644
--- a/client/plugos/hooks/document_editor.ts
+++ b/client/plugos/hooks/document_editor.ts
@@ -9,9 +9,6 @@ export class DocumentEditorHook implements Hook {
{ extensions: string[]; callback: DocumentEditorCallback }
>();
- constructor() {
- }
-
collectAllDocumentEditors(system: System) {
this.documentEditors.clear();
for (const plug of system.loadedPlugs.values()) {
diff --git a/client/plugos/hooks/plug_namespace.ts b/client/plugos/hooks/plug_namespace.ts
index ee4f9338..a73969a1 100644
--- a/client/plugos/hooks/plug_namespace.ts
+++ b/client/plugos/hooks/plug_namespace.ts
@@ -15,9 +15,6 @@ type SpaceFunction = {
export class PlugNamespaceHook implements Hook {
spaceFunctions: SpaceFunction[] = [];
- constructor() {
- }
-
apply(system: System): void {
system.on({
plugLoaded: () => {
diff --git a/client/plugos/hooks/slash_command.ts b/client/plugos/hooks/slash_command.ts
index 0d90db9e..9713cdcf 100644
--- a/client/plugos/hooks/slash_command.ts
+++ b/client/plugos/hooks/slash_command.ts
@@ -15,7 +15,7 @@ import type {
SlashCompletions,
} from "@silverbulletmd/silverbullet/type/client";
-const slashCommandRegexp = /([^\w:]|^)\/[\w#\-]*/;
+const slashCommandRegexp = /([^\w:]|^)\/[\w#-]*/;
export class SlashCommandHook implements Hook {
slashCommands: SlashCommand[] = [];
@@ -94,7 +94,7 @@ export class SlashCommandHook implements Hook {
continue;
}
if (
- def.exceptContexts && def.exceptContexts.some(
+ def.exceptContexts?.some(
(context) => parentNodes.some((node) => node.startsWith(context)),
)
) {
diff --git a/client/plugos/plug_compile.ts b/client/plugos/plug_compile.ts
index e03bf196..fb7a0aa3 100644
--- a/client/plugos/plug_compile.ts
+++ b/client/plugos/plug_compile.ts
@@ -6,7 +6,6 @@ import * as YAML from "js-yaml";
import * as esbuild from "esbuild";
import { bundleAssets } from "../asset_bundle/builder.ts";
import type { Manifest } from "./types.ts";
-import { version } from "../../version.ts";
import { existsSync } from "node:fs";
diff --git a/client/plugos/sandboxes/web_worker_sandbox.ts b/client/plugos/sandboxes/web_worker_sandbox.ts
index b3c5f3f1..24df2989 100644
--- a/client/plugos/sandboxes/web_worker_sandbox.ts
+++ b/client/plugos/sandboxes/web_worker_sandbox.ts
@@ -11,7 +11,7 @@ export function createWorkerSandboxFromLocalPath(
plug,
new URL(
name,
- document.baseURI.slice(0, -1) + fsEndpoint + "/", // We're NOT striping trailing '/', this used to be `location.origin`
+ `${document.baseURI.slice(0, -1) + fsEndpoint}/`, // We're NOT striping trailing '/', this used to be `location.origin`
),
);
}
diff --git a/client/plugos/sandboxes/worker_sandbox.ts b/client/plugos/sandboxes/worker_sandbox.ts
index 7487a1c4..a5ad5b41 100644
--- a/client/plugos/sandboxes/worker_sandbox.ts
+++ b/client/plugos/sandboxes/worker_sandbox.ts
@@ -94,10 +94,9 @@ export class WorkerSandbox implements Sandbox {
const resultCbs = this.outstandingInvocations.get(data.id!);
this.outstandingInvocations.delete(data.id!);
if (data.error) {
- resultCbs &&
- resultCbs.reject(new Error(data.error));
+ resultCbs?.reject(new Error(data.error));
} else {
- resultCbs && resultCbs.resolve(data.result);
+ resultCbs?.resolve(data.result);
}
break;
}
diff --git a/client/plugos/syscalls/editor.ts b/client/plugos/syscalls/editor.ts
index f53fcbc0..bb58f46e 100644
--- a/client/plugos/syscalls/editor.ts
+++ b/client/plugos/syscalls/editor.ts
@@ -110,7 +110,7 @@ export function editorSyscalls(client: Client): SysCallMapping {
}
if (
- // @ts-ignore: Legacy support
+ // @ts-expect-error: Legacy support
ref.page !== undefined
) {
console.warn(
@@ -127,7 +127,7 @@ export function editorSyscalls(client: Client): SysCallMapping {
legacyRef.kind ??= "page";
- let details: Ref["details"] = undefined;
+ let details: Ref["details"] ;
if (typeof legacyRef.pos === "number") {
details = {
@@ -232,7 +232,7 @@ export function editorSyscalls(client: Client): SysCallMapping {
"editor.newWindow": () => {
globalThis.open(
location.href,
- "rnd" + Math.random(),
+ `rnd${Math.random()}`,
`width=${globalThis.innerWidth},heigh=${globalThis.innerHeight}`,
);
},
@@ -268,7 +268,7 @@ export function editorSyscalls(client: Client): SysCallMapping {
const reader = new FileReader();
reader.readAsArrayBuffer(file);
reader.onloadend = async (evt) => {
- if (evt.target?.readyState == FileReader.DONE) {
+ if (evt.target?.readyState === FileReader.DONE) {
resolve({
name: file.name,
contentType: file.type,
@@ -506,7 +506,7 @@ export function editorSyscalls(client: Client): SysCallMapping {
},
"editor.vimEx": (_ctx, exCommand: string) => {
const cm = vimGetCm(client.editorView);
- if (cm && cm.state.vim) {
+ if (cm?.state.vim) {
return Vim.handleEx(cm as any, exCommand);
} else {
throw new Error("Vim mode not active or not initialized.");
@@ -555,30 +555,30 @@ export function editorSyscalls(client: Client): SysCallMapping {
if (config) {
config.unmap?.forEach((binding) => {
if (typeof binding === "string") {
- console.log("Unmapping " + binding);
- // @ts-ignore: unmap expects a string for the mode, this is problematic with Ex mappings which requires undefined or false
+ console.log(`Unmapping ${binding}`);
+ // @ts-expect-error: unmap expects a string for the mode, this is problematic with Ex mappings which requires undefined or false
Vim.unmap(binding, undefined);
} else if (binding.key) {
console.log(
- "Unmapping " + binding.key + " in " + (binding.mode ?? "normal"),
+ `Unmapping ${binding.key} in ${binding.mode ?? "normal"}`,
);
Vim.unmap(binding.key, binding.mode ?? "normal");
}
});
config.map?.forEach(({ map, to, mode }) => {
console.log(
- "Mapping " + map + " to " + to + " for " + (mode ?? "normal"),
+ `Mapping ${map} to ${to} for ${mode ?? "normal"}`,
);
Vim.map(map, to, mode ?? "normal");
});
config.noremap?.forEach(({ map, to, mode }) => {
console.log(
- "Noremapping " + map + " to " + to + " for " + (mode ?? "normal"),
+ `Noremapping ${map} to ${to} for ${mode ?? "normal"}`,
);
Vim.noremap(map, to, mode ?? "normal");
});
config.commands?.forEach(({ ex, command }) => {
- console.log("Mapping command '" + command + "' to Ex " + ex);
+ console.log(`Mapping command '${command}' to Ex ${ex}`);
Vim.defineEx(ex, "", () => client.runCommandByName(command));
});
} else {
diff --git a/client/plugos/syscalls/jsonschema.ts b/client/plugos/syscalls/jsonschema.ts
index 4e05957f..ab205970 100644
--- a/client/plugos/syscalls/jsonschema.ts
+++ b/client/plugos/syscalls/jsonschema.ts
@@ -33,7 +33,7 @@ export function validateObject(schema: any, object: any): undefined | string {
} else {
let text = ajv.errorsText(validate.errors);
text = text.replaceAll("/", ".");
- text = text.replace(/^data[\.\s]/, "");
+ text = text.replace(/^data[.\s]/, "");
return text;
}
} catch (e: any) {
diff --git a/client/plugos/syscalls/mq.ts b/client/plugos/syscalls/mq.ts
index 18a7f418..a6ae2cef 100644
--- a/client/plugos/syscalls/mq.ts
+++ b/client/plugos/syscalls/mq.ts
@@ -17,7 +17,7 @@ export function mqSyscalls(
_ctx,
def: MQListenerSpec,
) => {
- def.autoAck = def.autoAck != false;
+ def.autoAck = def.autoAck !== false;
// console.log("Registering Lua event listener: ", def.name);
client.config.insert([
"mqSubscriptions",
diff --git a/client/plugos/syscalls/space.ts b/client/plugos/syscalls/space.ts
index b4332a8b..39cc956d 100644
--- a/client/plugos/syscalls/space.ts
+++ b/client/plugos/syscalls/space.ts
@@ -32,7 +32,7 @@ export function spaceReadSyscalls(client: Client): SysCallMapping {
return (await client.space.readRef(ref)).text;
},
"space.pageExists": (_ctx, name: string): boolean => {
- return client.clientSystem.allKnownFiles.has(name + ".md");
+ return client.clientSystem.allKnownFiles.has(`${name}.md`);
},
"space.getPageMeta": (_ctx, name: string): Promise => {
return client.space.getPageMeta(name);
diff --git a/client/plugos/system.ts b/client/plugos/system.ts
index 457ed011..334407b4 100644
--- a/client/plugos/system.ts
+++ b/client/plugos/system.ts
@@ -193,8 +193,8 @@ export class System extends EventEmitter> {
this.plugs.delete(name);
}
- unloadAll(): Promise {
- return Promise.all(
+ async unloadAll(): Promise {
+ await Promise.all(
Array.from(this.plugs.keys()).map(this.unload.bind(this)),
);
}
diff --git a/client/plugos/worker_runtime.ts b/client/plugos/worker_runtime.ts
index 9216ea36..b44c72a8 100644
--- a/client/plugos/worker_runtime.ts
+++ b/client/plugos/worker_runtime.ts
@@ -20,7 +20,7 @@ let workerPostMessage = (_msg: ControllerMessage): void => {
// - in a browser's worker threads, typeof window === "undefined"
// - in Cloudflare workers typeof window === "undefined", but typeof globalThis.WebSocketPair is defined
const runningAsWebWorker = typeof window === "undefined" &&
- // @ts-ignore: globalThis
+ // @ts-expect-error: globalThis
typeof globalThis.WebSocketPair === "undefined";
const pendingRequests = new Map<
@@ -136,17 +136,16 @@ export async function sandboxFetch(
return syscall("sandboxFetch.fetch", reqInfo, options);
}
-// @ts-ignore: monkey patching fetch
globalThis.nativeFetch = globalThis.fetch;
// Monkey patch fetch()
export function monkeyPatchFetch() {
- // @ts-ignore: monkey patching fetch
- globalThis.fetch = async function (
+ // @ts-expect-error: monkey patching fetch
+ globalThis.fetch = async (
reqInfo: RequestInfo,
init?: RequestInit,
- ): Promise {
- const encodedBody = init && init.body
+ ): Promise => {
+ const encodedBody = init?.body
? base64Encode(
new Uint8Array(await (new Response(init.body)).arrayBuffer()),
)
diff --git a/client/reducer.ts b/client/reducer.ts
index f0f81f0f..0217cf30 100644
--- a/client/reducer.ts
+++ b/client/reducer.ts
@@ -76,7 +76,7 @@ export default function reducer(
let currPageMeta: PageMeta | undefined;
for (const pageMeta of action.allPages) {
const oldPageMetaItem = oldPageMeta.get(pageMeta.name);
- if (oldPageMetaItem && oldPageMetaItem.lastOpened) {
+ if (oldPageMetaItem?.lastOpened) {
pageMeta.lastOpened = oldPageMetaItem.lastOpened;
}
if (parseToRef(pageMeta.name)?.path === state.current?.path) {
diff --git a/client/service_worker.ts b/client/service_worker.ts
index d0957396..7882b25b 100644
--- a/client/service_worker.ts
+++ b/client/service_worker.ts
@@ -64,7 +64,7 @@ const proxyRouter = new ProxyRouter(
// Configuration mutex
let configuring = false;
-// @ts-ignore: debugging
+// @ts-expect-error: debugging
globalThis.proxyRouter = proxyRouter;
// This is the in-memory store of an encryption key that SB clients and the index engine can share without asking for it constantly
@@ -72,7 +72,7 @@ let encryptionKeyMemoryStore: CryptoKey | undefined;
// Let's clean this encryptionKey if there's no more clients left for a little while, asking to re-enter
setInterval(() => {
- // @ts-ignore: service worker API
+ // @ts-expect-error: service worker API
globalThis.clients.matchAll().then((clients) => {
if (clients.length === 0 && encryptionKeyMemoryStore) {
console.info("No more clients, flushing encryption key");
@@ -86,7 +86,7 @@ self.addEventListener("message", async (event: any) => {
const message: ServiceWorkerTargetMessage = event.data;
switch (message.type) {
case "skip-waiting": {
- // @ts-ignore: Skip waiting to activate this service worker immediately
+ // @ts-expect-error: Skip waiting to activate this service worker immediately
self.skipWaiting();
break;
}
@@ -317,7 +317,7 @@ self.addEventListener("message", async (event: any) => {
});
function broadcastMessage(message: ServiceWorkerSourceMessage) {
- // @ts-ignore: service worker API
+ // @ts-expect-error: service worker API
const clients: any = self.clients;
// Find all windows attached to this service worker
clients.matchAll({
@@ -364,7 +364,7 @@ self.addEventListener("install", (event: any) => {
Object.keys(precacheFiles).length,
"client files cached",
);
- // @ts-ignore: Force the waiting service worker to become the active service worker
+ // @ts-expect-error: Force the waiting service worker to become the active service worker
await self.skipWaiting();
})(),
);
@@ -389,7 +389,7 @@ self.addEventListener("activate", (event: any) => {
}
}),
);
- // @ts-ignore: Take control of all clients as soon as the service worker activates
+ // @ts-expect-error: Take control of all clients as soon as the service worker activates
await clients.claim();
})(),
);
diff --git a/client/space.ts b/client/space.ts
index 91327c31..0efb0771 100644
--- a/client/space.ts
+++ b/client/space.ts
@@ -106,7 +106,7 @@ export class Space {
let text = `**Error:** Header not found: ${desiredHeaderText}`;
let offset = 0;
traverseTree(tree, (n) => {
- if (n.type && n.type.startsWith("ATXHeading")) {
+ if (n.type?.startsWith("ATXHeading")) {
const level = +n.type!.substring("ATXHeading".length);
const headerText = renderToText(n).slice(level + 1);
let endPos = pageText.length;
diff --git a/client/space_lua/aggregates.test.ts b/client/space_lua/aggregates.test.ts
index 4a19388e..da9cad79 100644
--- a/client/space_lua/aggregates.test.ts
+++ b/client/space_lua/aggregates.test.ts
@@ -742,7 +742,7 @@ test("aggregate: custom concat with finish", async () => {
state.rawSet("s", String(value));
state.rawSet("first", false);
} else {
- state.rawSet("s", state.rawGet("s") + ", " + String(value));
+ state.rawSet("s", `${state.rawGet("s")}, ${String(value)}`);
}
return state;
}),
diff --git a/client/space_lua/aggregates.ts b/client/space_lua/aggregates.ts
index 96b47198..6046fbd3 100644
--- a/client/space_lua/aggregates.ts
+++ b/client/space_lua/aggregates.ts
@@ -119,7 +119,6 @@ const noCtx = {};
function buildAggCtx(name: string): LuaTable {
const ctx = new LuaTable();
ctx.rawSet("name", name);
- // @ts-ignore: Hack to access client via the browser
const clientConfig = globalThis.client?.config;
const aggConfig = clientConfig
? clientConfig.get(`aggregateConfig.${name}`, {})
@@ -129,7 +128,6 @@ function buildAggCtx(name: string): LuaTable {
}
export function getAggregateSpec(name: string): AggregateSpec | null {
- // @ts-ignore: Hack to access client via the browser
const clientConfig = globalThis.client?.config;
if (clientConfig) {
const spec: any = clientConfig.get(`aggregates.${name}`, null);
diff --git a/client/space_lua/eval.ts b/client/space_lua/eval.ts
index 94cd1741..fb933482 100644
--- a/client/space_lua/eval.ts
+++ b/client/space_lua/eval.ts
@@ -176,14 +176,6 @@ function blockMetaOrThrow(
}
}
-// Queryable guard to avoid `(collection as any).query` usage
-type Queryable = {
- query: (
- q: LuaCollectionQuery,
- env: LuaEnv,
- sf: LuaStackFrame,
- ) => Promise;
-};
function arithVerbFromOperator(op: string): string | null {
switch (op) {
@@ -1427,9 +1419,9 @@ function evalExpressions(
}
type EvalBlockResult =
- | void
+ | undefined
| ControlSignal
- | Promise;
+ | Promise;
function runStatementsNoGoto(
stmts: LuaStatement[],
@@ -1437,10 +1429,10 @@ function runStatementsNoGoto(
sf: LuaStackFrame,
returnOnReturn: boolean,
startIdx: number,
-): void | ControlSignal | Promise {
+): undefined | ControlSignal | Promise {
const processFrom = (
idx: number,
- ): void | ControlSignal | Promise => {
+ ): undefined | ControlSignal | Promise => {
for (let i = idx; i < stmts.length; i++) {
const result = evalStatement(
stmts[i],
@@ -1638,7 +1630,7 @@ export function evalStatement(
env: LuaEnv,
sf: LuaStackFrame,
returnOnReturn = false,
-): void | ControlSignal | Promise {
+): undefined | ControlSignal | Promise {
switch (s.type) {
case "Assignment": {
const a = asAssignment(s);
@@ -1790,7 +1782,7 @@ export function evalStatement(
return rpThen(rp, onValue) as any;
};
- return runFrom(0);
+ return runFrom(0) as undefined | Promise;
}
case "Semicolon": {
return;
@@ -1843,9 +1835,9 @@ export function evalStatement(
const runFrom = (
i: number,
):
- | void
+ | undefined
| ControlSignal
- | Promise => {
+ | Promise => {
if (i >= conds.length) {
if (iff.elseBlock) {
return evalStatement(iff.elseBlock, env, sf, returnOnReturn);
@@ -1872,7 +1864,7 @@ export function evalStatement(
case "While": {
const w = asWhile(s);
- const runAsync = async (): Promise => {
+ const runAsync = async (): Promise => {
while (true) {
const c = await evalExpression(w.condition, env, sf);
if (!luaTruthy(c)) {
@@ -1897,7 +1889,6 @@ export function evalStatement(
if (!luaTruthy(cv)) {
return;
}
- try {
const r = evalStatement(w.block, env, sf, returnOnReturn);
if (isPromise(r)) {
return (r as Promise).then((res) => {
@@ -1917,9 +1908,6 @@ export function evalStatement(
return r;
}
return runAsync();
- } catch (e: any) {
- throw e;
- }
});
}
if (!luaTruthy(c)) {
@@ -1949,7 +1937,7 @@ export function evalStatement(
case "Repeat": {
const r = asRepeat(s);
- const runAsync = async (): Promise => {
+ const runAsync = async (): Promise => {
while (true) {
const rr = evalStatement(r.block, env, sf, returnOnReturn);
const res = isPromise(rr) ? await rr : rr;
@@ -2118,7 +2106,7 @@ export function evalStatement(
loopEnv: LuaEnv,
i: number,
loopType: NumericType,
- ): void | ControlSignal | Promise => {
+ ): undefined | ControlSignal | Promise => {
loopEnv.setLocal(fr.name, wrapLoopVar(i, loopType));
return evalStatement(fr.block, loopEnv, sf, returnOnReturn);
}
@@ -2126,7 +2114,7 @@ export function evalStatement(
_loopEnv: LuaEnv,
i: number,
loopType: NumericType,
- ): void | ControlSignal | Promise => {
+ ): undefined | ControlSignal | Promise => {
const localEnv = new LuaEnv(env);
localEnv.setLocal(fr.name, wrapLoopVar(i, loopType));
return evalStatement(fr.block, localEnv, sf, returnOnReturn);
@@ -2165,9 +2153,9 @@ export function evalStatement(
step: number,
loopType: NumericType,
):
- | void
+ | undefined
| ControlSignal
- | Promise => {
+ | Promise => {
if (step === 0) {
throw new LuaRuntimeError("'for' step is zero", sf.withCtx(fr.ctx));
}
diff --git a/client/space_lua/labels.ts b/client/space_lua/labels.ts
index 18671f34..d4368b2e 100644
--- a/client/space_lua/labels.ts
+++ b/client/space_lua/labels.ts
@@ -122,7 +122,7 @@ function resolveFunction(root: LuaBlock): FunctionMeta {
while (searchBlock) {
const meta = blockMeta.get(searchBlock);
- if (meta && meta.labels.has(target)) {
+ if (meta?.labels.has(target)) {
labelIndex = meta.labels.get(target);
labelDefBlock = searchBlock;
break;
diff --git a/client/space_lua/lua.test.ts b/client/space_lua/lua.test.ts
index a225c479..2f6e511f 100644
--- a/client/space_lua/lua.test.ts
+++ b/client/space_lua/lua.test.ts
@@ -3,9 +3,9 @@ import { parse } from "./parse.ts";
import { luaBuildStandardEnv } from "./stdlib.ts";
import { LuaEnv, LuaRuntimeError, LuaStackFrame } from "./runtime.ts";
import { evalStatement } from "./eval.ts";
-import { readFile, readdir } from "node:fs/promises";
+import { readFile, } from "node:fs/promises";
import { fileURLToPath } from "node:url";
-import { dirname, join } from "node:path";
+import { dirname, } from "node:path";
import { readdirSync } from "node:fs";
const __dirname = dirname(fileURLToPath(import.meta.url));
diff --git a/client/space_lua/parse.test.ts b/client/space_lua/parse.test.ts
index 403d4d33..f6279b25 100644
--- a/client/space_lua/parse.test.ts
+++ b/client/space_lua/parse.test.ts
@@ -16,21 +16,15 @@ test("Test Lua parser", () => {
parse(`e([[hel]lo]], "Grinny face\\u{1F600}")`);
parse(`e([=[Hello page [[index]] end scene]=], [[yo]])`);
- // console.log(
- // JSON.stringify(
- parse(`e([==[Hello page [[index]] end scene]==], [==[yo]==])`),
- // null,
- // 2,
- // ),
- // );
- console.log(
- JSON.stringify(
- parse(`e([==[Hello page [[bla]]
+ parse(`e([==[Hello page [[index]] end scene]==], [==[yo]==])`);
+ console.log(
+ JSON.stringify(
+ parse(`e([==[Hello page [[bla]]
]==])`),
- null,
- 2,
- ),
- );
+ null,
+ 2,
+ ),
+ );
parse(`e(10 << 10, 10 >> 10, 10 & 10, 10 | 10, 10 ~ 10)`);
@@ -162,7 +156,8 @@ test("Test numeric constant parsing", () => {
expect((parseExpressionString(`0xBEBADA`) as LuaNumberLiteral).value).toEqual(0xBEBADA,
);
expect((parseExpressionString(`3.0`) as LuaNumberLiteral).value).toEqual(3.0);
- expect((parseExpressionString(`3.1416`) as LuaNumberLiteral).value).toEqual(3.1416,
+ expect((parseExpressionString(`3.1416`) as LuaNumberLiteral).value)// biome-ignore lint/suspicious/noApproximativeNumericConstant: testing exact value 3.1416, not Math.PI
+ .toEqual(3.1416,
);
expect((parseExpressionString(`314.16e-2`) as LuaNumberLiteral).value).toEqual(314.16e-2,
);
diff --git a/client/space_lua/parse.ts b/client/space_lua/parse.ts
index ac60d417..17133111 100644
--- a/client/space_lua/parse.ts
+++ b/client/space_lua/parse.ts
@@ -4,7 +4,7 @@ import {
cleanTree,
type ParseTree,
} from "@silverbulletmd/silverbullet/lib/tree";
-// @ts-ignore - Local generated JavaScript file without type definitions
+// @ts-expect-error - Local generated JavaScript file without type definitions
import { parser } from "./parse-lua.js";
import { styleTags, tags as t } from "@lezer/highlight";
import { indentNodeProp, LRLanguage } from "@codemirror/language";
@@ -586,7 +586,7 @@ function parseBlock(t: ParseTree, ctx: ASTCtx): LuaBlock {
if (t.type !== "Block") {
throw new Error(`Expected Block, got ${t.type}`);
}
- const stmtNodes = t.children!.filter((c) => c && c.type);
+ const stmtNodes = t.children!.filter((c) => c?.type);
const statements = stmtNodes.map((s) => parseStatement(s, ctx));
const block: LuaBlock = { type: "Block", statements, ctx: context(t, ctx) };
@@ -814,7 +814,7 @@ function parseStatement(t: ParseTree, ctx: ASTCtx): LuaStatement {
from?: number;
to?: number;
}[] = [];
- let elseBlock: LuaBlock | undefined = undefined;
+ let elseBlock: LuaBlock | undefined ;
for (let i = 0; i < t.children!.length; i += 4) {
const child = t.children![i];
if (!child || !child.children || !child.children[0]) {
@@ -949,7 +949,7 @@ function parseStatement(t: ParseTree, ctx: ASTCtx): LuaStatement {
console.error(t);
throw new Error(
`Unknown statement type: ${
- t.children![0] && t.children![0].text
+ t.children![0]?.text
? t.children![0].text
: String(t.type)
}`,
@@ -1044,7 +1044,7 @@ function parseFunctionName(t: ParseTree, ctx: ASTCtx): LuaFunctionName {
throw new Error(`Expected FunctionName, got ${t.type}`);
}
const propNames: string[] = [];
- let colonName: string | undefined = undefined;
+ let colonName: string | undefined ;
for (let i = 0; i < t.children!.length; i += 2) {
const prop = t.children![i];
propNames.push(prop.children![0].text!);
@@ -1152,8 +1152,9 @@ function parseExpression(t: ParseTree, ctx: ASTCtx): LuaExpression {
return {
type: "Number",
// Use the integer parser fox 0x literals
+ // biome-ignore lint/correctness/useParseIntRadix: hex strings need auto-detect radix
value: text.includes("x") ? parseInt(text) : parseFloat(text),
- numericType: /[\.eEpP]/.test(text) ? "float" : "int",
+ numericType: /[.eEpP]/.test(text) ? "float" : "int",
ctx: context(t, ctx),
};
}
@@ -1475,7 +1476,7 @@ export function stripLuaComments(s: string): string {
if (s[j] === "[") {
// Found long string start
const openBracket = s.substring(i, j + 1);
- const closeBracket = "]" + "=".repeat(equalsCount) + "]";
+ const closeBracket = `]${"=".repeat(equalsCount)}]`;
result += openBracket;
i = j + 1;
@@ -1528,7 +1529,7 @@ export function stripLuaComments(s: string): string {
}
if (s[j] === "[") {
// Found long comment start
- const closeBracket = "]" + "=".repeat(equalsCount) + "]";
+ const closeBracket = `]${"=".repeat(equalsCount)}]`;
// Replace opening bracket with spaces
result += " ".repeat(j - i + 1);
i = j + 1;
diff --git a/client/space_lua/query_collection.test.ts b/client/space_lua/query_collection.test.ts
index 30888b3d..68c086bb 100644
--- a/client/space_lua/query_collection.test.ts
+++ b/client/space_lua/query_collection.test.ts
@@ -4,7 +4,6 @@ import { ArrayQueryCollection } from "./query_collection.ts";
import {
LuaEnv,
LuaNativeJSFunction,
- LuaRuntimeError,
LuaStackFrame,
} from "./runtime.ts";
@@ -13,7 +12,7 @@ test("ArrayQueryCollection", async () => {
rootEnv.setLocal(
"build_name",
new LuaNativeJSFunction((a, b) => {
- return Promise.resolve(a + " " + b);
+ return Promise.resolve(`${a} ${b}`);
}),
);
diff --git a/client/space_lua/query_collection.ts b/client/space_lua/query_collection.ts
index 9713fc19..a823c059 100644
--- a/client/space_lua/query_collection.ts
+++ b/client/space_lua/query_collection.ts
@@ -815,7 +815,6 @@ export async function applyQuery(
if (query.orderBy) {
if (collation === undefined) {
- // @ts-ignore: Hack to access client via the browser
const config = globalThis.client.config;
collation = config.get("queryCollation", {});
}
diff --git a/client/space_lua/runtime.ts b/client/space_lua/runtime.ts
index c621860c..098dcc19 100644
--- a/client/space_lua/runtime.ts
+++ b/client/space_lua/runtime.ts
@@ -128,7 +128,7 @@ export function luaIsCallable(
}
if (v instanceof LuaTable) {
const mt = getMetatable(v, sf);
- if (mt && mt.has("__call")) {
+ if (mt?.has("__call")) {
const mm = mt.get("__call", sf);
return !!mm && (typeof mm === "function" || isILuaFunction(mm));
}
@@ -614,7 +614,7 @@ export class LuaTable implements ILuaSettable, ILuaGettable {
if (init && !Array.isArray(init)) {
for (const k in init) {
- if (Object.prototype.hasOwnProperty.call(init, k)) {
+ if (Object.hasOwn(init, k)) {
this.stringKeys[k] = (init as any)[k];
}
}
@@ -689,7 +689,7 @@ export class LuaTable implements ILuaSettable, ILuaGettable {
keys(): any[] {
const keys: any[] = [];
for (const k in this.stringKeys) {
- if (Object.prototype.hasOwnProperty.call(this.stringKeys, k)) {
+ if (Object.hasOwn(this.stringKeys, k)) {
keys.push(k);
}
}
@@ -706,7 +706,7 @@ export class LuaTable implements ILuaSettable, ILuaGettable {
empty(): boolean {
for (const k in this.stringKeys) {
- if (Object.prototype.hasOwnProperty.call(this.stringKeys, k)) {
+ if (Object.hasOwn(this.stringKeys, k)) {
return false;
}
}
@@ -934,7 +934,7 @@ export class LuaTable implements ILuaSettable, ILuaGettable {
);
}
- if (typeof key === "number" && isNaN(key)) {
+ if (typeof key === "number" && Number.isNaN(key)) {
throw new LuaRuntimeError(
"table index is NaN",
errSf,
@@ -1135,9 +1135,9 @@ export class LuaTable implements ILuaSettable, ILuaGettable {
if (typeof key === "string") {
result += key;
} else {
- result += "[" + key + "]";
+ result += `[${key}]`;
}
- result += " = " + await luaToString(this.get(key));
+ result += ` = ${await luaToString(this.get(key))}`;
}
result += "}";
return result;
@@ -1492,7 +1492,7 @@ export class LuaRuntimeError extends Error {
);
// Add position indicator
- const pointer = " ".repeat(column) + "^";
+ const pointer = `${" ".repeat(column)}^`;
traceStr += `* ${ctx.ref || "(unknown source)"} @ ${line}:${column}:\n` +
` ${codeLine}\n` +
@@ -1579,7 +1579,7 @@ export function luaToString(
const strVal = await luaToString(val, visited);
result += strVal;
}
- return result + "}";
+ return `${result}}`;
}
// Handle objects
@@ -1606,7 +1606,7 @@ export function luaToString(
}
export function luaFormatNumber(n: number, kind?: "int" | "float"): string {
- if (kind !== "float" && Number.isInteger(n) && isFinite(n)) {
+ if (kind !== "float" && Number.isInteger(n) && Number.isFinite(n)) {
return String(n);
}
if (n !== n) return "-nan";
@@ -1619,7 +1619,7 @@ export function luaFormatNumber(n: number, kind?: "int" | "float"): string {
const s = luaFormat("%.14g", n);
// Guarantee `.01 suffix for integer-valued floats
if (s.indexOf(".") === -1 && s.indexOf("e") === -1) {
- return s + ".0";
+ return `${s}.0`;
}
return s;
}
diff --git a/client/space_lua/stdlib.ts b/client/space_lua/stdlib.ts
index 0d7ec5ab..3837106c 100644
--- a/client/space_lua/stdlib.ts
+++ b/client/space_lua/stdlib.ts
@@ -450,7 +450,7 @@ const nextFunction = new LuaBuiltinFunction(
const someFunction = new LuaBuiltinFunction(async (_sf, value: any) => {
switch (await luaTypeOf(value)) {
case "number":
- if (!isFinite(value)) return null;
+ if (!Number.isFinite(value)) return null;
break;
case "string":
if (value.trim() === "") return null;
diff --git a/client/space_lua/stdlib/format.ts b/client/space_lua/stdlib/format.ts
index a4cb3489..7b7f73ac 100644
--- a/client/space_lua/stdlib/format.ts
+++ b/client/space_lua/stdlib/format.ts
@@ -128,8 +128,8 @@ function pad(s: string, width: number, flags: number, numPad: boolean): string {
}
function addSign(s: string, flags: number): string {
- if (flags & FLAG_PLUS) return "+" + s;
- if (flags & FLAG_SPACE) return " " + s;
+ if (flags & FLAG_PLUS) return `+${s}`;
+ if (flags & FLAG_SPACE) return ` ${s}`;
return s;
}
@@ -200,7 +200,7 @@ function formatInt(n: number, spec: FormatSpec): string {
let result: string;
if (neg) {
- result = "-" + prefix + digits;
+ result = `-${prefix}${digits}`;
} else {
result = addSign(prefix + digits, spec.flags);
}
@@ -216,7 +216,7 @@ function formatFloat(n: number, spec: FormatSpec): string {
const lower = code | 32; // to lowercase
// Lua convention
- if (!isFinite(n)) {
+ if (!Number.isFinite(n)) {
let s: string;
if (n !== n) {
s = upper ? "-NAN" : "-nan";
@@ -275,9 +275,9 @@ function formatFloat(n: number, spec: FormatSpec): string {
const EIdx = body.indexOf("E");
const expIdx = eIdx !== -1 ? eIdx : EIdx;
if (expIdx !== -1) {
- body = body.slice(0, expIdx) + "." + body.slice(expIdx);
+ body = `${body.slice(0, expIdx)}.${body.slice(expIdx)}`;
} else {
- body = body + ".";
+ body = `${body}.`;
}
}
}
@@ -287,16 +287,16 @@ function formatFloat(n: number, spec: FormatSpec): string {
if (body.indexOf(".") === -1) {
const expIdx = findExpIndex(body);
if (expIdx !== -1) {
- body = body.slice(0, expIdx) + "." + body.slice(expIdx);
+ body = `${body.slice(0, expIdx)}.${body.slice(expIdx)}`;
} else {
- body = body + ".";
+ body = `${body}.`;
}
}
}
let result: string;
if (neg) {
- result = "-" + body;
+ result = `-${body}`;
} else {
result = addSign(body, spec.flags);
}
@@ -322,7 +322,7 @@ function ensureExpTwoDigits(s: string): string {
const digitStart = signIdx + 1;
const expLen = s.length - digitStart;
if (expLen < 2) {
- return s.slice(0, digitStart) + "0" + s.slice(digitStart);
+ return `${s.slice(0, digitStart)}0${s.slice(digitStart)}`;
}
return s;
}
@@ -353,7 +353,7 @@ function formatHexFloat(n: number, spec: FormatSpec): string {
const code = spec.spec;
const upper = code === 65; // 'A'
- if (!isFinite(n)) {
+ if (!Number.isFinite(n)) {
let s: string;
if (n !== n) {
s = upper ? "-NAN" : "-nan";
@@ -373,7 +373,7 @@ function formatHexFloat(n: number, spec: FormatSpec): string {
if (abs === 0) {
const prec = spec.hasPrec ? spec.prec : 0;
if (prec > 0) {
- body = "0x0." + "0".repeat(prec) + "p+0";
+ body = `0x0.${"0".repeat(prec)}p+0`;
} else {
body = "0x0p+0";
}
@@ -395,14 +395,14 @@ function formatHexFloat(n: number, spec: FormatSpec): string {
}
}
if (!hasDot) {
- body = body.slice(0, pIdx) + "." + body.slice(pIdx);
+ body = `${body.slice(0, pIdx)}.${body.slice(pIdx)}`;
}
}
}
let result: string;
if (neg) {
- result = "-" + body;
+ result = `-${body}`;
} else {
result = addSign(body, spec.flags);
}
@@ -474,9 +474,9 @@ function hexFloatBody(abs: number, spec: FormatSpec): string {
const expSign = exponent >= 0 ? "+" : "";
if (fracHex.length > 0) {
- return "0x" + firstDigit + "." + fracHex + "p" + expSign + exponent;
+ return `0x${firstDigit}.${fracHex}p${expSign}${exponent}`;
}
- return "0x" + firstDigit + "p" + expSign + exponent;
+ return `0x${firstDigit}p${expSign}${exponent}`;
}
// Convert 52-bit value to 13 hex digits, zero-padded
@@ -581,7 +581,7 @@ function quoteString(s: string): string {
if (ds.length < 3) out += "0".repeat(3 - ds.length);
out += ds;
} else {
- out += "\\" + c.toString();
+ out += `\\${c.toString()}`;
}
} else {
out += String.fromCharCode(c);
@@ -643,7 +643,7 @@ function toPointer(v: unknown): string {
id = nextId++;
stringIds.set(key, id);
}
- return "0x" + id.toString(16).padStart(14, "0");
+ return `0x${id.toString(16).padStart(14, "0")}`;
}
const obj = v as object;
@@ -652,7 +652,7 @@ function toPointer(v: unknown): string {
id = nextId++;
objectIds.set(obj, id);
}
- return "0x" + id.toString(16).padStart(14, "0");
+ return `0x${id.toString(16).padStart(14, "0")}`;
}
function formatPointer(v: unknown, spec: FormatSpec): string {
diff --git a/client/space_lua/stdlib/math.ts b/client/space_lua/stdlib/math.ts
index 90c8f801..df113a9b 100644
--- a/client/space_lua/stdlib/math.ts
+++ b/client/space_lua/stdlib/math.ts
@@ -52,15 +52,15 @@ export const mathApi = new LuaTable({
*/
tointeger: new LuaBuiltinFunction((_sf, x?: any) => {
if (typeof x === "number") {
- return Number.isInteger(x) && isFinite(x) ? x : null;
+ return Number.isInteger(x) && Number.isFinite(x) ? x : null;
}
if (isTaggedFloat(x)) {
const n = x.value;
- return Number.isInteger(n) && isFinite(n) ? n : null;
+ return Number.isInteger(n) && Number.isFinite(n) ? n : null;
}
if (typeof x === "string") {
const n = untagNumber(x); // Number(x) coerces the string
- if (isNaN(n) || !isFinite(n) || !Number.isInteger(n)) return null;
+ if (Number.isNaN(n) || !Number.isFinite(n) || !Number.isInteger(n)) return null;
return n;
}
return null;
@@ -123,12 +123,12 @@ export const mathApi = new LuaTable({
// Special cases: frexp(0) = (0, 0); frexp(+-inf/nan) = (x, 0).
frexp: new LuaBuiltinFunction((_sf, x: number) => {
const xn = untagNumber(x);
- if (xn === 0 || !isFinite(xn) || isNaN(xn)) {
+ if (xn === 0 || !Number.isFinite(xn) || Number.isNaN(xn)) {
return new LuaMultiRes([xn, 0]);
}
const abs = Math.abs(xn);
let e = Math.floor(Math.log2(abs)) + 1;
- let m = xn / Math.pow(2, e);
+ let m = xn / 2 ** e;
if (Math.abs(m) >= 1.0) {
e += 1;
m /= 2;
@@ -142,7 +142,7 @@ export const mathApi = new LuaTable({
// Returns m * 2^e (the inverse of frexp). Mirrors C99/Lua.
ldexp: new LuaBuiltinFunction((_sf, m: number, e: number) =>
- untagNumber(m) * Math.pow(2, untagNumber(e))
+ untagNumber(m) * 2 ** untagNumber(e)
),
// Power and logarithms
@@ -155,7 +155,7 @@ export const mathApi = new LuaTable({
}),
// Power function (deprecated in Lua 5.4 but retained for compatibility)
pow: new LuaBuiltinFunction((_sf, x: number, y: number) =>
- Math.pow(untagNumber(x), untagNumber(y))
+ untagNumber(x) ** untagNumber(y)
),
sqrt: new LuaBuiltinFunction((_sf, x: number) => Math.sqrt(untagNumber(x))),
diff --git a/client/space_lua/stdlib/net.ts b/client/space_lua/stdlib/net.ts
index d79de4e8..8927168f 100644
--- a/client/space_lua/stdlib/net.ts
+++ b/client/space_lua/stdlib/net.ts
@@ -66,7 +66,7 @@ export const netApi = new LuaTable({
(uri: string, options: { uri?: string; encoding?: string } = {}) => {
options.uri = uri;
return client.clientSystem.serviceRegistry.invokeBestMatch(
- "net.readURI:" + uri,
+ `net.readURI:${uri}`,
options,
);
},
@@ -74,7 +74,7 @@ export const netApi = new LuaTable({
writeURI: new LuaNativeJSFunction(
(uri: string, content: string | Uint8Array) => {
return client.clientSystem.serviceRegistry.invokeBestMatch(
- "net.writeURI:" + uri,
+ `net.writeURI:${uri}`,
{ uri, content },
);
},
diff --git a/client/space_lua/stdlib/pattern.ts b/client/space_lua/stdlib/pattern.ts
index 795ddfc6..c4c5fce7 100644
--- a/client/space_lua/stdlib/pattern.ts
+++ b/client/space_lua/stdlib/pattern.ts
@@ -409,7 +409,6 @@ function match(ms: MatchState, si: number, pi: number): number {
}
si++;
pi = ep;
- continue;
}
}
diff --git a/client/space_lua/stdlib/prng.ts b/client/space_lua/stdlib/prng.ts
index ecb9d51e..82301866 100644
--- a/client/space_lua/stdlib/prng.ts
+++ b/client/space_lua/stdlib/prng.ts
@@ -92,7 +92,7 @@ export class LuaPRNG {
return Number(rv >> 11n) * (1.0 / 9007199254740992.0);
}
- if (!isFinite(arg1) || !Number.isInteger(arg1)) {
+ if (!Number.isFinite(arg1) || !Number.isInteger(arg1)) {
throw new Error(
"bad argument #1 to 'random' (number has no integer representation)",
);
@@ -112,7 +112,7 @@ export class LuaPRNG {
return Number(this.project(rv, BigInt(arg1) - 1n) + 1n);
}
- if (!isFinite(arg2) || !Number.isInteger(arg2)) {
+ if (!Number.isFinite(arg2) || !Number.isInteger(arg2)) {
throw new Error(
"bad argument #2 to 'random' (number has no integer representation)",
);
@@ -128,12 +128,12 @@ export class LuaPRNG {
if (arg1 === undefined) {
return this.autoSeed();
}
- if (!isFinite(arg1) || !Number.isInteger(arg1)) {
+ if (!Number.isFinite(arg1) || !Number.isInteger(arg1)) {
throw new Error(
"bad argument #1 to 'randomseed' (number has no integer representation)",
);
}
- if (arg2 !== undefined && (!isFinite(arg2) || !Number.isInteger(arg2))) {
+ if (arg2 !== undefined && (!Number.isFinite(arg2) || !Number.isInteger(arg2))) {
throw new Error(
"bad argument #2 to 'randomseed' (number has no integer representation)",
);
diff --git a/client/space_lua/tonumber.ts b/client/space_lua/tonumber.ts
index 3f790d18..4e3e421f 100644
--- a/client/space_lua/tonumber.ts
+++ b/client/space_lua/tonumber.ts
@@ -283,7 +283,7 @@ function parseDecFloat(s: string): { ok: boolean; value: number } {
return { ok: false, value: 0 };
}
- const result = sign * (hasExp ? val * Math.pow(10, exp) : val);
+ const result = sign * (hasExp ? val * 10 ** exp : val);
return { ok: true, value: result };
}
@@ -434,7 +434,7 @@ function parseHexFloat(s: string): { ok: boolean; value: number } {
}
const frac = fracVal === 0 ? 0 : (fracVal / fracScale);
- const result = sign * (intVal + frac) * Math.pow(2, expSign * exp);
+ const result = sign * (intVal + frac) * 2 ** (expSign * exp);
return { ok: true, value: result };
}
@@ -460,6 +460,7 @@ export function luaToNumberDetailed(
}
{
+ // biome-ignore lint/correctness/useParseIntRadix: local parseInt function, not global
const parsed = parseInt(s);
if (parsed.ok) {
const v = parsed.value;
diff --git a/client/space_lua_api.ts b/client/space_lua_api.ts
index d3cc0d96..3d1323fe 100644
--- a/client/space_lua_api.ts
+++ b/client/space_lua_api.ts
@@ -75,7 +75,7 @@ export async function handleLuaError(e: LuaRuntimeError, system: System) {
e.message,
e.sf?.astCtx,
);
- if (e.sf?.astCtx && e.sf.astCtx.ref) {
+ if (e.sf?.astCtx?.ref) {
// We got an error and actually know where it came from, let's navigate there to help debugging
await system.localSyscall(
"editor.flashNotification",
diff --git a/client/spaces/datastore_space_primitives.test.ts b/client/spaces/datastore_space_primitives.test.ts
index 41706d37..ab7c675b 100644
--- a/client/spaces/datastore_space_primitives.test.ts
+++ b/client/spaces/datastore_space_primitives.test.ts
@@ -1,4 +1,4 @@
-import { expect, test } from "vitest";
+import { test } from "vitest";
import "fake-indexeddb/auto";
import { IndexedDBKvPrimitives } from "../data/indexeddb_kv_primitives.ts";
import { DataStoreSpacePrimitives } from "./datastore_space_primitives.ts";
diff --git a/client/spaces/http_space_primitives.ts b/client/spaces/http_space_primitives.ts
index ca562cdb..f77235d8 100644
--- a/client/spaces/http_space_primitives.ts
+++ b/client/spaces/http_space_primitives.ts
@@ -189,9 +189,9 @@ export class HttpSpacePrimitives implements SpacePrimitives {
"Content-Type": "application/octet-stream",
};
if (meta) {
- headers["X-Created"] = "" + meta.created;
- headers["X-Last-Modified"] = "" + meta.lastModified;
- headers["X-Perm"] = "" + meta.perm;
+ headers["X-Created"] = `${meta.created}`;
+ headers["X-Last-Modified"] = `${meta.lastModified}`;
+ headers["X-Perm"] = `${meta.perm}`;
}
const res = await this.authenticatedFetch(
diff --git a/client/spaces/sync.test.ts b/client/spaces/sync.test.ts
index d17bafd8..991e1848 100644
--- a/client/spaces/sync.test.ts
+++ b/client/spaces/sync.test.ts
@@ -1,7 +1,6 @@
import { expect, test } from "vitest";
import { SpaceSync, SyncSnapshot } from "./sync.ts";
import { sleep } from "@silverbulletmd/silverbullet/lib/async";
-import { assert } from "node:console";
import { MemoryKvPrimitives } from "../data/memory_kv_primitives.ts";
import { DataStoreSpacePrimitives } from "./datastore_space_primitives.ts";
diff --git a/client/spaces/sync.ts b/client/spaces/sync.ts
index 743191ea..66d7b0c9 100644
--- a/client/spaces/sync.ts
+++ b/client/spaces/sync.ts
@@ -55,8 +55,6 @@ export type SyncOptions = {
isSyncCandidate: (path: string) => boolean;
};
-type SyncDirection = "primary->secondary" | "secondary->primary";
-
export type SyncEvents = {
syncProgress: (
syncStatus: SyncStatus,
@@ -150,7 +148,7 @@ export class SpaceSync extends EventEmitter {
"Completed:",
operations,
"operations in",
- ((Date.now() - startTime) / 1000) + "s",
+ `${(Date.now() - startTime) / 1000}s`,
);
} finally {
this.isSyncing = false;
diff --git a/package-lock.json b/package-lock.json
index 722d4a92..3276198f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -54,6 +54,7 @@
"plug-compile": "dist/plug-compile.js"
},
"devDependencies": {
+ "@biomejs/biome": "2.4.6",
"@preact/preset-vite": "^2.10.3",
"@types/gitignore-parser": "^0.0.3",
"@types/js-yaml": "^4.0.9",
@@ -67,7 +68,7 @@
"vitest": "^4.0.18"
},
"engines": {
- "node": ">=24.0.0",
+ "node": ">=24.13.0",
"npm": ">=10.0.0"
}
},
@@ -386,6 +387,169 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@biomejs/biome": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.4.6.tgz",
+ "integrity": "sha512-QnHe81PMslpy3mnpL8DnO2M4S4ZnYPkjlGCLWBZT/3R9M6b5daArWMMtEfP52/n174RKnwRIf3oT8+wc9ihSfQ==",
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "bin": {
+ "biome": "bin/biome"
+ },
+ "engines": {
+ "node": ">=14.21.3"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/biome"
+ },
+ "optionalDependencies": {
+ "@biomejs/cli-darwin-arm64": "2.4.6",
+ "@biomejs/cli-darwin-x64": "2.4.6",
+ "@biomejs/cli-linux-arm64": "2.4.6",
+ "@biomejs/cli-linux-arm64-musl": "2.4.6",
+ "@biomejs/cli-linux-x64": "2.4.6",
+ "@biomejs/cli-linux-x64-musl": "2.4.6",
+ "@biomejs/cli-win32-arm64": "2.4.6",
+ "@biomejs/cli-win32-x64": "2.4.6"
+ }
+ },
+ "node_modules/@biomejs/cli-darwin-arm64": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.4.6.tgz",
+ "integrity": "sha512-NW18GSyxr+8sJIqgoGwVp5Zqm4SALH4b4gftIA0n62PTuBs6G2tHlwNAOj0Vq0KKSs7Sf88VjjmHh0O36EnzrQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-darwin-x64": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.4.6.tgz",
+ "integrity": "sha512-4uiE/9tuI7cnjtY9b07RgS7gGyYOAfIAGeVJWEfeCnAarOAS7qVmuRyX6d7JTKw28/mt+rUzMasYeZ+0R/U1Mw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-arm64": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.4.6.tgz",
+ "integrity": "sha512-kMLaI7OF5GN1Q8Doymjro1P8rVEoy7BKQALNz6fiR8IC1WKduoNyteBtJlHT7ASIL0Cx2jR6VUOBIbcB1B8pew==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-arm64-musl": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.4.6.tgz",
+ "integrity": "sha512-F/JdB7eN22txiTqHM5KhIVt0jVkzZwVYrdTR1O3Y4auBOQcXxHK4dxULf4z43QyZI5tsnQJrRBHZy7wwtL+B3A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-x64": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.4.6.tgz",
+ "integrity": "sha512-oHXmUFEoH8Lql1xfc3QkFLiC1hGR7qedv5eKNlC185or+o4/4HiaU7vYODAH3peRCfsuLr1g6v2fK9dFFOYdyw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-linux-x64-musl": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.4.6.tgz",
+ "integrity": "sha512-C9s98IPDu7DYarjlZNuzJKTjVHN03RUnmHV5htvqsx6vEUXCDSJ59DNwjKVD5XYoSS4N+BYhq3RTBAL8X6svEg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-win32-arm64": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.4.6.tgz",
+ "integrity": "sha512-xzThn87Pf3YrOGTEODFGONmqXpTwUNxovQb72iaUOdcw8sBSY3+3WD8Hm9IhMYLnPi0n32s3L3NWU6+eSjfqFg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
+ "node_modules/@biomejs/cli-win32-x64": {
+ "version": "2.4.6",
+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.4.6.tgz",
+ "integrity": "sha512-7++XhnsPlr1HDbor5amovPjOH6vsrFOCdp93iKXhFn6bcMUI6soodj3WWKfgEO6JosKU1W5n3uky3WW9RlRjTg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT OR Apache-2.0",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=14.21.3"
+ }
+ },
"node_modules/@codemirror/autocomplete": {
"version": "6.20.0",
"resolved": "https://registry.npmjs.org/@codemirror/autocomplete/-/autocomplete-6.20.0.tgz",
diff --git a/package.json b/package.json
index 1475e7ca..8b5eb0d9 100644
--- a/package.json
+++ b/package.json
@@ -58,6 +58,7 @@
"prepublishOnly": "npm run build:plug-compile",
"test": "vitest run",
"check": "tsc --noEmit",
+ "lint": "biome lint .",
"bench": "vitest bench"
},
"dependencies": {
@@ -104,6 +105,7 @@
"turndown": "7.2.2"
},
"devDependencies": {
+ "@biomejs/biome": "2.4.6",
"@preact/preset-vite": "^2.10.3",
"@types/gitignore-parser": "^0.0.3",
"@types/js-yaml": "^4.0.9",
diff --git a/plug-api/lib/async.ts b/plug-api/lib/async.ts
index 380b44e0..42a7b9c2 100644
--- a/plug-api/lib/async.ts
+++ b/plug-api/lib/async.ts
@@ -1,6 +1,6 @@
export function throttle(func: () => void, limit: number): () => void {
let timer: any = null;
- return function () {
+ return () => {
if (!timer) {
timer = setTimeout(() => {
func();
@@ -15,7 +15,7 @@ export function throttleImmediately(
limit: number,
): () => void {
let timer: any = null;
- return function () {
+ return () => {
if (!timer) {
func();
timer = setTimeout(() => {
diff --git a/plug-api/lib/dates.test.ts b/plug-api/lib/dates.test.ts
index f945ed1e..63958a4a 100644
--- a/plug-api/lib/dates.test.ts
+++ b/plug-api/lib/dates.test.ts
@@ -1,4 +1,4 @@
-import { expect, test } from "vitest";
+import { test } from "vitest";
import { localDateString } from "./dates.ts";
test("Dates", () => {
diff --git a/plug-api/lib/json.ts b/plug-api/lib/json.ts
index 7c4a6564..1fadfc1c 100644
--- a/plug-api/lib/json.ts
+++ b/plug-api/lib/json.ts
@@ -125,7 +125,7 @@ export function deepClone(obj: T, ignoreKeys: string[] = []): T {
for (const key in obj) {
if (ignoreKeys.includes(key)) {
objClone[key] = obj[key];
- } else if (Object.prototype.hasOwnProperty.call(obj, key)) {
+ } else if (Object.hasOwn(obj, key)) {
objClone[key] = deepClone(obj[key], ignoreKeys);
}
}
diff --git a/plug-api/lib/ref.ts b/plug-api/lib/ref.ts
index bd8ca5fa..800f0b17 100644
--- a/plug-api/lib/ref.ts
+++ b/plug-api/lib/ref.ts
@@ -95,7 +95,7 @@ export function isValidPath(path: string): path is Path {
* TO THE INNER WORKINGS OF SILVERBULLET AND CHANGES COULD INTRODUCE MAJOR BUGS
*/
const refRegex =
- /^(?\^)?(?(?!.*\.[a-zA-Z0-9]+\.md$)(?!\/?(\.|\^))(?!.*(?:\/|^)\.{1,2}(?:\/|$)|.*\/{2})(?!.*(?:\]\]|\[\[))[^@#\|<>]*)(@(?\d+)|@[Ll](?\d+)(?:[Cc](?\d+))?|#\s*(?.*))?$/;
+ /^(?\^)?(?(?!.*\.[a-zA-Z0-9]+\.md$)(?!\/?(\.|\^))(?!.*(?:\/|^)\.{1,2}(?:\/|$)|.*\/{2})(?!.*(?:\]\]|\[\[))[^@#|<>]*)(@(?\d+)|@[Ll](?\d+)(?:[Cc](?\d+))?|#\s*(?.*))?$/;
/**
* Parses a reference string into a ref object.
@@ -118,13 +118,13 @@ export function parseToRef(stringRef: string): Ref | null {
if (groups.pos !== undefined) {
ref.details = {
type: "position",
- pos: parseInt(groups.pos),
+ pos: parseInt(groups.pos, 10),
};
} else if (groups.line !== undefined) {
ref.details = {
type: "linecolumn",
- line: parseInt(groups.line),
- column: groups.col !== undefined ? parseInt(groups.col) : 1,
+ line: parseInt(groups.line, 10),
+ column: groups.col !== undefined ? parseInt(groups.col, 10) : 1,
};
} else if (groups.header !== undefined) {
ref.details = {
diff --git a/plug-api/lib/transclusion.ts b/plug-api/lib/transclusion.ts
index 78a2e226..b7914681 100644
--- a/plug-api/lib/transclusion.ts
+++ b/plug-api/lib/transclusion.ts
@@ -45,19 +45,19 @@ export function parseDimensionFromAlias(
const [width, height] = dimPart.split("x");
dim = {};
if (width) {
- dim.width = parseInt(width);
+ dim.width = parseInt(width, 10);
}
if (height) {
- dim.height = parseInt(height);
+ dim.height = parseInt(height, 10);
}
} else if (/^[x\d]/.test(text)) {
const [width, height] = text.split("x");
dim = {};
if (width) {
- dim.width = parseInt(width);
+ dim.width = parseInt(width, 10);
}
if (height) {
- dim.height = parseInt(height);
+ dim.height = parseInt(height, 10);
}
alias = "";
} else {
@@ -74,7 +74,7 @@ export function parseDimensionFromAlias(
export function parseTransclusion(
text: string,
): Transclusion | null {
- let url, alias = undefined;
+ let url, alias ;
let linktype: LinkType = "markdownlink";
// TODO: Take in the tree and use tree nodes to get url and alias (Applies to all regex uses)
mdLinkRegex.lastIndex = 0;
diff --git a/plug-api/lib/tree.ts b/plug-api/lib/tree.ts
index 12f2f1cd..99d19da9 100644
--- a/plug-api/lib/tree.ts
+++ b/plug-api/lib/tree.ts
@@ -91,7 +91,7 @@ export function replaceNodesMatching(
tree: ParseTree,
substituteFn: (tree: ParseTree) => ParseTree | null | undefined,
) {
- if (tree && tree.children) {
+ if (tree?.children) {
const children = tree.children.slice();
for (const child of children) {
const subst = substituteFn(child);
diff --git a/plug-api/lib/yaml.ts b/plug-api/lib/yaml.ts
index e96f1b24..ee1aecf1 100644
--- a/plug-api/lib/yaml.ts
+++ b/plug-api/lib/yaml.ts
@@ -44,7 +44,7 @@ function serializeToYamlValue(
return "[]"; // Use flow style for empty arrays for simplicity
}
// Determine indentation for list items (base + 2 spaces)
- const itemIndentation = baseIndentation + " ";
+ const itemIndentation = `${baseIndentation} `;
// Format each item recursively, preceded by '- ' marker
return "\n" +
value.map((item) =>
@@ -55,7 +55,7 @@ function serializeToYamlValue(
} else if (typeof value === "object" && value !== null) {
// Basic object serialization (not requested, but good to consider)
// This is highly simplified and doesn't handle nesting well without more context
- const itemIndentation = baseIndentation + " ";
+ const itemIndentation = `${baseIndentation} `;
const entries = Object.entries(value);
if (entries.length === 0) return "{}"; // Flow style empty objects
return "\n" +
@@ -89,7 +89,7 @@ export function applyPatches(
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const trimmedLine = line.trim();
- if (trimmedLine.startsWith(key + ":")) {
+ if (trimmedLine.startsWith(`${key}:`)) {
keyLineIndex = i;
startDeleteIndex = i;
endDeleteIndex = i;
@@ -203,7 +203,7 @@ export function applyPatches(
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const trimmedLine = line.trim();
- if (trimmedLine.startsWith(key + ":")) {
+ if (trimmedLine.startsWith(`${key}:`)) {
keyLineIndex = i;
// Extract inline comment if present
const commentMatch = line.match(/#.*$/);
@@ -214,7 +214,7 @@ export function applyPatches(
for (let j = i - 1; j >= 0; j--) {
const prevLine = lines[j].trim();
if (prevLine.startsWith("#")) {
- commentBlock = lines[j] + "\n" + commentBlock;
+ commentBlock = `${lines[j]}\n${commentBlock}`;
} else if (prevLine !== "") {
break;
}
@@ -223,7 +223,7 @@ export function applyPatches(
for (let j = i + 1; j < lines.length; j++) {
const nextLine = lines[j].trim();
if (nextLine.startsWith("#")) {
- trailingComments += lines[j] + "\n";
+ trailingComments += `${lines[j]}\n`;
} else if (nextLine !== "") {
break;
}
@@ -243,7 +243,7 @@ export function applyPatches(
} else {
// For scalars, format as key: value
replacementLine = `${key}: ${serializedNewValue}${
- inlineComment ? " " + inlineComment : ""
+ inlineComment ? ` ${inlineComment}` : ""
}`;
}
@@ -267,14 +267,14 @@ export function applyPatches(
];
// Join lines and ensure proper newlines
- currentYaml = newContent.join("\n").replace(/\n*$/, "\n") + "\n";
+ currentYaml = `${newContent.join("\n").replace(/\n*$/, "\n")}\n`;
} else {
// Key not found: Add the new key-value pair to the end
const newLineBlock = replacementLine;
if (currentYaml.trim() === "") {
- currentYaml = newLineBlock + "\n";
+ currentYaml = `${newLineBlock}\n`;
} else {
- currentYaml = currentYaml.replace(/\n*$/, "\n") + newLineBlock + "\n";
+ currentYaml = `${currentYaml.replace(/\n*$/, "\n") + newLineBlock}\n`;
}
}
}
diff --git a/plug-api/system_mock.ts b/plug-api/system_mock.ts
index 9d7276b7..a3cae529 100644
--- a/plug-api/system_mock.ts
+++ b/plug-api/system_mock.ts
@@ -71,7 +71,6 @@ export function createMockSystem() {
systemSyscalls(clientMock, false),
);
- // @ts-ignore: global
globalThis.syscall = (name: string, ...args: any): Promise => {
return system.localSyscall(name, args);
};
diff --git a/plugs/editor/complete.ts b/plugs/editor/complete.ts
index ed31d4c1..29c63c84 100644
--- a/plugs/editor/complete.ts
+++ b/plugs/editor/complete.ts
@@ -30,10 +30,10 @@ export async function pageComplete(completeEvent: CompleteEvent) {
let isWikilink = true;
// This negative lookbehind is to prevent matching query[[. This requires negative lookbehind, which generally supported now (it seems), in versions of iOS Safari 13.1 and later
// https://caniuse.com/js-regexp-lookbehind
- let match = /(? ({
...page,
- name: "^" + page.name,
+ name: `^${page.name}`,
}));
} else {
// This is the most common case, we're combining three types of completions here:
@@ -88,7 +88,7 @@ export async function pageComplete(completeEvent: CompleteEvent) {
return {
from: completeEvent.pos - prefix.length,
- options: allPages.map((pageMeta) => {
+ options: allPages.flatMap((pageMeta) => {
const completions: any[] = [];
const namePrefix = (pageMeta as PageMeta).pageDecoration?.prefix || "";
const cssClass = ((pageMeta as PageMeta).pageDecoration?.cssClasses || [])
@@ -121,7 +121,7 @@ export async function pageComplete(completeEvent: CompleteEvent) {
for (const alias of pageMeta.aliases) {
const decoratedName = namePrefix + alias;
completions.push({
- label: "" + alias,
+ label: `${alias}`,
displayLabel: decoratedName,
boost: new Date(pageMeta.lastModified).getTime(),
apply: pageMeta.tag === "template"
@@ -154,19 +154,19 @@ export async function pageComplete(completeEvent: CompleteEvent) {
boost = boost * 1.1;
} else {
// Absolute path otherwise
- labelText = "/" + labelText;
+ labelText = `/${labelText}`;
}
completions.push({
label: labelText,
displayLabel: namePrefix + labelText,
boost: boost,
- apply: labelText.includes(" ") ? "<" + labelText + ">" : labelText,
+ apply: labelText.includes(" ") ? `<${labelText}>` : labelText,
type: "page",
cssClass,
});
}
return completions;
- }).flat(),
+ }),
};
}
diff --git a/plugs/editor/editor.ts b/plugs/editor/editor.ts
index 26e8faf3..3b1a5e76 100644
--- a/plugs/editor/editor.ts
+++ b/plugs/editor/editor.ts
@@ -159,9 +159,9 @@ export async function moveToLineCommand() {
return;
}
let column = 1;
- const line = parseInt(match[1]);
+ const line = parseInt(match[1], 10);
if (match[2]) {
- column = parseInt(match[2]);
+ column = parseInt(match[2], 10);
}
await editor.moveCursorToLine(line, column, true); // showing the movement for better UX
}
diff --git a/plugs/editor/outline.ts b/plugs/editor/outline.ts
index 0d902de6..5b9c8587 100644
--- a/plugs/editor/outline.ts
+++ b/plugs/editor/outline.ts
@@ -143,7 +143,7 @@ export async function indentItem() {
const currentItemBounds = determineItemBounds(text, cursorPos);
const itemText = text.slice(currentItemBounds.from, currentItemBounds.to);
const newText = itemText.split("\n").map((line) =>
- line ? " " + line : line
+ line ? ` ${line}` : line
).join("\n");
const preText = text.slice(currentItemBounds.from, cursorPos);
const newCursorPos = cursorPos + preText.split("\n").length * 2;
@@ -198,7 +198,7 @@ export async function outdentItem() {
export function ensureNewLine(s: string) {
if (!s.endsWith("\n")) {
- return s + "\n";
+ return `${s}\n`;
} else {
return s;
}
diff --git a/plugs/editor/stats.ts b/plugs/editor/stats.ts
index 726a57fa..d5461908 100644
--- a/plugs/editor/stats.ts
+++ b/plugs/editor/stats.ts
@@ -1,7 +1,7 @@
import { editor, space } from "@silverbulletmd/silverbullet/syscalls";
function countWords(str: string): number {
- const matches = str.match(/[\w\d\'-]+/gi);
+ const matches = str.match(/[\w\d'-]+/gi);
return matches ? matches.length : 0;
}
diff --git a/plugs/editor/text.ts b/plugs/editor/text.ts
index d75cd40d..b241f355 100644
--- a/plugs/editor/text.ts
+++ b/plugs/editor/text.ts
@@ -24,13 +24,13 @@ export async function listifySelection() {
const selection = await editor.getSelection();
//if very first of doc, just add a bullet and end
- if (selection.to == 0 && selection.from == 0) {
+ if (selection.to === 0 && selection.from === 0) {
await editor.insertAtCursor("* ");
return;
}
let from = selection.from;
- if (text[from] == "\n") {
+ if (text[from] === "\n") {
//end of line, need to find previous line break
from--;
}
diff --git a/plugs/editor/upload.ts b/plugs/editor/upload.ts
index 33abb86b..11fadd0a 100644
--- a/plugs/editor/upload.ts
+++ b/plugs/editor/upload.ts
@@ -110,7 +110,7 @@ export async function saveFile(file: UploadFile) {
documentMarkdown = `[${finalFilePath}](${encodePageURI(finalFilePath)})`;
}
if (file.contentType.startsWith("image/")) {
- documentMarkdown = "!" + documentMarkdown;
+ documentMarkdown = `!${documentMarkdown}`;
}
editor.insertAtCursor(documentMarkdown);
}
diff --git a/plugs/emoji/emoji.ts b/plugs/emoji/emoji.ts
index 6c68b957..7f7630d8 100644
--- a/plugs/emoji/emoji.ts
+++ b/plugs/emoji/emoji.ts
@@ -85,7 +85,7 @@ async function updateConfig() {
}
if (badAliases.length > 0) {
await editor.flashNotification(
- errorMsg + `, need to fix: ${badAliases.join(",")}`,
+ `${errorMsg}, need to fix: ${badAliases.join(",")}`,
"error",
);
}
diff --git a/plugs/image-viewer/viewer.ts b/plugs/image-viewer/viewer.ts
index edac863d..120b8a4e 100644
--- a/plugs/image-viewer/viewer.ts
+++ b/plugs/image-viewer/viewer.ts
@@ -61,7 +61,7 @@ html, body {
* Copyright Timmy Willison and other contributors
* https://github.com/timmywil/panzoom/blob/main/MIT-License.txt
*/
-((t,e)=>{"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Panzoom=e()})(this,function(){var a,X=function(){return(X=Object.assign||function(t){for(var e,n=1,o=arguments.length;n{for(var e=t;e&&e.parentNode;){if(e.parentNode===document)return 1;e=e.parentNode instanceof ShadowRoot?e.parentNode.host:e.parentNode}})(u))throw new Error("Panzoom should be called on elements that have been attached to the DOM");f=X(X({},q),f);t=u;var t,l=Z.test(t.namespaceURI)&&"svg"!==t.nodeName.toLowerCase(),n=u.parentNode;n.style.overflow=f.overflow,n.style.userSelect="none",n.style.touchAction=f.touchAction,(f.canvas?n:u).style.cursor=f.cursor,u.style.userSelect="none",u.style.touchAction=f.touchAction,C(u,"transformOrigin","string"==typeof f.origin?f.origin:l?"0 0":"50% 50%");var r,a,i,c,s,d,m=0,h=0,v=1,p=!1;function g(t,e,n){n.silent||(n=new CustomEvent(t,{detail:e}),u.dispatchEvent(n))}function y(o,r,t){var a={x:m,y:h,scale:v,isSVG:l,originalEvent:t};return requestAnimationFrame(function(){var t,e,n;"boolean"==typeof r.animate&&(r.animate?(t=u,e=r,n=Y("transform"),C(t,"transition","".concat(n," ").concat(e.duration,"ms ").concat(e.easing))):C(u,"transition","none")),r.setTransform(u,a,r),g(o,a,r),g("panzoomchange",a,r)}),a}function w(t,e,n,o){var r,a,i,c,l,s,d,o=X(X({},f),o),p={x:m,y:h,opts:o};return!o.force&&(o.disablePan||o.panOnlyWhenZoomed&&v===o.startScale)||(t=parseFloat(t),e=parseFloat(e),o.disableXAxis||(p.x=(o.relative?m:0)+t),o.disableYAxis||(p.y=(o.relative?h:0)+e),o.contain&&(e=((r=(e=(t=N(u)).elem.width/v)*n)-e)/2,i=((a=(i=t.elem.height/v)*n)-i)/2,"inside"===o.contain?(c=(-t.elem.margin.left-t.parent.padding.left+e)/n,l=(t.parent.width-r-t.parent.padding.left-t.elem.margin.left-t.parent.border.left-t.parent.border.right+e)/n,p.x=Math.max(Math.min(p.x,l),c),s=(-t.elem.margin.top-t.parent.padding.top+i)/n,d=(t.parent.height-a-t.parent.padding.top-t.elem.margin.top-t.parent.border.top-t.parent.border.bottom+i)/n,p.y=Math.max(Math.min(p.y,d),s)):"outside"===o.contain&&(c=(-(r-t.parent.width)-t.parent.padding.left-t.parent.border.left-t.parent.border.right+e)/n,l=(e-t.parent.padding.left)/n,p.x=Math.max(Math.min(p.x,l),c),s=(-(a-t.parent.height)-t.parent.padding.top-t.parent.border.top-t.parent.border.bottom+i)/n,d=(i-t.parent.padding.top)/n,p.y=Math.max(Math.min(p.y,d),s))),o.roundPixels&&(p.x=Math.round(p.x),p.y=Math.round(p.y))),p}function b(t,e){var n,o,r,a,e=X(X({},f),e),i={scale:v,opts:e};return!e.force&&e.disableZoom||(n=f.minScale,o=f.maxScale,e.contain&&(a=(e=N(u)).elem.width/v,r=e.elem.height/v,1{for(var n,o,r=t;null!=r;r=r.parentNode)if(n=r,o=e.excludeClass,1===n.nodeType&&-1<" ".concat((n.getAttribute("class")||"").trim()," ").indexOf(" ".concat(o," "))||-1{"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).Panzoom=e()})(this,function(){var a,X=function(){return(X=Object.assign||function(t){for(var e,n=1,o=arguments.length;n{for(var e=t;e&&e.parentNode;){if(e.parentNode===document)return 1;e=e.parentNode instanceof ShadowRoot?e.parentNode.host:e.parentNode}})(u))throw new Error("Panzoom should be called on elements that have been attached to the DOM");f=X(X({},q),f);t=u;var t,l=Z.test(t.namespaceURI)&&"svg"!==t.nodeName.toLowerCase(),n=u.parentNode;n.style.overflow=f.overflow,n.style.userSelect="none",n.style.touchAction=f.touchAction,(f.canvas?n:u).style.cursor=f.cursor,u.style.userSelect="none",u.style.touchAction=f.touchAction,C(u,"transformOrigin","string"==typeof f.origin?f.origin:l?"0 0":"50% 50%");var r,a,i,c,s,d,m=0,h=0,v=1,p=!1;function g(t,e,n){n.silent||(n=new CustomEvent(t,{detail:e}),u.dispatchEvent(n))}function y(o,r,t){var a={x:m,y:h,scale:v,isSVG:l,originalEvent:t};return requestAnimationFrame(function(){var t,e,n;"boolean"==typeof r.animate&&(r.animate?(t=u,e=r,n=Y("transform"),C(t,"transition","".concat(n," ").concat(e.duration,"ms ").concat(e.easing))):C(u,"transition","none")),r.setTransform(u,a,r),g(o,a,r),g("panzoomchange",a,r)}),a}function w(t,e,n,o){var r,a,i,c,l,s,d,o=X(X({},f),o),p={x:m,y:h,opts:o};return!o.force&&(o.disablePan||o.panOnlyWhenZoomed&&v===o.startScale)||(t=parseFloat(t),e=parseFloat(e),o.disableXAxis||(p.x=(o.relative?m:0)+t),o.disableYAxis||(p.y=(o.relative?h:0)+e),o.contain&&(e=((r=(e=(t=N(u)).elem.width/v)*n)-e)/2,i=((a=(i=t.elem.height/v)*n)-i)/2,"inside"===o.contain?(c=(-t.elem.margin.left-t.parent.padding.left+e)/n,l=(t.parent.width-r-t.parent.padding.left-t.elem.margin.left-t.parent.border.left-t.parent.border.right+e)/n,p.x=Math.max(Math.min(p.x,l),c),s=(-t.elem.margin.top-t.parent.padding.top+i)/n,d=(t.parent.height-a-t.parent.padding.top-t.elem.margin.top-t.parent.border.top-t.parent.border.bottom+i)/n,p.y=Math.max(Math.min(p.y,d),s)):"outside"===o.contain&&(c=(-(r-t.parent.width)-t.parent.padding.left-t.parent.border.left-t.parent.border.right+e)/n,l=(e-t.parent.padding.left)/n,p.x=Math.max(Math.min(p.x,l),c),s=(-(a-t.parent.height)-t.parent.padding.top-t.parent.border.top-t.parent.border.bottom+i)/n,d=(i-t.parent.padding.top)/n,p.y=Math.max(Math.min(p.y,d),s))),o.roundPixels&&(p.x=Math.round(p.x),p.y=Math.round(p.y))),p}function b(t,e){var n,o,r,a,e=X(X({},f),e),i={scale:v,opts:e};return!e.force&&e.disableZoom||(n=f.minScale,o=f.maxScale,e.contain&&(a=(e=N(u)).elem.width/v,r=e.elem.height/v,1{for(var n,o,r=t;null!=r;r=r.parentNode)if(n=r,o=e.excludeClass,1===n.nodeType&&-1<" ".concat((n.getAttribute("class")||"").trim()," ").indexOf(" ".concat(o," "))||-1[^\[]*)$/.exec(
+ const match = /(?:\[\[|\[.*?\]\()(?[^[]*)$/.exec(
completeEvent.linePrefix,
);
if (!match || !match.groups?.path) {
diff --git a/plugs/index/link.ts b/plugs/index/link.ts
index 241ba05d..88f6fa1d 100644
--- a/plugs/index/link.ts
+++ b/plugs/index/link.ts
@@ -173,7 +173,7 @@ export async function indexLinks(
wikiLinkRegex.lastIndex = 0;
const match = wikiLinkRegex.exec(text);
// Search in entire node text to get correct position, but check for full match against trimmed
- if (match && match.groups && match[0] === trimmed) {
+ if (match?.groups && match[0] === trimmed) {
const { leadingTrivia, stringRef, alias } = match.groups;
const pos = textNode.from! + match.index! + leadingTrivia.length;
const link: LinkObject = {
diff --git a/plugs/index/lint.ts b/plugs/index/lint.ts
index ae1baa1f..f8526420 100644
--- a/plugs/index/lint.ts
+++ b/plugs/index/lint.ts
@@ -81,7 +81,7 @@ function lintYamlBlock(
): LintDiagnostic | undefined {
try {
const parsed = YAML.load(yamlText) as any;
- if (pageName && parsed.name && parsed.name != pageName) {
+ if (pageName && parsed.name && parsed.name !== pageName) {
return {
from: startPos,
to: startPos + yamlText.length,
diff --git a/plugs/index/refactor.ts b/plugs/index/refactor.ts
index 4bc8411d..7ff65fd5 100644
--- a/plugs/index/refactor.ts
+++ b/plugs/index/refactor.ts
@@ -43,7 +43,7 @@ export async function renamePageCommand(cmdDef: any) {
editor.flashNotification("Must provide a non-empty page title.", "error");
return false;
}
- const pageList: [string, string][] = [[oldName + ".md", newName + ".md"]];
+ const pageList: [string, string][] = [[`${oldName}.md`, `${newName}.md`]];
await batchRenameFiles(pageList);
return true;
}
@@ -80,7 +80,7 @@ export async function renamePageLinkCommand() {
editor.flashNotification("Must provide a non-empty page title.", "error");
return false;
}
- const pageList: [string, string][] = [[oldName + ".md", newName + ".md"]];
+ const pageList: [string, string][] = [[`${oldName}.md`, `${newName}.md`]];
await batchRenameFiles(pageList);
}
@@ -225,7 +225,7 @@ async function renamePage(oldName: string, newName: string) {
newTail = newTail.replace(/^.*?(?=@\d*|#|\$|\))/, newLink);
// Wrap in <> if link has spaces
if (newLink.includes(" ")) {
- newTail = "<" + newTail.replace(")", ">)");
+ newTail = `<${newTail.replace(")", ">)")}`;
}
text = text.substring(0, link.pos) + newTail;
}
@@ -239,7 +239,7 @@ async function renamePage(oldName: string, newName: string) {
const batchRenameDocuments: [string, string][] = [];
for (const document of documentsToMove) {
const newAttName = oldFolder.length === 0
- ? newFolder + "/" + document
+ ? `${newFolder}/${document}`
: document.replace(oldFolder, newFolder).replace(/^\//, "");
batchRenameDocuments.push([document, newAttName]);
}
@@ -340,7 +340,7 @@ export async function renamePrefixCommand(cmdDef: any) {
file,
) => file.startsWith(oldPrefix));
allAffectedFiles = allAffectedFiles.concat(
- allPages.map((page) => page.name + ".md").filter((page) =>
+ allPages.map((page) => `${page.name}.md`).filter((page) =>
page.startsWith(oldPrefix)
),
);
@@ -452,7 +452,7 @@ async function updateBacklinks(
// Is [Markdown link]()
if (newTail.startsWith("/") || newTail.startsWith("")) {
// Is absolute mdlink, update with full path with leading /
- newLink = "/" + newLink;
+ newLink = `/${newLink}`;
} else {
// Is relative mdlink
newLink = absoluteToRelativePath(pageToEdit, newLink);
@@ -461,7 +461,7 @@ async function updateBacklinks(
// Wrap in <> if link has spaces
if (newLink.includes(" ")) {
- newTail = "<" + newTail.replace(")", ">)");
+ newTail = `<${newTail.replace(")", ">)")}`;
}
} else {
// Is wikilink, replace with full path
diff --git a/plugs/index/snippet.ts b/plugs/index/snippet.ts
index 98dc7b9a..54212e2d 100644
--- a/plugs/index/snippet.ts
+++ b/plugs/index/snippet.ts
@@ -51,7 +51,7 @@ export function extractSnippet(
// Find tasks that don't have a page reference, and add one
const taskMatch = line.match(
- /^(\s*)([\*\-]\s+\[[^\]]+\]\s+)([^\[][^\[].+)$/,
+ /^(\s*)([*-]\s+\[[^\]]+\]\s+)([^[][^[].+)$/,
);
if (taskMatch) {
const pos = lineLengths.slice(0, i).reduce((acc, len) =>
diff --git a/plugs/index/tags.ts b/plugs/index/tags.ts
index b5c8cfc0..ea146216 100644
--- a/plugs/index/tags.ts
+++ b/plugs/index/tags.ts
@@ -67,7 +67,7 @@ export async function tagComplete(completeEvent: CompleteEvent) {
return null;
}
- const match = /#[^#\s\[\]]+\w*$/.exec(completeEvent.linePrefix);
+ const match = /#[^#\s[\]]+\w*$/.exec(completeEvent.linePrefix);
if (!match) {
return null;
}
@@ -104,7 +104,7 @@ export function updateITags(obj: ObjectValue, frontmatter: FrontMatter) {
/** Get markup for a hashtag name with # prefix and angle brackets if necessary */
export function renderHashtag(name: string): string {
// detect with the same regex as the parser
- const simple: string = "#" + name;
+ const simple: string = `#${name}`;
const match = simple.match(tagRegex);
if (!match || match[0].length !== simple.length) {
return `#<${name}>`;
diff --git a/plugs/index/task.ts b/plugs/index/task.ts
index e29ff700..f44f84a9 100644
--- a/plugs/index/task.ts
+++ b/plugs/index/task.ts
@@ -44,7 +44,7 @@ async function convertListItemToTask(node: ParseTree) {
let taskMarker: string;
if (originalMark.match(/^\d+\./)) {
// Numbered list: preserve the number
- taskMarker = originalMark + " [ ]";
+ taskMarker = `${originalMark} [ ]`;
} else {
// Bullet list: use standard bullet
taskMarker = "* [ ]";
diff --git a/plugs/plug-manager/plugmanager.ts b/plugs/plug-manager/plugmanager.ts
index fa97fd04..f0fcc38a 100644
--- a/plugs/plug-manager/plugmanager.ts
+++ b/plugs/plug-manager/plugmanager.ts
@@ -91,7 +91,7 @@ export async function updatePlugsCommand() {
typeof manifest.name !== "string"
) {
// Try taking a good guess at a name if it isn't provided
- const match = /\/([^\/]+)\.plug\.js$/.exec(plugUri);
+ const match = /\/([^/]+)\.plug\.js$/.exec(plugUri);
if (!match) {
console.error(
`No plug name provided and could not extract name from ${plugUri} ignoring...`,
@@ -140,7 +140,7 @@ export async function updatePlugsCommand() {
await editor.flashNotification("All done!");
system.reloadPlugs();
} catch (e: any) {
- editor.flashNotification("Error updating plugs: " + e.message, "error");
+ editor.flashNotification(`Error updating plugs: ${e.message}`, "error");
}
}