From 03a1e3ed210bea1c8c3e2bec7848518a68c6131a Mon Sep 17 00:00:00 2001 From: Emmaline Date: Fri, 2 May 2025 01:11:15 -0600 Subject: [PATCH] updates checkCode to new framework --- cli/prompts.ts | 8 ++- deno.json | 6 ++- must_await_cli_prompts.ts | 45 ++++++++++++++++ testing/test.ts | 7 +++ tools/checkCode.ts | 109 ++++++++++++++++++++++---------------- tools/fieldRename.ts | 4 +- 6 files changed, 128 insertions(+), 51 deletions(-) create mode 100644 must_await_cli_prompts.ts diff --git a/cli/prompts.ts b/cli/prompts.ts index ec8bbf6..e183ef5 100644 --- a/cli/prompts.ts +++ b/cli/prompts.ts @@ -1,5 +1,5 @@ +// deno-lint-disable-must-await-calls import { Cursor } from "./cursor.ts"; -import { ScrollManager } from "./scrollManager.ts"; import { colorize } from "./style.ts"; import { TerminalBlock, TerminalLayout } from "./TerminalLayout.ts"; @@ -75,10 +75,14 @@ export function cliAlert(message: string, block?: TerminalBlock) { }); } -export function cliLog(message: string, block?: TerminalBlock) { +export function cliLog( + message: string | object | Array, + block?: TerminalBlock, +) { if (!block) { console.log(message); } else { + if (typeof message === "object") message = Deno.inspect(message); block.setLines(message.split("\n")); } } diff --git a/deno.json b/deno.json index b87cf86..60c29cd 100644 --- a/deno.json +++ b/deno.json @@ -19,10 +19,14 @@ "rules": { "exclude": [ "no-explicit-any" + ], + "include": [ + "require-await" ] }, "plugins": [ - "./no-log.ts" + "./no-log.ts", + "./must_await_cli_prompts.ts" ] } } \ No newline at end of file diff --git a/must_await_cli_prompts.ts b/must_await_cli_prompts.ts new file mode 100644 index 0000000..a45197a --- /dev/null +++ b/must_await_cli_prompts.ts @@ -0,0 +1,45 @@ +const TARGET_FUNCTIONS = new Set(["cliAlert", "cliPrompt", "cliConfirm"]); + +const plugin: Deno.lint.Plugin = { + name: "must-await-calls", + rules: { + "must-await-calls": { + create(context) { + return { + CallExpression(node) { + if ( + node.callee.type !== "Identifier" || + !TARGET_FUNCTIONS.has(node.callee.name) + ) return; + + const parent = node.parent; + + // Allow `await fetchData()` + if (parent?.type === "AwaitExpression") return; + + // Allow `return fetchData()` or `return await fetchData()` + if (parent?.type === "ReturnStatement") return; + + // Allow `fetchData().then(...)` + if ( + parent?.type === "MemberExpression" && + parent.property.type === "Identifier" && + parent.property.name === "then" + ) return; + + context.report({ + node, + message: + `Call to "${node.callee.name}" must be awaited, returned, or .then-chained.`, + fix(fixer) { + return fixer.insertTextBefore(node, "await "); + }, + }); + }, + }; + }, + }, + }, +}; + +export default plugin; diff --git a/testing/test.ts b/testing/test.ts index e69de29..ea306bd 100644 --- a/testing/test.ts +++ b/testing/test.ts @@ -0,0 +1,7 @@ +const thing: string = ""; +switch (thing) { + case "Text1": + break; + default: + break; +} diff --git a/tools/checkCode.ts b/tools/checkCode.ts index a9a1a3c..8e3f142 100644 --- a/tools/checkCode.ts +++ b/tools/checkCode.ts @@ -1,57 +1,74 @@ +import { forceArgs } from "../cli/forceArgs.ts"; +import { cliAlert, cliLog } from "../cli/prompts.ts"; +import { colorize } from "../cli/style.ts"; +import type { TerminalBlock } from "../cli/TerminalLayout.ts"; import { loadPdfForm } from "../util/saveLoadPdf.ts"; -import { callWithArgPrompt } from "util/call.ts"; -export async function checkFile(pdfPath: string, csPath: string) { - while (!pdfPath || !pdfPath.endsWith(".pdf")) { - pdfPath = prompt("Please provide path to PDF file:") || ""; - } - while (!csPath || !csPath.endsWith(".cs")) { - csPath = prompt("Please provide path to CS class file:") || ""; - } - - const form = await loadPdfForm(pdfPath); - - const fields = form.getFields(); - const csFiles = await Promise.all( - csPath.split(",").map((c) => Deno.readTextFile(c.trim())), - ); - - const fieldNames: string[] = fields.map((f) => f.getName()) - .filter((f) => { - const rx = new RegExp( - `(? rx.test(c)); - }) - .filter((f) => !f.toLowerCase().includes("signature")); - - if (fieldNames.length) { - console.log( - "%cThe following field names are not present in the CS code", - "color: red", - ); - console.log(fieldNames); - alert("Your princess is in another castle..."); - } else { - console.log("%cAll form fields present", "color: lime"); - alert("Ok!"); +function getCaseSyntaxPatternByFileExtension( + extenstion: string, + field: string, +) { + switch (extenstion.trim().toLowerCase().replace(".", "")) { + case "cs": + case "js": + case "ts": + default: + return `(? "); + description = "Checks if form fields are present in a given code file"; + private block?: TerminalBlock; + setBlock(block: TerminalBlock) { + this.block = block; + this.block.setPreserveHistory(true); } - async run(...args: string[]) { - await callWithArgPrompt(checkFile, [ - ["Please provide path to PDF file:", (p) => !!p && p.endsWith(".pdf")], - [ - "Please provide path to CS file (comma separated for multiple):", - (p) => !!p && p.endsWith(".cs"), - ], - ], args); + async help() { + cliLog("Usage: checkcode ", this.block); + await cliAlert("", this.block); + } + async run(pdfPath: string, codePaths: string) { + [pdfPath, codePaths] = await forceArgs([pdfPath, codePaths], [ + "Please provide path to PDF file:", + "Please provide path(s) to code file(s) (comma separated for multiple):", + ]); + + const form = await loadPdfForm(pdfPath); + + const fields = form.getFields(); + const codeFiles: [string, string][] = codePaths.split(",").map(( + c, + ) => [c, Deno.readTextFileSync(c.trim())]); + + const fieldNames: string[] = fields.map((f) => f.getName()) + .filter((f) => !f.toLowerCase().includes("signature")); + let unfound = fieldNames.slice(); + + for (const [path, content] of codeFiles) { + unfound = unfound.filter((f) => { + const rx = new RegExp( + getCaseSyntaxPatternByFileExtension(path.split(".").at(-1) ?? "", f), + ); + return rx.test(content); + }); + } + + if (unfound.length) { + cliLog( + colorize( + "The following field names are not present in the CS code", + "red", + ), + this.block, + ); + cliLog(unfound, this.block); + await cliAlert("Your princess is in another castle...", this.block); + } else { + cliLog(colorize("All form fields present", "green"), this.block); + await cliAlert("Ok!", this.block); + } } } diff --git a/tools/fieldRename.ts b/tools/fieldRename.ts index f0d027a..36c97e2 100644 --- a/tools/fieldRename.ts +++ b/tools/fieldRename.ts @@ -87,8 +87,8 @@ class RenameFields implements ITool { this.block = block; } - help(standalone = false) { - cliAlert( + async help(standalone = false) { + await cliAlert( "Usage: rename-fields \n", standalone ? undefined : this.block, );