diff --git a/deno.jsonc b/deno.jsonc index 3058694..8a70367 100644 --- a/deno.jsonc +++ b/deno.jsonc @@ -1,7 +1,23 @@ { "tasks": { "build": "deno run -A script/build.ts", - "start": "deno run -A --unstable mod.ts", - "dev": "deno run -A --unstable --watch mod.ts", + "start": "deno run -A --unstable-kv mod.ts", + "dev": "deno run -A --unstable-kv --watch mod.ts" + }, + "imports": { + "@amoutonbrady/lz-string": "npm:@amoutonbrady/lz-string@^0.1.0", + "@oak/oak": "jsr:@oak/oak@^17.2.0", + "@shikijs/rehype": "npm:@shikijs/rehype@3.7.0", + "@shikijs/twoslash": "npm:@shikijs/twoslash@3.7.0", + "@std/path": "jsr:@std/path@^1.1.6", + "@std/yaml": "jsr:@std/yaml@^1.1.2", + "@tajpouria/cors": "jsr:@tajpouria/cors@^1.2.1", + "rehype-raw": "npm:rehype-raw@^7.0.0", + "rehype-stringify": "npm:rehype-stringify@^10.0.1", + "remark-gfm": "npm:remark-gfm@^4.0.1", + "remark-parse": "npm:remark-parse@^11.0.0", + "remark-rehype": "npm:remark-rehype@^11.1.2", + "typescript": "npm:typescript@^6", + "unified": "npm:unified@^11.0.5" } } \ No newline at end of file diff --git a/deps.ts b/deps.ts index e6d2a52..65af41a 100644 --- a/deps.ts +++ b/deps.ts @@ -1,37 +1,23 @@ -// @deno-types=https://unpkg.com/typescript@latest/lib/typescript.d.ts -export { default as Typescript } from "https://esm.sh/typescript@latest" +export { default as Typescript } from "typescript"; -export * as lzstring from "https://esm.sh/@amoutonbrady/lz-string" -export * as path from "https://deno.land/std/path/mod.ts" +export * as lzstring from "@amoutonbrady/lz-string"; +export * as path from "@std/path"; -export * as oak from "https://deno.land/x/oak/mod.ts" -export { oakCors as cors } from "https://deno.land/x/cors/mod.ts" +export * as oak from "@oak/oak"; +export { oakCors as cors } from "@tajpouria/cors"; -export { parse } from "https://deno.land/std/yaml/parse.ts" +export { parse } from "@std/yaml"; -export { unified } from "https://esm.sh/unified" -export { default as fromMarkdown } from "https://esm.sh/remark-parse" -export { default as withHtmlInMarkdown } from "https://esm.sh/rehype-raw" -export { default as toHtml } from "https://esm.sh/rehype-stringify" -export { default as toHast } from "https://esm.sh/remark-rehype" -export { default as withShiki } from "https://esm.sh/@stefanprobst/remark-shiki" +export { unified } from "unified"; +export { default as fromMarkdown } from "remark-parse"; +export { default as GithubMarkdownFlavor } from "remark-gfm"; +export { default as toHast } from "remark-rehype"; -// @deno-types=https://esm.sh/shiki -export * as shiki from "https://unpkg.com/shiki/dist/index.browser.mjs" +export { default as withHtmlInMarkdown } from "rehype-raw"; +export { default as withShiki } from "@shikijs/rehype"; +export { default as toHtml } from "rehype-stringify"; -export { default as GithubMarkdownFlavor } from "https://esm.sh/remark-gfm" +export { transformerTwoslash } from "@shikijs/twoslash"; -export { default as html, h, Fragment } from "https://deno.land/x/htm/mod.ts" -export { default as ColorScheme } from "https://deno.land/x/htm/plugins/color-scheme.ts" - -declare module "https://esm.sh/typescript@latest" { - // Hacking in some internal stuff - type TypescriptOption = { - name: string; - type: "list" | "boolean" | "number" | "string" | Map; - element?: TypescriptOption; - }; - - export const optionDeclarations: Array; -} - \ No newline at end of file +export { default as html, h, Fragment } from "https://deno.land/x/htm/mod.ts"; +export { default as ColorScheme } from "https://deno.land/x/htm/plugins/color-scheme.ts"; \ No newline at end of file diff --git a/script/docs.tsx b/script/docs.tsx index 3f10b88..460f031 100644 --- a/script/docs.tsx +++ b/script/docs.tsx @@ -1,62 +1,76 @@ import { ColorScheme, fromMarkdown, + GithubMarkdownFlavor, html, path, - shiki, toHast, toHtml, + transformerTwoslash, unified, withHtmlInMarkdown, withShiki, - GithubMarkdownFlavor, } from "../deps.ts"; -// Destructure necessary path utilities from path (similar to path in Node.js) const { dirname, fromFileUrl, join } = path; - -// Get the directory of the current module file -// This is similar to __dirname in Node.js, but Deno uses URLs for modules, so we need to convert from a file URL to a path const __dirname = dirname(fromFileUrl(import.meta.url)); -// check the color scheme with system settings automatically html.use(ColorScheme("dark")); export async function getDocs() { - shiki.setCDN("https://unpkg.com/shiki/"); - const highlighter = await shiki.getHighlighter({ theme: "github-dark" }); - + const markdown = await Deno.readTextFile( + join(__dirname, "../README.md"), + ); + const file = await unified() - .use(fromMarkdown) // Parse markdown content to a syntax tree + // Markdown string -> MDAST + .use(fromMarkdown) .use(GithubMarkdownFlavor) - .use(withShiki, { highlighter }) - .use(toHast, { allowDangerousHtml: true }) // Turn markdown syntax tree to HTML syntax tree, ignoring embedded HTML + + // MDAST -> HAST + .use(toHast, { + allowDangerousHtml: true, + }) + + // Parse embedded Markdown HTML into normal HAST nodes. .use(withHtmlInMarkdown) - .use(toHtml) // Serialize HTML syntax tree; - .process( - new TextDecoder().decode( - await Deno.readFile(join(__dirname, "../README.md")), - ), - ); + + // Highlight HAST code blocks with modern Shiki. + .use(withShiki, { + theme: "github-dark", + transformers: [ + transformerTwoslash({ + explicitTrigger: true, + }), + ], + }) + + // HAST -> HTML string + .use(toHtml) + .process(markdown); return ( await html({ lang: "en", - title: "Intro. - Typescript Code Analyzer API", + title: "Intro. - TypeScript Code Analyzer API", meta: { description: - "The REST API accepts a JSON & Form Data body with the following properties: code, extension, and options.", + "The REST API accepts a JSON and Form Data body with the following properties: code, extension, and options.", }, links: [ - { rel: "mask-icon", href: "/favicon/favicon.svg", color: "#ffffff" }, + { + rel: "mask-icon", + href: "/favicon/favicon.svg", + color: "#ffffff", + }, { rel: "stylesheet", - href: "https://unpkg.com/sakura.css/css/normalize.css ", + href: "https://unpkg.com/sakura.css/css/normalize.css", type: "text/css", }, { rel: "stylesheet", - href: "https://unpkg.com/sakura.css/css/sakura-vader.css ", + href: "https://unpkg.com/sakura.css/css/sakura-vader.css", type: "text/css", }, { @@ -68,4 +82,4 @@ export async function getDocs() { body: String(file), }) ).body; -} +} \ No newline at end of file diff --git a/static/index.html b/static/index.html index 19f3276..3ac4b79 100644 --- a/static/index.html +++ b/static/index.html @@ -1,4 +1,4 @@ -Intro. - Typescript Code Analyzer API

