@w5s/eslint-config-ignore 1.31.0 → 1.33.0

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.
package/dist/index.d.ts CHANGED
@@ -25,9 +25,14 @@ export interface ESLintIgnoreOptions {
25
25
  */
26
26
  ignores?: ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']) | ESLintIgnoreConfig['ignores'];
27
27
  /**
28
- * Override configuration name
28
+ * Override the namespace used in the configuration name (default: 'w5s')
29
+ *
30
+ * @example
31
+ * ```ts
32
+ * await eslintIgnores({ namespace: 'custom-name' });// { name: 'custom-name/eslint-ignore', ignores: [...] }
33
+ * ```
29
34
  */
30
- name?: ESLintIgnoreConfig['name'];
35
+ namespace?: string | undefined;
31
36
  /**
32
37
  * Include recommended settings and default ignored files
33
38
  */
@@ -43,7 +48,8 @@ export interface ESLintIgnoreOptions {
43
48
  * await eslintIgnores({
44
49
  * ignores: [
45
50
  * // Add custom paths here
46
- * ]
51
+ * ],
52
+ * // namespace: 'custom-name', // Optional namespace override
47
53
  * })
48
54
  * ];
49
55
  * ```
package/dist/index.js CHANGED
@@ -124,7 +124,7 @@ function convertIgnorePatternToMinimatch(pattern) {
124
124
  for (const char of patternWithoutLeadingSlash) {
125
125
  if (!isEscaped && (char === "{" || char === "(")) escapedPatternWithoutLeadingSlash += "\\";
126
126
  escapedPatternWithoutLeadingSlash += char;
127
- isEscaped = char === "\\" ? !isEscaped : false;
127
+ isEscaped = char === "\\" && !isEscaped;
128
128
  }
129
129
  const matchInsideSuffix = patternToTest.endsWith("/**") ? "/*" : "";
130
130
  return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`;
@@ -206,8 +206,7 @@ async function ignoreFileFind(rootDir, options) {
206
206
  }
207
207
  function isIgnored(patterns, candidateRel) {
208
208
  const m = lastMatchWins(patterns, candidateRel);
209
- if (!m) return false;
210
- return !m.startsWith("!");
209
+ return m ? !m.startsWith("!") : false;
211
210
  }
212
211
  async function collectAncestorGitignores(startDir) {
213
212
  const files = [];
@@ -285,7 +284,8 @@ async function ignoreFileFind(rootDir, options) {
285
284
  * await eslintIgnores({
286
285
  * ignores: [
287
286
  * // Add custom paths here
288
- * ]
287
+ * ],
288
+ * // namespace: 'custom-name', // Optional namespace override
289
289
  * })
290
290
  * ];
