@cjser/globby 16.2.2-cjser.2 → 16.2.3-cjser.2

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.
@@ -26,7 +26,7 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  ));
27
27
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
28
28
 
29
- // packages/@cjser/globby.tmp-26-1784218928215/index.js
29
+ // packages/@cjser/globby.tmp-26-1786379054379/index.js
30
30
  var index_exports = {};
31
31
  __export(index_exports, {
32
32
  convertPathToPattern: () => convertPathToPattern,
@@ -50,7 +50,7 @@ var import_sindresorhus_merge_streams = __toESM(require("@cjser/sindresorhus__me
50
50
  var import_fast_glob3 = __toESM(require("fast-glob"), 1);
51
51
  var import_node2 = require("@cjser/unicorn-magic/node");
52
52
 
53
- // packages/@cjser/globby.tmp-26-1784218928215/ignore.js
53
+ // packages/@cjser/globby.tmp-26-1786379054379/ignore.js
54
54
  var import_node_process = __toESM(require("node:process"), 1);
55
55
  var import_node_fs2 = __toESM(require("node:fs"), 1);
56
56
  var import_promises = __toESM(require("node:fs/promises"), 1);
@@ -62,7 +62,7 @@ var import_is_path_inside2 = __toESM(require("@cjser/is-path-inside"), 1);
62
62
  var import_slash2 = __toESM(require("@cjser/slash"), 1);
63
63
  var import_node = require("@cjser/unicorn-magic/node");
64
64
 
65
- // packages/@cjser/globby.tmp-26-1784218928215/utilities.js
65
+ // packages/@cjser/globby.tmp-26-1786379054379/utilities.js
66
66
  var import_node_fs = __toESM(require("node:fs"), 1);
67
67
  var import_node_path = __toESM(require("node:path"), 1);
68
68
  var import_node_util = require("node:util");
@@ -274,8 +274,10 @@ var GITIGNORE_WILDCARDS = /(?<!\\)[*?[]/u;
274
274
  var hasGitignoreWildcards = (value) => GITIGNORE_WILDCARDS.test(value);
275
275
  var MICROMATCH_ONLY_SYNTAX = /[(){}|\\]/u;
276
276
  var unescapeGitignorePattern = (value) => value.replaceAll(/\\(.)/gu, "$1");
277
+ var normalizeGitignorePatternForIgnore = (value) => value.replaceAll(/\\(.)/gu, (match, character) => "*[]\\".includes(character) ? match : character);
277
278
  var toLiteralPattern = (value) => import_fast_glob.default.escapePath(unescapeGitignorePattern(value));
278
279
  var finalSegment = (value) => value.replace(/\/+$/u, "").split("/").pop();
280
+ var toStandaloneRule = (value) => value.replace(/^([#!])/u, String.raw`\$1`);
279
281
  var isInsideCwd = (relativePath) => relativePath !== "" && !relativePath.startsWith("..") && !import_node_path.default.isAbsolute(relativePath);
280
282
  var anchorToCwd = (directory, body, cwd) => {
281
283
  const relativePath = (0, import_slash.default)(import_node_path.default.relative(cwd, import_node_path.default.join(directory, body)));
@@ -284,12 +286,17 @@ var anchorToCwd = (directory, body, cwd) => {
284
286
  var createNameComparer = () => {
285
287
  const nameMatchers = /* @__PURE__ */ new Map();
286
288
  const matchesName = (pattern, name) => {
287
- let nameMatcher = nameMatchers.get(pattern);
289
+ const namePath = unescapeGitignorePattern(name);
290
+ if (!(0, import_ignore.isPathValid)(namePath)) {
291
+ return true;
292
+ }
293
+ const normalizedPattern = normalizeGitignorePatternForIgnore(pattern);
294
+ let nameMatcher = nameMatchers.get(normalizedPattern);
288
295
  if (!nameMatcher) {
289
- nameMatcher = (0, import_ignore.default)().add([pattern]);
290
- nameMatchers.set(pattern, nameMatcher);
296
+ nameMatcher = (0, import_ignore.default)().add([toStandaloneRule(normalizedPattern)]);
297
+ nameMatchers.set(normalizedPattern, nameMatcher);
291
298
  }
292
- return nameMatcher.ignores(name);
299
+ return nameMatcher.ignores(namePath);
293
300
  };
294
301
  return (pattern, name) => {
295
302
  if (hasGitignoreWildcards(pattern) && hasGitignoreWildcards(name)) {
@@ -334,8 +341,9 @@ var getRulePrune = ({ pattern, directory }, { cwd, matcher, hasNegations, canSki
334
341
  if (target === void 0) {
335
342
  return void 0;
336
343
  }
344
+ const guardName = finalSegment(anchoredBody);
337
345
  if (isGlob) {
338
- return hasNegations ? void 0 : { pattern: toFastGlob(target), guardName: finalSegment(target) };
346
+ return hasNegations ? void 0 : { pattern: toFastGlob(target), guardName };
339
347
  }
340
348
  if (!matcher(import_node_path.default.resolve(cwd, target) + import_node_path.default.sep).ignored) {
341
349
  return void 0;
@@ -343,7 +351,7 @@ var getRulePrune = ({ pattern, directory }, { cwd, matcher, hasNegations, canSki
343
351
  const needsGuard = !gitignoreOnlySearch || target.includes("/");
344
352
  return {
345
353
  pattern: toFastGlob(import_fast_glob.default.escapePath(target)),
346
- guardName: needsGuard ? finalSegment(target) : void 0
354
+ guardName: needsGuard ? guardName : void 0
347
355
  };
348
356
  };
349
357
  var buildPrunePatternsAndGuards = (rules, matcher, cwd, { gitignoreOnlySearch = false, searchesForGitignoreFiles = false } = {}) => {
@@ -376,7 +384,7 @@ var buildPrunePatternsAndGuards = (rules, matcher, cwd, { gitignoreOnlySearch =
376
384
  };
377
385
  var convertPatternsForFastGlob = (rules, matcher, cwd) => buildPrunePatternsAndGuards(rules, matcher, cwd).patterns;
378
386
 
379
- // packages/@cjser/globby.tmp-26-1784218928215/ignore.js
387
+ // packages/@cjser/globby.tmp-26-1786379054379/ignore.js
380
388
  var defaultIgnoredDirectories = [
381
389
  "**/node_modules",
382
390
  "**/flow-typed",
@@ -1064,7 +1072,7 @@ var getIgnorePatternsAndPredicateSync = (patterns, options, includeParentIgnoreF
1064
1072
  var isGitIgnored = (options) => isIgnoredByIgnoreFiles(GITIGNORE_FILES_PATTERN, options);
1065
1073
  var isGitIgnoredSync = (options) => isIgnoredByIgnoreFilesSync(GITIGNORE_FILES_PATTERN, options);
1066
1074
 
1067
- // packages/@cjser/globby.tmp-26-1784218928215/index.js
1075
+ // packages/@cjser/globby.tmp-26-1786379054379/index.js
1068
1076
  var assertPatternsInput = (patterns) => {
1069
1077
  if (patterns.some((pattern) => typeof pattern !== "string")) {
1070
1078
  throw new TypeError("Patterns must be a string or an array of strings");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cjser/globby",
3
- "version": "16.2.2-cjser.2",
3
+ "version": "16.2.3-cjser.2",
4
4
  "description": "User-friendly glob matching",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -99,11 +99,11 @@
99
99
  "types": "./index.d.ts",
100
100
  "main": "./dist-cjser/index.cjs",
101
101
  "cjser": {
102
- "sourceVersion": "16.2.2",
102
+ "sourceVersion": "16.2.3",
103
103
  "cjserVersion": 2,
104
104
  "original": {
105
105
  "name": "globby",
106
- "version": "16.2.2",
106
+ "version": "16.2.3",
107
107
  "exports": {
108
108
  "types": "./index.d.ts",
109
109
  "default": "./index.js"
package/utilities.js CHANGED
@@ -2,7 +2,7 @@ import fs from 'node:fs';
2
2
  import path from 'node:path';
3
3
  import {promisify} from 'node:util';
4
4
  import fastGlob from 'fast-glob';
5
- import gitIgnore from 'ignore';
5
+ import gitIgnore, {isPathValid} from 'ignore';
6
6
  import isPathInside from '@cjser/is-path-inside';
7
7
  import slash from '@cjser/slash';
8
8
 
@@ -359,12 +359,18 @@ const MICROMATCH_ONLY_SYNTAX = /[(){}|\\]/u;
359
359
  // In gitignore, `\x` means the literal character x.
360
360
  const unescapeGitignorePattern = value => value.replaceAll(/\\(.)/gu, '$1');
361
361
 
362
+ // Normalize ordinary escaped characters for the ignore package, while preserving escapes that it handles as literals. An escaped question mark is widened to a wildcard because the ignore package does not match it literally, and a possible match is safer here than pruning too much.
363
+ const normalizeGitignorePatternForIgnore = value => value.replaceAll(/\\(.)/gu, (match, character) => '*[]\\'.includes(character) ? match : character);
364
+
362
365
  // Turn gitignore-literal text into fast-glob-literal text, so characters like `+(` cannot be
363
366
  // misread as micromatch syntax.
364
367
  const toLiteralPattern = value => fastGlob.escapePath(unescapeGitignorePattern(value));
365
368
 
366
369
  const finalSegment = value => value.replace(/\/+$/u, '').split('/').pop();
367
370
 
371
+ // A fragment of rule text is not a rule on its own: `#name` would open a comment and `!name` a negation, both of which stop naming anything. Escape the leading character so the fragment keeps naming what it did inside the rule it came from.
372
+ const toStandaloneRule = value => value.replace(/^([#!])/u, String.raw`\$1`);
373
+
368
374
  const isInsideCwd = relativePath => relativePath !== '' && !relativePath.startsWith('..') && !path.isAbsolute(relativePath);
369
375
 
370
376
  /**
@@ -385,13 +391,20 @@ const anchorToCwd = (directory, body, cwd) => {
385
391
  const createNameComparer = () => {
386
392
  const nameMatchers = new Map();
387
393
  const matchesName = (pattern, name) => {
388
- let nameMatcher = nameMatchers.get(pattern);
394
+ // The name is rule text, not a path: in gitignore `\#foo` names the file `#foo`. `Ignore#ignores()` only accepts a `path.relative()`d string and throws otherwise, so unescape first and treat whatever it still rejects (`.`, `..`, anything anchored) as a possible match.
395
+ const namePath = unescapeGitignorePattern(name);
396
+ if (!isPathValid(namePath)) {
397
+ return true;
398
+ }
399
+
400
+ const normalizedPattern = normalizeGitignorePatternForIgnore(pattern);
401
+ let nameMatcher = nameMatchers.get(normalizedPattern);
389
402
  if (!nameMatcher) {
390
- nameMatcher = gitIgnore().add([pattern]);
391
- nameMatchers.set(pattern, nameMatcher);
403
+ nameMatcher = gitIgnore().add([toStandaloneRule(normalizedPattern)]);
404
+ nameMatchers.set(normalizedPattern, nameMatcher);
392
405
  }
393
406
 
394
- return nameMatcher.ignores(name);
407
+ return nameMatcher.ignores(namePath);
395
408
  };
396
409
 
397
410
  // A negation can only re-include the excluded path itself; nothing below it can be re-included once the directory is excluded. Two globs cannot be compared this way, so treat them as a possible match.
@@ -472,11 +485,14 @@ const getRulePrune = ({pattern, directory}, {cwd, matcher, hasNegations, canSkip
472
485
  return undefined;
473
486
  }
474
487
 
488
+ // The guard name is compared against negations as rule text, so it has to keep the escapes the rule was written with; the target has already lost them.
489
+ const guardName = finalSegment(anchoredBody);
490
+
475
491
  if (isGlob) {
476
492
  // A glob does not name a concrete path, so the matcher cannot confirm it is ignored.
477
493
  return hasNegations
478
494
  ? undefined
479
- : {pattern: toFastGlob(target), guardName: finalSegment(target)};
495
+ : {pattern: toFastGlob(target), guardName};
480
496
  }
481
497
 
482
498
  if (!matcher(path.resolve(cwd, target) + path.sep).ignored) {
@@ -487,7 +503,7 @@ const getRulePrune = ({pattern, directory}, {cwd, matcher, hasNegations, canSkip
487
503
  const needsGuard = !gitignoreOnlySearch || target.includes('/');
488
504
  return {
489
505
  pattern: toFastGlob(fastGlob.escapePath(target)),
490
- guardName: needsGuard ? finalSegment(target) : undefined,
506
+ guardName: needsGuard ? guardName : undefined,
491
507
  };
492
508
  };
493
509