Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion tools/cli/src/helpers/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ function resolveSourceMapPath(sourceProcessor: SourceProcessor) {
return pipe(
asset.path,
(path) => sourceProcessor.getSourceMapPathFromSourceFile(path),
R.map((result) => result ?? pathIfExists(`${asset.path}.map`)),
R.map((path) => (path ? Ok(path) : Err('could not find source map for source'))),
R.map((path) => ({
...asset,
Expand Down
17 changes: 6 additions & 11 deletions tools/cli/src/helpers/logs.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import { Asset, log, LogLevel, ProcessAssetResult } from '@backtrace/sourcemap-tools';
import { Asset, log, LogLevel } from '@backtrace/sourcemap-tools';
import { CliLogger } from '../logger';
import { SourceAndSourceMapPaths } from '../models/Asset';

export function createAssetLogger(
logger: CliLogger,
): (level: LogLevel) => <T extends Asset | ProcessAssetResult>(message: string | ((t: T) => string)) => (asset: T) => T;
): (level: LogLevel) => <T extends Asset>(message: string | ((t: T) => string)) => (asset: T) => T;
export function createAssetLogger(
logger: CliLogger,
level: LogLevel,
): <T extends Asset | ProcessAssetResult>(message: string | ((t: T) => string)) => (asset: T) => T;
): <T extends Asset>(message: string | ((t: T) => string)) => (asset: T) => T;
export function createAssetLogger(logger: CliLogger, level?: LogLevel) {
function logAsset(level: LogLevel) {
const logFn = log(logger, level);

return function logAsset<T extends Asset | ProcessAssetResult>(message: string | ((t: T) => string)) {
return function logAsset<T extends Asset>(message: string | ((t: T) => string)) {
return function logAsset(asset: T) {
return logFn<T>(
(t) =>
`${'name' in t ? t.name : t.asset.name}: ${
typeof message === 'function' ? message(asset) : message
}`,
)(asset);
return logFn<T>((t) => `${t.name}: ${typeof message === 'function' ? message(asset) : message}`)(asset);
};
};
}
Expand All @@ -32,4 +27,4 @@ export const logAssets =
(logger: CliLogger, level: LogLevel) =>
(message: string) =>
<T extends SourceAndSourceMapPaths>(assets: T) =>
log(logger, level)<T>(`${assets.source.name}: ${message}`)(assets);
log(logger, level)<T>(`${assets.source.name}:${assets.sourceMap?.name ?? '?'}: ${message}`)(assets);
36 changes: 16 additions & 20 deletions tools/cli/src/sourcemaps/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,28 +199,24 @@ export function processSource(force: boolean) {
sourceMapDebugId: getSourceMapDebugId(sourceAndSourceMap),
});

const shouldProcess = (sourceDebugId: string | undefined, sourceMapDebugId: string | undefined) =>
force || !sourceDebugId || !sourceMapDebugId || sourceDebugId !== sourceMapDebugId;

return async function processSource(asset: SourceAndSourceMap): Promise<ProcessedSourceAndSourceMap> {
return pipe(asset, getDebugIds, ({ sourceDebugId, sourceMapDebugId }) =>
shouldProcess(sourceDebugId, sourceMapDebugId)
? pipe(
asset,
(asset) =>
sourceProcessor.processSourceAndSourceMap(
asset.source.content,
asset.sourceMap.content,
sourceDebugId ?? sourceMapDebugId,
),
(result) =>
({
source: { ...asset.source, content: result.source },
sourceMap: { ...asset.sourceMap, content: result.sourceMap },
debugId: result.debugId,
} as ProcessedSourceAndSourceMap),
)
: ({ ...asset, debugId: sourceDebugId } as ProcessedSourceAndSourceMap),
pipe(
asset,
(asset) =>
sourceProcessor.processSourceAndSourceMap(
asset.source.content,
asset.sourceMap.content,
sourceDebugId ?? sourceMapDebugId,
force,
),
(result) =>
({
source: { ...asset.source, content: result.source },
sourceMap: { ...asset.sourceMap, content: result.sourceMap },
debugId: result.debugId,
} as ProcessedSourceAndSourceMap),
),
);
};
}
Expand Down

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

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

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._btDebugIds=e._btDebugIds||{},e._btDebugIds[n]="4fe9a5c9-ab48-b240-9469-04aa2db251b6")}catch(e){}}();
;!function(){try{var k="_btDebugIds",u="undefined",v="4fe9a5c9-ab48-b240-9469-04aa2db251b6",a=function(x){try{x[k]=x[k]||{};x[k][n]=v}catch{}},n=(new Error).stack;n&&(u!=typeof window?a(window):u);n&&(u!=typeof global?a(global):u);n&&(u!=typeof self?a(self):u);n&&(u!=typeof globalThis?a(globalThis):u)}catch{}}();
function doSomething() {
console.log('Done something');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._btDebugIds=e._btDebugIds||{},e._btDebugIds[n]="d538bdaa-8149-8111-25f0-b5c0f472366a")}catch(e){}}();
;!function(){try{var k="_btDebugIds",u="undefined",v="d538bdaa-8149-8111-25f0-b5c0f472366a",a=function(x){try{x[k]=x[k]||{};x[k][n]=v}catch{}},n=(new Error).stack;n&&(u!=typeof window?a(window):u);n&&(u!=typeof global?a(global):u);n&&(u!=typeof self?a(self):u);n&&(u!=typeof globalThis?a(globalThis):u)}catch{}}();
function doSomething() {
console.log('Done something');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._btDebugIds=e._btDebugIds||{},e._btDebugIds[n]="4fe9a5c9-ab48-b240-9469-04aa2db251b6")}catch(e){}}();
;!function(){try{var k="_btDebugIds",u="undefined",v="4fe9a5c9-ab48-b240-9469-04aa2db251b6",a=function(x){try{x[k]=x[k]||{};x[k][n]=v}catch{}},n=(new Error).stack;n&&(u!=typeof window?a(window):u);n&&(u!=typeof global?a(global):u);n&&(u!=typeof self?a(self):u);n&&(u!=typeof globalThis?a(globalThis):u)}catch{}}();
function doSomething() {
console.log('Done something');
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
;!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},n=(new Error).stack;n&&(e._btDebugIds=e._btDebugIds||{},e._btDebugIds[n]="d538bdaa-8149-8111-25f0-b5c0f472366a")}catch(e){}}();
;!function(){try{var k="_btDebugIds",u="undefined",v="d538bdaa-8149-8111-25f0-b5c0f472366a",a=function(x){try{x[k]=x[k]||{};x[k][n]=v}catch{}},n=(new Error).stack;n&&(u!=typeof window?a(window):u);n&&(u!=typeof global?a(global):u);n&&(u!=typeof self?a(self):u);n&&(u!=typeof globalThis?a(globalThis):u)}catch{}}();
function doSomething() {
console.log('Done something');
}
Expand Down
2 changes: 1 addition & 1 deletion tools/cli/tests/_files/processed-sources/entry1.js

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

