From 3682a7a7633c15b18874d100b8327ba46c794153 Mon Sep 17 00:00:00 2001 From: Endeavorance Date: Thu, 3 Apr 2025 09:47:19 -0400 Subject: [PATCH] Add support for processors over http --- biome.json | 5 +---- bunfig.toml | 1 + src/binding.ts | 6 ++++-- src/cli.ts | 4 ++-- src/errors.ts | 2 +- src/parse.ts | 6 +++--- src/preload/http-plugin.js | 40 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 bunfig.toml create mode 100644 src/preload/http-plugin.js diff --git a/biome.json b/biome.json index 1814905..7988bf6 100644 --- a/biome.json +++ b/biome.json @@ -7,10 +7,7 @@ }, "files": { "ignoreUnknown": false, - "ignore": [ - "*.d.ts", - "*.json" - ], + "ignore": ["*.d.ts", "*.json"], "include": [ "./src/**/*.ts", "./src/**/*.tsx", diff --git a/bunfig.toml b/bunfig.toml new file mode 100644 index 0000000..a7461c6 --- /dev/null +++ b/bunfig.toml @@ -0,0 +1 @@ +preload = ["./src/preload/http-plugin.js"] diff --git a/src/binding.ts b/src/binding.ts index c1f9e96..ae2bcc2 100644 --- a/src/binding.ts +++ b/src/binding.ts @@ -1,6 +1,6 @@ import path, { dirname } from "node:path"; import { Glob } from "bun"; -import { MuseFileNotFoundError, MuseError } from "./errors"; +import { MuseError, MuseFileNotFoundError } from "./errors"; import { parseMuseFile } from "./parse"; import { type Binding, @@ -14,7 +14,9 @@ async function loadProcessor( bindingDirname: string, processorPath: string, ): Promise { - const resolvedProcessorPath = path.resolve(bindingDirname, processorPath); + const resolvedProcessorPath = processorPath.startsWith("http") + ? processorPath + : path.resolve(bindingDirname, processorPath); const { process, name, description } = await import(resolvedProcessorPath); if (!process || typeof process !== "function") { diff --git a/src/cli.ts b/src/cli.ts index 762d30e..c8380ab 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,8 +1,8 @@ import { parseArgs } from "node:util"; import chalk from "chalk"; -import { MuseError } from "./errors"; -import { loadBinding } from "./binding"; import { version } from "../package.json"; +import { loadBinding } from "./binding"; +import { MuseError } from "./errors"; import type { Binding, CLIArguments } from "./types"; interface Loggers { diff --git a/src/errors.ts b/src/errors.ts index d5184d7..47d98d5 100644 --- a/src/errors.ts +++ b/src/errors.ts @@ -27,4 +27,4 @@ export class MuseFileNotFoundError extends MuseFileError { } } -export class CLIError extends MuseError { } +export class CLIError extends MuseError {} diff --git a/src/parse.ts b/src/parse.ts index 842f6d2..509bf63 100644 --- a/src/parse.ts +++ b/src/parse.ts @@ -1,7 +1,7 @@ -import { normalize, extname } from "node:path"; -import YAML from "yaml"; -import TOML from "smol-toml"; +import { extname, normalize } from "node:path"; import EMDY from "@endeavorance/emdy"; +import TOML from "smol-toml"; +import YAML from "yaml"; import type { MuseEntry, UnknownRecord } from "./types"; function parseYAMLEntries(text: string): UnknownRecord[] { diff --git a/src/preload/http-plugin.js b/src/preload/http-plugin.js new file mode 100644 index 0000000..bb7f732 --- /dev/null +++ b/src/preload/http-plugin.js @@ -0,0 +1,40 @@ +const rx_any = /./; +const rx_http = /^https?:\/\//; +const rx_relative_path = /^\.\.?\//; +const rx_absolute_path = /^\//; + +async function load_http_module(href) { + return fetch(href).then((response) => + response + .text() + .then((text) => + response.ok + ? { contents: text, loader: "js" } + : Promise.reject( + new Error(`Failed to load module '${href}'': ${text}`), + ), + ), + ); +} + +Bun.plugin({ + name: "http_imports", + setup(build) { + build.onResolve({ filter: rx_relative_path }, (args) => { + if (rx_http.test(args.importer)) { + return { path: new URL(args.path, args.importer).href }; + } + }); + build.onResolve({ filter: rx_absolute_path }, (args) => { + if (rx_http.test(args.importer)) { + return { path: new URL(args.path, args.importer).href }; + } + }); + build.onLoad({ filter: rx_any, namespace: "http" }, (args) => + load_http_module(`http:${args.path}`), + ); + build.onLoad({ filter: rx_any, namespace: "https" }, (args) => + load_http_module(`https:${args.path}`), + ); + }, +});