Skip to content
This repository was archived by the owner on Jun 24, 2024. It is now read-only.

Commit 58958a5

Browse files
committed
fix: refactor to fix dep map overwrite problem
An issue potentially existed where if multiple versions of the same dependency existed with different file paths then when they were inserted into the dependency map the last entry would win. This change makes it so that individual feed items are handled in isolation therefore avoiding a shared map which risks overwrite.
1 parent 04bd73e commit 58958a5

14 files changed

+221
-158
lines changed

lib/calculate-relative-path.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
'use strict';
2+
3+
const { join, relative, dirname, basename } = require('path');
4+
5+
module.exports = function calculateRelativePath(feedItemPath, dependencyPath) {
6+
const path = dirname(dependencyPath);
7+
const filename = basename(dependencyPath);
8+
const relativePath = relative(dirname(feedItemPath), path);
9+
return `./${join(relativePath, filename)}`;
10+
};

lib/map-dep-names-to-paths.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
'use strict';
2+
3+
const calculateRelativePath = require('./calculate-relative-path');
4+
5+
module.exports = function mapDepNamesToPaths(hashToFileMap, feedItem) {
6+
const { deps } = feedItem;
7+
const depToFileMap = new Map();
8+
for (const dependency of Object.keys(deps)) {
9+
if (['.', '/'].includes(dependency[0])) continue;
10+
const dependencyId = deps[dependency];
11+
const dependencyPath = hashToFileMap.get(dependencyId);
12+
const relativePath = calculateRelativePath(
13+
feedItem.file,
14+
dependencyPath
15+
);
16+
depToFileMap.set(dependency, relativePath);
17+
}
18+
return depToFileMap;
19+
};

lib/map-feed-dependencies.js

Lines changed: 0 additions & 31 deletions
This file was deleted.

lib/map-hash-to-path.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
'use strict';
2+
3+
module.exports = function mapHashToPath(feed) {
4+
const hashToFileMap = new Map();
5+
for (const item of feed) {
6+
hashToFileMap.set(item.id, item.file);
7+
}
8+
return hashToFileMap;
9+
};

lib/replace-dependencies.js

Lines changed: 0 additions & 37 deletions
This file was deleted.

lib/replace-require-statements.js

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
'use strict';
2+
3+
module.exports = function replaceRequireStatements(sourceCode, dependencyMap) {
4+
for (const dependency of dependencyMap.keys()) {
5+
// if relative or absolute path already then skip.
6+
if (['.', '/'].includes(dependency[0])) continue;
7+
8+
sourceCode = sourceCode.replace(
9+
new RegExp(`require\\s*\\(\\s*['"]${dependency}['"]\\s*\\)`, 'g'),
10+
`require('${dependencyMap.get(dependency)}')`
11+
);
12+
}
13+
return sourceCode;
14+
};

lib/unpack-feed.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22

33
const { join } = require('path');
44
const { outputFile } = require('fs-extra');
5-
const replaceDependencies = require('./replace-dependencies');
6-
const mapFeedDependencies = require('./map-feed-dependencies');
5+
const mapHashToPath = require('./map-hash-to-path');
6+
const mapDepNamesToPaths = require('./map-dep-names-to-paths');
7+
const replaceRequireStatements = require('./replace-require-statements');
78

89
/**
910
* Unpacks a given feed's source code. Recreates the directory structure
@@ -14,9 +15,11 @@ const mapFeedDependencies = require('./map-feed-dependencies');
1415
* @param {object[]} feed - browserify bundle feed
1516
*/
1617
module.exports = async function unpackFeed(root, feed) {
17-
const feedDependencies = mapFeedDependencies(feed);
18+
const hashToFile = mapHashToPath(feed);
19+
1820
for (const item of feed) {
19-
const content = replaceDependencies(feedDependencies, item);
21+
const depToFileMap = mapDepNamesToPaths(hashToFile, item);
22+
const content = replaceRequireStatements(item.source, depToFileMap);
2023
await outputFile(join(root, item.file), content);
2124
}
2225
};
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// Jest Snapshot v1, https://goo.gl/fbAQLP
2+
3+
exports[`returns map of feed ids -> feed file paths 1`] = `
4+
Array [
5+
Array [
6+
"3c4ca5444d554f82cb15c2437ed545b2ea6f6a6e98476ec372b21b6cf7d8085a",
7+
"/Users/ricwalke/src/asset-pipe/asset-pipe-js-reader/test/mock/podletA/entrypoint.js",
8+
],
9+
Array [
10+
"94def8251ca7023be6c5aeda886a4055d4d47fd62238228def5888398bbdf318",
11+
"/Users/ricwalke/src/asset-pipe/asset-pipe-js-reader/test/mock/podletA/lib/index.js",
12+
],
13+
]
14+
`;

