@parcel/utils 2.0.0-beta.2 → 2.0.0-nightly.1004

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.
Files changed (74) hide show
  1. package/lib/index.js +35741 -542
  2. package/lib/index.js.map +1 -0
  3. package/package.json +36 -16
  4. package/src/DefaultMap.js +1 -1
  5. package/src/alternatives.js +26 -7
  6. package/src/ansi-html.js +1 -1
  7. package/src/blob.js +1 -0
  8. package/src/collection.js +14 -2
  9. package/src/config.js +59 -9
  10. package/src/countLines.js +5 -2
  11. package/src/debounce.js +1 -1
  12. package/src/dependency-location.js +5 -5
  13. package/src/generateBuildMetrics.js +4 -4
  14. package/src/getExisting.js +1 -4
  15. package/src/glob.js +14 -3
  16. package/src/hash.js +34 -0
  17. package/src/index.js +10 -10
  18. package/src/path.js +11 -1
  19. package/src/prettyDiagnostic.js +40 -25
  20. package/src/relativeBundlePath.js +3 -5
  21. package/src/replaceBundleReferences.js +42 -24
  22. package/src/schema.js +22 -19
  23. package/src/shared-buffer.js +24 -0
  24. package/src/sourcemap.js +60 -5
  25. package/src/urlJoin.js +3 -1
  26. package/test/DefaultMap.test.js +7 -4
  27. package/test/config.test.js +50 -0
  28. package/test/input/config/config.json +3 -0
  29. package/test/input/config/empty.json +0 -0
  30. package/test/input/config/empty.toml +0 -0
  31. package/test/replaceBundleReferences.test.js +96 -4
  32. package/test/sourcemap.test.js +3 -3
  33. package/test/throttle.test.js +1 -1
  34. package/test/urlJoin.test.js +11 -0
  35. package/lib/DefaultMap.js +0 -64
  36. package/lib/Deferred.js +0 -34
  37. package/lib/PromiseQueue.js +0 -144
  38. package/lib/TapStream.js +0 -46
  39. package/lib/alternatives.js +0 -151
  40. package/lib/ansi-html.js +0 -32
  41. package/lib/blob.js +0 -47
  42. package/lib/bundle-url.js +0 -43
  43. package/lib/collection.js +0 -51
  44. package/lib/config.js +0 -146
  45. package/lib/countLines.js +0 -18
  46. package/lib/debounce.js +0 -20
  47. package/lib/dependency-location.js +0 -21
  48. package/lib/escape-html.js +0 -24
  49. package/lib/generateBuildMetrics.js +0 -156
  50. package/lib/generateCertificate.js +0 -149
  51. package/lib/getCertificate.js +0 -19
  52. package/lib/getExisting.js +0 -31
  53. package/lib/getRootDir.js +0 -74
  54. package/lib/glob.js +0 -118
  55. package/lib/http-server.js +0 -110
  56. package/lib/is-url.js +0 -27
  57. package/lib/isDirectoryInside.js +0 -24
  58. package/lib/md5.js +0 -61
  59. package/lib/objectHash.js +0 -34
  60. package/lib/openInBrowser.js +0 -94
  61. package/lib/parseCSSImport.js +0 -16
  62. package/lib/path.js +0 -44
  63. package/lib/prettifyTime.js +0 -10
  64. package/lib/prettyDiagnostic.js +0 -115
  65. package/lib/relativeBundlePath.js +0 -34
  66. package/lib/relativeUrl.js +0 -32
  67. package/lib/replaceBundleReferences.js +0 -184
  68. package/lib/schema.js +0 -391
  69. package/lib/sourcemap.js +0 -94
  70. package/lib/stream.js +0 -86
  71. package/lib/throttle.js +0 -16
  72. package/lib/urlJoin.js +0 -43
  73. package/src/.babelrc +0 -3
  74. package/src/md5.js +0 -56
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parcel/utils",
3
- "version": "2.0.0-beta.2",
3
+ "version": "2.0.0-nightly.1004+47379bf8",
4
4
  "description": "Blazing fast, zero configuration web application bundler",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -19,30 +19,50 @@
