-
Notifications
You must be signed in to change notification settings - Fork 15
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
35efcea
commit 6dcdfcc
Showing
7 changed files
with
113 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,8 @@ | |
"deps/**", | ||
"lib/**", | ||
"node_modules/**", | ||
"test/snapshot/**" | ||
"test/snapshot/**", | ||
"test/fixtures/**" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
type SwcError = { | ||
code: "UnsupportedSyntax" | "InvalidSyntax"; | ||
message: string; | ||
}; | ||
|
||
// Type guard to check if error is SwcError | ||
export function isSwcError(error: unknown): error is SwcError { | ||
return (error as SwcError).code !== undefined; | ||
} | ||
|
||
// Since swc throw an object, we need to wrap it in a proper error | ||
export function wrapAndReThrowSwcError(error: SwcError): never { | ||
switch (error.code) { | ||
case "UnsupportedSyntax": { | ||
const unsupportedSyntaxError = new Error(error.message); | ||
unsupportedSyntaxError.name = "UnsupportedSyntaxError"; | ||
throw unsupportedSyntaxError; | ||
} | ||
case "InvalidSyntax": | ||
throw new SyntaxError(error.message); | ||
default: | ||
throw error; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,42 @@ | ||
import type { LoadFnOutput, LoadHookContext } from "node:module"; | ||
import type { Options } from "../lib/wasm"; | ||
import { isSwcError, wrapAndReThrowSwcError } from "./errors.js"; | ||
import { transformSync } from "./index.js"; | ||
|
||
type NextLoad = ( | ||
url: string, | ||
context?: LoadHookContext, | ||
) => LoadFnOutput | Promise<LoadFnOutput>; | ||
|
||
export async function load( | ||
url: string, | ||
context: LoadHookContext, | ||
nextLoad: NextLoad, | ||
nextLoad: ( | ||
url: string, | ||
context?: LoadHookContext, | ||
) => LoadFnOutput | Promise<LoadFnOutput>, | ||
) { | ||
const { format } = context; | ||
if (format.endsWith("-typescript")) { | ||
// Use format 'module' so it returns the source as-is, without stripping the types. | ||
// Format 'commonjs' would not return the source for historical reasons. | ||
const { source } = await nextLoad(url, { | ||
...context, | ||
format: "module", | ||
}); | ||
// biome-ignore lint/style/noNonNullAssertion: If module exists, it will have a source | ||
const { code } = transformSync(source!.toString(), { | ||
mode: "strip-only", | ||
} as Options); | ||
return { | ||
format: format.replace("-typescript", ""), | ||
// Source map is not necessary in strip-only mode. However, to map the source | ||
// file in debuggers to the original TypeScript source, add a sourceURL magic | ||
// comment to hint that it is a generated source. | ||
source: `${code}\n\n//# sourceURL=${url}`, | ||
}; | ||
try { | ||
const { source } = await nextLoad(url, { | ||
...context, | ||
format: "module", | ||
}); | ||
// biome-ignore lint/style/noNonNullAssertion: If module exists, it will have a source | ||
const { code } = transformSync(source!.toString(), { | ||
mode: "strip-only", | ||
}); | ||
return { | ||
format: format.replace("-typescript", ""), | ||
// Source map is not necessary in strip-only mode. However, to map the source | ||
// file in debuggers to the original TypeScript source, add a sourceURL magic | ||
// comment to hint that it is a generated source. | ||
source: `${code}\n\n//# sourceURL=${url}`, | ||
}; | ||
} catch (error: unknown) { | ||
if (isSwcError(error)) { | ||
wrapAndReThrowSwcError(error); | ||
} | ||
// If the error is not an SwcError, rethrow it | ||
throw error; | ||
} | ||
} | ||
return nextLoad(url, context); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,44 +1,51 @@ | ||
import type { LoadFnOutput, LoadHookContext } from "node:module"; | ||
import type { Options } from "../lib/wasm"; | ||
import { isSwcError, wrapAndReThrowSwcError } from "./errors.js"; | ||
import { transformSync } from "./index.js"; | ||
|
||
type NextLoad = ( | ||
url: string, | ||
context?: LoadHookContext, | ||
) => LoadFnOutput | Promise<LoadFnOutput>; | ||
|
||
export async function load( | ||
url: string, | ||
context: LoadHookContext, | ||
nextLoad: NextLoad, | ||
nextLoad: ( | ||
url: string, | ||
context?: LoadHookContext, | ||
) => LoadFnOutput | Promise<LoadFnOutput>, | ||
) { | ||
const { format } = context; | ||
if (format.endsWith("-typescript")) { | ||
// Use format 'module' so it returns the source as-is, without stripping the types. | ||
// Format 'commonjs' would not return the source for historical reasons. | ||
const { source } = await nextLoad(url, { | ||
...context, | ||
format: "module", | ||
}); | ||
try { | ||
// Use format 'module' so it returns the source as-is, without stripping the types. | ||
// Format 'commonjs' would not return the source for historical reasons. | ||
const { source } = await nextLoad(url, { | ||
...context, | ||
format: "module", | ||
}); | ||
|
||
// biome-ignore lint/style/noNonNullAssertion: If module exists, it will have a source | ||
const { code, map } = transformSync(source!.toString(), { | ||
mode: "transform", | ||
sourceMap: true, | ||
filename: url, | ||
} as Options); | ||
// biome-ignore lint/style/noNonNullAssertion: If module exists, it will have a source | ||
const { code, map } = transformSync(source!.toString(), { | ||
mode: "transform", | ||
sourceMap: true, | ||
filename: url, | ||
} as Options); | ||
|
||
let output = code; | ||
let output = code; | ||
|
||
if (map) { | ||
const base64SourceMap = Buffer.from(map).toString("base64"); | ||
output = `${code}\n\n//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`; | ||
} | ||
if (map) { | ||
const base64SourceMap = Buffer.from(map).toString("base64"); | ||
output = `${code}\n\n//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`; | ||
} | ||
|
||
return { | ||
format: format.replace("-typescript", ""), | ||
source: `${output}\n\n//# sourceURL=${url}`, | ||
}; | ||
return { | ||
format: format.replace("-typescript", ""), | ||
source: `${output}\n\n//# sourceURL=${url}`, | ||
}; | ||
} catch (error) { | ||
if (isSwcError(error)) { | ||
wrapAndReThrowSwcError(error); | ||
} | ||
// If the error is not an SwcError, rethrow it | ||
throw error; | ||
} | ||
} | ||
return nextLoad(url, context); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
function foo(){ | ||
await Promise.resolve(); | ||
Check failure on line 2 in test/fixtures/invalid-syntax.ts GitHub Actions / ubuntu-latest w/ Node.js 22.x
Check failure on line 2 in test/fixtures/invalid-syntax.ts GitHub Actions / macos-latest w/ Node.js 22.x
Check failure on line 2 in test/fixtures/invalid-syntax.ts GitHub Actions / windows-latest w/ Node.js 22.x
Check failure on line 2 in test/fixtures/invalid-syntax.ts GitHub Actions / ubuntu-latest w/ Node.js 23.x
Check failure on line 2 in test/fixtures/invalid-syntax.ts GitHub Actions / macos-latest w/ Node.js 23.x
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters