@swiftuijs/twill 0.1.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.
Files changed (72) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +138 -0
  3. package/bin/twill.mjs +12 -0
  4. package/dist/branches.d.ts +12 -0
  5. package/dist/cli.d.ts +1 -0
  6. package/dist/cli.js +128 -0
  7. package/dist/cli.js.map +1 -0
  8. package/dist/compiler-Bi9TNOhX.js +1127 -0
  9. package/dist/compiler-Bi9TNOhX.js.map +1 -0
  10. package/dist/compiler.d.ts +50 -0
  11. package/dist/config.d.ts +6 -0
  12. package/dist/config.js +55 -0
  13. package/dist/config.js.map +1 -0
  14. package/dist/declarations.d.ts +14 -0
  15. package/dist/declarations.js +132 -0
  16. package/dist/declarations.js.map +1 -0
  17. package/dist/defer.d.ts +17 -0
  18. package/dist/doctor.d.ts +20 -0
  19. package/dist/doctor.js +198 -0
  20. package/dist/doctor.js.map +1 -0
  21. package/dist/editor.d.ts +53 -0
  22. package/dist/editor.js +261 -0
  23. package/dist/editor.js.map +1 -0
  24. package/dist/esbuild.d.ts +3 -0
  25. package/dist/esbuild.js +7 -0
  26. package/dist/esbuild.js.map +1 -0
  27. package/dist/files-D1mERoxc.js +46 -0
  28. package/dist/files-D1mERoxc.js.map +1 -0
  29. package/dist/files.d.ts +5 -0
  30. package/dist/index.d.ts +2 -0
  31. package/dist/index.js +2 -0
  32. package/dist/loader.d.ts +3 -0
  33. package/dist/loader.js +54 -0
  34. package/dist/loader.js.map +1 -0
  35. package/dist/parser.d.ts +9 -0
  36. package/dist/plugin-BGabvyT6.js +112 -0
  37. package/dist/plugin-BGabvyT6.js.map +1 -0
  38. package/dist/plugin.d.ts +9 -0
  39. package/dist/project.d.ts +62 -0
  40. package/dist/project.js +416 -0
  41. package/dist/project.js.map +1 -0
  42. package/dist/recovery.d.ts +3 -0
  43. package/dist/register.d.ts +1 -0
  44. package/dist/register.js +7 -0
  45. package/dist/register.js.map +1 -0
  46. package/dist/rollup.d.ts +3 -0
  47. package/dist/rollup.js +7 -0
  48. package/dist/rollup.js.map +1 -0
  49. package/dist/rspack.d.ts +3 -0
  50. package/dist/rspack.js +7 -0
  51. package/dist/rspack.js.map +1 -0
  52. package/dist/syntax.d.ts +11 -0
  53. package/dist/syntax.js +10 -0
  54. package/dist/syntax.js.map +1 -0
  55. package/dist/transpile-DwVekVFM.js +51 -0
  56. package/dist/transpile-DwVekVFM.js.map +1 -0
  57. package/dist/transpile.d.ts +11 -0
  58. package/dist/typescript-plugin.LICENSE.txt +375 -0
  59. package/dist/typescript-plugin.cjs +17741 -0
  60. package/dist/typescript-plugin.cjs.map +1 -0
  61. package/dist/typescript-plugin.d.ts +5 -0
  62. package/dist/vite-react.d.ts +10 -0
  63. package/dist/vite-react.js +22 -0
  64. package/dist/vite-react.js.map +1 -0
  65. package/dist/vite.d.ts +3 -0
  66. package/dist/vite.js +7 -0
  67. package/dist/vite.js.map +1 -0
  68. package/dist/webpack.d.ts +3 -0
  69. package/dist/webpack.js +7 -0
  70. package/dist/webpack.js.map +1 -0
  71. package/package.json +180 -0
  72. package/schemas/twill.schema.json +16 -0