19
19
  "engines": {
20
20
  "node": ">= 12.0.0"
21
21
  },
22
+ "targets": {
23
+ "main": {
24
+ "includeNodeModules": {
25
+ "@parcel/codeframe": false,
26
+ "@parcel/diagnostic": false,
27
+ "@parcel/hash": false,
28
+ "@parcel/logger": false,
29
+ "@parcel/markdown-ansi": false,
30
+ "@parcel/source-map": false,
31
+ "chalk": false
32
+ }
33
+ }
34
+ },
22
35
  "dependencies": {
36
+ "@parcel/codeframe": "2.0.0-nightly.1004+47379bf8",
37
+ "@parcel/diagnostic": "2.0.0-nightly.1004+47379bf8",
38
+ "@parcel/hash": "2.3.3-nightly.2627+47379bf8",
39
+ "@parcel/logger": "2.0.0-nightly.1004+47379bf8",
40
+ "@parcel/markdown-ansi": "2.0.0-nightly.1004+47379bf8",
41
+ "@parcel/source-map": "^2.0.0",
42
+ "chalk": "^4.1.0"
43
+ },
44
+ "devDependencies": {
45
+ "@babel/plugin-transform-flow-strip-types": "^7.2.0",
23
46
  "@iarna/toml": "^2.2.0",
24
- "@parcel/codeframe": "2.0.0-beta.2",
25
- "@parcel/diagnostic": "2.0.0-beta.2",
26
- "@parcel/logger": "2.0.0-beta.2",
27
- "@parcel/markdown-ansi": "2.0.0-beta.2",
28
- "@parcel/source-map": "2.0.0-alpha.4.21",
29
- "ansi-html": "^0.0.7",
30
- "chalk": "^4.1.0",
47
+ "ansi-html-community": "0.0.8",
31
48
  "clone": "^2.1.1",
32
49
  "fast-glob": "3.1.1",
33
50
  "fastest-levenshtein": "^1.0.8",
34
51
  "is-glob": "^4.0.0",
35
52
  "is-url": "^1.2.2",
36
- "json5": "^1.0.1",
53
+ "json5": "^2.2.0",
37
54
  "lru-cache": "^6.0.0",
38
- "micromatch": "^4.0.2",
39
- "node-forge": "^0.10.0",
55
+ "micromatch": "^4.0.4",
56
+ "node-forge": "^1.2.1",
40
57
  "nullthrows": "^1.1.1",
41
- "open": "^7.0.3"
58
+ "open": "^7.0.3",
59
+ "random-int": "^1.0.0",
60
+ "terminal-link": "^2.1.1"
42
61
  },
43
- "devDependencies": {
44
- "@babel/plugin-transform-flow-strip-types": "^7.2.0",
45
- "random-int": "^1.0.0"
62
+ "browser": {
63
+ "./src/generateCertificate.js": false,
64
+ "./src/http-server.js": false,
65
+ "./src/openInBrowser.js": false
46
66
  },
47
- "gitHead": "a3aa86815e098c90fda72a08d29646ff059ab74d"
67
+ "gitHead": "47379bf8fabeb2cfe03ade8802d942388b153e5b"
48
68
  }