291
291
  * ```
@@ -294,6 +294,7 @@ async function ignoreFileFind(rootDir, options) {
294
294
  */
295
295
  async function eslintIgnores(options = {}) {
296
296
  const cwd = options.cwd ?? process.cwd();
297
+ const namespace = options.namespace ?? "w5s";
297
298
  const recommended = options.recommended ?? true;
298
299
  const ignoreFilePaths = await ignoreFileFind(cwd);
299
300
  const ignoreGlobs = await Promise.all(ignoreFilePaths.map(async (ignoreFilePathRelative) => {
@@ -306,15 +307,15 @@ async function eslintIgnores(options = {}) {
306
307
  if (options.ignoreGitModules ?? true) mergedIgnores.push(...await gitModulesIgnore(cwd));
307
308
  return {
308
309
  ignores: typeof options.ignores === "function" ? options.ignores(mergedIgnores) : options.ignores ? [...mergedIgnores, ...options.ignores] : mergedIgnores,
309
- name: options.name ?? "w5s/eslint-ignore"
310
+ name: `${namespace}/eslint-ignore`
310
311
  };
311
312
  }
312
313
  //#endregion
313
314
  //#region src/meta.ts
314
315
  const meta = Object.freeze({
315
- buildNumber: 1790065426,
316
+ buildNumber: 1790874075,
316
317
  name: "@w5s/eslint-config-ignore",
317
- version: "1.31.0"
318
+ version: "1.33.0"
318
319
  });
319
320
  //#endregion
320
321
  export { eslintIgnores as default, eslintIgnores, meta };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["fs"],"sources":["../src/defaultIgnores.ts","../src/internal/gitModulesIgnore.ts","../src/internal/ignoreFileParse.ts","../src/internal/convertIgnorePatternToMinimatch.ts","../src/internal/ignoreRuleResolve.ts","../src/internal/ignoreFileFind.ts","../src/eslintIgnores.ts","../src/meta.ts"],"sourcesContent":["export const defaultIgnores = [\n // Lock files\n '**/package-lock.json',\n '**/yarn.lock',\n '**/pnpm-lock.yaml',\n '**/bun.lockb',\n\n // Commonly ignored\n '**/output',\n '**/.output',\n '**/coverage',\n '**/temp',\n '**/.temp',\n '**/tmp',\n '**/.tmp',\n '**/.cache',\n\n // Well known extensions to ignore\n '**/*.min.*',\n '**/*.timestamp-*.mjs',\n\n // Framework specific temporary folder\n '.go/',\n '.pnpm-store/',\n '**/.vitepress/cache',\n '**/.vite-inspect',\n '**/.history',\n '**/.nuxt',\n '**/.next',\n '**/next-env.d.ts',\n '**/.svelte-kit',\n '**/.vercel',\n '**/.idea',\n '**/.yarn',\n '**/__snapshots__/**',\n\n // Generated markdown\n '**/CHANGELOG.md',\n\n // git submodules (makefile-core / makefile-ci)\n '.modules/',\n\n // AI related\n '**/.context',\n '**/.claude',\n '**/.agents',\n '**/.*/skills',\n];\n","import fs from 'node:fs';\nimport nodePath from 'node:path';\n\nconst SUBMODULE_PATH_RE = /path\\s*=\\s*(.+)/g;\n\n/**\n * Read `cwd/.gitmodules` and return ESLint ignore glob patterns for every\n * listed submodule. Returns an empty array when no `.gitmodules` file exists.\n *\n * @param cwd\n * @example\n * ```ts\n * await gitModulesIgnore('/path/to/project');\n * // ['**\\/packages/foo\\/**', '**\\/packages/bar\\/**']\n * ```\n */\nexport async function gitModulesIgnore(cwd: string): Promise<Array<string>> {\n const gmPath = nodePath.join(cwd, '.gitmodules');\n try {\n let stat = null;\n try {\n stat = await fs.promises.stat(gmPath);\n } catch {\n stat = null;\n }\n if (!stat?.isFile()) return [];\n\n const content = (await fs.promises.readFile(gmPath, 'utf8'));\n const paths = gitModulesParse(content);\n return paths.map((p) => `${p.replaceAll('\\\\', '/')}/**`);\n } catch {\n return [];\n }\n}\n\n/**\n * Parse the content of a `.gitmodules` file and return the list of submodule paths.\n *\n * @param content\n * @example\n * ```ts\n * gitModulesParse('[submodule \"foo\"]\\n\\tpath = packages/foo\\n');\n * // ['packages/foo']\n * ```\n */\nexport function gitModulesParse(content: string): Array<string> {\n const paths: Array<string> = [];\n SUBMODULE_PATH_RE.lastIndex = 0;\n for (;;) {\n const matches = SUBMODULE_PATH_RE.exec(content);\n if (!matches) break;\n const captured = matches[1];\n if (captured) paths.push(captured.trim());\n }\n return paths;\n}\n","import parseGitignore from 'parse-gitignore';\n\nexport function ignoreFileParse(input: string): Array<string> {\n return parseGitignore.parse(input).patterns;\n};\n","/**\n * Converts a gitignore-style pattern to an ESLint-compatible minimatch pattern.\n *\n * Ported from `@eslint/config-helpers` (eslint/rewrite).\n *\n * @see https://github.com/eslint/rewrite/blob/main/packages/config-helpers/src/ignore-file.js\n * @param pattern The .eslintignore or .gitignore pattern to convert.\n * @returns The converted minimatch pattern.\n */\nexport function convertIgnorePatternToMinimatch(pattern: string): string {\n const isNegated = pattern.startsWith('!');\n const negatedPrefix = isNegated ? '!' : '';\n const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd();\n\n // special cases\n if (['', '**', '**/', '/**'].includes(patternToTest)) {\n return `${negatedPrefix}${patternToTest}`;\n }\n\n const firstIndexOfSlash = patternToTest.indexOf('/');\n\n const matchEverywherePrefix = firstIndexOfSlash === -1 || firstIndexOfSlash === patternToTest.length - 1 ? '**/' : '';\n\n const patternWithoutLeadingSlash = firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest;\n\n /*\n * Escape `{` and `(` because in gitignore patterns they are just\n * literal characters without any specific syntactic meaning,\n * while in minimatch patterns they can form brace expansion or ext glob syntax.\n */\n let escapedPatternWithoutLeadingSlash = '';\n let isEscaped = false;\n\n for (const char of patternWithoutLeadingSlash) {\n if (!isEscaped && (char === '{' || char === '(')) {\n escapedPatternWithoutLeadingSlash += '\\\\';\n }\n\n escapedPatternWithoutLeadingSlash += char;\n\n isEscaped = char === '\\\\' ? !isEscaped : false;\n }\n\n const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : '';\n\n return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`;\n}\n","import { convertIgnorePatternToMinimatch } from './convertIgnorePatternToMinimatch.js';\n\nconst ROOT_PREFIX_PATTERN = /^\\.\\/?/;\n\nconst normalizePath = (p: string) => p.replaceAll('\\\\', '/').replace(ROOT_PREFIX_PATTERN, '');\n\n/**\n * Resolve a raw ignore rule from a `.gitignore` file into a flat ESLint\n * minimatch glob relative to the configured working directory.\n *\n * @example\n * ```ts\n * import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';\n *\n * ignoreRuleResolve('.', 'out'); // '**\\/out'\n * ignoreRuleResolve('.', '/dist'); // 'dist'\n * ignoreRuleResolve('android', 'build'); // 'android/**\\/build'\n * ignoreRuleResolve('android', '/build'); // 'android/build'\n * ignoreRuleResolve('android', '!build'); // '!android/**\\/build'\n * ```\n *\n * @internal\n * @param prefix A path prefix that points to the directory containing the `.gitignore` file.\n * @param rule The raw ignore rule parsed from `.gitignore`.\n * @returns A normalized ignore pattern relative to the root `cwd`.\n */\nexport function ignoreRuleResolve(prefix: string, rule: string): string {\n const negated = rule.startsWith('!');\n const raw = negated ? rule.slice(1) : rule;\n const normalizedPrefix = prefix === '.' || prefix === '' ? '' : normalizePath(prefix);\n\n let converted: string;\n if (raw.startsWith('/')) {\n const joined = normalizedPrefix\n ? `${normalizedPrefix}/${raw.slice(1)}`\n : raw.slice(1);\n converted = convertIgnorePatternToMinimatch(`/${joined}`);\n } else {\n const dirPrefix = normalizedPrefix ? `${normalizedPrefix}/` : '';\n converted = dirPrefix + convertIgnorePatternToMinimatch(raw);\n }\n\n return negated ? `!${converted}` : converted;\n}\n","/* eslint-disable unicorn/prefer-await */\nimport { minimatch } from 'minimatch';\nimport fs from 'node:fs/promises';\nimport nodePath from 'node:path';\n\nimport { ignoreFileParse } from './ignoreFileParse.js';\nimport { ignoreRuleResolve } from './ignoreRuleResolve.js';\n\nconst GITIGNORE_FILE = '.gitignore';\n\nexport interface IgnoreFileFindOptions {\n /** Directory names to skip when searching downward from `rootDir`. */\n excludeDirs?: Array<string>;\n /** Maximum recursion depth when searching downward. Defaults to 8. */\n maxDepth?: number;\n /** When true (default), stop ancestor traversal when a `.git` directory is found. */\n stopAtGitRoot?: boolean;\n}\n\n/**\n * Find `.gitignore` files relevant to `rootDir`.\n *\n * Behavior:\n * - Searches downwards from `rootDir` (BFS) for `.gitignore` files, skipping `excludeDirs`.\n * - Walks ancestors from `rootDir` up to the filesystem root (and stops at a `.git` folder when `stopAtGitRoot` is true).\n * - Returns relative paths to `rootDir`.\n *\n * @param rootDir\n * @param options\n */\nexport async function ignoreFileFind(\n rootDir: string,\n options?: IgnoreFileFindOptions,\n): Promise<Array<string>> {\n const excludeDirs = new Set(options?.excludeDirs ?? ['node_modules', '.git']);\n const maxDepth = options?.maxDepth ?? 8;\n const stopAtGitRoot = options?.stopAtGitRoot ?? true;\n\n const absoluteRootDir = nodePath.resolve(rootDir);\n const found = new Set<string>();\n\n // --- Helpers (internal, not exported) ---------------------------------\n const normalize = (p: string) => p.replaceAll('\\\\', '/');\n\n function patternMatchesPath(pattern: string, candidateRel: string): boolean {\n const normCandidate = normalize(candidateRel);\n const normPattern = normalize(pattern);\n\n if (minimatch(normCandidate, normPattern, { dot: true })) {\n return true;\n }\n\n if (minimatch(normCandidate, `${normPattern}/**`, { dot: true })) {\n return true;\n }\n\n if (normPattern.endsWith('/')) {\n const withoutTrailing = normPattern.slice(0, -1);\n if (minimatch(normCandidate, withoutTrailing, { dot: true })) {\n return true;\n }\n if (minimatch(normCandidate, `${withoutTrailing}/**`, { dot: true })) {\n return true;\n }\n }\n\n return false;\n }\n\n function lastMatchWins(patterns: Array<string>, candidateRel: string): null | string {\n let lastMatch: null | string = null;\n for (const p of patterns) {\n const pat = p.startsWith('!') ? p.slice(1) : p;\n if (!pat) continue;\n\n if (patternMatchesPath(pat, candidateRel)) {\n lastMatch = p;\n }\n }\n return lastMatch;\n }\n\n function isIgnored(patterns: Array<string>, candidateRel: string): boolean {\n const m = lastMatchWins(patterns, candidateRel);\n if (!m) return false;\n return !m.startsWith('!');\n }\n\n async function collectAncestorGitignores(startDir: string): Promise<Array<string>> {\n const files: Array<string> = [];\n let dir = startDir;\n while (true) {\n const gi = nodePath.join(dir, GITIGNORE_FILE);\n try {\n const stat = await fs.stat(gi).catch(() => null);\n if (stat?.isFile()) files.push(gi);\n } catch {\n // ignore\n }\n\n if (stopAtGitRoot) {\n try {\n const gitStat = await fs.stat(nodePath.join(dir, '.git')).catch(() => null);\n if (gitStat?.isDirectory()) break;\n } catch {\n // ignore\n }\n }\n\n const parent = nodePath.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // eslint-disable-next-line unicorn/no-array-reverse\n return files.reverse();\n }\n\n async function parseAndResolve(giPath: string): Promise<Array<string>> {\n try {\n const content = (await fs.readFile(giPath, 'utf8'));\n const parsed = ignoreFileParse(content);\n const prefixRel = nodePath.relative(rootDir, nodePath.dirname(giPath));\n return parsed.map((p) => ignoreRuleResolve(prefixRel, p));\n } catch {\n return [];\n }\n }\n\n // --- Build initial patterns from ancestor .gitignore files -------------\n const ancestorFiles = await collectAncestorGitignores(absoluteRootDir);\n const initialPatterns: Array<string> = [];\n for (const gi of ancestorFiles) {\n const parsed = await parseAndResolve(gi);\n if (parsed.length > 0) initialPatterns.push(...parsed);\n found.add(gi);\n }\n\n // --- BFS downward carrying accumulated patterns -----------------------\n const queue: Array<{ depth: number; dir: string; patterns: Array<string> }> = [\n { depth: 0, dir: absoluteRootDir, patterns: [...initialPatterns] },\n ];\n\n while (queue.length > 0) {\n // eslint-disable-next-line ts/no-non-null-assertion\n const { depth, dir: currentDir, patterns } = queue.shift()!;\n if (depth > maxDepth) continue;\n\n let entries;\n try {\n entries = await fs.readdir(currentDir, { withFileTypes: true });\n } catch {\n continue; // unreadable\n }\n\n // If local .gitignore exists, parse and extend patterns\n\n // eslint-disable-next-line unicorn/prefer-array-some\n const local = entries.find((e) => e.isFile() && e.name === GITIGNORE_FILE);\n const combinedPatterns = local ? [...patterns, ...(await parseAndResolve(nodePath.join(currentDir, GITIGNORE_FILE)))] : patterns;\n if (local) found.add(nodePath.join(currentDir, GITIGNORE_FILE));\n\n for (const ent of entries) {\n if (!ent.isDirectory()) continue;\n if (excludeDirs.has(ent.name)) continue;\n const subdir = nodePath.join(currentDir, ent.name);\n const rel = nodePath.relative(rootDir, subdir);\n if (isIgnored(combinedPatterns, rel)) continue;\n queue.push({ depth: depth + 1, dir: subdir, patterns: combinedPatterns });\n }\n }\n\n return [...found].map((p) => nodePath.relative(rootDir, p));\n}\n","import fs from 'node:fs';\nimport nodePath from 'node:path';\nimport process from 'node:process';\n\nimport { defaultIgnores } from './defaultIgnores.js';\nimport { gitModulesIgnore } from './internal/gitModulesIgnore.js';\nimport { ignoreFileFind } from './internal/ignoreFileFind.js';\nimport { ignoreFileParse } from './internal/ignoreFileParse.js';\nimport { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';\n\nexport interface ESLintIgnoreConfig {\n /**\n * The file globs to ignore\n */\n ignores: Array<string>;\n\n /**\n * The configuration name\n */\n name: string;\n}\n\nexport interface ESLintIgnoreOptions {\n /**\n * Override current working directory\n */\n cwd?: string;\n\n /**\n * Whether to ignore git submodules (default: true)\n */\n ignoreGitModules?: boolean;\n\n /**\n * Override or customize ignore patterns.\n * - If passed an array, it appends patterns to the merged ignore list.\n * - If passed a function, it receives the merged list and returns the final array.\n */\n ignores?: ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']) | ESLintIgnoreConfig['ignores'];\n\n /**\n * Override configuration name\n */\n name?: ESLintIgnoreConfig['name'];\n\n /**\n * Include recommended settings and default ignored files\n */\n recommended?: boolean | undefined;\n}\n\n/**\n * Create a new eslint configuration object\n *\n * @example\n * ```ts\n * // eslint.config.js\n * export default [\n * await eslintIgnores({\n * ignores: [\n * // Add custom paths here\n * ]\n * })\n * ];\n * ```\n *\n * @param options\n */\nexport async function eslintIgnores(options: ESLintIgnoreOptions = {}): Promise<ESLintIgnoreConfig> {\n const cwd = options.cwd ?? process.cwd();\n const recommended = options.recommended ?? true;\n const ignoreFilePaths = await ignoreFileFind(cwd);\n const ignoreGlobs = (await Promise.all(ignoreFilePaths.map(async (ignoreFilePathRelative) => {\n const ignoreFilePath = nodePath.join(cwd, ignoreFilePathRelative);\n const ignoreFileContent = String(await fs.promises.readFile(ignoreFilePath));\n const patterns = ignoreFileParse(ignoreFileContent);\n const ignoreDirectoryRelative = nodePath.dirname(ignoreFilePathRelative);\n\n return patterns.map((pattern) => ignoreRuleResolve(ignoreDirectoryRelative, pattern));\n })));\n\n const mergedIgnores = [\n ...(recommended ? defaultIgnores : []),\n ...ignoreGlobs.flat(),\n ];\n\n // Optionally include .gitmodules entries as ignores (each submodule path -> `${path}/**`)\n if (options.ignoreGitModules ?? true) {\n mergedIgnores.push(...await gitModulesIgnore(cwd));\n }\n\n const ignores = typeof options.ignores === 'function'\n ? options.ignores(mergedIgnores)\n : options.ignores\n ? [...mergedIgnores, ...options.ignores]\n : mergedIgnores;\n\n return {\n ignores,\n name: options.name ?? 'w5s/eslint-ignore',\n };\n}\n","export const meta = Object.freeze({\n // @ts-ignore - these variables are injected at build time\n buildNumber: (typeof __PACKAGE_BUILD_NUMBER__ === 'undefined' ? 0 : __PACKAGE_BUILD_NUMBER__) as number,\n // @ts-ignore - these variables are injected at build time\n name: (typeof __PACKAGE_NAME__ === 'undefined' ? '' : __PACKAGE_NAME__) as string,\n // @ts-ignore - these variables are injected at build time\n version: (typeof __PACKAGE_VERSION__ === 'undefined' ? '' : __PACKAGE_VERSION__) as string,\n});\n"],"mappings":";;;;;;;AAAA,MAAa,iBAAiB;CAE5B;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CAGA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CAGA;CAGA;CACA;CACA;CACA;AACF;;;AC5CA,MAAM,oBAAoB;;;;;;;;;;;;AAa1B,eAAsB,iBAAiB,KAAqC;CAC1E,MAAM,SAAS,SAAS,KAAK,KAAK,aAAa;CAC/C,IAAI;EACF,IAAI,OAAO;EACX,IAAI;GACF,OAAO,MAAM,GAAG,SAAS,KAAK,MAAM;EACtC,QAAQ;GACN,OAAO;EACT;EACA,IAAI,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC;EAI7B,OADc,gBAAgB,MADP,GAAG,SAAS,SAAS,QAAQ,MAAM,CAE/C,CAAC,CAAC,KAAK,MAAM,GAAG,EAAE,WAAW,MAAM,GAAG,EAAE,IAAI;CACzD,QAAQ;EACN,OAAO,CAAC;CACV;AACF;;;;;;;;;;;AAYA,SAAgB,gBAAgB,SAAgC;CAC9D,MAAM,QAAuB,CAAC;CAC9B,kBAAkB,YAAY;CAC9B,SAAS;EACP,MAAM,UAAU,kBAAkB,KAAK,OAAO;EAC9C,IAAI,CAAC,SAAS;EACd,MAAM,WAAW,QAAQ;EACzB,IAAI,UAAU,MAAM,KAAK,SAAS,KAAK,CAAC;CAC1C;CACA,OAAO;AACT;;;ACrDA,SAAgB,gBAAgB,OAA8B;CAC5D,OAAO,eAAe,MAAM,KAAK,CAAC,CAAC;AACrC;;;;;;;;;;;;ACKA,SAAgB,gCAAgC,SAAyB;CACvE,MAAM,YAAY,QAAQ,WAAW,GAAG;CACxC,MAAM,gBAAgB,YAAY,MAAM;CACxC,MAAM,iBAAiB,YAAY,QAAQ,MAAM,CAAC,IAAI,QAAA,CAAS,QAAQ;CAGvE,IAAI;EAAC;EAAI;EAAM;EAAO;CAAK,CAAC,CAAC,SAAS,aAAa,GACjD,OAAO,GAAG,gBAAgB;CAG5B,MAAM,oBAAoB,cAAc,QAAQ,GAAG;CAEnD,MAAM,wBAAwB,sBAAsB,MAAM,sBAAsB,cAAc,SAAS,IAAI,QAAQ;CAEnH,MAAM,6BAA6B,sBAAsB,IAAI,cAAc,MAAM,CAAC,IAAI;CAOtF,IAAI,oCAAoC;CACxC,IAAI,YAAY;CAEhB,KAAK,MAAM,QAAQ,4BAA4B;EAC7C,IAAI,CAAC,cAAc,SAAS,OAAO,SAAS,MAC1C,qCAAqC;EAGvC,qCAAqC;EAErC,YAAY,SAAS,OAAO,CAAC,YAAY;CAC3C;CAEA,MAAM,oBAAoB,cAAc,SAAS,KAAK,IAAI,OAAO;CAEjE,OAAO,GAAG,gBAAgB,wBAAwB,oCAAoC;AACxF;;;AC5CA,MAAM,sBAAsB;AAE5B,MAAM,iBAAiB,MAAc,EAAE,WAAW,MAAM,GAAG,CAAC,CAAC,QAAQ,qBAAqB,EAAE;;;;;;;;;;;;;;;;;;;;;AAsB5F,SAAgB,kBAAkB,QAAgB,MAAsB;CACtE,MAAM,UAAU,KAAK,WAAW,GAAG;CACnC,MAAM,MAAM,UAAU,KAAK,MAAM,CAAC,IAAI;CACtC,MAAM,mBAAmB,WAAW,OAAO,WAAW,KAAK,KAAK,cAAc,MAAM;CAEpF,IAAI;CACJ,IAAI,IAAI,WAAW,GAAG,GAIpB,YAAY,gCAAgC,IAH7B,mBACX,GAAG,iBAAiB,GAAG,IAAI,MAAM,CAAC,MAClC,IAAI,MAAM,CAAC,GACyC;MAGxD,aADkB,mBAAmB,GAAG,iBAAiB,KAAK,MACtC,gCAAgC,GAAG;CAG7D,OAAO,UAAU,IAAI,cAAc;AACrC;;;ACnCA,MAAM,iBAAiB;;;;;;;;;;;;AAsBvB,eAAsB,eACpB,SACA,SACwB;CACxB,MAAM,cAAc,IAAI,IAAI,SAAS,eAAe,CAAC,gBAAgB,MAAM,CAAC;CAC5E,MAAM,WAAW,SAAS,YAAY;CACtC,MAAM,gBAAgB,SAAS,iBAAiB;CAEhD,MAAM,kBAAkB,SAAS,QAAQ,OAAO;CAChD,MAAM,wBAAQ,IAAI,IAAY;CAG9B,MAAM,aAAa,MAAc,EAAE,WAAW,MAAM,GAAG;CAEvD,SAAS,mBAAmB,SAAiB,cAA+B;EAC1E,MAAM,gBAAgB,UAAU,YAAY;EAC5C,MAAM,cAAc,UAAU,OAAO;EAErC,IAAI,UAAU,eAAe,aAAa,EAAE,KAAK,KAAK,CAAC,GACrD,OAAO;EAGT,IAAI,UAAU,eAAe,GAAG,YAAY,MAAM,EAAE,KAAK,KAAK,CAAC,GAC7D,OAAO;EAGT,IAAI,YAAY,SAAS,GAAG,GAAG;GAC7B,MAAM,kBAAkB,YAAY,MAAM,GAAG,EAAE;GAC/C,IAAI,UAAU,eAAe,iBAAiB,EAAE,KAAK,KAAK,CAAC,GACzD,OAAO;GAET,IAAI,UAAU,eAAe,GAAG,gBAAgB,MAAM,EAAE,KAAK,KAAK,CAAC,GACjE,OAAO;EAEX;EAEA,OAAO;CACT;CAEA,SAAS,cAAc,UAAyB,cAAqC;EACnF,IAAI,YAA2B;EAC/B,KAAK,MAAM,KAAK,UAAU;GACxB,MAAM,MAAM,EAAE,WAAW,GAAG,IAAI,EAAE,MAAM,CAAC,IAAI;GAC7C,IAAI,CAAC,KAAK;GAEV,IAAI,mBAAmB,KAAK,YAAY,GACtC,YAAY;EAEhB;EACA,OAAO;CACT;CAEA,SAAS,UAAU,UAAyB,cAA+B;EACzE,MAAM,IAAI,cAAc,UAAU,YAAY;EAC9C,IAAI,CAAC,GAAG,OAAO;EACf,OAAO,CAAC,EAAE,WAAW,GAAG;CAC1B;CAEA,eAAe,0BAA0B,UAA0C;EACjF,MAAM,QAAuB,CAAC;EAC9B,IAAI,MAAM;EACV,OAAO,MAAM;GACX,MAAM,KAAK,SAAS,KAAK,KAAK,cAAc;GAC5C,IAAI;IAEF,KAAI,MADeA,KAAG,KAAK,EAAE,CAAC,CAAC,YAAY,IAAI,EAAA,EACrC,OAAO,GAAG,MAAM,KAAK,EAAE;GACnC,QAAQ,CAER;GAEA,IAAI,eACF,IAAI;IAEF,KAAI,MADkBA,KAAG,KAAK,SAAS,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,YAAY,IAAI,EAAA,EAC7D,YAAY,GAAG;GAC9B,QAAQ,CAER;GAGF,MAAM,SAAS,SAAS,QAAQ,GAAG;GACnC,IAAI,WAAW,KAAK;GACpB,MAAM;EACR;EAEA,OAAO,MAAM,QAAQ;CACvB;CAEA,eAAe,gBAAgB,QAAwC;EACrE,IAAI;GAEF,MAAM,SAAS,gBAAgB,MADRA,KAAG,SAAS,QAAQ,MAAM,CACX;GACtC,MAAM,YAAY,SAAS,SAAS,SAAS,SAAS,QAAQ,MAAM,CAAC;GACrE,OAAO,OAAO,KAAK,MAAM,kBAAkB,WAAW,CAAC,CAAC;EAC1D,QAAQ;GACN,OAAO,CAAC;EACV;CACF;CAGA,MAAM,gBAAgB,MAAM,0BAA0B,eAAe;CACrE,MAAM,kBAAiC,CAAC;CACxC,KAAK,MAAM,MAAM,eAAe;EAC9B,MAAM,SAAS,MAAM,gBAAgB,EAAE;EACvC,IAAI,OAAO,SAAS,GAAG,gBAAgB,KAAK,GAAG,MAAM;EACrD,MAAM,IAAI,EAAE;CACd;CAGA,MAAM,QAAwE,CAC5E;EAAE,OAAO;EAAG,KAAK;EAAiB,UAAU,CAAC,GAAG,eAAe;CAAE,CACnE;CAEA,OAAO,MAAM,SAAS,GAAG;EAEvB,MAAM,EAAE,OAAO,KAAK,YAAY,aAAa,MAAM,MAAM;EACzD,IAAI,QAAQ,UAAU;EAEtB,IAAI;EACJ,IAAI;GACF,UAAU,MAAMA,KAAG,QAAQ,YAAY,EAAE,eAAe,KAAK,CAAC;EAChE,QAAQ;GACN;EACF;EAKA,MAAM,QAAQ,QAAQ,MAAM,MAAM,EAAE,OAAO,KAAK,EAAE,SAAS,cAAc;EACzE,MAAM,mBAAmB,QAAQ,CAAC,GAAG,UAAU,GAAI,MAAM,gBAAgB,SAAS,KAAK,YAAY,cAAc,CAAC,CAAE,IAAI;EACxH,IAAI,OAAO,MAAM,IAAI,SAAS,KAAK,YAAY,cAAc,CAAC;EAE9D,KAAK,MAAM,OAAO,SAAS;GACzB,IAAI,CAAC,IAAI,YAAY,GAAG;GACxB,IAAI,YAAY,IAAI,IAAI,IAAI,GAAG;GAC/B,MAAM,SAAS,SAAS,KAAK,YAAY,IAAI,IAAI;GAEjD,IAAI,UAAU,kBADF,SAAS,SAAS,SAAS,MACL,CAAC,GAAG;GACtC,MAAM,KAAK;IAAE,OAAO,QAAQ;IAAG,KAAK;IAAQ,UAAU;GAAiB,CAAC;EAC1E;CACF;CAEA,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,MAAM,SAAS,SAAS,SAAS,CAAC,CAAC;AAC5D;;;;;;;;;;;;;;;;;;;;ACxGA,eAAsB,cAAc,UAA+B,CAAC,GAAgC;CAClG,MAAM,MAAM,QAAQ,OAAO,QAAQ,IAAI;CACvC,MAAM,cAAc,QAAQ,eAAe;CAC3C,MAAM,kBAAkB,MAAM,eAAe,GAAG;CAChD,MAAM,cAAe,MAAM,QAAQ,IAAI,gBAAgB,IAAI,OAAO,2BAA2B;EAC3F,MAAM,iBAAiB,SAAS,KAAK,KAAK,sBAAsB;EAEhE,MAAM,WAAW,gBADS,OAAO,MAAM,GAAG,SAAS,SAAS,cAAc,CACzC,CAAiB;EAClD,MAAM,0BAA0B,SAAS,QAAQ,sBAAsB;EAEvE,OAAO,SAAS,KAAK,YAAY,kBAAkB,yBAAyB,OAAO,CAAC;CACtF,CAAC,CAAC;CAEF,MAAM,gBAAgB,CACpB,GAAI,cAAc,iBAAiB,CAAC,GACpC,GAAG,YAAY,KAAK,CACtB;CAGA,IAAI,QAAQ,oBAAoB,MAC9B,cAAc,KAAK,GAAG,MAAM,iBAAiB,GAAG,CAAC;CASnD,OAAO;EACL,SAPc,OAAO,QAAQ,YAAY,aACvC,QAAQ,QAAQ,aAAa,IAC7B,QAAQ,UACN,CAAC,GAAG,eAAe,GAAG,QAAQ,OAAO,IACrC;EAIJ,MAAM,QAAQ,QAAQ;CACxB;AACF;;;ACrGA,MAAa,OAAO,OAAO,OAAO;CAEhC,aAAA;CAEA,MAAA;CAEA,SAAA;AACF,CAAC"}