@@ -0,0 +1,416 @@
1
+ import { a as isTwillFile, i as inferLanguage, n as extensions, o as originalPosition, r as generatedPosition, s as transform, t as TwillSyntaxError } from "./compiler-Bi9TNOhX.js";
2
+ import { loadConfig } from "./config.js";
3
+ import { t as isDependency } from "./files-D1mERoxc.js";
4
+ import MagicString from "magic-string";
5
+ import { dirname, resolve } from "node:path";
6
+ import ts from "typescript";
7
+ import remapping from "@ampproject/remapping";
8
+ //#region src/recovery.ts
9
+ /** Editor-only recovery; build and CLI compilation always use strict parsing. */
10
+ function recoverTransform(source, options) {
11
+ const repaired = new MagicString(source);
12
+ let text = source;
13
+ for (let attempt = 0; attempt < 8; attempt++) try {
14
+ const result = transform(text, options);
15
+ if (text === source) return result;
16
+ const repairMap = repaired.generateMap({
17
+ source: options.filename,
18
+ includeContent: true,
19
+ hires: true
20
+ });
21
+ const map = remapping([JSON.parse(result.map.toString()), JSON.parse(repairMap.toString())], () => null);
22
+ return {
23
+ ...result,
24
+ map
25
+ };
26
+ } catch (error) {
27
+ if (!(error instanceof TwillSyntaxError)) throw error;
28
+ const before = text.slice(0, error.offset);
29
+ let insertion;
30
+ let offset = error.offset;
31
+ if (/\.\s*$/.test(before)) insertion = "__twillIncomplete";
32
+ else if (offset >= text.length) {
33
+ const stack = [];
34
+ for (const token of text.matchAll(/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|`(?:\\.|[^`\\])*`|\/\*[\s\S]*?\*\/|\/\/[^\n]*|[()[\]{}])/g)) if ("([{".includes(token[0])) stack.push(token[0]);
35
+ else if (")]}".includes(token[0])) stack.pop();
36
+ const opening = stack.at(-1);
37
+ if (!opening) throw error;
38
+ insertion = {
39
+ "(": ")",
40
+ "[": "]",
41
+ "{": "}"
42
+ }[opening];
43
+ } else throw error;
44
+ if (offset >= text.length) offset = source.length;
45
+ else if (text !== source) {
46
+ const prefix = text.slice(0, offset).split("\n");
47
+ const point = originalPosition({
48
+ code: text,
49
+ map: repaired.generateMap({
50
+ source: options.filename,
51
+ hires: true
52
+ })
53
+ }, prefix.length, prefix.at(-1).length);
54
+ const starts = [0];
55
+ for (const match of source.matchAll(/\n/g)) starts.push(match.index + 1);
56
+ offset = point.line == null || point.column == null ? source.length : starts[point.line - 1] + point.column;
57
+ }
58
+ repaired.appendLeft(offset, insertion);
59
+ text = repaired.toString();
60
+ }
61
+ return transform(source, options);
62
+ }
63
+ //#endregion
64
+ //#region src/project.ts
65
+ function lineStarts(text) {
66
+ const starts = [0];
67
+ const breaks = /\n/g;
68
+ while (breaks.exec(text)) starts.push(breaks.lastIndex);
69
+ return starts;
70
+ }
71
+ function positionAt(starts, offset) {
72
+ let low = 0;
73
+ let high = starts.length;
74
+ while (low + 1 < high) {
75
+ const mid = low + high >>> 1;
76
+ if (starts[mid] <= offset) low = mid;
77
+ else high = mid;
78
+ }
79
+ return {
80
+ line: low + 1,
81
+ column: offset - starts[low]
82
+ };
83
+ }
84
+ var extraExtensions = extensions.map((extension) => ({
85
+ extension,
86
+ isMixedContent: false,
87
+ scriptKind: ts.ScriptKind.Deferred
88
+ }));
89
+ function virtualFilename(filename) {
90
+ filename = filename.replaceAll("\\", "/");
91
+ return isTwillFile(filename) ? filename + {
92
+ ts: ".ts",
93
+ tsx: ".tsx",
94
+ js: ".js",
95
+ jsx: ".jsx"
96
+ }[inferLanguage(filename)] : filename;
97
+ }
98
+ function sourceFilename(filename) {
99
+ filename = filename.replaceAll("\\", "/");
100
+ if (isTwillFile(filename)) return filename;
101
+ return filename.replace(/(\.twill)\.ts$/, "$1").replace(/(\.twillx)\.tsx$/, "$1");
102
+ }
103
+ /** A virtual-source TypeScript project shared by the CLI and VS Code extension. */
104
+ var TwillProject = class {
105
+ root;
106
+ service;
107
+ compilerOptions;
108
+ configFiles;
109
+ files;
110
+ overlays = /* @__PURE__ */ new Map();
111
+ results = /* @__PURE__ */ new Map();
112
+ lineMaps = /* @__PURE__ */ new WeakMap();
113
+ version = 0;
114
+ invalidation = 0;
115
+ fileVersions = /* @__PURE__ */ new Map();
116
+ configurationErrors;
117
+ options;
118
+ host;
119
+ recover;
120
+ discoverFiles;
121
+ constructor(tsconfig, options = {}, projectOptions = {}) {
122
+ const configFile = sourceFilename(resolve(tsconfig));
123
+ this.root = dirname(configFile);
124
+ this.recover = projectOptions.recover ?? false;
125
+ this.options = {
126
+ ...loadConfig(this.root, configFile),
127
+ ...options
128
+ };
129
+ const configReads = /* @__PURE__ */ new Set([configFile, sourceFilename(resolve(this.root, "twill.config.json"))]);
130
+ const configHost = {
131
+ ...ts.sys,
132
+ readFile: (filename) => {
133
+ configReads.add(sourceFilename(filename));
134
+ return ts.sys.readFile(filename);
135
+ }
136
+ };
137
+ const raw = projectOptions.inferred && !ts.sys.fileExists(configFile) ? { config: { compilerOptions: {
138
+ strict: true,
139
+ target: "ES2022",
140
+ module: "ESNext",
141
+ moduleResolution: "Bundler",
142
+ jsx: "react-jsx"
143
+ } } } : ts.readConfigFile(configFile, configHost.readFile);
144
+ const parsed = ts.parseJsonConfigFileContent(raw.config ?? {}, configHost, this.root, {
145
+ allowJs: true,
146
+ allowImportingTsExtensions: true,
147
+ noEmit: true
148
+ }, configFile, void 0, extraExtensions);
149
+ this.configurationErrors = [...raw.error ? [raw.error] : [], ...parsed.errors];
150
+ if (parsed.projectReferences?.length && !projectOptions.declarationRedirects) this.configurationErrors = [...this.configurationErrors, {
151
+ category: ts.DiagnosticCategory.Error,
152
+ code: 90002,
153
+ file: void 0,
154
+ start: void 0,
155
+ length: void 0,
156
+ messageText: "TypeScript project references are not supported by twill check. Check each referenced project separately."
157
+ }];
158
+ this.compilerOptions = parsed.options;
159
+ this.configFiles = [...configReads];
160
+ this.options.jsxImportSource ??= parsed.options.jsxImportSource;
161
+ this.files = parsed.fileNames.map(virtualFilename);
162
+ this.discoverFiles = () => ts.parseJsonConfigFileContent(raw.config ?? {}, configHost, this.root, {
163
+ allowJs: true,
164
+ allowImportingTsExtensions: true,
165
+ noEmit: true
166
+ }, configFile, void 0, extraExtensions).fileNames.map(virtualFilename);
167
+ const readFile = (name) => {
168
+ const original = sourceFilename(name);
169
+ const source = this.overlays.get(original) ?? ts.sys.readFile(original);
170
+ if (source === void 0) return void 0;
171
+ if (!isTwillFile(original)) return source;
172
+ try {
173
+ return this.result(original, source).code;
174
+ } catch {
175
+ return "";
176
+ }
177
+ };
178
+ const fileExists = (name) => this.overlays.has(sourceFilename(name)) || ts.sys.fileExists(sourceFilename(name));
179
+ const resolutionHost = {
180
+ ...ts.sys,
181
+ readFile,
182
+ fileExists
183
+ };
184
+ this.host = {
185
+ ...ts.sys,
186
+ getScriptFileNames: () => this.files,
187
+ useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,
188
+ getScriptVersion: (name) => `${this.invalidation}:${this.fileVersions.get(sourceFilename(name)) ?? 0}`,
189
+ getProjectVersion: () => String(this.version),
190
+ getScriptSnapshot: (name) => {
191
+ const text = readFile(name);
192
+ return text === void 0 ? void 0 : ts.ScriptSnapshot.fromString(text);
193
+ },
194
+ getCurrentDirectory: () => this.root,
195
+ getCompilationSettings: () => this.compilerOptions,
196
+ getDefaultLibFileName: projectOptions.defaultLibFileName ?? ((opts) => ts.getDefaultLibFilePath(opts)),
197
+ readFile,
198
+ fileExists,
199
+ resolveModuleNames: (names, importer) => names.map((name) => {
200
+ const resolved = ts.resolveModuleName(name, importer, this.compilerOptions, resolutionHost).resolvedModule;
201
+ if (resolved) {
202
+ const redirect = projectOptions.declarationRedirects?.get(sourceFilename(resolved.resolvedFileName));
203
+ return redirect ? {
204
+ ...resolved,
205
+ resolvedFileName: redirect,
206
+ extension: ts.Extension.Dts
207
+ } : {
208
+ ...resolved,
209
+ resolvedFileName: virtualFilename(resolved.resolvedFileName)
210
+ };
211
+ }
212
+ if (name.startsWith(".") || name.startsWith("/")) {
213
+ const base = resolve(dirname(sourceFilename(importer)), name);
214
+ const candidates = isTwillFile(base) ? [base] : extensions.flatMap((extension) => [base + extension, resolve(base, "index" + extension)]);
215
+ for (const candidate of candidates) if (fileExists(candidate)) {
216
+ const redirect = projectOptions.declarationRedirects?.get(sourceFilename(candidate));
217
+ if (redirect) return {
218
+ resolvedFileName: redirect,
219
+ extension: ts.Extension.Dts,
220
+ isExternalLibraryImport: false
221
+ };
222
+ const file = virtualFilename(candidate);
223
+ return {
224
+ resolvedFileName: file,
225
+ extension: file.endsWith(".tsx") ? ts.Extension.Tsx : ts.Extension.Ts,
226
+ isExternalLibraryImport: false
227
+ };
228
+ }
229
+ }
230
+ })
231
+ };
232
+ this.service = ts.createLanguageService(this.host);
233
+ }
234
+ /** Declaration-only native TypeScript emit from the checked virtual program. */
235
+ declarationOutput(outDir, declarationMap = true) {
236
+ const diagnostics = this.diagnostics();
237
+ if (diagnostics.some((item) => item.category === "error")) return {
238
+ diagnostics,
239
+ files: []
240
+ };
241
+ const previous = this.service.getProgram();
242
+ if (!previous) return {
243
+ diagnostics,
244
+ files: []
245
+ };
246
+ const options = {
247
+ ...this.compilerOptions,
248
+ noEmit: false,
249
+ declaration: true,
250
+ emitDeclarationOnly: true,
251
+ declarationMap,
252
+ noEmitOnError: true,
253
+ incremental: false,
254
+ composite: false,
255
+ rootDir: this.compilerOptions.rootDir ?? this.root,
256
+ outDir,
257
+ declarationDir: outDir,
258
+ allowImportingTsExtensions: true
259
+ };
260
+ const host = ts.createCompilerHost(options);
261
+ host.readFile = this.host.readFile;
262
+ host.fileExists = this.host.fileExists;
263
+ host.getCurrentDirectory = () => this.root;
264
+ host.resolveModuleNames = this.host.resolveModuleNames;
265
+ host.getSourceFile = (filename, languageVersion) => previous.getSourceFile(filename) ?? (host.readFile(filename) === void 0 ? void 0 : ts.createSourceFile(filename, host.readFile(filename), languageVersion, true));
266
+ const program = ts.createProgram(previous.getRootFileNames(), options, host);
267
+ const errors = ts.getPreEmitDiagnostics(program).map((item) => this.diagnostic(item));
268
+ if (errors.some((item) => item.category === "error")) return {
269
+ diagnostics: errors,
270
+ files: []
271
+ };
272
+ const files = [];
273
+ const emitted = program.emit(void 0, (filename, text, _bom, _error, sources) => {
274
+ files.push({
275
+ filename: sourceFilename(filename),
276
+ text,
277
+ sources: sources?.map((source) => sourceFilename(source.fileName)) ?? []
278
+ });
279
+ }, void 0, true);
280
+ return {
281
+ diagnostics: [...diagnostics, ...emitted.diagnostics.map((item) => this.diagnostic(item))],
282
+ files: emitted.emitSkipped ? [] : files
283
+ };
284
+ }
285
+ result(filename, source) {
286
+ const cached = this.results.get(filename);
287
+ if (cached?.source === source) return cached.result;
288
+ const result = (this.recover ? recoverTransform : transform)(source, {
289
+ ...this.options,
290
+ filename
291
+ });
292
+ this.results.set(filename, {
293
+ source,
294
+ result
295
+ });
296
+ return result;
297
+ }
298
+ update(filename, text) {
299
+ filename = sourceFilename(resolve(filename));
300
+ if (text !== void 0 && text === this.overlays.get(filename) && this.files.includes(virtualFilename(filename))) return;
301
+ if (text === void 0) this.overlays.delete(filename);
302
+ else this.overlays.set(filename, text);
303
+ this.fileVersions.set(filename, (this.fileVersions.get(filename) ?? 0) + 1);
304
+ if (!this.files.includes(virtualFilename(filename))) this.files.push(virtualFilename(filename));
305
+ this.results.delete(filename);
306
+ this.version++;
307
+ }
308
+ invalidate() {
309
+ this.invalidation++;
310
+ this.version++;
311
+ this.results.clear();
312
+ }
313
+ /** Refresh a disk version without discarding unsaved overlays or other transforms. */
314
+ refresh(filename, discover = false) {
315
+ filename = sourceFilename(resolve(filename));
316
+ if (discover) this.files = [.../* @__PURE__ */ new Set([...this.discoverFiles(), ...[...this.overlays.keys()].map(virtualFilename)])];
317
+ if (!this.overlays.has(filename)) {
318
+ this.results.delete(filename);
319
+ this.fileVersions.set(filename, (this.fileVersions.get(filename) ?? 0) + 1);
320
+ }
321
+ this.version++;
322
+ }
323
+ text(filename) {
324
+ filename = sourceFilename(resolve(filename));
325
+ return this.overlays.get(filename) ?? ts.sys.readFile(filename);
326
+ }
327
+ transformed(filename) {
328
+ filename = sourceFilename(resolve(filename));
329
+ const source = this.text(filename);
330
+ return source !== void 0 && isTwillFile(filename) ? this.result(filename, source) : void 0;
331
+ }
332
+ sourceFiles() {
333
+ const dependencies = this.service.getProgram()?.getSourceFiles().filter((file) => !file.isDeclarationFile && !isDependency(file.fileName)).map((file) => file.fileName) ?? [];
334
+ return [...new Set([...this.files, ...dependencies].map(sourceFilename))];
335
+ }
336
+ lines(filename, result) {
337
+ let lines = this.lineMaps.get(result);
338
+ if (!lines) {
339
+ lines = {
340
+ original: lineStarts(this.text(filename)),
341
+ generated: lineStarts(result.code)
342
+ };
343
+ this.lineMaps.set(result, lines);
344
+ }
345
+ return lines;
346
+ }
347
+ toGeneratedOffset(filename, offset) {
348
+ const result = this.transformed(filename);
349
+ if (!result) return offset;
350
+ const lines = this.lines(filename, result);
351
+ const sourcePosition = positionAt(lines.original, offset);
352
+ const position = generatedPosition(result, sourcePosition.line, sourcePosition.column);
353
+ if (position.line === null || position.column === null) return offset;
354
+ return (lines.generated[position.line - 1] ?? 0) + position.column;
355
+ }
356
+ toOriginalOffset(filename, offset) {
357
+ const result = this.transformed(filename);
358
+ if (!result) return offset;
359
+ const lines = this.lines(filename, result);
360
+ const sourcePosition = positionAt(lines.generated, offset);
361
+ const position = originalPosition(result, sourcePosition.line, sourcePosition.column);
362
+ if (position.line === null || position.column === null) return 0;
363
+ return (lines.original[position.line - 1] ?? 0) + position.column;
364
+ }
365
+ diagnostic(diagnostic) {
366
+ const filename = diagnostic.file ? sourceFilename(diagnostic.file.fileName) : void 0;
367
+ const source = filename ? this.text(filename) ?? "" : "";
368
+ const start = filename ? this.toOriginalOffset(filename, diagnostic.start ?? 0) : 0;
369
+ const end = filename ? this.toOriginalOffset(filename, (diagnostic.start ?? 0) + (diagnostic.length ?? 1)) : start + 1;
370
+ const before = source.slice(0, start).split(/\r\n|[\r\n\u2028\u2029]/);
371
+ return {
372
+ filename,
373
+ line: before.length,
374
+ column: before.at(-1).length,
375
+ length: Math.max(1, end - start),
376
+ code: diagnostic.code,
377
+ category: diagnostic.category === ts.DiagnosticCategory.Error ? "error" : diagnostic.category === ts.DiagnosticCategory.Warning ? "warning" : "message",
378
+ message: ts.flattenDiagnosticMessageText(diagnostic.messageText, "\n")
379
+ };
380
+ }
381
+ diagnostics(filename) {
382
+ const result = this.configurationErrors.map((error) => this.diagnostic(error));
383
+ if (!filename) result.push(...this.service.getCompilerOptionsDiagnostics().map((error) => this.diagnostic(error)));
384
+ const files = filename ? [virtualFilename(resolve(filename))] : this.sourceFiles().map(virtualFilename);
385
+ for (const file of files) {
386
+ if (/\.d\.[cm]?ts$/.test(file)) continue;
387
+ try {
388
+ if (this.recover && isTwillFile(sourceFilename(file))) transform(this.text(file) ?? "", {
389
+ ...this.options,
390
+ filename: sourceFilename(file)
391
+ });
392
+ this.transformed(file);
393
+ result.push(...[...this.service.getSyntacticDiagnostics(file), ...this.service.getSemanticDiagnostics(file)].map((error) => this.diagnostic(error)));
394
+ } catch (error) {
395
+ const syntax = error;
396
+ result.push({
397
+ filename: sourceFilename(file),
398
+ line: syntax.line ?? 1,
399
+ column: syntax.column ?? 0,
400
+ length: 1,
401
+ code: 90001,
402
+ category: "error",
403
+ message: syntax.message
404
+ });
405
+ }
406
+ }
407
+ return result;
408
+ }
409
+ dispose() {
410
+ this.service.dispose();
411
+ }
412
+ };
413
+ //#endregion
414
+ export { TwillProject, isDependency, sourceFilename, virtualFilename };
415
+
416
+ //# sourceMappingURL=project.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project.js","names":[],"sources":["../src/recovery.ts","../src/project.ts"],"sourcesContent":["import MagicString from 'magic-string';\nimport remapping from '@ampproject/remapping';\nimport {\n transform,\n TwillSyntaxError,\n originalPosition,\n type TransformOptions,\n type TransformResult,\n} from './compiler.js';\n\n/** Editor-only recovery; build and CLI compilation always use strict parsing. */\nexport function recoverTransform(source: string, options: TransformOptions): TransformResult {\n const repaired = new MagicString(source);\n let text = source;\n // Complete a missing member name or a few unfinished delimiters. Limit repair\n // attempts so malformed documents cannot lock up the extension host.\n for (let attempt = 0; attempt < 8; attempt++) {\n try {\n const result = transform(text, options);\n if (text === source) return result;\n const repairMap = repaired.generateMap({\n source: options.filename,\n includeContent: true,\n hires: true,\n });\n const map = remapping(\n [JSON.parse(result.map.toString()), JSON.parse(repairMap.toString())],\n () => null,\n );\n return { ...result, map: map as unknown as TransformResult['map'] };\n } catch (error) {\n if (!(error instanceof TwillSyntaxError)) throw error;\n const before = text.slice(0, error.offset);\n let insertion: string;\n let offset = error.offset;\n if (/\\.\\s*$/.test(before)) insertion = '__twillIncomplete';\n else if (offset >= text.length) {\n // Match lexical delimiters via the original source. This path only\n // handles suffix completion; it never makes build output valid.\n const stack: string[] = [];\n const scanner =\n /(?:\"(?:\\\\.|[^\"\\\\])*\"|'(?:\\\\.|[^'\\\\])*'|`(?:\\\\.|[^`\\\\])*`|\\/\\*[\\s\\S]*?\\*\\/|\\/\\/[^\\n]*|[()[\\]{}])/g;\n for (const token of text.matchAll(scanner)) {\n if ('([{'.includes(token[0])) stack.push(token[0]);\n else if (')]}'.includes(token[0])) stack.pop();\n }\n const opening = stack.at(-1);\n if (!opening) throw error;\n insertion = ({ '(': ')', '[': ']', '{': '}' } as Record<string, string>)[opening]!;\n } else throw error;\n // Later parser errors refer to the repaired text. Map interior offsets\n // back before inserting again; suffix repairs always anchor at source EOF.\n if (offset >= text.length) offset = source.length;\n else if (text !== source) {\n const prefix = text.slice(0, offset).split('\\n');\n const point = originalPosition(\n {\n code: text,\n map: repaired.generateMap({ source: options.filename, hires: true }),\n } as TransformResult,\n prefix.length,\n prefix.at(-1)!.length,\n );\n const starts = [0];\n for (const match of source.matchAll(/\\n/g)) starts.push(match.index! + 1);\n offset =\n point.line == null || point.column == null\n ? source.length\n : starts[point.line - 1]! + point.column;\n }\n repaired.appendLeft(offset, insertion);\n text = repaired.toString();\n }\n }\n return transform(source, options);\n}\n","import ts from 'typescript';\nimport { resolve, dirname } from 'node:path';\nimport {\n transform,\n extensions,\n isTwillFile,\n inferLanguage,\n originalPosition,\n generatedPosition,\n type TransformOptions,\n type TransformResult,\n} from './compiler.js';\nimport { loadConfig } from './config.js';\nimport { recoverTransform } from './recovery.js';\nimport { isDependency } from './files.js';\nexport { isDependency } from './files.js';\n\nfunction lineStarts(text: string): number[] {\n const starts = [0];\n // MagicString maps count LF-delimited lines. TS language-service APIs here\n // take absolute offsets, so keep the map's coordinates at this boundary.\n const breaks = /\\n/g;\n while (breaks.exec(text)) starts.push(breaks.lastIndex);\n return starts;\n}\nfunction positionAt(starts: number[], offset: number) {\n let low = 0;\n let high = starts.length;\n while (low + 1 < high) {\n const mid = (low + high) >>> 1;\n if (starts[mid]! <= offset) low = mid;\n else high = mid;\n }\n return { line: low + 1, column: offset - starts[low]! };\n}\n\n// TypeScript's config discovery accepts custom TS extensions only as Deferred;\n// each virtual filename below supplies the actual script kind to the service.\nconst extraExtensions = extensions.map((extension) => ({\n extension,\n isMixedContent: false,\n scriptKind: ts.ScriptKind.Deferred,\n}));\nexport function virtualFilename(filename: string): string {\n filename = filename.replaceAll('\\\\', '/');\n return isTwillFile(filename)\n ? filename + { ts: '.ts', tsx: '.tsx', js: '.js', jsx: '.jsx' }[inferLanguage(filename)]\n : filename;\n}\nexport function sourceFilename(filename: string): string {\n filename = filename.replaceAll('\\\\', '/');\n if (isTwillFile(filename)) return filename;\n return filename.replace(/(\\.twill)\\.ts$/, '$1').replace(/(\\.twillx)\\.tsx$/, '$1');\n}\n\nexport interface ProjectDiagnostic {\n filename?: string;\n line: number;\n column: number;\n length: number;\n code: number;\n category: 'error' | 'warning' | 'message';\n message: string;\n}\n\n/** A virtual-source TypeScript project shared by the CLI and VS Code extension. */\nexport class TwillProject {\n readonly root: string;\n readonly service: ts.LanguageService;\n readonly compilerOptions: ts.CompilerOptions;\n readonly configFiles: readonly string[];\n private files: string[];\n private overlays = new Map<string, string>();\n private results = new Map<string, { source: string; result: TransformResult }>();\n private lineMaps = new WeakMap<TransformResult, { original: number[]; generated: number[] }>();\n private version = 0;\n private invalidation = 0;\n private fileVersions = new Map<string, number>();\n private configurationErrors: readonly ts.Diagnostic[];\n private options: TransformOptions;\n private readonly host: ts.LanguageServiceHost;\n private recover: boolean;\n private discoverFiles: () => string[];\n\n constructor(\n tsconfig: string,\n options: TransformOptions = {},\n projectOptions: {\n inferred?: boolean;\n recover?: boolean;\n defaultLibFileName?: (options: ts.CompilerOptions) => string;\n declarationRedirects?: ReadonlyMap<string, string>;\n } = {},\n ) {\n const configFile = sourceFilename(resolve(tsconfig));\n this.root = dirname(configFile);\n this.recover = projectOptions.recover ?? false;\n this.options = { ...loadConfig(this.root, configFile), ...options };\n const configReads = new Set([\n configFile,\n sourceFilename(resolve(this.root, 'twill.config.json')),\n ]);\n const configHost = {\n ...ts.sys,\n readFile: (filename: string) => {\n configReads.add(sourceFilename(filename));\n return ts.sys.readFile(filename);\n },\n };\n const raw =\n projectOptions.inferred && !ts.sys.fileExists(configFile)\n ? {\n config: {\n compilerOptions: {\n strict: true,\n target: 'ES2022',\n module: 'ESNext',\n moduleResolution: 'Bundler',\n jsx: 'react-jsx',\n },\n },\n }\n : ts.readConfigFile(configFile, configHost.readFile);\n const parsed = ts.parseJsonConfigFileContent(\n raw.config ?? {},\n configHost,\n this.root,\n { allowJs: true, allowImportingTsExtensions: true, noEmit: true },\n configFile,\n undefined,\n extraExtensions,\n );\n this.configurationErrors = [...(raw.error ? [raw.error] : []), ...parsed.errors];\n if (parsed.projectReferences?.length && !projectOptions.declarationRedirects)\n this.configurationErrors = [\n ...this.configurationErrors,\n {\n category: ts.DiagnosticCategory.Error,\n code: 90002,\n file: undefined,\n start: undefined,\n length: undefined,\n messageText:\n 'TypeScript project references are not supported by twill check. Check each referenced project separately.',\n },\n ];\n this.compilerOptions = parsed.options;\n this.configFiles = [...configReads];\n this.options.jsxImportSource ??= parsed.options.jsxImportSource;\n this.files = parsed.fileNames.map(virtualFilename);\n this.discoverFiles = () =>\n ts\n .parseJsonConfigFileContent(\n raw.config ?? {},\n configHost,\n this.root,\n { allowJs: true, allowImportingTsExtensions: true, noEmit: true },\n configFile,\n undefined,\n extraExtensions,\n )\n .fileNames.map(virtualFilename);\n const readFile = (name: string) => {\n const original = sourceFilename(name);\n const source = this.overlays.get(original) ?? ts.sys.readFile(original);\n if (source === undefined) return undefined;\n if (!isTwillFile(original)) return source;\n // Syntax failures are reported separately, with original source positions.\n // Keep the service alive so other open documents still work.\n try {\n return this.result(original, source).code;\n } catch {\n return '';\n }\n };\n const fileExists = (name: string) =>\n this.overlays.has(sourceFilename(name)) || ts.sys.fileExists(sourceFilename(name));\n const resolutionHost: ts.ModuleResolutionHost = { ...ts.sys, readFile, fileExists };\n this.host = {\n ...ts.sys,\n getScriptFileNames: () => this.files,\n useCaseSensitiveFileNames: () => ts.sys.useCaseSensitiveFileNames,\n getScriptVersion: (name) =>\n `${this.invalidation}:${this.fileVersions.get(sourceFilename(name)) ?? 0}`,\n getProjectVersion: () => String(this.version),\n getScriptSnapshot: (name) => {\n const text = readFile(name);\n return text === undefined ? undefined : ts.ScriptSnapshot.fromString(text);\n },\n getCurrentDirectory: () => this.root,\n getCompilationSettings: () => this.compilerOptions,\n getDefaultLibFileName:\n projectOptions.defaultLibFileName ?? ((opts) => ts.getDefaultLibFilePath(opts)),\n readFile,\n fileExists,\n resolveModuleNames: (names, importer) =>\n names.map((name) => {\n const resolved = ts.resolveModuleName(\n name,\n importer,\n this.compilerOptions,\n resolutionHost,\n ).resolvedModule;\n if (resolved) {\n const redirect = projectOptions.declarationRedirects?.get(\n sourceFilename(resolved.resolvedFileName),\n );\n return redirect\n ? { ...resolved, resolvedFileName: redirect, extension: ts.Extension.Dts }\n : { ...resolved, resolvedFileName: virtualFilename(resolved.resolvedFileName) };\n }\n if (name.startsWith('.') || name.startsWith('/')) {\n const base = resolve(dirname(sourceFilename(importer)), name);\n const candidates = isTwillFile(base)\n ? [base]\n : extensions.flatMap((extension) => [\n base + extension,\n resolve(base, 'index' + extension),\n ]);\n for (const candidate of candidates) {\n if (fileExists(candidate)) {\n const redirect = projectOptions.declarationRedirects?.get(\n sourceFilename(candidate),\n );\n if (redirect)\n return {\n resolvedFileName: redirect,\n extension: ts.Extension.Dts,\n isExternalLibraryImport: false,\n };\n const file = virtualFilename(candidate);\n // Fallback candidates are exclusively .twill/.twillx; native\n // JS/TS extensions are resolved by TypeScript above.\n const extension = file.endsWith('.tsx') ? ts.Extension.Tsx : ts.Extension.Ts;\n return { resolvedFileName: file, extension, isExternalLibraryImport: false };\n }\n }\n }\n return undefined;\n }),\n };\n this.service = ts.createLanguageService(this.host);\n }\n\n /** Declaration-only native TypeScript emit from the checked virtual program. */\n declarationOutput(outDir: string, declarationMap = true) {\n const diagnostics = this.diagnostics();\n if (diagnostics.some((item) => item.category === 'error')) return { diagnostics, files: [] };\n const previous = this.service.getProgram();\n if (!previous) return { diagnostics, files: [] };\n const options: ts.CompilerOptions = {\n ...this.compilerOptions,\n noEmit: false,\n declaration: true,\n emitDeclarationOnly: true,\n declarationMap,\n noEmitOnError: true,\n incremental: false,\n composite: false,\n rootDir: this.compilerOptions.rootDir ?? this.root,\n outDir,\n declarationDir: outDir,\n allowImportingTsExtensions: true,\n };\n const host = ts.createCompilerHost(options);\n host.readFile = this.host.readFile!;\n host.fileExists = this.host.fileExists!;\n host.getCurrentDirectory = () => this.root;\n host.resolveModuleNames = this.host.resolveModuleNames;\n host.getSourceFile = (filename, languageVersion) =>\n previous.getSourceFile(filename) ??\n (host.readFile(filename) === undefined\n ? undefined\n : ts.createSourceFile(filename, host.readFile(filename)!, languageVersion, true));\n const program = ts.createProgram(previous.getRootFileNames(), options, host);\n const errors = ts.getPreEmitDiagnostics(program).map((item) => this.diagnostic(item));\n if (errors.some((item) => item.category === 'error')) return { diagnostics: errors, files: [] };\n const files: { filename: string; text: string; sources: string[] }[] = [];\n const emitted = program.emit(\n undefined,\n (filename, text, _bom, _error, sources) => {\n files.push({\n filename: sourceFilename(filename),\n text,\n sources: sources?.map((source) => sourceFilename(source.fileName)) ?? [],\n });\n },\n undefined,\n true,\n );\n return {\n diagnostics: [...diagnostics, ...emitted.diagnostics.map((item) => this.diagnostic(item))],\n files: emitted.emitSkipped ? [] : files,\n };\n }\n\n private result(filename: string, source: string): TransformResult {\n const cached = this.results.get(filename);\n if (cached?.source === source) return cached.result;\n const result = (this.recover ? recoverTransform : transform)(source, {\n ...this.options,\n filename,\n });\n this.results.set(filename, { source, result });\n return result;\n }\n\n update(filename: string, text?: string) {\n filename = sourceFilename(resolve(filename));\n // Hover and completion often submit the same open document. An unchanged\n // overlay must retain compiler results and TypeScript's semantic caches.\n if (\n text !== undefined &&\n text === this.overlays.get(filename) &&\n this.files.includes(virtualFilename(filename))\n )\n return;\n if (text === undefined) this.overlays.delete(filename);\n else this.overlays.set(filename, text);\n this.fileVersions.set(filename, (this.fileVersions.get(filename) ?? 0) + 1);\n if (!this.files.includes(virtualFilename(filename))) this.files.push(virtualFilename(filename));\n this.results.delete(filename);\n this.version++;\n }\n\n invalidate() {\n this.invalidation++;\n this.version++;\n this.results.clear();\n }\n\n /** Refresh a disk version without discarding unsaved overlays or other transforms. */\n refresh(filename: string, discover = false) {\n filename = sourceFilename(resolve(filename));\n if (discover)\n this.files = [\n ...new Set([...this.discoverFiles(), ...[...this.overlays.keys()].map(virtualFilename)]),\n ];\n if (!this.overlays.has(filename)) {\n this.results.delete(filename);\n this.fileVersions.set(filename, (this.fileVersions.get(filename) ?? 0) + 1);\n }\n this.version++;\n }\n\n text(filename: string): string | undefined {\n filename = sourceFilename(resolve(filename));\n return this.overlays.get(filename) ?? ts.sys.readFile(filename);\n }\n\n transformed(filename: string): TransformResult | undefined {\n filename = sourceFilename(resolve(filename));\n const source = this.text(filename);\n return source !== undefined && isTwillFile(filename)\n ? this.result(filename, source)\n : undefined;\n }\n\n sourceFiles(): string[] {\n const dependencies =\n this.service\n .getProgram()\n ?.getSourceFiles()\n .filter((file) => !file.isDeclarationFile && !isDependency(file.fileName))\n .map((file) => file.fileName) ?? [];\n return [...new Set([...this.files, ...dependencies].map(sourceFilename))];\n }\n\n private lines(filename: string, result: TransformResult) {\n let lines = this.lineMaps.get(result);\n if (!lines) {\n lines = { original: lineStarts(this.text(filename)!), generated: lineStarts(result.code) };\n this.lineMaps.set(result, lines);\n }\n return lines;\n }\n\n toGeneratedOffset(filename: string, offset: number): number {\n const result = this.transformed(filename);\n if (!result) return offset;\n const lines = this.lines(filename, result);\n const sourcePosition = positionAt(lines.original, offset);\n const position = generatedPosition(result, sourcePosition.line, sourcePosition.column);\n if (position.line === null || position.column === null) return offset;\n return (lines.generated[position.line - 1] ?? 0) + position.column;\n }\n\n toOriginalOffset(filename: string, offset: number): number {\n const result = this.transformed(filename);\n if (!result) return offset;\n const lines = this.lines(filename, result);\n const sourcePosition = positionAt(lines.generated, offset);\n const position = originalPosition(result, sourcePosition.line, sourcePosition.column);\n if (position.line === null || position.column === null) return 0;\n return (lines.original[position.line - 1] ?? 0) + position.column;\n }\n\n private diagnostic(diagnostic: ts.Diagnostic): ProjectDiagnostic {\n const filename = diagnostic.file ? sourceFilename(diagnostic.file.fileName) : undefined;\n const source = filename ? (this.text(filename) ?? '') : '';\n const start = filename ? this.toOriginalOffset(filename, diagnostic.start ?? 0) : 0;\n const end = filename\n ? this.toOriginalOffset(filename, (diagnostic.start ?? 0) + (diagnostic.length ?? 1))\n : start + 1;\n const before = source.slice(0, start).split(/\\r\\n|[\\r\\n\\u2028\\u2029]/);\n return {\n filename,\n line: before.length,\n column: before.at(-1)!.length,\n length: Math.max(1, end - start),\n code: diagnostic.code,\n category:\n diagnostic.category === ts.DiagnosticCategory.Error\n ? 'error'\n : diagnostic.category === ts.DiagnosticCategory.Warning\n ? 'warning'\n : 'message',\n message: ts.flattenDiagnosticMessageText(diagnostic.messageText, '\\n'),\n };\n }\n\n diagnostics(filename?: string): ProjectDiagnostic[] {\n const result = this.configurationErrors.map((error) => this.diagnostic(error));\n if (!filename)\n result.push(\n ...this.service.getCompilerOptionsDiagnostics().map((error) => this.diagnostic(error)),\n );\n const files = filename\n ? [virtualFilename(resolve(filename))]\n : this.sourceFiles().map(virtualFilename);\n for (const file of files) {\n if (/\\.d\\.[cm]?ts$/.test(file)) continue;\n try {\n if (this.recover && isTwillFile(sourceFilename(file)))\n transform(this.text(file) ?? '', { ...this.options, filename: sourceFilename(file) });\n this.transformed(file);\n result.push(\n ...[\n ...this.service.getSyntacticDiagnostics(file),\n ...this.service.getSemanticDiagnostics(file),\n ].map((error) => this.diagnostic(error)),\n );\n } catch (error) {\n const syntax = error as { message: string; line?: number; column?: number };\n result.push({\n filename: sourceFilename(file),\n line: syntax.line ?? 1,\n column: syntax.column ?? 0,\n length: 1,\n code: 90001,\n category: 'error',\n message: syntax.message,\n });\n }\n }\n return result;\n }\n\n dispose() {\n this.service.dispose();\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { TransformOptions, TransformResult } from './compiler.js';
2
+ /** Editor-only recovery; build and CLI compilation always use strict parsing. */
3
+ export declare function recoverTransform(source: string, options: TransformOptions): TransformResult;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,7 @@
1
+ import { register } from "node:module";
2
+ //#region src/register.ts
3
+ register("./loader.js", import.meta.url);
4
+ //#endregion
5
+ export {};
6
+
7
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"register.js","names":[],"sources":["../src/register.ts"],"sourcesContent":["import { register } from 'node:module';\nregister('./loader.js', import.meta.url);\n"],"mappings":";;AACA,SAAS,eAAe,YAAY,GAAG"}
@@ -0,0 +1,3 @@
1
+ declare const _default: (options?: import('./plugin.js').PluginOptions | undefined) => import('unplugin').RollupPlugin<any>;
2
+ export default _default;
3
+ export type { PluginOptions } from './plugin.js';
package/dist/rollup.js ADDED
@@ -0,0 +1,7 @@
1
+ import { t as twillPlugin } from "./plugin-BGabvyT6.js";
2
+ //#region src/rollup.ts
3
+ var rollup_default = twillPlugin.rollup;
4
+ //#endregion
5
+ export { rollup_default as default };
6
+
7
+ //# sourceMappingURL=rollup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rollup.js","names":[],"sources":["../src/rollup.ts"],"sourcesContent":["import { twillPlugin } from './plugin.js';\nexport default twillPlugin.rollup;\nexport type { PluginOptions } from './plugin.js';\n"],"mappings":";;AACA,IAAA,iBAAe,YAAY"}
@@ -0,0 +1,3 @@
1
+ declare const _default: (options?: import('./plugin.js').PluginOptions | undefined) => import('unplugin').RspackPluginInstance;
2
+ export default _default;
3
+ export type { PluginOptions } from './plugin.js';
package/dist/rspack.js ADDED
@@ -0,0 +1,7 @@
1
+ import { t as twillPlugin } from "./plugin-BGabvyT6.js";
2
+ //#region src/rspack.ts
3
+ var rspack_default = twillPlugin.rspack;
4
+ //#endregion
5
+ export { rspack_default as default };
6
+
7
+ //# sourceMappingURL=rspack.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rspack.js","names":[],"sources":["../src/rspack.ts"],"sourcesContent":["import { twillPlugin } from './plugin.js';\nexport default twillPlugin.rspack;\nexport type { PluginOptions } from './plugin.js';\n"],"mappings":";;AACA,IAAA,iBAAe,YAAY"}
@@ -0,0 +1,11 @@
1
+ import { TransformOptions } from './compiler.js';
2
+ /** Original ESTree and dialect metadata for source-aware tooling. */
3
+ export declare function parseSyntax(source: string, options?: TransformOptions): {
4
+ ast: any;
5
+ calls: any[];
6
+ guards: any[];
7
+ defers: any[];
8
+ switches: any[];
9
+ comments: any[];
10
+ closures: any;
11
+ };
package/dist/syntax.js ADDED
@@ -0,0 +1,10 @@
1
+ import { c as parse, i as inferLanguage } from "./compiler-Bi9TNOhX.js";
2
+ //#region src/syntax.ts
3
+ /** Original ESTree and dialect metadata for source-aware tooling. */
4
+ function parseSyntax(source, options = {}) {
5
+ return parse(source, options.language ?? inferLanguage(options.filename ?? "input.twill"), options.sourceType ?? "module");
6
+ }
7
+ //#endregion
8
+ export { parseSyntax };
9
+
10
+ //# sourceMappingURL=syntax.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"syntax.js","names":[],"sources":["../src/syntax.ts"],"sourcesContent":["import { parse } from './parser.js';\nimport { inferLanguage, type TransformOptions } from './compiler.js';\n\n/** Original ESTree and dialect metadata for source-aware tooling. */\nexport function parseSyntax(source: string, options: TransformOptions = {}) {\n return parse(\n source,\n options.language ?? inferLanguage(options.filename ?? 'input.twill'),\n options.sourceType ?? 'module',\n );\n}\n"],"mappings":";;;AAIA,SAAgB,YAAY,QAAgB,UAA4B,CAAC,GAAG;CAC1E,OAAO,MACL,QACA,QAAQ,YAAY,cAAc,QAAQ,YAAY,aAAa,GACnE,QAAQ,cAAc,QACxB;AACF"}
@@ -0,0 +1,51 @@
1
+ import { i as inferLanguage, s as transform } from "./compiler-Bi9TNOhX.js";
2
+ import MagicString from "magic-string";
3
+ import ts from "typescript";
4
+ import remapping from "@ampproject/remapping";
5
+ //#region src/transpile.ts
6
+ function transpile(source, options = {}, target = ts.ScriptTarget.ESNext) {
7
+ const filename = options.filename ?? "input.twill";
8
+ const result = transform(source, options);
9
+ const language = options.language ?? inferLanguage(filename);
10
+ return transpileNative(result.code, filename, language, result.map.toString(), options.jsxImportSource, target);
11
+ }
12
+ /** Native source never goes through Twill's parser or implicit-return rules. */
13
+ function transpileNative(source, filename, language = inferLanguage(filename), syntaxMap, jsxImportSource, target = ts.ScriptTarget.ESNext) {
14
+ if (language === "js") return {
15
+ code: source,
16
+ map: syntaxMap ?? new MagicString(source).generateMap({
17
+ source: filename,
18
+ includeContent: true,
19
+ hires: true
20
+ }).toString()
21
+ };
22
+ const output = ts.transpileModule(source, {
23
+ fileName: syntaxMap ? filename + (language.endsWith("x") ? ".tsx" : ".ts") : filename,
24
+ compilerOptions: {
25
+ target,
26
+ module: ts.ModuleKind.ESNext,
27
+ jsx: ts.JsxEmit.ReactJSX,
28
+ jsxImportSource,
29
+ sourceMap: true,
30
+ inlineSources: true,
31
+ isolatedModules: true,
32
+ verbatimModuleSyntax: true
33
+ },
34
+ reportDiagnostics: true
35
+ });
36
+ const errors = output.diagnostics?.filter((diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error);
37
+ if (errors?.length) throw new Error(ts.formatDiagnostics(errors, {
38
+ getCanonicalFileName: (name) => name,
39
+ getCurrentDirectory: () => "",
40
+ getNewLine: () => "\n"
41
+ }));
42
+ const map = syntaxMap ? remapping([JSON.parse(output.sourceMapText), JSON.parse(syntaxMap)], () => null).toString() : output.sourceMapText;
43
+ return {
44
+ code: output.outputText.replace(/^\/\/# sourceMappingURL=.*$/m, ""),
45
+ map
46
+ };
47
+ }
48
+ //#endregion
49
+ export { transpileNative as n, transpile as t };
50
+
51
+ //# sourceMappingURL=transpile-DwVekVFM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transpile-DwVekVFM.js","names":[],"sources":["../src/transpile.ts"],"sourcesContent":["import ts from 'typescript';\nimport remapping from '@ampproject/remapping';\nimport MagicString from 'magic-string';\nimport { transform, inferLanguage, type TransformOptions } from './compiler.js';\n\nexport function transpile(\n source: string,\n options: TransformOptions = {},\n target = ts.ScriptTarget.ESNext,\n) {\n const filename = options.filename ?? 'input.twill';\n const result = transform(source, options);\n const language = options.language ?? inferLanguage(filename);\n return transpileNative(\n result.code,\n filename,\n language,\n result.map.toString(),\n options.jsxImportSource,\n target,\n );\n}\n\n/** Native source never goes through Twill's parser or implicit-return rules. */\nexport function transpileNative(\n source: string,\n filename: string,\n language = inferLanguage(filename),\n syntaxMap?: string,\n jsxImportSource?: string,\n target = ts.ScriptTarget.ESNext,\n) {\n // Plain JavaScript needs no type erasure or JSX transform. Leave modern JS\n // (including comments and import attributes) to the host's target pipeline.\n if (language === 'js')\n return {\n code: source,\n map:\n syntaxMap ??\n new MagicString(source)\n .generateMap({ source: filename, includeContent: true, hires: true })\n .toString(),\n };\n const output = ts.transpileModule(source, {\n fileName: syntaxMap ? filename + (language.endsWith('x') ? '.tsx' : '.ts') : filename,\n compilerOptions: {\n target,\n module: ts.ModuleKind.ESNext,\n jsx: ts.JsxEmit.ReactJSX,\n jsxImportSource,\n sourceMap: true,\n inlineSources: true,\n isolatedModules: true,\n verbatimModuleSyntax: true,\n },\n reportDiagnostics: true,\n });\n const errors = output.diagnostics?.filter(\n (diagnostic) => diagnostic.category === ts.DiagnosticCategory.Error,\n );\n if (errors?.length)\n throw new Error(\n ts.formatDiagnostics(errors, {\n getCanonicalFileName: (name) => name,\n getCurrentDirectory: () => '',\n getNewLine: () => '\\n',\n }),\n );\n const map = syntaxMap\n ? remapping([JSON.parse(output.sourceMapText!), JSON.parse(syntaxMap)], () => null).toString()\n : output.sourceMapText!;\n return {\n code: output.outputText.replace(/^\\/\\/# sourceMappingURL=.*$/m, ''),\n map,\n };\n}\n"],"mappings":";;;;;AAKA,SAAgB,UACd,QACA,UAA4B,CAAC,GAC7B,SAAS,GAAG,aAAa,QACzB;CACA,MAAM,WAAW,QAAQ,YAAY;CACrC,MAAM,SAAS,UAAU,QAAQ,OAAO;CACxC,MAAM,WAAW,QAAQ,YAAY,cAAc,QAAQ;CAC3D,OAAO,gBACL,OAAO,MACP,UACA,UACA,OAAO,IAAI,SAAS,GACpB,QAAQ,iBACR,MACF;AACF;;AAGA,SAAgB,gBACd,QACA,UACA,WAAW,cAAc,QAAQ,GACjC,WACA,iBACA,SAAS,GAAG,aAAa,QACzB;CAGA,IAAI,aAAa,MACf,OAAO;EACL,MAAM;EACN,KACE,aACA,IAAI,YAAY,MAAM,CAAC,CACpB,YAAY;GAAE,QAAQ;GAAU,gBAAgB;GAAM,OAAO;EAAK,CAAC,CAAC,CACpE,SAAS;CAChB;CACF,MAAM,SAAS,GAAG,gBAAgB,QAAQ;EACxC,UAAU,YAAY,YAAY,SAAS,SAAS,GAAG,IAAI,SAAS,SAAS;EAC7E,iBAAiB;GACf;GACA,QAAQ,GAAG,WAAW;GACtB,KAAK,GAAG,QAAQ;GAChB;GACA,WAAW;GACX,eAAe;GACf,iBAAiB;GACjB,sBAAsB;EACxB;EACA,mBAAmB;CACrB,CAAC;CACD,MAAM,SAAS,OAAO,aAAa,QAChC,eAAe,WAAW,aAAa,GAAG,mBAAmB,KAChE;CACA,IAAI,QAAQ,QACV,MAAM,IAAI,MACR,GAAG,kBAAkB,QAAQ;EAC3B,uBAAuB,SAAS;EAChC,2BAA2B;EAC3B,kBAAkB;CACpB,CAAC,CACH;CACF,MAAM,MAAM,YACR,UAAU,CAAC,KAAK,MAAM,OAAO,aAAc,GAAG,KAAK,MAAM,SAAS,CAAC,SAAS,IAAI,CAAC,CAAC,SAAS,IAC3F,OAAO;CACX,OAAO;EACL,MAAM,OAAO,WAAW,QAAQ,gCAAgC,EAAE;EAClE;CACF;AACF"}
@@ -0,0 +1,11 @@
1
+ import { default as ts } from 'typescript';
2
+ import { TransformOptions } from './compiler.js';
3
+ export declare function transpile(source: string, options?: TransformOptions, target?: ts.ScriptTarget): {
4
+ code: string;
5
+ map: string;
6
+ };
7
+ /** Native source never goes through Twill's parser or implicit-return rules. */
8
+ export declare function transpileNative(source: string, filename: string, language?: import('./compiler.js').Language, syntaxMap?: string, jsxImportSource?: string, target?: ts.ScriptTarget): {
9
+ code: string;
10
+ map: string;
11
+ };