ttsc 0.8.1 → 0.10.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 +39 -68
- package/cmd/ttsc/api_compile.go +109 -115
- package/cmd/ttsc/api_transform.go +54 -51
- package/cmd/ttsc/main.go +103 -121
- package/driver/program.go +30 -2
- package/driver/rewrite.go +126 -9
- package/go.mod +2 -0
- package/lib/TtscCompiler.js +28 -46
- package/lib/TtscCompiler.js.map +1 -1
- package/lib/compiler/internal/buildNativeCompiler.js +8 -38
- package/lib/compiler/internal/buildNativeCompiler.js.map +1 -1
- package/lib/compiler/internal/compileProjectInMemory.js +36 -63
- package/lib/compiler/internal/compileProjectInMemory.js.map +1 -1
- package/lib/compiler/internal/project/readProjectConfig.js +108 -60
- package/lib/compiler/internal/project/readProjectConfig.js.map +1 -1
- package/lib/compiler/internal/project/resolveProjectConfig.js +15 -45
- package/lib/compiler/internal/project/resolveProjectConfig.js.map +1 -1
- package/lib/compiler/internal/resolveBinary.js +10 -40
- package/lib/compiler/internal/resolveBinary.js.map +1 -1
- package/lib/compiler/internal/resolveEmittedJavaScript.js +21 -48
- package/lib/compiler/internal/resolveEmittedJavaScript.js.map +1 -1
- package/lib/compiler/internal/resolveTsgo.js +14 -44
- package/lib/compiler/internal/resolveTsgo.js.map +1 -1
- package/lib/compiler/internal/runBuild.d.ts +7 -0
- package/lib/compiler/internal/runBuild.js +47 -66
- package/lib/compiler/internal/runBuild.js.map +1 -1
- package/lib/compiler/internal/runSingleFileEmit.js +18 -48
- package/lib/compiler/internal/runSingleFileEmit.js.map +1 -1
- package/lib/compiler/internal/transformProjectInMemory.js +41 -75
- package/lib/compiler/internal/transformProjectInMemory.js.map +1 -1
- package/lib/launcher/internal/getCompilerVersionText.js +7 -37
- package/lib/launcher/internal/getCompilerVersionText.js.map +1 -1
- package/lib/launcher/internal/prepareExecution.js +48 -69
- package/lib/launcher/internal/prepareExecution.js.map +1 -1
- package/lib/launcher/internal/runTtsc.js +53 -64
- package/lib/launcher/internal/runTtsc.js.map +1 -1
- package/lib/launcher/internal/runTtsx.js +328 -57
- package/lib/launcher/internal/runTtsx.js.map +1 -1
- package/lib/plugin/internal/buildSourcePlugin.d.ts +8 -0
- package/lib/plugin/internal/buildSourcePlugin.js +287 -139
- package/lib/plugin/internal/buildSourcePlugin.js.map +1 -1
- package/lib/plugin/internal/loadProjectPlugins.d.ts +2 -0
- package/lib/plugin/internal/loadProjectPlugins.js +197 -9
- package/lib/plugin/internal/loadProjectPlugins.js.map +1 -1
- package/lib/structures/ITtscCompilerContext.d.ts +16 -3
- package/lib/structures/ITtscCompilerResult.d.ts +4 -0
- package/lib/structures/ITtscCompilerTransformation.d.ts +2 -0
- package/lib/structures/ITtscPluginFactoryContext.d.ts +6 -3
- package/lib/structures/ITtscProjectPluginConfig.d.ts +8 -7
- package/lib/structures/internal/ITtscParsedProjectConfig.d.ts +2 -0
- package/lib/structures/internal/ITtscProjectLocatorOptions.d.ts +2 -0
- package/lib/structures/internal/TtscCommonOptions.d.ts +2 -0
- package/package.json +9 -14
- package/shim/diagnosticwriter/lint.go +8 -0
- package/shim/printer/go.mod +5 -0
- package/shim/printer/shim.go +23 -0
- package/src/TtscCompiler.ts +20 -5
- package/src/compiler/internal/buildNativeCompiler.ts +2 -2
- package/src/compiler/internal/compileProjectInMemory.ts +21 -16
- package/src/compiler/internal/project/readProjectConfig.ts +134 -35
- package/src/compiler/internal/project/resolveProjectConfig.ts +2 -2
- package/src/compiler/internal/resolveBinary.ts +2 -2
- package/src/compiler/internal/resolveEmittedJavaScript.ts +11 -7
- package/src/compiler/internal/resolveTsgo.ts +2 -2
- package/src/compiler/internal/runBuild.ts +34 -21
- package/src/compiler/internal/runSingleFileEmit.ts +3 -3
- package/src/compiler/internal/transformProjectInMemory.ts +37 -37
- package/src/launcher/internal/getCompilerVersionText.ts +2 -2
- package/src/launcher/internal/prepareExecution.ts +14 -4
- package/src/launcher/internal/runTtsc.ts +30 -4
- package/src/launcher/internal/runTtsx.ts +377 -26
- package/src/plugin/internal/buildSourcePlugin.ts +321 -50
- package/src/plugin/internal/loadProjectPlugins.ts +266 -10
- package/src/structures/ITtscCompilerContext.ts +17 -3
- package/src/structures/ITtscCompilerResult.ts +5 -0
- package/src/structures/ITtscCompilerTransformation.ts +3 -0
- package/src/structures/ITtscPluginFactoryContext.ts +6 -3
- package/src/structures/ITtscProjectPluginConfig.ts +8 -7
- package/src/structures/internal/ITtscParsedProjectConfig.ts +2 -0
- package/src/structures/internal/ITtscProjectLocatorOptions.ts +2 -0
- package/src/structures/internal/TtscCommonOptions.ts +2 -0
- package/utility/host.go +622 -20
- package/cmd/ttsc/main_test.go +0 -288
- package/test/compiler.test.ts +0 -422
- package/test/platform.test.ts +0 -12
- package/test/project.test.ts +0 -197
- package/test/source-build.test.ts +0 -45
- package/test/tsgo.test.ts +0 -69
package/test/compiler.test.ts
DELETED
|
@@ -1,422 +0,0 @@
|
|
|
1
|
-
const assert = require("node:assert/strict");
|
|
2
|
-
const fs = require("node:fs");
|
|
3
|
-
const os = require("node:os");
|
|
4
|
-
const path = require("node:path");
|
|
5
|
-
const test = require("node:test");
|
|
6
|
-
|
|
7
|
-
const { TtscCompiler } = require("../lib/index.js");
|
|
8
|
-
const { resolveTsgo } = require("../lib/compiler/internal/resolveTsgo.js");
|
|
9
|
-
const tsgo = resolveTsgo({ cwd: path.resolve(__dirname, "..") }).binary;
|
|
10
|
-
|
|
11
|
-
test("TtscCompiler.compile returns output without writing project files", () => {
|
|
12
|
-
const root = createProject();
|
|
13
|
-
const compiler = new TtscCompiler({
|
|
14
|
-
binary: tsgo,
|
|
15
|
-
cwd: root,
|
|
16
|
-
plugins: false,
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const result = compiler.compile();
|
|
20
|
-
|
|
21
|
-
assert.equal(result.type, "success");
|
|
22
|
-
assert.match(result.output["dist/main.js"], /api-ok/);
|
|
23
|
-
assert.match(result.output["dist/main.js"], /console\.log\(\s*message\s*\)/);
|
|
24
|
-
assert.match(result.output["dist/main.d.ts"], /declare const message/);
|
|
25
|
-
assert.match(result.output["dist/main.js.map"], /"version":3/);
|
|
26
|
-
assert.match(result.output["dist/main.d.ts.map"], /"version":3/);
|
|
27
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test("TtscCompiler can disable project plugin loading", () => {
|
|
31
|
-
const root = createProject({
|
|
32
|
-
plugins: [{ transform: "./missing-plugin.cjs" }],
|
|
33
|
-
});
|
|
34
|
-
const compiler = new TtscCompiler({
|
|
35
|
-
binary: tsgo,
|
|
36
|
-
cwd: root,
|
|
37
|
-
plugins: false,
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
const result = compiler.compile();
|
|
41
|
-
|
|
42
|
-
assert.equal(result.type, "success");
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
test("TtscCompiler.compile applies configured source plugins without project output", () => {
|
|
46
|
-
const root = createProject({
|
|
47
|
-
plugins: [{ transform: "./plugin.cjs" }],
|
|
48
|
-
source: 'export const value = goUpper("plugin");\nconsole.log(value);\n',
|
|
49
|
-
});
|
|
50
|
-
writeCompilerPlugin(root);
|
|
51
|
-
const compiler = new TtscCompiler({ binary: tsgo, cwd: root });
|
|
52
|
-
|
|
53
|
-
const result = compiler.compile();
|
|
54
|
-
|
|
55
|
-
assert.equal(result.type, "success");
|
|
56
|
-
assert.match(result.output["dist/main.js"], /PLUGIN/);
|
|
57
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("TtscCompiler.transform returns TypeScript source without project files", () => {
|
|
61
|
-
const root = createProject();
|
|
62
|
-
const compiler = new TtscCompiler({
|
|
63
|
-
binary: tsgo,
|
|
64
|
-
cwd: root,
|
|
65
|
-
plugins: false,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
const result = compiler.transform();
|
|
69
|
-
|
|
70
|
-
assert.equal(result.type, "success");
|
|
71
|
-
assert.match(
|
|
72
|
-
result.typescript["src/main.ts"],
|
|
73
|
-
/const message: string = "api-ok"/,
|
|
74
|
-
);
|
|
75
|
-
assert.match(
|
|
76
|
-
result.typescript["src/main.ts"],
|
|
77
|
-
/console\.log\(\s*message\s*\)/,
|
|
78
|
-
);
|
|
79
|
-
assert.equal(result.typescript["dist/main.js"], undefined);
|
|
80
|
-
assert.equal(result.typescript["dist/main.d.ts"], undefined);
|
|
81
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
test("TtscCompiler.transform returns every included TypeScript source file", () => {
|
|
85
|
-
const root = createProject({
|
|
86
|
-
files: {
|
|
87
|
-
"src/helpers.ts":
|
|
88
|
-
"export const helper = (value: string): string => value.toUpperCase();\n",
|
|
89
|
-
"src/nested/model.ts": "export interface Model { value: string }\n",
|
|
90
|
-
},
|
|
91
|
-
source:
|
|
92
|
-
'import { helper } from "./helpers";\nconst message: string = helper("api-ok");\nconsole.log(message);\n',
|
|
93
|
-
});
|
|
94
|
-
const compiler = new TtscCompiler({
|
|
95
|
-
binary: tsgo,
|
|
96
|
-
cwd: root,
|
|
97
|
-
plugins: false,
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
const result = compiler.transform();
|
|
101
|
-
|
|
102
|
-
assert.equal(result.type, "success");
|
|
103
|
-
assert.match(result.typescript["src/main.ts"], /helper\("api-ok"\)/);
|
|
104
|
-
assert.match(result.typescript["src/helpers.ts"], /toUpperCase/);
|
|
105
|
-
assert.match(result.typescript["src/nested/model.ts"], /interface Model/);
|
|
106
|
-
for (const key of Object.keys(result.typescript)) {
|
|
107
|
-
assert.equal(key.startsWith("dist/"), false);
|
|
108
|
-
assert.equal(/\.(?:js|cjs|mjs|d\.ts|map)$/.test(key), false);
|
|
109
|
-
}
|
|
110
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
test("TtscCompiler.transform applies configured source plugins to TypeScript output", () => {
|
|
114
|
-
const root = createProject({
|
|
115
|
-
plugins: [{ transform: "./plugin.cjs" }],
|
|
116
|
-
source: 'export const value = goUpper("plugin");\nconsole.log(value);\n',
|
|
117
|
-
});
|
|
118
|
-
writeCompilerPlugin(root);
|
|
119
|
-
const compiler = new TtscCompiler({ binary: tsgo, cwd: root });
|
|
120
|
-
|
|
121
|
-
const result = compiler.transform();
|
|
122
|
-
|
|
123
|
-
assert.equal(result.type, "success");
|
|
124
|
-
assert.match(
|
|
125
|
-
result.typescript["src/main.ts"],
|
|
126
|
-
/export const value = "PLUGIN"/,
|
|
127
|
-
);
|
|
128
|
-
assert.match(result.typescript["src/main.ts"], /console\.log\(value\)/);
|
|
129
|
-
assert.equal(result.typescript["dist/main.js"], undefined);
|
|
130
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
test("TtscCompiler.transform rejects plugin output that is not TypeScript source", () => {
|
|
134
|
-
const root = createProject({
|
|
135
|
-
plugins: [{ transform: "./plugin.cjs" }],
|
|
136
|
-
source: 'export const value = goUpper("plugin");\nconsole.log(value);\n',
|
|
137
|
-
});
|
|
138
|
-
writeBrokenTransformPlugin(root);
|
|
139
|
-
const compiler = new TtscCompiler({ binary: tsgo, cwd: root });
|
|
140
|
-
|
|
141
|
-
const result = compiler.transform();
|
|
142
|
-
|
|
143
|
-
assert.equal(result.type, "exception");
|
|
144
|
-
assert.match(result.error.message, /did not return a TypeScript source map/);
|
|
145
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("TtscCompiler.transform returns failure on compiler diagnostics", () => {
|
|
149
|
-
const root = createProject({
|
|
150
|
-
source: 'const value: number = "not-a-number";\nconsole.log(value);\n',
|
|
151
|
-
});
|
|
152
|
-
const compiler = new TtscCompiler({
|
|
153
|
-
binary: tsgo,
|
|
154
|
-
cwd: root,
|
|
155
|
-
plugins: false,
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
const result = compiler.transform();
|
|
159
|
-
|
|
160
|
-
assert.equal(result.type, "failure");
|
|
161
|
-
assert.equal(result.diagnostics[0].code, 2322);
|
|
162
|
-
assert.match(result.typescript["src/main.ts"], /not-a-number/);
|
|
163
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
164
|
-
});
|
|
165
|
-
|
|
166
|
-
test("TtscCompiler.compile returns structured diagnostics", () => {
|
|
167
|
-
const root = createProject({
|
|
168
|
-
source: 'const value: number = "not-a-number";\nconsole.log(value);\n',
|
|
169
|
-
});
|
|
170
|
-
const compiler = new TtscCompiler({
|
|
171
|
-
binary: tsgo,
|
|
172
|
-
cwd: root,
|
|
173
|
-
plugins: false,
|
|
174
|
-
});
|
|
175
|
-
|
|
176
|
-
const result = compiler.compile();
|
|
177
|
-
|
|
178
|
-
assert.equal(result.type, "failure");
|
|
179
|
-
assert.equal(result.diagnostics.length, 1);
|
|
180
|
-
assert.equal(result.diagnostics[0].category, "error");
|
|
181
|
-
assert.equal(result.diagnostics[0].code, 2322);
|
|
182
|
-
assert.equal(typeof result.diagnostics[0].start, "number");
|
|
183
|
-
assert.equal(typeof result.diagnostics[0].length, "number");
|
|
184
|
-
assert.equal(result.diagnostics[0].line, 1);
|
|
185
|
-
assert.equal(result.diagnostics[0].character, 7);
|
|
186
|
-
assert.equal(result.diagnostics[0].file.endsWith("src/main.ts"), true);
|
|
187
|
-
assert.match(result.diagnostics[0].messageText, /not assignable/);
|
|
188
|
-
assert.equal(typeof result.output, "object");
|
|
189
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
190
|
-
});
|
|
191
|
-
|
|
192
|
-
test("TtscCompiler.compile does not accept per-call context overrides", () => {
|
|
193
|
-
const root = createProject();
|
|
194
|
-
const other = createProject({
|
|
195
|
-
plugins: [{ transform: "./missing-plugin.cjs" }],
|
|
196
|
-
});
|
|
197
|
-
const compiler = new TtscCompiler({
|
|
198
|
-
binary: tsgo,
|
|
199
|
-
cwd: root,
|
|
200
|
-
plugins: false,
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
const result = compiler.compile({
|
|
204
|
-
binary: path.join(other, "missing-tsgo"),
|
|
205
|
-
cwd: other,
|
|
206
|
-
plugins: [{ transform: "./missing-plugin.cjs" }],
|
|
207
|
-
});
|
|
208
|
-
|
|
209
|
-
assert.equal(result.type, "success");
|
|
210
|
-
assert.match(result.output["dist/main.js"], /api-ok/);
|
|
211
|
-
assert.equal(fs.existsSync(path.join(root, "dist")), false);
|
|
212
|
-
assert.equal(fs.existsSync(path.join(other, "dist")), false);
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
test("TtscCompiler.prepare builds source plugins and clean removes context cache", () => {
|
|
216
|
-
const root = createProject({
|
|
217
|
-
plugins: [{ transform: "./plugin.cjs" }],
|
|
218
|
-
});
|
|
219
|
-
writeSourcePlugin(root);
|
|
220
|
-
const cacheDir = path.join(root, ".cache", "ttsc");
|
|
221
|
-
const compiler = new TtscCompiler({ binary: tsgo, cacheDir, cwd: root });
|
|
222
|
-
|
|
223
|
-
const prepared = compiler.prepare();
|
|
224
|
-
|
|
225
|
-
assert.equal(prepared.length, 1);
|
|
226
|
-
assert.equal(fs.existsSync(prepared[0]), true);
|
|
227
|
-
assert.equal(prepared[0].startsWith(path.join(cacheDir, "plugins")), true);
|
|
228
|
-
|
|
229
|
-
const removed = compiler.clean();
|
|
230
|
-
|
|
231
|
-
assert.deepEqual(removed, [cacheDir]);
|
|
232
|
-
assert.equal(fs.existsSync(cacheDir), false);
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
function createProject(options = {}) {
|
|
236
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-compiler-api-"));
|
|
237
|
-
fs.mkdirSync(path.join(root, "src"), { recursive: true });
|
|
238
|
-
fs.writeFileSync(
|
|
239
|
-
path.join(root, "src", "main.ts"),
|
|
240
|
-
options.source ??
|
|
241
|
-
'const message: string = "api-ok";\nconsole.log(message);\n',
|
|
242
|
-
"utf8",
|
|
243
|
-
);
|
|
244
|
-
for (const [file, content] of Object.entries(options.files ?? {})) {
|
|
245
|
-
const location = path.join(root, file);
|
|
246
|
-
fs.mkdirSync(path.dirname(location), { recursive: true });
|
|
247
|
-
fs.writeFileSync(location, content, "utf8");
|
|
248
|
-
}
|
|
249
|
-
fs.writeFileSync(
|
|
250
|
-
path.join(root, "tsconfig.json"),
|
|
251
|
-
JSON.stringify(
|
|
252
|
-
{
|
|
253
|
-
compilerOptions: {
|
|
254
|
-
target: "ES2022",
|
|
255
|
-
module: "commonjs",
|
|
256
|
-
strict: true,
|
|
257
|
-
outDir: "dist",
|
|
258
|
-
declaration: true,
|
|
259
|
-
declarationMap: true,
|
|
260
|
-
rootDir: "src",
|
|
261
|
-
sourceMap: true,
|
|
262
|
-
plugins: options.plugins,
|
|
263
|
-
},
|
|
264
|
-
include: ["src"],
|
|
265
|
-
},
|
|
266
|
-
null,
|
|
267
|
-
2,
|
|
268
|
-
),
|
|
269
|
-
"utf8",
|
|
270
|
-
);
|
|
271
|
-
return root;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
function writeSourcePlugin(root) {
|
|
275
|
-
fs.writeFileSync(
|
|
276
|
-
path.join(root, "plugin.cjs"),
|
|
277
|
-
'module.exports = { name: "prepare-fixture", source: "./plugin-go" };\n',
|
|
278
|
-
"utf8",
|
|
279
|
-
);
|
|
280
|
-
fs.mkdirSync(path.join(root, "plugin-go"), { recursive: true });
|
|
281
|
-
fs.writeFileSync(
|
|
282
|
-
path.join(root, "plugin-go", "go.mod"),
|
|
283
|
-
"module example.com/preparefixture\n\ngo 1.26\n",
|
|
284
|
-
"utf8",
|
|
285
|
-
);
|
|
286
|
-
fs.writeFileSync(
|
|
287
|
-
path.join(root, "plugin-go", "main.go"),
|
|
288
|
-
"package main\n\nfunc main() {}\n",
|
|
289
|
-
"utf8",
|
|
290
|
-
);
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function writeBrokenTransformPlugin(root) {
|
|
294
|
-
fs.writeFileSync(
|
|
295
|
-
path.join(root, "plugin.cjs"),
|
|
296
|
-
'module.exports = { name: "broken-transform-fixture", source: "./plugin-go" };\n',
|
|
297
|
-
"utf8",
|
|
298
|
-
);
|
|
299
|
-
fs.mkdirSync(path.join(root, "plugin-go"), { recursive: true });
|
|
300
|
-
fs.writeFileSync(
|
|
301
|
-
path.join(root, "plugin-go", "go.mod"),
|
|
302
|
-
"module example.com/brokentransformfixture\n\ngo 1.26\n",
|
|
303
|
-
"utf8",
|
|
304
|
-
);
|
|
305
|
-
fs.writeFileSync(
|
|
306
|
-
path.join(root, "plugin-go", "main.go"),
|
|
307
|
-
[
|
|
308
|
-
"package main",
|
|
309
|
-
"",
|
|
310
|
-
"import (",
|
|
311
|
-
'\t"fmt"',
|
|
312
|
-
'\t"os"',
|
|
313
|
-
")",
|
|
314
|
-
"",
|
|
315
|
-
"func main() {",
|
|
316
|
-
'\tif len(os.Args) > 1 && os.Args[1] == "transform" {',
|
|
317
|
-
'\t\tfmt.Println(`{"output":{"dist/main.js":"console.log(\\"wrong\\");\\n"}}`)',
|
|
318
|
-
"\t\treturn",
|
|
319
|
-
"\t}",
|
|
320
|
-
"}",
|
|
321
|
-
"",
|
|
322
|
-
].join("\n"),
|
|
323
|
-
"utf8",
|
|
324
|
-
);
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function writeCompilerPlugin(root) {
|
|
328
|
-
fs.writeFileSync(
|
|
329
|
-
path.join(root, "plugin.cjs"),
|
|
330
|
-
'module.exports = { name: "compile-fixture", source: "./plugin-go" };\n',
|
|
331
|
-
"utf8",
|
|
332
|
-
);
|
|
333
|
-
fs.mkdirSync(path.join(root, "plugin-go"), { recursive: true });
|
|
334
|
-
fs.writeFileSync(
|
|
335
|
-
path.join(root, "plugin-go", "go.mod"),
|
|
336
|
-
"module example.com/compilefixture\n\ngo 1.26\n",
|
|
337
|
-
"utf8",
|
|
338
|
-
);
|
|
339
|
-
fs.writeFileSync(
|
|
340
|
-
path.join(root, "plugin-go", "main.go"),
|
|
341
|
-
[
|
|
342
|
-
"package main",
|
|
343
|
-
"",
|
|
344
|
-
"import (",
|
|
345
|
-
'\t"encoding/json"',
|
|
346
|
-
'\t"flag"',
|
|
347
|
-
'\t"fmt"',
|
|
348
|
-
'\t"os"',
|
|
349
|
-
'\t"path/filepath"',
|
|
350
|
-
'\t"strings"',
|
|
351
|
-
")",
|
|
352
|
-
"",
|
|
353
|
-
"func main() { os.Exit(run(os.Args[1:])) }",
|
|
354
|
-
"",
|
|
355
|
-
"func run(args []string) int {",
|
|
356
|
-
"\tif len(args) == 0 { return 2 }",
|
|
357
|
-
"\tswitch args[0] {",
|
|
358
|
-
'\tcase "build":',
|
|
359
|
-
"\t\treturn build(args[1:])",
|
|
360
|
-
'\tcase "transform":',
|
|
361
|
-
"\t\treturn transformSource(args[1:])",
|
|
362
|
-
'\tcase "check", "version":',
|
|
363
|
-
"\t\treturn 0",
|
|
364
|
-
"\tdefault:",
|
|
365
|
-
"\t\treturn 2",
|
|
366
|
-
"\t}",
|
|
367
|
-
"}",
|
|
368
|
-
"",
|
|
369
|
-
"func build(args []string) int {",
|
|
370
|
-
'\tfs := flag.NewFlagSet("build", flag.ContinueOnError)',
|
|
371
|
-
"\tfs.SetOutput(os.Stderr)",
|
|
372
|
-
'\tcwd := fs.String("cwd", "", "")',
|
|
373
|
-
'\toutDir := fs.String("outDir", "dist", "")',
|
|
374
|
-
'\t_ = fs.String("tsconfig", "", "")',
|
|
375
|
-
'\t_ = fs.String("plugins-json", "", "")',
|
|
376
|
-
'\t_ = fs.Bool("emit", false, "")',
|
|
377
|
-
'\t_ = fs.Bool("quiet", false, "")',
|
|
378
|
-
'\t_ = fs.Bool("verbose", false, "")',
|
|
379
|
-
'\t_ = fs.Bool("noEmit", false, "")',
|
|
380
|
-
"\tif err := fs.Parse(args); err != nil { return 2 }",
|
|
381
|
-
"\troot := *cwd",
|
|
382
|
-
'\tif root == "" { root, _ = os.Getwd() }',
|
|
383
|
-
'\tinput, err := os.ReadFile(filepath.Join(root, "src", "main.ts"))',
|
|
384
|
-
"\tif err != nil { fmt.Fprintln(os.Stderr, err); return 2 }",
|
|
385
|
-
'\tvalue := "PLUGIN"',
|
|
386
|
-
'\tif !strings.Contains(string(input), `goUpper("plugin")`) { value = "UNKNOWN" }',
|
|
387
|
-
'\toutput := fmt.Sprintf("\\"use strict\\";\\nObject.defineProperty(exports, \\"__esModule\\", { value: true });\\nexports.value = void 0;\\nconst value = %q;\\nexports.value = value;\\nconsole.log(value);\\n", value)',
|
|
388
|
-
'\tfile := filepath.Join(*outDir, "main.js")',
|
|
389
|
-
'\tif !filepath.IsAbs(*outDir) { file = filepath.Join(root, *outDir, "main.js") }',
|
|
390
|
-
"\tif err := os.MkdirAll(filepath.Dir(file), 0o755); err != nil { fmt.Fprintln(os.Stderr, err); return 2 }",
|
|
391
|
-
"\tif err := os.WriteFile(file, []byte(output), 0o644); err != nil { fmt.Fprintln(os.Stderr, err); return 2 }",
|
|
392
|
-
"\treturn 0",
|
|
393
|
-
"}",
|
|
394
|
-
"",
|
|
395
|
-
"type transformResult struct {",
|
|
396
|
-
'\tTypeScript map[string]string `json:"typescript"`',
|
|
397
|
-
"}",
|
|
398
|
-
"",
|
|
399
|
-
"func transformSource(args []string) int {",
|
|
400
|
-
'\tfs := flag.NewFlagSet("transform", flag.ContinueOnError)',
|
|
401
|
-
"\tfs.SetOutput(os.Stderr)",
|
|
402
|
-
'\tcwd := fs.String("cwd", "", "")',
|
|
403
|
-
'\t_ = fs.String("tsconfig", "", "")',
|
|
404
|
-
'\t_ = fs.String("plugins-json", "", "")',
|
|
405
|
-
"\tif err := fs.Parse(args); err != nil { return 2 }",
|
|
406
|
-
"\troot := *cwd",
|
|
407
|
-
'\tif root == "" { root, _ = os.Getwd() }',
|
|
408
|
-
'\tinput, err := os.ReadFile(filepath.Join(root, "src", "main.ts"))',
|
|
409
|
-
"\tif err != nil { fmt.Fprintln(os.Stderr, err); return 2 }",
|
|
410
|
-
'\tvalue := "PLUGIN"',
|
|
411
|
-
'\tif !strings.Contains(string(input), `goUpper("plugin")`) { value = "UNKNOWN" }',
|
|
412
|
-
'\toutput := fmt.Sprintf("export const value = %q;\\nconsole.log(value);\\n", value)',
|
|
413
|
-
'\tdata, err := json.Marshal(transformResult{TypeScript: map[string]string{"src/main.ts": output}})',
|
|
414
|
-
"\tif err != nil { fmt.Fprintln(os.Stderr, err); return 2 }",
|
|
415
|
-
"\tfmt.Fprintln(os.Stdout, string(data))",
|
|
416
|
-
"\treturn 0",
|
|
417
|
-
"}",
|
|
418
|
-
"",
|
|
419
|
-
].join("\n"),
|
|
420
|
-
"utf8",
|
|
421
|
-
);
|
|
422
|
-
}
|
package/test/platform.test.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
const assert = require("node:assert/strict");
|
|
2
|
-
const test = require("node:test");
|
|
3
|
-
const { resolveBinary } = require("../lib/compiler/internal/resolveBinary.js");
|
|
4
|
-
|
|
5
|
-
test("resolveBinary prefers TTSC_BINARY absolute override", () => {
|
|
6
|
-
const resolved = resolveBinary({
|
|
7
|
-
env: {
|
|
8
|
-
TTSC_BINARY: "/tmp/custom-ttsc",
|
|
9
|
-
},
|
|
10
|
-
});
|
|
11
|
-
assert.equal(resolved, "/tmp/custom-ttsc");
|
|
12
|
-
});
|
package/test/project.test.ts
DELETED
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
const assert = require("node:assert/strict");
|
|
2
|
-
const fs = require("node:fs");
|
|
3
|
-
const os = require("node:os");
|
|
4
|
-
const path = require("node:path");
|
|
5
|
-
const test = require("node:test");
|
|
6
|
-
|
|
7
|
-
const {
|
|
8
|
-
readProjectConfig,
|
|
9
|
-
} = require("../lib/compiler/internal/project/readProjectConfig.js");
|
|
10
|
-
const {
|
|
11
|
-
resolveProjectConfig,
|
|
12
|
-
} = require("../lib/compiler/internal/project/resolveProjectConfig.js");
|
|
13
|
-
|
|
14
|
-
test("resolveProjectConfig canonicalizes symlinked tsconfig paths", () => {
|
|
15
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-project-"));
|
|
16
|
-
const real = path.join(root, "real");
|
|
17
|
-
const link = path.join(root, "link");
|
|
18
|
-
fs.mkdirSync(real, { recursive: true });
|
|
19
|
-
fs.writeFileSync(path.join(real, "tsconfig.json"), "{}\n", "utf8");
|
|
20
|
-
fs.symlinkSync(real, link, "dir");
|
|
21
|
-
|
|
22
|
-
const resolved = resolveProjectConfig({
|
|
23
|
-
tsconfig: path.join(link, "tsconfig.json"),
|
|
24
|
-
});
|
|
25
|
-
assert.equal(resolved, fs.realpathSync(path.join(real, "tsconfig.json")));
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
test("readProjectConfig inherits plugins and outDir through tsconfig extends", () => {
|
|
29
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-project-"));
|
|
30
|
-
const shared = path.join(root, "config");
|
|
31
|
-
const project = path.join(root, "project");
|
|
32
|
-
fs.mkdirSync(shared, { recursive: true });
|
|
33
|
-
fs.mkdirSync(project, { recursive: true });
|
|
34
|
-
fs.writeFileSync(
|
|
35
|
-
path.join(shared, "tsconfig.json"),
|
|
36
|
-
JSON.stringify(
|
|
37
|
-
{
|
|
38
|
-
compilerOptions: {
|
|
39
|
-
outDir: "../dist/shared",
|
|
40
|
-
plugins: [{ transform: "./plugins/example.cjs" }],
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
null,
|
|
44
|
-
2,
|
|
45
|
-
),
|
|
46
|
-
"utf8",
|
|
47
|
-
);
|
|
48
|
-
fs.writeFileSync(
|
|
49
|
-
path.join(project, "tsconfig.json"),
|
|
50
|
-
JSON.stringify(
|
|
51
|
-
{
|
|
52
|
-
extends: "../config/tsconfig.json",
|
|
53
|
-
compilerOptions: {},
|
|
54
|
-
},
|
|
55
|
-
null,
|
|
56
|
-
2,
|
|
57
|
-
),
|
|
58
|
-
"utf8",
|
|
59
|
-
);
|
|
60
|
-
|
|
61
|
-
const parsed = readProjectConfig({
|
|
62
|
-
tsconfig: path.join(project, "tsconfig.json"),
|
|
63
|
-
});
|
|
64
|
-
assert.deepEqual(parsed.compilerOptions.plugins, [
|
|
65
|
-
{ transform: "./plugins/example.cjs" },
|
|
66
|
-
]);
|
|
67
|
-
assert.equal(parsed.compilerOptions.outDir, path.join(root, "dist/shared"));
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("readProjectConfig lets child tsconfig override inherited plugins", () => {
|
|
71
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-project-"));
|
|
72
|
-
const shared = path.join(root, "config");
|
|
73
|
-
const project = path.join(root, "project");
|
|
74
|
-
fs.mkdirSync(shared, { recursive: true });
|
|
75
|
-
fs.mkdirSync(project, { recursive: true });
|
|
76
|
-
fs.writeFileSync(
|
|
77
|
-
path.join(shared, "tsconfig.json"),
|
|
78
|
-
JSON.stringify(
|
|
79
|
-
{
|
|
80
|
-
compilerOptions: {
|
|
81
|
-
plugins: [{ transform: "./plugins/example.cjs" }],
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
null,
|
|
85
|
-
2,
|
|
86
|
-
),
|
|
87
|
-
"utf8",
|
|
88
|
-
);
|
|
89
|
-
fs.writeFileSync(
|
|
90
|
-
path.join(project, "tsconfig.json"),
|
|
91
|
-
JSON.stringify(
|
|
92
|
-
{
|
|
93
|
-
extends: "../config/tsconfig.json",
|
|
94
|
-
compilerOptions: {
|
|
95
|
-
plugins: [{ transform: "./local-plugin.cjs" }],
|
|
96
|
-
},
|
|
97
|
-
},
|
|
98
|
-
null,
|
|
99
|
-
2,
|
|
100
|
-
),
|
|
101
|
-
"utf8",
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
const parsed = readProjectConfig({
|
|
105
|
-
tsconfig: path.join(project, "tsconfig.json"),
|
|
106
|
-
});
|
|
107
|
-
assert.deepEqual(parsed.compilerOptions.plugins, [
|
|
108
|
-
{ transform: "./local-plugin.cjs" },
|
|
109
|
-
]);
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
test("readProjectConfig resolves package tsconfig extends", () => {
|
|
113
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-project-"));
|
|
114
|
-
const preset = path.join(root, "node_modules", "@scope", "tsconfig");
|
|
115
|
-
const project = path.join(root, "project");
|
|
116
|
-
fs.mkdirSync(preset, { recursive: true });
|
|
117
|
-
fs.mkdirSync(project, { recursive: true });
|
|
118
|
-
fs.writeFileSync(
|
|
119
|
-
path.join(preset, "base.json"),
|
|
120
|
-
JSON.stringify(
|
|
121
|
-
{
|
|
122
|
-
compilerOptions: {
|
|
123
|
-
outDir: "../../dist/preset",
|
|
124
|
-
plugins: [{ transform: "./plugins/from-preset.cjs" }],
|
|
125
|
-
},
|
|
126
|
-
},
|
|
127
|
-
null,
|
|
128
|
-
2,
|
|
129
|
-
),
|
|
130
|
-
"utf8",
|
|
131
|
-
);
|
|
132
|
-
fs.writeFileSync(
|
|
133
|
-
path.join(project, "tsconfig.json"),
|
|
134
|
-
JSON.stringify(
|
|
135
|
-
{
|
|
136
|
-
extends: "@scope/tsconfig/base.json",
|
|
137
|
-
compilerOptions: {},
|
|
138
|
-
},
|
|
139
|
-
null,
|
|
140
|
-
2,
|
|
141
|
-
),
|
|
142
|
-
"utf8",
|
|
143
|
-
);
|
|
144
|
-
|
|
145
|
-
const parsed = readProjectConfig({
|
|
146
|
-
tsconfig: path.join(project, "tsconfig.json"),
|
|
147
|
-
});
|
|
148
|
-
assert.deepEqual(parsed.compilerOptions.plugins, [
|
|
149
|
-
{ transform: "./plugins/from-preset.cjs" },
|
|
150
|
-
]);
|
|
151
|
-
assert.equal(
|
|
152
|
-
parsed.compilerOptions.outDir,
|
|
153
|
-
path.join(root, "node_modules", "dist", "preset"),
|
|
154
|
-
);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
test("readProjectConfig accepts JSONC comments and trailing commas", () => {
|
|
158
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-project-"));
|
|
159
|
-
fs.writeFileSync(
|
|
160
|
-
path.join(root, "tsconfig.json"),
|
|
161
|
-
`{
|
|
162
|
-
// plugin host configuration may live in JSONC tsconfig files
|
|
163
|
-
"compilerOptions": {
|
|
164
|
-
"plugins": [
|
|
165
|
-
{ "transform": "./plugins/jsonc.cjs" },
|
|
166
|
-
],
|
|
167
|
-
},
|
|
168
|
-
}\n`,
|
|
169
|
-
"utf8",
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
const parsed = readProjectConfig({
|
|
173
|
-
tsconfig: path.join(root, "tsconfig.json"),
|
|
174
|
-
});
|
|
175
|
-
assert.deepEqual(parsed.compilerOptions.plugins, [
|
|
176
|
-
{ transform: "./plugins/jsonc.cjs" },
|
|
177
|
-
]);
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
test("readProjectConfig rejects circular tsconfig extends", () => {
|
|
181
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-project-"));
|
|
182
|
-
fs.writeFileSync(
|
|
183
|
-
path.join(root, "a.json"),
|
|
184
|
-
JSON.stringify({ extends: "./b.json" }),
|
|
185
|
-
"utf8",
|
|
186
|
-
);
|
|
187
|
-
fs.writeFileSync(
|
|
188
|
-
path.join(root, "b.json"),
|
|
189
|
-
JSON.stringify({ extends: "./a.json" }),
|
|
190
|
-
"utf8",
|
|
191
|
-
);
|
|
192
|
-
|
|
193
|
-
assert.throws(
|
|
194
|
-
() => readProjectConfig({ tsconfig: path.join(root, "a.json") }),
|
|
195
|
-
/circular tsconfig extends detected/,
|
|
196
|
-
);
|
|
197
|
-
});
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
const assert = require("node:assert/strict");
|
|
2
|
-
const fs = require("node:fs");
|
|
3
|
-
const os = require("node:os");
|
|
4
|
-
const path = require("node:path");
|
|
5
|
-
const test = require("node:test");
|
|
6
|
-
|
|
7
|
-
const {
|
|
8
|
-
buildSourcePlugin,
|
|
9
|
-
} = require("../lib/plugin/internal/buildSourcePlugin.js");
|
|
10
|
-
|
|
11
|
-
test("buildSourcePlugin rejects a source outside a nearby Go module", () => {
|
|
12
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-source-plugin-"));
|
|
13
|
-
const source = path.join(root, "a", "b", "c", "d", "cmd");
|
|
14
|
-
fs.mkdirSync(source, { recursive: true });
|
|
15
|
-
|
|
16
|
-
assert.throws(
|
|
17
|
-
() =>
|
|
18
|
-
buildSourcePlugin({
|
|
19
|
-
baseDir: root,
|
|
20
|
-
pluginName: "missing-go-mod",
|
|
21
|
-
source,
|
|
22
|
-
ttscVersion: "1.0.0",
|
|
23
|
-
tsgoVersion: "7.0.0-dev",
|
|
24
|
-
}),
|
|
25
|
-
/go\.mod within 3 parent directories/,
|
|
26
|
-
);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test("buildSourcePlugin rejects non-directory and non-go.mod sources", () => {
|
|
30
|
-
const root = fs.mkdtempSync(path.join(os.tmpdir(), "ttsc-source-plugin-"));
|
|
31
|
-
const source = path.join(root, "plugin.txt");
|
|
32
|
-
fs.writeFileSync(source, "not a Go package\n", "utf8");
|
|
33
|
-
|
|
34
|
-
assert.throws(
|
|
35
|
-
() =>
|
|
36
|
-
buildSourcePlugin({
|
|
37
|
-
baseDir: root,
|
|
38
|
-
pluginName: "bad-source",
|
|
39
|
-
source,
|
|
40
|
-
ttscVersion: "1.0.0",
|
|
41
|
-
tsgoVersion: "7.0.0-dev",
|
|
42
|
-
}),
|
|
43
|
-
/Go package directory or go\.mod file/,
|
|
44
|
-
);
|
|
45
|
-
});
|