@poppinss/ts-exec 1.4.4 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +16 -0
- package/build/index.js +228 -2
- package/build/src/debug.d.ts +1 -1
- package/build/src/loader.d.ts +10 -6
- package/build/src/transform.d.ts +1 -1
- package/package.json +24 -25
- package/build/src/loader.js +0 -227
package/README.md
CHANGED
|
@@ -189,6 +189,22 @@ If you have `rewriteRelativeImportExtensions` enabled in your TypeScript configu
|
|
|
189
189
|
|
|
190
190
|
<br />
|
|
191
191
|
|
|
192
|
+
### Files loaded using `require`
|
|
193
|
+
|
|
194
|
+
TypeScript files loaded using `require` (for example, via `createRequire`) are also compiled by `ts-exec`, so enums and decorators work inside them. The same file resolution rules apply to them as well. You must enable the `rewriteRelativeImportExtensions` compiler option to require a file using its TypeScript extension.
|
|
195
|
+
|
|
196
|
+
```ts
|
|
197
|
+
import { createRequire } from 'node:module'
|
|
198
|
+
const require = createRequire(import.meta.url)
|
|
199
|
+
|
|
200
|
+
// Needs "rewriteRelativeImportExtensions"
|
|
201
|
+
const { Role } = require('./role.cts')
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The `.jsx` and `.tsx` files are always compiled as ES modules, including when they are loaded using `require`. Therefore, they cannot use `module.exports` or other CommonJS globals.
|
|
205
|
+
|
|
206
|
+
<br />
|
|
207
|
+
|
|
192
208
|
## 🤔 Why not tsx?
|
|
193
209
|
|
|
194
210
|
If you're currently using `tsx`, you might wonder why to switch. The answer depends on your priorities.
|
package/build/index.js
CHANGED
|
@@ -1,4 +1,230 @@
|
|
|
1
1
|
// index.ts
|
|
2
|
-
import {
|
|
2
|
+
import { registerHooks } from "module";
|
|
3
|
+
|
|
4
|
+
// src/loader.ts
|
|
5
|
+
import { extname } from "path";
|
|
6
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
7
|
+
|
|
8
|
+
// src/debug.ts
|
|
9
|
+
import { debuglog } from "util";
|
|
10
|
+
var debug_default = debuglog("ts-exec");
|
|
11
|
+
|
|
12
|
+
// src/get_config.ts
|
|
13
|
+
import { fileURLToPath } from "url";
|
|
14
|
+
import { getTsconfig } from "get-tsconfig";
|
|
15
|
+
var DEFAULT_CONFIG = {
|
|
16
|
+
sourceMaps: true,
|
|
17
|
+
module: {
|
|
18
|
+
type: "es6"
|
|
19
|
+
},
|
|
20
|
+
jsc: {
|
|
21
|
+
target: "esnext",
|
|
22
|
+
externalHelpers: false,
|
|
23
|
+
parser: {
|
|
24
|
+
syntax: "typescript",
|
|
25
|
+
tsx: true,
|
|
26
|
+
decorators: true,
|
|
27
|
+
dynamicImport: true
|
|
28
|
+
},
|
|
29
|
+
transform: {
|
|
30
|
+
decoratorMetadata: true,
|
|
31
|
+
legacyDecorator: true,
|
|
32
|
+
verbatimModuleSyntax: true,
|
|
33
|
+
useDefineForClassFields: true,
|
|
34
|
+
react: {
|
|
35
|
+
runtime: "automatic"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
experimental: {
|
|
39
|
+
keepImportAttributes: true
|
|
40
|
+
},
|
|
41
|
+
keepClassNames: true
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
function tsConfigToSwcConfig(tsConfig2) {
|
|
45
|
+
const tsTarget = tsConfig2.compilerOptions?.target?.toLowerCase();
|
|
46
|
+
return {
|
|
47
|
+
sourceMaps: tsConfig2.compilerOptions?.sourceMap ?? true,
|
|
48
|
+
module: {
|
|
49
|
+
/**
|
|
50
|
+
* Since, we will run the SWC transformer via Nodejs loader hooks, the
|
|
51
|
+
* entry point will always be ES6
|
|
52
|
+
*/
|
|
53
|
+
type: "es6"
|
|
54
|
+
},
|
|
55
|
+
jsc: {
|
|
56
|
+
target: tsTarget ? tsTarget === "es6" ? "esnext" : tsTarget : "esnext",
|
|
57
|
+
baseUrl: tsConfig2.compilerOptions?.baseUrl,
|
|
58
|
+
externalHelpers: false,
|
|
59
|
+
parser: {
|
|
60
|
+
syntax: "typescript",
|
|
61
|
+
tsx: !!tsConfig2.compilerOptions?.jsx,
|
|
62
|
+
decorators: true,
|
|
63
|
+
dynamicImport: true
|
|
64
|
+
},
|
|
65
|
+
transform: {
|
|
66
|
+
...tsConfig2.compilerOptions?.emitDecoratorMetadata ? {
|
|
67
|
+
decoratorMetadata: true
|
|
68
|
+
} : {},
|
|
69
|
+
...tsConfig2.compilerOptions?.experimentalDecorators ? {
|
|
70
|
+
legacyDecorator: true
|
|
71
|
+
} : {},
|
|
72
|
+
...tsConfig2.compilerOptions?.verbatimModuleSyntax ? {
|
|
73
|
+
verbatimModuleSyntax: true
|
|
74
|
+
} : {},
|
|
75
|
+
...tsConfig2.compilerOptions?.useDefineForClassFields ? {
|
|
76
|
+
useDefineForClassFields: true
|
|
77
|
+
} : {},
|
|
78
|
+
react: {
|
|
79
|
+
runtime: "automatic",
|
|
80
|
+
...tsConfig2.compilerOptions?.jsxImportSource ? {
|
|
81
|
+
importSource: tsConfig2.compilerOptions?.jsxImportSource
|
|
82
|
+
} : {}
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
experimental: {
|
|
86
|
+
keepImportAttributes: true
|
|
87
|
+
},
|
|
88
|
+
keepClassNames: true
|
|
89
|
+
}
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function getConfig(searchPath) {
|
|
93
|
+
const tsConfig2 = getTsconfig(
|
|
94
|
+
typeof searchPath === "string" ? searchPath : fileURLToPath(searchPath)
|
|
95
|
+
);
|
|
96
|
+
if (!tsConfig2) {
|
|
97
|
+
debug_default("Unable to locate tsconfig file");
|
|
98
|
+
return {
|
|
99
|
+
tsConfig: null,
|
|
100
|
+
tsConfigPath: null,
|
|
101
|
+
swcConfig: {
|
|
102
|
+
...DEFAULT_CONFIG
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
debug_default("tsConfig %O", tsConfig2.config);
|
|
107
|
+
const swcConfig2 = tsConfigToSwcConfig(tsConfig2.config);
|
|
108
|
+
debug_default("swcConfig %O", swcConfig2);
|
|
109
|
+
return { tsConfig: tsConfig2.config, tsConfigPath: tsConfig2.path, swcConfig: swcConfig2 };
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// src/transform.ts
|
|
113
|
+
import { transformSync as swcTransformSync } from "@swc/core";
|
|
114
|
+
function transformSync(source, options) {
|
|
115
|
+
const input = `${source ?? ""}`;
|
|
116
|
+
const { format, ...rest } = options;
|
|
117
|
+
rest.module.type = format === "commonjs-typescript" ? "commonjs" : "es6";
|
|
118
|
+
return swcTransformSync(input, rest);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
// src/loader.ts
|
|
122
|
+
var swcConfig;
|
|
123
|
+
var tsConfig;
|
|
124
|
+
function isTypeScriptFile(filePath) {
|
|
125
|
+
return !filePath.endsWith(".d.ts") && (filePath.endsWith(".ts") || filePath.endsWith(".tsx") || filePath.endsWith(".mts") || filePath.endsWith(".cts"));
|
|
126
|
+
}
|
|
127
|
+
function isLocalPath(specifier) {
|
|
128
|
+
return specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:");
|
|
129
|
+
}
|
|
130
|
+
function wrapAndReThrowSwcError(error) {
|
|
131
|
+
const errorHints = `${error.filename}:${error.startLine}
|
|
132
|
+
${error.snippet}
|
|
133
|
+
`;
|
|
134
|
+
switch (error.code) {
|
|
135
|
+
case "UnsupportedSyntax": {
|
|
136
|
+
const unsupportedSyntaxError = new Error(error.message);
|
|
137
|
+
unsupportedSyntaxError.name = "UnsupportedSyntaxError";
|
|
138
|
+
unsupportedSyntaxError.stack = `${errorHints}${unsupportedSyntaxError.stack}`;
|
|
139
|
+
throw unsupportedSyntaxError;
|
|
140
|
+
}
|
|
141
|
+
case "InvalidSyntax": {
|
|
142
|
+
const syntaxError = new SyntaxError(error.message);
|
|
143
|
+
syntaxError.stack = `${errorHints}${syntaxError.stack}`;
|
|
144
|
+
throw syntaxError;
|
|
145
|
+
}
|
|
146
|
+
default:
|
|
147
|
+
throw new Error(error.message);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
function initialize() {
|
|
151
|
+
const searchPath = process.env.TS_EXEC_PWD ?? process.cwd();
|
|
152
|
+
const config = getConfig(searchPath);
|
|
153
|
+
swcConfig = config.swcConfig;
|
|
154
|
+
tsConfig = config.tsConfig;
|
|
155
|
+
}
|
|
156
|
+
var resolve = (specifier, context, nextResolve) => {
|
|
157
|
+
debug_default("resolving specifier %s", specifier);
|
|
158
|
+
const [pathname] = specifier.split("?");
|
|
159
|
+
if (!tsConfig?.compilerOptions?.rewriteRelativeImportExtensions && context.parentURL && isTypeScriptFile(pathname)) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`Cannot import "${specifier}" using "${extname(pathname)}" extension. Enable "compilerOptions.rewriteRelativeImportExtensions" to import TypeScript files`
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
return nextResolve(specifier, context);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
if (error.code === "ERR_MODULE_NOT_FOUND" && error.url && isLocalPath(error.url)) {
|
|
168
|
+
let [urlPathname, ...urlQs] = error.url.split("?");
|
|
169
|
+
const fileExtension = extname(urlPathname);
|
|
170
|
+
const testExtensions = [];
|
|
171
|
+
if ([".js", ".mjs", ".cjs", ".jsx"].includes(fileExtension)) {
|
|
172
|
+
testExtensions.push(fileExtension.replace("js", "ts"));
|
|
173
|
+
}
|
|
174
|
+
if (fileExtension === ".js") {
|
|
175
|
+
testExtensions.push(".tsx");
|
|
176
|
+
}
|
|
177
|
+
for (const ext of testExtensions) {
|
|
178
|
+
const tryPath = urlPathname.slice(0, -fileExtension.length) + ext;
|
|
179
|
+
try {
|
|
180
|
+
const url = urlQs.length ? `${tryPath}?${urlQs.join("?")}` : tryPath;
|
|
181
|
+
debug_default("retrying to resolve file with specifier %s", url);
|
|
182
|
+
return nextResolve(url, context);
|
|
183
|
+
} catch {
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
throw error;
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
var load = function load2(url, context, nextLoad) {
|
|
191
|
+
const { format } = context;
|
|
192
|
+
debug_default("load file %s, %O", url, context);
|
|
193
|
+
if (format && (format === "module-typescript" || format === "commonjs-typescript") || url.endsWith(".tsx") || url.endsWith(".jsx")) {
|
|
194
|
+
try {
|
|
195
|
+
const { source } = nextLoad(url, {
|
|
196
|
+
...context,
|
|
197
|
+
format: "module"
|
|
198
|
+
});
|
|
199
|
+
const { code, map } = transformSync(source.toString(), {
|
|
200
|
+
format: format ?? "module-tsx",
|
|
201
|
+
filename: fileURLToPath2(url),
|
|
202
|
+
...swcConfig
|
|
203
|
+
});
|
|
204
|
+
let output = code;
|
|
205
|
+
if (map) {
|
|
206
|
+
const base64SourceMap = Buffer.from(map).toString("base64");
|
|
207
|
+
output = `${code}
|
|
208
|
+
|
|
209
|
+
//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`;
|
|
210
|
+
}
|
|
211
|
+
return {
|
|
212
|
+
format: format ? format.replace("-typescript", "") : "module",
|
|
213
|
+
source: `${output}
|
|
214
|
+
|
|
215
|
+
//# sourceURL=${url}`
|
|
216
|
+
};
|
|
217
|
+
} catch (error) {
|
|
218
|
+
if (error.code !== void 0) {
|
|
219
|
+
wrapAndReThrowSwcError(error);
|
|
220
|
+
}
|
|
221
|
+
throw error;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
return nextLoad(url, context);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
// index.ts
|
|
3
228
|
process.setSourceMapsEnabled(true);
|
|
4
|
-
|
|
229
|
+
initialize();
|
|
230
|
+
registerHooks({ resolve, load });
|
package/build/src/debug.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("util").DebugLogger;
|
|
1
|
+
declare const _default: import("node:util").DebugLogger;
|
|
2
2
|
export default _default;
|
package/build/src/loader.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { LoadHookSync, ResolveHookSync } from 'node:module';
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
3
|
+
* Loads the tsconfig file and computes the SWC config. Must be called
|
|
4
|
+
* before registering the hooks
|
|
4
5
|
*/
|
|
5
|
-
export declare function initialize():
|
|
6
|
+
export declare function initialize(): void;
|
|
6
7
|
/**
|
|
7
8
|
* Resolve hook to rewrite ".js" imports to ".ts" file only when
|
|
8
9
|
* "allowArbitraryExtensions" is not enabled. Otherwise, we expect
|
|
@@ -13,8 +14,11 @@ export declare function initialize(): Promise<void>;
|
|
|
13
14
|
* For example, someone registers a loader to import files from Github and
|
|
14
15
|
* our extension rewrite checks for same file on disk, hence it will fail.
|
|
15
16
|
*/
|
|
16
|
-
export declare const resolve:
|
|
17
|
+
export declare const resolve: ResolveHookSync;
|
|
17
18
|
/**
|
|
18
|
-
* Load hook to compile TypeScript and JSX files on the fly
|
|
19
|
+
* Load hook to compile TypeScript and JSX files on the fly.
|
|
20
|
+
*
|
|
21
|
+
* Node.js does not report a format for ".jsx" and ".tsx" files, hence
|
|
22
|
+
* they are always compiled as ES modules, even when loaded via "require".
|
|
19
23
|
*/
|
|
20
|
-
export declare const load:
|
|
24
|
+
export declare const load: LoadHookSync;
|
package/build/src/transform.d.ts
CHANGED
|
@@ -5,4 +5,4 @@ import { type Config as SwcConfig } from '@swc/core';
|
|
|
5
5
|
export declare function transformSync(source: string, options: SwcConfig & {
|
|
6
6
|
filename: string;
|
|
7
7
|
format: 'module-typescript' | 'commonjs-typescript' | 'module-tsx';
|
|
8
|
-
}):
|
|
8
|
+
}): import("@swc/types").Output;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@poppinss/ts-exec",
|
|
3
3
|
"description": "TypeScript JIT compiler built for correctness and supports legacy/experimental decorators",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=24.0.0"
|
|
7
7
|
},
|
|
@@ -27,33 +27,33 @@
|
|
|
27
27
|
"version": "npm run build",
|
|
28
28
|
"prepublishOnly": "npm run build",
|
|
29
29
|
"release": "release-it",
|
|
30
|
-
"quick:test": "node --
|
|
30
|
+
"quick:test": "node --enable-source-maps bin/test.ts"
|
|
31
31
|
},
|
|
32
32
|
"devDependencies": {
|
|
33
|
-
"@adonisjs/eslint-config": "^3.
|
|
34
|
-
"@adonisjs/prettier-config": "^1.
|
|
35
|
-
"@adonisjs/tsconfig": "^2.0.0
|
|
36
|
-
"@japa/assert": "^4.
|
|
37
|
-
"@japa/expect": "^3.0.
|
|
38
|
-
"@japa/expect-type": "^2.0.
|
|
39
|
-
"@japa/file-system": "^
|
|
40
|
-
"@japa/runner": "^
|
|
41
|
-
"@japa/snapshot": "^2.0.
|
|
42
|
-
"@release-it/conventional-changelog": "^
|
|
43
|
-
"@types/node": "^
|
|
44
|
-
"c8": "^
|
|
45
|
-
"eslint": "^
|
|
46
|
-
"ipaddr.js": "^2.
|
|
47
|
-
"preact": "^
|
|
48
|
-
"preact-render-to-string": "^6.
|
|
49
|
-
"prettier": "^3.
|
|
50
|
-
"release-it": "^
|
|
33
|
+
"@adonisjs/eslint-config": "^3.1.0",
|
|
34
|
+
"@adonisjs/prettier-config": "^1.5.0",
|
|
35
|
+
"@adonisjs/tsconfig": "^2.0.0",
|
|
36
|
+
"@japa/assert": "^4.2.0",
|
|
37
|
+
"@japa/expect": "^3.0.7",
|
|
38
|
+
"@japa/expect-type": "^2.0.4",
|
|
39
|
+
"@japa/file-system": "^3.0.0",
|
|
40
|
+
"@japa/runner": "^5.3.0",
|
|
41
|
+
"@japa/snapshot": "^2.0.10",
|
|
42
|
+
"@release-it/conventional-changelog": "^12.0.2",
|
|
43
|
+
"@types/node": "^26.6.4",
|
|
44
|
+
"c8": "^12.0.0",
|
|
45
|
+
"eslint": "^10.12.0",
|
|
46
|
+
"ipaddr.js": "^2.5.0",
|
|
47
|
+
"preact": "^11.0.0",
|
|
48
|
+
"preact-render-to-string": "^6.8.0",
|
|
49
|
+
"prettier": "^3.9.9",
|
|
50
|
+
"release-it": "^21.1.1",
|
|
51
51
|
"tsup": "^8.5.1",
|
|
52
|
-
"typescript": "^
|
|
52
|
+
"typescript": "^6.0.3"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@swc/core": "~1.
|
|
56
|
-
"get-tsconfig": "^4.
|
|
55
|
+
"@swc/core": "~1.16.13",
|
|
56
|
+
"get-tsconfig": "^4.14.3"
|
|
57
57
|
},
|
|
58
58
|
"homepage": "https://github.com/poppinss/ts-exec#readme",
|
|
59
59
|
"repository": {
|
|
@@ -77,8 +77,7 @@
|
|
|
77
77
|
},
|
|
78
78
|
"tsup": {
|
|
79
79
|
"entry": [
|
|
80
|
-
"index.ts"
|
|
81
|
-
"src/loader.ts"
|
|
80
|
+
"index.ts"
|
|
82
81
|
],
|
|
83
82
|
"outDir": "./build",
|
|
84
83
|
"clean": true,
|
package/build/src/loader.js
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
// src/loader.ts
|
|
2
|
-
import { extname } from "path";
|
|
3
|
-
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4
|
-
|
|
5
|
-
// src/debug.ts
|
|
6
|
-
import { debuglog } from "util";
|
|
7
|
-
var debug_default = debuglog("ts-exec");
|
|
8
|
-
|
|
9
|
-
// src/get_config.ts
|
|
10
|
-
import { fileURLToPath } from "url";
|
|
11
|
-
import { getTsconfig } from "get-tsconfig";
|
|
12
|
-
var DEFAULT_CONFIG = {
|
|
13
|
-
sourceMaps: true,
|
|
14
|
-
module: {
|
|
15
|
-
type: "es6"
|
|
16
|
-
},
|
|
17
|
-
jsc: {
|
|
18
|
-
target: "esnext",
|
|
19
|
-
externalHelpers: false,
|
|
20
|
-
parser: {
|
|
21
|
-
syntax: "typescript",
|
|
22
|
-
tsx: true,
|
|
23
|
-
decorators: true,
|
|
24
|
-
dynamicImport: true
|
|
25
|
-
},
|
|
26
|
-
transform: {
|
|
27
|
-
decoratorMetadata: true,
|
|
28
|
-
legacyDecorator: true,
|
|
29
|
-
verbatimModuleSyntax: true,
|
|
30
|
-
useDefineForClassFields: true,
|
|
31
|
-
react: {
|
|
32
|
-
runtime: "automatic"
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
experimental: {
|
|
36
|
-
keepImportAttributes: true
|
|
37
|
-
},
|
|
38
|
-
keepClassNames: true
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
function tsConfigToSwcConfig(tsConfig2) {
|
|
42
|
-
const tsTarget = tsConfig2.compilerOptions?.target?.toLowerCase();
|
|
43
|
-
return {
|
|
44
|
-
sourceMaps: tsConfig2.compilerOptions?.sourceMap ?? true,
|
|
45
|
-
module: {
|
|
46
|
-
/**
|
|
47
|
-
* Since, we will run the SWC transformer via Nodejs loader hooks, the
|
|
48
|
-
* entry point will always be ES6
|
|
49
|
-
*/
|
|
50
|
-
type: "es6"
|
|
51
|
-
},
|
|
52
|
-
jsc: {
|
|
53
|
-
target: tsTarget ? tsTarget === "es6" ? "esnext" : tsTarget : "esnext",
|
|
54
|
-
baseUrl: tsConfig2.compilerOptions?.baseUrl,
|
|
55
|
-
externalHelpers: false,
|
|
56
|
-
parser: {
|
|
57
|
-
syntax: "typescript",
|
|
58
|
-
tsx: !!tsConfig2.compilerOptions?.jsx,
|
|
59
|
-
decorators: true,
|
|
60
|
-
dynamicImport: true
|
|
61
|
-
},
|
|
62
|
-
transform: {
|
|
63
|
-
...tsConfig2.compilerOptions?.emitDecoratorMetadata ? {
|
|
64
|
-
decoratorMetadata: true
|
|
65
|
-
} : {},
|
|
66
|
-
...tsConfig2.compilerOptions?.experimentalDecorators ? {
|
|
67
|
-
legacyDecorator: true
|
|
68
|
-
} : {},
|
|
69
|
-
...tsConfig2.compilerOptions?.verbatimModuleSyntax ? {
|
|
70
|
-
verbatimModuleSyntax: true
|
|
71
|
-
} : {},
|
|
72
|
-
...tsConfig2.compilerOptions?.useDefineForClassFields ? {
|
|
73
|
-
useDefineForClassFields: true
|
|
74
|
-
} : {},
|
|
75
|
-
react: {
|
|
76
|
-
runtime: "automatic",
|
|
77
|
-
...tsConfig2.compilerOptions?.jsxImportSource ? {
|
|
78
|
-
importSource: tsConfig2.compilerOptions?.jsxImportSource
|
|
79
|
-
} : {}
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
experimental: {
|
|
83
|
-
keepImportAttributes: true
|
|
84
|
-
},
|
|
85
|
-
keepClassNames: true
|
|
86
|
-
}
|
|
87
|
-
};
|
|
88
|
-
}
|
|
89
|
-
function getConfig(searchPath) {
|
|
90
|
-
const tsConfig2 = getTsconfig(
|
|
91
|
-
typeof searchPath === "string" ? searchPath : fileURLToPath(searchPath)
|
|
92
|
-
);
|
|
93
|
-
if (!tsConfig2) {
|
|
94
|
-
debug_default("Unable to locate tsconfig file");
|
|
95
|
-
return {
|
|
96
|
-
tsConfig: null,
|
|
97
|
-
tsConfigPath: null,
|
|
98
|
-
swcConfig: {
|
|
99
|
-
...DEFAULT_CONFIG
|
|
100
|
-
}
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
|
-
debug_default("tsConfig %O", tsConfig2.config);
|
|
104
|
-
const swcConfig2 = tsConfigToSwcConfig(tsConfig2.config);
|
|
105
|
-
debug_default("swcConfig %O", swcConfig2);
|
|
106
|
-
return { tsConfig: tsConfig2.config, tsConfigPath: tsConfig2.path, swcConfig: swcConfig2 };
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
// src/transform.ts
|
|
110
|
-
import { transform as swcTransform } from "@swc/core";
|
|
111
|
-
function transformSync(source, options) {
|
|
112
|
-
const input = `${source ?? ""}`;
|
|
113
|
-
const { format, ...rest } = options;
|
|
114
|
-
rest.module.type = format === "commonjs-typescript" ? "commonjs" : "es6";
|
|
115
|
-
return swcTransform(input, rest);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
// src/loader.ts
|
|
119
|
-
var swcConfig;
|
|
120
|
-
var tsConfig;
|
|
121
|
-
function isTypeScriptFile(filePath) {
|
|
122
|
-
return !filePath.endsWith(".d.ts") && (filePath.endsWith(".ts") || filePath.endsWith(".tsx") || filePath.endsWith(".mts") || filePath.endsWith(".cts"));
|
|
123
|
-
}
|
|
124
|
-
function isLocalPath(specifier) {
|
|
125
|
-
return specifier.startsWith("./") || specifier.startsWith("../") || specifier.startsWith("/") || specifier.startsWith("file:");
|
|
126
|
-
}
|
|
127
|
-
function wrapAndReThrowSwcError(error) {
|
|
128
|
-
const errorHints = `${error.filename}:${error.startLine}
|
|
129
|
-
${error.snippet}
|
|
130
|
-
`;
|
|
131
|
-
switch (error.code) {
|
|
132
|
-
case "UnsupportedSyntax": {
|
|
133
|
-
const unsupportedSyntaxError = new Error(error.message);
|
|
134
|
-
unsupportedSyntaxError.name = "UnsupportedSyntaxError";
|
|
135
|
-
unsupportedSyntaxError.stack = `${errorHints}${unsupportedSyntaxError.stack}`;
|
|
136
|
-
throw unsupportedSyntaxError;
|
|
137
|
-
}
|
|
138
|
-
case "InvalidSyntax": {
|
|
139
|
-
const syntaxError = new SyntaxError(error.message);
|
|
140
|
-
syntaxError.stack = `${errorHints}${syntaxError.stack}`;
|
|
141
|
-
throw syntaxError;
|
|
142
|
-
}
|
|
143
|
-
default:
|
|
144
|
-
throw new Error(error.message);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
async function initialize() {
|
|
148
|
-
const searchPath = process.env.TS_EXEC_PWD ?? process.cwd();
|
|
149
|
-
const config = getConfig(searchPath);
|
|
150
|
-
swcConfig = config.swcConfig;
|
|
151
|
-
tsConfig = config.tsConfig;
|
|
152
|
-
}
|
|
153
|
-
var resolve = async (specifier, context, nextResolve) => {
|
|
154
|
-
debug_default("resolving specifier %s", specifier);
|
|
155
|
-
const [pathname] = specifier.split("?");
|
|
156
|
-
if (!tsConfig?.compilerOptions?.rewriteRelativeImportExtensions && context.parentURL && isTypeScriptFile(pathname)) {
|
|
157
|
-
throw new Error(
|
|
158
|
-
`Cannot import "${specifier}" using "${extname(pathname)}" extension. Enable "compilerOptions.rewriteRelativeImportExtensions" to import TypeScript files`
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
try {
|
|
162
|
-
return await nextResolve(specifier, context);
|
|
163
|
-
} catch (error) {
|
|
164
|
-
if (error.code === "ERR_MODULE_NOT_FOUND" && error.url && isLocalPath(error.url)) {
|
|
165
|
-
let [urlPathname, ...urlQs] = error.url.split("?");
|
|
166
|
-
const fileExtension = extname(urlPathname);
|
|
167
|
-
const testExtensions = [];
|
|
168
|
-
if ([".js", ".mjs", ".cjs", ".jsx"].includes(fileExtension)) {
|
|
169
|
-
testExtensions.push(fileExtension.replace("js", "ts"));
|
|
170
|
-
}
|
|
171
|
-
if (fileExtension === ".js") {
|
|
172
|
-
testExtensions.push(".tsx");
|
|
173
|
-
}
|
|
174
|
-
for (const ext of testExtensions) {
|
|
175
|
-
const tryPath = urlPathname.slice(0, -fileExtension.length) + ext;
|
|
176
|
-
try {
|
|
177
|
-
const url = urlQs.length ? `${tryPath}?${urlQs.join("?")}` : tryPath;
|
|
178
|
-
debug_default("retrying to resolve file with specifier %s", url);
|
|
179
|
-
return await nextResolve(url, context);
|
|
180
|
-
} catch {
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
throw error;
|
|
185
|
-
}
|
|
186
|
-
};
|
|
187
|
-
var load = async function load2(url, context, nextLoad) {
|
|
188
|
-
const { format } = context;
|
|
189
|
-
debug_default("load file %s, %O", url, context);
|
|
190
|
-
if (format && (format === "module-typescript" || format === "commonjs-typescript") || url.endsWith(".tsx") || url.endsWith(".jsx")) {
|
|
191
|
-
try {
|
|
192
|
-
const { source } = await nextLoad(url, {
|
|
193
|
-
...context,
|
|
194
|
-
format: "module"
|
|
195
|
-
});
|
|
196
|
-
const { code, map } = await transformSync(source.toString(), {
|
|
197
|
-
format: format ?? "module-tsx",
|
|
198
|
-
filename: fileURLToPath2(url),
|
|
199
|
-
...swcConfig
|
|
200
|
-
});
|
|
201
|
-
let output = code;
|
|
202
|
-
if (map) {
|
|
203
|
-
const base64SourceMap = Buffer.from(map).toString("base64");
|
|
204
|
-
output = `${code}
|
|
205
|
-
|
|
206
|
-
//# sourceMappingURL=data:application/json;base64,${base64SourceMap}`;
|
|
207
|
-
}
|
|
208
|
-
return {
|
|
209
|
-
format: format ? format.replace("-typescript", "") : "module",
|
|
210
|
-
source: `${output}
|
|
211
|
-
|
|
212
|
-
//# sourceURL=${url}`
|
|
213
|
-
};
|
|
214
|
-
} catch (error) {
|
|
215
|
-
if (error.code !== void 0) {
|
|
216
|
-
wrapAndReThrowSwcError(error);
|
|
217
|
-
}
|
|
218
|
-
throw error;
|
|
219
|
-
}
|
|
220
|
-
}
|
|
221
|
-
return nextLoad(url, context);
|
|
222
|
-
};
|
|
223
|
-
export {
|
|
224
|
-
initialize,
|
|
225
|
-
load,
|
|
226
|
-
resolve
|
|
227
|
-
};
|