Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow for URL as sourceRoot #1427

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
1 change: 0 additions & 1 deletion src/adapter/resourceProvider/basicResourceProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ export class BasicResourceProvider implements IResourceProvider {
return { ok: false, url, error, statusCode: 200 };
}
}

return this.fetchHttp(url, cancellationToken, headers);
}
/**
Expand Down
1 change: 1 addition & 0 deletions src/adapter/scriptSkipper/implementation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ export class ScriptSkipper {
if (
!skipped &&
source.absolutePath &&
urlUtils.isAbsolute(source.absolutePath) &&
this._testSkipAuthored(urlUtils.absolutePathToFileUrl(source.absolutePath))
) {
this.setIsUrlBlackboxSkipped(url, true);
Expand Down
13 changes: 9 additions & 4 deletions src/adapter/sources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1082,9 +1082,10 @@ export class SourceContainer {
const todo: Promise<unknown>[] = [];
for (const url of map.sources) {
const absolutePath = await this.sourcePathResolver.urlToAbsolutePath({ url, map });
const resolvedUrl = absolutePath
? utils.absolutePathToFileUrl(absolutePath)
: map.computedSourceUrl(url);
const resolvedUrl =
absolutePath && utils.isAbsolute(absolutePath)
? utils.absolutePathToFileUrl(absolutePath)
: map.computedSourceUrl(url);

const existing = this._sourceMapSourcesByUrl.get(resolvedUrl);
if (existing) {
Expand All @@ -1106,7 +1107,6 @@ export class SourceContainer {
resolvedUrl,
});

const fileUrl = absolutePath && utils.absolutePathToFileUrl(absolutePath);
const smContent = this.sourceMapFactory.guardSourceMapFn(
map,
() => map.sourceContentFor(url, true),
Expand All @@ -1129,6 +1129,10 @@ export class SourceContainer {
}
}

const fileUrl =
absolutePath && utils.isAbsolute(absolutePath)
? utils.absolutePathToFileUrl(absolutePath)
: absolutePath;
const source = new SourceFromMap(
this,
resolvedUrl,
Expand All @@ -1146,6 +1150,7 @@ export class SourceContainer {
);
source.compiledToSourceUrl.set(compiled, url);
compiled.sourceMap.sourceByUrl.set(url, source);

todo.push(this._addSource(source));
}

Expand Down
5 changes: 3 additions & 2 deletions src/adapter/threads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1751,8 +1751,9 @@ export class Thread implements IVariableStoreLocationProvider {
}

const compiledSource =
this._sourceContainer.getSourceByOriginalUrl(urlUtils.absolutePathToFileUrl(chunk.path)) ||
this._sourceContainer.getSourceByOriginalUrl(chunk.path);
this._sourceContainer.getSourceByOriginalUrl(
urlUtils.isAbsolute(chunk.path) ? urlUtils.absolutePathToFileUrl(chunk.path) : chunk.path,
) || this._sourceContainer.getSourceByOriginalUrl(chunk.path);
if (!compiledSource) {
todo.push(chunk.toString());
continue;
Expand Down
14 changes: 9 additions & 5 deletions src/common/sourceMaps/sourceMapResolutionUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ export function getFullSourceEntry(sourceRoot: string | undefined, sourcePath: s
if (!sourceRoot.endsWith('/')) {
sourceRoot += '/';
}

return sourceRoot + sourcePath;
}

Expand All @@ -35,12 +34,13 @@ export async function getComputedSourceRoot(
logger: ILogger,
): Promise<string> {
generatedPath = utils.fileUrlToAbsolutePath(generatedPath) || generatedPath;

let absSourceRoot: string;
if (sourceRoot) {
if (utils.isFileUrl(sourceRoot)) {
// sourceRoot points to a local path like "file:///c:/project/src", make it an absolute path
absSourceRoot = utils.fileUrlToAbsolutePath(sourceRoot);
} else if (utils.isValidUrl(sourceRoot)) {
absSourceRoot = sourceRoot;
} else if (utils.isAbsolute(sourceRoot)) {
// sourceRoot is like "/src", should be like http://localhost/src, resolve to a local path using pathMaping.
// If path mappings do not apply (e.g. node), assume that sourceRoot is actually a local absolute path.
Expand Down Expand Up @@ -79,9 +79,13 @@ export async function getComputedSourceRoot(
);
}

absSourceRoot = utils.stripTrailingSlash(absSourceRoot);
absSourceRoot = fixDriveLetterAndSlashes(absSourceRoot);

if (!utils.isValidUrl(absSourceRoot)) {
absSourceRoot = utils.stripTrailingSlash(absSourceRoot);
absSourceRoot = fixDriveLetterAndSlashes(absSourceRoot);
} else {
//guarantees one slash in the end for later join with sources files
absSourceRoot = new URL(absSourceRoot).href;
}
return absSourceRoot;
}

Expand Down
15 changes: 15 additions & 0 deletions src/common/urlUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,16 @@ export function isValidUrl(url: string): boolean {
}
}

export function isValidUrlWithProtocol(url: string): boolean {
try {
const parsed = new URL(url);

return parsed.protocol.toLowerCase() == 'http:' || parsed.protocol.toLowerCase() == 'https:';
} catch (e) {
return false;
}
}

export function escapeForRegExp(s: string): string {
const chars = '^[]{}()\\.^$*+?|-,';

Expand Down Expand Up @@ -301,6 +311,11 @@ export function fileUrlToNetworkPath(urlOrPath: string): string {

// TODO: this does not escape/unescape special characters, but it should.
export function absolutePathToFileUrl(absolutePath: string): string {
if (!isAbsolute(absolutePath)) {
throw new Error(
`You are using the 'absolutePathToFileUrl()' on a string which is not absolute: ${absolutePath}`,
);
}
if (platform === 'win32') {
return 'file:///' + platformPathToUrlPath(absolutePath);
}
Expand Down
24 changes: 11 additions & 13 deletions src/targets/browser/browserPathResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import {
} from '../../common/sourceMaps/sourceMapResolutionUtils';
import { IUrlResolution } from '../../common/sourcePathResolver';
import * as utils from '../../common/urlUtils';
import { urlToRegex } from '../../common/urlUtils';
import { isValidUrlWithProtocol, urlToRegex } from '../../common/urlUtils';
import { PathMapping } from '../../configuration';
import { ISourcePathResolverOptions, SourcePathResolverBase } from '../sourcePathResolver';

Expand Down Expand Up @@ -87,7 +87,6 @@ export class BrowserSourcePathResolver extends SourcePathResolverBase<IOptions>
if (queryCharacter !== -1 && url.slice(queryCharacter - 4, queryCharacter) !== '.vue') {
url = url.slice(0, queryCharacter);
}

return map ? this.sourceMapSourceToAbsolute(url, map) : this.simpleUrlToAbsolute(url);
}

Expand Down Expand Up @@ -170,7 +169,6 @@ export class BrowserSourcePathResolver extends SourcePathResolverBase<IOptions>
}

url = this.normalizeSourceMapUrl(url);

const { pathMapping } = this.options;
const fullSourceEntry = getFullSourceEntry(map.sourceRoot, url);
let mappedFullSourceEntry = this.sourceMapOverrides.apply(fullSourceEntry);
Expand Down Expand Up @@ -200,18 +198,18 @@ export class BrowserSourcePathResolver extends SourcePathResolverBase<IOptions>
}

if (!path.isAbsolute(url)) {
return properResolve(
await getComputedSourceRoot(
map.sourceRoot,
map.metadata.compiledPath,
pathMapping,
defaultPathMappingResolver,
this.logger,
),
url,
const computedSourceRoot = await getComputedSourceRoot(
map.sourceRoot,
map.metadata.compiledPath,
pathMapping,
defaultPathMappingResolver,
this.logger,
);
if (isValidUrlWithProtocol(computedSourceRoot)) {
return new URL(url, computedSourceRoot).href;
}
return properResolve(computedSourceRoot, url);
}

return fixDriveLetterAndSlashes(url);
}

Expand Down
23 changes: 23 additions & 0 deletions src/test/sources/sources-supports-remote-sources-1424.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

Source event for
{
reason : new
source : {
name : localhost꞉8001/remote-test/string.ts
path : localhost꞉8001/remote-test/string.ts
sourceReference : <number>
}
}
text/javascript
---------
let i = 0;
i++;
debugger;
i++;
i++;
i++;
i++;
i++;
console.log(i);//ts file

---------
10 changes: 10 additions & 0 deletions src/test/sources/sourcesTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,16 @@ describe('sources', () => {
handle.assertLog({ substring: true });
});

itIntegrates('supports remote sources (#1424)', async ({ r }) => {
const p = await r.launchUrlAndLoad('index.html');
p.addScriptTag('remote-test/string.js');

const source = await p.waitForSource('string.ts');
await dumpSource(p, source, '');

p.assertLog();
});

itIntegrates('works with relative webpack sourcemaps (#479)', async ({ r }) => {
const p = await r.launchUrl('webpack/relative-paths.html');

Expand Down
10 changes: 10 additions & 0 deletions testWorkspace/web/remote-test/string.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 10 additions & 0 deletions testWorkspace/web/remote-test/string.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions testWorkspace/web/remote-test/string.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let i = 0;
i++;
debugger;
i++;
i++;
i++;
i++;
i++;
console.log(i);//ts file