2 changes: 1 addition & 1 deletion tools/cli/tests/_files/processed-sources/entry2.js

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

2 changes: 1 addition & 1 deletion tools/cli/tests/_files/processed-with-sources/entry1.js

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

2 changes: 1 addition & 1 deletion tools/cli/tests/_files/processed-with-sources/entry2.js

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

2 changes: 1 addition & 1 deletion tools/cli/tests/_files/processed/entry1.js

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

2 changes: 1 addition & 1 deletion tools/cli/tests/_files/processed/entry2.js

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

49 changes: 42 additions & 7 deletions tools/cli/tests/sourcemaps/process.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,12 @@ describe('process', () => {
assert(result.isOk(), result.data as string);

for (const source of Object.values(originalSources)) {
expect(spy).toBeCalledWith(source, expect.anything(), expectAnythingOrNothing());
expect(spy).toBeCalledWith(
source,
expect.anything(),
expectAnythingOrNothing(),
expectAnythingOrNothing(),
);
}
}),
);
Expand Down Expand Up @@ -194,7 +199,12 @@ describe('process', () => {
assert(result.isOk(), result.data as string);

for (const source of Object.values(originalSources)) {
expect(spy).toBeCalledWith(source, expect.anything(), expectAnythingOrNothing());
expect(spy).toBeCalledWith(
source,
expect.anything(),
expectAnythingOrNothing(),
expectAnythingOrNothing(),
);
}
}),
);
Expand Down Expand Up @@ -358,7 +368,12 @@ describe('process', () => {
assert(result.isOk(), result.data as string);

for (const source of Object.values(originalSources)) {
expect(spy).toBeCalledWith(source, expect.anything(), expectAnythingOrNothing());
expect(spy).toBeCalledWith(
source,
expect.anything(),
expectAnythingOrNothing(),
expectAnythingOrNothing(),
);
}
}),
);
Expand Down Expand Up @@ -439,7 +454,12 @@ describe('process', () => {
assert(result.isOk(), result.data as string);

for (const source of Object.values(originalSources)) {
expect(spy).toBeCalledWith(source, expect.anything(), expectAnythingOrNothing());
expect(spy).toBeCalledWith(
source,
expect.anything(),
expectAnythingOrNothing(),
expectAnythingOrNothing(),
);
}
}),
);
Expand Down Expand Up @@ -520,7 +540,12 @@ describe('process', () => {
assert(result.isOk(), result.data as string);

for (const source of Object.values(originalSources)) {
expect(spy).toBeCalledWith(source, expect.anything(), expectAnythingOrNothing());
expect(spy).toBeCalledWith(
source,
expect.anything(),
expectAnythingOrNothing(),
expectAnythingOrNothing(),
);
}
}),
);
Expand Down Expand Up @@ -601,7 +626,12 @@ describe('process', () => {
assert(result.isOk(), result.data as string);

for (const source of Object.values(originalSources)) {
expect(spy).toBeCalledWith(source, expect.anything(), expectAnythingOrNothing());
expect(spy).toBeCalledWith(
source,
expect.anything(),
expectAnythingOrNothing(),
expectAnythingOrNothing(),
);
}
}),
);
Expand Down Expand Up @@ -688,7 +718,12 @@ describe('process', () => {
assert(result.isOk(), result.data as string);

for (const source of Object.values(originalSources)) {
expect(spy).toBeCalledWith(source, expect.anything(), expectAnythingOrNothing());
expect(spy).toBeCalledWith(
source,
expect.anything(),
expectAnythingOrNothing(),
expectAnythingOrNothing(),
);
}
}),
);
Expand Down
19 changes: 17 additions & 2 deletions tools/sourcemap-tools/src/DebugIdGenerator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ export const SOURCE_DEBUG_ID_VARIABLE = '_btDebugIds';
export const SOURCE_DEBUG_ID_COMMENT = 'debugId';
export const SOURCEMAP_DEBUG_ID_KEY = 'debugId';

