UNPKG

13.7 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.getEmitScriptTarget = exports.getUseDefineForClassFields = exports.getPatternFromSpec = exports.createTsInternals = void 0;
4const path_1 = require("path");
5const util_1 = require("./util");
6/** @internal */
7exports.createTsInternals = (0, util_1.cachedLookup)(createTsInternalsUncached);
8/**
9 * Given a reference to the TS compiler, return some TS internal functions that we
10 * could not or did not want to grab off the `ts` object.
11 * These have been copy-pasted from TS's source and tweaked as necessary.
12 *
13 * NOTE: This factory returns *only* functions which need a reference to the TS
14 * compiler. Other functions do not need a reference to the TS compiler so are
15 * exported directly from this file.
16 */
17function createTsInternalsUncached(_ts) {
18 const ts = _ts;
19 /**
20 * Copied from:
21 * https://github.com/microsoft/TypeScript/blob/v4.3.2/src/compiler/commandLineParser.ts#L2821-L2846
22 */
23 function getExtendsConfigPath(extendedConfig, host, basePath, errors, createDiagnostic) {
24 extendedConfig = (0, util_1.normalizeSlashes)(extendedConfig);
25 if (isRootedDiskPath(extendedConfig) ||
26 startsWith(extendedConfig, './') ||
27 startsWith(extendedConfig, '../')) {
28 let extendedConfigPath = getNormalizedAbsolutePath(extendedConfig, basePath);
29 if (!host.fileExists(extendedConfigPath) &&
30 !endsWith(extendedConfigPath, ts.Extension.Json)) {
31 extendedConfigPath = `${extendedConfigPath}.json`;
32 if (!host.fileExists(extendedConfigPath)) {
33 errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
34 return undefined;
35 }
36 }
37 return extendedConfigPath;
38 }
39 // If the path isn't a rooted or relative path, resolve like a module
40 const tsGte5_3_0 = (0, util_1.versionGteLt)(ts.version, '5.3.0');
41 const resolved = ts.nodeModuleNameResolver(extendedConfig, combinePaths(basePath, 'tsconfig.json'), { moduleResolution: ts.ModuleResolutionKind.NodeJs }, host,
42 /*cache*/ undefined,
43 /*projectRefs*/ undefined,
44 /*conditionsOrIsConfigLookup*/ tsGte5_3_0 ? undefined : true,
45 /*isConfigLookup*/ tsGte5_3_0 ? true : undefined);
46 if (resolved.resolvedModule) {
47 return resolved.resolvedModule.resolvedFileName;
48 }
49 errors.push(createDiagnostic(ts.Diagnostics.File_0_not_found, extendedConfig));
50 return undefined;
51 }
52 return { getExtendsConfigPath };
53}
54// These functions have alternative implementation to avoid copying too much from TS
55function isRootedDiskPath(path) {
56 return (0, path_1.isAbsolute)(path);
57}
58function combinePaths(path, ...paths) {
59 return (0, util_1.normalizeSlashes)((0, path_1.resolve)(path, ...paths.filter((path) => path)));
60}
61function getNormalizedAbsolutePath(fileName, currentDirectory) {
62 return (0, util_1.normalizeSlashes)(currentDirectory != null
63 ? (0, path_1.resolve)(currentDirectory, fileName)
64 : (0, path_1.resolve)(fileName));
65}
66function startsWith(str, prefix) {
67 return str.lastIndexOf(prefix, 0) === 0;
68}
69function endsWith(str, suffix) {
70 const expectedPos = str.length - suffix.length;
71 return expectedPos >= 0 && str.indexOf(suffix, expectedPos) === expectedPos;
72}
73// Reserved characters, forces escaping of any non-word (or digit), non-whitespace character.
74// It may be inefficient (we could just match (/[-[\]{}()*+?.,\\^$|#\s]/g), but this is future
75// proof.
76const reservedCharacterPattern = /[^\w\s\/]/g;
77/**
78 * @internal
79 * See also: getRegularExpressionForWildcard, which seems to do almost the same thing
80 */
81function getPatternFromSpec(spec, basePath) {
82 const pattern = spec && getSubPatternFromSpec(spec, basePath, excludeMatcher);
83 return pattern && `^(${pattern})${'($|/)'}`;
84}
85exports.getPatternFromSpec = getPatternFromSpec;
86function getSubPatternFromSpec(spec, basePath, { singleAsteriskRegexFragment, doubleAsteriskRegexFragment, replaceWildcardCharacter, }) {
87 let subpattern = '';
88 let hasWrittenComponent = false;
89 const components = getNormalizedPathComponents(spec, basePath);
90 const lastComponent = last(components);
91 // getNormalizedPathComponents includes the separator for the root component.
92 // We need to remove to create our regex correctly.
93 components[0] = removeTrailingDirectorySeparator(components[0]);
94 if (isImplicitGlob(lastComponent)) {
95 components.push('**', '*');
96 }
97 let optionalCount = 0;
98 for (let component of components) {
99 if (component === '**') {
100 subpattern += doubleAsteriskRegexFragment;
101 }
102 else {
103 if (hasWrittenComponent) {
104 subpattern += directorySeparator;
105 }
106 subpattern += component.replace(reservedCharacterPattern, replaceWildcardCharacter);
107 }
108 hasWrittenComponent = true;
109 }
110 while (optionalCount > 0) {
111 subpattern += ')?';
112 optionalCount--;
113 }
114 return subpattern;
115}
116const directoriesMatcher = {
117 singleAsteriskRegexFragment: '[^/]*',
118 /**
119 * Regex for the ** wildcard. Matches any num of subdirectories. When used for including
120 * files or directories, does not match subdirectories that start with a . character
121 */
122 doubleAsteriskRegexFragment: `(/[^/.][^/]*)*?`,
123 replaceWildcardCharacter: (match) => replaceWildcardCharacter(match, directoriesMatcher.singleAsteriskRegexFragment),
124};
125const excludeMatcher = {
126 singleAsteriskRegexFragment: '[^/]*',
127 doubleAsteriskRegexFragment: '(/.+?)?',
128 replaceWildcardCharacter: (match) => replaceWildcardCharacter(match, excludeMatcher.singleAsteriskRegexFragment),
129};
130function getNormalizedPathComponents(path, currentDirectory) {
131 return reducePathComponents(getPathComponents(path, currentDirectory));
132}
133function getPathComponents(path, currentDirectory = '') {
134 path = combinePaths(currentDirectory, path);
135 return pathComponents(path, getRootLength(path));
136}
137function reducePathComponents(components) {
138 if (!some(components))
139 return [];
140 const reduced = [components[0]];
141 for (let i = 1; i < components.length; i++) {
142 const component = components[i];
143 if (!component)
144 continue;
145 if (component === '.')
146 continue;
147 if (component === '..') {
148 if (reduced.length > 1) {
149 if (reduced[reduced.length - 1] !== '..') {
150 reduced.pop();
151 continue;
152 }
153 }
154 else if (reduced[0])
155 continue;
156 }
157 reduced.push(component);
158 }
159 return reduced;
160}
161function getRootLength(path) {
162 const rootLength = getEncodedRootLength(path);
163 return rootLength < 0 ? ~rootLength : rootLength;
164}
165function getEncodedRootLength(path) {
166 if (!path)
167 return 0;
168 const ch0 = path.charCodeAt(0);
169 // POSIX or UNC
170 if (ch0 === 47 /* CharacterCodes.slash */ || ch0 === 92 /* CharacterCodes.backslash */) {
171 if (path.charCodeAt(1) !== ch0)
172 return 1; // POSIX: "/" (or non-normalized "\")
173 const p1 = path.indexOf(ch0 === 47 /* CharacterCodes.slash */ ? directorySeparator : altDirectorySeparator, 2);
174 if (p1 < 0)
175 return path.length; // UNC: "//server" or "\\server"
176 return p1 + 1; // UNC: "//server/" or "\\server\"
177 }
178 // DOS
179 if (isVolumeCharacter(ch0) && path.charCodeAt(1) === 58 /* CharacterCodes.colon */) {
180 const ch2 = path.charCodeAt(2);
181 if (ch2 === 47 /* CharacterCodes.slash */ || ch2 === 92 /* CharacterCodes.backslash */)
182 return 3; // DOS: "c:/" or "c:\"
183 if (path.length === 2)
184 return 2; // DOS: "c:" (but not "c:d")
185 }
186 // URL
187 const schemeEnd = path.indexOf(urlSchemeSeparator);
188 if (schemeEnd !== -1) {
189 const authorityStart = schemeEnd + urlSchemeSeparator.length;
190 const authorityEnd = path.indexOf(directorySeparator, authorityStart);
191 if (authorityEnd !== -1) {
192 // URL: "file:///", "file://server/", "file://server/path"
193 // For local "file" URLs, include the leading DOS volume (if present).
194 // Per https://www.ietf.org/rfc/rfc1738.txt, a host of "" or "localhost" is a
195 // special case interpreted as "the machine from which the URL is being interpreted".
196 const scheme = path.slice(0, schemeEnd);
197 const authority = path.slice(authorityStart, authorityEnd);
198 if (scheme === 'file' &&
199 (authority === '' || authority === 'localhost') &&
200 isVolumeCharacter(path.charCodeAt(authorityEnd + 1))) {
201 const volumeSeparatorEnd = getFileUrlVolumeSeparatorEnd(path, authorityEnd + 2);
202 if (volumeSeparatorEnd !== -1) {
203 if (path.charCodeAt(volumeSeparatorEnd) === 47 /* CharacterCodes.slash */) {
204 // URL: "file:///c:/", "file://localhost/c:/", "file:///c%3a/", "file://localhost/c%3a/"
205 return ~(volumeSeparatorEnd + 1);
206 }
207 if (volumeSeparatorEnd === path.length) {
208 // URL: "file:///c:", "file://localhost/c:", "file:///c$3a", "file://localhost/c%3a"
209 // but not "file:///c:d" or "file:///c%3ad"
210 return ~volumeSeparatorEnd;
211 }
212 }
213 }
214 return ~(authorityEnd + 1); // URL: "file://server/", "http://server/"
215 }
216 return ~path.length; // URL: "file://server", "http://server"
217 }
218 // relative
219 return 0;
220}
221function ensureTrailingDirectorySeparator(path) {
222 if (!hasTrailingDirectorySeparator(path)) {
223 return path + directorySeparator;
224 }
225 return path;
226}
227function hasTrailingDirectorySeparator(path) {
228 return (path.length > 0 && isAnyDirectorySeparator(path.charCodeAt(path.length - 1)));
229}
230function isAnyDirectorySeparator(charCode) {
231 return (charCode === 47 /* CharacterCodes.slash */ || charCode === 92 /* CharacterCodes.backslash */);
232}
233function removeTrailingDirectorySeparator(path) {
234 if (hasTrailingDirectorySeparator(path)) {
235 return path.substr(0, path.length - 1);
236 }
237 return path;
238}
239const directorySeparator = '/';
240const altDirectorySeparator = '\\';
241const urlSchemeSeparator = '://';
242function isVolumeCharacter(charCode) {
243 return ((charCode >= 97 /* CharacterCodes.a */ && charCode <= 122 /* CharacterCodes.z */) ||
244 (charCode >= 65 /* CharacterCodes.A */ && charCode <= 90 /* CharacterCodes.Z */));
245}
246function getFileUrlVolumeSeparatorEnd(url, start) {
247 const ch0 = url.charCodeAt(start);
248 if (ch0 === 58 /* CharacterCodes.colon */)
249 return start + 1;
250 if (ch0 === 37 /* CharacterCodes.percent */ &&
251 url.charCodeAt(start + 1) === 51 /* CharacterCodes._3 */) {
252 const ch2 = url.charCodeAt(start + 2);
253 if (ch2 === 97 /* CharacterCodes.a */ || ch2 === 65 /* CharacterCodes.A */)
254 return start + 3;
255 }
256 return -1;
257}
258function some(array, predicate) {
259 if (array) {
260 if (predicate) {
261 for (const v of array) {
262 if (predicate(v)) {
263 return true;
264 }
265 }
266 }
267 else {
268 return array.length > 0;
269 }
270 }
271 return false;
272}
273function pathComponents(path, rootLength) {
274 const root = path.substring(0, rootLength);
275 const rest = path.substring(rootLength).split(directorySeparator);
276 if (rest.length && !lastOrUndefined(rest))
277 rest.pop();
278 return [root, ...rest];
279}
280function lastOrUndefined(array) {
281 return array.length === 0 ? undefined : array[array.length - 1];
282}
283function last(array) {
284 // Debug.assert(array.length !== 0);
285 return array[array.length - 1];
286}
287function replaceWildcardCharacter(match, singleAsteriskRegexFragment) {
288 return match === '*'
289 ? singleAsteriskRegexFragment
290 : match === '?'
291 ? '[^/]'
292 : '\\' + match;
293}
294/**
295 * An "includes" path "foo" is implicitly a glob "foo/** /*" (without the space) if its last component has no extension,
296 * and does not contain any glob characters itself.
297 */
298function isImplicitGlob(lastPathComponent) {
299 return !/[.*?]/.test(lastPathComponent);
300}
301const ts_ScriptTarget_ES5 = 1;
302const ts_ScriptTarget_ES2022 = 9;
303const ts_ScriptTarget_ESNext = 99;
304const ts_ModuleKind_Node16 = 100;
305const ts_ModuleKind_NodeNext = 199;
306// https://github.com/microsoft/TypeScript/blob/fc418a2e611c88cf9afa0115ff73490b2397d311/src/compiler/utilities.ts#L8761
307function getUseDefineForClassFields(compilerOptions) {
308 return compilerOptions.useDefineForClassFields === undefined
309 ? getEmitScriptTarget(compilerOptions) >= ts_ScriptTarget_ES2022
310 : compilerOptions.useDefineForClassFields;
311}
312exports.getUseDefineForClassFields = getUseDefineForClassFields;
313// https://github.com/microsoft/TypeScript/blob/fc418a2e611c88cf9afa0115ff73490b2397d311/src/compiler/utilities.ts#L8556
314function getEmitScriptTarget(compilerOptions) {
315 var _a;
316 return ((_a = compilerOptions.target) !== null && _a !== void 0 ? _a : ((compilerOptions.module === ts_ModuleKind_Node16 && ts_ScriptTarget_ES2022) ||
317 (compilerOptions.module === ts_ModuleKind_NodeNext && ts_ScriptTarget_ESNext) ||
318 ts_ScriptTarget_ES5));
319}
320exports.getEmitScriptTarget = getEmitScriptTarget;
321//# sourceMappingURL=ts-internals.js.map
\No newline at end of file