routie dev init since i didn't adhere to any proper guidance up until now

This commit is contained in:
2026-04-29 22:27:29 -06:00
commit e1dabb71e2
15301 changed files with 3562618 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Anthony Fu <https://github.com/antfu>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+113
View File
@@ -0,0 +1,113 @@
# eslint-config-flat-gitignore
[![npm version][npm-version-src]][npm-version-href]
[![npm downloads][npm-downloads-src]][npm-downloads-href]
[![bundle][bundle-src]][bundle-href]
[![JSDocs][jsdocs-src]][jsdocs-href]
[![License][license-src]][license-href]
`.gitignore` support for [ESLint Flat Config](https://eslint.org/docs/latest/use/configure/configuration-files-new).
## Usage
```bash
npm i -D eslint-config-flat-gitignore
```
```js
// eslint.config.js
import gitignore from 'eslint-config-flat-gitignore'
export default [
// recommended putting it at the first
gitignore(),
// your other configs here
]
```
By default it will only looks for `.gitignore` but NOT `.eslintignore`, as we would recommended move away from `.eslintignore` to declare directly in `eslint.config.js` for single source of truth. If you still want it, you can pass the `files` option to specify the files to look for.
```js
gitignore({
files: [
'.gitignore',
'.eslintignore',
]
})
```
By default, this plugin throws if any of the ignore files are missing. This can be disabled by passing setting the `strict` option to `false`.
```js
gitignore({
files: [
'.gitignore',
'.eslintignore',
],
strict: false,
})
```
By default, this plugin will try to look up the directory tree and match the first `.gitignore` file. You can disable this by setting the `root` option to `true`, or specify the `files` option to a specific path.
```js
gitignore({
root: true
})
```
If you want to include recursive `.gitignore` files (for example in monorepos), enable the `recursive` option.
```js
gitignore({
recursive: true,
})
```
If you want recursive discovery but need to skip specific directory names, pass an object to `recursive` with `skipDirs`.
```js
gitignore({
recursive: {
// Skip any directory with this name at any depth
skipDirs: ['dist', 'coverage'],
},
})
```
`skipDirs` matches directory names (not paths) and applies in addition to the built-in skipped directories: `.git` and `node_modules`.
This plugin will also automatically detect git submodule file `.gitmodules` and ignore all files under the submodule dirs. If you want to disable or customize this behavior, you can pass the `filesGitModules` option.
<!-- eslint-skip -->
```js
gitignore({
filesGitModules: [], // disable
filesGitModules: ['path/to/.gitmodules'], // customize
})
```
## Sponsors
<p align="center">
<a href="https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg">
<img src='https://cdn.jsdelivr.net/gh/antfu/static/sponsors.svg' alt='Sponsors' />
</a>
</p>
## License
[MIT](./LICENSE) License © 2023-PRESENT [Anthony Fu](https://github.com/antfu)
<!-- Badges -->
[npm-version-src]: https://img.shields.io/npm/v/eslint-config-flat-gitignore?style=flat&colorA=080f12&colorB=1fa669
[npm-version-href]: https://npmjs.com/package/eslint-config-flat-gitignore
[npm-downloads-src]: https://img.shields.io/npm/dm/eslint-config-flat-gitignore?style=flat&colorA=080f12&colorB=1fa669
[npm-downloads-href]: https://npmjs.com/package/eslint-config-flat-gitignore
[bundle-src]: https://img.shields.io/bundlephobia/minzip/eslint-config-flat-gitignore?style=flat&colorA=080f12&colorB=1fa669&label=minzip
[bundle-href]: https://bundlephobia.com/result?p=eslint-config-flat-gitignore
[license-src]: https://img.shields.io/github/license/antfu/eslint-config-flat-gitignore.svg?style=flat&colorA=080f12&colorB=1fa669
[license-href]: https://github.com/antfu/eslint-config-flat-gitignore/blob/main/LICENSE
[jsdocs-src]: https://img.shields.io/badge/jsdocs-reference-080f12?style=flat&colorA=080f12&colorB=1fa669
[jsdocs-href]: https://www.jsdocs.io/package/eslint-config-flat-gitignore
+59
View File
@@ -0,0 +1,59 @@
interface FlatGitignoreOptions {
/**
* Name of the configuration.
* @default 'gitignore'
*/
name?: string;
/**
* Path to `.gitignore` files, or files with compatible formats like `.eslintignore`.
* @default ['.gitignore'] // or findUpSync('.gitignore')
*/
files?: string | string[];
/**
* Path to `.gitmodules` file.
* @default ['.gitmodules'] // or findUpSync('.gitmodules')
*/
filesGitModules?: string | string[];
/**
* Throw an error if gitignore file not found.
* @default true
*/
strict?: boolean;
/**
* Mark the current working directory as the root directory,
* disable searching for `.gitignore` files in parent directories.
*
* This option is not effective when `files` is explicitly specified.
* @default false
*/
root?: boolean;
/**
* Current working directory.
* Used to resolve relative paths.
* @default process.cwd()
*/
cwd?: string;
/**
* Also include recursive `.gitignore` files under `cwd`.
*
* This option is useful for monorepos or projects that keep
* per-folder `.gitignore` files.
*
* Pass `{ skipDirs: ['name'] }` to skip directory names while
* scanning recursively. `skipDirs` matches by directory name at
* any depth (not by path), and is applied in addition to `.git`
* and `node_modules`.
* @default false
*/
recursive?: boolean | {
skipDirs: string[];
};
}
interface FlatConfigItem {
ignores: string[];
name?: string;
}
declare function ignore(options?: FlatGitignoreOptions): FlatConfigItem;
export { ignore as default };
export type { FlatConfigItem, FlatGitignoreOptions };
+145
View File
@@ -0,0 +1,145 @@
import fs from 'node:fs';
import path, { join, resolve, relative, dirname } from 'node:path';
import process from 'node:process';
import { convertIgnorePatternToMinimatch } from '@eslint/compat';
import 'node:fs/promises';
import { fileURLToPath } from 'node:url';
function toArray(array) {
array = array ?? [];
return Array.isArray(array) ? array : [array];
}
const toPath = urlOrPath => urlOrPath instanceof URL ? fileURLToPath(urlOrPath) : urlOrPath;
function findUpSync(name, {
cwd = process.cwd(),
type = 'file',
stopAt,
} = {}) {
let directory = path.resolve(toPath(cwd) ?? '');
const {root} = path.parse(directory);
stopAt = path.resolve(directory, toPath(stopAt) ?? root);
const isAbsoluteName = path.isAbsolute(name);
while (directory) {
const filePath = isAbsoluteName ? name : path.join(directory, name);
try {
const stats = fs.statSync(filePath, {throwIfNoEntry: false});
if ((type === 'file' && stats?.isFile()) || (type === 'directory' && stats?.isDirectory())) {
return filePath;
}
} catch {}
if (directory === stopAt || directory === root) {
break;
}
directory = path.dirname(directory);
}
}
const GITIGNORE = ".gitignore";
const GITMODULES = ".gitmodules";
const RE_NEWLINE = /\r?\n/u;
const RE_PARENT_PATH = /^(?:\.\.\/)+$/;
const RE_PATH_SEP = /[/\\]/;
const RE_SUBMODULE_PATH = /path\s*=\s*(.+)/u;
function ignore(options = {}) {
const ignores = [];
const {
cwd = process.cwd(),
root = false,
recursive = false,
files: _files = root ? GITIGNORE : findUpSync(GITIGNORE, { cwd }) || [],
filesGitModules: _filesGitModules = root ? fs.existsSync(join(cwd, GITMODULES)) ? GITMODULES : [] : findUpSync(GITMODULES, { cwd }) || [],
strict = true
} = options;
const files = new Set(toArray(_files).map((file) => resolve(cwd, file)));
if (recursive) {
const additionalIgnoreDirs = typeof recursive === "boolean" ? [] : recursive.skipDirs;
for (const file of findNestedFiles(cwd, GITIGNORE, additionalIgnoreDirs))
files.add(file);
}
const filesList = [...files];
const filesGitModules = toArray(_filesGitModules).map((file) => resolve(cwd, file));
for (const file of filesList) {
let content = "";
try {
content = fs.readFileSync(file, "utf8");
} catch (error) {
if (strict)
throw error;
continue;
}
const relativePath = relative(cwd, dirname(file)).replaceAll("\\", "/");
const globs = content.split(RE_NEWLINE).filter((line) => line && !line.startsWith("#")).map((line) => convertIgnorePatternToMinimatch(line)).map((glob) => relativeMinimatch(glob, relativePath, cwd)).filter((glob) => glob !== null);
ignores.push(...globs);
}
for (const file of filesGitModules) {
let content = "";
try {
content = fs.readFileSync(file, "utf8");
} catch (error) {
if (strict)
throw error;
continue;
}
const dirs = parseGitSubmodules(content);
ignores.push(...dirs.map((dir) => `${dir}/**`));
}
if (strict && filesList.length === 0)
throw new Error("No .gitignore file found");
return {
name: options.name || "gitignore",
ignores
};
}
function findNestedFiles(cwd, fileName, additionalIgnoreDirs) {
const files = [];
const directoriesToSkip = /* @__PURE__ */ new Set([".git", "node_modules", ...additionalIgnoreDirs]);
const queue = [cwd];
while (queue.length) {
const directory = queue.shift();
const entries = fs.readdirSync(directory, { withFileTypes: true });
for (const entry of entries) {
const absolutePath = join(directory, entry.name);
if (entry.isFile() && entry.name === fileName)
files.push(absolutePath);
if (entry.isDirectory() && !directoriesToSkip.has(entry.name))
queue.push(absolutePath);
}
}
return files;
}
function relativeMinimatch(pattern, relativePath, cwd) {
if (["", ".", "/"].includes(relativePath))
return pattern;
const negated = pattern.startsWith("!") ? "!" : "";
let cleanPattern = negated ? pattern.slice(1) : pattern;
if (!relativePath.endsWith("/"))
relativePath = `${relativePath}/`;
const isParent = relativePath.startsWith("..");
if (!isParent)
return `${negated}${relativePath}${cleanPattern}`;
if (!RE_PARENT_PATH.test(relativePath))
throw new Error("The ignore file location should be either a parent or child directory");
if (cleanPattern.startsWith("**"))
return pattern;
const parents = relative(resolve(cwd, relativePath), cwd).split(RE_PATH_SEP);
while (parents.length && cleanPattern.startsWith(`${parents[0]}/`)) {
cleanPattern = cleanPattern.slice(parents[0].length + 1);
parents.shift();
}
if (cleanPattern.startsWith("**"))
return `${negated}${cleanPattern}`;
if (parents.length === 0)
return `${negated}${cleanPattern}`;
return null;
}
function parseGitSubmodules(content) {
return content.split(RE_NEWLINE).map((line) => RE_SUBMODULE_PATH.exec(line)).filter((match) => match !== null).map((match) => match[1].trim());
}
export { ignore as default };
+67
View File
@@ -0,0 +1,67 @@
{
"name": "eslint-config-flat-gitignore",
"type": "module",
"version": "2.3.0",
"description": ".gitignore support for ESLint Flat Config",
"author": "Anthony Fu <anthonyfu117@hotmail.com>",
"license": "MIT",
"funding": "https://github.com/sponsors/antfu",
"homepage": "https://github.com/antfu/eslint-config-flat-gitignore#readme",
"repository": {
"type": "git",
"url": "git+https://github.com/antfu/eslint-config-flat-gitignore.git"
},
"bugs": "https://github.com/antfu/eslint-config-flat-gitignore/issues",
"keywords": [
"eslint-config",
"eslint-flat-config"
],
"sideEffects": false,
"exports": {
".": "./dist/index.mjs"
},
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"types": "./dist/index.d.mts",
"files": [
"dist"
],
"peerDependencies": {
"eslint": "^9.5.0 || ^10.0.0"
},
"dependencies": {
"@eslint/compat": "^2.0.3"
},
"devDependencies": {
"@antfu/eslint-config": "^7.7.3",
"@antfu/ni": "^30.0.0",
"@antfu/utils": "^9.3.0",
"@types/node": "^25.5.0",
"bumpp": "^11.0.1",
"eslint": "^10.1.0",
"find-up-simple": "^1.0.1",
"lint-staged": "^16.4.0",
"pnpm": "^10.32.1",
"simple-git-hooks": "^2.13.1",
"tsx": "^4.21.0",
"typescript": "^5.9.3",
"unbuild": "^3.6.1",
"vite": "^8.0.2",
"vitest": "^4.1.1"
},
"simple-git-hooks": {
"pre-commit": "pnpm lint-staged"
},
"lint-staged": {
"*": "eslint --fix"
},
"scripts": {
"build": "unbuild",
"dev": "unbuild --stub",
"lint": "eslint .",
"release": "bumpp",
"start": "tsx src/index.ts",
"test": "vitest --pool=forks",
"typecheck": "tsc --noEmit"
}
}