240810.1 · d92dda2b836b97aeea7211b4b6dbe5c2b79cc34f
feat: create amaro loader
reading declarations
@@ -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
@@ -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
@@ -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,+ });+}
@@ -0,0 +1,4 @@+enum Foo {+ A = "Hello, TypeScript!"+}+console.log(Foo.A);
@@ -0,0 +1 @@+console.log("Hello, TypeScript!");
@@ -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);+});
@@ -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 };