@parcel/utils 2.0.0-nightly.97 → 2.0.0-nightly.970

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 (100) hide show
  1. package/.eslintrc.js +6 -6
  2. package/lib/DefaultMap.js +0 -8
  3. package/lib/Deferred.js +10 -2
  4. package/lib/PromiseQueue.js +21 -30
  5. package/lib/TapStream.js +10 -10
  6. package/lib/alternatives.js +134 -0
  7. package/lib/ansi-html.js +10 -2
  8. package/lib/blob.js +26 -8
  9. package/lib/collection.js +14 -11
  10. package/lib/config.js +145 -35
  11. package/lib/countLines.js +2 -2
  12. package/lib/dependency-location.js +3 -3
  13. package/lib/generateBuildMetrics.js +148 -0
  14. package/lib/generateCertificate.js +33 -8
  15. package/lib/getExisting.js +11 -3
  16. package/lib/getRootDir.js +18 -7
  17. package/lib/glob.js +53 -19
  18. package/lib/hash.js +44 -0
  19. package/lib/http-server.js +48 -10
  20. package/lib/index.js +298 -224
  21. package/lib/is-url.js +12 -2
  22. package/lib/isDirectoryInside.js +24 -0
  23. package/lib/objectHash.js +10 -2
  24. package/lib/openInBrowser.js +94 -0
  25. package/lib/path.js +33 -6
  26. package/lib/prettyDiagnostic.js +107 -25
  27. package/lib/relativeBundlePath.js +13 -7
  28. package/lib/relativeUrl.js +19 -3
  29. package/lib/replaceBundleReferences.js +91 -35
  30. package/lib/schema.js +104 -33
  31. package/lib/shared-buffer.js +31 -0
  32. package/lib/sourcemap.js +147 -0
  33. package/lib/stream.js +38 -3
  34. package/lib/urlJoin.js +25 -6
  35. package/package.json +27 -16
  36. package/src/DefaultMap.js +1 -1
  37. package/src/PromiseQueue.js +16 -12
  38. package/src/alternatives.js +143 -0
  39. package/src/ansi-html.js +2 -2
  40. package/src/blob.js +4 -3
  41. package/src/bundle-url.js +1 -1
  42. package/src/collection.js +14 -14
  43. package/src/config.js +100 -35
  44. package/src/countLines.js +5 -2
  45. package/src/debounce.js +1 -1
  46. package/src/dependency-location.js +11 -6
  47. package/src/generateBuildMetrics.js +158 -0
  48. package/src/generateCertificate.js +1 -1
  49. package/src/getCertificate.js +1 -1
  50. package/src/getExisting.js +1 -4
  51. package/src/getRootDir.js +1 -2
  52. package/src/glob.js +29 -11
  53. package/src/hash.js +34 -0
  54. package/src/http-server.js +10 -12
  55. package/src/index.js +52 -23
  56. package/src/is-url.js +1 -1
  57. package/src/isDirectoryInside.js +11 -0
  58. package/src/openInBrowser.js +64 -0
  59. package/src/path.js +38 -6
  60. package/src/prettyDiagnostic.js +58 -24
  61. package/src/relativeBundlePath.js +8 -13
  62. package/src/replaceBundleReferences.js +75 -39
  63. package/src/schema.js +101 -44
  64. package/src/shared-buffer.js +24 -0
  65. package/src/sourcemap.js +135 -0
  66. package/src/stream.js +31 -1
  67. package/src/urlJoin.js +3 -1
  68. package/test/DefaultMap.test.js +7 -4
  69. package/test/config.test.js +50 -0
  70. package/test/input/config/config.json +3 -0
  71. package/test/input/config/empty.json +0 -0
  72. package/test/input/config/empty.toml +0 -0
  73. package/test/input/sourcemap/referenced-min.js +2 -0
  74. package/test/input/sourcemap/referenced-min.js.map +6 -0
  75. package/test/input/sourcemap/source-root.js +2 -0
  76. package/test/input/sourcemap/source-root.js.map +7 -0
  77. package/test/objectHash.test.js +33 -0
  78. package/test/prettifyTime.test.js +17 -0
  79. package/test/replaceBundleReferences.test.js +268 -0
  80. package/test/sourcemap.test.js +207 -0
  81. package/test/throttle.test.js +1 -2
  82. package/test/urlJoin.test.js +37 -0
  83. package/lib/generateBundleReport.js +0 -38
  84. package/lib/loadSourceMapUrl.js +0 -33
  85. package/lib/md5.js +0 -35
  86. package/lib/prettyError.js +0 -43
  87. package/lib/promisify.js +0 -13
  88. package/lib/resolve.js +0 -93
  89. package/lib/serializeObject.js +0 -28
  90. package/src/.babelrc +0 -3
  91. package/src/generateBundleReport.js +0 -51
  92. package/src/loadSourceMapUrl.js +0 -33
  93. package/src/md5.js +0 -44
  94. package/src/prettyError.js +0 -54
  95. package/src/promisify.js +0 -13
  96. package/src/resolve.js +0 -123
  97. package/src/serializeObject.js +0 -22
  98. package/test/input/sourcemap/referenced.js +0 -7
  99. package/test/loadSourceMapUrl.test.js +0 -37
  100. package/test/prettyError.test.js +0 -104
