@ttsc/unplugin 0.16.12 → 0.17.1
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/lib/bun-register.d.ts +19 -0
- package/lib/bun-register.js +47 -0
- package/lib/bun-register.js.map +1 -0
- package/lib/bun-register.mjs +42 -0
- package/lib/bun-register.mjs.map +1 -0
- package/lib/bun.d.ts +14 -2
- package/lib/bun.js +19 -4
- package/lib/bun.js.map +1 -1
- package/lib/bun.mjs +19 -4
- package/lib/bun.mjs.map +1 -1
- package/package.json +7 -2
- package/src/bun-register.ts +57 -0
- package/src/bun.ts +30 -6
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { TtscUnpluginOptions } from "./core/options";
|
|
2
|
+
/**
|
|
3
|
+
* Register the ttsc transform as a Bun **runtime** plugin.
|
|
4
|
+
*
|
|
5
|
+
* The other `@ttsc/unplugin/*` adapters cover bundlers (`Bun.build`, Vite,
|
|
6
|
+
* Webpack, …). This entry is the runtime counterpart: loading it registers the
|
|
7
|
+
* same transform on Bun's module loader, so `bun run` / `bun test` apply ttsc
|
|
8
|
+
* plugins (e.g. typia's `typia/lib/transform`) as files are imported, with no
|
|
9
|
+
* bundling step. Wire it up once via a `bunfig.toml` preload entry —
|
|
10
|
+
* `preload = ["@ttsc/unplugin/bun-register"]` — or imperatively with
|
|
11
|
+
* `import "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
12
|
+
* `tsconfig.json`, identical to the bundler adapters.
|
|
13
|
+
*
|
|
14
|
+
* @throws When called explicitly off the Bun runtime (`globalThis.Bun.plugin`
|
|
15
|
+
* is unavailable). The auto-registration below stays silent off Bun so the
|
|
16
|
+
* module is harmless to import from Node (tests, tooling).
|
|
17
|
+
*/
|
|
18
|
+
export declare function register(options?: TtscUnpluginOptions): void;
|
|
19
|
+
export default register;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var bun = require('./bun.js');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Register the ttsc transform as a Bun **runtime** plugin.
|
|
9
|
+
*
|
|
10
|
+
* The other `@ttsc/unplugin/*` adapters cover bundlers (`Bun.build`, Vite,
|
|
11
|
+
* Webpack, …). This entry is the runtime counterpart: loading it registers the
|
|
12
|
+
* same transform on Bun's module loader, so `bun run` / `bun test` apply ttsc
|
|
13
|
+
* plugins (e.g. typia's `typia/lib/transform`) as files are imported, with no
|
|
14
|
+
* bundling step. Wire it up once via a `bunfig.toml` preload entry —
|
|
15
|
+
* `preload = ["@ttsc/unplugin/bun-register"]` — or imperatively with
|
|
16
|
+
* `import "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
17
|
+
* `tsconfig.json`, identical to the bundler adapters.
|
|
18
|
+
*
|
|
19
|
+
* @throws When called explicitly off the Bun runtime (`globalThis.Bun.plugin`
|
|
20
|
+
* is unavailable). The auto-registration below stays silent off Bun so the
|
|
21
|
+
* module is harmless to import from Node (tests, tooling).
|
|
22
|
+
*/
|
|
23
|
+
function register(options) {
|
|
24
|
+
const runtime = bunRuntime();
|
|
25
|
+
if (runtime === undefined) {
|
|
26
|
+
throw new Error("@ttsc/unplugin/bun-register must run under the Bun runtime " +
|
|
27
|
+
"(globalThis.Bun.plugin is unavailable). Use a bundler adapter such as " +
|
|
28
|
+
"@ttsc/unplugin/vite for non-Bun toolchains.");
|
|
29
|
+
}
|
|
30
|
+
runtime.plugin(bun.default(options));
|
|
31
|
+
}
|
|
32
|
+
function bunRuntime() {
|
|
33
|
+
const runtime = globalThis.Bun;
|
|
34
|
+
return runtime !== undefined && typeof runtime.plugin === "function"
|
|
35
|
+
? runtime
|
|
36
|
+
: undefined;
|
|
37
|
+
}
|
|
38
|
+
// Auto-register on import so a `bunfig.toml` `preload` entry — which only
|
|
39
|
+
// imports the module — takes effect. Guarded so importing from Node (a stray
|
|
40
|
+
// import, or a unit test) is a harmless no-op rather than a throw.
|
|
41
|
+
if (bunRuntime() !== undefined) {
|
|
42
|
+
register();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
exports.default = register;
|
|
46
|
+
exports.register = register;
|
|
47
|
+
//# sourceMappingURL=bun-register.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun-register.js","sources":["../src/bun-register.ts"],"sourcesContent":[null],"names":["bun"],"mappings":";;;;;;AAcA;;;;;;;;;;;;;;;AAeG;AACG,SAAU,QAAQ,CAAC,OAA6B,EAAA;AACpD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,IAAI,OAAO,KAAK,SAAS,EAAE;QACzB,MAAM,IAAI,KAAK,CACb,6DAA6D;YAC3D,wEAAwE;AACxE,YAAA,6CAA6C,CAChD;IACH;IACA,OAAO,CAAC,MAAM,CAACA,WAAG,CAAC,OAAO,CAAC,CAAC;AAC9B;AAEA,SAAS,UAAU,GAAA;AACjB,IAAA,MAAM,OAAO,GAAI,UAAyC,CAAC,GAAG;IAC9D,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK;AACxD,UAAE;UACA,SAAS;AACf;AAEA;AACA;AACA;AACA,IAAI,UAAU,EAAE,KAAK,SAAS,EAAE;AAC9B,IAAA,QAAQ,EAAE;AACZ;;;;;"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import bun from './bun.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Register the ttsc transform as a Bun **runtime** plugin.
|
|
5
|
+
*
|
|
6
|
+
* The other `@ttsc/unplugin/*` adapters cover bundlers (`Bun.build`, Vite,
|
|
7
|
+
* Webpack, …). This entry is the runtime counterpart: loading it registers the
|
|
8
|
+
* same transform on Bun's module loader, so `bun run` / `bun test` apply ttsc
|
|
9
|
+
* plugins (e.g. typia's `typia/lib/transform`) as files are imported, with no
|
|
10
|
+
* bundling step. Wire it up once via a `bunfig.toml` preload entry —
|
|
11
|
+
* `preload = ["@ttsc/unplugin/bun-register"]` — or imperatively with
|
|
12
|
+
* `import "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
13
|
+
* `tsconfig.json`, identical to the bundler adapters.
|
|
14
|
+
*
|
|
15
|
+
* @throws When called explicitly off the Bun runtime (`globalThis.Bun.plugin`
|
|
16
|
+
* is unavailable). The auto-registration below stays silent off Bun so the
|
|
17
|
+
* module is harmless to import from Node (tests, tooling).
|
|
18
|
+
*/
|
|
19
|
+
function register(options) {
|
|
20
|
+
const runtime = bunRuntime();
|
|
21
|
+
if (runtime === undefined) {
|
|
22
|
+
throw new Error("@ttsc/unplugin/bun-register must run under the Bun runtime " +
|
|
23
|
+
"(globalThis.Bun.plugin is unavailable). Use a bundler adapter such as " +
|
|
24
|
+
"@ttsc/unplugin/vite for non-Bun toolchains.");
|
|
25
|
+
}
|
|
26
|
+
runtime.plugin(bun(options));
|
|
27
|
+
}
|
|
28
|
+
function bunRuntime() {
|
|
29
|
+
const runtime = globalThis.Bun;
|
|
30
|
+
return runtime !== undefined && typeof runtime.plugin === "function"
|
|
31
|
+
? runtime
|
|
32
|
+
: undefined;
|
|
33
|
+
}
|
|
34
|
+
// Auto-register on import so a `bunfig.toml` `preload` entry — which only
|
|
35
|
+
// imports the module — takes effect. Guarded so importing from Node (a stray
|
|
36
|
+
// import, or a unit test) is a harmless no-op rather than a throw.
|
|
37
|
+
if (bunRuntime() !== undefined) {
|
|
38
|
+
register();
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { register as default, register };
|
|
42
|
+
//# sourceMappingURL=bun-register.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bun-register.mjs","sources":["../src/bun-register.ts"],"sourcesContent":[null],"names":[],"mappings":";;AAcA;;;;;;;;;;;;;;;AAeG;AACG,SAAU,QAAQ,CAAC,OAA6B,EAAA;AACpD,IAAA,MAAM,OAAO,GAAG,UAAU,EAAE;AAC5B,IAAA,IAAI,OAAO,KAAK,SAAS,EAAE;QACzB,MAAM,IAAI,KAAK,CACb,6DAA6D;YAC3D,wEAAwE;AACxE,YAAA,6CAA6C,CAChD;IACH;IACA,OAAO,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC9B;AAEA,SAAS,UAAU,GAAA;AACjB,IAAA,MAAM,OAAO,GAAI,UAAyC,CAAC,GAAG;IAC9D,OAAO,OAAO,KAAK,SAAS,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK;AACxD,UAAE;UACA,SAAS;AACf;AAEA;AACA;AACA;AACA,IAAI,UAAU,EAAE,KAAK,SAAS,EAAE;AAC9B,IAAA,QAAQ,EAAE;AACZ;;;;"}
|
package/lib/bun.d.ts
CHANGED
|
@@ -12,6 +12,8 @@ export interface BunLikePlugin {
|
|
|
12
12
|
/** Called by Bun when the plugin is registered. */
|
|
13
13
|
setup(build: BunLikeBuild): void | Promise<void>;
|
|
14
14
|
}
|
|
15
|
+
/** Bun loader identifiers this adapter can emit (only TypeScript is matched). */
|
|
16
|
+
export type BunLoader = "ts" | "tsx";
|
|
15
17
|
/**
|
|
16
18
|
* Minimal subset of the Bun `BuildConfig` plugin build object.
|
|
17
19
|
*
|
|
@@ -23,7 +25,10 @@ export interface BunLikeBuild {
|
|
|
23
25
|
* Register a loader callback for files matching `filter`.
|
|
24
26
|
*
|
|
25
27
|
* The callback receives the absolute file path and must return the
|
|
26
|
-
* transformed file contents.
|
|
28
|
+
* transformed file contents plus the `loader` Bun should apply next. The
|
|
29
|
+
* `loader` matters most for the runtime path (`Bun.plugin`), where Bun must
|
|
30
|
+
* be told the returned contents are still TypeScript so it keeps transpiling
|
|
31
|
+
* them before execution.
|
|
27
32
|
*/
|
|
28
33
|
onLoad(options: {
|
|
29
34
|
filter: RegExp;
|
|
@@ -31,15 +36,22 @@ export interface BunLikeBuild {
|
|
|
31
36
|
path: string;
|
|
32
37
|
}) => Promise<{
|
|
33
38
|
contents: string;
|
|
39
|
+
loader: BunLoader;
|
|
34
40
|
}>): void;
|
|
35
41
|
}
|
|
36
42
|
/**
|
|
37
|
-
* Create a ttsc plugin for Bun's bundler.
|
|
43
|
+
* Create a ttsc plugin for Bun's bundler AND runtime.
|
|
38
44
|
*
|
|
39
45
|
* Bun does not implement the unplugin protocol, so this adapter instantiates
|
|
40
46
|
* the raw unplugin transform and wires it to Bun's `onLoad` hook manually. The
|
|
41
47
|
* adapter reads each matching file from disk and forwards the content to the
|
|
42
48
|
* ttsc transform; if the transform returns no changes the original source is
|
|
43
49
|
* passed through unchanged.
|
|
50
|
+
*
|
|
51
|
+
* The same object works for `Bun.build({ plugins: [ttsc()] })` (bundler) and
|
|
52
|
+
* for `Bun.plugin(ttsc())` / a `bunfig.toml` preload (runtime) — see
|
|
53
|
+
* `bun-register`. Every result carries an explicit `loader` so Bun keeps
|
|
54
|
+
* transpiling the emitted TypeScript at runtime; `sourceFilePattern` only
|
|
55
|
+
* matches TypeScript, so the loader is always `ts`/`tsx`.
|
|
44
56
|
*/
|
|
45
57
|
export default function bun(options?: TtscUnpluginOptions): BunLikePlugin;
|
package/lib/bun.js
CHANGED
|
@@ -6,13 +6,19 @@ var fs = require('node:fs/promises');
|
|
|
6
6
|
var index = require('./core/index.js');
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
|
-
* Create a ttsc plugin for Bun's bundler.
|
|
9
|
+
* Create a ttsc plugin for Bun's bundler AND runtime.
|
|
10
10
|
*
|
|
11
11
|
* Bun does not implement the unplugin protocol, so this adapter instantiates
|
|
12
12
|
* the raw unplugin transform and wires it to Bun's `onLoad` hook manually. The
|
|
13
13
|
* adapter reads each matching file from disk and forwards the content to the
|
|
14
14
|
* ttsc transform; if the transform returns no changes the original source is
|
|
15
15
|
* passed through unchanged.
|
|
16
|
+
*
|
|
17
|
+
* The same object works for `Bun.build({ plugins: [ttsc()] })` (bundler) and
|
|
18
|
+
* for `Bun.plugin(ttsc())` / a `bunfig.toml` preload (runtime) — see
|
|
19
|
+
* `bun-register`. Every result carries an explicit `loader` so Bun keeps
|
|
20
|
+
* transpiling the emitted TypeScript at runtime; `sourceFilePattern` only
|
|
21
|
+
* matches TypeScript, so the loader is always `ts`/`tsx`.
|
|
16
22
|
*/
|
|
17
23
|
function bun(options) {
|
|
18
24
|
return {
|
|
@@ -20,25 +26,34 @@ function bun(options) {
|
|
|
20
26
|
setup(build) {
|
|
21
27
|
const raw = index.default.raw(options, {});
|
|
22
28
|
build.onLoad({ filter: index.sourceFilePattern }, async (args) => {
|
|
29
|
+
const loader = bunLoaderFor(args.path);
|
|
23
30
|
const source = await fs.readFile(args.path, "utf8");
|
|
24
31
|
const result = typeof raw.transform === "function"
|
|
25
32
|
? await raw.transform.call({}, source, args.path)
|
|
26
33
|
: undefined;
|
|
27
34
|
// Unpack both shorthand string and object result shapes.
|
|
28
35
|
if (typeof result === "string") {
|
|
29
|
-
return { contents: result };
|
|
36
|
+
return { contents: result, loader };
|
|
30
37
|
}
|
|
31
38
|
if (typeof result === "object" &&
|
|
32
39
|
result !== null &&
|
|
33
40
|
"code" in result &&
|
|
34
41
|
typeof result.code === "string") {
|
|
35
|
-
return { contents: result.code };
|
|
42
|
+
return { contents: result.code, loader };
|
|
36
43
|
}
|
|
37
|
-
return { contents: source };
|
|
44
|
+
return { contents: source, loader };
|
|
38
45
|
});
|
|
39
46
|
},
|
|
40
47
|
};
|
|
41
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* Pick the Bun loader for a matched file. `sourceFilePattern` is
|
|
51
|
+
* `/\.[cm]?tsx?$/`, so a trailing `x` (`.tsx`/`.ctsx`/`.mtsx`) is JSX-flavored
|
|
52
|
+
* TypeScript and everything else (`.ts`/`.cts`/`.mts`) is plain TypeScript.
|
|
53
|
+
*/
|
|
54
|
+
function bunLoaderFor(filePath) {
|
|
55
|
+
return /x$/i.test(filePath) ? "tsx" : "ts";
|
|
56
|
+
}
|
|
42
57
|
|
|
43
58
|
exports.default = bun;
|
|
44
59
|
//# sourceMappingURL=bun.js.map
|
package/lib/bun.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.js","sources":["../src/bun.ts"],"sourcesContent":[null],"names":["unplugin","sourceFilePattern"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"bun.js","sources":["../src/bun.ts"],"sourcesContent":[null],"names":["unplugin","sourceFilePattern"],"mappings":";;;;;;;AAgDA;;;;;;;;;;;;;;AAcG;AACW,SAAU,GAAG,CAAC,OAA6B,EAAA;IACvD,OAAO;AACL,QAAA,IAAI,EAAE,eAAe;AACrB,QAAA,KAAK,CAAC,KAAK,EAAA;YACT,MAAM,GAAG,GAAGA,aAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,EAAyB,CAAC;AAC5D,YAAA,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAEC,uBAAiB,EAAE,EAAE,OAAO,IAAI,KAAI;gBACzD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,gBAAA,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AACnD,gBAAA,MAAM,MAAM,GACV,OAAO,GAAG,CAAC,SAAS,KAAK;AACvB,sBAAE,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAW,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI;sBACvD,SAAS;;AAEf,gBAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,oBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;gBACrC;gBACA,IACE,OAAO,MAAM,KAAK,QAAQ;AAC1B,oBAAA,MAAM,KAAK,IAAI;AACf,oBAAA,MAAM,IAAI,MAAM;AAChB,oBAAA,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAC/B;oBACA,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE;gBAC1C;AACA,gBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;AACrC,YAAA,CAAC,CAAC;QACJ,CAAC;KACF;AACH;AAEA;;;;AAIG;AACH,SAAS,YAAY,CAAC,QAAgB,EAAA;AACpC,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,KAAK,GAAG,IAAI;AAC5C;;;;"}
|
package/lib/bun.mjs
CHANGED
|
@@ -2,13 +2,19 @@ import fs from 'node:fs/promises';
|
|
|
2
2
|
import unplugin, { sourceFilePattern } from './core/index.mjs';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
|
-
* Create a ttsc plugin for Bun's bundler.
|
|
5
|
+
* Create a ttsc plugin for Bun's bundler AND runtime.
|
|
6
6
|
*
|
|
7
7
|
* Bun does not implement the unplugin protocol, so this adapter instantiates
|
|
8
8
|
* the raw unplugin transform and wires it to Bun's `onLoad` hook manually. The
|
|
9
9
|
* adapter reads each matching file from disk and forwards the content to the
|
|
10
10
|
* ttsc transform; if the transform returns no changes the original source is
|
|
11
11
|
* passed through unchanged.
|
|
12
|
+
*
|
|
13
|
+
* The same object works for `Bun.build({ plugins: [ttsc()] })` (bundler) and
|
|
14
|
+
* for `Bun.plugin(ttsc())` / a `bunfig.toml` preload (runtime) — see
|
|
15
|
+
* `bun-register`. Every result carries an explicit `loader` so Bun keeps
|
|
16
|
+
* transpiling the emitted TypeScript at runtime; `sourceFilePattern` only
|
|
17
|
+
* matches TypeScript, so the loader is always `ts`/`tsx`.
|
|
12
18
|
*/
|
|
13
19
|
function bun(options) {
|
|
14
20
|
return {
|
|
@@ -16,25 +22,34 @@ function bun(options) {
|
|
|
16
22
|
setup(build) {
|
|
17
23
|
const raw = unplugin.raw(options, {});
|
|
18
24
|
build.onLoad({ filter: sourceFilePattern }, async (args) => {
|
|
25
|
+
const loader = bunLoaderFor(args.path);
|
|
19
26
|
const source = await fs.readFile(args.path, "utf8");
|
|
20
27
|
const result = typeof raw.transform === "function"
|
|
21
28
|
? await raw.transform.call({}, source, args.path)
|
|
22
29
|
: undefined;
|
|
23
30
|
// Unpack both shorthand string and object result shapes.
|
|
24
31
|
if (typeof result === "string") {
|
|
25
|
-
return { contents: result };
|
|
32
|
+
return { contents: result, loader };
|
|
26
33
|
}
|
|
27
34
|
if (typeof result === "object" &&
|
|
28
35
|
result !== null &&
|
|
29
36
|
"code" in result &&
|
|
30
37
|
typeof result.code === "string") {
|
|
31
|
-
return { contents: result.code };
|
|
38
|
+
return { contents: result.code, loader };
|
|
32
39
|
}
|
|
33
|
-
return { contents: source };
|
|
40
|
+
return { contents: source, loader };
|
|
34
41
|
});
|
|
35
42
|
},
|
|
36
43
|
};
|
|
37
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Pick the Bun loader for a matched file. `sourceFilePattern` is
|
|
47
|
+
* `/\.[cm]?tsx?$/`, so a trailing `x` (`.tsx`/`.ctsx`/`.mtsx`) is JSX-flavored
|
|
48
|
+
* TypeScript and everything else (`.ts`/`.cts`/`.mts`) is plain TypeScript.
|
|
49
|
+
*/
|
|
50
|
+
function bunLoaderFor(filePath) {
|
|
51
|
+
return /x$/i.test(filePath) ? "tsx" : "ts";
|
|
52
|
+
}
|
|
38
53
|
|
|
39
54
|
export { bun as default };
|
|
40
55
|
//# sourceMappingURL=bun.mjs.map
|
package/lib/bun.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.mjs","sources":["../src/bun.ts"],"sourcesContent":[null],"names":[],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"bun.mjs","sources":["../src/bun.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAgDA;;;;;;;;;;;;;;AAcG;AACW,SAAU,GAAG,CAAC,OAA6B,EAAA;IACvD,OAAO;AACL,QAAA,IAAI,EAAE,eAAe;AACrB,QAAA,KAAK,CAAC,KAAK,EAAA;YACT,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,EAAyB,CAAC;AAC5D,YAAA,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,iBAAiB,EAAE,EAAE,OAAO,IAAI,KAAI;gBACzD,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC;AACtC,gBAAA,MAAM,MAAM,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC;AACnD,gBAAA,MAAM,MAAM,GACV,OAAO,GAAG,CAAC,SAAS,KAAK;AACvB,sBAAE,MAAM,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,EAAW,EAAE,MAAM,EAAE,IAAI,CAAC,IAAI;sBACvD,SAAS;;AAEf,gBAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,oBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;gBACrC;gBACA,IACE,OAAO,MAAM,KAAK,QAAQ;AAC1B,oBAAA,MAAM,KAAK,IAAI;AACf,oBAAA,MAAM,IAAI,MAAM;AAChB,oBAAA,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,EAC/B;oBACA,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE;gBAC1C;AACA,gBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE;AACrC,YAAA,CAAC,CAAC;QACJ,CAAC;KACF;AACH;AAEA;;;;AAIG;AACH,SAAS,YAAY,CAAC,QAAgB,EAAA;AACpC,IAAA,OAAO,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,KAAK,GAAG,IAAI;AAC5C;;;;"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttsc/unplugin",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.1",
|
|
4
4
|
"description": "Bundler adapters for ttsc plugins.",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"module": "lib/index.mjs",
|
|
@@ -21,6 +21,11 @@
|
|
|
21
21
|
"import": "./lib/bun.mjs",
|
|
22
22
|
"default": "./lib/bun.js"
|
|
23
23
|
},
|
|
24
|
+
"./bun-register": {
|
|
25
|
+
"types": "./lib/bun-register.d.ts",
|
|
26
|
+
"import": "./lib/bun-register.mjs",
|
|
27
|
+
"default": "./lib/bun-register.js"
|
|
28
|
+
},
|
|
24
29
|
"./esbuild": {
|
|
25
30
|
"types": "./lib/esbuild.d.ts",
|
|
26
31
|
"import": "./lib/esbuild.mjs",
|
|
@@ -102,7 +107,7 @@
|
|
|
102
107
|
"tslib": "^2.8.1",
|
|
103
108
|
"typescript": "7.0.1-rc",
|
|
104
109
|
"vite": "^7.1.12",
|
|
105
|
-
"ttsc": "0.
|
|
110
|
+
"ttsc": "0.17.1"
|
|
106
111
|
},
|
|
107
112
|
"repository": {
|
|
108
113
|
"type": "git",
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import bun, { type BunLikePlugin } from "./bun";
|
|
2
|
+
import type { TtscUnpluginOptions } from "./core/options";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Minimal shape of the Bun runtime global used to register a runtime plugin.
|
|
6
|
+
*
|
|
7
|
+
* Declared locally so the package needs no `bun-types` dependency; at runtime
|
|
8
|
+
* Bun exposes `Bun.plugin`, which accepts the same object the bundler adapter
|
|
9
|
+
* returns.
|
|
10
|
+
*/
|
|
11
|
+
interface BunRuntimeGlobal {
|
|
12
|
+
plugin(plugin: BunLikePlugin): void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Register the ttsc transform as a Bun **runtime** plugin.
|
|
17
|
+
*
|
|
18
|
+
* The other `@ttsc/unplugin/*` adapters cover bundlers (`Bun.build`, Vite,
|
|
19
|
+
* Webpack, …). This entry is the runtime counterpart: loading it registers the
|
|
20
|
+
* same transform on Bun's module loader, so `bun run` / `bun test` apply ttsc
|
|
21
|
+
* plugins (e.g. typia's `typia/lib/transform`) as files are imported, with no
|
|
22
|
+
* bundling step. Wire it up once via a `bunfig.toml` preload entry —
|
|
23
|
+
* `preload = ["@ttsc/unplugin/bun-register"]` — or imperatively with
|
|
24
|
+
* `import "@ttsc/unplugin/bun-register"`. Options are read from the nearest
|
|
25
|
+
* `tsconfig.json`, identical to the bundler adapters.
|
|
26
|
+
*
|
|
27
|
+
* @throws When called explicitly off the Bun runtime (`globalThis.Bun.plugin`
|
|
28
|
+
* is unavailable). The auto-registration below stays silent off Bun so the
|
|
29
|
+
* module is harmless to import from Node (tests, tooling).
|
|
30
|
+
*/
|
|
31
|
+
export function register(options?: TtscUnpluginOptions): void {
|
|
32
|
+
const runtime = bunRuntime();
|
|
33
|
+
if (runtime === undefined) {
|
|
34
|
+
throw new Error(
|
|
35
|
+
"@ttsc/unplugin/bun-register must run under the Bun runtime " +
|
|
36
|
+
"(globalThis.Bun.plugin is unavailable). Use a bundler adapter such as " +
|
|
37
|
+
"@ttsc/unplugin/vite for non-Bun toolchains.",
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
runtime.plugin(bun(options));
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function bunRuntime(): BunRuntimeGlobal | undefined {
|
|
44
|
+
const runtime = (globalThis as { Bun?: BunRuntimeGlobal }).Bun;
|
|
45
|
+
return runtime !== undefined && typeof runtime.plugin === "function"
|
|
46
|
+
? runtime
|
|
47
|
+
: undefined;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Auto-register on import so a `bunfig.toml` `preload` entry — which only
|
|
51
|
+
// imports the module — takes effect. Guarded so importing from Node (a stray
|
|
52
|
+
// import, or a unit test) is a harmless no-op rather than a throw.
|
|
53
|
+
if (bunRuntime() !== undefined) {
|
|
54
|
+
register();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export default register;
|
package/src/bun.ts
CHANGED
|
@@ -19,6 +19,9 @@ export interface BunLikePlugin {
|
|
|
19
19
|
setup(build: BunLikeBuild): void | Promise<void>;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
+
/** Bun loader identifiers this adapter can emit (only TypeScript is matched). */
|
|
23
|
+
export type BunLoader = "ts" | "tsx";
|
|
24
|
+
|
|
22
25
|
/**
|
|
23
26
|
* Minimal subset of the Bun `BuildConfig` plugin build object.
|
|
24
27
|
*
|
|
@@ -30,22 +33,33 @@ export interface BunLikeBuild {
|
|
|
30
33
|
* Register a loader callback for files matching `filter`.
|
|
31
34
|
*
|
|
32
35
|
* The callback receives the absolute file path and must return the
|
|
33
|
-
* transformed file contents.
|
|
36
|
+
* transformed file contents plus the `loader` Bun should apply next. The
|
|
37
|
+
* `loader` matters most for the runtime path (`Bun.plugin`), where Bun must
|
|
38
|
+
* be told the returned contents are still TypeScript so it keeps transpiling
|
|
39
|
+
* them before execution.
|
|
34
40
|
*/
|
|
35
41
|
onLoad(
|
|
36
42
|
options: { filter: RegExp },
|
|
37
|
-
loader: (args: {
|
|
43
|
+
loader: (args: {
|
|
44
|
+
path: string;
|
|
45
|
+
}) => Promise<{ contents: string; loader: BunLoader }>,
|
|
38
46
|
): void;
|
|
39
47
|
}
|
|
40
48
|
|
|
41
49
|
/**
|
|
42
|
-
* Create a ttsc plugin for Bun's bundler.
|
|
50
|
+
* Create a ttsc plugin for Bun's bundler AND runtime.
|
|
43
51
|
*
|
|
44
52
|
* Bun does not implement the unplugin protocol, so this adapter instantiates
|
|
45
53
|
* the raw unplugin transform and wires it to Bun's `onLoad` hook manually. The
|
|
46
54
|
* adapter reads each matching file from disk and forwards the content to the
|
|
47
55
|
* ttsc transform; if the transform returns no changes the original source is
|
|
48
56
|
* passed through unchanged.
|
|
57
|
+
*
|
|
58
|
+
* The same object works for `Bun.build({ plugins: [ttsc()] })` (bundler) and
|
|
59
|
+
* for `Bun.plugin(ttsc())` / a `bunfig.toml` preload (runtime) — see
|
|
60
|
+
* `bun-register`. Every result carries an explicit `loader` so Bun keeps
|
|
61
|
+
* transpiling the emitted TypeScript at runtime; `sourceFilePattern` only
|
|
62
|
+
* matches TypeScript, so the loader is always `ts`/`tsx`.
|
|
49
63
|
*/
|
|
50
64
|
export default function bun(options?: TtscUnpluginOptions): BunLikePlugin {
|
|
51
65
|
return {
|
|
@@ -53,6 +67,7 @@ export default function bun(options?: TtscUnpluginOptions): BunLikePlugin {
|
|
|
53
67
|
setup(build) {
|
|
54
68
|
const raw = unplugin.raw(options, {} as UnpluginContextMeta);
|
|
55
69
|
build.onLoad({ filter: sourceFilePattern }, async (args) => {
|
|
70
|
+
const loader = bunLoaderFor(args.path);
|
|
56
71
|
const source = await fs.readFile(args.path, "utf8");
|
|
57
72
|
const result =
|
|
58
73
|
typeof raw.transform === "function"
|
|
@@ -60,7 +75,7 @@ export default function bun(options?: TtscUnpluginOptions): BunLikePlugin {
|
|
|
60
75
|
: undefined;
|
|
61
76
|
// Unpack both shorthand string and object result shapes.
|
|
62
77
|
if (typeof result === "string") {
|
|
63
|
-
return { contents: result };
|
|
78
|
+
return { contents: result, loader };
|
|
64
79
|
}
|
|
65
80
|
if (
|
|
66
81
|
typeof result === "object" &&
|
|
@@ -68,10 +83,19 @@ export default function bun(options?: TtscUnpluginOptions): BunLikePlugin {
|
|
|
68
83
|
"code" in result &&
|
|
69
84
|
typeof result.code === "string"
|
|
70
85
|
) {
|
|
71
|
-
return { contents: result.code };
|
|
86
|
+
return { contents: result.code, loader };
|
|
72
87
|
}
|
|
73
|
-
return { contents: source };
|
|
88
|
+
return { contents: source, loader };
|
|
74
89
|
});
|
|
75
90
|
},
|
|
76
91
|
};
|
|
77
92
|
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Pick the Bun loader for a matched file. `sourceFilePattern` is
|
|
96
|
+
* `/\.[cm]?tsx?$/`, so a trailing `x` (`.tsx`/`.ctsx`/`.mtsx`) is JSX-flavored
|
|
97
|
+
* TypeScript and everything else (`.ts`/`.cts`/`.mts`) is plain TypeScript.
|
|
98
|
+
*/
|
|
99
|
+
function bunLoaderFor(filePath: string): BunLoader {
|
|
100
|
+
return /x$/i.test(filePath) ? "tsx" : "ts";
|
|
101
|
+
}
|