@stll/oxlint-config 0.6.0 → 0.8.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.cjs +26 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +47 -2
- package/dist/index.d.mts +47 -2
- package/dist/index.mjs +26 -2
- package/dist/index.mjs.map +1 -1
- package/dist/toolchain-check-cli.cjs +214 -0
- package/dist/toolchain-check-cli.cjs.map +1 -0
- package/dist/toolchain-check-cli.d.cts +1 -0
- package/dist/toolchain-check-cli.d.mts +1 -0
- package/dist/toolchain-check-cli.mjs +191 -0
- package/dist/toolchain-check-cli.mjs.map +1 -0
- package/package.json +10 -5
- package/toolchain.json +32 -0
package/dist/index.cjs
CHANGED
|
@@ -20,6 +20,30 @@ const libraryPlugins = [
|
|
|
20
20
|
"promise",
|
|
21
21
|
"react"
|
|
22
22
|
];
|
|
23
|
+
const reactCompilerRules = {
|
|
24
|
+
"react/capitalized-calls": "error",
|
|
25
|
+
"react/error-boundaries": "error",
|
|
26
|
+
"react/exhaustive-effect-dependencies": "error",
|
|
27
|
+
"react/globals": "error",
|
|
28
|
+
"react/hooks": "error",
|
|
29
|
+
"react/immutability": "error",
|
|
30
|
+
"react/incompatible-library": "error",
|
|
31
|
+
"react/invariant": "off",
|
|
32
|
+
"react/memo-dependencies": "error",
|
|
33
|
+
"react/no-deriving-state-in-effects": "error",
|
|
34
|
+
"react/preserve-manual-memoization": "error",
|
|
35
|
+
"react/purity": "error",
|
|
36
|
+
"react/refs": "error",
|
|
37
|
+
"react/rule-suppression": "error",
|
|
38
|
+
"react/set-state-in-effect": "error",
|
|
39
|
+
"react/set-state-in-render": "error",
|
|
40
|
+
"react/static-components": "error",
|
|
41
|
+
"react/syntax": "error",
|
|
42
|
+
"react/todo": "off",
|
|
43
|
+
"react/unsupported-syntax": "error",
|
|
44
|
+
"react/use-memo": "error",
|
|
45
|
+
"react/void-use-memo": "error"
|
|
46
|
+
};
|
|
23
47
|
const libraryRules = {
|
|
24
48
|
"no-console": "off",
|
|
25
49
|
"no-shadow": "error",
|
|
@@ -98,7 +122,7 @@ const libraryRules = {
|
|
|
98
122
|
"react/no-unsafe": "off",
|
|
99
123
|
"react/no-will-update-set-state": "off",
|
|
100
124
|
"react/void-dom-elements-no-children": "off",
|
|
101
|
-
|
|
125
|
+
...reactCompilerRules,
|
|
102
126
|
"sort-keys": "off",
|
|
103
127
|
"no-plusplus": "off",
|
|
104
128
|
"no-inline-comments": "off",
|
|
@@ -158,6 +182,7 @@ exports.libraryOverrides = libraryOverrides;
|
|
|
158
182
|
exports.libraryPlugins = libraryPlugins;
|
|
159
183
|
exports.libraryRules = libraryRules;
|
|
160
184
|
exports.noRawColorsPluginSpecifier = noRawColorsPluginSpecifier;
|
|
185
|
+
exports.reactCompilerRules = reactCompilerRules;
|
|
161
186
|
exports.stellaLowercasePluginSpecifier = stellaLowercasePluginSpecifier;
|
|
162
187
|
|
|
163
188
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { defineConfig, type OxlintConfig, type OxlintOverride } from \"oxlint\";\n\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Options = NonNullable<OxlintConfig[\"options\"]>;\ntype Plugins = NonNullable<OxlintConfig[\"plugins\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\n plugins?: Plugins;\n rules?: Rules;\n};\n\nexport const stellaLowercasePluginSpecifier = \"@stll/oxlint-config/plugin\";\nexport const noRawColorsPluginSpecifier = \"@stll/oxlint-config/no-raw-colors\";\n\nexport const libraryIgnorePatterns = [\"node_modules/\", \"dist/\", \"coverage/\"];\n\n// Setting oxlint's `plugins` config replaces its built-in default list rather\n// than appending to it. This must stay in sync with every plugin-prefixed\n// rule below: `import/*` and `promise/*` rules are configured further down,\n// but oxlint disables both plugins unless they are listed here, which left\n// `import/no-cycle` and every `promise/*` rule silently unenforced. `react`\n// is enabled for `react/react-compiler`; see the comment on that rule for\n// why every other `react/*` rule is explicitly turned back off below.\nexport const libraryPlugins = [\n \"eslint\",\n \"typescript\",\n \"unicorn\",\n \"oxc\",\n \"import\",\n \"promise\",\n \"react\",\n] satisfies Plugins;\n\nexport const libraryRules = {\n \"no-console\": \"off\",\n \"no-shadow\": \"error\",\n \"require-await\": \"error\",\n \"no-useless-catch\": \"error\",\n \"no-non-null-assertion\": \"error\",\n \"no-useless-assignment\": \"error\",\n \"no-loop-func\": \"error\",\n \"no-nested-ternary\": \"error\",\n \"no-void\": [\"error\", { allowAsStatement: true }],\n // Callback expressions should stay lexically scoped; avoids accidental `this` rebinding.\n \"prefer-arrow-callback\": \"error\",\n \"stella-lowercase/stella-lowercase\": \"error\",\n \"no-raw-colors/no-raw-colors\": \"error\",\n\n // Spreading into an accumulator on every loop iteration is O(n^2); push/concat instead.\n \"oxc/no-accumulating-spread\": \"error\",\n // Spreading inside `.map()` allocates a new array per callback invocation; push instead.\n \"oxc/no-map-spread\": \"error\",\n // Flags `if`/`switch` branches with identical bodies: likely dead logic or a missed merge.\n \"oxc/branches-sharing-code\": \"error\",\n\n \"typescript/no-explicit-any\": \"error\",\n \"typescript/no-dynamic-delete\": \"error\",\n \"typescript/no-misused-promises\": [\n \"error\",\n { checksVoidReturn: { attributes: false } },\n ],\n \"typescript/consistent-type-definitions\": [\"error\", \"type\"],\n \"typescript/consistent-return\": \"error\",\n \"typescript/dot-notation\": \"error\",\n \"typescript/no-inferrable-types\": \"off\",\n \"typescript/no-unnecessary-type-conversion\": \"error\",\n \"typescript/no-unnecessary-condition\": [\n \"error\",\n { allowConstantLoopConditions: \"only-allowed-literals\" },\n ],\n \"typescript/no-unnecessary-type-arguments\": \"error\",\n \"typescript/switch-exhaustiveness-check\": [\n \"error\",\n { considerDefaultExhaustiveForUnions: true },\n ],\n \"typescript/strict-boolean-expressions\": [\n \"error\",\n { allowNullableString: true, allowNullableBoolean: true },\n ],\n \"typescript/no-confusing-void-expression\": [\n \"error\",\n { ignoreArrowShorthand: true, ignoreVoidReturningFunctions: true },\n ],\n \"typescript/prefer-nullish-coalescing\": [\n \"error\",\n { ignorePrimitives: { string: true, boolean: true } },\n ],\n \"typescript/only-throw-error\": \"error\",\n \"typescript/return-await\": [\"error\", \"error-handling-correctness-only\"],\n\n \"unicorn/no-useless-undefined\": \"off\",\n \"unicorn/prefer-array-find\": \"error\",\n \"unicorn/prefer-at\": \"error\",\n \"unicorn/prefer-set-has\": \"error\",\n \"unicorn/filename-case\": \"off\",\n \"unicorn/consistent-function-scoping\": \"off\",\n \"unicorn/prefer-ternary\": \"off\",\n \"unicorn/no-array-reduce\": \"error\",\n \"unicorn/no-nested-ternary\": \"off\",\n // `Array.from({ length }).fill(obj)` shares one reference across every slot.\n \"unicorn/no-array-fill-with-reference-type\": \"error\",\n\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\n // Keep a blank line after the import block so it stays visually separate from module body.\n \"import/newline-after-import\": \"error\",\n\n \"promise/always-return\": \"error\",\n \"promise/no-return-in-finally\": \"error\",\n \"promise/prefer-await-to-then\": \"off\",\n \"promise/prefer-await-to-callbacks\": \"off\",\n \"promise/avoid-new\": \"off\",\n\n // Enabling the `react` plugin (above) turns on its whole correctness-category\n // rule set at \"warn\" by default, not just react-compiler. Only react-compiler\n // is a deliberate addition here, so the rest are turned off to keep this\n // package's blast radius scoped to the one rule being added; lift any of\n // these independently if a future change wants them.\n \"react/exhaustive-deps\": \"off\",\n \"react/forward-ref-uses-ref\": \"off\",\n \"react/jsx-key\": \"off\",\n \"react/jsx-no-duplicate-props\": \"off\",\n \"react/jsx-no-undef\": \"off\",\n \"react/jsx-props-no-spread-multi\": \"off\",\n \"react/no-children-prop\": \"off\",\n \"react/no-danger-with-children\": \"off\",\n \"react/no-did-mount-set-state\": \"off\",\n \"react/no-did-update-set-state\": \"off\",\n \"react/no-direct-mutation-state\": \"off\",\n \"react/no-find-dom-node\": \"off\",\n \"react/no-is-mounted\": \"off\",\n \"react/no-render-return-value\": \"off\",\n \"react/no-string-refs\": \"off\",\n \"react/no-this-in-sfc\": \"off\",\n \"react/no-unsafe\": \"off\",\n \"react/no-will-update-set-state\": \"off\",\n \"react/void-dom-elements-no-children\": \"off\",\n // Requires oxlint >= 1.70. Nursery rule upstream: flags violations of the\n // Rules of React that block compiler memoization; diagnostics may shift\n // between oxlint minors, so re-audit findings after bumping the oxlint\n // devDependency. oxlint has no bulk-suppression/baseline mechanism as of\n // 1.72.0 (oxc-project/oxc#10549 tracks the upstream feature request and is\n // still open); consumers adopting this against an existing findings\n // backlog should carve out temporary `overrides` entries per legacy path\n // (or per rule, at `\"off\"`) and fix forward, rather than expecting a\n // generated suppression file.\n \"react/react-compiler\": \"error\",\n\n \"sort-keys\": \"off\",\n \"no-plusplus\": \"off\",\n \"no-inline-comments\": \"off\",\n \"max-statements\": \"off\",\n \"prefer-destructuring\": \"off\",\n \"no-negated-condition\": \"off\",\n \"no-use-before-define\": \"off\",\n \"no-useless-return\": \"off\",\n \"no-warning-comments\": \"off\",\n \"no-unexpected-multiline\": \"off\",\n \"max-classes-per-file\": \"off\",\n \"class-methods-use-this\": \"off\",\n \"no-unmodified-loop-condition\": \"off\",\n complexity: \"off\",\n \"func-style\": \"off\",\n \"func-names\": \"off\",\n \"default-case\": \"off\",\n} satisfies Rules;\n\nexport const libraryOverrides = [\n {\n files: [\"**/*.{test,spec}.{ts,tsx,js,jsx}\", \"__test__/**\", \"__tests__/**\"],\n rules: {\n \"no-console\": \"off\",\n \"require-await\": \"off\",\n \"no-non-null-assertion\": \"off\",\n },\n },\n] satisfies OxlintOverride[];\n\nexport const library = (options: LibraryOptions = {}): OxlintConfig =>\n defineConfig({\n options: {\n denyWarnings: true,\n reportUnusedDisableDirectives: \"error\",\n typeAware: true,\n ...options.options,\n },\n plugins: Array.from(\n new Set([...libraryPlugins, ...(options.plugins ?? [])]),\n ),\n jsPlugins: [\n stellaLowercasePluginSpecifier,\n noRawColorsPluginSpecifier,\n ...(options.jsPlugins ?? []),\n ],\n ignorePatterns: [\n ...libraryIgnorePatterns,\n ...(options.ignorePatterns ?? []),\n ],\n rules: {\n ...libraryRules,\n ...options.rules,\n },\n overrides: [...libraryOverrides, ...(options.overrides ?? [])],\n });\n\nexport default library();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { defineConfig, type OxlintConfig, type OxlintOverride } from \"oxlint\";\n\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Options = NonNullable<OxlintConfig[\"options\"]>;\ntype Plugins = NonNullable<OxlintConfig[\"plugins\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\n plugins?: Plugins;\n rules?: Rules;\n};\n\nexport const stellaLowercasePluginSpecifier = \"@stll/oxlint-config/plugin\";\nexport const noRawColorsPluginSpecifier = \"@stll/oxlint-config/no-raw-colors\";\n\nexport const libraryIgnorePatterns = [\"node_modules/\", \"dist/\", \"coverage/\"];\n\n// Setting oxlint's `plugins` config replaces its built-in default list rather\n// than appending to it. This must stay in sync with every plugin-prefixed\n// rule below: `import/*` and `promise/*` rules are configured further down,\n// but oxlint disables both plugins unless they are listed here, which left\n// `import/no-cycle` and every `promise/*` rule silently unenforced. `react`\n// is enabled for the React Compiler category rules; see the comment on that\n// ruleset for why every other `react/*` rule is explicitly turned back off.\nexport const libraryPlugins = [\n \"eslint\",\n \"typescript\",\n \"unicorn\",\n \"oxc\",\n \"import\",\n \"promise\",\n \"react\",\n] satisfies Plugins;\n\n// Oxlint 1.80 replaced react/react-compiler with category-specific rules.\n// Keep the actionable compiler diagnostics strict while excluding internal\n// invariant and unfinished-feature reports that do not identify source bugs.\nexport const reactCompilerRules = {\n \"react/capitalized-calls\": \"error\",\n \"react/error-boundaries\": \"error\",\n \"react/exhaustive-effect-dependencies\": \"error\",\n \"react/globals\": \"error\",\n \"react/hooks\": \"error\",\n \"react/immutability\": \"error\",\n \"react/incompatible-library\": \"error\",\n \"react/invariant\": \"off\",\n \"react/memo-dependencies\": \"error\",\n \"react/no-deriving-state-in-effects\": \"error\",\n \"react/preserve-manual-memoization\": \"error\",\n \"react/purity\": \"error\",\n \"react/refs\": \"error\",\n \"react/rule-suppression\": \"error\",\n \"react/set-state-in-effect\": \"error\",\n \"react/set-state-in-render\": \"error\",\n \"react/static-components\": \"error\",\n \"react/syntax\": \"error\",\n \"react/todo\": \"off\",\n \"react/unsupported-syntax\": \"error\",\n \"react/use-memo\": \"error\",\n \"react/void-use-memo\": \"error\",\n} satisfies Rules;\n\nexport const libraryRules = {\n \"no-console\": \"off\",\n \"no-shadow\": \"error\",\n \"require-await\": \"error\",\n \"no-useless-catch\": \"error\",\n \"no-non-null-assertion\": \"error\",\n \"no-useless-assignment\": \"error\",\n \"no-loop-func\": \"error\",\n \"no-nested-ternary\": \"error\",\n \"no-void\": [\"error\", { allowAsStatement: true }],\n // Callback expressions should stay lexically scoped; avoids accidental `this` rebinding.\n \"prefer-arrow-callback\": \"error\",\n \"stella-lowercase/stella-lowercase\": \"error\",\n \"no-raw-colors/no-raw-colors\": \"error\",\n\n // Spreading into an accumulator on every loop iteration is O(n^2); push/concat instead.\n \"oxc/no-accumulating-spread\": \"error\",\n // Spreading inside `.map()` allocates a new array per callback invocation; push instead.\n \"oxc/no-map-spread\": \"error\",\n // Flags `if`/`switch` branches with identical bodies: likely dead logic or a missed merge.\n \"oxc/branches-sharing-code\": \"error\",\n\n \"typescript/no-explicit-any\": \"error\",\n \"typescript/no-dynamic-delete\": \"error\",\n \"typescript/no-misused-promises\": [\n \"error\",\n { checksVoidReturn: { attributes: false } },\n ],\n \"typescript/consistent-type-definitions\": [\"error\", \"type\"],\n \"typescript/consistent-return\": \"error\",\n \"typescript/dot-notation\": \"error\",\n \"typescript/no-inferrable-types\": \"off\",\n \"typescript/no-unnecessary-type-conversion\": \"error\",\n \"typescript/no-unnecessary-condition\": [\n \"error\",\n { allowConstantLoopConditions: \"only-allowed-literals\" },\n ],\n \"typescript/no-unnecessary-type-arguments\": \"error\",\n \"typescript/switch-exhaustiveness-check\": [\n \"error\",\n { considerDefaultExhaustiveForUnions: true },\n ],\n \"typescript/strict-boolean-expressions\": [\n \"error\",\n { allowNullableString: true, allowNullableBoolean: true },\n ],\n \"typescript/no-confusing-void-expression\": [\n \"error\",\n { ignoreArrowShorthand: true, ignoreVoidReturningFunctions: true },\n ],\n \"typescript/prefer-nullish-coalescing\": [\n \"error\",\n { ignorePrimitives: { string: true, boolean: true } },\n ],\n \"typescript/only-throw-error\": \"error\",\n \"typescript/return-await\": [\"error\", \"error-handling-correctness-only\"],\n\n \"unicorn/no-useless-undefined\": \"off\",\n \"unicorn/prefer-array-find\": \"error\",\n \"unicorn/prefer-at\": \"error\",\n \"unicorn/prefer-set-has\": \"error\",\n \"unicorn/filename-case\": \"off\",\n \"unicorn/consistent-function-scoping\": \"off\",\n \"unicorn/prefer-ternary\": \"off\",\n \"unicorn/no-array-reduce\": \"error\",\n \"unicorn/no-nested-ternary\": \"off\",\n // `Array.from({ length }).fill(obj)` shares one reference across every slot.\n \"unicorn/no-array-fill-with-reference-type\": \"error\",\n\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\n // Keep a blank line after the import block so it stays visually separate from module body.\n \"import/newline-after-import\": \"error\",\n\n \"promise/always-return\": \"error\",\n \"promise/no-return-in-finally\": \"error\",\n \"promise/prefer-await-to-then\": \"off\",\n \"promise/prefer-await-to-callbacks\": \"off\",\n \"promise/avoid-new\": \"off\",\n\n // Enabling the `react` plugin (above) turns on its whole correctness-category\n // rule set at \"warn\" by default, not just the React Compiler categories.\n // Only the compiler categories are deliberate additions here, so the rest\n // are turned off to keep this package's blast radius scoped; lift any of\n // these independently if a future change wants them.\n \"react/exhaustive-deps\": \"off\",\n \"react/forward-ref-uses-ref\": \"off\",\n \"react/jsx-key\": \"off\",\n \"react/jsx-no-duplicate-props\": \"off\",\n \"react/jsx-no-undef\": \"off\",\n \"react/jsx-props-no-spread-multi\": \"off\",\n \"react/no-children-prop\": \"off\",\n \"react/no-danger-with-children\": \"off\",\n \"react/no-did-mount-set-state\": \"off\",\n \"react/no-did-update-set-state\": \"off\",\n \"react/no-direct-mutation-state\": \"off\",\n \"react/no-find-dom-node\": \"off\",\n \"react/no-is-mounted\": \"off\",\n \"react/no-render-return-value\": \"off\",\n \"react/no-string-refs\": \"off\",\n \"react/no-this-in-sfc\": \"off\",\n \"react/no-unsafe\": \"off\",\n \"react/no-will-update-set-state\": \"off\",\n \"react/void-dom-elements-no-children\": \"off\",\n ...reactCompilerRules,\n\n \"sort-keys\": \"off\",\n \"no-plusplus\": \"off\",\n \"no-inline-comments\": \"off\",\n \"max-statements\": \"off\",\n \"prefer-destructuring\": \"off\",\n \"no-negated-condition\": \"off\",\n \"no-use-before-define\": \"off\",\n \"no-useless-return\": \"off\",\n \"no-warning-comments\": \"off\",\n \"no-unexpected-multiline\": \"off\",\n \"max-classes-per-file\": \"off\",\n \"class-methods-use-this\": \"off\",\n \"no-unmodified-loop-condition\": \"off\",\n complexity: \"off\",\n \"func-style\": \"off\",\n \"func-names\": \"off\",\n \"default-case\": \"off\",\n} satisfies Rules;\n\nexport const libraryOverrides = [\n {\n files: [\"**/*.{test,spec}.{ts,tsx,js,jsx}\", \"__test__/**\", \"__tests__/**\"],\n rules: {\n \"no-console\": \"off\",\n \"require-await\": \"off\",\n \"no-non-null-assertion\": \"off\",\n },\n },\n] satisfies OxlintOverride[];\n\nexport const library = (options: LibraryOptions = {}): OxlintConfig =>\n defineConfig({\n options: {\n denyWarnings: true,\n reportUnusedDisableDirectives: \"error\",\n typeAware: true,\n ...options.options,\n },\n plugins: Array.from(\n new Set([...libraryPlugins, ...(options.plugins ?? [])]),\n ),\n jsPlugins: [\n stellaLowercasePluginSpecifier,\n noRawColorsPluginSpecifier,\n ...(options.jsPlugins ?? []),\n ],\n ignorePatterns: [\n ...libraryIgnorePatterns,\n ...(options.ignorePatterns ?? []),\n ],\n rules: {\n ...libraryRules,\n ...options.rules,\n },\n overrides: [...libraryOverrides, ...(options.overrides ?? [])],\n });\n\nexport default library();\n"],"mappings":"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"}
|
package/dist/index.d.cts
CHANGED
|
@@ -16,7 +16,53 @@ declare const stellaLowercasePluginSpecifier = "@stll/oxlint-config/plugin";
|
|
|
16
16
|
declare const noRawColorsPluginSpecifier = "@stll/oxlint-config/no-raw-colors";
|
|
17
17
|
declare const libraryIgnorePatterns: string[];
|
|
18
18
|
declare const libraryPlugins: ("eslint" | "import" | "oxc" | "promise" | "react" | "typescript" | "unicorn")[];
|
|
19
|
+
declare const reactCompilerRules: {
|
|
20
|
+
"react/capitalized-calls": "error";
|
|
21
|
+
"react/error-boundaries": "error";
|
|
22
|
+
"react/exhaustive-effect-dependencies": "error";
|
|
23
|
+
"react/globals": "error";
|
|
24
|
+
"react/hooks": "error";
|
|
25
|
+
"react/immutability": "error";
|
|
26
|
+
"react/incompatible-library": "error";
|
|
27
|
+
"react/invariant": "off";
|
|
28
|
+
"react/memo-dependencies": "error";
|
|
29
|
+
"react/no-deriving-state-in-effects": "error";
|
|
30
|
+
"react/preserve-manual-memoization": "error";
|
|
31
|
+
"react/purity": "error";
|
|
32
|
+
"react/refs": "error";
|
|
33
|
+
"react/rule-suppression": "error";
|
|
34
|
+
"react/set-state-in-effect": "error";
|
|
35
|
+
"react/set-state-in-render": "error";
|
|
36
|
+
"react/static-components": "error";
|
|
37
|
+
"react/syntax": "error";
|
|
38
|
+
"react/todo": "off";
|
|
39
|
+
"react/unsupported-syntax": "error";
|
|
40
|
+
"react/use-memo": "error";
|
|
41
|
+
"react/void-use-memo": "error";
|
|
42
|
+
};
|
|
19
43
|
declare const libraryRules: {
|
|
44
|
+
"react/capitalized-calls": "error";
|
|
45
|
+
"react/error-boundaries": "error";
|
|
46
|
+
"react/exhaustive-effect-dependencies": "error";
|
|
47
|
+
"react/globals": "error";
|
|
48
|
+
"react/hooks": "error";
|
|
49
|
+
"react/immutability": "error";
|
|
50
|
+
"react/incompatible-library": "error";
|
|
51
|
+
"react/invariant": "off";
|
|
52
|
+
"react/memo-dependencies": "error";
|
|
53
|
+
"react/no-deriving-state-in-effects": "error";
|
|
54
|
+
"react/preserve-manual-memoization": "error";
|
|
55
|
+
"react/purity": "error";
|
|
56
|
+
"react/refs": "error";
|
|
57
|
+
"react/rule-suppression": "error";
|
|
58
|
+
"react/set-state-in-effect": "error";
|
|
59
|
+
"react/set-state-in-render": "error";
|
|
60
|
+
"react/static-components": "error";
|
|
61
|
+
"react/syntax": "error";
|
|
62
|
+
"react/todo": "off";
|
|
63
|
+
"react/unsupported-syntax": "error";
|
|
64
|
+
"react/use-memo": "error";
|
|
65
|
+
"react/void-use-memo": "error";
|
|
20
66
|
"no-console": "off";
|
|
21
67
|
"no-shadow": "error";
|
|
22
68
|
"require-await": "error";
|
|
@@ -106,7 +152,6 @@ declare const libraryRules: {
|
|
|
106
152
|
"react/no-unsafe": "off";
|
|
107
153
|
"react/no-will-update-set-state": "off";
|
|
108
154
|
"react/void-dom-elements-no-children": "off";
|
|
109
|
-
"react/react-compiler": "error";
|
|
110
155
|
"sort-keys": "off";
|
|
111
156
|
"no-plusplus": "off";
|
|
112
157
|
"no-inline-comments": "off";
|
|
@@ -136,5 +181,5 @@ declare const libraryOverrides: {
|
|
|
136
181
|
declare const library: (options?: LibraryOptions) => OxlintConfig;
|
|
137
182
|
declare const _default: OxlintConfig;
|
|
138
183
|
//#endregion
|
|
139
|
-
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryPlugins, libraryRules, noRawColorsPluginSpecifier, stellaLowercasePluginSpecifier };
|
|
184
|
+
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryPlugins, libraryRules, noRawColorsPluginSpecifier, reactCompilerRules, stellaLowercasePluginSpecifier };
|
|
140
185
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -16,7 +16,53 @@ declare const stellaLowercasePluginSpecifier = "@stll/oxlint-config/plugin";
|
|
|
16
16
|
declare const noRawColorsPluginSpecifier = "@stll/oxlint-config/no-raw-colors";
|
|
17
17
|
declare const libraryIgnorePatterns: string[];
|
|
18
18
|
declare const libraryPlugins: ("eslint" | "import" | "oxc" | "promise" | "react" | "typescript" | "unicorn")[];
|
|
19
|
+
declare const reactCompilerRules: {
|
|
20
|
+
"react/capitalized-calls": "error";
|
|
21
|
+
"react/error-boundaries": "error";
|
|
22
|
+
"react/exhaustive-effect-dependencies": "error";
|
|
23
|
+
"react/globals": "error";
|
|
24
|
+
"react/hooks": "error";
|
|
25
|
+
"react/immutability": "error";
|
|
26
|
+
"react/incompatible-library": "error";
|
|
27
|
+
"react/invariant": "off";
|
|
28
|
+
"react/memo-dependencies": "error";
|
|
29
|
+
"react/no-deriving-state-in-effects": "error";
|
|
30
|
+
"react/preserve-manual-memoization": "error";
|
|
31
|
+
"react/purity": "error";
|
|
32
|
+
"react/refs": "error";
|
|
33
|
+
"react/rule-suppression": "error";
|
|
34
|
+
"react/set-state-in-effect": "error";
|
|
35
|
+
"react/set-state-in-render": "error";
|
|
36
|
+
"react/static-components": "error";
|
|
37
|
+
"react/syntax": "error";
|
|
38
|
+
"react/todo": "off";
|
|
39
|
+
"react/unsupported-syntax": "error";
|
|
40
|
+
"react/use-memo": "error";
|
|
41
|
+
"react/void-use-memo": "error";
|
|
42
|
+
};
|
|
19
43
|
declare const libraryRules: {
|
|
44
|
+
"react/capitalized-calls": "error";
|
|
45
|
+
"react/error-boundaries": "error";
|
|
46
|
+
"react/exhaustive-effect-dependencies": "error";
|
|
47
|
+
"react/globals": "error";
|
|
48
|
+
"react/hooks": "error";
|
|
49
|
+
"react/immutability": "error";
|
|
50
|
+
"react/incompatible-library": "error";
|
|
51
|
+
"react/invariant": "off";
|
|
52
|
+
"react/memo-dependencies": "error";
|
|
53
|
+
"react/no-deriving-state-in-effects": "error";
|
|
54
|
+
"react/preserve-manual-memoization": "error";
|
|
55
|
+
"react/purity": "error";
|
|
56
|
+
"react/refs": "error";
|
|
57
|
+
"react/rule-suppression": "error";
|
|
58
|
+
"react/set-state-in-effect": "error";
|
|
59
|
+
"react/set-state-in-render": "error";
|
|
60
|
+
"react/static-components": "error";
|
|
61
|
+
"react/syntax": "error";
|
|
62
|
+
"react/todo": "off";
|
|
63
|
+
"react/unsupported-syntax": "error";
|
|
64
|
+
"react/use-memo": "error";
|
|
65
|
+
"react/void-use-memo": "error";
|
|
20
66
|
"no-console": "off";
|
|
21
67
|
"no-shadow": "error";
|
|
22
68
|
"require-await": "error";
|
|
@@ -106,7 +152,6 @@ declare const libraryRules: {
|
|
|
106
152
|
"react/no-unsafe": "off";
|
|
107
153
|
"react/no-will-update-set-state": "off";
|
|
108
154
|
"react/void-dom-elements-no-children": "off";
|
|
109
|
-
"react/react-compiler": "error";
|
|
110
155
|
"sort-keys": "off";
|
|
111
156
|
"no-plusplus": "off";
|
|
112
157
|
"no-inline-comments": "off";
|
|
@@ -136,5 +181,5 @@ declare const libraryOverrides: {
|
|
|
136
181
|
declare const library: (options?: LibraryOptions) => OxlintConfig;
|
|
137
182
|
declare const _default: OxlintConfig;
|
|
138
183
|
//#endregion
|
|
139
|
-
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryPlugins, libraryRules, noRawColorsPluginSpecifier, stellaLowercasePluginSpecifier };
|
|
184
|
+
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryPlugins, libraryRules, noRawColorsPluginSpecifier, reactCompilerRules, stellaLowercasePluginSpecifier };
|
|
140
185
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -16,6 +16,30 @@ const libraryPlugins = [
|
|
|
16
16
|
"promise",
|
|
17
17
|
"react"
|
|
18
18
|
];
|
|
19
|
+
const reactCompilerRules = {
|
|
20
|
+
"react/capitalized-calls": "error",
|
|
21
|
+
"react/error-boundaries": "error",
|
|
22
|
+
"react/exhaustive-effect-dependencies": "error",
|
|
23
|
+
"react/globals": "error",
|
|
24
|
+
"react/hooks": "error",
|
|
25
|
+
"react/immutability": "error",
|
|
26
|
+
"react/incompatible-library": "error",
|
|
27
|
+
"react/invariant": "off",
|
|
28
|
+
"react/memo-dependencies": "error",
|
|
29
|
+
"react/no-deriving-state-in-effects": "error",
|
|
30
|
+
"react/preserve-manual-memoization": "error",
|
|
31
|
+
"react/purity": "error",
|
|
32
|
+
"react/refs": "error",
|
|
33
|
+
"react/rule-suppression": "error",
|
|
34
|
+
"react/set-state-in-effect": "error",
|
|
35
|
+
"react/set-state-in-render": "error",
|
|
36
|
+
"react/static-components": "error",
|
|
37
|
+
"react/syntax": "error",
|
|
38
|
+
"react/todo": "off",
|
|
39
|
+
"react/unsupported-syntax": "error",
|
|
40
|
+
"react/use-memo": "error",
|
|
41
|
+
"react/void-use-memo": "error"
|
|
42
|
+
};
|
|
19
43
|
const libraryRules = {
|
|
20
44
|
"no-console": "off",
|
|
21
45
|
"no-shadow": "error",
|
|
@@ -94,7 +118,7 @@ const libraryRules = {
|
|
|
94
118
|
"react/no-unsafe": "off",
|
|
95
119
|
"react/no-will-update-set-state": "off",
|
|
96
120
|
"react/void-dom-elements-no-children": "off",
|
|
97
|
-
|
|
121
|
+
...reactCompilerRules,
|
|
98
122
|
"sort-keys": "off",
|
|
99
123
|
"no-plusplus": "off",
|
|
100
124
|
"no-inline-comments": "off",
|
|
@@ -147,6 +171,6 @@ const library = (options = {}) => defineConfig({
|
|
|
147
171
|
});
|
|
148
172
|
var src_default = library();
|
|
149
173
|
//#endregion
|
|
150
|
-
export { src_default as default, library, libraryIgnorePatterns, libraryOverrides, libraryPlugins, libraryRules, noRawColorsPluginSpecifier, stellaLowercasePluginSpecifier };
|
|
174
|
+
export { src_default as default, library, libraryIgnorePatterns, libraryOverrides, libraryPlugins, libraryRules, noRawColorsPluginSpecifier, reactCompilerRules, stellaLowercasePluginSpecifier };
|
|
151
175
|
|
|
152
176
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { defineConfig, type OxlintConfig, type OxlintOverride } from \"oxlint\";\n\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Options = NonNullable<OxlintConfig[\"options\"]>;\ntype Plugins = NonNullable<OxlintConfig[\"plugins\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\n plugins?: Plugins;\n rules?: Rules;\n};\n\nexport const stellaLowercasePluginSpecifier = \"@stll/oxlint-config/plugin\";\nexport const noRawColorsPluginSpecifier = \"@stll/oxlint-config/no-raw-colors\";\n\nexport const libraryIgnorePatterns = [\"node_modules/\", \"dist/\", \"coverage/\"];\n\n// Setting oxlint's `plugins` config replaces its built-in default list rather\n// than appending to it. This must stay in sync with every plugin-prefixed\n// rule below: `import/*` and `promise/*` rules are configured further down,\n// but oxlint disables both plugins unless they are listed here, which left\n// `import/no-cycle` and every `promise/*` rule silently unenforced. `react`\n// is enabled for `react/react-compiler`; see the comment on that rule for\n// why every other `react/*` rule is explicitly turned back off below.\nexport const libraryPlugins = [\n \"eslint\",\n \"typescript\",\n \"unicorn\",\n \"oxc\",\n \"import\",\n \"promise\",\n \"react\",\n] satisfies Plugins;\n\nexport const libraryRules = {\n \"no-console\": \"off\",\n \"no-shadow\": \"error\",\n \"require-await\": \"error\",\n \"no-useless-catch\": \"error\",\n \"no-non-null-assertion\": \"error\",\n \"no-useless-assignment\": \"error\",\n \"no-loop-func\": \"error\",\n \"no-nested-ternary\": \"error\",\n \"no-void\": [\"error\", { allowAsStatement: true }],\n // Callback expressions should stay lexically scoped; avoids accidental `this` rebinding.\n \"prefer-arrow-callback\": \"error\",\n \"stella-lowercase/stella-lowercase\": \"error\",\n \"no-raw-colors/no-raw-colors\": \"error\",\n\n // Spreading into an accumulator on every loop iteration is O(n^2); push/concat instead.\n \"oxc/no-accumulating-spread\": \"error\",\n // Spreading inside `.map()` allocates a new array per callback invocation; push instead.\n \"oxc/no-map-spread\": \"error\",\n // Flags `if`/`switch` branches with identical bodies: likely dead logic or a missed merge.\n \"oxc/branches-sharing-code\": \"error\",\n\n \"typescript/no-explicit-any\": \"error\",\n \"typescript/no-dynamic-delete\": \"error\",\n \"typescript/no-misused-promises\": [\n \"error\",\n { checksVoidReturn: { attributes: false } },\n ],\n \"typescript/consistent-type-definitions\": [\"error\", \"type\"],\n \"typescript/consistent-return\": \"error\",\n \"typescript/dot-notation\": \"error\",\n \"typescript/no-inferrable-types\": \"off\",\n \"typescript/no-unnecessary-type-conversion\": \"error\",\n \"typescript/no-unnecessary-condition\": [\n \"error\",\n { allowConstantLoopConditions: \"only-allowed-literals\" },\n ],\n \"typescript/no-unnecessary-type-arguments\": \"error\",\n \"typescript/switch-exhaustiveness-check\": [\n \"error\",\n { considerDefaultExhaustiveForUnions: true },\n ],\n \"typescript/strict-boolean-expressions\": [\n \"error\",\n { allowNullableString: true, allowNullableBoolean: true },\n ],\n \"typescript/no-confusing-void-expression\": [\n \"error\",\n { ignoreArrowShorthand: true, ignoreVoidReturningFunctions: true },\n ],\n \"typescript/prefer-nullish-coalescing\": [\n \"error\",\n { ignorePrimitives: { string: true, boolean: true } },\n ],\n \"typescript/only-throw-error\": \"error\",\n \"typescript/return-await\": [\"error\", \"error-handling-correctness-only\"],\n\n \"unicorn/no-useless-undefined\": \"off\",\n \"unicorn/prefer-array-find\": \"error\",\n \"unicorn/prefer-at\": \"error\",\n \"unicorn/prefer-set-has\": \"error\",\n \"unicorn/filename-case\": \"off\",\n \"unicorn/consistent-function-scoping\": \"off\",\n \"unicorn/prefer-ternary\": \"off\",\n \"unicorn/no-array-reduce\": \"error\",\n \"unicorn/no-nested-ternary\": \"off\",\n // `Array.from({ length }).fill(obj)` shares one reference across every slot.\n \"unicorn/no-array-fill-with-reference-type\": \"error\",\n\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\n // Keep a blank line after the import block so it stays visually separate from module body.\n \"import/newline-after-import\": \"error\",\n\n \"promise/always-return\": \"error\",\n \"promise/no-return-in-finally\": \"error\",\n \"promise/prefer-await-to-then\": \"off\",\n \"promise/prefer-await-to-callbacks\": \"off\",\n \"promise/avoid-new\": \"off\",\n\n // Enabling the `react` plugin (above) turns on its whole correctness-category\n // rule set at \"warn\" by default, not just react-compiler. Only react-compiler\n // is a deliberate addition here, so the rest are turned off to keep this\n // package's blast radius scoped to the one rule being added; lift any of\n // these independently if a future change wants them.\n \"react/exhaustive-deps\": \"off\",\n \"react/forward-ref-uses-ref\": \"off\",\n \"react/jsx-key\": \"off\",\n \"react/jsx-no-duplicate-props\": \"off\",\n \"react/jsx-no-undef\": \"off\",\n \"react/jsx-props-no-spread-multi\": \"off\",\n \"react/no-children-prop\": \"off\",\n \"react/no-danger-with-children\": \"off\",\n \"react/no-did-mount-set-state\": \"off\",\n \"react/no-did-update-set-state\": \"off\",\n \"react/no-direct-mutation-state\": \"off\",\n \"react/no-find-dom-node\": \"off\",\n \"react/no-is-mounted\": \"off\",\n \"react/no-render-return-value\": \"off\",\n \"react/no-string-refs\": \"off\",\n \"react/no-this-in-sfc\": \"off\",\n \"react/no-unsafe\": \"off\",\n \"react/no-will-update-set-state\": \"off\",\n \"react/void-dom-elements-no-children\": \"off\",\n // Requires oxlint >= 1.70. Nursery rule upstream: flags violations of the\n // Rules of React that block compiler memoization; diagnostics may shift\n // between oxlint minors, so re-audit findings after bumping the oxlint\n // devDependency. oxlint has no bulk-suppression/baseline mechanism as of\n // 1.72.0 (oxc-project/oxc#10549 tracks the upstream feature request and is\n // still open); consumers adopting this against an existing findings\n // backlog should carve out temporary `overrides` entries per legacy path\n // (or per rule, at `\"off\"`) and fix forward, rather than expecting a\n // generated suppression file.\n \"react/react-compiler\": \"error\",\n\n \"sort-keys\": \"off\",\n \"no-plusplus\": \"off\",\n \"no-inline-comments\": \"off\",\n \"max-statements\": \"off\",\n \"prefer-destructuring\": \"off\",\n \"no-negated-condition\": \"off\",\n \"no-use-before-define\": \"off\",\n \"no-useless-return\": \"off\",\n \"no-warning-comments\": \"off\",\n \"no-unexpected-multiline\": \"off\",\n \"max-classes-per-file\": \"off\",\n \"class-methods-use-this\": \"off\",\n \"no-unmodified-loop-condition\": \"off\",\n complexity: \"off\",\n \"func-style\": \"off\",\n \"func-names\": \"off\",\n \"default-case\": \"off\",\n} satisfies Rules;\n\nexport const libraryOverrides = [\n {\n files: [\"**/*.{test,spec}.{ts,tsx,js,jsx}\", \"__test__/**\", \"__tests__/**\"],\n rules: {\n \"no-console\": \"off\",\n \"require-await\": \"off\",\n \"no-non-null-assertion\": \"off\",\n },\n },\n] satisfies OxlintOverride[];\n\nexport const library = (options: LibraryOptions = {}): OxlintConfig =>\n defineConfig({\n options: {\n denyWarnings: true,\n reportUnusedDisableDirectives: \"error\",\n typeAware: true,\n ...options.options,\n },\n plugins: Array.from(\n new Set([...libraryPlugins, ...(options.plugins ?? [])]),\n ),\n jsPlugins: [\n stellaLowercasePluginSpecifier,\n noRawColorsPluginSpecifier,\n ...(options.jsPlugins ?? []),\n ],\n ignorePatterns: [\n ...libraryIgnorePatterns,\n ...(options.ignorePatterns ?? []),\n ],\n rules: {\n ...libraryRules,\n ...options.rules,\n },\n overrides: [...libraryOverrides, ...(options.overrides ?? [])],\n });\n\nexport default library();\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { defineConfig, type OxlintConfig, type OxlintOverride } from \"oxlint\";\n\ntype Rules = NonNullable<OxlintConfig[\"rules\"]>;\ntype JsPlugins = NonNullable<OxlintConfig[\"jsPlugins\"]>;\ntype Options = NonNullable<OxlintConfig[\"options\"]>;\ntype Plugins = NonNullable<OxlintConfig[\"plugins\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\n plugins?: Plugins;\n rules?: Rules;\n};\n\nexport const stellaLowercasePluginSpecifier = \"@stll/oxlint-config/plugin\";\nexport const noRawColorsPluginSpecifier = \"@stll/oxlint-config/no-raw-colors\";\n\nexport const libraryIgnorePatterns = [\"node_modules/\", \"dist/\", \"coverage/\"];\n\n// Setting oxlint's `plugins` config replaces its built-in default list rather\n// than appending to it. This must stay in sync with every plugin-prefixed\n// rule below: `import/*` and `promise/*` rules are configured further down,\n// but oxlint disables both plugins unless they are listed here, which left\n// `import/no-cycle` and every `promise/*` rule silently unenforced. `react`\n// is enabled for the React Compiler category rules; see the comment on that\n// ruleset for why every other `react/*` rule is explicitly turned back off.\nexport const libraryPlugins = [\n \"eslint\",\n \"typescript\",\n \"unicorn\",\n \"oxc\",\n \"import\",\n \"promise\",\n \"react\",\n] satisfies Plugins;\n\n// Oxlint 1.80 replaced react/react-compiler with category-specific rules.\n// Keep the actionable compiler diagnostics strict while excluding internal\n// invariant and unfinished-feature reports that do not identify source bugs.\nexport const reactCompilerRules = {\n \"react/capitalized-calls\": \"error\",\n \"react/error-boundaries\": \"error\",\n \"react/exhaustive-effect-dependencies\": \"error\",\n \"react/globals\": \"error\",\n \"react/hooks\": \"error\",\n \"react/immutability\": \"error\",\n \"react/incompatible-library\": \"error\",\n \"react/invariant\": \"off\",\n \"react/memo-dependencies\": \"error\",\n \"react/no-deriving-state-in-effects\": \"error\",\n \"react/preserve-manual-memoization\": \"error\",\n \"react/purity\": \"error\",\n \"react/refs\": \"error\",\n \"react/rule-suppression\": \"error\",\n \"react/set-state-in-effect\": \"error\",\n \"react/set-state-in-render\": \"error\",\n \"react/static-components\": \"error\",\n \"react/syntax\": \"error\",\n \"react/todo\": \"off\",\n \"react/unsupported-syntax\": \"error\",\n \"react/use-memo\": \"error\",\n \"react/void-use-memo\": \"error\",\n} satisfies Rules;\n\nexport const libraryRules = {\n \"no-console\": \"off\",\n \"no-shadow\": \"error\",\n \"require-await\": \"error\",\n \"no-useless-catch\": \"error\",\n \"no-non-null-assertion\": \"error\",\n \"no-useless-assignment\": \"error\",\n \"no-loop-func\": \"error\",\n \"no-nested-ternary\": \"error\",\n \"no-void\": [\"error\", { allowAsStatement: true }],\n // Callback expressions should stay lexically scoped; avoids accidental `this` rebinding.\n \"prefer-arrow-callback\": \"error\",\n \"stella-lowercase/stella-lowercase\": \"error\",\n \"no-raw-colors/no-raw-colors\": \"error\",\n\n // Spreading into an accumulator on every loop iteration is O(n^2); push/concat instead.\n \"oxc/no-accumulating-spread\": \"error\",\n // Spreading inside `.map()` allocates a new array per callback invocation; push instead.\n \"oxc/no-map-spread\": \"error\",\n // Flags `if`/`switch` branches with identical bodies: likely dead logic or a missed merge.\n \"oxc/branches-sharing-code\": \"error\",\n\n \"typescript/no-explicit-any\": \"error\",\n \"typescript/no-dynamic-delete\": \"error\",\n \"typescript/no-misused-promises\": [\n \"error\",\n { checksVoidReturn: { attributes: false } },\n ],\n \"typescript/consistent-type-definitions\": [\"error\", \"type\"],\n \"typescript/consistent-return\": \"error\",\n \"typescript/dot-notation\": \"error\",\n \"typescript/no-inferrable-types\": \"off\",\n \"typescript/no-unnecessary-type-conversion\": \"error\",\n \"typescript/no-unnecessary-condition\": [\n \"error\",\n { allowConstantLoopConditions: \"only-allowed-literals\" },\n ],\n \"typescript/no-unnecessary-type-arguments\": \"error\",\n \"typescript/switch-exhaustiveness-check\": [\n \"error\",\n { considerDefaultExhaustiveForUnions: true },\n ],\n \"typescript/strict-boolean-expressions\": [\n \"error\",\n { allowNullableString: true, allowNullableBoolean: true },\n ],\n \"typescript/no-confusing-void-expression\": [\n \"error\",\n { ignoreArrowShorthand: true, ignoreVoidReturningFunctions: true },\n ],\n \"typescript/prefer-nullish-coalescing\": [\n \"error\",\n { ignorePrimitives: { string: true, boolean: true } },\n ],\n \"typescript/only-throw-error\": \"error\",\n \"typescript/return-await\": [\"error\", \"error-handling-correctness-only\"],\n\n \"unicorn/no-useless-undefined\": \"off\",\n \"unicorn/prefer-array-find\": \"error\",\n \"unicorn/prefer-at\": \"error\",\n \"unicorn/prefer-set-has\": \"error\",\n \"unicorn/filename-case\": \"off\",\n \"unicorn/consistent-function-scoping\": \"off\",\n \"unicorn/prefer-ternary\": \"off\",\n \"unicorn/no-array-reduce\": \"error\",\n \"unicorn/no-nested-ternary\": \"off\",\n // `Array.from({ length }).fill(obj)` shares one reference across every slot.\n \"unicorn/no-array-fill-with-reference-type\": \"error\",\n\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\n // Keep a blank line after the import block so it stays visually separate from module body.\n \"import/newline-after-import\": \"error\",\n\n \"promise/always-return\": \"error\",\n \"promise/no-return-in-finally\": \"error\",\n \"promise/prefer-await-to-then\": \"off\",\n \"promise/prefer-await-to-callbacks\": \"off\",\n \"promise/avoid-new\": \"off\",\n\n // Enabling the `react` plugin (above) turns on its whole correctness-category\n // rule set at \"warn\" by default, not just the React Compiler categories.\n // Only the compiler categories are deliberate additions here, so the rest\n // are turned off to keep this package's blast radius scoped; lift any of\n // these independently if a future change wants them.\n \"react/exhaustive-deps\": \"off\",\n \"react/forward-ref-uses-ref\": \"off\",\n \"react/jsx-key\": \"off\",\n \"react/jsx-no-duplicate-props\": \"off\",\n \"react/jsx-no-undef\": \"off\",\n \"react/jsx-props-no-spread-multi\": \"off\",\n \"react/no-children-prop\": \"off\",\n \"react/no-danger-with-children\": \"off\",\n \"react/no-did-mount-set-state\": \"off\",\n \"react/no-did-update-set-state\": \"off\",\n \"react/no-direct-mutation-state\": \"off\",\n \"react/no-find-dom-node\": \"off\",\n \"react/no-is-mounted\": \"off\",\n \"react/no-render-return-value\": \"off\",\n \"react/no-string-refs\": \"off\",\n \"react/no-this-in-sfc\": \"off\",\n \"react/no-unsafe\": \"off\",\n \"react/no-will-update-set-state\": \"off\",\n \"react/void-dom-elements-no-children\": \"off\",\n ...reactCompilerRules,\n\n \"sort-keys\": \"off\",\n \"no-plusplus\": \"off\",\n \"no-inline-comments\": \"off\",\n \"max-statements\": \"off\",\n \"prefer-destructuring\": \"off\",\n \"no-negated-condition\": \"off\",\n \"no-use-before-define\": \"off\",\n \"no-useless-return\": \"off\",\n \"no-warning-comments\": \"off\",\n \"no-unexpected-multiline\": \"off\",\n \"max-classes-per-file\": \"off\",\n \"class-methods-use-this\": \"off\",\n \"no-unmodified-loop-condition\": \"off\",\n complexity: \"off\",\n \"func-style\": \"off\",\n \"func-names\": \"off\",\n \"default-case\": \"off\",\n} satisfies Rules;\n\nexport const libraryOverrides = [\n {\n files: [\"**/*.{test,spec}.{ts,tsx,js,jsx}\", \"__test__/**\", \"__tests__/**\"],\n rules: {\n \"no-console\": \"off\",\n \"require-await\": \"off\",\n \"no-non-null-assertion\": \"off\",\n },\n },\n] satisfies OxlintOverride[];\n\nexport const library = (options: LibraryOptions = {}): OxlintConfig =>\n defineConfig({\n options: {\n denyWarnings: true,\n reportUnusedDisableDirectives: \"error\",\n typeAware: true,\n ...options.options,\n },\n plugins: Array.from(\n new Set([...libraryPlugins, ...(options.plugins ?? [])]),\n ),\n jsPlugins: [\n stellaLowercasePluginSpecifier,\n noRawColorsPluginSpecifier,\n ...(options.jsPlugins ?? []),\n ],\n ignorePatterns: [\n ...libraryIgnorePatterns,\n ...(options.ignorePatterns ?? []),\n ],\n rules: {\n ...libraryRules,\n ...options.rules,\n },\n overrides: [...libraryOverrides, ...(options.overrides ?? [])],\n });\n\nexport default library();\n"],"mappings":"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"}
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
//#region \0rolldown/runtime.js
|
|
4
|
+
var __create = Object.create;
|
|
5
|
+
var __defProp = Object.defineProperty;
|
|
6
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
+
key = keys[i];
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
|
|
14
|
+
get: ((k) => from[k]).bind(null, key),
|
|
15
|
+
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
21
|
+
value: mod,
|
|
22
|
+
enumerable: true
|
|
23
|
+
}) : target, mod));
|
|
24
|
+
//#endregion
|
|
25
|
+
let node_fs = require("node:fs");
|
|
26
|
+
let node_child_process = require("node:child_process");
|
|
27
|
+
let node_path = require("node:path");
|
|
28
|
+
node_path = __toESM(node_path, 1);
|
|
29
|
+
//#region src/toolchain-check.ts
|
|
30
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
31
|
+
const scalar = (value) => value.trim().replace(/\s+#.*$/, "").replace(/^["']|["']$/g, "");
|
|
32
|
+
const trackedPath = (file) => !file.split("/").some((part) => part === "node_modules" || part === "vendor");
|
|
33
|
+
/** Check tracked consumer files without traversing dependencies or the working tree. */
|
|
34
|
+
const checkToolchain = ({ root, bunVersion, allowNonBunPackageManagers = [] }) => {
|
|
35
|
+
const files = (0, node_child_process.execFileSync)("git", [
|
|
36
|
+
"ls-files",
|
|
37
|
+
"-z",
|
|
38
|
+
"--cached"
|
|
39
|
+
], {
|
|
40
|
+
cwd: root,
|
|
41
|
+
encoding: "utf8"
|
|
42
|
+
}).split("\0").filter((file) => file !== "" && trackedPath(file));
|
|
43
|
+
const tracked = new Set(files);
|
|
44
|
+
const diagnostics = [];
|
|
45
|
+
const add = (file, line, message) => {
|
|
46
|
+
diagnostics.push({
|
|
47
|
+
path: file,
|
|
48
|
+
line,
|
|
49
|
+
message
|
|
50
|
+
});
|
|
51
|
+
};
|
|
52
|
+
const read = (file) => {
|
|
53
|
+
try {
|
|
54
|
+
return (0, node_fs.readFileSync)(node_path.default.join(root, file), "utf8");
|
|
55
|
+
} catch {
|
|
56
|
+
add(file, 1, "cannot read tracked file");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
const checkVersion = (file, line, value, label) => {
|
|
61
|
+
if (value !== bunVersion) add(file, line, `${label} must be ${bunVersion}, found ${String(value)}`);
|
|
62
|
+
};
|
|
63
|
+
const packages = /* @__PURE__ */ new Map();
|
|
64
|
+
for (const file of files.filter((entry) => node_path.default.basename(entry) === "package.json")) {
|
|
65
|
+
const text = read(file);
|
|
66
|
+
if (text === void 0) continue;
|
|
67
|
+
let json;
|
|
68
|
+
try {
|
|
69
|
+
json = JSON.parse(text);
|
|
70
|
+
} catch {
|
|
71
|
+
add(file, 1, "invalid package.json");
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
if (!isRecord(json)) {
|
|
75
|
+
add(file, 1, "package.json must contain an object");
|
|
76
|
+
continue;
|
|
77
|
+
}
|
|
78
|
+
packages.set(file, {
|
|
79
|
+
manager: json["packageManager"],
|
|
80
|
+
json,
|
|
81
|
+
text
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
const catalogSource = (json) => isRecord(json["workspaces"]) ? json["workspaces"] : json;
|
|
85
|
+
const rootCatalogs = catalogSource(packages.get("package.json")?.json ?? {});
|
|
86
|
+
for (const [file, { json, text }] of packages) {
|
|
87
|
+
const lines = text.split(/\r?\n/);
|
|
88
|
+
const reportedLines = /* @__PURE__ */ new Map();
|
|
89
|
+
const propertyLine = (key, value) => {
|
|
90
|
+
const serialized = value === void 0 ? void 0 : JSON.stringify(value);
|
|
91
|
+
const matchKey = `${key}:${serialized ?? ""}`;
|
|
92
|
+
const previous = reportedLines.get(matchKey) ?? -1;
|
|
93
|
+
const index = lines.findIndex((line, lineIndex) => lineIndex > previous && line.includes(`"${key}"`) && (serialized === void 0 || line.includes(serialized)));
|
|
94
|
+
if (index >= 0) reportedLines.set(matchKey, index);
|
|
95
|
+
return Math.max(1, index + 1);
|
|
96
|
+
};
|
|
97
|
+
if (json["packageManager"] !== void 0) {
|
|
98
|
+
if (typeof json["packageManager"] === "string" && json["packageManager"].startsWith("bun@")) checkVersion(file, propertyLine("packageManager"), json["packageManager"].slice(4), "packageManager Bun version");
|
|
99
|
+
else if (!allowNonBunPackageManagers.includes(file)) add(file, propertyLine("packageManager"), "packageManager is not Bun; use --allow-non-bun-package-manager with this path to allow it");
|
|
100
|
+
}
|
|
101
|
+
const checkDependencies = (value, resolveCatalog = false) => {
|
|
102
|
+
if (!isRecord(value) || value["bun-types"] === void 0) return;
|
|
103
|
+
const specifier = value["bun-types"];
|
|
104
|
+
const resolveVersion = () => {
|
|
105
|
+
if (!resolveCatalog || typeof specifier !== "string" || !specifier.startsWith("catalog:")) return specifier;
|
|
106
|
+
const catalogName = specifier.slice(8);
|
|
107
|
+
const source = file === "package.json" ? catalogSource(json) : rootCatalogs;
|
|
108
|
+
const catalog = catalogName === "" ? source["catalog"] : isRecord(source["catalogs"]) && source["catalogs"][catalogName];
|
|
109
|
+
return isRecord(catalog) ? catalog["bun-types"] : void 0;
|
|
110
|
+
};
|
|
111
|
+
checkVersion(file, propertyLine("bun-types", specifier), resolveVersion(), "bun-types");
|
|
112
|
+
};
|
|
113
|
+
checkDependencies(json["dependencies"], true);
|
|
114
|
+
checkDependencies(json["devDependencies"], true);
|
|
115
|
+
checkDependencies(json["catalog"]);
|
|
116
|
+
if (isRecord(json["catalogs"])) for (const catalog of Object.values(json["catalogs"])) checkDependencies(catalog);
|
|
117
|
+
if (isRecord(json["workspaces"])) {
|
|
118
|
+
checkDependencies(json["workspaces"]["catalog"]);
|
|
119
|
+
if (isRecord(json["workspaces"]["catalogs"])) for (const catalog of Object.values(json["workspaces"]["catalogs"])) checkDependencies(catalog);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
for (const file of files) {
|
|
123
|
+
const name = node_path.default.basename(file);
|
|
124
|
+
const workflow = /^\.github\/workflows\/[^/]+\.ya?ml$/.test(file) || /^\.github\/actions\/.+\/action\.ya?ml$/.test(file);
|
|
125
|
+
const dockerfile = name.startsWith("Dockerfile") || name === "Containerfile";
|
|
126
|
+
const versionFile = name === ".bun-version" || name === ".tool-versions";
|
|
127
|
+
const mise = name === "mise.toml" || name === ".mise.toml";
|
|
128
|
+
if (!workflow && !dockerfile && !versionFile && !mise) continue;
|
|
129
|
+
const text = read(file);
|
|
130
|
+
if (text === void 0) continue;
|
|
131
|
+
if (name === ".bun-version") checkVersion(file, 1, scalar(text), ".bun-version");
|
|
132
|
+
let section = "";
|
|
133
|
+
for (const [index, original] of text.split(/\r?\n/).entries()) {
|
|
134
|
+
const line = index + 1;
|
|
135
|
+
if (/^\s*#/.test(original) || original.trim() === "") continue;
|
|
136
|
+
if (workflow) {
|
|
137
|
+
if (original.match(/(?:^\s*(?:-\s*)?|[{,]\s*)["']?bun-version["']?\s*:/) !== null) add(file, line, "bun-version literals are forbidden; use bun-version-file pointing to a package.json with the shared Bun pin");
|
|
138
|
+
const reference = original.match(/(?:^\s*(?:-\s*)?|[{,]\s*)["']?bun-version-file["']?\s*:\s*(?:"([^"]*)"|'([^']*)'|([^,}]*))/);
|
|
139
|
+
if (reference !== null) {
|
|
140
|
+
const target = scalar(reference[1] ?? reference[2] ?? reference[3] ?? "");
|
|
141
|
+
const normalized = node_path.default.posix.normalize(target);
|
|
142
|
+
const pkg = packages.get(normalized);
|
|
143
|
+
if (target === "" || node_path.default.posix.isAbsolute(target) || normalized.startsWith("../") || !tracked.has(normalized) || node_path.default.basename(normalized) !== "package.json" || pkg?.manager !== `bun@${bunVersion}`) add(file, line, `bun-version-file must reference a tracked package.json with packageManager bun@${bunVersion}, found ${target}`);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
if (dockerfile) {
|
|
147
|
+
const image = original.match(/^\s*FROM\s+(?:--\S+\s+)*oven\/bun(?::([^\s@]+))?(?:@\S+)?(?:\s|$)/i);
|
|
148
|
+
if (image !== null) {
|
|
149
|
+
const tag = image[1];
|
|
150
|
+
if (tag !== void 0) {
|
|
151
|
+
const version = tag.match(/^(\d+\.\d+\.\d+)(?:-|$)/)?.[1];
|
|
152
|
+
checkVersion(file, line, version ?? tag, "oven/bun version");
|
|
153
|
+
} else if (!/oven\/bun@/i.test(original)) add(file, line, `oven/bun must use a ${bunVersion} version tag`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (name === ".tool-versions") {
|
|
157
|
+
const entry = original.match(/^\s*bun\s+(.+)$/);
|
|
158
|
+
if (entry !== null) checkVersion(file, line, scalar(entry[1] ?? ""), ".tool-versions Bun version");
|
|
159
|
+
}
|
|
160
|
+
if (mise) {
|
|
161
|
+
const heading = original.match(/^\s*\[([^\]]+)\]/);
|
|
162
|
+
if (heading !== null) section = heading[1] ?? "";
|
|
163
|
+
const checkMiseVersion = (value) => {
|
|
164
|
+
const inlineVersion = [...value.matchAll(/[,{]\s*([\w-]+|"[^"]+"|'[^']+')\s*=\s*("(?:\\.|[^"\\])*"|'[^']*'|[^,{}]+)\s*(?=[,}])/g)].find((field) => scalar(field[1] ?? "") === "version");
|
|
165
|
+
checkVersion(file, line, scalar(inlineVersion?.[2] ?? value), "mise Bun version");
|
|
166
|
+
};
|
|
167
|
+
const entry = original.match(/^\s*["']?bun["']?\s*=\s*(.+)$/);
|
|
168
|
+
if (entry !== null && section === "tools") checkMiseVersion(entry[1] ?? "");
|
|
169
|
+
const dotted = original.match(/^\s*tools\.bun(?:\.version)?\s*=\s*(.+)$/);
|
|
170
|
+
if (dotted !== null && section === "") checkMiseVersion(dotted[1] ?? "");
|
|
171
|
+
const tableVersion = original.match(/^\s*version\s*=\s*(.+)$/);
|
|
172
|
+
if (tableVersion !== null && section === "tools.bun") checkMiseVersion(tableVersion[1] ?? "");
|
|
173
|
+
const inlineTools = original.match(/^\s*tools\s*=\s*\{(.*)\}/);
|
|
174
|
+
if (inlineTools !== null && section === "") {
|
|
175
|
+
const inlineBun = inlineTools[1]?.match(/(?:^|,)\s*["']?bun["']?\s*=\s*(\{[^}]*\}|[^,}]+)/);
|
|
176
|
+
if (inlineBun !== null && inlineBun !== void 0) checkMiseVersion(inlineBun[1] ?? "");
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return diagnostics;
|
|
182
|
+
};
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/toolchain-check-cli.ts
|
|
185
|
+
try {
|
|
186
|
+
const allowNonBunPackageManagers = [];
|
|
187
|
+
const args = process.argv.slice(2);
|
|
188
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
189
|
+
const argument = args[index];
|
|
190
|
+
if (argument === "--help") {
|
|
191
|
+
process.stdout.write("Usage: stll-toolchain-check [--allow-non-bun-package-manager <tracked package.json path>]\n");
|
|
192
|
+
process.exit(0);
|
|
193
|
+
}
|
|
194
|
+
const value = args.at(index + 1);
|
|
195
|
+
if (argument !== "--allow-non-bun-package-manager" || value === void 0 || value.startsWith("--")) throw new Error(`unexpected or incomplete argument: ${argument}`);
|
|
196
|
+
allowNonBunPackageManagers.push(value);
|
|
197
|
+
index += 1;
|
|
198
|
+
}
|
|
199
|
+
const toolchain = JSON.parse((0, node_fs.readFileSync)(new URL("../toolchain.json", require("url").pathToFileURL(__filename).href), "utf8"));
|
|
200
|
+
if (typeof toolchain !== "object" || toolchain === null || !("bun" in toolchain) || typeof toolchain.bun !== "string") throw new Error("installed toolchain.json must define a Bun version");
|
|
201
|
+
const diagnostics = checkToolchain({
|
|
202
|
+
root: process.cwd(),
|
|
203
|
+
bunVersion: toolchain.bun,
|
|
204
|
+
allowNonBunPackageManagers
|
|
205
|
+
});
|
|
206
|
+
for (const diagnostic of diagnostics) process.stderr.write(`${diagnostic.path}:${diagnostic.line}: ${diagnostic.message}\n`);
|
|
207
|
+
if (diagnostics.length > 0) process.exitCode = 1;
|
|
208
|
+
} catch (error) {
|
|
209
|
+
process.stderr.write(`toolchain-check:1: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
210
|
+
process.exitCode = 1;
|
|
211
|
+
}
|
|
212
|
+
//#endregion
|
|
213
|
+
|
|
214
|
+
//# sourceMappingURL=toolchain-check-cli.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolchain-check-cli.cjs","names":["path"],"sources":["../src/toolchain-check.ts","../src/toolchain-check-cli.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport type ToolchainDiagnostic = {\n path: string;\n line: number;\n message: string;\n};\n\nexport type CheckToolchainOptions = {\n root: string;\n bunVersion: string;\n allowNonBunPackageManagers?: readonly string[];\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst scalar = (value: string) =>\n value\n .trim()\n .replace(/\\s+#.*$/, \"\")\n .replace(/^[\"']|[\"']$/g, \"\");\n\nconst trackedPath = (file: string) =>\n !file.split(\"/\").some((part) => part === \"node_modules\" || part === \"vendor\");\n\n/** Check tracked consumer files without traversing dependencies or the working tree. */\nexport const checkToolchain = ({\n root,\n bunVersion,\n allowNonBunPackageManagers = [],\n}: CheckToolchainOptions): ToolchainDiagnostic[] => {\n const files = execFileSync(\"git\", [\"ls-files\", \"-z\", \"--cached\"], {\n cwd: root,\n encoding: \"utf8\",\n })\n .split(\"\\0\")\n .filter((file) => file !== \"\" && trackedPath(file));\n const tracked = new Set(files);\n const diagnostics: ToolchainDiagnostic[] = [];\n const add = (file: string, line: number, message: string) => {\n diagnostics.push({ path: file, line, message });\n };\n const read = (file: string): string | undefined => {\n try {\n return readFileSync(path.join(root, file), \"utf8\");\n } catch {\n add(file, 1, \"cannot read tracked file\");\n return undefined;\n }\n };\n const checkVersion = (\n file: string,\n line: number,\n value: unknown,\n label: string,\n ) => {\n if (value !== bunVersion) {\n add(file, line, `${label} must be ${bunVersion}, found ${String(value)}`);\n }\n };\n const packages = new Map<\n string,\n { manager: unknown; json: Record<string, unknown>; text: string }\n >();\n for (const file of files.filter(\n (entry) => path.basename(entry) === \"package.json\",\n )) {\n const text = read(file);\n if (text === undefined) continue;\n let json: unknown;\n try {\n json = JSON.parse(text);\n } catch {\n add(file, 1, \"invalid package.json\");\n continue;\n }\n if (!isRecord(json)) {\n add(file, 1, \"package.json must contain an object\");\n continue;\n }\n packages.set(file, { manager: json[\"packageManager\"], json, text });\n }\n const catalogSource = (json: Record<string, unknown>) =>\n isRecord(json[\"workspaces\"]) ? json[\"workspaces\"] : json;\n const rootCatalogs = catalogSource(packages.get(\"package.json\")?.json ?? {});\n for (const [file, { json, text }] of packages) {\n const lines = text.split(/\\r?\\n/);\n const reportedLines = new Map<string, number>();\n const propertyLine = (key: string, value?: unknown) => {\n const serialized =\n value === undefined ? undefined : JSON.stringify(value);\n const matchKey = `${key}:${serialized ?? \"\"}`;\n const previous = reportedLines.get(matchKey) ?? -1;\n const index = lines.findIndex(\n (line, lineIndex) =>\n lineIndex > previous &&\n line.includes(`\"${key}\"`) &&\n (serialized === undefined || line.includes(serialized)),\n );\n if (index >= 0) reportedLines.set(matchKey, index);\n return Math.max(1, index + 1);\n };\n if (json[\"packageManager\"] !== undefined) {\n if (\n typeof json[\"packageManager\"] === \"string\" &&\n json[\"packageManager\"].startsWith(\"bun@\")\n ) {\n checkVersion(\n file,\n propertyLine(\"packageManager\"),\n json[\"packageManager\"].slice(4),\n \"packageManager Bun version\",\n );\n } else if (!allowNonBunPackageManagers.includes(file)) {\n add(\n file,\n propertyLine(\"packageManager\"),\n \"packageManager is not Bun; use --allow-non-bun-package-manager with this path to allow it\",\n );\n }\n }\n const checkDependencies = (value: unknown, resolveCatalog = false) => {\n if (!isRecord(value) || value[\"bun-types\"] === undefined) return;\n const specifier = value[\"bun-types\"];\n const resolveVersion = () => {\n if (\n !resolveCatalog ||\n typeof specifier !== \"string\" ||\n !specifier.startsWith(\"catalog:\")\n )\n return specifier;\n const catalogName = specifier.slice(\"catalog:\".length);\n const source =\n file === \"package.json\" ? catalogSource(json) : rootCatalogs;\n const catalog =\n catalogName === \"\"\n ? source[\"catalog\"]\n : isRecord(source[\"catalogs\"]) && source[\"catalogs\"][catalogName];\n return isRecord(catalog) ? catalog[\"bun-types\"] : undefined;\n };\n checkVersion(\n file,\n propertyLine(\"bun-types\", specifier),\n resolveVersion(),\n \"bun-types\",\n );\n };\n checkDependencies(json[\"dependencies\"], true);\n checkDependencies(json[\"devDependencies\"], true);\n checkDependencies(json[\"catalog\"]);\n if (isRecord(json[\"catalogs\"])) {\n for (const catalog of Object.values(json[\"catalogs\"]))\n checkDependencies(catalog);\n }\n if (isRecord(json[\"workspaces\"])) {\n checkDependencies(json[\"workspaces\"][\"catalog\"]);\n if (isRecord(json[\"workspaces\"][\"catalogs\"])) {\n for (const catalog of Object.values(json[\"workspaces\"][\"catalogs\"]))\n checkDependencies(catalog);\n }\n }\n }\n for (const file of files) {\n const name = path.basename(file);\n const workflow =\n /^\\.github\\/workflows\\/[^/]+\\.ya?ml$/.test(file) ||\n /^\\.github\\/actions\\/.+\\/action\\.ya?ml$/.test(file);\n const dockerfile =\n name.startsWith(\"Dockerfile\") || name === \"Containerfile\";\n const versionFile = name === \".bun-version\" || name === \".tool-versions\";\n const mise = name === \"mise.toml\" || name === \".mise.toml\";\n if (!workflow && !dockerfile && !versionFile && !mise) continue;\n const text = read(file);\n if (text === undefined) continue;\n if (name === \".bun-version\")\n checkVersion(file, 1, scalar(text), \".bun-version\");\n let section = \"\";\n for (const [index, original] of text.split(/\\r?\\n/).entries()) {\n const line = index + 1;\n if (/^\\s*#/.test(original) || original.trim() === \"\") continue;\n if (workflow) {\n const pin = original.match(\n /(?:^\\s*(?:-\\s*)?|[{,]\\s*)[\"']?bun-version[\"']?\\s*:/,\n );\n if (pin !== null)\n add(\n file,\n line,\n \"bun-version literals are forbidden; use bun-version-file pointing to a package.json with the shared Bun pin\",\n );\n const reference = original.match(\n /(?:^\\s*(?:-\\s*)?|[{,]\\s*)[\"']?bun-version-file[\"']?\\s*:\\s*(?:\"([^\"]*)\"|'([^']*)'|([^,}]*))/,\n );\n if (reference !== null) {\n const target = scalar(\n reference[1] ?? reference[2] ?? reference[3] ?? \"\",\n );\n const normalized = path.posix.normalize(target);\n const pkg = packages.get(normalized);\n if (\n target === \"\" ||\n path.posix.isAbsolute(target) ||\n normalized.startsWith(\"../\") ||\n !tracked.has(normalized) ||\n path.basename(normalized) !== \"package.json\" ||\n pkg?.manager !== `bun@${bunVersion}`\n ) {\n add(\n file,\n line,\n `bun-version-file must reference a tracked package.json with packageManager bun@${bunVersion}, found ${target}`,\n );\n }\n }\n }\n if (dockerfile) {\n const image = original.match(\n /^\\s*FROM\\s+(?:--\\S+\\s+)*oven\\/bun(?::([^\\s@]+))?(?:@\\S+)?(?:\\s|$)/i,\n );\n if (image !== null) {\n const tag = image[1];\n if (tag !== undefined) {\n const version = tag.match(/^(\\d+\\.\\d+\\.\\d+)(?:-|$)/)?.[1];\n checkVersion(file, line, version ?? tag, \"oven/bun version\");\n } else if (!/oven\\/bun@/i.test(original)) {\n add(file, line, `oven/bun must use a ${bunVersion} version tag`);\n }\n }\n }\n if (name === \".tool-versions\") {\n const entry = original.match(/^\\s*bun\\s+(.+)$/);\n if (entry !== null)\n checkVersion(\n file,\n line,\n scalar(entry[1] ?? \"\"),\n \".tool-versions Bun version\",\n );\n }\n if (mise) {\n const heading = original.match(/^\\s*\\[([^\\]]+)\\]/);\n if (heading !== null) section = heading[1] ?? \"\";\n const checkMiseVersion = (value: string) => {\n const inlineVersion = [\n ...value.matchAll(\n /[,{]\\s*([\\w-]+|\"[^\"]+\"|'[^']+')\\s*=\\s*(\"(?:\\\\.|[^\"\\\\])*\"|'[^']*'|[^,{}]+)\\s*(?=[,}])/g,\n ),\n ].find((field) => scalar(field[1] ?? \"\") === \"version\");\n checkVersion(\n file,\n line,\n scalar(inlineVersion?.[2] ?? value),\n \"mise Bun version\",\n );\n };\n const entry = original.match(/^\\s*[\"']?bun[\"']?\\s*=\\s*(.+)$/);\n if (entry !== null && section === \"tools\")\n checkMiseVersion(entry[1] ?? \"\");\n const dotted = original.match(\n /^\\s*tools\\.bun(?:\\.version)?\\s*=\\s*(.+)$/,\n );\n if (dotted !== null && section === \"\")\n checkMiseVersion(dotted[1] ?? \"\");\n const tableVersion = original.match(/^\\s*version\\s*=\\s*(.+)$/);\n if (tableVersion !== null && section === \"tools.bun\")\n checkMiseVersion(tableVersion[1] ?? \"\");\n const inlineTools = original.match(/^\\s*tools\\s*=\\s*\\{(.*)\\}/);\n if (inlineTools !== null && section === \"\") {\n const inlineBun = inlineTools[1]?.match(\n /(?:^|,)\\s*[\"']?bun[\"']?\\s*=\\s*(\\{[^}]*\\}|[^,}]+)/,\n );\n if (inlineBun !== null && inlineBun !== undefined)\n checkMiseVersion(inlineBun[1] ?? \"\");\n }\n }\n }\n }\n return diagnostics;\n};\n","#!/usr/bin/env node\nimport { readFileSync } from \"node:fs\";\n\nimport { checkToolchain } from \"./toolchain-check\";\n\ntry {\n const allowNonBunPackageManagers: string[] = [];\n const args = process.argv.slice(2);\n for (let index = 0; index < args.length; index += 1) {\n const argument = args[index];\n if (argument === \"--help\") {\n process.stdout.write(\n \"Usage: stll-toolchain-check [--allow-non-bun-package-manager <tracked package.json path>]\\n\",\n );\n process.exit(0);\n }\n const value = args.at(index + 1);\n if (\n argument !== \"--allow-non-bun-package-manager\" ||\n value === undefined ||\n value.startsWith(\"--\")\n ) {\n throw new Error(`unexpected or incomplete argument: ${argument}`);\n }\n allowNonBunPackageManagers.push(value);\n index += 1;\n }\n const toolchain: unknown = JSON.parse(\n readFileSync(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n );\n if (\n typeof toolchain !== \"object\" ||\n toolchain === null ||\n !(\"bun\" in toolchain) ||\n typeof toolchain.bun !== \"string\"\n ) {\n throw new Error(\"installed toolchain.json must define a Bun version\");\n }\n const diagnostics = checkToolchain({\n root: process.cwd(),\n bunVersion: toolchain.bun,\n allowNonBunPackageManagers,\n });\n for (const diagnostic of diagnostics)\n process.stderr.write(\n `${diagnostic.path}:${diagnostic.line}: ${diagnostic.message}\\n`,\n );\n if (diagnostics.length > 0) process.exitCode = 1;\n} catch (error) {\n process.stderr.write(\n `toolchain-check:1: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
//#region src/toolchain-check.ts
|
|
6
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
7
|
+
const scalar = (value) => value.trim().replace(/\s+#.*$/, "").replace(/^["']|["']$/g, "");
|
|
8
|
+
const trackedPath = (file) => !file.split("/").some((part) => part === "node_modules" || part === "vendor");
|
|
9
|
+
/** Check tracked consumer files without traversing dependencies or the working tree. */
|
|
10
|
+
const checkToolchain = ({ root, bunVersion, allowNonBunPackageManagers = [] }) => {
|
|
11
|
+
const files = execFileSync("git", [
|
|
12
|
+
"ls-files",
|
|
13
|
+
"-z",
|
|
14
|
+
"--cached"
|
|
15
|
+
], {
|
|
16
|
+
cwd: root,
|
|
17
|
+
encoding: "utf8"
|
|
18
|
+
}).split("\0").filter((file) => file !== "" && trackedPath(file));
|
|
19
|
+
const tracked = new Set(files);
|
|
20
|
+
const diagnostics = [];
|
|
21
|
+
const add = (file, line, message) => {
|
|
22
|
+
diagnostics.push({
|
|
23
|
+
path: file,
|
|
24
|
+
line,
|
|
25
|
+
message
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
const read = (file) => {
|
|
29
|
+
try {
|
|
30
|
+
return readFileSync(path.join(root, file), "utf8");
|
|
31
|
+
} catch {
|
|
32
|
+
add(file, 1, "cannot read tracked file");
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
const checkVersion = (file, line, value, label) => {
|
|
37
|
+
if (value !== bunVersion) add(file, line, `${label} must be ${bunVersion}, found ${String(value)}`);
|
|
38
|
+
};
|
|
39
|
+
const packages = /* @__PURE__ */ new Map();
|
|
40
|
+
for (const file of files.filter((entry) => path.basename(entry) === "package.json")) {
|
|
41
|
+
const text = read(file);
|
|
42
|
+
if (text === void 0) continue;
|
|
43
|
+
let json;
|
|
44
|
+
try {
|
|
45
|
+
json = JSON.parse(text);
|
|
46
|
+
} catch {
|
|
47
|
+
add(file, 1, "invalid package.json");
|
|
48
|
+
continue;
|
|
49
|
+
}
|
|
50
|
+
if (!isRecord(json)) {
|
|
51
|
+
add(file, 1, "package.json must contain an object");
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
packages.set(file, {
|
|
55
|
+
manager: json["packageManager"],
|
|
56
|
+
json,
|
|
57
|
+
text
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
const catalogSource = (json) => isRecord(json["workspaces"]) ? json["workspaces"] : json;
|
|
61
|
+
const rootCatalogs = catalogSource(packages.get("package.json")?.json ?? {});
|
|
62
|
+
for (const [file, { json, text }] of packages) {
|
|
63
|
+
const lines = text.split(/\r?\n/);
|
|
64
|
+
const reportedLines = /* @__PURE__ */ new Map();
|
|
65
|
+
const propertyLine = (key, value) => {
|
|
66
|
+
const serialized = value === void 0 ? void 0 : JSON.stringify(value);
|
|
67
|
+
const matchKey = `${key}:${serialized ?? ""}`;
|
|
68
|
+
const previous = reportedLines.get(matchKey) ?? -1;
|
|
69
|
+
const index = lines.findIndex((line, lineIndex) => lineIndex > previous && line.includes(`"${key}"`) && (serialized === void 0 || line.includes(serialized)));
|
|
70
|
+
if (index >= 0) reportedLines.set(matchKey, index);
|
|
71
|
+
return Math.max(1, index + 1);
|
|
72
|
+
};
|
|
73
|
+
if (json["packageManager"] !== void 0) {
|
|
74
|
+
if (typeof json["packageManager"] === "string" && json["packageManager"].startsWith("bun@")) checkVersion(file, propertyLine("packageManager"), json["packageManager"].slice(4), "packageManager Bun version");
|
|
75
|
+
else if (!allowNonBunPackageManagers.includes(file)) add(file, propertyLine("packageManager"), "packageManager is not Bun; use --allow-non-bun-package-manager with this path to allow it");
|
|
76
|
+
}
|
|
77
|
+
const checkDependencies = (value, resolveCatalog = false) => {
|
|
78
|
+
if (!isRecord(value) || value["bun-types"] === void 0) return;
|
|
79
|
+
const specifier = value["bun-types"];
|
|
80
|
+
const resolveVersion = () => {
|
|
81
|
+
if (!resolveCatalog || typeof specifier !== "string" || !specifier.startsWith("catalog:")) return specifier;
|
|
82
|
+
const catalogName = specifier.slice(8);
|
|
83
|
+
const source = file === "package.json" ? catalogSource(json) : rootCatalogs;
|
|
84
|
+
const catalog = catalogName === "" ? source["catalog"] : isRecord(source["catalogs"]) && source["catalogs"][catalogName];
|
|
85
|
+
return isRecord(catalog) ? catalog["bun-types"] : void 0;
|
|
86
|
+
};
|
|
87
|
+
checkVersion(file, propertyLine("bun-types", specifier), resolveVersion(), "bun-types");
|
|
88
|
+
};
|
|
89
|
+
checkDependencies(json["dependencies"], true);
|
|
90
|
+
checkDependencies(json["devDependencies"], true);
|
|
91
|
+
checkDependencies(json["catalog"]);
|
|
92
|
+
if (isRecord(json["catalogs"])) for (const catalog of Object.values(json["catalogs"])) checkDependencies(catalog);
|
|
93
|
+
if (isRecord(json["workspaces"])) {
|
|
94
|
+
checkDependencies(json["workspaces"]["catalog"]);
|
|
95
|
+
if (isRecord(json["workspaces"]["catalogs"])) for (const catalog of Object.values(json["workspaces"]["catalogs"])) checkDependencies(catalog);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
for (const file of files) {
|
|
99
|
+
const name = path.basename(file);
|
|
100
|
+
const workflow = /^\.github\/workflows\/[^/]+\.ya?ml$/.test(file) || /^\.github\/actions\/.+\/action\.ya?ml$/.test(file);
|
|
101
|
+
const dockerfile = name.startsWith("Dockerfile") || name === "Containerfile";
|
|
102
|
+
const versionFile = name === ".bun-version" || name === ".tool-versions";
|
|
103
|
+
const mise = name === "mise.toml" || name === ".mise.toml";
|
|
104
|
+
if (!workflow && !dockerfile && !versionFile && !mise) continue;
|
|
105
|
+
const text = read(file);
|
|
106
|
+
if (text === void 0) continue;
|
|
107
|
+
if (name === ".bun-version") checkVersion(file, 1, scalar(text), ".bun-version");
|
|
108
|
+
let section = "";
|
|
109
|
+
for (const [index, original] of text.split(/\r?\n/).entries()) {
|
|
110
|
+
const line = index + 1;
|
|
111
|
+
if (/^\s*#/.test(original) || original.trim() === "") continue;
|
|
112
|
+
if (workflow) {
|
|
113
|
+
if (original.match(/(?:^\s*(?:-\s*)?|[{,]\s*)["']?bun-version["']?\s*:/) !== null) add(file, line, "bun-version literals are forbidden; use bun-version-file pointing to a package.json with the shared Bun pin");
|
|
114
|
+
const reference = original.match(/(?:^\s*(?:-\s*)?|[{,]\s*)["']?bun-version-file["']?\s*:\s*(?:"([^"]*)"|'([^']*)'|([^,}]*))/);
|
|
115
|
+
if (reference !== null) {
|
|
116
|
+
const target = scalar(reference[1] ?? reference[2] ?? reference[3] ?? "");
|
|
117
|
+
const normalized = path.posix.normalize(target);
|
|
118
|
+
const pkg = packages.get(normalized);
|
|
119
|
+
if (target === "" || path.posix.isAbsolute(target) || normalized.startsWith("../") || !tracked.has(normalized) || path.basename(normalized) !== "package.json" || pkg?.manager !== `bun@${bunVersion}`) add(file, line, `bun-version-file must reference a tracked package.json with packageManager bun@${bunVersion}, found ${target}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
if (dockerfile) {
|
|
123
|
+
const image = original.match(/^\s*FROM\s+(?:--\S+\s+)*oven\/bun(?::([^\s@]+))?(?:@\S+)?(?:\s|$)/i);
|
|
124
|
+
if (image !== null) {
|
|
125
|
+
const tag = image[1];
|
|
126
|
+
if (tag !== void 0) {
|
|
127
|
+
const version = tag.match(/^(\d+\.\d+\.\d+)(?:-|$)/)?.[1];
|
|
128
|
+
checkVersion(file, line, version ?? tag, "oven/bun version");
|
|
129
|
+
} else if (!/oven\/bun@/i.test(original)) add(file, line, `oven/bun must use a ${bunVersion} version tag`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (name === ".tool-versions") {
|
|
133
|
+
const entry = original.match(/^\s*bun\s+(.+)$/);
|
|
134
|
+
if (entry !== null) checkVersion(file, line, scalar(entry[1] ?? ""), ".tool-versions Bun version");
|
|
135
|
+
}
|
|
136
|
+
if (mise) {
|
|
137
|
+
const heading = original.match(/^\s*\[([^\]]+)\]/);
|
|
138
|
+
if (heading !== null) section = heading[1] ?? "";
|
|
139
|
+
const checkMiseVersion = (value) => {
|
|
140
|
+
const inlineVersion = [...value.matchAll(/[,{]\s*([\w-]+|"[^"]+"|'[^']+')\s*=\s*("(?:\\.|[^"\\])*"|'[^']*'|[^,{}]+)\s*(?=[,}])/g)].find((field) => scalar(field[1] ?? "") === "version");
|
|
141
|
+
checkVersion(file, line, scalar(inlineVersion?.[2] ?? value), "mise Bun version");
|
|
142
|
+
};
|
|
143
|
+
const entry = original.match(/^\s*["']?bun["']?\s*=\s*(.+)$/);
|
|
144
|
+
if (entry !== null && section === "tools") checkMiseVersion(entry[1] ?? "");
|
|
145
|
+
const dotted = original.match(/^\s*tools\.bun(?:\.version)?\s*=\s*(.+)$/);
|
|
146
|
+
if (dotted !== null && section === "") checkMiseVersion(dotted[1] ?? "");
|
|
147
|
+
const tableVersion = original.match(/^\s*version\s*=\s*(.+)$/);
|
|
148
|
+
if (tableVersion !== null && section === "tools.bun") checkMiseVersion(tableVersion[1] ?? "");
|
|
149
|
+
const inlineTools = original.match(/^\s*tools\s*=\s*\{(.*)\}/);
|
|
150
|
+
if (inlineTools !== null && section === "") {
|
|
151
|
+
const inlineBun = inlineTools[1]?.match(/(?:^|,)\s*["']?bun["']?\s*=\s*(\{[^}]*\}|[^,}]+)/);
|
|
152
|
+
if (inlineBun !== null && inlineBun !== void 0) checkMiseVersion(inlineBun[1] ?? "");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return diagnostics;
|
|
158
|
+
};
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/toolchain-check-cli.ts
|
|
161
|
+
try {
|
|
162
|
+
const allowNonBunPackageManagers = [];
|
|
163
|
+
const args = process.argv.slice(2);
|
|
164
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
165
|
+
const argument = args[index];
|
|
166
|
+
if (argument === "--help") {
|
|
167
|
+
process.stdout.write("Usage: stll-toolchain-check [--allow-non-bun-package-manager <tracked package.json path>]\n");
|
|
168
|
+
process.exit(0);
|
|
169
|
+
}
|
|
170
|
+
const value = args.at(index + 1);
|
|
171
|
+
if (argument !== "--allow-non-bun-package-manager" || value === void 0 || value.startsWith("--")) throw new Error(`unexpected or incomplete argument: ${argument}`);
|
|
172
|
+
allowNonBunPackageManagers.push(value);
|
|
173
|
+
index += 1;
|
|
174
|
+
}
|
|
175
|
+
const toolchain = JSON.parse(readFileSync(new URL("../toolchain.json", import.meta.url), "utf8"));
|
|
176
|
+
if (typeof toolchain !== "object" || toolchain === null || !("bun" in toolchain) || typeof toolchain.bun !== "string") throw new Error("installed toolchain.json must define a Bun version");
|
|
177
|
+
const diagnostics = checkToolchain({
|
|
178
|
+
root: process.cwd(),
|
|
179
|
+
bunVersion: toolchain.bun,
|
|
180
|
+
allowNonBunPackageManagers
|
|
181
|
+
});
|
|
182
|
+
for (const diagnostic of diagnostics) process.stderr.write(`${diagnostic.path}:${diagnostic.line}: ${diagnostic.message}\n`);
|
|
183
|
+
if (diagnostics.length > 0) process.exitCode = 1;
|
|
184
|
+
} catch (error) {
|
|
185
|
+
process.stderr.write(`toolchain-check:1: ${error instanceof Error ? error.message : String(error)}\n`);
|
|
186
|
+
process.exitCode = 1;
|
|
187
|
+
}
|
|
188
|
+
//#endregion
|
|
189
|
+
export {};
|
|
190
|
+
|
|
191
|
+
//# sourceMappingURL=toolchain-check-cli.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toolchain-check-cli.mjs","names":[],"sources":["../src/toolchain-check.ts","../src/toolchain-check-cli.ts"],"sourcesContent":["import { execFileSync } from \"node:child_process\";\nimport { readFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport type ToolchainDiagnostic = {\n path: string;\n line: number;\n message: string;\n};\n\nexport type CheckToolchainOptions = {\n root: string;\n bunVersion: string;\n allowNonBunPackageManagers?: readonly string[];\n};\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === \"object\" && value !== null && !Array.isArray(value);\n\nconst scalar = (value: string) =>\n value\n .trim()\n .replace(/\\s+#.*$/, \"\")\n .replace(/^[\"']|[\"']$/g, \"\");\n\nconst trackedPath = (file: string) =>\n !file.split(\"/\").some((part) => part === \"node_modules\" || part === \"vendor\");\n\n/** Check tracked consumer files without traversing dependencies or the working tree. */\nexport const checkToolchain = ({\n root,\n bunVersion,\n allowNonBunPackageManagers = [],\n}: CheckToolchainOptions): ToolchainDiagnostic[] => {\n const files = execFileSync(\"git\", [\"ls-files\", \"-z\", \"--cached\"], {\n cwd: root,\n encoding: \"utf8\",\n })\n .split(\"\\0\")\n .filter((file) => file !== \"\" && trackedPath(file));\n const tracked = new Set(files);\n const diagnostics: ToolchainDiagnostic[] = [];\n const add = (file: string, line: number, message: string) => {\n diagnostics.push({ path: file, line, message });\n };\n const read = (file: string): string | undefined => {\n try {\n return readFileSync(path.join(root, file), \"utf8\");\n } catch {\n add(file, 1, \"cannot read tracked file\");\n return undefined;\n }\n };\n const checkVersion = (\n file: string,\n line: number,\n value: unknown,\n label: string,\n ) => {\n if (value !== bunVersion) {\n add(file, line, `${label} must be ${bunVersion}, found ${String(value)}`);\n }\n };\n const packages = new Map<\n string,\n { manager: unknown; json: Record<string, unknown>; text: string }\n >();\n for (const file of files.filter(\n (entry) => path.basename(entry) === \"package.json\",\n )) {\n const text = read(file);\n if (text === undefined) continue;\n let json: unknown;\n try {\n json = JSON.parse(text);\n } catch {\n add(file, 1, \"invalid package.json\");\n continue;\n }\n if (!isRecord(json)) {\n add(file, 1, \"package.json must contain an object\");\n continue;\n }\n packages.set(file, { manager: json[\"packageManager\"], json, text });\n }\n const catalogSource = (json: Record<string, unknown>) =>\n isRecord(json[\"workspaces\"]) ? json[\"workspaces\"] : json;\n const rootCatalogs = catalogSource(packages.get(\"package.json\")?.json ?? {});\n for (const [file, { json, text }] of packages) {\n const lines = text.split(/\\r?\\n/);\n const reportedLines = new Map<string, number>();\n const propertyLine = (key: string, value?: unknown) => {\n const serialized =\n value === undefined ? undefined : JSON.stringify(value);\n const matchKey = `${key}:${serialized ?? \"\"}`;\n const previous = reportedLines.get(matchKey) ?? -1;\n const index = lines.findIndex(\n (line, lineIndex) =>\n lineIndex > previous &&\n line.includes(`\"${key}\"`) &&\n (serialized === undefined || line.includes(serialized)),\n );\n if (index >= 0) reportedLines.set(matchKey, index);\n return Math.max(1, index + 1);\n };\n if (json[\"packageManager\"] !== undefined) {\n if (\n typeof json[\"packageManager\"] === \"string\" &&\n json[\"packageManager\"].startsWith(\"bun@\")\n ) {\n checkVersion(\n file,\n propertyLine(\"packageManager\"),\n json[\"packageManager\"].slice(4),\n \"packageManager Bun version\",\n );\n } else if (!allowNonBunPackageManagers.includes(file)) {\n add(\n file,\n propertyLine(\"packageManager\"),\n \"packageManager is not Bun; use --allow-non-bun-package-manager with this path to allow it\",\n );\n }\n }\n const checkDependencies = (value: unknown, resolveCatalog = false) => {\n if (!isRecord(value) || value[\"bun-types\"] === undefined) return;\n const specifier = value[\"bun-types\"];\n const resolveVersion = () => {\n if (\n !resolveCatalog ||\n typeof specifier !== \"string\" ||\n !specifier.startsWith(\"catalog:\")\n )\n return specifier;\n const catalogName = specifier.slice(\"catalog:\".length);\n const source =\n file === \"package.json\" ? catalogSource(json) : rootCatalogs;\n const catalog =\n catalogName === \"\"\n ? source[\"catalog\"]\n : isRecord(source[\"catalogs\"]) && source[\"catalogs\"][catalogName];\n return isRecord(catalog) ? catalog[\"bun-types\"] : undefined;\n };\n checkVersion(\n file,\n propertyLine(\"bun-types\", specifier),\n resolveVersion(),\n \"bun-types\",\n );\n };\n checkDependencies(json[\"dependencies\"], true);\n checkDependencies(json[\"devDependencies\"], true);\n checkDependencies(json[\"catalog\"]);\n if (isRecord(json[\"catalogs\"])) {\n for (const catalog of Object.values(json[\"catalogs\"]))\n checkDependencies(catalog);\n }\n if (isRecord(json[\"workspaces\"])) {\n checkDependencies(json[\"workspaces\"][\"catalog\"]);\n if (isRecord(json[\"workspaces\"][\"catalogs\"])) {\n for (const catalog of Object.values(json[\"workspaces\"][\"catalogs\"]))\n checkDependencies(catalog);\n }\n }\n }\n for (const file of files) {\n const name = path.basename(file);\n const workflow =\n /^\\.github\\/workflows\\/[^/]+\\.ya?ml$/.test(file) ||\n /^\\.github\\/actions\\/.+\\/action\\.ya?ml$/.test(file);\n const dockerfile =\n name.startsWith(\"Dockerfile\") || name === \"Containerfile\";\n const versionFile = name === \".bun-version\" || name === \".tool-versions\";\n const mise = name === \"mise.toml\" || name === \".mise.toml\";\n if (!workflow && !dockerfile && !versionFile && !mise) continue;\n const text = read(file);\n if (text === undefined) continue;\n if (name === \".bun-version\")\n checkVersion(file, 1, scalar(text), \".bun-version\");\n let section = \"\";\n for (const [index, original] of text.split(/\\r?\\n/).entries()) {\n const line = index + 1;\n if (/^\\s*#/.test(original) || original.trim() === \"\") continue;\n if (workflow) {\n const pin = original.match(\n /(?:^\\s*(?:-\\s*)?|[{,]\\s*)[\"']?bun-version[\"']?\\s*:/,\n );\n if (pin !== null)\n add(\n file,\n line,\n \"bun-version literals are forbidden; use bun-version-file pointing to a package.json with the shared Bun pin\",\n );\n const reference = original.match(\n /(?:^\\s*(?:-\\s*)?|[{,]\\s*)[\"']?bun-version-file[\"']?\\s*:\\s*(?:\"([^\"]*)\"|'([^']*)'|([^,}]*))/,\n );\n if (reference !== null) {\n const target = scalar(\n reference[1] ?? reference[2] ?? reference[3] ?? \"\",\n );\n const normalized = path.posix.normalize(target);\n const pkg = packages.get(normalized);\n if (\n target === \"\" ||\n path.posix.isAbsolute(target) ||\n normalized.startsWith(\"../\") ||\n !tracked.has(normalized) ||\n path.basename(normalized) !== \"package.json\" ||\n pkg?.manager !== `bun@${bunVersion}`\n ) {\n add(\n file,\n line,\n `bun-version-file must reference a tracked package.json with packageManager bun@${bunVersion}, found ${target}`,\n );\n }\n }\n }\n if (dockerfile) {\n const image = original.match(\n /^\\s*FROM\\s+(?:--\\S+\\s+)*oven\\/bun(?::([^\\s@]+))?(?:@\\S+)?(?:\\s|$)/i,\n );\n if (image !== null) {\n const tag = image[1];\n if (tag !== undefined) {\n const version = tag.match(/^(\\d+\\.\\d+\\.\\d+)(?:-|$)/)?.[1];\n checkVersion(file, line, version ?? tag, \"oven/bun version\");\n } else if (!/oven\\/bun@/i.test(original)) {\n add(file, line, `oven/bun must use a ${bunVersion} version tag`);\n }\n }\n }\n if (name === \".tool-versions\") {\n const entry = original.match(/^\\s*bun\\s+(.+)$/);\n if (entry !== null)\n checkVersion(\n file,\n line,\n scalar(entry[1] ?? \"\"),\n \".tool-versions Bun version\",\n );\n }\n if (mise) {\n const heading = original.match(/^\\s*\\[([^\\]]+)\\]/);\n if (heading !== null) section = heading[1] ?? \"\";\n const checkMiseVersion = (value: string) => {\n const inlineVersion = [\n ...value.matchAll(\n /[,{]\\s*([\\w-]+|\"[^\"]+\"|'[^']+')\\s*=\\s*(\"(?:\\\\.|[^\"\\\\])*\"|'[^']*'|[^,{}]+)\\s*(?=[,}])/g,\n ),\n ].find((field) => scalar(field[1] ?? \"\") === \"version\");\n checkVersion(\n file,\n line,\n scalar(inlineVersion?.[2] ?? value),\n \"mise Bun version\",\n );\n };\n const entry = original.match(/^\\s*[\"']?bun[\"']?\\s*=\\s*(.+)$/);\n if (entry !== null && section === \"tools\")\n checkMiseVersion(entry[1] ?? \"\");\n const dotted = original.match(\n /^\\s*tools\\.bun(?:\\.version)?\\s*=\\s*(.+)$/,\n );\n if (dotted !== null && section === \"\")\n checkMiseVersion(dotted[1] ?? \"\");\n const tableVersion = original.match(/^\\s*version\\s*=\\s*(.+)$/);\n if (tableVersion !== null && section === \"tools.bun\")\n checkMiseVersion(tableVersion[1] ?? \"\");\n const inlineTools = original.match(/^\\s*tools\\s*=\\s*\\{(.*)\\}/);\n if (inlineTools !== null && section === \"\") {\n const inlineBun = inlineTools[1]?.match(\n /(?:^|,)\\s*[\"']?bun[\"']?\\s*=\\s*(\\{[^}]*\\}|[^,}]+)/,\n );\n if (inlineBun !== null && inlineBun !== undefined)\n checkMiseVersion(inlineBun[1] ?? \"\");\n }\n }\n }\n }\n return diagnostics;\n};\n","#!/usr/bin/env node\nimport { readFileSync } from \"node:fs\";\n\nimport { checkToolchain } from \"./toolchain-check\";\n\ntry {\n const allowNonBunPackageManagers: string[] = [];\n const args = process.argv.slice(2);\n for (let index = 0; index < args.length; index += 1) {\n const argument = args[index];\n if (argument === \"--help\") {\n process.stdout.write(\n \"Usage: stll-toolchain-check [--allow-non-bun-package-manager <tracked package.json path>]\\n\",\n );\n process.exit(0);\n }\n const value = args.at(index + 1);\n if (\n argument !== \"--allow-non-bun-package-manager\" ||\n value === undefined ||\n value.startsWith(\"--\")\n ) {\n throw new Error(`unexpected or incomplete argument: ${argument}`);\n }\n allowNonBunPackageManagers.push(value);\n index += 1;\n }\n const toolchain: unknown = JSON.parse(\n readFileSync(new URL(\"../toolchain.json\", import.meta.url), \"utf8\"),\n );\n if (\n typeof toolchain !== \"object\" ||\n toolchain === null ||\n !(\"bun\" in toolchain) ||\n typeof toolchain.bun !== \"string\"\n ) {\n throw new Error(\"installed toolchain.json must define a Bun version\");\n }\n const diagnostics = checkToolchain({\n root: process.cwd(),\n bunVersion: toolchain.bun,\n allowNonBunPackageManagers,\n });\n for (const diagnostic of diagnostics)\n process.stderr.write(\n `${diagnostic.path}:${diagnostic.line}: ${diagnostic.message}\\n`,\n );\n if (diagnostics.length > 0) process.exitCode = 1;\n} catch (error) {\n process.stderr.write(\n `toolchain-check:1: ${error instanceof Error ? error.message : String(error)}\\n`,\n );\n process.exitCode = 1;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/oxlint-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.8.0",
|
|
4
4
|
"description": "Shared general oxlint configuration for stella packages.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -8,8 +8,12 @@
|
|
|
8
8
|
"url": "git+https://github.com/stella/tooling.git",
|
|
9
9
|
"directory": "packages/oxlint-config"
|
|
10
10
|
},
|
|
11
|
+
"bin": {
|
|
12
|
+
"stll-toolchain-check": "./dist/toolchain-check-cli.mjs"
|
|
13
|
+
},
|
|
11
14
|
"files": [
|
|
12
|
-
"dist"
|
|
15
|
+
"dist",
|
|
16
|
+
"toolchain.json"
|
|
13
17
|
],
|
|
14
18
|
"type": "module",
|
|
15
19
|
"main": "dist/index.mjs",
|
|
@@ -47,7 +51,8 @@
|
|
|
47
51
|
"default": "./dist/no-raw-colors.cjs"
|
|
48
52
|
},
|
|
49
53
|
"default": "./dist/no-raw-colors.mjs"
|
|
50
|
-
}
|
|
54
|
+
},
|
|
55
|
+
"./toolchain.json": "./toolchain.json"
|
|
51
56
|
},
|
|
52
57
|
"publishConfig": {
|
|
53
58
|
"access": "public"
|
|
@@ -61,11 +66,11 @@
|
|
|
61
66
|
"devDependencies": {
|
|
62
67
|
"@stll/typescript-config": "workspace:*",
|
|
63
68
|
"oxfmt": "0.48.0",
|
|
64
|
-
"oxlint": "1.
|
|
69
|
+
"oxlint": "1.81.0",
|
|
65
70
|
"typescript": "7.0.2"
|
|
66
71
|
},
|
|
67
72
|
"peerDependencies": {
|
|
68
|
-
"oxlint": ">=1.
|
|
73
|
+
"oxlint": ">=1.80.0 <2",
|
|
69
74
|
"oxlint-tsgolint": ">=7.0.2001 <8"
|
|
70
75
|
},
|
|
71
76
|
"engines": {
|
package/toolchain.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"bun": "1.4.3",
|
|
3
|
+
"typescript": "7.0.2",
|
|
4
|
+
"oxlint": "1.81.0",
|
|
5
|
+
"oxlint-tsgolint": "7.0.2001",
|
|
6
|
+
"typescriptInstallLayouts": [
|
|
7
|
+
{
|
|
8
|
+
"type": "direct",
|
|
9
|
+
"compilerPackage": "typescript",
|
|
10
|
+
"compilerSpecifier": "7.0.2",
|
|
11
|
+
"typecheckCommand": "tsc --noEmit"
|
|
12
|
+
},
|
|
13
|
+
{
|
|
14
|
+
"type": "split-compatibility",
|
|
15
|
+
"compilerPackage": "@typescript/native",
|
|
16
|
+
"compilerSpecifier": "npm:typescript@7.0.2",
|
|
17
|
+
"compatibilityPackage": "typescript",
|
|
18
|
+
"compatibilitySpecifier": "6.0.3",
|
|
19
|
+
"typecheckCommand": "node ./node_modules/@typescript/native/bin/tsc --noEmit"
|
|
20
|
+
}
|
|
21
|
+
],
|
|
22
|
+
"typescript6Compatibility": {
|
|
23
|
+
"version": "6.0.3",
|
|
24
|
+
"packageAlias": "typescript-compat",
|
|
25
|
+
"apiConsumers": ["TypeScript compiler API"],
|
|
26
|
+
"peerBlockers": [
|
|
27
|
+
"@astrojs/check",
|
|
28
|
+
"@typescript-eslint/utils",
|
|
29
|
+
"dependency-cruiser"
|
|
30
|
+
]
|
|
31
|
+
}
|
|
32
|
+
}
|