@w5s/eslint-config-ignore 1.1.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Julien Polo
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # W5S ESLint ignore configuration _(@w5s/eslint-config-ignore)_
2
+
3
+ [![NPM Version][package-version-svg]][package-url]
4
+ [![License][license-image]][license-url]
5
+
6
+ > Shared ignore configuration generator for ESLint presets.
7
+
8
+ ## Installation
9
+
10
+ ```console
11
+ npm install --save-dev @w5s/eslint-config-ignore
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```ts
17
+ import { ignores } from '@w5s/eslint-config-ignore';
18
+
19
+ export default [ignores()];
20
+ ```
21
+
22
+ ## API
23
+
24
+ - `ignores(options?)`
25
+ - `options.ignores?: string[]`
26
+
27
+ ## License
28
+
29
+ [MIT][license-url]
30
+
31
+ [package-version-svg]: https://img.shields.io/npm/v/@w5s/eslint-config-ignore.svg?style=flat-square
32
+ [package-url]: https://www.npmjs.com/package/@w5s/eslint-config-ignore
33
+ [license-image]: https://img.shields.io/badge/license-MIT-green.svg?style=flat-square
34
+ [license-url]: ../../LICENSE
@@ -0,0 +1,59 @@
1
+ //#region src/meta.d.ts
2
+ declare const meta: Readonly<{
3
+ name: string;
4
+ version: string;
5
+ buildNumber: number;
6
+ }>;
7
+ //#endregion
8
+ //#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
+ interface ESLintIgnoreConfig {
28
+ /**
29
+ * The configuration name
30
+ */
31
+ name: string;
32
+ /**
33
+ * The file globs to ignore
34
+ */
35
+ ignores: Array<string>;
36
+ }
37
+ interface ESLintIgnoreOptions {
38
+ /**
39
+ * Override configuration name
40
+ */
41
+ name?: ESLintIgnoreConfig['name'];
42
+ /**
43
+ * Override current working directory
44
+ */
45
+ cwd?: string;
46
+ /**
47
+ * Override or customize ignore patterns.
48
+ * - If passed an array, it appends patterns to the merged ignore list.
49
+ * - If passed a function, it receives the merged list and returns the final array.
50
+ */
51
+ ignores?: ESLintIgnoreConfig['ignores'] | ((ignores: ESLintIgnoreConfig['ignores']) => ESLintIgnoreConfig['ignores']);
52
+ /**
53
+ * Include recommended settings and default ignored files
54
+ */
55
+ recommended?: boolean | undefined;
56
+ }
57
+ //#endregion
58
+ export { ESLintIgnoreConfig, ESLintIgnoreOptions, type ESLintIgnoreOptions as Options, eslintIgnores as default, eslintIgnores, meta };
59
+ //# sourceMappingURL=index.d.ts.map
package/dist/index.js ADDED
@@ -0,0 +1,128 @@
1
+ import fs from "node:fs";
2
+ import nodePath from "node:path";
3
+ import process from "node:process";
4
+ import parseGitignore from "parse-gitignore";
5
+ import { findUp } from "find-up";
6
+ //#region src/meta.ts
7
+ const meta = Object.freeze({
8
+ name: "@w5s/eslint-config-ignore",
9
+ version: "1.1.0",
10
+ buildNumber: 1
11
+ });
12
+ //#endregion
13
+ //#region src/defaultIgnores.ts
14
+ const defaultIgnores = [
15
+ "**/package-lock.json",
16
+ "**/yarn.lock",
17
+ "**/pnpm-lock.yaml",
18
+ "**/bun.lockb",
19
+ "**/output",
20
+ "**/.output",
21
+ "**/coverage",
22
+ "**/temp",
23
+ "**/.temp",
24
+ "**/tmp",
25
+ "**/.tmp",
26
+ "**/.cache",
27
+ "**/*.min.*",
28
+ "**/*.timestamp-*.mjs",
29
+ ".go/",
30
+ ".pnpm-store/",
31
+ "**/.vitepress/cache",
32
+ "**/.vite-inspect",
33
+ "**/.history",
34
+ "**/.nuxt",
35
+ "**/.next",
36
+ "**/.svelte-kit",
37
+ "**/.vercel",
38
+ "**/.idea",
39
+ "**/.yarn",
40
+ "**/__snapshots__/**",
41
+ ".modules/",
42
+ "**/.context",
43
+ "**/.claude",
44
+ "**/.agents",
45
+ "**/.*/skills"
46
+ ];
47
+ //#endregion
48
+ //#region src/internal/ignoreFileParse.ts
49
+ function ignoreFileParse(input) {
50
+ return parseGitignore.parse(input).patterns;
51
+ }
52
+ //#endregion
53
+ //#region src/internal/ignoreFileFind.ts
54
+ async function ignoreFileFind(cwd) {
55
+ return (await Promise.all([
56
+ findUp(nodePath.join("", ".gitignore"), { cwd }),
57
+ findUp(nodePath.join("android", ".gitignore"), { cwd }),
58
+ findUp(nodePath.join("ios", ".gitignore"), { cwd })
59
+ ])).filter((filePath) => filePath !== void 0).map((filePath) => nodePath.relative(cwd, filePath));
60
+ }
61
+ //#endregion
62
+ //#region src/internal/ignoreRuleResolve.ts
63
+ /**
64
+ * Resolve a raw ignore rule from a `.gitignore` file into a path
65
+ * relative to the configured working directory.
66
+ *
67
+ * @example
68
+ * ```ts
69
+ * import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';
70
+ *
71
+ * ignoreRuleResolve('.', 'dist'); // 'dist'
72
+ * ignoreRuleResolve('.', '/dist'); // 'dist'
73
+ * ignoreRuleResolve('android', 'android-build'); // 'android/android-build'
74
+ * ignoreRuleResolve('android', '!android-build'); // '!android/android-build'
75
+ * ```
76
+ *
77
+ * @internal
78
+ * @param prefix A path prefix that points to the directory containing the `.gitignore` file.
79
+ * @param rule The raw ignore rule parsed from `.gitignore`.
80
+ * @returns A normalized ignore pattern relative to the root `cwd`.
81
+ */
82
+ function ignoreRuleResolve(prefix, rule) {
83
+ const negated = rule.startsWith("!");
84
+ const normalizedPattern = negated ? rule.slice(1) : rule;
85
+ const trimmedPattern = normalizedPattern.startsWith("/") ? normalizedPattern.slice(1) : normalizedPattern;
86
+ const relativeIgnorePath = nodePath.join(prefix, trimmedPattern);
87
+ return negated ? `!${relativeIgnorePath}` : relativeIgnorePath;
88
+ }
89
+ //#endregion
90
+ //#region src/eslintIgnores.ts
91
+ /**
92
+ * Create a new eslint configuration object
93
+ *
94
+ * @example
95
+ * ```ts
96
+ * // eslint.config.js
97
+ * export default [
98
+ * await eslintIgnores({
99
+ * ignores: [
100
+ * // Add custom paths here
101
+ * ]
102
+ * })
103
+ * ];
104
+ * ```
105
+ *
106
+ * @param options
107
+ */
108
+ async function eslintIgnores(options = {}) {
109
+ const cwd = options.cwd ?? process.cwd();
110
+ const recommended = options.recommended ?? true;
111
+ const ignoreFilePaths = await ignoreFileFind(cwd);
112
+ const ignoreGlobs = await Promise.all(ignoreFilePaths.map(async (ignoreFilePathRelative) => {
113
+ const ignoreFilePath = nodePath.join(cwd, ignoreFilePathRelative);
114
+ const patterns = ignoreFileParse(String(await fs.promises.readFile(ignoreFilePath)));
115
+ const ignoreDirectoryRelative = nodePath.dirname(ignoreFilePathRelative);
116
+ return patterns.map((pattern) => ignoreRuleResolve(ignoreDirectoryRelative, pattern));
117
+ }));
118
+ const mergedIgnores = [...recommended ? defaultIgnores : [], ...ignoreGlobs.flat()];
119
+ const ignores = typeof options.ignores === "function" ? options.ignores(mergedIgnores) : options.ignores ? [...mergedIgnores, ...options.ignores] : mergedIgnores;
120
+ return {
121
+ name: options.name ?? "w5s/eslint-ignore",
122
+ ignores
123
+ };
124
+ }
125
+ //#endregion
126
+ export { eslintIgnores as default, eslintIgnores, meta };
127
+
128
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/meta.ts","../src/defaultIgnores.ts","../src/internal/ignoreFileParse.ts","../src/internal/ignoreFileFind.ts","../src/internal/ignoreRuleResolve.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';\nimport { findUp } from 'find-up';\n\nexport async function ignoreFileFind(cwd: string): Promise<Array<string>> {\n const files = await Promise.all(\n [\n findUp(nodePath.join('', '.gitignore'), { cwd }),\n // TODO: refactor as generic exploration\n findUp(nodePath.join('android', '.gitignore'), { cwd }),\n findUp(nodePath.join('ios', '.gitignore'), { cwd }),\n ],\n );\n\n return files\n .filter((filePath): filePath is string => filePath !== undefined)\n .map((filePath) => nodePath.relative(cwd, filePath));\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 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":";;;;;;AAAA,MAAa,OAAO,OAAO,OAAO;CAEhC,MAAA;CAEA,SAAA;CAEA,aAAa;AACf,CAAC;;;ACPD,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;CAGA;CAGA;CACA;CACA;CACA;AACF;;;ACzCA,SAAgB,gBAAgB,OAA8B;CAC5D,OAAO,eAAe,MAAM,KAAK,CAAC,CAAC;AACrC;;;ACDA,eAAsB,eAAe,KAAqC;CAUxE,QAAO,MATa,QAAQ,IAC1B;EACE,OAAO,SAAS,KAAK,IAAI,YAAY,GAAG,EAAE,IAAI,CAAC;EAE/C,OAAO,SAAS,KAAK,WAAW,YAAY,GAAG,EAAE,IAAI,CAAC;EACtD,OAAO,SAAS,KAAK,OAAO,YAAY,GAAG,EAAE,IAAI,CAAC;CACpD,CACF,EAAA,CAGG,QAAQ,aAAiC,aAAa,KAAA,CAAS,CAAC,CAChE,KAAK,aAAa,SAAS,SAAS,KAAK,QAAQ,CAAC;AACvD;;;;;;;;;;;;;;;;;;;;;;ACKA,SAAgB,kBAAkB,QAAgB,MAAc;CAC9D,MAAM,UAAU,KAAK,WAAW,GAAG;CACnC,MAAM,oBAAoB,UAAU,KAAK,MAAM,CAAC,IAAI;CACpD,MAAM,iBAAiB,kBAAkB,WAAW,GAAG,IACnD,kBAAkB,MAAM,CAAC,IACzB;CACJ,MAAM,qBAAqB,SAAS,KAAK,QAAQ,cAAc;CAE/D,OAAO,UAAU,IAAI,uBAAuB;AAC9C;;;;;;;;;;;;;;;;;;;;ACLA,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,CACzB,CAAC;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;CAEA,MAAM,UAAU,OAAO,QAAQ,YAAY,aACvC,QAAQ,QAAQ,aAAa,IAC7B,QAAQ,UACN,CAAC,GAAG,eAAe,GAAG,QAAQ,OAAO,IACrC;CAEN,OAAO;EACL,MAAM,QAAQ,QAAQ;EACtB;CACF;AACF"}
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@w5s/eslint-config-ignore",
3
+ "version": "1.1.0",
4
+ "description": "Shared ESLint ignore configuration generator",
5
+ "keywords": [
6
+ "eslint",
7
+ "config",
8
+ "ignore"
9
+ ],
10
+ "homepage": "https://github.com/w5s/project-config/blob/main/packages/eslint-config-ignore#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/w5s/project-config/issues"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+ssh@github.com:w5s/project-config.git",
17
+ "directory": "packages/eslint-config-ignore"
18
+ },
19
+ "license": "MIT",
20
+ "author": "Julien Polo <julien.polo@gmail.com>",
21
+ "type": "module",
22
+ "exports": {
23
+ ".": {
24
+ "import": {
25
+ "types": "./dist/index.d.ts",
26
+ "default": "./dist/index.js"
27
+ }
28
+ },
29
+ "./dist/*": "./dist/*"
30
+ },
31
+ "files": [
32
+ "dist/",
33
+ "src/",
34
+ "index.js",
35
+ "index.d.ts",
36
+ "!*.d.ts.map",
37
+ "!**/*.spec.*",
38
+ "!**/__tests__/**"
39
+ ],
40
+ "scripts": {
41
+ "postpack": "clean-package restore"
42
+ },
43
+ "dependencies": {
44
+ "find-up": "^8.0.0",
45
+ "parse-gitignore": "^2.0.0"
46
+ },
47
+ "peerDependencies": {
48
+ "eslint": "9.x || 10.x",
49
+ "typescript": "4.x || 5.x || 6.x"
50
+ },
51
+ "peerDependenciesMeta": {
52
+ "eslint": {
53
+ "optional": true
54
+ },
55
+ "typescript": {
56
+ "optional": true
57
+ }
58
+ },
59
+ "engines": {
60
+ "node": ">=22.0.0"
61
+ },
62
+ "publishConfig": {
63
+ "access": "public"
64
+ },
65
+ "sideEffect": false,
66
+ "gitHead": "fc447207d2af5368f809a9a90d0e4056344b812a"
67
+ }
@@ -0,0 +1,44 @@
1
+ export const defaultIgnores = [
2
+ // Lock files
3
+ '**/package-lock.json',
4
+ '**/yarn.lock',
5
+ '**/pnpm-lock.yaml',
6
+ '**/bun.lockb',
7
+
8
+ // Commonly ignored
9
+ '**/output',
10
+ '**/.output',
11
+ '**/coverage',
12
+ '**/temp',
13
+ '**/.temp',
14
+ '**/tmp',
15
+ '**/.tmp',
16
+ '**/.cache',
17
+
18
+ // Well known extensions to ignore
19
+ '**/*.min.*',
20
+ '**/*.timestamp-*.mjs',
21
+
22
+ // Framework specific temporary folder
23
+ '.go/',
24
+ '.pnpm-store/',
25
+ '**/.vitepress/cache',
26
+ '**/.vite-inspect',
27
+ '**/.history',
28
+ '**/.nuxt',
29
+ '**/.next',
30
+ '**/.svelte-kit',
31
+ '**/.vercel',
32
+ '**/.idea',
33
+ '**/.yarn',
34
+ '**/__snapshots__/**',
35
+
36
+ // git submodules (makefile-core / makefile-ci)
37
+ '.modules/',
38
+
39
+ // AI related
40
+ '**/.context',
41
+ '**/.claude',
42
+ '**/.agents',
43
+ '**/.*/skills',
44
+ ];
@@ -0,0 +1,90 @@
1
+ import fs from 'node:fs';
2
+ import nodePath from 'node:path';
3
+ import process from 'node:process';
4
+ import { defaultIgnores } from './defaultIgnores.js';
5
+ import { ignoreFileParse } from './internal/ignoreFileParse.js';
6
+ import { ignoreFileFind } from './internal/ignoreFileFind.js';
7
+ import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';
8
+
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
+ export async function eslintIgnores(options: ESLintIgnoreOptions = {}): Promise<ESLintIgnoreConfig> {
27
+ const cwd = options.cwd ?? process.cwd();
28
+ const recommended = options.recommended ?? true;
29
+ const ignoreFilePaths = await ignoreFileFind(cwd);
30
+ const ignoreGlobs = (await Promise.all(ignoreFilePaths.map(async (ignoreFilePathRelative) => {
31
+ const ignoreFilePath = nodePath.join(cwd, ignoreFilePathRelative);
32
+ const ignoreFileContent = String(await fs.promises.readFile(ignoreFilePath));
33
+ const patterns = ignoreFileParse(ignoreFileContent);
34
+ const ignoreDirectoryRelative = nodePath.dirname(ignoreFilePathRelative);
35
+
36
+ return patterns.map((pattern) => ignoreRuleResolve(ignoreDirectoryRelative, pattern));
37
+ })));
38
+
39
+ const mergedIgnores = [
40
+ ...(recommended ? defaultIgnores : []),
41
+ ...ignoreGlobs.flat(),
42
+ ];
43
+
44
+ const ignores = typeof options.ignores === 'function'
45
+ ? options.ignores(mergedIgnores)
46
+ : options.ignores
47
+ ? [...mergedIgnores, ...options.ignores]
48
+ : mergedIgnores;
49
+
50
+ return {
51
+ name: options.name ?? 'w5s/eslint-ignore',
52
+ ignores,
53
+ };
54
+ }
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 ADDED
@@ -0,0 +1,4 @@
1
+ export * from './meta.js';
2
+ export * from './eslintIgnores.js';
3
+ export type { ESLintIgnoreOptions as Options } from './eslintIgnores.js';
4
+ export { eslintIgnores as default } from './eslintIgnores.js';
@@ -0,0 +1,17 @@
1
+ import nodePath from 'node:path';
2
+ import { findUp } from 'find-up';
3
+
4
+ export async function ignoreFileFind(cwd: string): Promise<Array<string>> {
5
+ const files = await Promise.all(
6
+ [
7
+ findUp(nodePath.join('', '.gitignore'), { cwd }),
8
+ // TODO: refactor as generic exploration
9
+ findUp(nodePath.join('android', '.gitignore'), { cwd }),
10
+ findUp(nodePath.join('ios', '.gitignore'), { cwd }),
11
+ ],
12
+ );
13
+
14
+ return files
15
+ .filter((filePath): filePath is string => filePath !== undefined)
16
+ .map((filePath) => nodePath.relative(cwd, filePath));
17
+ }
@@ -0,0 +1,5 @@
1
+ import parseGitignore from 'parse-gitignore';
2
+
3
+ export function ignoreFileParse(input: string): Array<string> {
4
+ return parseGitignore.parse(input).patterns;
5
+ };
@@ -0,0 +1,31 @@
1
+ import nodePath from 'node:path';
2
+
3
+ /**
4
+ * Resolve a raw ignore rule from a `.gitignore` file into a path
5
+ * relative to the configured working directory.
6
+ *
7
+ * @example
8
+ * ```ts
9
+ * import { ignoreRuleResolve } from './internal/ignoreRuleResolve.js';
10
+ *
11
+ * ignoreRuleResolve('.', 'dist'); // 'dist'
12
+ * ignoreRuleResolve('.', '/dist'); // 'dist'
13
+ * ignoreRuleResolve('android', 'android-build'); // 'android/android-build'
14
+ * ignoreRuleResolve('android', '!android-build'); // '!android/android-build'
15
+ * ```
16
+ *
17
+ * @internal
18
+ * @param prefix A path prefix that points to the directory containing the `.gitignore` file.
19
+ * @param rule The raw ignore rule parsed from `.gitignore`.
20
+ * @returns A normalized ignore pattern relative to the root `cwd`.
21
+ */
22
+ export function ignoreRuleResolve(prefix: string, rule: string) {
23
+ const negated = rule.startsWith('!');
24
+ const normalizedPattern = negated ? rule.slice(1) : rule;
25
+ const trimmedPattern = normalizedPattern.startsWith('/')
26
+ ? normalizedPattern.slice(1)
27
+ : normalizedPattern;
28
+ const relativeIgnorePath = nodePath.join(prefix, trimmedPattern);
29
+
30
+ return negated ? `!${relativeIgnorePath}` : relativeIgnorePath;
31
+ }
package/src/meta.ts ADDED
@@ -0,0 +1,8 @@
1
+ export const meta = Object.freeze({
2
+ // @ts-ignore - these variables are injected at build time
3
+ name: (typeof __PACKAGE_NAME__ === 'undefined' ? '' : __PACKAGE_NAME__) as string,
4
+ // @ts-ignore - these variables are injected at build time
5
+ 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
+ });