@w5s/eslint-config-ignore 1.2.6 → 1.2.8

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
@@ -1,44 +1,15 @@
1
- //#region src/meta.d.ts
2
- declare const meta: Readonly<{
3
- name: string;
4
- version: string;
5
- buildNumber: number;
6
- }>;
7
- //#endregion
8
1
  //#region src/eslintIgnores.d.ts
9
- /**
10
- * Create a new eslint configuration object
11
- *
12
- * @example
13
- * ```ts
14
- * // eslint.config.js
15
- * export default [
16
- * await eslintIgnores({
17
- * ignores: [
18
- * // Add custom paths here
19
- * ]
20
- * })
21
- * ];
22
- * ```
23
- *
24
- * @param options
25
- */
26
- declare function eslintIgnores(options?: ESLintIgnoreOptions): Promise<ESLintIgnoreConfig>;
27
2
  interface ESLintIgnoreConfig {
28
- /**
29
- * The configuration name
30
- */
31
- name: string;
32
3
  /**
33
4
  * The file globs to ignore
34
5
  */
35
6
  ignores: Array<string>;
36
- }
37
- interface ESLintIgnoreOptions {
38
7
  /**
39
- * Override configuration name
8
+ * The configuration name
40
9
  */
41
- name?: ESLintIgnoreConfig['name'];
10
+ name: string;
11
+ }
12
+ interface ESLintIgnoreOptions {
42
13
  /**
43
14
  * Override current working directory
44
15
  */
@@ -48,12 +19,41 @@ interface ESLintIgnoreOptions {
48
19
  * - If passed an array, it appends patterns to the merged ignore list.
49
20
  * - If passed a function, it receives the merged list and returns the final array.
50
21
  */
51
- ignores?: ESLintIgnoreConfig['ignores'] | ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']);
22
+ ignores?: ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']) | ESLintIgnoreConfig['ignores'];
23
+ /**
24
+ * Override configuration name
25
+ */
26
+ name?: ESLintIgnoreConfig['name'];
52
27
  /**
53
28
  * Include recommended settings and default ignored files
54
29
  */
55
30
  recommended?: boolean | undefined;
56
31
  }
32
+ /**
33
+ * Create a new eslint configuration object
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * // eslint.config.js
38
+ * export default [
39
+ * await eslintIgnores({
40
+ * ignores: [
41
+ * // Add custom paths here
42
+ * ]
43
+ * })
44
+ * ];
45
+ * ```
46
+ *
47
+ * @param options
48
+ */
49
+ declare function eslintIgnores(options?: ESLintIgnoreOptions): Promise<ESLintIgnoreConfig>;
50
+ //#endregion
51
+ //#region src/meta.d.ts
52
+ declare const meta: Readonly<{
53
+ buildNumber: number;
54
+ name: string;
55
+ version: string;
56
+ }>;
57
57
  //#endregion
58
58
  export { ESLintIgnoreConfig, ESLintIgnoreOptions, type ESLintIgnoreOptions as Options, eslintIgnores as default, eslintIgnores, meta };
59
59
  //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -1,15 +1,8 @@
1
1
  import fs from "node:fs";
2
2
  import nodePath from "node:path";
3
3
  import process from "node:process";
4
- import parseGitignore from "parse-gitignore";
5
4
  import fs$1 from "node:fs/promises";
6
- //#region src/meta.ts
7
- const meta = Object.freeze({
8
- name: "@w5s/eslint-config-ignore",
9
- version: "1.2.6",
10
- buildNumber: 1
11
- });
12
- //#endregion
5
+ import parseGitignore from "parse-gitignore";
13
6
  //#region src/defaultIgnores.ts
14
7
  const defaultIgnores = [
15
8
  "**/package-lock.json",
@@ -108,7 +101,8 @@ async function ignoreFileFind(rootDir, options) {
108
101
  const normCandidate = normalize(candidateRel);
109
102
  let lastMatch = null;
110
103
  for (const p of patterns) {
111
- const patNorm = normalize(p.startsWith("!") ? p.slice(1) : p);
104
+ const pat = p.startsWith("!") ? p.slice(1) : p;
105
+ const patNorm = normalize(pat);
112
106
  if (!patNorm) continue;
113
107
  if (normCandidate === patNorm || normCandidate.startsWith(patNorm + "/")) lastMatch = p;
114
108
  }
@@ -155,12 +149,12 @@ async function ignoreFileFind(rootDir, options) {
155
149
  found.add(gi);
156
150
  }
157
151
  const queue = [{
158
- dir: absoluteRootDir,
159
152
  depth: 0,
153
+ dir: absoluteRootDir,
160
154
  patterns: [...initialPatterns]
161
155
  }];
162
156
  while (queue.length > 0) {
163
- const { dir: currentDir, depth, patterns } = queue.shift();
157
+ const { depth, dir: currentDir, patterns } = queue.shift();
164
158
  if (depth > maxDepth) continue;
165
159
  let entries;
166
160
  try {
@@ -177,8 +171,8 @@ async function ignoreFileFind(rootDir, options) {
177
171
  const subdir = nodePath.join(currentDir, ent.name);
178
172
  if (isIgnored(combinedPatterns, nodePath.relative(rootDir, subdir))) continue;
179
173
  queue.push({
180
- dir: subdir,
181
174
  depth: depth + 1,
175
+ dir: subdir,
182
176
  patterns: combinedPatterns
183
177
  });
184
178
  }
@@ -215,13 +209,19 @@ async function eslintIgnores(options = {}) {
215
209
  return patterns.map((pattern) => ignoreRuleResolve(ignoreDirectoryRelative, pattern));
216
210
  }));
217
211
  const mergedIgnores = [...recommended ? defaultIgnores : [], ...ignoreGlobs.flat()];
218
- const ignores = typeof options.ignores === "function" ? options.ignores(mergedIgnores) : options.ignores ? [...mergedIgnores, ...options.ignores] : mergedIgnores;
219
212
  return {
220
- name: options.name ?? "w5s/eslint-ignore",
221
- ignores
213
+ ignores: typeof options.ignores === "function" ? options.ignores(mergedIgnores) : options.ignores ? [...mergedIgnores, ...options.ignores] : mergedIgnores,
214
+ name: options.name ?? "w5s/eslint-ignore"
222
215
  };
223
216
  }
224
217
  //#endregion
218
+ //#region src/meta.ts
219
+ const meta = Object.freeze({
220
+ buildNumber: 1,
221
+ name: "@w5s/eslint-config-ignore",
222
+ version: "1.2.8"
223
+ });
224
+ //#endregion
225
225
  export { eslintIgnores as default, eslintIgnores, meta };
226
226
 
227
227
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["fs"],"sources":["../src/meta.ts","../src/defaultIgnores.ts","../src/internal/ignoreFileParse.ts","../src/internal/ignoreRuleResolve.ts","../src/internal/ignoreFileFind.ts","../src/eslintIgnores.ts"],"sourcesContent":["export const meta = Object.freeze({\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 // @ts-ignore - these variables are injected at build time\n buildNumber: 1 as number, // (typeof __PACKAGE_BUILD_NUMBER__ === 'undefined' ? 0 : __PACKAGE_BUILD_NUMBER__) as number,\n});\n","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 '**/.svelte-kit',\n '**/.vercel',\n '**/.idea',\n '**/.yarn',\n '**/__snapshots__/**',\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 parseGitignore from 'parse-gitignore';\n\nexport function ignoreFileParse(input: string): Array<string> {\n return parseGitignore.parse(input).patterns;\n};\n","import nodePath from 'node:path';\n\n/**\n * Resolve a raw ignore rule from a `.gitignore` file into a path\n * relative to the configured working directory.\n *\n * @example\n * ```ts\n * import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';\n *\n * ignoreRuleResolve('.', 'dist'); // 'dist'\n * ignoreRuleResolve('.', '/dist'); // 'dist'\n * ignoreRuleResolve('android', 'android-build'); // 'android/android-build'\n * ignoreRuleResolve('android', '!android-build'); // '!android/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) {\n const negated = rule.startsWith('!');\n const normalizedPattern = negated ? rule.slice(1) : rule;\n const trimmedPattern = normalizedPattern.startsWith('/')\n ? normalizedPattern.slice(1)\n : normalizedPattern;\n const relativeIgnorePath = nodePath.join(prefix, trimmedPattern);\n\n return negated ? `!${relativeIgnorePath}` : relativeIgnorePath;\n}\n","import nodePath from 'node:path';\nimport fs from 'node:fs/promises';\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?: 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', 'dist', 'build', 'out']);\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 lastMatchWins(patterns: string[], candidateRel: string): string | null {\n const normCandidate = normalize(candidateRel);\n let lastMatch: string | null = null;\n for (const p of patterns) {\n const neg = p.startsWith('!');\n const pat = neg ? p.slice(1) : p;\n const patNorm = normalize(pat);\n if (!patNorm) continue;\n\n if (normCandidate === patNorm || normCandidate.startsWith(patNorm + '/')) {\n lastMatch = p;\n }\n }\n return lastMatch;\n }\n\n function isIgnored(patterns: 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<string[]> {\n const files: 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 && 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 && 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<string[]> {\n try {\n const content = String(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: 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<{ dir: string; depth: number; patterns: string[] }> = [\n { dir: absoluteRootDir, depth: 0, patterns: [...initialPatterns] },\n ];\n\n while (queue.length > 0) {\n // eslint-disable-next-line ts/no-non-null-assertion\n const { dir: currentDir, depth, 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 // 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({ dir: subdir, depth: depth + 1, 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';\nimport { defaultIgnores } from './defaultIgnores.js';\nimport { ignoreFileParse } from './internal/ignoreFileParse.js';\nimport { ignoreFileFind } from './internal/ignoreFileFind.js';\nimport { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';\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 const ignores = typeof options.ignores === 'function'\n ? options.ignores(mergedIgnores)\n : options.ignores\n ? [...mergedIgnores, ...options.ignores]\n : mergedIgnores;\n\n return {\n name: options.name ?? 'w5s/eslint-ignore',\n ignores,\n };\n}\n\nexport interface ESLintIgnoreConfig {\n /**\n * The configuration name\n */\n name: string;\n\n /**\n * The file globs to ignore\n */\n ignores: Array<string>;\n}\n\nexport interface ESLintIgnoreOptions {\n /**\n * Override configuration name\n */\n name?: ESLintIgnoreConfig['name'];\n\n /**\n * Override current working directory\n */\n cwd?: string;\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?: ESLintIgnoreConfig['ignores'] | ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']);\n\n /**\n * Include recommended settings and default ignored files\n */\n recommended?: boolean | undefined;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["fs"],"sources":["../src/defaultIgnores.ts","../src/internal/ignoreFileParse.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 '**/.svelte-kit',\n '**/.vercel',\n '**/.idea',\n '**/.yarn',\n '**/__snapshots__/**',\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 parseGitignore from 'parse-gitignore';\n\nexport function ignoreFileParse(input: string): Array<string> {\n return parseGitignore.parse(input).patterns;\n};\n","import nodePath from 'node:path';\n\n/**\n * Resolve a raw ignore rule from a `.gitignore` file into a path\n * relative to the configured working directory.\n *\n * @example\n * ```ts\n * import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';\n *\n * ignoreRuleResolve('.', 'dist'); // 'dist'\n * ignoreRuleResolve('.', '/dist'); // 'dist'\n * ignoreRuleResolve('android', 'android-build'); // 'android/android-build'\n * ignoreRuleResolve('android', '!android-build'); // '!android/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) {\n const negated = rule.startsWith('!');\n const normalizedPattern = negated ? rule.slice(1) : rule;\n const trimmedPattern = normalizedPattern.startsWith('/')\n ? normalizedPattern.slice(1)\n : normalizedPattern;\n const relativeIgnorePath = nodePath.join(prefix, trimmedPattern);\n\n return negated ? `!${relativeIgnorePath}` : relativeIgnorePath;\n}\n","/* eslint-disable unicorn/prefer-await */\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?: 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', 'dist', 'build', 'out']);\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 lastMatchWins(patterns: string[], candidateRel: string): null | string {\n const normCandidate = normalize(candidateRel);\n let lastMatch: null | string = null;\n for (const p of patterns) {\n const neg = p.startsWith('!');\n const pat = neg ? p.slice(1) : p;\n const patNorm = normalize(pat);\n if (!patNorm) continue;\n\n if (normCandidate === patNorm || normCandidate.startsWith(patNorm + '/')) {\n lastMatch = p;\n }\n }\n return lastMatch;\n }\n\n function isIgnored(patterns: 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<string[]> {\n const files: 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 && 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 && 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<string[]> {\n try {\n const content = String(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: 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: 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 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 { 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 * 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 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: 1 as number, // (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.2.6",
3
+ "version": "1.2.8",
4
4
  "description": "Shared ESLint ignore configuration generator",
5
5
  "keywords": [
6
6
  "eslint",
@@ -58,5 +58,5 @@
58
58
  "access": "public"
59
59
  },
60
60
  "sideEffect": false,
61
- "gitHead": "4cca98f83977b854f9d1d6b2338658aa3104ad0b"
61
+ "gitHead": "e6c63e0164ce2199e59bdca360f4766b6a78584d"
62
62
  }
@@ -1,11 +1,48 @@
1
1
  import fs from 'node:fs';
2
2
  import nodePath from 'node:path';
3
3
  import process from 'node:process';
4
+
4
5
  import { defaultIgnores } from './defaultIgnores.js';
5
- import { ignoreFileParse } from './internal/ignoreFileParse.js';
6
6
  import { ignoreFileFind } from './internal/ignoreFileFind.js';
7
+ import { ignoreFileParse } from './internal/ignoreFileParse.js';
7
8
  import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';
8
9
 
10
+ export interface ESLintIgnoreConfig {
11
+ /**
12
+ * The file globs to ignore
13
+ */
14
+ ignores: Array<string>;
15
+
16
+ /**
17
+ * The configuration name
18
+ */
19
+ name: string;
20
+ }
21
+
22
+ export interface ESLintIgnoreOptions {
23
+ /**
24
+ * Override current working directory
25
+ */
26
+ cwd?: string;
27
+
28
+ /**
29
+ * Override or customize ignore patterns.
30
+ * - If passed an array, it appends patterns to the merged ignore list.
31
+ * - If passed a function, it receives the merged list and returns the final array.
32
+ */
33
+ ignores?: ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']) | ESLintIgnoreConfig['ignores'];
34
+
35
+ /**
36
+ * Override configuration name
37
+ */
38
+ name?: ESLintIgnoreConfig['name'];
39
+
40
+ /**
41
+ * Include recommended settings and default ignored files
42
+ */
43
+ recommended?: boolean | undefined;
44
+ }
45
+
9
46
  /**
10
47
  * Create a new eslint configuration object
11
48
  *
@@ -48,43 +85,7 @@ export async function eslintIgnores(options: ESLintIgnoreOptions = {}): Promise<
48
85
  : mergedIgnores;
49
86
 
50
87
  return {
51
- name: options.name ?? 'w5s/eslint-ignore',
52
88
  ignores,
89
+ name: options.name ?? 'w5s/eslint-ignore',
53
90
  };
54
91
  }
55
-
56
- export interface ESLintIgnoreConfig {
57
- /**
58
- * The configuration name
59
- */
60
- name: string;
61
-
62
- /**
63
- * The file globs to ignore
64
- */
65
- ignores: Array<string>;
66
- }
67
-
68
- export interface ESLintIgnoreOptions {
69
- /**
70
- * Override configuration name
71
- */
72
- name?: ESLintIgnoreConfig['name'];
73
-
74
- /**
75
- * Override current working directory
76
- */
77
- cwd?: string;
78
-
79
- /**
80
- * Override or customize ignore patterns.
81
- * - If passed an array, it appends patterns to the merged ignore list.
82
- * - If passed a function, it receives the merged list and returns the final array.
83
- */
84
- ignores?: ESLintIgnoreConfig['ignores'] | ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']);
85
-
86
- /**
87
- * Include recommended settings and default ignored files
88
- */
89
- recommended?: boolean | undefined;
90
- }
package/src/index.ts CHANGED
@@ -1,4 +1,4 @@
1
- export * from './meta.js';
2
1
  export * from './eslintIgnores.js';
3
2
  export type { ESLintIgnoreOptions as Options } from './eslintIgnores.js';
4
3
  export { eslintIgnores as default } from './eslintIgnores.js';
4
+ export * from './meta.js';
@@ -1,5 +1,7 @@
1
- import nodePath from 'node:path';
1
+ /* eslint-disable unicorn/prefer-await */
2
2
  import fs from 'node:fs/promises';
3
+ import nodePath from 'node:path';
4
+
3
5
  import { ignoreFileParse } from './ignoreFileParse.js';
4
6
  import { ignoreRuleResolve } from './ignoreRuleResolve.js';
5
7
 
@@ -39,9 +41,9 @@ export async function ignoreFileFind(
39
41
  // --- Helpers (internal, not exported) ---------------------------------
40
42
  const normalize = (p: string) => p.replaceAll('\\', '/');
41
43
 
42
- function lastMatchWins(patterns: string[], candidateRel: string): string | null {
44
+ function lastMatchWins(patterns: string[], candidateRel: string): null | string {
43
45
  const normCandidate = normalize(candidateRel);
44
- let lastMatch: string | null = null;
46
+ let lastMatch: null | string = null;
45
47
  for (const p of patterns) {
46
48
  const neg = p.startsWith('!');
47
49
  const pat = neg ? p.slice(1) : p;
@@ -111,13 +113,13 @@ export async function ignoreFileFind(
111
113
  }
112
114
 
113
115
  // --- BFS downward carrying accumulated patterns -----------------------
114
- const queue: Array<{ dir: string; depth: number; patterns: string[] }> = [
115
- { dir: absoluteRootDir, depth: 0, patterns: [...initialPatterns] },
116
+ const queue: Array<{ depth: number; dir: string; patterns: string[] }> = [
117
+ { depth: 0, dir: absoluteRootDir, patterns: [...initialPatterns] },
116
118
  ];
117
119
 
118
120
  while (queue.length > 0) {
119
121
  // eslint-disable-next-line ts/no-non-null-assertion
120
- const { dir: currentDir, depth, patterns } = queue.shift()!;
122
+ const { depth, dir: currentDir, patterns } = queue.shift()!;
121
123
  if (depth > maxDepth) continue;
122
124
 
123
125
  let entries;
@@ -128,7 +130,7 @@ export async function ignoreFileFind(
128
130
  }
129
131
 
130
132
  // If local .gitignore exists, parse and extend patterns
131
- // eslint-disable-next-line unicorn/prefer-array-some
133
+
132
134
  const local = entries.find((e) => e.isFile() && e.name === GITIGNORE_FILE);
133
135
  const combinedPatterns = local ? [...patterns, ...(await parseAndResolve(nodePath.join(currentDir, GITIGNORE_FILE)))] : patterns;
134
136
  if (local) found.add(nodePath.join(currentDir, GITIGNORE_FILE));
@@ -139,7 +141,7 @@ export async function ignoreFileFind(
139
141
  const subdir = nodePath.join(currentDir, ent.name);
140
142
  const rel = nodePath.relative(rootDir, subdir);
141
143
  if (isIgnored(combinedPatterns, rel)) continue;
142
- queue.push({ dir: subdir, depth: depth + 1, patterns: combinedPatterns });
144
+ queue.push({ depth: depth + 1, dir: subdir, patterns: combinedPatterns });
143
145
  }
144
146
  }
145
147
 
package/src/meta.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export const meta = Object.freeze({
2
+ // @ts-ignore - these variables are injected at build time
3
+ buildNumber: 1 as number, // (typeof __PACKAGE_BUILD_NUMBER__ === 'undefined' ? 0 : __PACKAGE_BUILD_NUMBER__) as number,
2
4
  // @ts-ignore - these variables are injected at build time
3
5
  name: (typeof __PACKAGE_NAME__ === 'undefined' ? '' : __PACKAGE_NAME__) as string,
4
6
  // @ts-ignore - these variables are injected at build time
5
7
  version: (typeof __PACKAGE_VERSION__ === 'undefined' ? '' : __PACKAGE_VERSION__) as string,
6
- // @ts-ignore - these variables are injected at build time
7
- buildNumber: 1 as number, // (typeof __PACKAGE_BUILD_NUMBER__ === 'undefined' ? 0 : __PACKAGE_BUILD_NUMBER__) as number,
8
8
  });