/**
* Matches leading and trailing semicolons, e.g. in `;;foo;bar;;`
*/
const MATCH_SEMICOLONS_REGEX = /^;+|;+$/;

export class DebugIdGenerator {
public generateSourceSnippet(uuid: string) {
return `;!function(){try{var k="${SOURCE_DEBUG_ID_VARIABLE}",u="undefined",v="${uuid}",a=function(x){try{x[k]=x[k]||{};x[k][n]=v}catch{}},n=(new Error).stack;n&&(u!=typeof window?a(window):u);n&&(u!=typeof global?a(global):u);n&&(u!=typeof self?a(self):u);n&&(u!=typeof globalThis?a(globalThis):u)}catch{}}();`;
Expand All @@ -15,7 +20,7 @@ export class DebugIdGenerator {
const replaceAll = () => source.replace(oldDebugId, newDebugId);

// Try to replace more safely first
const oldSourceSnippet = this.generateSourceSnippet(oldDebugId);
const oldSourceSnippet = this.generateSourceSnippet(oldDebugId).replace(MATCH_SEMICOLONS_REGEX, '');
if (source.indexOf(oldSourceSnippet) !== -1) {
source = source.replace(oldSourceSnippet, this.generateSourceSnippet(newDebugId));
} else {
Expand All @@ -32,7 +37,17 @@ export class DebugIdGenerator {
return source;
}

public getSourceDebugId(source: string): string | undefined {
public hasCodeSnippet(source: string, debugId: string) {
const sourceSnippet = this.generateSourceSnippet(debugId).replace(MATCH_SEMICOLONS_REGEX, '');
return source.includes(sourceSnippet);
}

public hasCommentSnippet(source: string, debugId: string) {
const commentSnippet = this.generateSourceComment(debugId);
return source.includes(commentSnippet);
}

public getSourceDebugIdFromComment(source: string): string | undefined {
const regex = new RegExp(`^//# ${SOURCE_DEBUG_ID_COMMENT}=(.+)$`, 'm');
const match = source.match(regex);
if (!match) {
Expand Down
Loading