test/calculate-relative-path.test.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
'use strict';
2+
3+
const calculateRelativePath = require('../lib/calculate-relative-path');
4+
5+
test('divergent paths', () => {
6+
const feedItemPath = '/common/path/another-dep/index.js';
7+
const dependencyPath = '/common/path/my-dep/index.js';
8+
9+
const result = calculateRelativePath(feedItemPath, dependencyPath);
10+
expect(result).toBe('./../my-dep/index.js');
11+
});
12+
13+
test('nested dependency path', () => {
14+
const feedItemPath = '/common/index.js';
15+
const dependencyPath = '/common/dep/path/index.js';
16+
17+
const result = calculateRelativePath(feedItemPath, dependencyPath);
18+
expect(result).toBe('./dep/path/index.js');
19+
});
20+
21+
test('nested path -> parent path', () => {
22+
const feedItemPath = '/common/dep/path/my-dep/index.js';
23+
const dependencyPath = '/common/index.js';
24+
25+
const result = calculateRelativePath(feedItemPath, dependencyPath);
26+
expect(result).toBe('./../../../index.js');
27+
});

test/map-dep-names-to-paths.test.js

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
'use strict';
2+
3+
const mapDepNamesToPaths = require('../lib/map-dep-names-to-paths');
4+
5+
test('dependency map created for feed item with single dep', () => {
6+
const hashToFileMap = new Map([[1, '/common/one/index.js']]);
7+
const item = {
8+
id: 4,
9+
file: '/common/index.js',
10+
source: '',
11+
deps: { one: 1 },
12+
};
13+
14+
const result = mapDepNamesToPaths(hashToFileMap, item);
15+
expect(result.get('one')).toBe('./one/index.js');
16+
expect(Array.from(result)).toHaveLength(1);
17+
});
18+
19+
test('dependency map created for feed item with multiple deps', () => {
20+
const hashToFileMap = new Map([
21+
[1, '/common/one/index.js'],
22+
[2, '/common/two/index.js'],
23+
[3, '/common/three/index.js'],
24+
]);
25+
const item = {
26+
id: 4,
27+
file: '/common/index.js',
28+
source: '',
29+
deps: { one: 1, two: 2, three: 3 },
30+
};
31+
32+
const result = mapDepNamesToPaths(hashToFileMap, item);
33+
expect(result.get('one')).toBe('./one/index.js');
34+
expect(result.get('two')).toBe('./two/index.js');
35+
expect(result.get('three')).toBe('./three/index.js');
36+
expect(Array.from(result)).toHaveLength(3);
37+
});
38+
39+
test('relative path dependencies ignored', () => {
40+
const hashToFileMap = new Map([
41+
[1, '/common/one/index.js'],
42+
[2, '/common/two/index.js'],
43+
[3, '/common/three/index.js'],
44+
]);
45+
const item = {
46+
id: 4,
47+
file: '/common/index.js',
48+
source: '',
49+
deps: { './one': 2 },
50+
};
51+
52+
const result = mapDepNamesToPaths(hashToFileMap, item);
53+
expect(result.has('./one')).toBe(false);
54+
expect(Array.from(result)).toHaveLength(0);
55+
});
56+
57+
test('absolute path dependencies ignored', () => {
58+
const hashToFileMap = new Map([
59+
[1, '/common/one/index.js'],
60+
[2, '/common/two/index.js'],
61+
[3, '/common/three/index.js'],
62+
]);
63+
const item = {
64+
id: 4,
65+
file: '/common/index.js',
66+
source: '',
67+
deps: { '/one': 2 },
68+
};
69+
70+
const result = mapDepNamesToPaths(hashToFileMap, item);
71+
expect(result.has('/one')).toBe(false);
72+
expect(Array.from(result)).toHaveLength(0);
73+
});

0 commit comments

Comments
 (0)