@ttsc/unplugin 0.8.1 → 0.9.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 +8 -9
- package/lib/api.js +3 -2
- package/lib/api.js.map +1 -1
- package/lib/api.mjs +1 -1
- package/lib/bun.js +1 -1
- package/lib/bun.js.map +1 -1
- package/lib/bun.mjs +1 -1
- package/lib/bun.mjs.map +1 -1
- package/lib/core/index.d.ts +2 -2
- package/lib/core/index.js +7 -2
- package/lib/core/index.js.map +1 -1
- package/lib/core/index.mjs +8 -4
- package/lib/core/index.mjs.map +1 -1
- package/lib/core/options.d.ts +3 -3
- package/lib/core/transform.d.ts +10 -2
- package/lib/core/transform.js +231 -75
- package/lib/core/transform.js.map +1 -1
- package/lib/core/transform.mjs +232 -58
- package/lib/core/transform.mjs.map +1 -1
- package/package.json +4 -7
- package/src/bun.ts +1 -1
- package/src/core/index.ts +14 -4
- package/src/core/options.ts +3 -3
- package/src/core/transform.ts +301 -60
package/README.md
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
Bundler adapter for `ttsc` plugins.
|
|
13
13
|
|
|
14
|
-
Use it when Vite, Rollup, esbuild, Webpack, Rspack, Next.js, Farm, or Bun
|
|
14
|
+
Use it when Vite, Rollup, esbuild, Webpack, Rspack, Next.js, Farm, or Bun owns the build but the project still needs `ttsc` plugins.
|
|
15
15
|
|
|
16
16
|
## Setup
|
|
17
17
|
|
|
@@ -150,7 +150,7 @@ await Bun.build({
|
|
|
150
150
|
|
|
151
151
|
## Configuration
|
|
152
152
|
|
|
153
|
-
By default, `@ttsc/unplugin` finds the nearest `tsconfig.json` from the file being transformed and
|
|
153
|
+
By default, `@ttsc/unplugin` finds the nearest `tsconfig.json` from the file being transformed and uses that project's plugin settings, including directly installed plugin packages.
|
|
154
154
|
|
|
155
155
|
If that is already the config you want, `ttsc()` is enough.
|
|
156
156
|
|
|
@@ -188,7 +188,10 @@ export default {
|
|
|
188
188
|
transform: "@ttsc/lint",
|
|
189
189
|
config: { "no-var": "error" },
|
|
190
190
|
},
|
|
191
|
-
{
|
|
191
|
+
{
|
|
192
|
+
transform: "typia/lib/transform",
|
|
193
|
+
finite: true,
|
|
194
|
+
},
|
|
192
195
|
],
|
|
193
196
|
},
|
|
194
197
|
}),
|
|
@@ -200,7 +203,7 @@ export default {
|
|
|
200
203
|
|
|
201
204
|
### Plugin Overrides
|
|
202
205
|
|
|
203
|
-
Use the top-level `plugins` option inside `ttsc(...)` when the bundler should
|
|
206
|
+
Use the top-level `plugins` option inside `ttsc(...)` when the bundler should use a different plugin list from `tsconfig.json`:
|
|
204
207
|
|
|
205
208
|
```ts
|
|
206
209
|
import ttsc from "@ttsc/unplugin/vite";
|
|
@@ -217,11 +220,7 @@ export default {
|
|
|
217
220
|
};
|
|
218
221
|
```
|
|
219
222
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
1. `plugins` option.
|
|
223
|
-
2. `compilerOptions.plugins` option.
|
|
224
|
-
3. `compilerOptions.plugins` from `project` / discovered `tsconfig.json`.
|
|
223
|
+
Explicit adapter options override the plugin list read from the selected project config.
|
|
225
224
|
|
|
226
225
|
Set `plugins: false` to run the adapter without loading project plugins.
|
|
227
226
|
|
package/lib/api.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var index = require('./core/index.js');
|
|
4
|
-
var options = require('./core/options.js');
|
|
5
4
|
var transform = require('./core/transform.js');
|
|
5
|
+
var options = require('./core/options.js');
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
exports.unplugin = index.default;
|
|
10
|
-
exports.
|
|
10
|
+
exports.createTtscTransformCache = transform.createTtscTransformCache;
|
|
11
11
|
exports.transformTtsc = transform.transformTtsc;
|
|
12
|
+
exports.resolveOptions = options.resolveOptions;
|
|
12
13
|
//# sourceMappingURL=api.js.map
|
package/lib/api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"api.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;"}
|
package/lib/api.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as unplugin } from './core/index.mjs';
|
|
2
|
+
export { createTtscTransformCache, transformTtsc } from './core/transform.mjs';
|
|
2
3
|
export { resolveOptions } from './core/options.mjs';
|
|
3
|
-
export { transformTtsc } from './core/transform.mjs';
|
|
4
4
|
//# sourceMappingURL=api.mjs.map
|
package/lib/bun.js
CHANGED
|
@@ -5,7 +5,7 @@ Object.defineProperty(exports, '__esModule', { value: true });
|
|
|
5
5
|
var fs = require('node:fs/promises');
|
|
6
6
|
var index = require('./core/index.js');
|
|
7
7
|
|
|
8
|
-
const sourceFilePattern = /\.[cm]?
|
|
8
|
+
const sourceFilePattern = /\.[cm]?tsx?$/;
|
|
9
9
|
function bun(options) {
|
|
10
10
|
return {
|
|
11
11
|
name: "ttsc-unplugin",
|
package/lib/bun.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.js","sources":["../src/bun.ts"],"sourcesContent":[null],"names":["unplugin"],"mappings":";;;;;;;AAkBA,MAAM,iBAAiB,GAAG,
|
|
1
|
+
{"version":3,"file":"bun.js","sources":["../src/bun.ts"],"sourcesContent":[null],"names":["unplugin"],"mappings":";;;;;;;AAkBA,MAAM,iBAAiB,GAAG,cAAc;AAE1B,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,EAAE,iBAAiB,EAAE,EAAE,OAAO,IAAI,KAAI;AACzD,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;AACf,gBAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,oBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;gBAC7B;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;AACA,oBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE;gBAClC;AACA,gBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;AAC7B,YAAA,CAAC,CAAC;QACJ,CAAC;KACF;AACH;;;;"}
|
package/lib/bun.mjs
CHANGED
package/lib/bun.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.mjs","sources":["../src/bun.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAkBA,MAAM,iBAAiB,GAAG,
|
|
1
|
+
{"version":3,"file":"bun.mjs","sources":["../src/bun.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAkBA,MAAM,iBAAiB,GAAG,cAAc;AAE1B,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;AACzD,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;AACf,gBAAA,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE;AAC9B,oBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;gBAC7B;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;AACA,oBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,IAAI,EAAE;gBAClC;AACA,gBAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE;AAC7B,YAAA,CAAC,CAAC;QACJ,CAAC;KACF;AACH;;;;"}
|
package/lib/core/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import type { UnpluginInstance } from "unplugin";
|
|
2
2
|
import type { TtscUnpluginOptions } from "./options";
|
|
3
3
|
import { resolveOptions } from "./options";
|
|
4
|
-
import { transformTtsc } from "./transform";
|
|
4
|
+
import { createTtscTransformCache, transformTtsc } from "./transform";
|
|
5
5
|
declare const unplugin: UnpluginInstance<TtscUnpluginOptions | undefined, false>;
|
|
6
6
|
export type { TtscUnpluginCompilerOptionsJson, TtscUnpluginOptions, } from "./options";
|
|
7
|
-
export { resolveOptions, transformTtsc, unplugin };
|
|
7
|
+
export { createTtscTransformCache, resolveOptions, transformTtsc, unplugin };
|
|
8
8
|
export default unplugin;
|
package/lib/core/index.js
CHANGED
|
@@ -7,11 +7,12 @@ var options = require('./options.js');
|
|
|
7
7
|
var transform = require('./transform.js');
|
|
8
8
|
|
|
9
9
|
const name = "ttsc-unplugin";
|
|
10
|
-
const sourceFilePattern = /\.[cm]?
|
|
10
|
+
const sourceFilePattern = /\.[cm]?tsx?$/;
|
|
11
11
|
const nodeModulesPattern = /(?:^|[/\\])node_modules(?:[/\\]|$)/;
|
|
12
12
|
const virtualModulePattern = /\0/;
|
|
13
13
|
const unpluginFactory = (rawOptions = {}) => {
|
|
14
14
|
const options$1 = options.resolveOptions(rawOptions);
|
|
15
|
+
const transformCache = transform.createTtscTransformCache();
|
|
15
16
|
let aliases;
|
|
16
17
|
return {
|
|
17
18
|
name,
|
|
@@ -21,6 +22,9 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
21
22
|
aliases = config.resolve.alias;
|
|
22
23
|
},
|
|
23
24
|
},
|
|
25
|
+
buildStart() {
|
|
26
|
+
transformCache.clear();
|
|
27
|
+
},
|
|
24
28
|
transformInclude(id) {
|
|
25
29
|
const file = transform.stripQuery(id);
|
|
26
30
|
return isTransformTarget(file);
|
|
@@ -30,7 +34,7 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
30
34
|
if (!isTransformTarget(file)) {
|
|
31
35
|
return undefined;
|
|
32
36
|
}
|
|
33
|
-
return transform.transformTtsc(file, source, options$1, aliases);
|
|
37
|
+
return transform.transformTtsc(file, source, options$1, aliases, transformCache);
|
|
34
38
|
},
|
|
35
39
|
};
|
|
36
40
|
};
|
|
@@ -43,6 +47,7 @@ function isTransformTarget(id) {
|
|
|
43
47
|
}
|
|
44
48
|
|
|
45
49
|
exports.resolveOptions = options.resolveOptions;
|
|
50
|
+
exports.createTtscTransformCache = transform.createTtscTransformCache;
|
|
46
51
|
exports.transformTtsc = transform.transformTtsc;
|
|
47
52
|
exports.default = unplugin;
|
|
48
53
|
exports.unplugin = unplugin;
|
package/lib/core/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":";;;;;;;;
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":["options","resolveOptions","createTtscTransformCache","stripQuery","transformTtsc","createUnplugin","isDeclarationFile"],"mappings":";;;;;;;;AAYA,MAAM,IAAI,GAAG,eAAe;AAC5B,MAAM,iBAAiB,GAAG,cAAc;AACxC,MAAM,kBAAkB,GAAG,oCAAoC;AAC/D,MAAM,oBAAoB,GAAG,IAAI;AAEjC,MAAM,eAAe,GAGjB,CAAC,UAAU,GAAG,EAAE,KAAI;AACtB,IAAA,MAAMA,SAAO,GAAGC,sBAAc,CAAC,UAAU,CAAC;AAC1C,IAAA,MAAM,cAAc,GAAGC,kCAAwB,EAAE;AACjD,IAAA,IAAI,OAAgB;IAEpB,OAAO;QACL,IAAI;AACJ,QAAA,OAAO,EAAE,KAAK;AAEd,QAAA,IAAI,EAAE;AACJ,YAAA,cAAc,CAAC,MAAM,EAAA;AACnB,gBAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;YAChC,CAAC;AACF,SAAA;QAED,UAAU,GAAA;YACR,cAAc,CAAC,KAAK,EAAE;QACxB,CAAC;AAED,QAAA,gBAAgB,CAAC,EAAE,EAAA;AACjB,YAAA,MAAM,IAAI,GAAGC,oBAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC;QAChC,CAAC;AAED,QAAA,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,EAAA;AACxB,YAAA,MAAM,IAAI,GAAGA,oBAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;AAC5B,gBAAA,OAAO,SAAS;YAClB;AACA,YAAA,OAAOC,uBAAa,CAAC,IAAI,EAAE,MAAM,EAAEJ,SAAO,EAAE,OAAO,EAAE,cAAc,CAAC;QACtE,CAAC;KACF;AACH,CAAC;AAED,MAAM,QAAQ,GACZK,yBAAc,CAAC,eAAe;AAUhC,SAAS,iBAAiB,CAAC,EAAU,EAAA;AACnC,IAAA,QACE,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,QAAA,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,CAACC,2BAAiB,CAAC,EAAE,CAAC;AACtB,QAAA,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAEhC;;;;;;;;"}
|
package/lib/core/index.mjs
CHANGED
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
import { createUnplugin } from 'unplugin';
|
|
2
2
|
import { resolveOptions } from './options.mjs';
|
|
3
|
-
import { stripQuery, transformTtsc, isDeclarationFile } from './transform.mjs';
|
|
3
|
+
import { stripQuery, transformTtsc, isDeclarationFile, createTtscTransformCache } from './transform.mjs';
|
|
4
4
|
|
|
5
5
|
const name = "ttsc-unplugin";
|
|
6
|
-
const sourceFilePattern = /\.[cm]?
|
|
6
|
+
const sourceFilePattern = /\.[cm]?tsx?$/;
|
|
7
7
|
const nodeModulesPattern = /(?:^|[/\\])node_modules(?:[/\\]|$)/;
|
|
8
8
|
const virtualModulePattern = /\0/;
|
|
9
9
|
const unpluginFactory = (rawOptions = {}) => {
|
|
10
10
|
const options = resolveOptions(rawOptions);
|
|
11
|
+
const transformCache = createTtscTransformCache();
|
|
11
12
|
let aliases;
|
|
12
13
|
return {
|
|
13
14
|
name,
|
|
@@ -17,6 +18,9 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
17
18
|
aliases = config.resolve.alias;
|
|
18
19
|
},
|
|
19
20
|
},
|
|
21
|
+
buildStart() {
|
|
22
|
+
transformCache.clear();
|
|
23
|
+
},
|
|
20
24
|
transformInclude(id) {
|
|
21
25
|
const file = stripQuery(id);
|
|
22
26
|
return isTransformTarget(file);
|
|
@@ -26,7 +30,7 @@ const unpluginFactory = (rawOptions = {}) => {
|
|
|
26
30
|
if (!isTransformTarget(file)) {
|
|
27
31
|
return undefined;
|
|
28
32
|
}
|
|
29
|
-
return transformTtsc(file, source, options, aliases);
|
|
33
|
+
return transformTtsc(file, source, options, aliases, transformCache);
|
|
30
34
|
},
|
|
31
35
|
};
|
|
32
36
|
};
|
|
@@ -38,5 +42,5 @@ function isTransformTarget(id) {
|
|
|
38
42
|
!nodeModulesPattern.test(id));
|
|
39
43
|
}
|
|
40
44
|
|
|
41
|
-
export { unplugin as default, resolveOptions, transformTtsc, unplugin };
|
|
45
|
+
export { createTtscTransformCache, unplugin as default, resolveOptions, transformTtsc, unplugin };
|
|
42
46
|
//# sourceMappingURL=index.mjs.map
|
package/lib/core/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/core/index.ts"],"sourcesContent":[null],"names":[],"mappings":";;;;AAYA,MAAM,IAAI,GAAG,eAAe;AAC5B,MAAM,iBAAiB,GAAG,cAAc;AACxC,MAAM,kBAAkB,GAAG,oCAAoC;AAC/D,MAAM,oBAAoB,GAAG,IAAI;AAEjC,MAAM,eAAe,GAGjB,CAAC,UAAU,GAAG,EAAE,KAAI;AACtB,IAAA,MAAM,OAAO,GAAG,cAAc,CAAC,UAAU,CAAC;AAC1C,IAAA,MAAM,cAAc,GAAG,wBAAwB,EAAE;AACjD,IAAA,IAAI,OAAgB;IAEpB,OAAO;QACL,IAAI;AACJ,QAAA,OAAO,EAAE,KAAK;AAEd,QAAA,IAAI,EAAE;AACJ,YAAA,cAAc,CAAC,MAAM,EAAA;AACnB,gBAAA,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK;YAChC,CAAC;AACF,SAAA;QAED,UAAU,GAAA;YACR,cAAc,CAAC,KAAK,EAAE;QACxB,CAAC;AAED,QAAA,gBAAgB,CAAC,EAAE,EAAA;AACjB,YAAA,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,OAAO,iBAAiB,CAAC,IAAI,CAAC;QAChC,CAAC;AAED,QAAA,MAAM,SAAS,CAAC,MAAM,EAAE,EAAE,EAAA;AACxB,YAAA,MAAM,IAAI,GAAG,UAAU,CAAC,EAAE,CAAC;AAC3B,YAAA,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,EAAE;AAC5B,gBAAA,OAAO,SAAS;YAClB;AACA,YAAA,OAAO,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,CAAC;QACtE,CAAC;KACF;AACH,CAAC;AAED,MAAM,QAAQ,GACZ,cAAc,CAAC,eAAe;AAUhC,SAAS,iBAAiB,CAAC,EAAU,EAAA;AACnC,IAAA,QACE,iBAAiB,CAAC,IAAI,CAAC,EAAE,CAAC;AAC1B,QAAA,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,CAAC,iBAAiB,CAAC,EAAE,CAAC;AACtB,QAAA,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;AAEhC;;;;"}
|
package/lib/core/options.d.ts
CHANGED
|
@@ -18,9 +18,9 @@ export interface TtscUnpluginOptions {
|
|
|
18
18
|
/**
|
|
19
19
|
* `ttsc` plugin entries.
|
|
20
20
|
*
|
|
21
|
-
* `undefined` reads `compilerOptions.plugins`
|
|
22
|
-
* `false` disables project plugins, and
|
|
23
|
-
* plugin list.
|
|
21
|
+
* `undefined` reads project plugins from `compilerOptions.plugins` and
|
|
22
|
+
* directly installed package markers, `false` disables project plugins, and
|
|
23
|
+
* an array overrides the project plugin list.
|
|
24
24
|
*/
|
|
25
25
|
plugins?: readonly ITtscProjectPluginConfig[] | false;
|
|
26
26
|
}
|
package/lib/core/transform.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { ITtscCompilerTransformation } from "ttsc";
|
|
1
2
|
import type { TransformResult } from "unplugin";
|
|
2
3
|
import type { ResolvedTtscUnpluginOptions } from "./options";
|
|
3
4
|
export type TtscTransformResult = Exclude<TransformResult, string | null | undefined>;
|
|
@@ -5,7 +6,14 @@ export interface TtscTransformAlias {
|
|
|
5
6
|
find: string | RegExp;
|
|
6
7
|
replacement: string;
|
|
7
8
|
}
|
|
8
|
-
export
|
|
9
|
+
export interface TtscCachedProjectTransform {
|
|
10
|
+
inputHashes: Record<string, string>;
|
|
11
|
+
projectRoot: string;
|
|
12
|
+
result: ITtscCompilerTransformation;
|
|
13
|
+
}
|
|
14
|
+
export type TtscTransformCache = Map<string, Promise<TtscCachedProjectTransform>>;
|
|
15
|
+
export declare function createTtscTransformCache(): TtscTransformCache;
|
|
16
|
+
export declare function transformTtsc(id: string, source: string, options: ResolvedTtscUnpluginOptions, aliases?: unknown, cache?: TtscTransformCache): Promise<TtscTransformResult | undefined>;
|
|
9
17
|
export declare function stripQuery(id: string): string;
|
|
10
18
|
export declare function isDeclarationFile(id: string): boolean;
|
|
11
|
-
export declare function createTransformResult(source: string, code: string
|
|
19
|
+
export declare function createTransformResult(source: string, code: string): TtscTransformResult | undefined;
|
package/lib/core/transform.js
CHANGED
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var Diff = require('diff-match-patch-es');
|
|
4
3
|
var fs = require('node:fs');
|
|
4
|
+
var crypto = require('node:crypto');
|
|
5
|
+
var os = require('node:os');
|
|
5
6
|
var path = require('node:path');
|
|
6
|
-
var MagicString = require('magic-string');
|
|
7
7
|
var ttsc = require('ttsc');
|
|
8
8
|
|
|
9
|
-
function
|
|
10
|
-
|
|
11
|
-
if (e) {
|
|
12
|
-
Object.keys(e).forEach(function (k) {
|
|
13
|
-
if (k !== 'default') {
|
|
14
|
-
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
15
|
-
Object.defineProperty(n, k, d.get ? d : {
|
|
16
|
-
enumerable: true,
|
|
17
|
-
get: function () { return e[k]; }
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
});
|
|
21
|
-
}
|
|
22
|
-
n.default = e;
|
|
23
|
-
return Object.freeze(n);
|
|
9
|
+
function createTtscTransformCache() {
|
|
10
|
+
return new Map();
|
|
24
11
|
}
|
|
25
|
-
|
|
26
|
-
var Diff__namespace = /*#__PURE__*/_interopNamespaceDefault(Diff);
|
|
27
|
-
|
|
28
|
-
async function transformTtsc(id, source, options, aliases) {
|
|
12
|
+
async function transformTtsc(id, source, options, aliases, cache) {
|
|
29
13
|
const clean = stripQuery(id);
|
|
30
14
|
if (clean.includes("\0")) {
|
|
31
15
|
return undefined;
|
|
@@ -38,29 +22,43 @@ async function transformTtsc(id, source, options, aliases) {
|
|
|
38
22
|
const tsconfigDir = path.dirname(tsconfig);
|
|
39
23
|
const baseUrl = resolveBaseUrl(tsconfigDir, options.compilerOptions);
|
|
40
24
|
const aliasPaths = createAliasPaths(baseUrl, aliases);
|
|
41
|
-
const
|
|
25
|
+
const key = createTransformCacheKey({
|
|
42
26
|
aliasPaths,
|
|
43
|
-
baseUrl,
|
|
44
27
|
compilerOptions: options.compilerOptions,
|
|
28
|
+
plugins: options.plugins,
|
|
45
29
|
tsconfig,
|
|
46
30
|
});
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
const
|
|
50
|
-
|
|
31
|
+
let transformed = cache?.get(key);
|
|
32
|
+
if (transformed !== undefined) {
|
|
33
|
+
const cached = await transformed;
|
|
34
|
+
if (matchesCachedSource(cached, file, source)) {
|
|
35
|
+
reportSuccessDiagnostics(cached.result);
|
|
36
|
+
const code = selectTransformedSource({
|
|
37
|
+
file,
|
|
38
|
+
projectRoot: cached.projectRoot,
|
|
39
|
+
result: cached.result,
|
|
40
|
+
});
|
|
41
|
+
return createTransformResult(source, code);
|
|
42
|
+
}
|
|
43
|
+
cache?.delete(key);
|
|
44
|
+
transformed = undefined;
|
|
45
|
+
}
|
|
46
|
+
if (transformed === undefined) {
|
|
47
|
+
transformed = transformProject({
|
|
48
|
+
aliasPaths,
|
|
49
|
+
baseUrl,
|
|
50
|
+
compilerOptions: options.compilerOptions,
|
|
51
|
+
currentFile: file,
|
|
52
|
+
currentSource: source,
|
|
51
53
|
plugins: options.plugins,
|
|
52
|
-
tsconfig
|
|
53
|
-
}).transform();
|
|
54
|
-
const code = selectTransformedSource({
|
|
55
|
-
file,
|
|
56
|
-
projectRoot: path.dirname(effectiveTsconfig),
|
|
57
|
-
result,
|
|
54
|
+
tsconfig,
|
|
58
55
|
});
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
finally {
|
|
62
|
-
configured.dispose();
|
|
56
|
+
cache?.set(key, transformed);
|
|
63
57
|
}
|
|
58
|
+
const { projectRoot, result } = await transformed;
|
|
59
|
+
reportSuccessDiagnostics(result);
|
|
60
|
+
const code = selectTransformedSource({ file, projectRoot, result });
|
|
61
|
+
return createTransformResult(source, code);
|
|
64
62
|
}
|
|
65
63
|
function stripQuery(id) {
|
|
66
64
|
const query = id.search(/[?#]/);
|
|
@@ -72,70 +70,184 @@ function stripQuery(id) {
|
|
|
72
70
|
function isDeclarationFile(id) {
|
|
73
71
|
return id.endsWith(".d.ts") || id.endsWith(".d.mts") || id.endsWith(".d.cts");
|
|
74
72
|
}
|
|
75
|
-
function createTransformResult(source, code
|
|
73
|
+
function createTransformResult(source, code) {
|
|
76
74
|
if (source === code) {
|
|
77
75
|
return undefined;
|
|
78
76
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
77
|
+
return { code };
|
|
78
|
+
}
|
|
79
|
+
function matchesCachedSource(cached, file, source) {
|
|
80
|
+
const currentKey = toProjectKey(cached.projectRoot, file);
|
|
81
|
+
const currentHashes = collectProjectInputHashes(cached.projectRoot);
|
|
82
|
+
currentHashes[currentKey] = hashText(source);
|
|
83
|
+
return sameHashes(cached.inputHashes, currentHashes);
|
|
84
|
+
}
|
|
85
|
+
function collectInputHashes(props) {
|
|
86
|
+
const hashes = collectProjectInputHashes(props.projectRoot);
|
|
87
|
+
if (props.result.type !== "exception") {
|
|
88
|
+
for (const key of Object.keys(props.result.typescript)) {
|
|
89
|
+
const file = path.resolve(props.projectRoot, key);
|
|
90
|
+
try {
|
|
91
|
+
hashes[key] = hashText(fs.readFileSync(file, "utf8"));
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// A plugin may synthesize a virtual TypeScript file. It should not
|
|
95
|
+
// decide cache reuse for real source files.
|
|
96
|
+
}
|
|
88
97
|
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
}
|
|
99
|
+
hashes[toProjectKey(props.projectRoot, props.currentFile)] = hashText(props.currentSource);
|
|
100
|
+
return hashes;
|
|
101
|
+
}
|
|
102
|
+
function collectProjectInputHashes(projectRoot) {
|
|
103
|
+
const hashes = {};
|
|
104
|
+
for (const file of listProjectInputFiles(projectRoot)) {
|
|
105
|
+
try {
|
|
106
|
+
hashes[toProjectKey(projectRoot, file)] = hashText(fs.readFileSync(file));
|
|
92
107
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
index += 1;
|
|
108
|
+
catch {
|
|
109
|
+
// File watchers may observe a transform while another process is moving
|
|
110
|
+
// or deleting files. The missing key invalidates older cache entries.
|
|
97
111
|
}
|
|
98
|
-
|
|
99
|
-
|
|
112
|
+
}
|
|
113
|
+
return hashes;
|
|
114
|
+
}
|
|
115
|
+
function listProjectInputFiles(root) {
|
|
116
|
+
const out = [];
|
|
117
|
+
const stack = [root];
|
|
118
|
+
while (stack.length !== 0) {
|
|
119
|
+
const current = stack.pop();
|
|
120
|
+
let entries;
|
|
121
|
+
try {
|
|
122
|
+
entries = fs.readdirSync(current, { withFileTypes: true });
|
|
123
|
+
}
|
|
124
|
+
catch {
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
for (const entry of entries) {
|
|
128
|
+
if (isIgnoredProjectDirectory(entry.name)) {
|
|
129
|
+
continue;
|
|
130
|
+
}
|
|
131
|
+
const file = path.join(current, entry.name);
|
|
132
|
+
if (entry.isDirectory()) {
|
|
133
|
+
stack.push(file);
|
|
134
|
+
}
|
|
135
|
+
else if (entry.isFile()) {
|
|
136
|
+
out.push(file);
|
|
137
|
+
}
|
|
100
138
|
}
|
|
101
|
-
offset += text.length;
|
|
102
139
|
}
|
|
103
|
-
|
|
104
|
-
|
|
140
|
+
out.sort();
|
|
141
|
+
return out;
|
|
142
|
+
}
|
|
143
|
+
function isIgnoredProjectDirectory(name) {
|
|
144
|
+
return (name === ".git" ||
|
|
145
|
+
name === ".ttsc" ||
|
|
146
|
+
name === ".cache" ||
|
|
147
|
+
name === ".next" ||
|
|
148
|
+
name === ".nuxt" ||
|
|
149
|
+
name === ".svelte-kit" ||
|
|
150
|
+
name === ".turbo" ||
|
|
151
|
+
name === ".vite" ||
|
|
152
|
+
name === "build" ||
|
|
153
|
+
name === "coverage" ||
|
|
154
|
+
name === "dist" ||
|
|
155
|
+
name === "node_modules" ||
|
|
156
|
+
name === "out" ||
|
|
157
|
+
name === "temp" ||
|
|
158
|
+
name === "tmp");
|
|
159
|
+
}
|
|
160
|
+
function sameHashes(left, right) {
|
|
161
|
+
const leftKeys = Object.keys(left);
|
|
162
|
+
const rightKeys = Object.keys(right);
|
|
163
|
+
if (leftKeys.length !== rightKeys.length) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
return leftKeys.every((key) => right[key] === left[key]);
|
|
167
|
+
}
|
|
168
|
+
function hashText(input) {
|
|
169
|
+
return crypto.createHash("sha256").update(input).digest("hex");
|
|
170
|
+
}
|
|
171
|
+
async function transformProject(props) {
|
|
172
|
+
const configured = createTransformTsconfig(props);
|
|
173
|
+
const projectRoot = path.dirname(props.tsconfig);
|
|
174
|
+
try {
|
|
175
|
+
const result = new ttsc.TtscCompiler({
|
|
176
|
+
cwd: projectRoot,
|
|
177
|
+
plugins: props.plugins,
|
|
178
|
+
projectRoot,
|
|
179
|
+
tsconfig: configured.path,
|
|
180
|
+
}).transform();
|
|
181
|
+
return {
|
|
182
|
+
inputHashes: collectInputHashes({
|
|
183
|
+
currentFile: props.currentFile,
|
|
184
|
+
currentSource: props.currentSource,
|
|
185
|
+
projectRoot,
|
|
186
|
+
result,
|
|
187
|
+
}),
|
|
188
|
+
projectRoot,
|
|
189
|
+
result,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
finally {
|
|
193
|
+
configured.dispose();
|
|
105
194
|
}
|
|
106
|
-
return {
|
|
107
|
-
code: magic.toString(),
|
|
108
|
-
map: magic.generateMap({
|
|
109
|
-
file: `${id}.map`,
|
|
110
|
-
includeContent: true,
|
|
111
|
-
source: id,
|
|
112
|
-
}),
|
|
113
|
-
};
|
|
114
195
|
}
|
|
115
196
|
function createTransformTsconfig(props) {
|
|
116
|
-
const compilerOptions = {
|
|
197
|
+
const compilerOptions = normalizeCompilerOptionsForGeneratedTsconfig({
|
|
117
198
|
...props.compilerOptions,
|
|
118
199
|
...createAliasCompilerOptions(props),
|
|
119
|
-
};
|
|
200
|
+
}, path.dirname(props.tsconfig));
|
|
120
201
|
if (Object.keys(compilerOptions).length === 0) {
|
|
121
202
|
return {
|
|
122
203
|
path: props.tsconfig,
|
|
123
204
|
dispose: () => undefined,
|
|
124
205
|
};
|
|
125
206
|
}
|
|
126
|
-
const directory = path.
|
|
127
|
-
const file = path.join(directory,
|
|
128
|
-
.toString(36)
|
|
129
|
-
.slice(2)}.json`);
|
|
207
|
+
const directory = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-unplugin-"));
|
|
208
|
+
const file = path.join(directory, "tsconfig.json");
|
|
130
209
|
fs.writeFileSync(file, JSON.stringify({
|
|
131
|
-
extends:
|
|
210
|
+
extends: normalizePath(props.tsconfig),
|
|
132
211
|
compilerOptions,
|
|
133
212
|
}, null, 2), "utf8");
|
|
134
213
|
return {
|
|
135
214
|
path: file,
|
|
136
|
-
dispose: () => fs.rmSync(
|
|
215
|
+
dispose: () => fs.rmSync(directory, { force: true, recursive: true }),
|
|
137
216
|
};
|
|
138
217
|
}
|
|
218
|
+
function normalizeCompilerOptionsForGeneratedTsconfig(compilerOptions, tsconfigDir) {
|
|
219
|
+
const output = { ...compilerOptions };
|
|
220
|
+
for (const key of ["baseUrl", "declarationDir", "outDir", "rootDir"]) {
|
|
221
|
+
if (typeof output[key] === "string") {
|
|
222
|
+
output[key] = path.resolve(tsconfigDir, output[key]);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
for (const key of ["rootDirs", "typeRoots"]) {
|
|
226
|
+
if (Array.isArray(output[key])) {
|
|
227
|
+
output[key] = output[key].map((entry) => typeof entry === "string" ? path.resolve(tsconfigDir, entry) : entry);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
if (hasPaths(output.paths) && typeof output.baseUrl !== "string") {
|
|
231
|
+
output.baseUrl = tsconfigDir;
|
|
232
|
+
}
|
|
233
|
+
if (Array.isArray(output.plugins)) {
|
|
234
|
+
output.plugins = output.plugins.map((entry) => normalizePluginConfigForGeneratedTsconfig(entry, tsconfigDir));
|
|
235
|
+
}
|
|
236
|
+
return output;
|
|
237
|
+
}
|
|
238
|
+
function normalizePluginConfigForGeneratedTsconfig(entry, tsconfigDir) {
|
|
239
|
+
if (typeof entry !== "object" || entry === null || Array.isArray(entry)) {
|
|
240
|
+
return entry;
|
|
241
|
+
}
|
|
242
|
+
const output = { ...entry };
|
|
243
|
+
for (const key of ["config", "source", "transform"]) {
|
|
244
|
+
const value = output[key];
|
|
245
|
+
if (typeof value === "string" && isRelativeSpecifier(value)) {
|
|
246
|
+
output[key] = path.resolve(tsconfigDir, value);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
return output;
|
|
250
|
+
}
|
|
139
251
|
function createAliasCompilerOptions(props) {
|
|
140
252
|
if (Object.keys(props.aliasPaths).length === 0) {
|
|
141
253
|
return {};
|
|
@@ -148,6 +260,12 @@ function createAliasCompilerOptions(props) {
|
|
|
148
260
|
},
|
|
149
261
|
};
|
|
150
262
|
}
|
|
263
|
+
function hasPaths(value) {
|
|
264
|
+
return (typeof value === "object" &&
|
|
265
|
+
value !== null &&
|
|
266
|
+
!Array.isArray(value) &&
|
|
267
|
+
Object.keys(value).length !== 0);
|
|
268
|
+
}
|
|
151
269
|
function readPaths(value) {
|
|
152
270
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
153
271
|
return {};
|
|
@@ -207,6 +325,34 @@ function normalizeAliases(aliases) {
|
|
|
207
325
|
}
|
|
208
326
|
return [];
|
|
209
327
|
}
|
|
328
|
+
function createTransformCacheKey(props) {
|
|
329
|
+
return stableStringify({
|
|
330
|
+
aliasPaths: props.aliasPaths,
|
|
331
|
+
compilerOptions: props.compilerOptions,
|
|
332
|
+
plugins: props.plugins,
|
|
333
|
+
tsconfig: path.resolve(props.tsconfig),
|
|
334
|
+
});
|
|
335
|
+
}
|
|
336
|
+
function stableStringify(value) {
|
|
337
|
+
if (Array.isArray(value)) {
|
|
338
|
+
return `[${value.map(stableStringify).join(",")}]`;
|
|
339
|
+
}
|
|
340
|
+
if (value && typeof value === "object") {
|
|
341
|
+
return `{${Object.entries(value)
|
|
342
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
343
|
+
.map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`)
|
|
344
|
+
.join(",")}}`;
|
|
345
|
+
}
|
|
346
|
+
return JSON.stringify(value);
|
|
347
|
+
}
|
|
348
|
+
function isRelativeSpecifier(value) {
|
|
349
|
+
return (value === "." ||
|
|
350
|
+
value === ".." ||
|
|
351
|
+
value.startsWith("./") ||
|
|
352
|
+
value.startsWith("../") ||
|
|
353
|
+
value.startsWith(".\\") ||
|
|
354
|
+
value.startsWith("..\\"));
|
|
355
|
+
}
|
|
210
356
|
function isAlias(value) {
|
|
211
357
|
return (typeof value === "object" &&
|
|
212
358
|
value !== null &&
|
|
@@ -234,6 +380,15 @@ function selectTransformedSource(props) {
|
|
|
234
380
|
}
|
|
235
381
|
throw new Error(`ttsc transform did not return output for ${props.file}`);
|
|
236
382
|
}
|
|
383
|
+
function reportSuccessDiagnostics(result) {
|
|
384
|
+
if (result.type !== "success" || result.diagnostics === undefined) {
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
const text = formatDiagnostics(result.diagnostics);
|
|
388
|
+
if (text.length !== 0) {
|
|
389
|
+
process.stderr.write(`${text}\n`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
237
392
|
function formatDiagnostics(diagnostics) {
|
|
238
393
|
if (diagnostics.length === 0) {
|
|
239
394
|
return "ttsc transform failed";
|
|
@@ -290,6 +445,7 @@ function normalizePath(file) {
|
|
|
290
445
|
}
|
|
291
446
|
|
|
292
447
|
exports.createTransformResult = createTransformResult;
|
|
448
|
+
exports.createTtscTransformCache = createTtscTransformCache;
|
|
293
449
|
exports.isDeclarationFile = isDeclarationFile;
|
|
294
450
|
exports.stripQuery = stripQuery;
|
|
295
451
|
exports.transformTtsc = transformTtsc;
|