@michaelhelvey/vite-config 1.0.1 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -46,10 +46,7 @@ export default defineConfig({
46
46
  You can import the rule and plugin helpers to build your own lint config:
47
47
 
48
48
  ```ts
49
- import {
50
- rulesForCategory,
51
- pluginsForCategory,
52
- } from "@michaelhelvey/vite-config";
49
+ import { rulesForCategory, pluginsForCategory } from "@michaelhelvey/vite-config";
53
50
 
54
51
  // Get all rules for a preset as { "scope/rule-name": "error" }
55
52
  const rules = rulesForCategory("production_react");
@@ -66,14 +63,12 @@ The full scraped oxlint rule table is available as a separate export:
66
63
  import { RULES } from "@michaelhelvey/vite-config/rules";
67
64
  ```
68
65
 
69
- Each entry includes `scope`, `value`, `category`, `type_aware`, `fix`,
70
- `default`, and `docs_url`.
66
+ Each entry includes `scope`, `value`, `category`, `type_aware`, `fix`, `default`, and `docs_url`.
71
67
 
72
68
  ## Updating rules
73
69
 
74
70
  The rule table in `src/rules.ts` is auto-generated from the
75
- [oxc rules page](https://oxc.rs/docs/guide/usage/linter/rules.html). To refresh
76
- it:
71
+ [oxc rules page](https://oxc.rs/docs/guide/usage/linter/rules.html). To refresh it:
77
72
 
78
73
  ```sh
79
74
  npm run build:generate # runs scripts/scrape-rules.ts
package/dist/index.mjs CHANGED
@@ -100,9 +100,23 @@ const DEFAULT_USER_CONFIG = {
100
100
  useTabs: false
101
101
  },
102
102
  lint: {
103
+ env: {
104
+ browser: true,
105
+ builtin: true,
106
+ es2024: true,
107
+ node: true
108
+ },
103
109
  ignorePatterns: await ignoresFromGitIgnore(),
104
110
  plugins: pluginsForCategory("production_node"),
105
- rules: rulesForCategory("production_node"),
111
+ rules: {
112
+ ...rulesForCategory("production_node"),
113
+ "typescript/consistent-type-imports": ["error", {
114
+ fixStyle: "separate-type-imports",
115
+ prefer: "type-imports"
116
+ }],
117
+ "eslint/no-shadow": "off",
118
+ "typescript/no-unsafe-type-assertion": "off"
119
+ },
106
120
  overrides: [{
107
121
  files: ["**/*.tsx"],
108
122
  plugins: pluginsForCategory("production_react"),
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { UserConfig } from \"vite-plus\";\nimport { RULES } from \"./rules.ts\";\n\ntype OxlintPluginType = (typeof RULES)[number][\"scope\"];\ntype OxlintCategoryType = (typeof RULES)[number][\"category\"];\n\ninterface CustomDefaultsEntry {\n categories: OxlintCategoryType[];\n plugins: OxlintPluginType[];\n}\n\ninterface CustomDefaults {\n production_node: CustomDefaultsEntry;\n production_react: CustomDefaultsEntry;\n test: CustomDefaultsEntry;\n}\n\n/**\n * Mapping from a broad category of code \"e.g. nodejs production code\" to a list of categories and\n * oxlint plugins to enable.\n */\nexport const customOxlintDefaults: CustomDefaults = {\n production_node: {\n categories: [\"correctness\", \"perf\", \"suspicious\"],\n plugins: [\"eslint\", \"oxc\", \"typescript\", \"promise\"],\n },\n production_react: {\n categories: [\"correctness\", \"perf\", \"suspicious\"],\n plugins: [\"eslint\", \"oxc\", \"typescript\", \"promise\", \"react\", \"react-perf\", \"jsx-a11y\"],\n },\n test: {\n categories: [\"correctness\"],\n plugins: [\"eslint\", \"oxc\", \"promise\", \"vitest\"],\n },\n};\n\ntype CustomOxlintCategory = keyof typeof customOxlintDefaults;\n\n/**\n * Finds the root of the git repository, then loads any .gitignore files there, then returns a list\n * of glob patterns from it. Doesn't handle GIT_DIR or worktrees or any weird shit.\n */\nexport const ignoresFromGitIgnore = async (): Promise<string[]> => {\n const gitRoot = await new Promise<string>((resolve, reject) => {\n const cp = spawn(\"git\", [\"rev-parse\", \"--show-toplevel\"], { stdio: \"pipe\" });\n cp.on(\"error\", reject);\n\n cp.stdout?.on(\"data\", (pathBuf: Buffer) => {\n resolve(pathBuf.toString(\"utf-8\").trim());\n });\n });\n\n const gitIgnorePath = path.join(gitRoot, \".gitignore\");\n const gitIgnoreExists = await fs.promises\n .access(gitIgnorePath, fs.constants.R_OK)\n .then(() => true)\n .catch(() => false);\n\n if (gitIgnoreExists) {\n const gitIgnoreContents = await fs.promises.readFile(gitIgnorePath, \"utf-8\");\n return gitIgnoreContents.split(/\\s/);\n }\n\n return [];\n};\n\nexport const pluginsForCategory = (category: CustomOxlintCategory) =>\n customOxlintDefaults[category].plugins;\nexport const rulesForCategory = (category: CustomOxlintCategory) => {\n const rules: Record<string, \"error\"> = {};\n const config = customOxlintDefaults[category];\n\n for (const rule of RULES) {\n if (config.plugins.includes(rule.scope) && config.categories.includes(rule.category)) {\n rules[`${rule.scope}/${rule.value}`] = \"error\";\n }\n }\n\n return rules;\n};\n\nconst DEFAULT_STAGED: UserConfig[\"staged\"] = {\n \"*\": \"vp check --fix\",\n};\n\nconst DEFAULT_FMT: UserConfig[\"fmt\"] = {\n sortImports: {\n customGroups: [\n { groupName: \"builtin\", selector: \"builtin\" },\n { groupName: \"thirdparty\", selector: \"external\" },\n { groupName: \"everything-else\", elementNamePattern: [\"*\"] },\n ],\n newlinesBetween: false,\n sortPackageJson: true,\n },\n printWidth: 100,\n proseWrap: \"always\",\n semi: true,\n singleQuote: false,\n tabWidth: 2,\n trailingComma: \"all\",\n useTabs: false,\n};\n\nconst DEFAULT_LINT: UserConfig[\"lint\"] = {\n ignorePatterns: await ignoresFromGitIgnore(),\n plugins: pluginsForCategory(\"production_node\"),\n rules: rulesForCategory(\"production_node\"),\n overrides: [\n {\n files: [\"**/*.tsx\"],\n plugins: pluginsForCategory(\"production_react\"),\n rules: rulesForCategory(\"production_react\"),\n },\n {\n files: [\"*/*.test.*\"],\n plugins: pluginsForCategory(\"test\"),\n rules: rulesForCategory(\"test\"),\n },\n ],\n options: {\n typeAware: true,\n typeCheck: true,\n },\n};\n\nconst DEFAULT_TEST: UserConfig[\"test\"] = {\n passWithNoTests: true,\n unstubGlobals: true,\n unstubEnvs: true,\n mockReset: true,\n};\n\nconst DEFAULT_USER_CONFIG: UserConfig = {\n staged: DEFAULT_STAGED,\n fmt: DEFAULT_FMT,\n lint: DEFAULT_LINT,\n test: DEFAULT_TEST,\n};\n\nexport default DEFAULT_USER_CONFIG;\n"],"mappings":";;;;;;;;;AAwBA,MAAa,uBAAuC;CAClD,iBAAiB;EACf,YAAY;GAAC;GAAe;GAAQ;GAAa;EACjD,SAAS;GAAC;GAAU;GAAO;GAAc;GAAU;EACpD;CACD,kBAAkB;EAChB,YAAY;GAAC;GAAe;GAAQ;GAAa;EACjD,SAAS;GAAC;GAAU;GAAO;GAAc;GAAW;GAAS;GAAc;GAAW;EACvF;CACD,MAAM;EACJ,YAAY,CAAC,cAAc;EAC3B,SAAS;GAAC;GAAU;GAAO;GAAW;GAAS;EAChD;CACF;;;;;AAQD,MAAa,uBAAuB,YAA+B;CACjE,MAAM,UAAU,MAAM,IAAI,SAAiB,SAAS,WAAW;EAC7D,MAAM,KAAK,MAAM,OAAO,CAAC,aAAa,kBAAkB,EAAE,EAAE,OAAO,QAAQ,CAAC;AAC5E,KAAG,GAAG,SAAS,OAAO;AAEtB,KAAG,QAAQ,GAAG,SAAS,YAAoB;AACzC,WAAQ,QAAQ,SAAS,QAAQ,CAAC,MAAM,CAAC;IACzC;GACF;CAEF,MAAM,gBAAgB,KAAK,KAAK,SAAS,aAAa;AAMtD,KALwB,MAAM,GAAG,SAC9B,OAAO,eAAe,GAAG,UAAU,KAAK,CACxC,WAAW,KAAK,CAChB,YAAY,MAAM,CAInB,SAD0B,MAAM,GAAG,SAAS,SAAS,eAAe,QAAQ,EACnD,MAAM,KAAK;AAGtC,QAAO,EAAE;;AAGX,MAAa,sBAAsB,aACjC,qBAAqB,UAAU;AACjC,MAAa,oBAAoB,aAAmC;CAClE,MAAM,QAAiC,EAAE;CACzC,MAAM,SAAS,qBAAqB;AAEpC,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,QAAQ,SAAS,KAAK,MAAM,IAAI,OAAO,WAAW,SAAS,KAAK,SAAS,CAClF,OAAM,GAAG,KAAK,MAAM,GAAG,KAAK,WAAW;AAI3C,QAAO;;AAuDT,MAAM,sBAAkC;CACtC,QArD2C,EAC3C,KAAK,kBACN;CAoDC,KAlDqC;EACrC,aAAa;GACX,cAAc;IACZ;KAAE,WAAW;KAAW,UAAU;KAAW;IAC7C;KAAE,WAAW;KAAc,UAAU;KAAY;IACjD;KAAE,WAAW;KAAmB,oBAAoB,CAAC,IAAI;KAAE;IAC5D;GACD,iBAAiB;GACjB,iBAAiB;GAClB;EACD,YAAY;EACZ,WAAW;EACX,MAAM;EACN,aAAa;EACb,UAAU;EACV,eAAe;EACf,SAAS;EACV;CAkCC,MAhCuC;EACvC,gBAAgB,MAAM,sBAAsB;EAC5C,SAAS,mBAAmB,kBAAkB;EAC9C,OAAO,iBAAiB,kBAAkB;EAC1C,WAAW,CACT;GACE,OAAO,CAAC,WAAW;GACnB,SAAS,mBAAmB,mBAAmB;GAC/C,OAAO,iBAAiB,mBAAmB;GAC5C,EACD;GACE,OAAO,CAAC,aAAa;GACrB,SAAS,mBAAmB,OAAO;GACnC,OAAO,iBAAiB,OAAO;GAChC,CACF;EACD,SAAS;GACP,WAAW;GACX,WAAW;GACZ;EACF;CAaC,MAXuC;EACvC,iBAAiB;EACjB,eAAe;EACf,YAAY;EACZ,WAAW;EACZ;CAOA"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { spawn } from \"node:child_process\";\nimport fs from \"node:fs\";\nimport path from \"node:path\";\nimport type { UserConfig } from \"vite-plus\";\nimport { RULES } from \"./rules.ts\";\n\ntype OxlintPluginType = (typeof RULES)[number][\"scope\"];\ntype OxlintCategoryType = (typeof RULES)[number][\"category\"];\n\ninterface CustomDefaultsEntry {\n categories: OxlintCategoryType[];\n plugins: OxlintPluginType[];\n}\n\ninterface CustomDefaults {\n production_node: CustomDefaultsEntry;\n production_react: CustomDefaultsEntry;\n test: CustomDefaultsEntry;\n}\n\n/**\n * Mapping from a broad category of code \"e.g. nodejs production code\" to a list of categories and\n * oxlint plugins to enable.\n */\nexport const customOxlintDefaults: CustomDefaults = {\n production_node: {\n categories: [\"correctness\", \"perf\", \"suspicious\"],\n plugins: [\"eslint\", \"oxc\", \"typescript\", \"promise\"],\n },\n production_react: {\n categories: [\"correctness\", \"perf\", \"suspicious\"],\n plugins: [\"eslint\", \"oxc\", \"typescript\", \"promise\", \"react\", \"react-perf\", \"jsx-a11y\"],\n },\n test: {\n categories: [\"correctness\"],\n plugins: [\"eslint\", \"oxc\", \"promise\", \"vitest\"],\n },\n};\n\ntype CustomOxlintCategory = keyof typeof customOxlintDefaults;\n\n/**\n * Finds the root of the git repository, then loads any .gitignore files there, then returns a list\n * of glob patterns from it. Doesn't handle GIT_DIR or worktrees or any weird shit.\n */\nexport const ignoresFromGitIgnore = async (): Promise<string[]> => {\n const gitRoot = await new Promise<string>((resolve, reject) => {\n const cp = spawn(\"git\", [\"rev-parse\", \"--show-toplevel\"], { stdio: \"pipe\" });\n cp.on(\"error\", reject);\n\n cp.stdout?.on(\"data\", (pathBuf: Buffer) => {\n resolve(pathBuf.toString(\"utf-8\").trim());\n });\n });\n\n const gitIgnorePath = path.join(gitRoot, \".gitignore\");\n const gitIgnoreExists = await fs.promises\n .access(gitIgnorePath, fs.constants.R_OK)\n .then(() => true)\n .catch(() => false);\n\n if (gitIgnoreExists) {\n const gitIgnoreContents = await fs.promises.readFile(gitIgnorePath, \"utf-8\");\n return gitIgnoreContents.split(/\\s/);\n }\n\n return [];\n};\n\nexport const pluginsForCategory = (category: CustomOxlintCategory) =>\n customOxlintDefaults[category].plugins;\nexport const rulesForCategory = (category: CustomOxlintCategory) => {\n const rules: Record<string, \"error\"> = {};\n const config = customOxlintDefaults[category];\n\n for (const rule of RULES) {\n if (config.plugins.includes(rule.scope) && config.categories.includes(rule.category)) {\n rules[`${rule.scope}/${rule.value}`] = \"error\";\n }\n }\n\n return rules;\n};\n\nconst DEFAULT_STAGED: UserConfig[\"staged\"] = {\n \"*\": \"vp check --fix\",\n};\n\nconst DEFAULT_FMT: UserConfig[\"fmt\"] = {\n sortImports: {\n customGroups: [\n { groupName: \"builtin\", selector: \"builtin\" },\n { groupName: \"thirdparty\", selector: \"external\" },\n { groupName: \"everything-else\", elementNamePattern: [\"*\"] },\n ],\n newlinesBetween: false,\n sortPackageJson: true,\n },\n printWidth: 100,\n proseWrap: \"always\",\n semi: true,\n singleQuote: false,\n tabWidth: 2,\n trailingComma: \"all\",\n useTabs: false,\n};\n\nconst DEFAULT_LINT: UserConfig[\"lint\"] = {\n env: {\n browser: true,\n builtin: true,\n es2024: true,\n node: true,\n },\n ignorePatterns: await ignoresFromGitIgnore(),\n plugins: pluginsForCategory(\"production_node\"),\n rules: {\n ...rulesForCategory(\"production_node\"),\n \"typescript/consistent-type-imports\": [\n \"error\",\n { fixStyle: \"separate-type-imports\", prefer: \"type-imports\" },\n ],\n \"eslint/no-shadow\": \"off\",\n \"typescript/no-unsafe-type-assertion\": \"off\",\n },\n overrides: [\n {\n files: [\"**/*.tsx\"],\n plugins: pluginsForCategory(\"production_react\"),\n rules: rulesForCategory(\"production_react\"),\n },\n {\n files: [\"*/*.test.*\"],\n plugins: pluginsForCategory(\"test\"),\n rules: rulesForCategory(\"test\"),\n },\n ],\n options: {\n typeAware: true,\n typeCheck: true,\n },\n};\n\nconst DEFAULT_TEST: UserConfig[\"test\"] = {\n passWithNoTests: true,\n unstubGlobals: true,\n unstubEnvs: true,\n mockReset: true,\n};\n\nconst DEFAULT_USER_CONFIG: UserConfig = {\n staged: DEFAULT_STAGED,\n fmt: DEFAULT_FMT,\n lint: DEFAULT_LINT,\n test: DEFAULT_TEST,\n};\n\nexport default DEFAULT_USER_CONFIG;\n"],"mappings":";;;;;;;;;AAwBA,MAAa,uBAAuC;CAClD,iBAAiB;EACf,YAAY;GAAC;GAAe;GAAQ;GAAa;EACjD,SAAS;GAAC;GAAU;GAAO;GAAc;GAAU;EACpD;CACD,kBAAkB;EAChB,YAAY;GAAC;GAAe;GAAQ;GAAa;EACjD,SAAS;GAAC;GAAU;GAAO;GAAc;GAAW;GAAS;GAAc;GAAW;EACvF;CACD,MAAM;EACJ,YAAY,CAAC,cAAc;EAC3B,SAAS;GAAC;GAAU;GAAO;GAAW;GAAS;EAChD;CACF;;;;;AAQD,MAAa,uBAAuB,YAA+B;CACjE,MAAM,UAAU,MAAM,IAAI,SAAiB,SAAS,WAAW;EAC7D,MAAM,KAAK,MAAM,OAAO,CAAC,aAAa,kBAAkB,EAAE,EAAE,OAAO,QAAQ,CAAC;AAC5E,KAAG,GAAG,SAAS,OAAO;AAEtB,KAAG,QAAQ,GAAG,SAAS,YAAoB;AACzC,WAAQ,QAAQ,SAAS,QAAQ,CAAC,MAAM,CAAC;IACzC;GACF;CAEF,MAAM,gBAAgB,KAAK,KAAK,SAAS,aAAa;AAMtD,KALwB,MAAM,GAAG,SAC9B,OAAO,eAAe,GAAG,UAAU,KAAK,CACxC,WAAW,KAAK,CAChB,YAAY,MAAM,CAInB,SAD0B,MAAM,GAAG,SAAS,SAAS,eAAe,QAAQ,EACnD,MAAM,KAAK;AAGtC,QAAO,EAAE;;AAGX,MAAa,sBAAsB,aACjC,qBAAqB,UAAU;AACjC,MAAa,oBAAoB,aAAmC;CAClE,MAAM,QAAiC,EAAE;CACzC,MAAM,SAAS,qBAAqB;AAEpC,MAAK,MAAM,QAAQ,MACjB,KAAI,OAAO,QAAQ,SAAS,KAAK,MAAM,IAAI,OAAO,WAAW,SAAS,KAAK,SAAS,CAClF,OAAM,GAAG,KAAK,MAAM,GAAG,KAAK,WAAW;AAI3C,QAAO;;AAqET,MAAM,sBAAkC;CACtC,QAnE2C,EAC3C,KAAK,kBACN;CAkEC,KAhEqC;EACrC,aAAa;GACX,cAAc;IACZ;KAAE,WAAW;KAAW,UAAU;KAAW;IAC7C;KAAE,WAAW;KAAc,UAAU;KAAY;IACjD;KAAE,WAAW;KAAmB,oBAAoB,CAAC,IAAI;KAAE;IAC5D;GACD,iBAAiB;GACjB,iBAAiB;GAClB;EACD,YAAY;EACZ,WAAW;EACX,MAAM;EACN,aAAa;EACb,UAAU;EACV,eAAe;EACf,SAAS;EACV;CAgDC,MA9CuC;EACvC,KAAK;GACH,SAAS;GACT,SAAS;GACT,QAAQ;GACR,MAAM;GACP;EACD,gBAAgB,MAAM,sBAAsB;EAC5C,SAAS,mBAAmB,kBAAkB;EAC9C,OAAO;GACL,GAAG,iBAAiB,kBAAkB;GACtC,sCAAsC,CACpC,SACA;IAAE,UAAU;IAAyB,QAAQ;IAAgB,CAC9D;GACD,oBAAoB;GACpB,uCAAuC;GACxC;EACD,WAAW,CACT;GACE,OAAO,CAAC,WAAW;GACnB,SAAS,mBAAmB,mBAAmB;GAC/C,OAAO,iBAAiB,mBAAmB;GAC5C,EACD;GACE,OAAO,CAAC,aAAa;GACrB,SAAS,mBAAmB,OAAO;GACnC,OAAO,iBAAiB,OAAO;GAChC,CACF;EACD,SAAS;GACP,WAAW;GACX,WAAW;GACZ;EACF;CAaC,MAXuC;EACvC,iBAAiB;EACjB,eAAe;EACf,YAAY;EACZ,WAAW;EACZ;CAOA"}
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@michaelhelvey/vite-config",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
4
4
  "description": "sane defaults for vite+",
5
5
  "license": "MIT",
6
+ "files": [
7
+ "dist",
8
+ "README.md",
9
+ "package.json"
10
+ ],
6
11
  "type": "module",
7
12
  "exports": {
8
13
  ".": "./dist/index.mjs",
9
14
  "./rules": "./dist/rules.mjs",
10
15
  "./package.json": "./package.json"
11
16
  },
12
- "files": [
13
- "dist",
14
- "README.md",
15
- "package.json"
16
- ],
17
17
  "scripts": {
18
18
  "prepare": "vp config",
19
19
  "prepublish": "bun run build",