package/src/DefaultMap.js CHANGED
@@ -24,7 +24,7 @@ export class DefaultMap<K, V> extends Map<K, V> {
24
24
 
25
25
  // Duplicated from DefaultMap implementation for Flow
26
26
  // Roughly mirrors https://github.com/facebook/flow/blob/2eb5a78d92c167117ba9caae070afd2b9f598599/lib/core.js#L617
27
- export class DefaultWeakMap<K: {...}, V> extends WeakMap<K, V> {
27
+ export class DefaultWeakMap<K: interface {}, V> extends WeakMap<K, V> {
28
28
  _getDefault: K => V;
29
29
 
30
30
  constructor(getDefault: K => V, entries?: Iterable<[K, V]>) {
@@ -62,6 +62,8 @@ async function findAllFilesUp({
62
62
  basedir,
63
63
  maxlength,
64
64
  collected,
65
+ leadingDotSlash = true,
66
+ includeDirectories = true,
65
67
  }: {|
66
68
  fs: FileSystem,
67
69
  dir: string,
@@ -69,16 +71,18 @@ async function findAllFilesUp({
69
71
  basedir: string,
70
72
  maxlength: number,
71
73
  collected: Array<string>,
74
+ leadingDotSlash?: boolean,
75
+ includeDirectories?: boolean,
72
76
  |}): Promise<mixed> {
73
77
  let dirContent = (await fs.readdir(dir)).sort();
74
78
  return Promise.all(
75
79
  dirContent.map(async item => {
76
80
  let fullPath = path.join(dir, item);
77
- let relativeFilePath = relativePath(basedir, fullPath);
81
+ let relativeFilePath = relativePath(basedir, fullPath, leadingDotSlash);
78
82
  if (relativeFilePath.length < maxlength) {
79
83
  let stats = await fs.stat(fullPath);
80
84
  let isDir = stats.isDirectory();
81
- if (isDir || stats.isFile()) {
85
+ if ((isDir && includeDirectories) || stats.isFile()) {
82
86
  collected.push(relativeFilePath);
83
87
  }
84
88
 
@@ -102,15 +106,21 @@ export async function findAlternativeFiles(
102
106
  fs: FileSystem,
103
107
  fileSpecifier: string,
104
108
  dir: string,
109
+ projectRoot: string,
110
+ leadingDotSlash?: boolean = true,
111
+ includeDirectories?: boolean = true,
112
+ includeExtension?: boolean = false,
105
113
  ): Promise<Array<string>> {
106
114
  let potentialFiles: Array<string> = [];
107
115
  // Find our root, we won't recommend files above the package root as that's bad practise
108
- let pkg = await resolveConfig(fs, path.join(dir, 'index'), ['package.json']);
109
- if (!pkg) {
110
- return potentialFiles;
111
- }
116
+ let pkg = await resolveConfig(
117
+ fs,
118
+ path.join(dir, 'index'),
119
+ ['package.json'],
120
+ projectRoot,
121
+ );
112
122
 
113
- let pkgRoot = path.dirname(pkg);
123
+ let pkgRoot = pkg ? path.dirname(pkg) : projectRoot;
114
124
  await findAllFilesUp({
115
125
  fs,
116
126
  dir: pkgRoot,
@@ -118,7 +128,16 @@ export async function findAlternativeFiles(
118
128
  basedir: dir,
119
129
  maxlength: fileSpecifier.length + 10,
120
130
  collected: potentialFiles,
131
+ leadingDotSlash,
132
+ includeDirectories,
121
133
  });
122
134
 
135
+ if (path.extname(fileSpecifier) === '' && !includeExtension) {
136
+ potentialFiles = potentialFiles.map(p => {
137
+ let ext = path.extname(p);
138
+ return ext.length > 0 ? p.slice(0, -ext.length) : p;
139
+ });
140
+ }
141
+
123
142
  return fuzzySearch(potentialFiles, fileSpecifier).slice(0, 2);
124
143
  }
package/src/ansi-html.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // @flow strict-local
2
- import ansiHTML from 'ansi-html';
2
+ import ansiHTML from 'ansi-html-community';
3
3
  import {escapeHTML} from './escape-html';
4
4
 
5
5
  export function ansiHtml(ansi: string): string {
package/src/blob.js CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  import type {Blob} from '@parcel/types';
4
4
 
5
+ import {Buffer} from 'buffer';
5
6
  import {bufferStream} from './';
6
7
  import {Readable} from 'stream';
7
8
 
package/src/collection.js CHANGED
@@ -6,14 +6,14 @@ export function unique<T>(array: Array<T>): Array<T> {
6
6
 
7
7
  export function objectSortedEntries(obj: {
8
8
  +[string]: mixed,
9
- ...,
9
+ ...
10
10
  }): Array<[string, mixed]> {
11
11
  return Object.entries(obj).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
12
12
  }
13
13
 
14
14
  export function objectSortedEntriesDeep(object: {
15
15
  +[string]: mixed,
16
- ...,
16
+ ...
17
17
  }): Array<[string, mixed]> {
18
18
  let sortedEntries = objectSortedEntries(object);
19
19
  for (let i = 0; i < sortedEntries.length; i++) {
@@ -43,3 +43,15 @@ export function setDifference<T>(a: Set<T>, b: Set<T>): Set<T> {
43
43
  }
44
44
  return difference;
45
45
  }
46
+
47
+ export function setIntersect<T>(a: Set<T>, b: Set<T>): void {
48
+ for (let entry of a) {
49
+ if (!b.has(entry)) {
50
+ a.delete(entry);
51
+ }
52
+ }
53
+ }
54
+
55
+ export function setUnion<T>(a: Iterable<T>, b: Iterable<T>): Set<T> {
56
+ return new Set([...a, ...b]);
57
+ }
package/src/config.js CHANGED
@@ -2,9 +2,10 @@
2
2
 
3
3
  import type {ConfigResult, File, FilePath} from '@parcel/types';
4
4
  import type {FileSystem} from '@parcel/fs';
5
+ import ThrowableDiagnostic from '@parcel/diagnostic';
5
6
  import path from 'path';
6
7
  import clone from 'clone';
7
- import {parse as json5} from 'json5';
8
+ import json5 from 'json5';
8
9
  import {parse as toml} from '@iarna/toml';
9
10
  import LRU from 'lru-cache';
10
11
 
@@ -15,36 +16,53 @@ export type ConfigOutput = {|
15
16
 
16
17
  export type ConfigOptions = {|
17
18
  parse?: boolean,
19
+ parser?: string => any,
18
20
  |};
19
21
 
20
22
  const configCache = new LRU<FilePath, ConfigOutput>({max: 500});
23
+ const resolveCache = new Map();
21
24
 
22
25
  export function resolveConfig(
23
26
  fs: FileSystem,
24
27
  filepath: FilePath,
25
28
  filenames: Array<FilePath>,
29
+ projectRoot: FilePath,
26
30
  ): Promise<?FilePath> {
27
- return Promise.resolve(
28
- fs.findAncestorFile(filenames, path.dirname(filepath)),
31
+ // Cache the result of resolving config for this directory.
32
+ // This is automatically invalidated at the end of the current build.
33
+ let key = path.dirname(filepath) + filenames.join(',');
34
+ let cached = resolveCache.get(key);
35
+ if (cached !== undefined) {
36
+ return Promise.resolve(cached);
37
+ }
38
+
39
+ let resolved = fs.findAncestorFile(
40
+ filenames,
41
+ path.dirname(filepath),
42
+ projectRoot,
29
43
  );
44
+ resolveCache.set(key, resolved);
45
+ return Promise.resolve(resolved);
30
46
  }
31
47
 
32
48
  export function resolveConfigSync(
33
49
  fs: FileSystem,
34
50
  filepath: FilePath,
35
51
  filenames: Array<FilePath>,
52
+ projectRoot: FilePath,
36
53
  ): ?FilePath {
37
- return fs.findAncestorFile(filenames, path.dirname(filepath));
54
+ return fs.findAncestorFile(filenames, path.dirname(filepath), projectRoot);
38
55
  }
39
56
 
40
57
  export async function loadConfig(
41
58
  fs: FileSystem,
42
59
  filepath: FilePath,
43
60
  filenames: Array<FilePath>,
61
+ projectRoot: FilePath,
44
62
  opts: ?ConfigOptions,
45
63
  ): Promise<ConfigOutput | null> {
46
64
  let parse = opts?.parse ?? true;
47
- let configFile = await resolveConfig(fs, filepath, filenames);
65
+ let configFile = await resolveConfig(fs, filepath, filenames, projectRoot);
48
66
  if (configFile) {
49
67
  let cachedOutput = configCache.get(String(parse) + configFile);
50
68
  if (cachedOutput) {
@@ -65,14 +83,45 @@ export async function loadConfig(
65
83
  }
66
84
 
67
85
  let configContent = await fs.readFile(configFile, 'utf8');
68
- if (!configContent) return null;
69
86
 
70
87
  let config;
71
88
  if (parse === false) {
72
89
  config = configContent;
73
90
  } else {
74
- let parse = getParser(extname);
75
- config = parse(configContent);
91
+ let parse = opts?.parser ?? getParser(extname);
92
+ try {
93
+ config = parse(configContent);
94
+ } catch (e) {
95
+ if (extname !== '' && extname !== 'json') {
96
+ throw e;
97
+ }
98
+
99
+ let pos = {
100
+ line: e.lineNumber,
101
+ column: e.columnNumber,
102
+ };
103
+
104
+ throw new ThrowableDiagnostic({
105
+ diagnostic: {
106
+ message: `Failed to parse ${path.basename(configFile)}`,
107
+ origin: '@parcel/utils',
108
+ codeFrames: [
109
+ {
110
+ language: 'json5',
111
+ filePath: configFile,
112
+ code: configContent,
113
+ codeHighlights: [
114
+ {
115
+ start: pos,
116
+ end: pos,
117
+ message: e.message,
118
+ },
119
+ ],
120
+ },
121
+ ],
122
+ },
123
+ });
124
+ }
76
125
  }
77
126
 
78
127
  let output = {
@@ -96,6 +145,7 @@ export async function loadConfig(
96
145
 
97
146
  loadConfig.clear = () => {
98
147
  configCache.reset();
148
+ resolveCache.clear();
99
149
  };
100
150
 
101
151
  function getParser(extname) {
@@ -104,6 +154,6 @@ function getParser(extname) {
104
154
  return toml;
105
155
  case 'json':
106
156
  default:
107
- return json5;
157
+ return json5.parse;
108
158
  }
109
159
  }
package/src/countLines.js CHANGED
@@ -1,8 +1,11 @@
1
1
  // @flow strict-local
2
2
 
3
- export default function countLines(string: string): number {
3
+ export default function countLines(
4
+ string: string,
5
+ startIndex: number = 0,
6
+ ): number {
4
7
  let lines = 1;
5
- for (let i = 0; i < string.length; i++) {
8
+ for (let i = startIndex; i < string.length; i++) {
6
9
  if (string.charAt(i) === '\n') {
7
10
  lines++;
8
11
  }
package/src/debounce.js CHANGED
@@ -6,7 +6,7 @@ export default function debounce<TArgs: Array<mixed>>(
6
6
  ): (...args: TArgs) => void {
7
7
  let timeout;
8
8
 
9
- return function(...args: TArgs) {
9
+ return function (...args: TArgs) {
10
10
  if (timeout) {
11
11
  clearTimeout(timeout);
12
12
  }
@@ -1,11 +1,11 @@
1
1
  // @flow
2
+
2
3
  export default function createDependencyLocation(
3
- start: {
4
+ start: interface {
4
5
  line: number,
5
6
  column: number,
6
- ...
7
7
  },
8
- moduleSpecifier: string,
8
+ specifier: string,
9
9
  lineOffset: number = 0,
10
10
  columnOffset: number = 0,
11
11
  // Imports are usually wrapped in quotes
@@ -16,7 +16,7 @@ export default function createDependencyLocation(
16
16
  start: {|column: number, line: number|},
17
17
  |} {
18
18
  return {
19
- filePath: moduleSpecifier,
19
+ filePath: specifier,
20
20
  start: {
21
21
  line: start.line + lineOffset,
22
22
  column: start.column + columnOffset,
@@ -25,7 +25,7 @@ export default function createDependencyLocation(
25
25
  line: start.line + lineOffset,
26
26
  column:
27
27
  start.column +
28
- moduleSpecifier.length -
28
+ specifier.length -
29
29
  1 +
30
30
  importWrapperLength +
31
31
  columnOffset,
@@ -1,6 +1,6 @@
1
1
  // @flow
2
2
 
3
- import type {FilePath, NamedBundle} from '@parcel/types';
3
+ import type {FilePath, PackagedBundle} from '@parcel/types';
4
4
  import type {FileSystem} from '@parcel/fs';
5
5
  import SourceMap from '@parcel/source-map';
6
6
  import nullthrows from 'nullthrows';
@@ -38,7 +38,7 @@ async function getSourcemapSizes(
38
38
 
39
39
  let rawMap = mapUrlData.map;
40
40
  let sourceMap = new SourceMap(projectRoot);
41
- sourceMap.addRawMappings(rawMap);
41
+ sourceMap.addVLQMap(rawMap);
42
42
  let parsedMapData = sourceMap.getMap();
43
43
 
44
44
  if (parsedMapData.mappings.length > 2) {
@@ -97,7 +97,7 @@ async function getSourcemapSizes(
97
97
  }
98
98
 
99
99
  async function createBundleStats(
100
- bundle: NamedBundle,
100
+ bundle: PackagedBundle,
101
101
  fs: FileSystem,
102
102
  projectRoot: FilePath,
103
103
  ) {
@@ -144,7 +144,7 @@ async function createBundleStats(
144
144
  }
145
145
 
146
146
  export default async function generateBuildMetrics(
147
- bundles: Array<NamedBundle>,
147
+ bundles: Array<PackagedBundle>,
148
148
  fs: FileSystem,
149
149
  projectRoot: FilePath,
150
150
  ): Promise<BuildMetrics> {
@@ -14,10 +14,7 @@ export default function getExisting(
14
14
  return {
15
15
  source,
16
16
  minified: fs.existsSync(minifiedPath)
17
- ? fs
18
- .readFileSync(minifiedPath, 'utf8')
19
- .trim()
20
- .replace(/;$/, '')
17
+ ? fs.readFileSync(minifiedPath, 'utf8').trim().replace(/;$/, '')
21
18
  : source,
22
19
  };
23
20
  }
package/src/glob.js CHANGED
@@ -5,15 +5,26 @@ import type {FileSystem} from '@parcel/fs';
5
5
 
6
6
  import _isGlob from 'is-glob';
7
7
  import fastGlob, {type FastGlobOptions} from 'fast-glob';
8
- import {isMatch} from 'micromatch';
8
+ import {isMatch, makeRe, type Options} from 'micromatch';
9
9
  import {normalizeSeparators} from './path';
10
10
 
11
11
  export function isGlob(p: FilePath): any {
12
12
  return _isGlob(normalizeSeparators(p));
13
13
  }
14
14
 
15
- export function isGlobMatch(filePath: FilePath, glob: Glob): any {
16
- return isMatch(filePath, normalizeSeparators(glob));
15
+ export function isGlobMatch(
16
+ filePath: FilePath,
17
+ glob: Glob | Array<Glob>,
18
+ opts?: Options,
19
+ ): any {
20
+ glob = Array.isArray(glob)
21
+ ? glob.map(normalizeSeparators)
22
+ : normalizeSeparators(glob);
23
+ return isMatch(filePath, glob, opts);
24
+ }
25
+
26
+ export function globToRegex(glob: Glob, opts?: Options): RegExp {
27
+ return makeRe(glob, opts);
17
28
  }
18
29
 
19
30
  export function globSync(
package/src/hash.js ADDED
@@ -0,0 +1,34 @@
1
+ // @flow strict-local
2
+
3
+ import type {Readable} from 'stream';
4
+ import type {FileSystem} from '@parcel/fs';
5
+
6
+ import {objectSortedEntriesDeep} from './collection';
7
+ import {hashString, Hash} from '@parcel/hash';
8
+
9
+ export function hashStream(stream: Readable): Promise<string> {
10
+ let hash = new Hash();
11
+ return new Promise((resolve, reject) => {
12
+ stream.on('error', err => {
13
+ reject(err);
14
+ });
15
+ stream
16
+ .on('data', chunk => {
17
+ hash.writeBuffer(chunk);
18
+ })
19
+ .on('end', function () {
20
+ resolve(hash.finish());
21
+ })
22
+ .on('error', err => {
23
+ reject(err);
24
+ });
25
+ });
26
+ }
27
+
28
+ export function hashObject(obj: {+[string]: mixed, ...}): string {
29
+ return hashString(JSON.stringify(objectSortedEntriesDeep(obj)));
30
+ }
31
+
32
+ export function hashFile(fs: FileSystem, filePath: string): Promise<string> {
33
+ return hashStream(fs.createReadStream(filePath));
34
+ }
package/src/index.js CHANGED
@@ -1,9 +1,11 @@
1
1
  // @flow strict-local
2
2
  export type * from './config';
3
+ export type * from './Deferred';
3
4
  export type * from './generateBuildMetrics';
5
+ export type * from './http-server';
6
+ export type * from './path';
4
7
  export type * from './prettyDiagnostic';
5
8
  export type * from './schema';
6
- export type * from './http-server';
7
9
 
8
10
  export {default as countLines} from './countLines';
9
11
  export {default as generateBuildMetrics} from './generateBuildMetrics';
@@ -33,21 +35,18 @@ export {
33
35
  objectSortedEntries,
34
36
  objectSortedEntriesDeep,
35
37
  setDifference,
38
+ setIntersect,
39
+ setUnion,
36
40
  } from './collection';
37
41
  export {resolveConfig, resolveConfigSync, loadConfig} from './config';
38
42
  export {DefaultMap, DefaultWeakMap} from './DefaultMap';
39
43
  export {makeDeferredWithPromise} from './Deferred';
40
- export {isGlob, isGlobMatch, globSync, glob} from './glob';
41
- export {
42
- md5FromString,
43
- md5FromReadableStream,
44
- md5FromObject,
45
- md5FromOrderedObject,
46
- md5FromFilePath,
47
- } from './md5';
44
+ export {isGlob, isGlobMatch, globSync, glob, globToRegex} from './glob';
45
+ export {hashStream, hashObject, hashFile} from './hash';
46
+ export {SharedBuffer} from './shared-buffer';
48
47
  export {fuzzySearch} from './schema';
49
48
  export {createHTTPServer} from './http-server';
50
- export {normalizeSeparators, normalizePath, relativePath} from './path';
49
+ export {normalizePath, normalizeSeparators, relativePath} from './path';
51
50
  export {
52
51
  replaceURLReferences,
53
52
  replaceInlineReferences,
@@ -69,4 +68,5 @@ export {
69
68
  matchSourceMappingURL,
70
69
  loadSourceMapUrl,
71
70
  loadSourceMap,
71
+ remapSourceLocation,
72
72
  } from './sourcemap';
package/src/path.js CHANGED
@@ -22,7 +22,12 @@ export function normalizePath(
22
22
  filePath: FilePath,
23
23
  leadingDotSlash: boolean = true,
24
24
  ): FilePath {
25
- if (leadingDotSlash && filePath[0] !== '.' && filePath[0] !== '/') {
25
+ if (
26
+ leadingDotSlash &&
27
+ (filePath[0] !== '.' ||
28
+ (filePath[1] !== '.' && filePath[1] !== '/' && filePath[1] !== '\\')) &&
29
+ !path.isAbsolute(filePath)
30
+ ) {
26
31
  return normalizeSeparators('./' + filePath);
27
32
  } else {
28
33
  return normalizeSeparators(filePath);
@@ -34,5 +39,10 @@ export function relativePath(
34
39
  to: string,
35
40
  leadingDotSlash: boolean = true,
36
41
  ): FilePath {
42
+ // Fast path
43
+ if (to.startsWith(from + '/')) {
44
+ return (leadingDotSlash ? './' : '') + to.slice(from.length + 1);
45
+ }
46
+
37
47
  return normalizePath(path.relative(from, to), leadingDotSlash);
38
48
  }