@esportsplus/typescript 0.29.5 → 0.31.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 +11 -3
- package/bin/tsc-alias +1 -1
- package/build/cli/diagnostics.d.ts +4 -0
- package/build/cli/diagnostics.js +90 -0
- package/build/cli/tsc.d.ts +10 -2
- package/build/cli/tsc.js +352 -51
- package/build/compiler/ast.d.ts +7 -5
- package/build/compiler/ast.js +6 -6
- package/build/compiler/code.d.ts +5 -4
- package/build/compiler/code.js +12 -1
- package/build/compiler/coordinator.d.ts +17 -7
- package/build/compiler/coordinator.js +56 -32
- package/build/compiler/imports.d.ts +7 -3
- package/build/compiler/imports.js +30 -24
- package/build/compiler/index.d.ts +3 -0
- package/build/compiler/index.js +1 -0
- package/build/compiler/language-service.d.ts +24 -5
- package/build/compiler/language-service.js +215 -53
- package/build/compiler/plugins/index.d.ts +4 -2
- package/build/compiler/plugins/tsc.d.ts +1 -1
- package/build/compiler/plugins/vite.d.ts +6 -3
- package/build/compiler/plugins/vite.js +12 -7
- package/build/compiler/sourcemap.d.ts +50 -0
- package/build/compiler/sourcemap.js +247 -0
- package/build/compiler/types.d.ts +7 -6
- package/build/compiler/uid.d.ts +5 -2
- package/build/compiler/uid.js +33 -4
- package/build/index.d.ts +1 -1
- package/build/index.js +1 -1
- package/build/ts.d.ts +3 -0
- package/build/ts.js +3 -0
- package/package.json +22 -8
- package/tsconfig.dev.json +13 -0
- package/tsconfig.package.json +4 -1
- package/.claude/skills/code-audit/registry-typescript.json +0 -326
- package/.editorconfig +0 -9
- package/.gitattributes +0 -2
- package/.github/dependabot.yml +0 -25
- package/.github/workflows/bump.yml +0 -27
- package/.github/workflows/dependabot.yml +0 -58
- package/.github/workflows/publish.yml +0 -42
- package/.github/workflows/templates/bump.yml +0 -9
- package/.github/workflows/templates/dependabot.yml +0 -12
- package/.github/workflows/templates/publish.yml +0 -16
- package/src/cli/tsc.ts +0 -235
- package/src/compiler/ast.ts +0 -60
- package/src/compiler/code.ts +0 -27
- package/src/compiler/coordinator.ts +0 -279
- package/src/compiler/imports.ts +0 -175
- package/src/compiler/index.ts +0 -7
- package/src/compiler/language-service.ts +0 -121
- package/src/compiler/plugins/index.ts +0 -5
- package/src/compiler/plugins/tsc.ts +0 -6
- package/src/compiler/plugins/vite.ts +0 -91
- package/src/compiler/types.ts +0 -83
- package/src/compiler/uid.ts +0 -10
- package/src/constants.ts +0 -4
- package/src/index.ts +0 -1
- package/tests/cli/tsc.test.ts +0 -155
- package/tests/compiler/ast.test.ts +0 -131
- package/tests/compiler/code.test.ts +0 -73
- package/tests/compiler/coordinator.bench.ts +0 -101
- package/tests/compiler/coordinator.test.ts +0 -855
- package/tests/compiler/imports.test.ts +0 -167
- package/tests/compiler/language-service.test.ts +0 -90
- package/tests/compiler/plugins.test.ts +0 -172
- package/tests/compiler/uid.test.ts +0 -70
- package/tsconfig.json +0 -3
- package/vitest.config.ts +0 -14
|
@@ -1,73 +1,235 @@
|
|
|
1
|
+
import { API, DiagnosticCategory } from 'typescript/unstable/sync';
|
|
1
2
|
import { PACKAGE_NAME } from '../constants.js';
|
|
2
|
-
import
|
|
3
|
+
import fs from 'fs';
|
|
3
4
|
import path from 'path';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const backslashes = /\\/g;
|
|
6
|
+
let cache = new Map(), scratchEntry = null;
|
|
7
|
+
function advance(entry, changed) {
|
|
8
|
+
let snapshot = entry.api.updateSnapshot({ fileChanges: { changed } });
|
|
9
|
+
if (!entry.snapshot.isDisposed()) {
|
|
10
|
+
entry.snapshot.dispose();
|
|
11
|
+
}
|
|
12
|
+
entry.api.clearSourceFileCache();
|
|
13
|
+
entry.project = resolveProject(snapshot, entry.configFileName);
|
|
14
|
+
entry.snapshot = snapshot;
|
|
15
|
+
}
|
|
16
|
+
function advanceScratch(id, content) {
|
|
17
|
+
if (!scratchEntry) {
|
|
18
|
+
scratchEntry = createScratch(id);
|
|
19
|
+
}
|
|
20
|
+
else if (scratchEntry.file !== id) {
|
|
21
|
+
reseedScratch(scratchEntry, id);
|
|
22
|
+
}
|
|
23
|
+
let entry = scratchEntry;
|
|
24
|
+
entry.contents.set(id, content);
|
|
25
|
+
let snapshot = entry.api.updateSnapshot({ fileChanges: { changed: [id] } });
|
|
26
|
+
if (!entry.snapshot.isDisposed()) {
|
|
27
|
+
entry.snapshot.dispose();
|
|
28
|
+
}
|
|
29
|
+
entry.api.clearSourceFileCache();
|
|
30
|
+
entry.project = resolveProject(snapshot, entry.config);
|
|
31
|
+
entry.snapshot = snapshot;
|
|
32
|
+
return entry;
|
|
33
|
+
}
|
|
34
|
+
function createEntry(root) {
|
|
35
|
+
let configFileName = findConfig(root);
|
|
36
|
+
if (!configFileName) {
|
|
8
37
|
throw new Error(`${PACKAGE_NAME}: tsconfig.json not found`);
|
|
9
38
|
}
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
},
|
|
38
|
-
getScriptVersion: (fileName) => String(versions.get(fileName) || 0),
|
|
39
|
-
readFile: ts.sys.readFile
|
|
40
|
-
};
|
|
41
|
-
return { contents, host, rootFiles, service: ts.createLanguageService(host), versions };
|
|
39
|
+
let contents = new Map(), api = new API({ cwd: root, fs: overlayFileSystem(contents) }), snapshot = api.updateSnapshot({ openProjects: [configFileName] }), project = resolveProject(snapshot, configFileName);
|
|
40
|
+
for (let diagnostic of project.program.getConfigFileParsingDiagnostics()) {
|
|
41
|
+
if (diagnostic.category === DiagnosticCategory.Error) {
|
|
42
|
+
snapshot.dispose();
|
|
43
|
+
api.close();
|
|
44
|
+
throw new Error(`${PACKAGE_NAME}: error parsing tsconfig.json ${diagnostic.text}`);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return { api, configFileName, contents, pending: new Set(), project, root, seen: seed(project.program), snapshot };
|
|
48
|
+
}
|
|
49
|
+
function createScratch(file) {
|
|
50
|
+
let config = normalize(process.cwd()) + '/tsconfig.tsparse.json', contents = new Map();
|
|
51
|
+
contents.set(config, scratchConfig(file));
|
|
52
|
+
let api = new API({ cwd: process.cwd(), fs: overlayFileSystem(contents) }), snapshot = api.updateSnapshot({ openProjects: [config] }), project = resolveProject(snapshot, config);
|
|
53
|
+
return { api, config, contents, file, project, snapshot };
|
|
54
|
+
}
|
|
55
|
+
function disposeEntry(entry) {
|
|
56
|
+
if (!entry.snapshot.isDisposed()) {
|
|
57
|
+
entry.snapshot.dispose();
|
|
58
|
+
}
|
|
59
|
+
entry.api.close();
|
|
60
|
+
}
|
|
61
|
+
function disposeScratch(entry) {
|
|
62
|
+
if (!entry.snapshot.isDisposed()) {
|
|
63
|
+
entry.snapshot.dispose();
|
|
64
|
+
}
|
|
65
|
+
entry.api.close();
|
|
42
66
|
}
|
|
43
67
|
function getEntry(root) {
|
|
44
68
|
let entry = cache.get(root);
|
|
45
69
|
if (!entry) {
|
|
46
|
-
entry =
|
|
70
|
+
entry = createEntry(root);
|
|
47
71
|
cache.set(root, entry);
|
|
48
72
|
}
|
|
49
73
|
return entry;
|
|
50
74
|
}
|
|
51
|
-
|
|
75
|
+
function normalize(fileName) {
|
|
76
|
+
return fileName.replace(backslashes, '/');
|
|
77
|
+
}
|
|
78
|
+
function overlayFileSystem(contents) {
|
|
79
|
+
return {
|
|
80
|
+
fileExists: (fileName) => {
|
|
81
|
+
if (contents.has(normalize(fileName))) {
|
|
82
|
+
return true;
|
|
83
|
+
}
|
|
84
|
+
return undefined;
|
|
85
|
+
},
|
|
86
|
+
getAccessibleEntries: (directoryName) => {
|
|
87
|
+
let directory = normalize(directoryName), extra = [];
|
|
88
|
+
for (let key of contents.keys()) {
|
|
89
|
+
if (key.slice(0, key.lastIndexOf('/')) === directory) {
|
|
90
|
+
extra.push(key.slice(key.lastIndexOf('/') + 1));
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
if (extra.length === 0) {
|
|
94
|
+
return undefined;
|
|
95
|
+
}
|
|
96
|
+
let directories = [], files = [];
|
|
97
|
+
try {
|
|
98
|
+
for (let entry of fs.readdirSync(directory, { withFileTypes: true })) {
|
|
99
|
+
(entry.isDirectory() ? directories : files).push(entry.name);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
}
|
|
104
|
+
return { directories, files: [...files, ...extra] };
|
|
105
|
+
},
|
|
106
|
+
readFile: (fileName) => {
|
|
107
|
+
let content = contents.get(normalize(fileName));
|
|
108
|
+
if (content !== undefined) {
|
|
109
|
+
return content;
|
|
110
|
+
}
|
|
111
|
+
return undefined;
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
function recreate(entry) {
|
|
116
|
+
if (!entry.snapshot.isDisposed()) {
|
|
117
|
+
entry.snapshot.dispose();
|
|
118
|
+
}
|
|
119
|
+
entry.api.close();
|
|
120
|
+
entry.api = new API({ cwd: entry.root, fs: overlayFileSystem(entry.contents) });
|
|
121
|
+
entry.snapshot = entry.api.updateSnapshot({ openProjects: [entry.configFileName] });
|
|
122
|
+
entry.project = resolveProject(entry.snapshot, entry.configFileName);
|
|
123
|
+
entry.seen = seed(entry.project.program);
|
|
124
|
+
}
|
|
125
|
+
function reseedScratch(entry, file) {
|
|
126
|
+
entry.contents.delete(entry.file);
|
|
127
|
+
entry.contents.set(entry.config, scratchConfig(file));
|
|
128
|
+
if (!entry.snapshot.isDisposed()) {
|
|
129
|
+
entry.snapshot.dispose();
|
|
130
|
+
}
|
|
131
|
+
entry.api.close();
|
|
132
|
+
entry.api = new API({ cwd: process.cwd(), fs: overlayFileSystem(entry.contents) });
|
|
133
|
+
entry.file = file;
|
|
134
|
+
entry.snapshot = entry.api.updateSnapshot({ openProjects: [entry.config] });
|
|
135
|
+
entry.project = resolveProject(entry.snapshot, entry.config);
|
|
136
|
+
}
|
|
137
|
+
function resolveProject(snapshot, configFileName) {
|
|
138
|
+
let project = snapshot.getProject(configFileName);
|
|
139
|
+
if (!project) {
|
|
140
|
+
throw new Error(`${PACKAGE_NAME}: project not found for ${configFileName}`);
|
|
141
|
+
}
|
|
142
|
+
return project;
|
|
143
|
+
}
|
|
144
|
+
function scratchConfig(file) {
|
|
145
|
+
return JSON.stringify({
|
|
146
|
+
compilerOptions: {
|
|
147
|
+
allowJs: true,
|
|
148
|
+
module: 'esnext',
|
|
149
|
+
moduleResolution: 'bundler',
|
|
150
|
+
skipLibCheck: true,
|
|
151
|
+
target: 'es2024'
|
|
152
|
+
},
|
|
153
|
+
files: [file]
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
function seed(program) {
|
|
157
|
+
let seen = new Set();
|
|
158
|
+
for (let name of program.getSourceFileNames()) {
|
|
159
|
+
seen.add(normalize(name));
|
|
160
|
+
}
|
|
161
|
+
return seen;
|
|
162
|
+
}
|
|
163
|
+
const dispose = (root) => {
|
|
164
|
+
if (root === undefined) {
|
|
165
|
+
for (let entry of cache.values()) {
|
|
166
|
+
disposeEntry(entry);
|
|
167
|
+
}
|
|
168
|
+
cache.clear();
|
|
169
|
+
if (scratchEntry) {
|
|
170
|
+
disposeScratch(scratchEntry);
|
|
171
|
+
scratchEntry = null;
|
|
172
|
+
}
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
52
175
|
let entry = cache.get(root);
|
|
53
176
|
if (entry) {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
177
|
+
disposeEntry(entry);
|
|
178
|
+
cache.delete(root);
|
|
179
|
+
}
|
|
180
|
+
};
|
|
181
|
+
const findConfig = (startDir) => {
|
|
182
|
+
let current = path.resolve(startDir);
|
|
183
|
+
while (true) {
|
|
184
|
+
let candidate = path.join(current, 'tsconfig.json');
|
|
185
|
+
if (fs.existsSync(candidate)) {
|
|
186
|
+
return normalize(candidate);
|
|
187
|
+
}
|
|
188
|
+
let parent = path.dirname(current);
|
|
189
|
+
if (parent === current) {
|
|
190
|
+
return null;
|
|
191
|
+
}
|
|
192
|
+
current = parent;
|
|
57
193
|
}
|
|
58
194
|
};
|
|
195
|
+
const invalidate = (root, fileName) => {
|
|
196
|
+
let entry = cache.get(root);
|
|
197
|
+
if (!entry) {
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
let id = normalize(fileName);
|
|
201
|
+
entry.contents.delete(id);
|
|
202
|
+
entry.pending.add(id);
|
|
203
|
+
};
|
|
204
|
+
const parse = (fileName, content) => {
|
|
205
|
+
return scratch(fileName, content).sourceFile;
|
|
206
|
+
};
|
|
207
|
+
const scratch = (fileName, content) => {
|
|
208
|
+
let id = normalize(fileName), entry = advanceScratch(id, content), source = entry.project.program.getSourceFile(id);
|
|
209
|
+
if (!source) {
|
|
210
|
+
throw new Error(`${PACKAGE_NAME}: failed to parse ${fileName}`);
|
|
211
|
+
}
|
|
212
|
+
return { checker: entry.project.checker, program: entry.project.program, sourceFile: source };
|
|
213
|
+
};
|
|
59
214
|
const update = (root, fileName, content) => {
|
|
60
|
-
let entry = getEntry(root),
|
|
61
|
-
|
|
62
|
-
|
|
215
|
+
let entry = getEntry(root), id = normalize(fileName);
|
|
216
|
+
entry.contents.set(id, content);
|
|
217
|
+
if (entry.seen.has(id)) {
|
|
218
|
+
entry.pending.add(id);
|
|
219
|
+
let changed = [...entry.pending];
|
|
220
|
+
entry.pending.clear();
|
|
221
|
+
advance(entry, changed);
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
recreate(entry);
|
|
225
|
+
entry.pending.clear();
|
|
226
|
+
entry.seen.add(id);
|
|
63
227
|
}
|
|
64
|
-
entry.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
if (!program) {
|
|
68
|
-
throw new Error(`${PACKAGE_NAME}: failed to get program from language service`);
|
|
228
|
+
let source = entry.project.program.getSourceFile(id);
|
|
229
|
+
if (!source || source.text !== content) {
|
|
230
|
+
throw new Error(`${PACKAGE_NAME}: failed to load ${fileName} into the program`);
|
|
69
231
|
}
|
|
70
|
-
return program;
|
|
232
|
+
return { checker: entry.project.checker, program: entry.project.program };
|
|
71
233
|
};
|
|
72
|
-
export default { invalidate, update };
|
|
73
|
-
export { invalidate, update };
|
|
234
|
+
export default { dispose, findConfig, invalidate, parse, scratch, update };
|
|
235
|
+
export { dispose, findConfig, invalidate, parse, scratch, update };
|
|
@@ -7,12 +7,14 @@ declare const _default: {
|
|
|
7
7
|
}) => ({ root }?: {
|
|
8
8
|
root?: string;
|
|
9
9
|
}) => {
|
|
10
|
+
closeBundle: () => void;
|
|
11
|
+
closeWatcher: () => void;
|
|
10
12
|
configResolved: (config: unknown) => void;
|
|
11
|
-
enforce:
|
|
13
|
+
enforce: 'pre';
|
|
12
14
|
name: string;
|
|
13
15
|
transform: (code: string, id: string) => {
|
|
14
16
|
code: string;
|
|
15
|
-
map:
|
|
17
|
+
map: import("../index.js").SourceMapV3;
|
|
16
18
|
} | null;
|
|
17
19
|
watchChange: (id: string) => void;
|
|
18
20
|
};
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { Plugin } from '../types.js';
|
|
2
|
+
import type { SourceMapV3 } from '../sourcemap.js';
|
|
2
3
|
type VitePlugin = {
|
|
4
|
+
closeBundle: () => void;
|
|
5
|
+
closeWatcher: () => void;
|
|
3
6
|
configResolved: (config: unknown) => void;
|
|
4
7
|
enforce: 'pre';
|
|
5
8
|
name: string;
|
|
6
9
|
transform: (code: string, id: string) => {
|
|
7
10
|
code: string;
|
|
8
|
-
map:
|
|
11
|
+
map: SourceMapV3;
|
|
9
12
|
} | null;
|
|
10
13
|
watchChange: (id: string) => void;
|
|
11
14
|
};
|
|
@@ -14,7 +17,7 @@ type VitePluginOptions = {
|
|
|
14
17
|
onWatchChange?: () => void;
|
|
15
18
|
plugins: Plugin[];
|
|
16
19
|
};
|
|
17
|
-
|
|
20
|
+
export default _default;
|
|
21
|
+
declare function _default({ name, onWatchChange, plugins }: VitePluginOptions): ({ root }?: {
|
|
18
22
|
root?: string;
|
|
19
23
|
}) => VitePlugin;
|
|
20
|
-
export default _default;
|
|
@@ -1,12 +1,20 @@
|
|
|
1
|
-
import { ts } from '../../index.js';
|
|
2
1
|
import coordinator from '../coordinator.js';
|
|
3
2
|
import languageService from '../language-service.js';
|
|
3
|
+
import sourcemap from '../sourcemap.js';
|
|
4
4
|
const DIRECTORY_SEPARATOR_REGEX = /\\/g;
|
|
5
5
|
const FILE_REGEX = /\.[tj]sx?$/;
|
|
6
6
|
let contexts = new Map();
|
|
7
7
|
export default ({ name, onWatchChange, plugins }) => {
|
|
8
8
|
return ({ root } = {}) => {
|
|
9
9
|
return {
|
|
10
|
+
closeBundle() {
|
|
11
|
+
languageService.dispose(root || '');
|
|
12
|
+
contexts.delete(root || '');
|
|
13
|
+
},
|
|
14
|
+
closeWatcher() {
|
|
15
|
+
languageService.dispose(root || '');
|
|
16
|
+
contexts.delete(root || '');
|
|
17
|
+
},
|
|
10
18
|
configResolved(config) {
|
|
11
19
|
root ??= config.root;
|
|
12
20
|
},
|
|
@@ -17,20 +25,17 @@ export default ({ name, onWatchChange, plugins }) => {
|
|
|
17
25
|
return null;
|
|
18
26
|
}
|
|
19
27
|
try {
|
|
20
|
-
let normalizedId = id.replace(DIRECTORY_SEPARATOR_REGEX, '/'),
|
|
21
|
-
if (!sourceFile) {
|
|
22
|
-
sourceFile = ts.createSourceFile(normalizedId, code, ts.ScriptTarget.Latest, true);
|
|
23
|
-
}
|
|
28
|
+
let normalizedId = id.replace(DIRECTORY_SEPARATOR_REGEX, '/'), { checker, program } = languageService.update(root || '', normalizedId, code), sourceFile = program.getSourceFile(normalizedId) ?? languageService.parse(normalizedId, code);
|
|
24
29
|
let key = root || '', ctx = contexts.get(key);
|
|
25
30
|
if (!ctx) {
|
|
26
31
|
ctx = new Map();
|
|
27
32
|
contexts.set(key, ctx);
|
|
28
33
|
}
|
|
29
|
-
let result = coordinator.transform(plugins, code, sourceFile,
|
|
34
|
+
let result = coordinator.transform(plugins, code, sourceFile, { checker, program }, key, ctx);
|
|
30
35
|
if (!result.changed) {
|
|
31
36
|
return null;
|
|
32
37
|
}
|
|
33
|
-
return { code: result.code, map:
|
|
38
|
+
return { code: result.code, map: sourcemap.toSourceMapV3(result.map, result.code, code, normalizedId) };
|
|
34
39
|
}
|
|
35
40
|
catch (error) {
|
|
36
41
|
console.error(`${name}: error transforming ${id}:`, error);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
type Edit = {
|
|
2
|
+
end: number;
|
|
3
|
+
newText: string;
|
|
4
|
+
start: number;
|
|
5
|
+
};
|
|
6
|
+
type OffsetAnchor = {
|
|
7
|
+
afterEnd: number;
|
|
8
|
+
afterStart: number;
|
|
9
|
+
beforeStart: number;
|
|
10
|
+
identity: boolean;
|
|
11
|
+
};
|
|
12
|
+
type PositionMapping = {
|
|
13
|
+
generations: OffsetAnchor[][];
|
|
14
|
+
};
|
|
15
|
+
type Segment = {
|
|
16
|
+
genColumn: number;
|
|
17
|
+
name?: number;
|
|
18
|
+
originalColumn?: number;
|
|
19
|
+
originalLine?: number;
|
|
20
|
+
source?: number;
|
|
21
|
+
};
|
|
22
|
+
type SourceMapV3 = {
|
|
23
|
+
file?: string;
|
|
24
|
+
mappings: string;
|
|
25
|
+
names: string[];
|
|
26
|
+
sourceRoot?: string;
|
|
27
|
+
sources: (string | null)[];
|
|
28
|
+
sourcesContent?: (string | null)[];
|
|
29
|
+
version: 3;
|
|
30
|
+
};
|
|
31
|
+
declare const buildGeneration: (beforeText: string, edits: Edit[]) => OffsetAnchor[];
|
|
32
|
+
declare const composeEmittedMap: (map: SourceMapV3, mapping: PositionMapping, transformedText: string, originalText: string) => SourceMapV3;
|
|
33
|
+
declare const decode: (mappings: string) => number[][][];
|
|
34
|
+
declare const encode: (decoded: number[][][]) => string;
|
|
35
|
+
declare const originalPositionFor: (mapping: PositionMapping, transformedText: string, originalText: string, line: number, column: number) => {
|
|
36
|
+
column: number;
|
|
37
|
+
line: number;
|
|
38
|
+
};
|
|
39
|
+
declare const toSourceMapV3: (mapping: PositionMapping, transformedText: string, originalText: string, source: string) => SourceMapV3;
|
|
40
|
+
declare const _default: {
|
|
41
|
+
buildGeneration: typeof buildGeneration;
|
|
42
|
+
composeEmittedMap: typeof composeEmittedMap;
|
|
43
|
+
decode: typeof decode;
|
|
44
|
+
encode: typeof encode;
|
|
45
|
+
originalPositionFor: typeof originalPositionFor;
|
|
46
|
+
toSourceMapV3: typeof toSourceMapV3;
|
|
47
|
+
};
|
|
48
|
+
export default _default;
|
|
49
|
+
export { buildGeneration, composeEmittedMap, decode, encode, originalPositionFor, toSourceMapV3 };
|
|
50
|
+
export type { Edit, OffsetAnchor, PositionMapping, Segment, SourceMapV3 };
|
|
@@ -0,0 +1,247 @@
|
|
|
1
|
+
const BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
|
2
|
+
const CLASS_OTHER = 2;
|
|
3
|
+
const CLASS_SPACE = 1;
|
|
4
|
+
const CLASS_WORD = 0;
|
|
5
|
+
let inverse = buildInverse();
|
|
6
|
+
function buildInverse() {
|
|
7
|
+
let table = new Int8Array(128).fill(-1);
|
|
8
|
+
for (let i = 0, n = BASE64.length; i < n; i++) {
|
|
9
|
+
table[BASE64.charCodeAt(i)] = i;
|
|
10
|
+
}
|
|
11
|
+
return table;
|
|
12
|
+
}
|
|
13
|
+
function charClass(code) {
|
|
14
|
+
if ((code >= 48 && code <= 57) || (code >= 65 && code <= 90) || (code >= 97 && code <= 122) || code === 36 || code === 95) {
|
|
15
|
+
return CLASS_WORD;
|
|
16
|
+
}
|
|
17
|
+
if (code === 9 || code === 10 || code === 13 || code === 32) {
|
|
18
|
+
return CLASS_SPACE;
|
|
19
|
+
}
|
|
20
|
+
return CLASS_OTHER;
|
|
21
|
+
}
|
|
22
|
+
function decodeVlqArray(segment) {
|
|
23
|
+
let out = [], i = 0, n = segment.length;
|
|
24
|
+
while (i < n) {
|
|
25
|
+
let digit = 0, result = 0, shift = 0;
|
|
26
|
+
do {
|
|
27
|
+
digit = inverse[segment.charCodeAt(i)];
|
|
28
|
+
i++;
|
|
29
|
+
result += (digit & 31) << shift;
|
|
30
|
+
shift += 5;
|
|
31
|
+
} while (digit & 32);
|
|
32
|
+
out.push((result & 1) ? -(result >>> 1) : (result >>> 1));
|
|
33
|
+
}
|
|
34
|
+
return out;
|
|
35
|
+
}
|
|
36
|
+
function encodeVlq(value) {
|
|
37
|
+
let out = '', vlq = value < 0 ? ((-value) << 1) | 1 : value << 1;
|
|
38
|
+
do {
|
|
39
|
+
let digit = vlq & 31;
|
|
40
|
+
vlq >>>= 5;
|
|
41
|
+
if (vlq > 0) {
|
|
42
|
+
digit |= 32;
|
|
43
|
+
}
|
|
44
|
+
out += BASE64[digit];
|
|
45
|
+
} while (vlq > 0);
|
|
46
|
+
return out;
|
|
47
|
+
}
|
|
48
|
+
function lineStarts(text) {
|
|
49
|
+
let starts = [0];
|
|
50
|
+
for (let i = 0, n = text.length; i < n; i++) {
|
|
51
|
+
if (text.charCodeAt(i) === 10) {
|
|
52
|
+
starts.push(i + 1);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return starts;
|
|
56
|
+
}
|
|
57
|
+
function offsetToLineCol(starts, offset) {
|
|
58
|
+
let hi = starts.length - 1, line = 0, lo = 0;
|
|
59
|
+
while (lo <= hi) {
|
|
60
|
+
let mid = (lo + hi) >> 1;
|
|
61
|
+
if (starts[mid] <= offset) {
|
|
62
|
+
line = mid;
|
|
63
|
+
lo = mid + 1;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
hi = mid - 1;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return { column: offset - starts[line], line };
|
|
70
|
+
}
|
|
71
|
+
function rawToSegments(raw) {
|
|
72
|
+
let name = 0, origColumn = 0, origLine = 0, source = 0;
|
|
73
|
+
return raw.map((line) => {
|
|
74
|
+
let genColumn = 0;
|
|
75
|
+
return line.map((values) => {
|
|
76
|
+
genColumn += values[0];
|
|
77
|
+
let segment = { genColumn };
|
|
78
|
+
if (values.length >= 4) {
|
|
79
|
+
source += values[1];
|
|
80
|
+
origLine += values[2];
|
|
81
|
+
origColumn += values[3];
|
|
82
|
+
segment.originalColumn = origColumn;
|
|
83
|
+
segment.originalLine = origLine;
|
|
84
|
+
segment.source = source;
|
|
85
|
+
if (values.length >= 5) {
|
|
86
|
+
name += values[4];
|
|
87
|
+
segment.name = name;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return segment;
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
function resolveGeneration(anchors, offset) {
|
|
95
|
+
let found = anchors[0], hi = anchors.length - 1, lo = 0;
|
|
96
|
+
while (lo <= hi) {
|
|
97
|
+
let mid = (lo + hi) >> 1, anchor = anchors[mid];
|
|
98
|
+
if (offset < anchor.afterStart) {
|
|
99
|
+
hi = mid - 1;
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
found = anchor;
|
|
103
|
+
lo = mid + 1;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (found.identity) {
|
|
107
|
+
return found.beforeStart + (offset - found.afterStart);
|
|
108
|
+
}
|
|
109
|
+
return found.beforeStart;
|
|
110
|
+
}
|
|
111
|
+
function resolveOffset(mapping, offset) {
|
|
112
|
+
let generations = mapping.generations, result = offset;
|
|
113
|
+
for (let i = generations.length - 1; i >= 0; i--) {
|
|
114
|
+
result = resolveGeneration(generations[i], result);
|
|
115
|
+
}
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
function segmentAt(starts, offset, genColumn) {
|
|
119
|
+
let position = offsetToLineCol(starts, offset);
|
|
120
|
+
return { genColumn, originalColumn: position.column, originalLine: position.line, source: 0 };
|
|
121
|
+
}
|
|
122
|
+
function segmentsToRaw(segments) {
|
|
123
|
+
let name = 0, origColumn = 0, origLine = 0, source = 0;
|
|
124
|
+
return segments.map((line) => {
|
|
125
|
+
let genColumn = 0;
|
|
126
|
+
return line.map((segment) => {
|
|
127
|
+
let values = [segment.genColumn - genColumn];
|
|
128
|
+
genColumn = segment.genColumn;
|
|
129
|
+
if (segment.source !== undefined && segment.originalLine !== undefined && segment.originalColumn !== undefined) {
|
|
130
|
+
values.push(segment.source - source, segment.originalLine - origLine, segment.originalColumn - origColumn);
|
|
131
|
+
origColumn = segment.originalColumn;
|
|
132
|
+
origLine = segment.originalLine;
|
|
133
|
+
source = segment.source;
|
|
134
|
+
if (segment.name !== undefined) {
|
|
135
|
+
values.push(segment.name - name);
|
|
136
|
+
name = segment.name;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return values;
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
const buildGeneration = (beforeText, edits) => {
|
|
144
|
+
let afterCursor = 0, anchors = [], beforeCursor = 0, ordered = [...edits].sort((a, b) => a.start - b.start);
|
|
145
|
+
for (let i = 0, n = ordered.length; i < n; i++) {
|
|
146
|
+
let edit = ordered[i];
|
|
147
|
+
if (edit.start > beforeCursor) {
|
|
148
|
+
let length = edit.start - beforeCursor;
|
|
149
|
+
anchors.push({ afterEnd: afterCursor + length, afterStart: afterCursor, beforeStart: beforeCursor, identity: true });
|
|
150
|
+
afterCursor += length;
|
|
151
|
+
}
|
|
152
|
+
let inserted = edit.newText.length;
|
|
153
|
+
if (inserted > 0) {
|
|
154
|
+
anchors.push({ afterEnd: afterCursor + inserted, afterStart: afterCursor, beforeStart: edit.start, identity: false });
|
|
155
|
+
afterCursor += inserted;
|
|
156
|
+
}
|
|
157
|
+
beforeCursor = edit.end;
|
|
158
|
+
}
|
|
159
|
+
if (beforeCursor < beforeText.length) {
|
|
160
|
+
anchors.push({ afterEnd: afterCursor + (beforeText.length - beforeCursor), afterStart: afterCursor, beforeStart: beforeCursor, identity: true });
|
|
161
|
+
}
|
|
162
|
+
if (anchors.length === 0) {
|
|
163
|
+
anchors.push({ afterEnd: 0, afterStart: 0, beforeStart: 0, identity: true });
|
|
164
|
+
}
|
|
165
|
+
return anchors;
|
|
166
|
+
};
|
|
167
|
+
const composeEmittedMap = (map, mapping, transformedText, originalText) => {
|
|
168
|
+
let oStarts = lineStarts(originalText), segments = rawToSegments(decode(map.mappings)), tStarts = lineStarts(transformedText);
|
|
169
|
+
for (let i = 0, n = segments.length; i < n; i++) {
|
|
170
|
+
let line = segments[i];
|
|
171
|
+
for (let j = 0, m = line.length; j < m; j++) {
|
|
172
|
+
let segment = line[j];
|
|
173
|
+
if (segment.originalLine === undefined || segment.originalColumn === undefined) {
|
|
174
|
+
continue;
|
|
175
|
+
}
|
|
176
|
+
let base = segment.originalLine < tStarts.length ? tStarts[segment.originalLine] : transformedText.length, position = offsetToLineCol(oStarts, resolveOffset(mapping, base + segment.originalColumn));
|
|
177
|
+
segment.originalColumn = position.column;
|
|
178
|
+
segment.originalLine = position.line;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
let composed = {
|
|
182
|
+
mappings: encode(segmentsToRaw(segments)),
|
|
183
|
+
names: map.names ?? [],
|
|
184
|
+
sources: map.sources,
|
|
185
|
+
version: 3
|
|
186
|
+
};
|
|
187
|
+
if (map.file !== undefined) {
|
|
188
|
+
composed.file = map.file;
|
|
189
|
+
}
|
|
190
|
+
if (map.sourceRoot !== undefined) {
|
|
191
|
+
composed.sourceRoot = map.sourceRoot;
|
|
192
|
+
}
|
|
193
|
+
return composed;
|
|
194
|
+
};
|
|
195
|
+
const decode = (mappings) => {
|
|
196
|
+
if (mappings === '') {
|
|
197
|
+
return [];
|
|
198
|
+
}
|
|
199
|
+
return mappings.split(';').map((line) => {
|
|
200
|
+
if (line === '') {
|
|
201
|
+
return [];
|
|
202
|
+
}
|
|
203
|
+
return line.split(',').map((segment) => decodeVlqArray(segment));
|
|
204
|
+
});
|
|
205
|
+
};
|
|
206
|
+
const encode = (decoded) => {
|
|
207
|
+
let lines = [];
|
|
208
|
+
for (let i = 0, n = decoded.length; i < n; i++) {
|
|
209
|
+
let parts = [], segments = decoded[i];
|
|
210
|
+
for (let j = 0, m = segments.length; j < m; j++) {
|
|
211
|
+
let encoded = '', values = segments[j];
|
|
212
|
+
for (let k = 0, o = values.length; k < o; k++) {
|
|
213
|
+
encoded += encodeVlq(values[k]);
|
|
214
|
+
}
|
|
215
|
+
parts.push(encoded);
|
|
216
|
+
}
|
|
217
|
+
lines.push(parts.join(','));
|
|
218
|
+
}
|
|
219
|
+
return lines.join(';');
|
|
220
|
+
};
|
|
221
|
+
const originalPositionFor = (mapping, transformedText, originalText, line, column) => {
|
|
222
|
+
let tStarts = lineStarts(transformedText), base = line < tStarts.length ? tStarts[line] : transformedText.length;
|
|
223
|
+
return offsetToLineCol(lineStarts(originalText), resolveOffset(mapping, base + column));
|
|
224
|
+
};
|
|
225
|
+
const toSourceMapV3 = (mapping, transformedText, originalText, source) => {
|
|
226
|
+
let oStarts = lineStarts(originalText), segments = [], tStarts = lineStarts(transformedText);
|
|
227
|
+
for (let line = 0, n = tStarts.length; line < n; line++) {
|
|
228
|
+
let end = line + 1 < n ? tStarts[line + 1] - 1 : transformedText.length, previous = resolveOffset(mapping, tStarts[line]), start = tStarts[line];
|
|
229
|
+
let row = [segmentAt(oStarts, previous, 0)];
|
|
230
|
+
for (let offset = start + 1; offset < end; offset++) {
|
|
231
|
+
let current = charClass(transformedText.charCodeAt(offset));
|
|
232
|
+
if (current !== CLASS_OTHER && current === charClass(transformedText.charCodeAt(offset - 1))) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
let resolved = resolveOffset(mapping, offset);
|
|
236
|
+
if (resolved === previous) {
|
|
237
|
+
continue;
|
|
238
|
+
}
|
|
239
|
+
previous = resolved;
|
|
240
|
+
row.push(segmentAt(oStarts, resolved, offset - start));
|
|
241
|
+
}
|
|
242
|
+
segments.push(row);
|
|
243
|
+
}
|
|
244
|
+
return { mappings: encode(segmentsToRaw(segments)), names: [], sources: [source], version: 3 };
|
|
245
|
+
};
|
|
246
|
+
export default { buildGeneration, composeEmittedMap, decode, encode, originalPositionFor, toSourceMapV3 };
|
|
247
|
+
export { buildGeneration, composeEmittedMap, decode, encode, originalPositionFor, toSourceMapV3 };
|