index.cjs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409
  1. 'use strict';
  2. const fs = require('node:fs');
  3. const fsp = require('node:fs/promises');
  4. const node_module = require('node:module');
  5. const path = require('node:path');
  6. const process = require('node:process');
  7. const node_url = require('node:url');
  8. const mlly = require('mlly');
  9. var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
  10. function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e.default : e; }
  11. const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
  12. const fsp__default = /*#__PURE__*/_interopDefaultCompat(fsp);
  13. const path__default = /*#__PURE__*/_interopDefaultCompat(path);
  14. const process__default = /*#__PURE__*/_interopDefaultCompat(process);
  15. /*
  16. How it works:
  17. `this.#head` is an instance of `Node` which keeps track of its current value and nests another instance of `Node` that keeps the value that comes after it. When a value is provided to `.enqueue()`, the code needs to iterate through `this.#head`, going deeper and deeper to find the last value. However, iterating through every single item is slow. This problem is solved by saving a reference to the last value as `this.#tail` so that it can reference it to add a new value.
  18. */
  19. class Node {
  20. value;
  21. next;
  22. constructor(value) {
  23. this.value = value;
  24. }
  25. }
  26. class Queue {
  27. #head;
  28. #tail;
  29. #size;
  30. constructor() {
  31. this.clear();
  32. }
  33. enqueue(value) {
  34. const node = new Node(value);
  35. if (this.#head) {
  36. this.#tail.next = node;
  37. this.#tail = node;
  38. } else {
  39. this.#head = node;
  40. this.#tail = node;
  41. }
  42. this.#size++;
  43. }
  44. dequeue() {
  45. const current = this.#head;
  46. if (!current) {
  47. return;
  48. }
  49. this.#head = this.#head.next;
  50. this.#size--;
  51. return current.value;
  52. }
  53. clear() {
  54. this.#head = undefined;
  55. this.#tail = undefined;
  56. this.#size = 0;
  57. }
  58. get size() {
  59. return this.#size;
  60. }
  61. * [Symbol.iterator]() {
  62. let current = this.#head;
  63. while (current) {
  64. yield current.value;
  65. current = current.next;
  66. }
  67. }
  68. }
  69. function pLimit(concurrency) {
  70. if (!((Number.isInteger(concurrency) || concurrency === Number.POSITIVE_INFINITY) && concurrency > 0)) {
  71. throw new TypeError('Expected `concurrency` to be a number from 1 and up');
  72. }
  73. const queue = new Queue();
  74. let activeCount = 0;
  75. const next = () => {
  76. activeCount--;
  77. if (queue.size > 0) {
  78. queue.dequeue()();
  79. }
  80. };
  81. const run = async (fn, resolve, args) => {
  82. activeCount++;
  83. const result = (async () => fn(...args))();
  84. resolve(result);
  85. try {
  86. await result;
  87. } catch {}
  88. next();
  89. };
  90. const enqueue = (fn, resolve, args) => {
  91. queue.enqueue(run.bind(undefined, fn, resolve, args));
  92. (async () => {
  93. // This function needs to wait until the next microtask before comparing
  94. // `activeCount` to `concurrency`, because `activeCount` is updated asynchronously
  95. // when the run function is dequeued and called. The comparison in the if-statement
  96. // needs to happen asynchronously as well to get an up-to-date value for `activeCount`.
  97. await Promise.resolve();
  98. if (activeCount < concurrency && queue.size > 0) {
  99. queue.dequeue()();
  100. }
  101. })();
  102. };
  103. const generator = (fn, ...args) => new Promise(resolve => {
  104. enqueue(fn, resolve, args);
  105. });
  106. Object.defineProperties(generator, {
  107. activeCount: {
  108. get: () => activeCount,
  109. },
  110. pendingCount: {
  111. get: () => queue.size,
  112. },
  113. clearQueue: {
  114. value: () => {
  115. queue.clear();
  116. },
  117. },
  118. });
  119. return generator;
  120. }
  121. class EndError extends Error {
  122. constructor(value) {
  123. super();
  124. this.value = value;
  125. }
  126. }
  127. // The input can also be a promise, so we await it.
  128. const testElement = async (element, tester) => tester(await element);
  129. // The input can also be a promise, so we `Promise.all()` them both.
  130. const finder = async element => {
  131. const values = await Promise.all(element);
  132. if (values[1] === true) {
  133. throw new EndError(values[0]);
  134. }
  135. return false;
  136. };
  137. async function pLocate(
  138. iterable,
  139. tester,
  140. {
  141. concurrency = Number.POSITIVE_INFINITY,
  142. preserveOrder = true,
  143. } = {},
  144. ) {
  145. const limit = pLimit(concurrency);
  146. // Start all the promises concurrently with optional limit.
  147. const items = [...iterable].map(element => [element, limit(testElement, element, tester)]);
  148. // Check the promises either serially or concurrently.
  149. const checkLimit = pLimit(preserveOrder ? 1 : Number.POSITIVE_INFINITY);
  150. try {
  151. await Promise.all(items.map(element => checkLimit(finder, element)));
  152. } catch (error) {
  153. if (error instanceof EndError) {
  154. return error.value;
  155. }
  156. throw error;
  157. }
  158. }
  159. const typeMappings = {
  160. directory: 'isDirectory',
  161. file: 'isFile',
  162. };
  163. function checkType(type) {
  164. if (Object.hasOwnProperty.call(typeMappings, type)) {
  165. return;
  166. }
  167. throw new Error(`Invalid type specified: ${type}`);
  168. }
  169. const matchType = (type, stat) => stat[typeMappings[type]]();
  170. const toPath$1 = urlOrPath => urlOrPath instanceof URL ? node_url.fileURLToPath(urlOrPath) : urlOrPath;
  171. async function locatePath(
  172. paths,
  173. {
  174. cwd = process__default.cwd(),
  175. type = 'file',
  176. allowSymlinks = true,
  177. concurrency,
  178. preserveOrder,
  179. } = {},
  180. ) {
  181. checkType(type);
  182. cwd = toPath$1(cwd);
  183. const statFunction = allowSymlinks ? fs.promises.stat : fs.promises.lstat;
  184. return pLocate(paths, async path_ => {
  185. try {
  186. const stat = await statFunction(path__default.resolve(cwd, path_));
  187. return matchType(type, stat);
  188. } catch {
  189. return false;
  190. }
  191. }, {concurrency, preserveOrder});
  192. }
  193. const toPath = urlOrPath => urlOrPath instanceof URL ? node_url.fileURLToPath(urlOrPath) : urlOrPath;
  194. const findUpStop = Symbol('findUpStop');
  195. async function findUpMultiple(name, options = {}) {
  196. let directory = path__default.resolve(toPath(options.cwd) || '');
  197. const {root} = path__default.parse(directory);
  198. const stopAt = path__default.resolve(directory, options.stopAt || root);
  199. const limit = options.limit || Number.POSITIVE_INFINITY;
  200. const paths = [name].flat();
  201. const runMatcher = async locateOptions => {
  202. if (typeof name !== 'function') {
  203. return locatePath(paths, locateOptions);
  204. }
  205. const foundPath = await name(locateOptions.cwd);
  206. if (typeof foundPath === 'string') {
  207. return locatePath([foundPath], locateOptions);
  208. }
  209. return foundPath;
  210. };
  211. const matches = [];
  212. // eslint-disable-next-line no-constant-condition
  213. while (true) {
  214. // eslint-disable-next-line no-await-in-loop
  215. const foundPath = await runMatcher({...options, cwd: directory});
  216. if (foundPath === findUpStop) {
  217. break;
  218. }
  219. if (foundPath) {
  220. matches.push(path__default.resolve(directory, foundPath));
  221. }
  222. if (directory === stopAt || matches.length >= limit) {
  223. break;
  224. }
  225. directory = path__default.dirname(directory);
  226. }
  227. return matches;
  228. }
  229. async function findUp(name, options = {}) {
  230. const matches = await findUpMultiple(name, {...options, limit: 1});
  231. return matches[0];
  232. }
  233. function _resolve(path$1, options = {}) {
  234. if (options.platform === "auto" || !options.platform)
  235. options.platform = process__default.platform === "win32" ? "win32" : "posix";
  236. if (process__default.versions.pnp) {
  237. const paths = options.paths || [];
  238. if (paths.length === 0)
  239. paths.push(process__default.cwd());
  240. const targetRequire = node_module.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.src || new URL('index.cjs', document.baseURI).href)));
  241. try {
  242. return targetRequire.resolve(path$1, { paths });
  243. } catch {
  244. }
  245. }
  246. const modulePath = mlly.resolvePathSync(path$1, {
  247. url: options.paths
  248. });
  249. if (options.platform === "win32")
  250. return path.win32.normalize(modulePath);
  251. return modulePath;
  252. }
  253. function resolveModule(name, options = {}) {
  254. try {
  255. return _resolve(name, options);
  256. } catch {
  257. return void 0;
  258. }
  259. }
  260. async function importModule(path) {
  261. const i = await import(path);
  262. if (i)
  263. return mlly.interopDefault(i);
  264. return i;
  265. }
  266. function isPackageExists(name, options = {}) {
  267. return !!resolvePackage(name, options);
  268. }
  269. function getPackageJsonPath(name, options = {}) {
  270. const entry = resolvePackage(name, options);
  271. if (!entry)
  272. return;
  273. return searchPackageJSON(entry);
  274. }
  275. async function getPackageInfo(name, options = {}) {
  276. const packageJsonPath = getPackageJsonPath(name, options);
  277. if (!packageJsonPath)
  278. return;
  279. const packageJson = JSON.parse(await fs__default.promises.readFile(packageJsonPath, "utf8"));
  280. return {
  281. name,
  282. version: packageJson.version,
  283. rootPath: path.dirname(packageJsonPath),
  284. packageJsonPath,
  285. packageJson
  286. };
  287. }
  288. function getPackageInfoSync(name, options = {}) {
  289. const packageJsonPath = getPackageJsonPath(name, options);
  290. if (!packageJsonPath)
  291. return;
  292. const packageJson = JSON.parse(fs__default.readFileSync(packageJsonPath, "utf8"));
  293. return {
  294. name,
  295. version: packageJson.version,
  296. rootPath: path.dirname(packageJsonPath),
  297. packageJsonPath,
  298. packageJson
  299. };
  300. }
  301. function resolvePackage(name, options = {}) {
  302. try {
  303. return _resolve(`${name}/package.json`, options);
  304. } catch {
  305. }
  306. try {
  307. return _resolve(name, options);
  308. } catch (e) {
  309. if (e.code !== "MODULE_NOT_FOUND" && e.code !== "ERR_MODULE_NOT_FOUND")
  310. console.error(e);
  311. return false;
  312. }
  313. }
  314. function searchPackageJSON(dir) {
  315. let packageJsonPath;
  316. while (true) {
  317. if (!dir)
  318. return;
  319. const newDir = path.dirname(dir);
  320. if (newDir === dir)
  321. return;
  322. dir = newDir;
  323. packageJsonPath = path.join(dir, "package.json");
  324. if (fs__default.existsSync(packageJsonPath))
  325. break;
  326. }
  327. return packageJsonPath;
  328. }
  329. async function loadPackageJSON(cwd = process__default.cwd()) {
  330. const path = await findUp("package.json", { cwd });
  331. if (!path || !fs__default.existsSync(path))
  332. return null;
  333. return JSON.parse(await fsp__default.readFile(path, "utf-8"));
  334. }
  335. async function isPackageListed(name, cwd) {
  336. const pkg = await loadPackageJSON(cwd) || {};
  337. return name in (pkg.dependencies || {}) || name in (pkg.devDependencies || {});
  338. }
  339. exports.getPackageInfo = getPackageInfo;
  340. exports.getPackageInfoSync = getPackageInfoSync;
  341. exports.importModule = importModule;
  342. exports.isPackageExists = isPackageExists;
  343. exports.isPackageListed = isPackageListed;
  344. exports.loadPackageJSON = loadPackageJSON;
  345. exports.resolveModule = resolveModule;