ai-typescript-check

+Intro. - TypeScript Code Analyzer API

ai-typescript-check

GitHub | Docs | License

ai-typescript-check is a ChatGPT plugin and API that provides linting, auto-completion, error checking, and type checking for TypeScript, JSX/TSX, and JavaScript files. It uses a modified version of @typescript/twoslash. Meaning all the typescript twoslash tips and tricks all work out of the box.

While primarily designed as a ChatGPT plugin for type checking TypeScript code, ai-typescript-check can also be used as a standalone API for type checking in any coding environment. We welcome your feedback and suggestions. You can check out the OpenAPI Spec to learn more about the API static/.well-known/openapi.yaml or using the website at ts-check.okikio.dev/.well-known/openapi.yaml

@@ -25,12 +25,12 @@

Prompt

Type check transferables

-
import { hasTransferables } from "transferables" 
+
import { hasTransferables } from "transferables" 

Response

The TypeScript code:

-
import { hasTransferables } from "transferables"
+
import { hasTransferables } from "transferables"

imports a function named hasTransferables from a module named "transferables". The function hasTransferables takes up to three parameters:

  1. obj: unknown - The object to check for transferables.
  2. @@ -40,43 +40,43 @@

    The function returns a boolean value indicating whether the input contains at least one transferable object, up to a maximum number of iterations.

    Please note that the function hasTransferables is imported but not used in your code, which is why the TypeScript compiler is giving a warning.

    Here is the type information for hasTransferables:

    -
    (alias) function hasTransferables(obj: unknown, streams?: boolean, maxCount?: number): boolean
    +
    (alias) function hasTransferables(obj: unknown, streams?: boolean, maxCount?: number): boolean

    And here is the documentation for the function:

    -
    Quickly checks to see if input contains at least one transferable object, up to a max number of iterations
    +
    Quickly checks to see if input contains at least one transferable object, up to a max number of iterations

    You can see the code in the TypeScript playground here.