1
+ {"version":3,"file":"index.js","names":["fs"],"sources":["../src/defaultIgnores.ts","../src/internal/gitModulesIgnore.ts","../src/internal/ignoreFileParse.ts","../src/internal/convertIgnorePatternToMinimatch.ts","../src/internal/ignoreRuleResolve.ts","../src/internal/ignoreFileFind.ts","../src/eslintIgnores.ts","../src/meta.ts"],"sourcesContent":["export const defaultIgnores = [\n // Lock files\n '**/package-lock.json',\n '**/yarn.lock',\n '**/pnpm-lock.yaml',\n '**/bun.lockb',\n\n // Commonly ignored\n '**/output',\n '**/.output',\n '**/coverage',\n '**/temp',\n '**/.temp',\n '**/tmp',\n '**/.tmp',\n '**/.cache',\n\n // Well known extensions to ignore\n '**/*.min.*',\n '**/*.timestamp-*.mjs',\n\n // Framework specific temporary folder\n '.go/',\n '.pnpm-store/',\n '**/.vitepress/cache',\n '**/.vite-inspect',\n '**/.history',\n '**/.nuxt',\n '**/.next',\n '**/next-env.d.ts',\n '**/.svelte-kit',\n '**/.vercel',\n '**/.idea',\n '**/.yarn',\n '**/__snapshots__/**',\n\n // Generated markdown\n '**/CHANGELOG.md',\n\n // git submodules (makefile-core / makefile-ci)\n '.modules/',\n\n // AI related\n '**/.context',\n '**/.claude',\n '**/.agents',\n '**/.*/skills',\n];\n","import fs from 'node:fs';\nimport nodePath from 'node:path';\n\nconst SUBMODULE_PATH_RE = /path\\s*=\\s*(.+)/g;\n\n/**\n * Read `cwd/.gitmodules` and return ESLint ignore glob patterns for every\n * listed submodule. Returns an empty array when no `.gitmodules` file exists.\n *\n * @param cwd\n * @example\n * ```ts\n * await gitModulesIgnore('/path/to/project');\n * // ['**\\/packages/foo\\/**', '**\\/packages/bar\\/**']\n * ```\n */\nexport async function gitModulesIgnore(cwd: string): Promise<Array<string>> {\n const gmPath = nodePath.join(cwd, '.gitmodules');\n try {\n let stat = null;\n try {\n stat = await fs.promises.stat(gmPath);\n } catch {\n stat = null;\n }\n if (!stat?.isFile()) return [];\n\n const content = (await fs.promises.readFile(gmPath, 'utf8'));\n const paths = gitModulesParse(content);\n return paths.map((p) => `${p.replaceAll('\\\\', '/')}/**`);\n } catch {\n return [];\n }\n}\n\n/**\n * Parse the content of a `.gitmodules` file and return the list of submodule paths.\n *\n * @param content\n * @example\n * ```ts\n * gitModulesParse('[submodule \"foo\"]\\n\\tpath = packages/foo\\n');\n * // ['packages/foo']\n * ```\n */\nexport function gitModulesParse(content: string): Array<string> {\n const paths: Array<string> = [];\n SUBMODULE_PATH_RE.lastIndex = 0;\n for (;;) {\n const matches = SUBMODULE_PATH_RE.exec(content);\n if (!matches) break;\n const captured = matches[1];\n if (captured) paths.push(captured.trim());\n }\n return paths;\n}\n","import parseGitignore from 'parse-gitignore';\n\nexport function ignoreFileParse(input: string): Array<string> {\n return parseGitignore.parse(input).patterns;\n};\n","/**\n * Converts a gitignore-style pattern to an ESLint-compatible minimatch pattern.\n *\n * Ported from `@eslint/config-helpers` (eslint/rewrite).\n *\n * @see https://github.com/eslint/rewrite/blob/main/packages/config-helpers/src/ignore-file.js\n * @param pattern The .eslintignore or .gitignore pattern to convert.\n * @returns The converted minimatch pattern.\n */\nexport function convertIgnorePatternToMinimatch(pattern: string): string {\n const isNegated = pattern.startsWith('!');\n const negatedPrefix = isNegated ? '!' : '';\n const patternToTest = (isNegated ? pattern.slice(1) : pattern).trimEnd();\n\n // special cases\n if (['', '**', '**/', '/**'].includes(patternToTest)) {\n return `${negatedPrefix}${patternToTest}`;\n }\n\n const firstIndexOfSlash = patternToTest.indexOf('/');\n\n const matchEverywherePrefix = firstIndexOfSlash === -1 || firstIndexOfSlash === patternToTest.length - 1 ? '**/' : '';\n\n const patternWithoutLeadingSlash = firstIndexOfSlash === 0 ? patternToTest.slice(1) : patternToTest;\n\n /*\n * Escape `{` and `(` because in gitignore patterns they are just\n * literal characters without any specific syntactic meaning,\n * while in minimatch patterns they can form brace expansion or ext glob syntax.\n */\n let escapedPatternWithoutLeadingSlash = '';\n let isEscaped = false;\n\n for (const char of patternWithoutLeadingSlash) {\n if (!isEscaped && (char === '{' || char === '(')) {\n escapedPatternWithoutLeadingSlash += '\\\\';\n }\n\n escapedPatternWithoutLeadingSlash += char;\n\n isEscaped = char === '\\\\' && !isEscaped;\n }\n\n const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : '';\n\n return `${negatedPrefix}${matchEverywherePrefix}${escapedPatternWithoutLeadingSlash}${matchInsideSuffix}`;\n}\n","import { convertIgnorePatternToMinimatch } from './convertIgnorePatternToMinimatch.js';\n\nconst ROOT_PREFIX_PATTERN = /^\\.\\/?/;\n\nconst normalizePath = (p: string) => p.replaceAll('\\\\', '/').replace(ROOT_PREFIX_PATTERN, '');\n\n/**\n * Resolve a raw ignore rule from a `.gitignore` file into a flat ESLint\n * minimatch glob relative to the configured working directory.\n *\n * @example\n * ```ts\n * import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';\n *\n * ignoreRuleResolve('.', 'out'); // '**\\/out'\n * ignoreRuleResolve('.', '/dist'); // 'dist'\n * ignoreRuleResolve('android', 'build'); // 'android/**\\/build'\n * ignoreRuleResolve('android', '/build'); // 'android/build'\n * ignoreRuleResolve('android', '!build'); // '!android/**\\/build'\n * ```\n *\n * @internal\n * @param prefix A path prefix that points to the directory containing the `.gitignore` file.\n * @param rule The raw ignore rule parsed from `.gitignore`.\n * @returns A normalized ignore pattern relative to the root `cwd`.\n */\nexport function ignoreRuleResolve(prefix: string, rule: string): string {\n const negated = rule.startsWith('!');\n const raw = negated ? rule.slice(1) : rule;\n const normalizedPrefix = prefix === '.' || prefix === '' ? '' : normalizePath(prefix);\n\n let converted: string;\n if (raw.startsWith('/')) {\n const joined = normalizedPrefix\n ? `${normalizedPrefix}/${raw.slice(1)}`\n : raw.slice(1);\n converted = convertIgnorePatternToMinimatch(`/${joined}`);\n } else {\n const dirPrefix = normalizedPrefix ? `${normalizedPrefix}/` : '';\n converted = dirPrefix + convertIgnorePatternToMinimatch(raw);\n }\n\n return negated ? `!${converted}` : converted;\n}\n","/* eslint-disable unicorn/prefer-await */\nimport { minimatch } from 'minimatch';\nimport fs from 'node:fs/promises';\nimport nodePath from 'node:path';\n\nimport { ignoreFileParse } from './ignoreFileParse.js';\nimport { ignoreRuleResolve } from './ignoreRuleResolve.js';\n\nconst GITIGNORE_FILE = '.gitignore';\n\nexport interface IgnoreFileFindOptions {\n /** Directory names to skip when searching downward from `rootDir`. */\n excludeDirs?: Array<string>;\n /** Maximum recursion depth when searching downward. Defaults to 8. */\n maxDepth?: number;\n /** When true (default), stop ancestor traversal when a `.git` directory is found. */\n stopAtGitRoot?: boolean;\n}\n\n/**\n * Find `.gitignore` files relevant to `rootDir`.\n *\n * Behavior:\n * - Searches downwards from `rootDir` (BFS) for `.gitignore` files, skipping `excludeDirs`.\n * - Walks ancestors from `rootDir` up to the filesystem root (and stops at a `.git` folder when `stopAtGitRoot` is true).\n * - Returns relative paths to `rootDir`.\n *\n * @param rootDir\n * @param options\n */\nexport async function ignoreFileFind(\n rootDir: string,\n options?: IgnoreFileFindOptions,\n): Promise<Array<string>> {\n const excludeDirs = new Set(options?.excludeDirs ?? ['node_modules', '.git']);\n const maxDepth = options?.maxDepth ?? 8;\n const stopAtGitRoot = options?.stopAtGitRoot ?? true;\n\n const absoluteRootDir = nodePath.resolve(rootDir);\n const found = new Set<string>();\n\n // --- Helpers (internal, not exported) ---------------------------------\n const normalize = (p: string) => p.replaceAll('\\\\', '/');\n\n function patternMatchesPath(pattern: string, candidateRel: string): boolean {\n const normCandidate = normalize(candidateRel);\n const normPattern = normalize(pattern);\n\n if (minimatch(normCandidate, normPattern, { dot: true })) {\n return true;\n }\n\n if (minimatch(normCandidate, `${normPattern}/**`, { dot: true })) {\n return true;\n }\n\n if (normPattern.endsWith('/')) {\n const withoutTrailing = normPattern.slice(0, -1);\n if (minimatch(normCandidate, withoutTrailing, { dot: true })) {\n return true;\n }\n if (minimatch(normCandidate, `${withoutTrailing}/**`, { dot: true })) {\n return true;\n }\n }\n\n return false;\n }\n\n function lastMatchWins(patterns: Array<string>, candidateRel: string): null | string {\n let lastMatch: null | string = null;\n for (const p of patterns) {\n const pat = p.startsWith('!') ? p.slice(1) : p;\n if (!pat) continue;\n\n if (patternMatchesPath(pat, candidateRel)) {\n lastMatch = p;\n }\n }\n return lastMatch;\n }\n\n function isIgnored(patterns: Array<string>, candidateRel: string): boolean {\n const m = lastMatchWins(patterns, candidateRel);\n return m ? !m.startsWith('!') : false;\n }\n\n async function collectAncestorGitignores(startDir: string): Promise<Array<string>> {\n const files: Array<string> = [];\n let dir = startDir;\n while (true) {\n const gi = nodePath.join(dir, GITIGNORE_FILE);\n try {\n const stat = await fs.stat(gi).catch(() => null);\n if (stat?.isFile()) files.push(gi);\n } catch {\n // ignore\n }\n\n if (stopAtGitRoot) {\n try {\n const gitStat = await fs.stat(nodePath.join(dir, '.git')).catch(() => null);\n if (gitStat?.isDirectory()) break;\n } catch {\n // ignore\n }\n }\n\n const parent = nodePath.dirname(dir);\n if (parent === dir) break;\n dir = parent;\n }\n // eslint-disable-next-line unicorn/no-array-reverse\n return files.reverse();\n }\n\n async function parseAndResolve(giPath: string): Promise<Array<string>> {\n try {\n const content = (await fs.readFile(giPath, 'utf8'));\n const parsed = ignoreFileParse(content);\n const prefixRel = nodePath.relative(rootDir, nodePath.dirname(giPath));\n return parsed.map((p) => ignoreRuleResolve(prefixRel, p));\n } catch {\n return [];\n }\n }\n\n // --- Build initial patterns from ancestor .gitignore files -------------\n const ancestorFiles = await collectAncestorGitignores(absoluteRootDir);\n const initialPatterns: Array<string> = [];\n for (const gi of ancestorFiles) {\n const parsed = await parseAndResolve(gi);\n if (parsed.length > 0) initialPatterns.push(...parsed);\n found.add(gi);\n }\n\n // --- BFS downward carrying accumulated patterns -----------------------\n const queue: Array<{ depth: number; dir: string; patterns: Array<string> }> = [\n { depth: 0, dir: absoluteRootDir, patterns: [...initialPatterns] },\n ];\n\n while (queue.length > 0) {\n // eslint-disable-next-line ts/no-non-null-assertion\n const { depth, dir: currentDir, patterns } = queue.shift()!;\n if (depth > maxDepth) continue;\n\n let entries;\n try {\n entries = await fs.readdir(currentDir, { withFileTypes: true });\n } catch {\n continue; // unreadable\n }\n\n // If local .gitignore exists, parse and extend patterns\n\n // eslint-disable-next-line unicorn/prefer-array-some\n const local = entries.find((e) => e.isFile() && e.name === GITIGNORE_FILE);\n const combinedPatterns = local ? [...patterns, ...(await parseAndResolve(nodePath.join(currentDir, GITIGNORE_FILE)))] : patterns;\n if (local) found.add(nodePath.join(currentDir, GITIGNORE_FILE));\n\n for (const ent of entries) {\n if (!ent.isDirectory()) continue;\n if (excludeDirs.has(ent.name)) continue;\n const subdir = nodePath.join(currentDir, ent.name);\n const rel = nodePath.relative(rootDir, subdir);\n if (isIgnored(combinedPatterns, rel)) continue;\n queue.push({ depth: depth + 1, dir: subdir, patterns: combinedPatterns });\n }\n }\n\n return [...found].map((p) => nodePath.relative(rootDir, p));\n}\n","import fs from 'node:fs';\nimport nodePath from 'node:path';\nimport process from 'node:process';\n\nimport { defaultIgnores } from './defaultIgnores.js';\nimport { gitModulesIgnore } from './internal/gitModulesIgnore.js';\nimport { ignoreFileFind } from './internal/ignoreFileFind.js';\nimport { ignoreFileParse } from './internal/ignoreFileParse.js';\nimport { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';\n\nexport interface ESLintIgnoreConfig {\n /**\n * The file globs to ignore\n */\n ignores: Array<string>;\n\n /**\n * The configuration name\n */\n name: string;\n}\n\nexport interface ESLintIgnoreOptions {\n /**\n * Override current working directory\n */\n cwd?: string;\n\n /**\n * Whether to ignore git submodules (default: true)\n */\n ignoreGitModules?: boolean;\n\n /**\n * Override or customize ignore patterns.\n * - If passed an array, it appends patterns to the merged ignore list.\n * - If passed a function, it receives the merged list and returns the final array.\n */\n ignores?: ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']) | ESLintIgnoreConfig['ignores'];\n\n /**\n * Override the namespace used in the configuration name (default: 'w5s')\n *\n * @example\n * ```ts\n * await eslintIgnores({ namespace: 'custom-name' });// { name: 'custom-name/eslint-ignore', ignores: [...] }\n * ```\n */\n namespace?: string | undefined;\n\n /**\n * Include recommended settings and default ignored files\n */\n recommended?: boolean | undefined;\n}\n\n/**\n * Create a new eslint configuration object\n *\n * @example\n * ```ts\n * // eslint.config.js\n * export default [\n * await eslintIgnores({\n * ignores: [\n * // Add custom paths here\n * ],\n * // namespace: 'custom-name', // Optional namespace override\n * })\n * ];\n * ```\n *\n * @param options\n */\nexport async function eslintIgnores(options: ESLintIgnoreOptions = {}): Promise<ESLintIgnoreConfig> {\n const cwd = options.cwd ?? process.cwd();\n const namespace = options.namespace ?? 'w5s';\n const recommended = options.recommended ?? true;\n const ignoreFilePaths = await ignoreFileFind(cwd);\n const ignoreGlobs = (await Promise.all(ignoreFilePaths.map(async (ignoreFilePathRelative) => {\n const ignoreFilePath = nodePath.join(cwd, ignoreFilePathRelative);\n const ignoreFileContent = String(await fs.promises.readFile(ignoreFilePath));\n const patterns = ignoreFileParse(ignoreFileContent);\n const ignoreDirectoryRelative = nodePath.dirname(ignoreFilePathRelative);\n\n return patterns.map((pattern) => ignoreRuleResolve(ignoreDirectoryRelative, pattern));\n })));\n\n const mergedIgnores = [\n ...(recommended ? defaultIgnores : []),\n ...ignoreGlobs.flat(),\n ];\n\n // Optionally include .gitmodules entries as ignores (each submodule path -> `${path}/**`)\n if (options.ignoreGitModules ?? true) {\n mergedIgnores.push(...await gitModulesIgnore(cwd));\n }\n\n const ignores = typeof options.ignores === 'function'\n ? options.ignores(mergedIgnores)\n : options.ignores\n ? [...mergedIgnores, ...options.ignores]\n : mergedIgnores;\n\n return {\n ignores,\n name: `${namespace}/eslint-ignore`,\n };\n}\n","export const meta = Object.freeze({\n // @ts-ignore - these variables are injected at build time\n buildNumber: (typeof __PACKAGE_BUILD_NUMBER__ === 'undefined' ? 0 : __PACKAGE_BUILD_NUMBER__) as number,\n // @ts-ignore - these variables are injected at build time\n name: (typeof __PACKAGE_NAME__ === 'undefined' ? '' : __PACKAGE_NAME__) as string,\n // @ts-ignore - these variables are injected at build time\n version: (typeof __PACKAGE_VERSION__ === 'undefined' ? '' : __PACKAGE_VERSION__) as string,\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@w5s/eslint-config-ignore",
3
- "version": "1.31.0",
3
+ "version": "1.33.0",
4
4
  "description": "Shared ESLint ignore configuration generator",
5
5
  "keywords": [
6
6
  "eslint",
@@ -59,5 +59,5 @@
59
59
  "publishConfig": {
60
60
  "access": "public"
61
61
  },
62
- "gitHead": "ed181ba68ebff886310db849facb938bb00f61ca"
62
+ "gitHead": "22c5f0c577887c9855d4a6fa3c139e0e36a1bc6a"
63
63
  }
@@ -39,9 +39,14 @@ export interface ESLintIgnoreOptions {
39
39
  ignores?: ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']) | ESLintIgnoreConfig['ignores'];
40
40
 
41
41
  /**
42
- * Override configuration name
42
+ * Override the namespace used in the configuration name (default: 'w5s')
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * await eslintIgnores({ namespace: 'custom-name' });// { name: 'custom-name/eslint-ignore', ignores: [...] }
47
+ * ```
43
48
  */
44
- name?: ESLintIgnoreConfig['name'];
49
+ namespace?: string | undefined;
45
50
 
46
51
  /**
47
52
  * Include recommended settings and default ignored files
@@ -59,7 +64,8 @@ export interface ESLintIgnoreOptions {
59
64
  * await eslintIgnores({
60
65
  * ignores: [
61
66
  * // Add custom paths here
62
- * ]
67
+ * ],
68
+ * // namespace: 'custom-name', // Optional namespace override
63
69
  * })
64
70
  * ];
65
71
  * ```
@@ -68,6 +74,7 @@ export interface ESLintIgnoreOptions {
68
74
  */
69
75
  export async function eslintIgnores(options: ESLintIgnoreOptions = {}): Promise<ESLintIgnoreConfig> {
70
76
  const cwd = options.cwd ?? process.cwd();
77
+ const namespace = options.namespace ?? 'w5s';
71
78
  const recommended = options.recommended ?? true;
72
79
  const ignoreFilePaths = await ignoreFileFind(cwd);
73
80
  const ignoreGlobs = (await Promise.all(ignoreFilePaths.map(async (ignoreFilePathRelative) => {
@@ -97,6 +104,6 @@ export async function eslintIgnores(options: ESLintIgnoreOptions = {}): Promise<
97
104
 
98
105
  return {
99
106
  ignores,
100
- name: options.name ?? 'w5s/eslint-ignore',
107
+ name: `${namespace}/eslint-ignore`,
101
108
  };
102
109
  }
@@ -38,7 +38,7 @@ export function convertIgnorePatternToMinimatch(pattern: string): string {
38
38
 
39
39
  escapedPatternWithoutLeadingSlash += char;
40
40
 
41
- isEscaped = char === '\\' ? !isEscaped : false;
41
+ isEscaped = char === '\\' && !isEscaped;
42
42
  }
43
43
 
44
44
  const matchInsideSuffix = patternToTest.endsWith('/**') ? '/*' : '';
@@ -82,8 +82,7 @@ export async function ignoreFileFind(
82
82
 
83
83
  function isIgnored(patterns: Array<string>, candidateRel: string): boolean {
84
84
  const m = lastMatchWins(patterns, candidateRel);
85
- if (!m) return false;
86
- return !m.startsWith('!');
85
+ return m ? !m.startsWith('!') : false;
87
86
  }
88
87
 
89
88
  async function collectAncestorGitignores(startDir: string): Promise<Array<string>> {