package/.eslintrc.js CHANGED
@@ -5,16 +5,16 @@ const RESTRICTED_CONFIG = [
5
5
  {
6
6
  name: '@parcel/workers',
7
7
  message:
8
- 'Do not import workers inside utils. Instead, create a separate package.'
9
- }
10
- ]
11
- }
8
+ 'Do not import workers inside utils. Instead, create a separate package.',
9
+ },
10
+ ],
11
+ },
12
12
  ];
13
13
 
14
14
  module.exports = {
15
15
  extends: '@parcel/eslint-config',
16
16
  rules: {
17
17
  'no-restricted-imports': RESTRICTED_CONFIG,
18
- 'no-restricted-modules': RESTRICTED_CONFIG
19
- }
18
+ 'no-restricted-modules': RESTRICTED_CONFIG,
19
+ },
20
20
  };
package/lib/DefaultMap.js CHANGED
@@ -5,14 +5,9 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.DefaultWeakMap = exports.DefaultMap = void 0;
7
7
 
8
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
9
-
10
8
  class DefaultMap extends Map {
11
9
  constructor(getDefault, entries) {
12
10
  super(entries);
13
-
14
- _defineProperty(this, "_getDefault", void 0);
15
-
16
11
  this._getDefault = getDefault;
17
12
  }
18
13
 
@@ -39,9 +34,6 @@ exports.DefaultMap = DefaultMap;
39
34
  class DefaultWeakMap extends WeakMap {
40
35
  constructor(getDefault, entries) {
41
36
  super(entries);
42
-
43
- _defineProperty(this, "_getDefault", void 0);
44
-
45
37
  this._getDefault = getDefault;
46
38
  }
47
39
 
package/lib/Deferred.js CHANGED
@@ -5,7 +5,15 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.makeDeferredWithPromise = makeDeferredWithPromise;
7
7
 
8
- var _assert = _interopRequireDefault(require("assert"));
8
+ function _assert() {
9
+ const data = _interopRequireDefault(require("assert"));
10
+
11
+ _assert = function () {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
9
17
 
10
18
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
11
19
 
@@ -18,7 +26,7 @@ function makeDeferredWithPromise() {
18
26
  };
19
27
  }); // Promise constructor callback executes synchronously, so this is defined
20
28
 
21
- (0, _assert.default)(deferred != null);
29
+ (0, _assert().default)(deferred != null);
22
30
  return {
23
31
  deferred,
24
32
  promise
@@ -7,26 +7,16 @@ exports.default = void 0;
7
7
 
8
8
  var _Deferred = require("./Deferred");
9
9
 
10
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
11
-
12
10
  class PromiseQueue {
11
+ _numRunning = 0;
12
+ _queue = [];
13
+ _runPromise = null;
14
+ _count = 0;
15
+ _results = [];
16
+
13
17
  constructor(opts = {
14
18
  maxConcurrent: Infinity
15
19
  }) {
16
- _defineProperty(this, "_deferred", void 0);
17
-
18
- _defineProperty(this, "_maxConcurrent", void 0);
19
-
20
- _defineProperty(this, "_numRunning", 0);
21
-
22
- _defineProperty(this, "_queue", []);
23
-
24
- _defineProperty(this, "_runPromise", null);
25
-
26
- _defineProperty(this, "_count", 0);
27
-
28
- _defineProperty(this, "_results", []);
29
-
30
20
  if (opts.maxConcurrent <= 0) {
31
21
  throw new TypeError('maxConcurrent must be a positive, non-zero value');
32
22
  }
@@ -87,7 +77,7 @@ class PromiseQueue {
87
77
  if (this._queue.length) {
88
78
  this._next();
89
79
  } else if (this._numRunning === 0) {
90
- this._resolve();
80
+ this._done();
91
81
  }
92
82
  }
93
83
 
@@ -96,10 +86,15 @@ class PromiseQueue {
96
86
 
97
87
  try {
98
88
  await fn();
99
- this._numRunning--;
100
89
  } catch (e) {
101
- this._reject(e); // rejecting resets state so numRunning is reset to 0 here
102
-
90
+ // Only store the first error that occurs.
91
+ // We don't reject immediately so that any other concurrent
92
+ // requests have time to complete.
93
+ if (this._error == null) {
94
+ this._error = e;
95
+ }
96
+ } finally {
97
+ this._numRunning--;
103
98
  }
104
99
  }
105
100
 
@@ -112,17 +107,13 @@ class PromiseQueue {
112
107
  this._deferred = null;
113
108
  }
114
109
 
115
- _reject(err) {
116
- if (this._deferred != null) {
117
- this._deferred.reject(err);
118
- }
119
-
120
- this._resetState();
121
- }
122
-
123
- _resolve() {
110
+ _done() {
124
111
  if (this._deferred != null) {
125
- this._deferred.resolve(this._results);
112
+ if (this._error != null) {
113
+ this._deferred.reject(this._error);
114
+ } else {
115
+ this._deferred.resolve(this._results);
116
+ }
126
117
  }
127
118
 
128
119
  this._resetState();
package/lib/TapStream.js CHANGED
@@ -5,24 +5,24 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = void 0;
7
7
 
8
- var _stream = require("stream");
8
+ function _stream() {
9
+ const data = require("stream");
9
10
 
10
- function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
11
+ _stream = function () {
12
+ return data;
13
+ };
11
14
 
12
- function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
13
-
14
- function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
15
+ return data;
16
+ }
15
17
 
16
18
  /*
17
19
  * "Taps" into the contents of a flowing stream, yielding chunks to the passed
18
20
  * callback. Continues to pass data chunks down the stream.
19
21
  */
20
- class TapStream extends _stream.Transform {
22
+ class TapStream extends _stream().Transform {
21
23
  constructor(tap, options) {
22
- super(_objectSpread({}, options));
23
-
24
- _defineProperty(this, "_tap", void 0);
25
-
24
+ super({ ...options
25
+ });
26
26
  this._tap = tap;
27
27
  }
28
28
 
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.findAlternativeNodeModules = findAlternativeNodeModules;
7
+ exports.findAlternativeFiles = findAlternativeFiles;
8
+
9
+ function _path() {
10
+ const data = _interopRequireDefault(require("path"));
11
+
12
+ _path = function () {
13
+ return data;
14
+ };
15
+
16
+ return data;
17
+ }
18
+
19
+ var _schema = require("./schema");
20
+
21
+ var _path2 = require("./path");
22
+
23
+ var _config = require("./config");
24
+
25
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
26
+
27
+ async function findAlternativeNodeModules(fs, moduleName, dir) {
28
+ let potentialModules = [];
29
+
30
+ let root = _path().default.parse(dir).root;
31
+
32
+ let isOrganisationModule = moduleName.startsWith('@');
33
+
34
+ while (dir !== root) {
35
+ // Skip node_modules directories
36
+ if (_path().default.basename(dir) === 'node_modules') {
37
+ dir = _path().default.dirname(dir);
38
+ }
39
+
40
+ try {
41
+ let modulesDir = _path().default.join(dir, 'node_modules');
42
+
43
+ let stats = await fs.stat(modulesDir);
44
+
45
+ if (stats.isDirectory()) {
46
+ let dirContent = (await fs.readdir(modulesDir)).sort(); // Filter out the modules that interest us
47
+
48
+ let modules = dirContent.filter(i => isOrganisationModule ? i.startsWith('@') : !i.startsWith('@')); // If it's an organisation module, loop through all the modules of that organisation
49
+
50
+ if (isOrganisationModule) {
51
+ await Promise.all(modules.map(async item => {
52
+ let orgDirPath = _path().default.join(modulesDir, item);
53
+
54
+ let orgDirContent = (await fs.readdir(orgDirPath)).sort(); // Add all org packages
55
+
56
+ potentialModules.push(...orgDirContent.map(i => `${item}/${i}`));
57
+ }));
58
+ }
59
+ }
60
+ } catch (err) {// ignore
61
+ } // Move up a directory
62
+
63
+
64
+ dir = _path().default.dirname(dir);
65
+ }
66
+
67
+ return (0, _schema.fuzzySearch)(potentialModules.sort(), moduleName).slice(0, 2);
68
+ }
69
+
70
+ async function findAllFilesUp({
71
+ fs,
72
+ dir,
73
+ root,
74
+ basedir,
75
+ maxlength,
76
+ collected,
77
+ leadingDotSlash = true,
78
+ includeDirectories = true
79
+ }) {
80
+ let dirContent = (await fs.readdir(dir)).sort();
81
+ return Promise.all(dirContent.map(async item => {
82
+ let fullPath = _path().default.join(dir, item);
83
+
84
+ let relativeFilePath = (0, _path2.relativePath)(basedir, fullPath, leadingDotSlash);
85
+
86
+ if (relativeFilePath.length < maxlength) {
87
+ let stats = await fs.stat(fullPath);
88
+ let isDir = stats.isDirectory();
89
+
90
+ if (isDir && includeDirectories || stats.isFile()) {
91
+ collected.push(relativeFilePath);
92
+ } // If it's a directory, run over each item within said directory...
93
+
94
+
95
+ if (isDir) {
96
+ return findAllFilesUp({
97
+ fs,
98
+ dir: fullPath,
99
+ root,
100
+ basedir,
101
+ maxlength,
102
+ collected
103
+ });
104
+ }
105
+ }
106
+ }));
107
+ }
108
+
109
+ async function findAlternativeFiles(fs, fileSpecifier, dir, projectRoot, leadingDotSlash = true, includeDirectories = true, includeExtension = false) {
110
+ let potentialFiles = []; // Find our root, we won't recommend files above the package root as that's bad practise
111
+
112
+ let pkg = await (0, _config.resolveConfig)(fs, _path().default.join(dir, 'index'), ['package.json'], projectRoot);
113
+ let pkgRoot = pkg ? _path().default.dirname(pkg) : projectRoot;
114
+ await findAllFilesUp({
115
+ fs,
116
+ dir: pkgRoot,
117
+ root: pkgRoot,
118
+ basedir: dir,
119
+ maxlength: fileSpecifier.length + 10,
120
+ collected: potentialFiles,
121
+ leadingDotSlash,
122
+ includeDirectories
123
+ });
124
+
125
+ if (_path().default.extname(fileSpecifier) === '' && !includeExtension) {
126
+ potentialFiles = potentialFiles.map(p => {
127
+ let ext = _path().default.extname(p);
128
+
129
+ return ext.length > 0 ? p.slice(0, -ext.length) : p;
130
+ });
131
+ }
132
+
133
+ return (0, _schema.fuzzySearch)(potentialFiles, fileSpecifier).slice(0, 2);
134
+ }
package/lib/ansi-html.js CHANGED
@@ -5,12 +5,20 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.ansiHtml = ansiHtml;
7
7
 
8
- var _ansiHtml = _interopRequireDefault(require("ansi-html"));
8
+ function _ansiHtmlCommunity() {
9
+ const data = _interopRequireDefault(require("ansi-html-community"));
10
+
11
+ _ansiHtmlCommunity = function () {
12
+ return data;
13
+ };
14
+
15
+ return data;
16
+ }
9
17
 
10
18
  var _escapeHtml = require("./escape-html");
11
19
 
12
20
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
13
21
 
14
22
  function ansiHtml(ansi) {
15
- return (0, _ansiHtml.default)((0, _escapeHtml.escapeHTML)(ansi));
23
+ return (0, _ansiHtmlCommunity().default)((0, _escapeHtml.escapeHTML)(ansi));
16
24
  }
package/lib/blob.js CHANGED
@@ -6,24 +6,42 @@ Object.defineProperty(exports, "__esModule", {
6
6
  exports.blobToBuffer = blobToBuffer;
7
7
  exports.blobToString = blobToString;
8
8
 
9
- var _ = require("../");
9
+ function _buffer() {
10
+ const data = require("buffer");
10
11
 
11
- var _stream = require("stream");
12
+ _buffer = function () {
13
+ return data;
14
+ };
15
+
16
+ return data;
17
+ }
18
+
19
+ var _ = require("./");
20
+
21
+ function _stream() {
22
+ const data = require("stream");
23
+
24
+ _stream = function () {
25
+ return data;
26
+ };
27
+
28
+ return data;
29
+ }
12
30
 
13
31
  function blobToBuffer(blob) {
14
- if (blob instanceof _stream.Readable) {
32
+ if (blob instanceof _stream().Readable) {
15
33
  return (0, _.bufferStream)(blob);
16
- } else if (blob instanceof Buffer) {
17
- return Buffer.from(blob);
34
+ } else if (blob instanceof _buffer().Buffer) {
35
+ return Promise.resolve(_buffer().Buffer.from(blob));
18
36
  } else {
19
- return Buffer.from(blob, 'utf8');
37
+ return Promise.resolve(_buffer().Buffer.from(blob, 'utf8'));
20
38
  }
21
39
  }
22
40
 
23
41
  async function blobToString(blob) {
24
- if (blob instanceof _stream.Readable) {
42
+ if (blob instanceof _stream().Readable) {
25
43
  return (await (0, _.bufferStream)(blob)).toString();
26
- } else if (blob instanceof Buffer) {
44
+ } else if (blob instanceof _buffer().Buffer) {
27
45
  return blob.toString();
28
46
  } else {
29
47
  return blob;
package/lib/collection.js CHANGED
@@ -4,25 +4,16 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.unique = unique;
7
- exports.flatMap = flatMap;
8
7
  exports.objectSortedEntries = objectSortedEntries;
9
8
  exports.objectSortedEntriesDeep = objectSortedEntriesDeep;
10
9
  exports.setDifference = setDifference;
10
+ exports.setIntersect = setIntersect;
11
+ exports.setUnion = setUnion;
11
12
 
12
13
  function unique(array) {
13
14
  return [...new Set(array)];
14
15
  }
15
16
 
16
- function flatMap(array, projectFn) {
17
- let out = [];
18
-
19
- for (let arr of array.map(projectFn)) {
20
- out.push(...arr);
21
- }
22
-
23
- return out;
24
- }
25
-
26
17
  function objectSortedEntries(obj) {
27
18
  return Object.entries(obj).sort(([keyA], [keyB]) => keyA.localeCompare(keyB));
28
19
  }
@@ -59,4 +50,16 @@ function setDifference(a, b) {
59
50
  }
60
51
 
61
52
  return difference;
53
+ }
54
+
55
+ function setIntersect(a, b) {
56
+ for (let entry of a) {
57
+ if (!b.has(entry)) {
58
+ a.delete(entry);
59
+ }
60
+ }
61
+ }
62
+
63
+ function setUnion(a, b) {
64
+ return new Set([...a, ...b]);
62
65
  }
package/lib/config.js CHANGED
@@ -4,79 +4,173 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.resolveConfig = resolveConfig;
7
+ exports.resolveConfigSync = resolveConfigSync;
7
8
  exports.loadConfig = loadConfig;
8
9
 
9
- var _path = _interopRequireDefault(require("path"));
10
+ function _diagnostic() {
11
+ const data = _interopRequireDefault(require("@parcel/diagnostic"));
10
12
 
11
- var _clone = _interopRequireDefault(require("clone"));
13
+ _diagnostic = function () {
14
+ return data;
15
+ };
12
16
 
13
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
17
+ return data;
18
+ }
14
19
 
15
- const PARSERS = {
16
- json: require('json5').parse,
17
- toml: require('@iarna/toml').parse
18
- };
19
- const existsCache = new Map();
20
+ function _path() {
21
+ const data = _interopRequireDefault(require("path"));
20
22
 
21
- async function resolveConfig(fs, filepath, filenames, opts, root = _path.default.parse(filepath).root) {
22
- filepath = await fs.realpath(_path.default.dirname(filepath)); // Don't traverse above the module root
23
+ _path = function () {
24
+ return data;
25
+ };
23
26
 
24
- if (filepath === root || _path.default.basename(filepath) === 'node_modules') {
25
- return null;
26
- }
27
+ return data;
28
+ }
27
29
 
28
- for (const filename of filenames) {
29
- let file = _path.default.join(filepath, filename);
30
+ function _clone() {
31
+ const data = _interopRequireDefault(require("clone"));
30
32
 
31
- if ((await fs.exists(file)) && (await fs.stat(file)).isFile()) {
32
- return file;
33
- }
33
+ _clone = function () {
34
+ return data;
35
+ };
36
+
37
+ return data;
38
+ }
39
+
40
+ function _json() {
41
+ const data = require("json5");
42
+
43
+ _json = function () {
44
+ return data;
45
+ };
46
+
47
+ return data;
48
+ }
49
+
50
+ function _toml() {
51
+ const data = require("@iarna/toml");
52
+
53
+ _toml = function () {
54
+ return data;
55
+ };
56
+
57
+ return data;
58
+ }
59
+
60
+ function _lruCache() {
61
+ const data = _interopRequireDefault(require("lru-cache"));
62
+
63
+ _lruCache = function () {
64
+ return data;
65
+ };
66
+
67
+ return data;
68
+ }
69
+
70
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
71
+
72
+ const configCache = new (_lruCache().default)({
73
+ max: 500
74
+ });
75
+ const resolveCache = new Map();
76
+
77
+ function resolveConfig(fs, filepath, filenames, projectRoot) {
78
+ // Cache the result of resolving config for this directory.
79
+ // This is automatically invalidated at the end of the current build.
80
+ let key = _path().default.dirname(filepath) + filenames.join(',');
81
+ let cached = resolveCache.get(key);
82
+
83
+ if (cached !== undefined) {
84
+ return Promise.resolve(cached);
34
85
  }
35
86
 
36
- return resolveConfig(fs, filepath, filenames, opts);
87
+ let resolved = fs.findAncestorFile(filenames, _path().default.dirname(filepath), projectRoot);
88
+ resolveCache.set(key, resolved);
89
+ return Promise.resolve(resolved);
37
90
  }
38
91
 
39
- async function loadConfig(fs, filepath, filenames, opts) {
40
- let configFile = await resolveConfig(fs, filepath, filenames, opts);
92
+ function resolveConfigSync(fs, filepath, filenames, projectRoot) {
93
+ return fs.findAncestorFile(filenames, _path().default.dirname(filepath), projectRoot);
94
+ }
95
+
96
+ async function loadConfig(fs, filepath, filenames, projectRoot, opts) {
97
+ var _opts$parse;
98
+
99
+ let parse = (_opts$parse = opts === null || opts === void 0 ? void 0 : opts.parse) !== null && _opts$parse !== void 0 ? _opts$parse : true;
100
+ let configFile = await resolveConfig(fs, filepath, filenames, projectRoot);
41
101
 
42
102
  if (configFile) {
103
+ let cachedOutput = configCache.get(String(parse) + configFile);
104
+
105
+ if (cachedOutput) {
106
+ return cachedOutput;
107
+ }
108
+
43
109
  try {
44
- let extname = _path.default.extname(configFile).slice(1);
110
+ let extname = _path().default.extname(configFile).slice(1);
45
111
 
46
112
  if (extname === 'js') {
47
- return {
113
+ let output = {
48
114
  // $FlowFixMe
49
- config: (0, _clone.default)(require(configFile)),
115
+ config: (0, _clone().default)(require(configFile)),
50
116
  files: [{
51
117
  filePath: configFile
52
118
  }]
53
119
  };
120
+ configCache.set(configFile, output);
121
+ return output;
54
122
  }
55
123
 
56
124
  let configContent = await fs.readFile(configFile, 'utf8');
57
-
58
- if (!configContent) {
59
- return null;
60
- }
61
-
62
125
  let config;
63
126
 
64
- if (opts && opts.parse === false) {
127
+ if (parse === false) {
65
128
  config = configContent;
66
129
  } else {
67
- let parse = PARSERS[extname] || PARSERS.json;
68
- config = parse(configContent);
130
+ var _opts$parser;
131
+
132
+ let parse = (_opts$parser = opts === null || opts === void 0 ? void 0 : opts.parser) !== null && _opts$parser !== void 0 ? _opts$parser : getParser(extname);
133
+
134
+ try {
135
+ config = parse(configContent);
136
+ } catch (e) {
137
+ if (extname !== '' && extname !== 'json') {
138
+ throw e;
139
+ }
140
+
141
+ let pos = {
142
+ line: e.lineNumber,
143
+ column: e.columnNumber
144
+ };
145
+ throw new (_diagnostic().default)({
146
+ diagnostic: {
147
+ message: `Failed to parse ${_path().default.basename(configFile)}`,
148
+ origin: '@parcel/utils',
149
+ codeFrames: [{
150
+ language: 'json5',
151
+ filePath: configFile,
152
+ code: configContent,
153
+ codeHighlights: [{
154
+ start: pos,
155
+ end: pos,
156
+ message: e.message
157
+ }]
158
+ }]
159
+ }
160
+ });
161
+ }
69
162
  }
70
163
 
71
- return {
72
- config: config,
164
+ let output = {
165
+ config,
73
166
  files: [{
74
167
  filePath: configFile
75
168
  }]
76
169
  };
170
+ configCache.set(String(parse) + configFile, output);
171
+ return output;
77
172
  } catch (err) {
78
173
  if (err.code === 'MODULE_NOT_FOUND' || err.code === 'ENOENT') {
79
- existsCache.delete(configFile);
80
174
  return null;
81
175
  }
82
176
 
@@ -85,4 +179,20 @@ async function loadConfig(fs, filepath, filenames, opts) {
85
179
  }
86
180
 
87
181
  return null;
182
+ }
183
+
184
+ loadConfig.clear = () => {
185
+ configCache.reset();
186
+ resolveCache.clear();
187
+ };
188
+
189
+ function getParser(extname) {
190
+ switch (extname) {
191
+ case 'toml':
192
+ return _toml().parse;
193
+
194
+ case 'json':
195
+ default:
196
+ return _json().parse;
197
+ }
88
198
  }
package/lib/countLines.js CHANGED
@@ -5,10 +5,10 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.default = countLines;
7
7
 
8
- function countLines(string) {
8
+ function countLines(string, startIndex = 0) {
9
9
  let lines = 1;
10
10
 
11
- for (let i = 0; i < string.length; i++) {
11
+ for (let i = startIndex; i < string.length; i++) {
12
12
  if (string.charAt(i) === '\n') {
13
13
  lines++;
14
14
  }