Here's this exmaple on ChatGPT: https://chat.openai.com/share/3b32d004-a1c3-4dfc-b862-5426518d31ef

API

To utilize ai-typescript-check, please follow the steps below:

-
// Instantiate a new FormData object
-const formData = new FormData();
-formData.append("code", "import { hasTransferables } from \"transferables\"");
-formData.append("extension", "ts");
+
// Instantiate a new FormData object
+const formData = new FormData();
+formData.append("code", "import { hasTransferables } from \"transferables\"");
+formData.append("extension", "ts");
 
-// Initiate a POST request to the API
-const res = await fetch("https://ts-check.okikio.dev/twoslash", {
-  method: "POST",
-  body: formData
-})
+// Initiate a POST request to the API
+const res = await fetch("https://ts-check.okikio.dev/twoslash", {
+  method: "POST",
+  body: formData
+})
 
-// Output the response
-console.log({
-  json: await res.json()
-})
+// Output the response +console.log({ + json: await res.json() +})

Alternatively, you can pass the options as a query parameter:

-
// Define the options
-const options = JSON.stringify({
-  "code": `import { hasTransferables } from "transferables"`,
-  "extension": "ts"
-});
+
// Define the options
+const options = JSON.stringify({
+  "code": `import { hasTransferables } from "transferables"`,
+  "extension": "ts"
+});
 
-// Initiate a GET request to the API
-const res = await fetch(`https://ts-check.okikio.dev/twoslash?options=${options}`)
+// Initiate a GET request to the API
+const res = await fetch(`https://ts-check.okikio.dev/twoslash?options=${options}`)
 
-// Output the response
-console.log({
-  json: await res.json()
-})
+// Output the response +console.log({ + json: await res.json() +})

Response

The API will return a JSON object containing the following information:

Here's an example response:

-
{
-  "code": "import { hasTransferables } from \"transferables\"",
-  "extension": "ts",
-  "highlights": [],
-  "queries": [],
-  "staticQuickInfos": [
-    {
-      "text": "(alias) function hasTransferables(obj: unknown, streams?: boolean, maxCount?: number): boolean\nimport hasTransferables",
-      "docs": "Quickly checks to see if input contains at least one transferable object, up to a max number of iterations\nThanks @aaorris for the help optimizing perf.",
-      "start": 9,
-      "length": 16,
-      "line": 0,
-      "character": 9,
-      "targetString": "hasTransferables"
-    }
-  ],
-  "errors": [],
-  "warnings": [
-    {
-      "category": 2,
-      "code": 6133,
-      "length": 48,
-      "line": 0,
-      "character": 0,
-      "renderedMessage": "'hasTransferables' is declared but its value is never read.",
-      "id": "warn-6133-0-48"
-    }
-  ],
-  "playgroundURL": "https://www.typescriptlang.org/play/#code/JYWwDg9gTgLgBAbzgCwIYGcAqVUDt0BmApjgEYA2R6cAvnAVBCHAEQw77FmXotA",
-  "tags": []
-}
+
{
+  "code": "import { hasTransferables } from \"transferables\"",
+  "extension": "ts",
+  "highlights": [],
+  "queries": [],
+  "staticQuickInfos": [
+    {
+      "text": "(alias) function hasTransferables(obj: unknown, streams?: boolean, maxCount?: number): boolean\nimport hasTransferables",
+      "docs": "Quickly checks to see if input contains at least one transferable object, up to a max number of iterations\nThanks @aaorris for the help optimizing perf.",
+      "start": 9,
+      "length": 16,
+      "line": 0,
+      "character": 9,
+      "targetString": "hasTransferables"
+    }
+  ],
+  "errors": [],
+  "warnings": [
+    {
+      "category": 2,
+      "code": 6133,
+      "length": 48,
+      "line": 0,
+      "character": 0,
+      "renderedMessage": "'hasTransferables' is declared but its value is never read.",
+      "id": "warn-6133-0-48"
+    }
+  ],
+  "playgroundURL": "https://www.typescriptlang.org/play/#code/JYWwDg9gTgLgBAbzgCwIYGcAqVUDt0BmApjgEYA2R6cAvnAVBCHAEQw77FmXotA",
+  "tags": []
+}

API Reference

ai-typescript-check provides two main API endpoints: POST /twoslash and GET /twoslash. Both endpoints accept TwoSlashOptions as input and return TwoSlashReturn as output.

POST /twoslash