@ 261027.7

240810.1 · d92dda2b836b97aeea7211b4b6dbe5c2b79cc34f

feat: create amaro loader

reading declarations

src/index.ts

@@ -1,18 +1,2 @@-import type { Options, TransformOutput } from "../lib/wasm";-import swc from "../lib/wasm.js";--const DEFAULT_OPTIONS: Options = {-	mode: "strip-only",-};--export function transformSync(-	source: string,-	options: Options,-): TransformOutput {-	// Ensure that the source code is a string-	const input = `${source ?? ""}`;-	return swc.transformSync(input, {-		...DEFAULT_OPTIONS,-		...options,-	});-}+export { transformSync } from "./transform.ts";+export { load } from "./loader.ts";

src/loader.ts

new file mode 100644@@ -0,0 +1,14 @@+import swc from "../lib/wasm.js";+import type { LoadHook } from "node:module";+import { readFile } from "node:fs/promises";++export const load: LoadHook = async (source, context, nextLoad) => {+	if (context.format?.includes("typescript")) {+		const data = await readFile(source, "utf8");+		return {+			source: swc.transformSync(data).code,+			shortCircuit: true, // Skips bundled transpilation+		};+	}+	return { source: await nextLoad(source, context) };+};

src/transform.ts

new file mode 100644@@ -0,0 +1,18 @@+import type { Options, TransformOutput } from "../lib/wasm";+import swc from "../lib/wasm.js";++const DEFAULT_OPTIONS: Options = {+	mode: "strip-only",+};++export function transformSync(+	source: string,+	options: Options,+): TransformOutput {+	// Ensure that the source code is a string+	const input = `${source ?? ""}`;+	return swc.transformSync(input, {+		...DEFAULT_OPTIONS,+		...options,+	});+}

test/fixtures/enum.ts

new file mode 100644@@ -0,0 +1,4 @@+enum Foo {+    A = "Hello, TypeScript!"+}+console.log(Foo.A);

test/fixtures/hello.ts

new file mode 100644@@ -0,0 +1 @@+console.log("Hello, TypeScript!");

test/loader.test.js

new file mode 100644@@ -0,0 +1,29 @@+const { spawnPromisified, fixturesPath } = require("./util/util.js");+const { test } = require("node:test");+const { match, strictEqual } = require("node:assert");++test("should work as a loader", async () => {+	const result = await spawnPromisified(process.execPath, [+		"--experimental-strip-types",+		"--no-warnings",+		"--import=./dist/index.js",+		fixturesPath("hello.ts"),+	]);++	strictEqual(result.stderr, "");+	match(result.stdout, /Hello, TypeScript!/);+	strictEqual(result.code, 0);+});++test("should work with enums", async () => {+	const result = await spawnPromisified(process.execPath, [+		"--experimental-strip-types",+		"--no-warnings",+		"--import=./dist/index.js",+		fixturesPath("enum.ts"),+	]);++	strictEqual(result.stderr, "");+	match(result.stdout, /Hello, TypeScript!/);+	strictEqual(result.code, 0);+});

test/util/util.js

new file mode 100644@@ -0,0 +1,44 @@+const { spawn } = require("node:child_process");+const path = require("node:path");++function spawnPromisified(...args) {+	let stderr = "";+	let stdout = "";++	const child = spawn(...args);+	child.stderr.setEncoding("utf8");+	child.stderr.on("data", (data) => {+		stderr += data;+	});+	child.stdout.setEncoding("utf8");+	child.stdout.on("data", (data) => {+		stdout += data;+	});++	return new Promise((resolve, reject) => {+		child.on("close", (code, signal) => {+			resolve({+				code,+				signal,+				stderr,+				stdout,+			});+		});+		child.on("error", (code, signal) => {+			reject({+				code,+				signal,+				stderr,+				stdout,+			});+		});+	});+}++const fixturesDir = path.join(__dirname, "..", "fixtures");++function fixturesPath(...args) {+	return path.join(fixturesDir, ...args);+}++module.exports = { spawnPromisified, fixturesPath };