@stll/oxlint-config 0.2.0 → 0.3.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 +8 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -1
- package/dist/index.d.mts +3 -1
- package/dist/index.mjs +8 -2
- package/dist/index.mjs.map +1 -1
- package/dist/no-raw-colors.cjs +156 -0
- package/dist/no-raw-colors.cjs.map +1 -0
- package/dist/no-raw-colors.d.cts +35 -0
- package/dist/no-raw-colors.d.mts +36 -0
- package/dist/no-raw-colors.mjs +152 -0
- package/dist/no-raw-colors.mjs.map +1 -0
- package/package.json +13 -1
package/dist/index.cjs
CHANGED
|
@@ -5,6 +5,7 @@ Object.defineProperties(exports, {
|
|
|
5
5
|
let oxlint = require("oxlint");
|
|
6
6
|
//#region src/index.ts
|
|
7
7
|
const stellaLowercasePluginSpecifier = "@stll/oxlint-config/plugin";
|
|
8
|
+
const noRawColorsPluginSpecifier = "@stll/oxlint-config/no-raw-colors";
|
|
8
9
|
const libraryIgnorePatterns = [
|
|
9
10
|
"node_modules/",
|
|
10
11
|
"dist/",
|
|
@@ -21,6 +22,7 @@ const libraryRules = {
|
|
|
21
22
|
"no-nested-ternary": "error",
|
|
22
23
|
"no-void": ["error", { allowAsStatement: true }],
|
|
23
24
|
"stella-lowercase/stella-lowercase": "error",
|
|
25
|
+
"no-raw-colors/no-raw-colors": "error",
|
|
24
26
|
"typescript/no-explicit-any": "error",
|
|
25
27
|
"typescript/no-dynamic-delete": "error",
|
|
26
28
|
"typescript/no-misused-promises": ["error", { checksVoidReturn: { attributes: false } }],
|
|
@@ -99,7 +101,11 @@ const library = (options = {}) => (0, oxlint.defineConfig)({
|
|
|
99
101
|
typeAware: true,
|
|
100
102
|
...options.options
|
|
101
103
|
},
|
|
102
|
-
jsPlugins: [
|
|
104
|
+
jsPlugins: [
|
|
105
|
+
stellaLowercasePluginSpecifier,
|
|
106
|
+
noRawColorsPluginSpecifier,
|
|
107
|
+
...options.jsPlugins ?? []
|
|
108
|
+
],
|
|
103
109
|
ignorePatterns: [...libraryIgnorePatterns, ...options.ignorePatterns ?? []],
|
|
104
110
|
rules: {
|
|
105
111
|
...libraryRules,
|
|
@@ -114,6 +120,7 @@ exports.library = library;
|
|
|
114
120
|
exports.libraryIgnorePatterns = libraryIgnorePatterns;
|
|
115
121
|
exports.libraryOverrides = libraryOverrides;
|
|
116
122
|
exports.libraryRules = libraryRules;
|
|
123
|
+
exports.noRawColorsPluginSpecifier = noRawColorsPluginSpecifier;
|
|
117
124
|
exports.stellaLowercasePluginSpecifier = stellaLowercasePluginSpecifier;
|
|
118
125
|
|
|
119
126
|
//# 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\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\n rules?: Rules;\n};\n\nexport const stellaLowercasePluginSpecifier = \"@stll/oxlint-config/plugin\";\n\nexport const libraryIgnorePatterns = [\"node_modules/\", \"dist/\", \"coverage/\"];\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 \"stella-lowercase/stella-lowercase\": \"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\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\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 \"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 jsPlugins: [stellaLowercasePluginSpecifier
|
|
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\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\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\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 \"stella-lowercase/stella-lowercase\": \"error\",\n \"no-raw-colors/no-raw-colors\": \"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\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\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 \"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 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":";;;;;;AAcA,MAAa,iCAAiC;AAC9C,MAAa,6BAA6B;AAE1C,MAAa,wBAAwB;CAAC;CAAiB;CAAS;AAAW;AAE3E,MAAa,eAAe;CAC1B,cAAc;CACd,aAAa;CACb,iBAAiB;CACjB,oBAAoB;CACpB,yBAAyB;CACzB,yBAAyB;CACzB,gBAAgB;CAChB,qBAAqB;CACrB,WAAW,CAAC,SAAS,EAAE,kBAAkB,KAAK,CAAC;CAC/C,qCAAqC;CACrC,+BAA+B;CAE/B,8BAA8B;CAC9B,gCAAgC;CAChC,kCAAkC,CAChC,SACA,EAAE,kBAAkB,EAAE,YAAY,MAAM,EAAE,CAC5C;CACA,0CAA0C,CAAC,SAAS,MAAM;CAC1D,gCAAgC;CAChC,2BAA2B;CAC3B,kCAAkC;CAClC,6CAA6C;CAC7C,uCAAuC,CACrC,SACA,EAAE,6BAA6B,wBAAwB,CACzD;CACA,4CAA4C;CAC5C,0CAA0C,CACxC,SACA,EAAE,oCAAoC,KAAK,CAC7C;CACA,yCAAyC,CACvC,SACA;EAAE,qBAAqB;EAAM,sBAAsB;CAAK,CAC1D;CACA,2CAA2C,CACzC,SACA;EAAE,sBAAsB;EAAM,8BAA8B;CAAK,CACnE;CACA,wCAAwC,CACtC,SACA,EAAE,kBAAkB;EAAE,QAAQ;EAAM,SAAS;CAAK,EAAE,CACtD;CACA,+BAA+B;CAC/B,2BAA2B,CAAC,SAAS,iCAAiC;CAEtE,gCAAgC;CAChC,6BAA6B;CAC7B,qBAAqB;CACrB,0BAA0B;CAC1B,yBAAyB;CACzB,uCAAuC;CACvC,0BAA0B;CAC1B,2BAA2B;CAC3B,6BAA6B;CAE7B,mBAAmB;CACnB,0CAA0C;CAE1C,yBAAyB;CACzB,gCAAgC;CAChC,gCAAgC;CAChC,qCAAqC;CACrC,qBAAqB;CAErB,aAAa;CACb,eAAe;CACf,sBAAsB;CACtB,kBAAkB;CAClB,wBAAwB;CACxB,wBAAwB;CACxB,wBAAwB;CACxB,qBAAqB;CACrB,uBAAuB;CACvB,2BAA2B;CAC3B,wBAAwB;CACxB,0BAA0B;CAC1B,gCAAgC;CAChC,YAAY;CACZ,cAAc;CACd,cAAc;CACd,gBAAgB;AAClB;AAEA,MAAa,mBAAmB,CAC9B;CACE,OAAO;EAAC;EAAoC;EAAe;CAAc;CACzE,OAAO;EACL,cAAc;EACd,iBAAiB;EACjB,yBAAyB;CAC3B;AACF,CACF;AAEA,MAAa,WAAW,UAA0B,CAAC,OAAA,GAAA,OAAA,cACpC;CACX,SAAS;EACP,cAAc;EACd,+BAA+B;EAC/B,WAAW;EACX,GAAG,QAAQ;CACb;CACA,WAAW;EACT;EACA;EACA,GAAI,QAAQ,aAAa,CAAC;CAC5B;CACA,gBAAgB,CACd,GAAG,uBACH,GAAI,QAAQ,kBAAkB,CAAC,CACjC;CACA,OAAO;EACL,GAAG;EACH,GAAG,QAAQ;CACb;CACA,WAAW,CAAC,GAAG,kBAAkB,GAAI,QAAQ,aAAa,CAAC,CAAE;AAC/D,CAAC;AAEH,IAAA,cAAe,QAAQ"}
|
package/dist/index.d.cts
CHANGED
|
@@ -12,6 +12,7 @@ type LibraryOptions = {
|
|
|
12
12
|
rules?: Rules;
|
|
13
13
|
};
|
|
14
14
|
declare const stellaLowercasePluginSpecifier = "@stll/oxlint-config/plugin";
|
|
15
|
+
declare const noRawColorsPluginSpecifier = "@stll/oxlint-config/no-raw-colors";
|
|
15
16
|
declare const libraryIgnorePatterns: string[];
|
|
16
17
|
declare const libraryRules: {
|
|
17
18
|
"no-console": "off";
|
|
@@ -26,6 +27,7 @@ declare const libraryRules: {
|
|
|
26
27
|
allowAsStatement: boolean;
|
|
27
28
|
}];
|
|
28
29
|
"stella-lowercase/stella-lowercase": "error";
|
|
30
|
+
"no-raw-colors/no-raw-colors": "error";
|
|
29
31
|
"typescript/no-explicit-any": "error";
|
|
30
32
|
"typescript/no-dynamic-delete": "error";
|
|
31
33
|
"typescript/no-misused-promises": ["error", {
|
|
@@ -106,5 +108,5 @@ declare const libraryOverrides: {
|
|
|
106
108
|
declare const library: (options?: LibraryOptions) => OxlintConfig;
|
|
107
109
|
declare const _default: OxlintConfig;
|
|
108
110
|
//#endregion
|
|
109
|
-
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryRules, stellaLowercasePluginSpecifier };
|
|
111
|
+
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryRules, noRawColorsPluginSpecifier, stellaLowercasePluginSpecifier };
|
|
110
112
|
//# sourceMappingURL=index.d.cts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -12,6 +12,7 @@ type LibraryOptions = {
|
|
|
12
12
|
rules?: Rules;
|
|
13
13
|
};
|
|
14
14
|
declare const stellaLowercasePluginSpecifier = "@stll/oxlint-config/plugin";
|
|
15
|
+
declare const noRawColorsPluginSpecifier = "@stll/oxlint-config/no-raw-colors";
|
|
15
16
|
declare const libraryIgnorePatterns: string[];
|
|
16
17
|
declare const libraryRules: {
|
|
17
18
|
"no-console": "off";
|
|
@@ -26,6 +27,7 @@ declare const libraryRules: {
|
|
|
26
27
|
allowAsStatement: boolean;
|
|
27
28
|
}];
|
|
28
29
|
"stella-lowercase/stella-lowercase": "error";
|
|
30
|
+
"no-raw-colors/no-raw-colors": "error";
|
|
29
31
|
"typescript/no-explicit-any": "error";
|
|
30
32
|
"typescript/no-dynamic-delete": "error";
|
|
31
33
|
"typescript/no-misused-promises": ["error", {
|
|
@@ -106,5 +108,5 @@ declare const libraryOverrides: {
|
|
|
106
108
|
declare const library: (options?: LibraryOptions) => OxlintConfig;
|
|
107
109
|
declare const _default: OxlintConfig;
|
|
108
110
|
//#endregion
|
|
109
|
-
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryRules, stellaLowercasePluginSpecifier };
|
|
111
|
+
export { LibraryOptions, _default as default, library, libraryIgnorePatterns, libraryOverrides, libraryRules, noRawColorsPluginSpecifier, stellaLowercasePluginSpecifier };
|
|
110
112
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { defineConfig } from "oxlint";
|
|
2
2
|
//#region src/index.ts
|
|
3
3
|
const stellaLowercasePluginSpecifier = "@stll/oxlint-config/plugin";
|
|
4
|
+
const noRawColorsPluginSpecifier = "@stll/oxlint-config/no-raw-colors";
|
|
4
5
|
const libraryIgnorePatterns = [
|
|
5
6
|
"node_modules/",
|
|
6
7
|
"dist/",
|
|
@@ -17,6 +18,7 @@ const libraryRules = {
|
|
|
17
18
|
"no-nested-ternary": "error",
|
|
18
19
|
"no-void": ["error", { allowAsStatement: true }],
|
|
19
20
|
"stella-lowercase/stella-lowercase": "error",
|
|
21
|
+
"no-raw-colors/no-raw-colors": "error",
|
|
20
22
|
"typescript/no-explicit-any": "error",
|
|
21
23
|
"typescript/no-dynamic-delete": "error",
|
|
22
24
|
"typescript/no-misused-promises": ["error", { checksVoidReturn: { attributes: false } }],
|
|
@@ -95,7 +97,11 @@ const library = (options = {}) => defineConfig({
|
|
|
95
97
|
typeAware: true,
|
|
96
98
|
...options.options
|
|
97
99
|
},
|
|
98
|
-
jsPlugins: [
|
|
100
|
+
jsPlugins: [
|
|
101
|
+
stellaLowercasePluginSpecifier,
|
|
102
|
+
noRawColorsPluginSpecifier,
|
|
103
|
+
...options.jsPlugins ?? []
|
|
104
|
+
],
|
|
99
105
|
ignorePatterns: [...libraryIgnorePatterns, ...options.ignorePatterns ?? []],
|
|
100
106
|
rules: {
|
|
101
107
|
...libraryRules,
|
|
@@ -105,6 +111,6 @@ const library = (options = {}) => defineConfig({
|
|
|
105
111
|
});
|
|
106
112
|
var src_default = library();
|
|
107
113
|
//#endregion
|
|
108
|
-
export { src_default as default, library, libraryIgnorePatterns, libraryOverrides, libraryRules, stellaLowercasePluginSpecifier };
|
|
114
|
+
export { src_default as default, library, libraryIgnorePatterns, libraryOverrides, libraryRules, noRawColorsPluginSpecifier, stellaLowercasePluginSpecifier };
|
|
109
115
|
|
|
110
116
|
//# 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\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\n rules?: Rules;\n};\n\nexport const stellaLowercasePluginSpecifier = \"@stll/oxlint-config/plugin\";\n\nexport const libraryIgnorePatterns = [\"node_modules/\", \"dist/\", \"coverage/\"];\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 \"stella-lowercase/stella-lowercase\": \"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\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\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 \"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 jsPlugins: [stellaLowercasePluginSpecifier
|
|
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\"]>;\n\nexport type LibraryOptions = {\n jsPlugins?: JsPlugins;\n ignorePatterns?: string[];\n options?: Options;\n overrides?: OxlintOverride[];\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\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 \"stella-lowercase/stella-lowercase\": \"error\",\n \"no-raw-colors/no-raw-colors\": \"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\n \"import/no-cycle\": \"error\",\n \"import/consistent-type-specifier-style\": \"off\",\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 \"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 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":";;AAcA,MAAa,iCAAiC;AAC9C,MAAa,6BAA6B;AAE1C,MAAa,wBAAwB;CAAC;CAAiB;CAAS;AAAW;AAE3E,MAAa,eAAe;CAC1B,cAAc;CACd,aAAa;CACb,iBAAiB;CACjB,oBAAoB;CACpB,yBAAyB;CACzB,yBAAyB;CACzB,gBAAgB;CAChB,qBAAqB;CACrB,WAAW,CAAC,SAAS,EAAE,kBAAkB,KAAK,CAAC;CAC/C,qCAAqC;CACrC,+BAA+B;CAE/B,8BAA8B;CAC9B,gCAAgC;CAChC,kCAAkC,CAChC,SACA,EAAE,kBAAkB,EAAE,YAAY,MAAM,EAAE,CAC5C;CACA,0CAA0C,CAAC,SAAS,MAAM;CAC1D,gCAAgC;CAChC,2BAA2B;CAC3B,kCAAkC;CAClC,6CAA6C;CAC7C,uCAAuC,CACrC,SACA,EAAE,6BAA6B,wBAAwB,CACzD;CACA,4CAA4C;CAC5C,0CAA0C,CACxC,SACA,EAAE,oCAAoC,KAAK,CAC7C;CACA,yCAAyC,CACvC,SACA;EAAE,qBAAqB;EAAM,sBAAsB;CAAK,CAC1D;CACA,2CAA2C,CACzC,SACA;EAAE,sBAAsB;EAAM,8BAA8B;CAAK,CACnE;CACA,wCAAwC,CACtC,SACA,EAAE,kBAAkB;EAAE,QAAQ;EAAM,SAAS;CAAK,EAAE,CACtD;CACA,+BAA+B;CAC/B,2BAA2B,CAAC,SAAS,iCAAiC;CAEtE,gCAAgC;CAChC,6BAA6B;CAC7B,qBAAqB;CACrB,0BAA0B;CAC1B,yBAAyB;CACzB,uCAAuC;CACvC,0BAA0B;CAC1B,2BAA2B;CAC3B,6BAA6B;CAE7B,mBAAmB;CACnB,0CAA0C;CAE1C,yBAAyB;CACzB,gCAAgC;CAChC,gCAAgC;CAChC,qCAAqC;CACrC,qBAAqB;CAErB,aAAa;CACb,eAAe;CACf,sBAAsB;CACtB,kBAAkB;CAClB,wBAAwB;CACxB,wBAAwB;CACxB,wBAAwB;CACxB,qBAAqB;CACrB,uBAAuB;CACvB,2BAA2B;CAC3B,wBAAwB;CACxB,0BAA0B;CAC1B,gCAAgC;CAChC,YAAY;CACZ,cAAc;CACd,cAAc;CACd,gBAAgB;AAClB;AAEA,MAAa,mBAAmB,CAC9B;CACE,OAAO;EAAC;EAAoC;EAAe;CAAc;CACzE,OAAO;EACL,cAAc;EACd,iBAAiB;EACjB,yBAAyB;CAC3B;AACF,CACF;AAEA,MAAa,WAAW,UAA0B,CAAC,MACjD,aAAa;CACX,SAAS;EACP,cAAc;EACd,+BAA+B;EAC/B,WAAW;EACX,GAAG,QAAQ;CACb;CACA,WAAW;EACT;EACA;EACA,GAAI,QAAQ,aAAa,CAAC;CAC5B;CACA,gBAAgB,CACd,GAAG,uBACH,GAAI,QAAQ,kBAAkB,CAAC,CACjC;CACA,OAAO;EACL,GAAG;EACH,GAAG,QAAQ;CACb;CACA,WAAW,CAAC,GAAG,kBAAkB,GAAI,QAAQ,aAAa,CAAC,CAAE;AAC/D,CAAC;AAEH,IAAA,cAAe,QAAQ"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
Object.defineProperties(exports, {
|
|
2
|
+
__esModule: { value: true },
|
|
3
|
+
[Symbol.toStringTag]: { value: "Module" }
|
|
4
|
+
});
|
|
5
|
+
//#region src/no-raw-colors.ts
|
|
6
|
+
const isAstNode = (node) => typeof node === "object" && node !== null && "type" in node && typeof node.type === "string";
|
|
7
|
+
const SHADED_PALETTE_COLORS = [
|
|
8
|
+
"red",
|
|
9
|
+
"orange",
|
|
10
|
+
"amber",
|
|
11
|
+
"yellow",
|
|
12
|
+
"lime",
|
|
13
|
+
"green",
|
|
14
|
+
"emerald",
|
|
15
|
+
"teal",
|
|
16
|
+
"cyan",
|
|
17
|
+
"sky",
|
|
18
|
+
"blue",
|
|
19
|
+
"indigo",
|
|
20
|
+
"violet",
|
|
21
|
+
"purple",
|
|
22
|
+
"fuchsia",
|
|
23
|
+
"pink",
|
|
24
|
+
"rose",
|
|
25
|
+
"slate",
|
|
26
|
+
"gray",
|
|
27
|
+
"zinc",
|
|
28
|
+
"neutral",
|
|
29
|
+
"stone",
|
|
30
|
+
"taupe",
|
|
31
|
+
"mauve",
|
|
32
|
+
"mist",
|
|
33
|
+
"olive"
|
|
34
|
+
];
|
|
35
|
+
const COLOR_SHADES = [
|
|
36
|
+
"50",
|
|
37
|
+
"100",
|
|
38
|
+
"200",
|
|
39
|
+
"300",
|
|
40
|
+
"400",
|
|
41
|
+
"500",
|
|
42
|
+
"600",
|
|
43
|
+
"700",
|
|
44
|
+
"800",
|
|
45
|
+
"900",
|
|
46
|
+
"950"
|
|
47
|
+
];
|
|
48
|
+
const COLOR_PREFIXES = [
|
|
49
|
+
"accent",
|
|
50
|
+
"bg",
|
|
51
|
+
"border",
|
|
52
|
+
"border-b",
|
|
53
|
+
"border-e",
|
|
54
|
+
"border-l",
|
|
55
|
+
"border-r",
|
|
56
|
+
"border-s",
|
|
57
|
+
"border-t",
|
|
58
|
+
"border-x",
|
|
59
|
+
"border-y",
|
|
60
|
+
"caret",
|
|
61
|
+
"decoration",
|
|
62
|
+
"divide",
|
|
63
|
+
"drop-shadow",
|
|
64
|
+
"fill",
|
|
65
|
+
"from",
|
|
66
|
+
"inset-ring",
|
|
67
|
+
"inset-shadow",
|
|
68
|
+
"marker",
|
|
69
|
+
"outline",
|
|
70
|
+
"placeholder",
|
|
71
|
+
"ring",
|
|
72
|
+
"ring-offset",
|
|
73
|
+
"scrollbar-thumb",
|
|
74
|
+
"scrollbar-track",
|
|
75
|
+
"shadow",
|
|
76
|
+
"stroke",
|
|
77
|
+
"text",
|
|
78
|
+
"text-shadow",
|
|
79
|
+
"to",
|
|
80
|
+
"via"
|
|
81
|
+
].join("|");
|
|
82
|
+
const SHADED_PALETTE_COLOR_PATTERN = SHADED_PALETTE_COLORS.join("|");
|
|
83
|
+
const COLOR_SHADE_PATTERN = COLOR_SHADES.join("|");
|
|
84
|
+
const CLASS_COLOR_BOUNDARY = "(?:^|:)!?";
|
|
85
|
+
const SHADED_PALETTE_PATTERN = new RegExp(`${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:${SHADED_PALETTE_COLOR_PATTERN})-(?:${COLOR_SHADE_PATTERN})(?![\\w-])`);
|
|
86
|
+
const BW_PATTERN = new RegExp(`${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:white|black)(?![/\\w-])`);
|
|
87
|
+
const isRawColorClass = (value) => SHADED_PALETTE_PATTERN.test(value) || BW_PATTERN.test(value);
|
|
88
|
+
const checkValue = (context, node, value) => {
|
|
89
|
+
for (const token of value.split(/\s+/)) if (isRawColorClass(token)) context.report({
|
|
90
|
+
node,
|
|
91
|
+
messageId: "rawColor",
|
|
92
|
+
data: { match: token }
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
const IMPORT_EXPORT_SOURCE_PARENT_TYPES = new Set([
|
|
96
|
+
"ExportAllDeclaration",
|
|
97
|
+
"ExportNamedDeclaration",
|
|
98
|
+
"ImportDeclaration",
|
|
99
|
+
"TSExternalModuleReference",
|
|
100
|
+
"TSImportType"
|
|
101
|
+
]);
|
|
102
|
+
const isImportOrExportSource = (node) => {
|
|
103
|
+
const parent = node.parent;
|
|
104
|
+
return isAstNode(parent) && IMPORT_EXPORT_SOURCE_PARENT_TYPES.has(parent.type);
|
|
105
|
+
};
|
|
106
|
+
const isDynamicImportCall = (node) => {
|
|
107
|
+
if (node.type === "ImportExpression") return true;
|
|
108
|
+
if (node.type !== "CallExpression") return false;
|
|
109
|
+
const callee = node["callee"];
|
|
110
|
+
return isAstNode(callee) && callee.type === "Import";
|
|
111
|
+
};
|
|
112
|
+
const isDynamicImportSource = (node) => {
|
|
113
|
+
const parent = node.parent;
|
|
114
|
+
if (!isAstNode(parent)) return false;
|
|
115
|
+
if (isDynamicImportCall(parent)) return true;
|
|
116
|
+
if (parent.type !== "TemplateLiteral") return false;
|
|
117
|
+
const grandparent = parent.parent;
|
|
118
|
+
return isAstNode(grandparent) && isDynamicImportCall(grandparent);
|
|
119
|
+
};
|
|
120
|
+
const templateElementText = (node) => {
|
|
121
|
+
const value = node["value"];
|
|
122
|
+
if (typeof value !== "object" || value === null) return null;
|
|
123
|
+
const cooked = "cooked" in value ? value.cooked : null;
|
|
124
|
+
if (typeof cooked === "string") return cooked;
|
|
125
|
+
const raw = "raw" in value ? value.raw : null;
|
|
126
|
+
return typeof raw === "string" ? raw : null;
|
|
127
|
+
};
|
|
128
|
+
var no_raw_colors_default = {
|
|
129
|
+
meta: { name: "no-raw-colors" },
|
|
130
|
+
rules: { "no-raw-colors": {
|
|
131
|
+
meta: {
|
|
132
|
+
type: "problem",
|
|
133
|
+
messages: { rawColor: "Hardcoded color '{{match}}' bypasses semantic tokens. Use semantic tokens (bg-muted, text-foreground, bg-success/12, bg-warning/12, bg-destructive/12, etc.) instead." }
|
|
134
|
+
},
|
|
135
|
+
create(context) {
|
|
136
|
+
return {
|
|
137
|
+
Literal(node) {
|
|
138
|
+
const value = node["value"];
|
|
139
|
+
if (typeof value !== "string") return;
|
|
140
|
+
if (isImportOrExportSource(node) || isDynamicImportSource(node)) return;
|
|
141
|
+
checkValue(context, node, value);
|
|
142
|
+
},
|
|
143
|
+
TemplateElement(node) {
|
|
144
|
+
if (isDynamicImportSource(node)) return;
|
|
145
|
+
const value = templateElementText(node);
|
|
146
|
+
if (value === null) return;
|
|
147
|
+
checkValue(context, node, value);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
} }
|
|
152
|
+
};
|
|
153
|
+
//#endregion
|
|
154
|
+
exports.default = no_raw_colors_default;
|
|
155
|
+
|
|
156
|
+
//# sourceMappingURL=no-raw-colors.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-raw-colors.cjs","names":[],"sources":["../src/no-raw-colors.ts"],"sourcesContent":["// Detect hardcoded Tailwind color classes that bypass semantic tokens.\n//\n// Semantic tokens (bg-background, bg-muted, text-foreground, bg-success/12, …)\n// adapt via CSS variables and stay legible across themes. Raw palette colors\n// (bg-stone-50, text-gray-900, bg-emerald-100, text-amber-800, bg-white, …)\n// either break dark mode (neutrals) or pin a component to a hue that ignores\n// the design system. Use the semantic equivalents instead.\n\ntype AstNode = { type: string; parent?: unknown } & Record<string, unknown>;\n\ntype RuleContext = {\n report: (diagnostic: {\n node: unknown;\n messageId: \"rawColor\";\n data?: { match: string };\n }) => void;\n};\n\nconst isAstNode = (node: unknown): node is AstNode =>\n typeof node === \"object\" &&\n node !== null &&\n \"type\" in node &&\n typeof node.type === \"string\";\n\nconst SHADED_PALETTE_COLORS = [\n \"red\",\n \"orange\",\n \"amber\",\n \"yellow\",\n \"lime\",\n \"green\",\n \"emerald\",\n \"teal\",\n \"cyan\",\n \"sky\",\n \"blue\",\n \"indigo\",\n \"violet\",\n \"purple\",\n \"fuchsia\",\n \"pink\",\n \"rose\",\n \"slate\",\n \"gray\",\n \"zinc\",\n \"neutral\",\n \"stone\",\n \"taupe\",\n \"mauve\",\n \"mist\",\n \"olive\",\n] as const;\nconst COLOR_SHADES = [\n \"50\",\n \"100\",\n \"200\",\n \"300\",\n \"400\",\n \"500\",\n \"600\",\n \"700\",\n \"800\",\n \"900\",\n \"950\",\n] as const;\nconst COLOR_UTILITY_PREFIXES = [\n \"accent\",\n \"bg\",\n \"border\",\n \"border-b\",\n \"border-e\",\n \"border-l\",\n \"border-r\",\n \"border-s\",\n \"border-t\",\n \"border-x\",\n \"border-y\",\n \"caret\",\n \"decoration\",\n \"divide\",\n \"drop-shadow\",\n \"fill\",\n \"from\",\n \"inset-ring\",\n \"inset-shadow\",\n \"marker\",\n \"outline\",\n \"placeholder\",\n \"ring\",\n \"ring-offset\",\n \"scrollbar-thumb\",\n \"scrollbar-track\",\n \"shadow\",\n \"stroke\",\n \"text\",\n \"text-shadow\",\n \"to\",\n \"via\",\n] as const;\nconst COLOR_PREFIXES = COLOR_UTILITY_PREFIXES.join(\"|\");\nconst SHADED_PALETTE_COLOR_PATTERN = SHADED_PALETTE_COLORS.join(\"|\");\nconst COLOR_SHADE_PATTERN = COLOR_SHADES.join(\"|\");\nconst CLASS_COLOR_BOUNDARY = \"(?:^|:)!?\";\n\nconst SHADED_PALETTE_PATTERN = new RegExp(\n `${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:${SHADED_PALETTE_COLOR_PATTERN})-(?:${COLOR_SHADE_PATTERN})(?![\\\\w-])`,\n);\n// Standalone white/black utilities; permit opacity (bg-white/20) and compounds\n// (bg-whitesmoke) so only the bare palette tokens fire.\nconst BW_PATTERN = new RegExp(\n `${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:white|black)(?![/\\\\w-])`,\n);\n\nconst isRawColorClass = (value: string): boolean =>\n SHADED_PALETTE_PATTERN.test(value) || BW_PATTERN.test(value);\n\nconst checkValue = (\n context: RuleContext,\n node: unknown,\n value: string,\n): void => {\n for (const token of value.split(/\\s+/)) {\n if (isRawColorClass(token)) {\n context.report({\n node,\n messageId: \"rawColor\",\n data: { match: token },\n });\n }\n }\n};\n\nconst IMPORT_EXPORT_SOURCE_PARENT_TYPES = new Set([\n \"ExportAllDeclaration\",\n \"ExportNamedDeclaration\",\n \"ImportDeclaration\",\n \"TSExternalModuleReference\",\n \"TSImportType\",\n]);\n\nconst isImportOrExportSource = (node: AstNode): boolean => {\n const parent = node.parent;\n return (\n isAstNode(parent) && IMPORT_EXPORT_SOURCE_PARENT_TYPES.has(parent.type)\n );\n};\n\nconst isDynamicImportCall = (node: AstNode): boolean => {\n if (node.type === \"ImportExpression\") {\n return true;\n }\n if (node.type !== \"CallExpression\") {\n return false;\n }\n const callee = node[\"callee\"];\n return isAstNode(callee) && callee.type === \"Import\";\n};\n\nconst isDynamicImportSource = (node: AstNode): boolean => {\n const parent = node.parent;\n if (!isAstNode(parent)) {\n return false;\n }\n if (isDynamicImportCall(parent)) {\n return true;\n }\n if (parent.type !== \"TemplateLiteral\") {\n return false;\n }\n const grandparent = parent.parent;\n return isAstNode(grandparent) && isDynamicImportCall(grandparent);\n};\n\nconst templateElementText = (node: AstNode): string | null => {\n const value = node[\"value\"];\n if (typeof value !== \"object\" || value === null) {\n return null;\n }\n const cooked = \"cooked\" in value ? value.cooked : null;\n if (typeof cooked === \"string\") {\n return cooked;\n }\n const raw = \"raw\" in value ? value.raw : null;\n return typeof raw === \"string\" ? raw : null;\n};\n\nexport default {\n meta: { name: \"no-raw-colors\" },\n rules: {\n \"no-raw-colors\": {\n meta: {\n type: \"problem\",\n messages: {\n rawColor:\n \"Hardcoded color '{{match}}' bypasses semantic tokens. Use semantic tokens (bg-muted, text-foreground, bg-success/12, bg-warning/12, bg-destructive/12, etc.) instead.\",\n },\n },\n create(context: RuleContext) {\n return {\n Literal(node: AstNode) {\n const value = node[\"value\"];\n if (typeof value !== \"string\") {\n return;\n }\n if (isImportOrExportSource(node) || isDynamicImportSource(node)) {\n return;\n }\n checkValue(context, node, value);\n },\n TemplateElement(node: AstNode) {\n if (isDynamicImportSource(node)) {\n return;\n }\n const value = templateElementText(node);\n if (value === null) {\n return;\n }\n checkValue(context, node, value);\n },\n };\n },\n },\n },\n};\n"],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
//#region src/no-raw-colors.d.ts
|
|
2
|
+
type AstNode = {
|
|
3
|
+
type: string;
|
|
4
|
+
parent?: unknown;
|
|
5
|
+
} & Record<string, unknown>;
|
|
6
|
+
type RuleContext = {
|
|
7
|
+
report: (diagnostic: {
|
|
8
|
+
node: unknown;
|
|
9
|
+
messageId: "rawColor";
|
|
10
|
+
data?: {
|
|
11
|
+
match: string;
|
|
12
|
+
};
|
|
13
|
+
}) => void;
|
|
14
|
+
};
|
|
15
|
+
declare const _default: {
|
|
16
|
+
meta: {
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
19
|
+
rules: {
|
|
20
|
+
"no-raw-colors": {
|
|
21
|
+
meta: {
|
|
22
|
+
type: string;
|
|
23
|
+
messages: {
|
|
24
|
+
rawColor: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
create(context: RuleContext): {
|
|
28
|
+
Literal(node: AstNode): void;
|
|
29
|
+
TemplateElement(node: AstNode): void;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
export = _default;
|
|
35
|
+
//# sourceMappingURL=no-raw-colors.d.cts.map
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
//#region src/no-raw-colors.d.ts
|
|
2
|
+
type AstNode = {
|
|
3
|
+
type: string;
|
|
4
|
+
parent?: unknown;
|
|
5
|
+
} & Record<string, unknown>;
|
|
6
|
+
type RuleContext = {
|
|
7
|
+
report: (diagnostic: {
|
|
8
|
+
node: unknown;
|
|
9
|
+
messageId: "rawColor";
|
|
10
|
+
data?: {
|
|
11
|
+
match: string;
|
|
12
|
+
};
|
|
13
|
+
}) => void;
|
|
14
|
+
};
|
|
15
|
+
declare const _default: {
|
|
16
|
+
meta: {
|
|
17
|
+
name: string;
|
|
18
|
+
};
|
|
19
|
+
rules: {
|
|
20
|
+
"no-raw-colors": {
|
|
21
|
+
meta: {
|
|
22
|
+
type: string;
|
|
23
|
+
messages: {
|
|
24
|
+
rawColor: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
create(context: RuleContext): {
|
|
28
|
+
Literal(node: AstNode): void;
|
|
29
|
+
TemplateElement(node: AstNode): void;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
//#endregion
|
|
35
|
+
export { _default as default };
|
|
36
|
+
//# sourceMappingURL=no-raw-colors.d.mts.map
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
//#region src/no-raw-colors.ts
|
|
2
|
+
const isAstNode = (node) => typeof node === "object" && node !== null && "type" in node && typeof node.type === "string";
|
|
3
|
+
const SHADED_PALETTE_COLORS = [
|
|
4
|
+
"red",
|
|
5
|
+
"orange",
|
|
6
|
+
"amber",
|
|
7
|
+
"yellow",
|
|
8
|
+
"lime",
|
|
9
|
+
"green",
|
|
10
|
+
"emerald",
|
|
11
|
+
"teal",
|
|
12
|
+
"cyan",
|
|
13
|
+
"sky",
|
|
14
|
+
"blue",
|
|
15
|
+
"indigo",
|
|
16
|
+
"violet",
|
|
17
|
+
"purple",
|
|
18
|
+
"fuchsia",
|
|
19
|
+
"pink",
|
|
20
|
+
"rose",
|
|
21
|
+
"slate",
|
|
22
|
+
"gray",
|
|
23
|
+
"zinc",
|
|
24
|
+
"neutral",
|
|
25
|
+
"stone",
|
|
26
|
+
"taupe",
|
|
27
|
+
"mauve",
|
|
28
|
+
"mist",
|
|
29
|
+
"olive"
|
|
30
|
+
];
|
|
31
|
+
const COLOR_SHADES = [
|
|
32
|
+
"50",
|
|
33
|
+
"100",
|
|
34
|
+
"200",
|
|
35
|
+
"300",
|
|
36
|
+
"400",
|
|
37
|
+
"500",
|
|
38
|
+
"600",
|
|
39
|
+
"700",
|
|
40
|
+
"800",
|
|
41
|
+
"900",
|
|
42
|
+
"950"
|
|
43
|
+
];
|
|
44
|
+
const COLOR_PREFIXES = [
|
|
45
|
+
"accent",
|
|
46
|
+
"bg",
|
|
47
|
+
"border",
|
|
48
|
+
"border-b",
|
|
49
|
+
"border-e",
|
|
50
|
+
"border-l",
|
|
51
|
+
"border-r",
|
|
52
|
+
"border-s",
|
|
53
|
+
"border-t",
|
|
54
|
+
"border-x",
|
|
55
|
+
"border-y",
|
|
56
|
+
"caret",
|
|
57
|
+
"decoration",
|
|
58
|
+
"divide",
|
|
59
|
+
"drop-shadow",
|
|
60
|
+
"fill",
|
|
61
|
+
"from",
|
|
62
|
+
"inset-ring",
|
|
63
|
+
"inset-shadow",
|
|
64
|
+
"marker",
|
|
65
|
+
"outline",
|
|
66
|
+
"placeholder",
|
|
67
|
+
"ring",
|
|
68
|
+
"ring-offset",
|
|
69
|
+
"scrollbar-thumb",
|
|
70
|
+
"scrollbar-track",
|
|
71
|
+
"shadow",
|
|
72
|
+
"stroke",
|
|
73
|
+
"text",
|
|
74
|
+
"text-shadow",
|
|
75
|
+
"to",
|
|
76
|
+
"via"
|
|
77
|
+
].join("|");
|
|
78
|
+
const SHADED_PALETTE_COLOR_PATTERN = SHADED_PALETTE_COLORS.join("|");
|
|
79
|
+
const COLOR_SHADE_PATTERN = COLOR_SHADES.join("|");
|
|
80
|
+
const CLASS_COLOR_BOUNDARY = "(?:^|:)!?";
|
|
81
|
+
const SHADED_PALETTE_PATTERN = new RegExp(`${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:${SHADED_PALETTE_COLOR_PATTERN})-(?:${COLOR_SHADE_PATTERN})(?![\\w-])`);
|
|
82
|
+
const BW_PATTERN = new RegExp(`${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:white|black)(?![/\\w-])`);
|
|
83
|
+
const isRawColorClass = (value) => SHADED_PALETTE_PATTERN.test(value) || BW_PATTERN.test(value);
|
|
84
|
+
const checkValue = (context, node, value) => {
|
|
85
|
+
for (const token of value.split(/\s+/)) if (isRawColorClass(token)) context.report({
|
|
86
|
+
node,
|
|
87
|
+
messageId: "rawColor",
|
|
88
|
+
data: { match: token }
|
|
89
|
+
});
|
|
90
|
+
};
|
|
91
|
+
const IMPORT_EXPORT_SOURCE_PARENT_TYPES = new Set([
|
|
92
|
+
"ExportAllDeclaration",
|
|
93
|
+
"ExportNamedDeclaration",
|
|
94
|
+
"ImportDeclaration",
|
|
95
|
+
"TSExternalModuleReference",
|
|
96
|
+
"TSImportType"
|
|
97
|
+
]);
|
|
98
|
+
const isImportOrExportSource = (node) => {
|
|
99
|
+
const parent = node.parent;
|
|
100
|
+
return isAstNode(parent) && IMPORT_EXPORT_SOURCE_PARENT_TYPES.has(parent.type);
|
|
101
|
+
};
|
|
102
|
+
const isDynamicImportCall = (node) => {
|
|
103
|
+
if (node.type === "ImportExpression") return true;
|
|
104
|
+
if (node.type !== "CallExpression") return false;
|
|
105
|
+
const callee = node["callee"];
|
|
106
|
+
return isAstNode(callee) && callee.type === "Import";
|
|
107
|
+
};
|
|
108
|
+
const isDynamicImportSource = (node) => {
|
|
109
|
+
const parent = node.parent;
|
|
110
|
+
if (!isAstNode(parent)) return false;
|
|
111
|
+
if (isDynamicImportCall(parent)) return true;
|
|
112
|
+
if (parent.type !== "TemplateLiteral") return false;
|
|
113
|
+
const grandparent = parent.parent;
|
|
114
|
+
return isAstNode(grandparent) && isDynamicImportCall(grandparent);
|
|
115
|
+
};
|
|
116
|
+
const templateElementText = (node) => {
|
|
117
|
+
const value = node["value"];
|
|
118
|
+
if (typeof value !== "object" || value === null) return null;
|
|
119
|
+
const cooked = "cooked" in value ? value.cooked : null;
|
|
120
|
+
if (typeof cooked === "string") return cooked;
|
|
121
|
+
const raw = "raw" in value ? value.raw : null;
|
|
122
|
+
return typeof raw === "string" ? raw : null;
|
|
123
|
+
};
|
|
124
|
+
var no_raw_colors_default = {
|
|
125
|
+
meta: { name: "no-raw-colors" },
|
|
126
|
+
rules: { "no-raw-colors": {
|
|
127
|
+
meta: {
|
|
128
|
+
type: "problem",
|
|
129
|
+
messages: { rawColor: "Hardcoded color '{{match}}' bypasses semantic tokens. Use semantic tokens (bg-muted, text-foreground, bg-success/12, bg-warning/12, bg-destructive/12, etc.) instead." }
|
|
130
|
+
},
|
|
131
|
+
create(context) {
|
|
132
|
+
return {
|
|
133
|
+
Literal(node) {
|
|
134
|
+
const value = node["value"];
|
|
135
|
+
if (typeof value !== "string") return;
|
|
136
|
+
if (isImportOrExportSource(node) || isDynamicImportSource(node)) return;
|
|
137
|
+
checkValue(context, node, value);
|
|
138
|
+
},
|
|
139
|
+
TemplateElement(node) {
|
|
140
|
+
if (isDynamicImportSource(node)) return;
|
|
141
|
+
const value = templateElementText(node);
|
|
142
|
+
if (value === null) return;
|
|
143
|
+
checkValue(context, node, value);
|
|
144
|
+
}
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
} }
|
|
148
|
+
};
|
|
149
|
+
//#endregion
|
|
150
|
+
export { no_raw_colors_default as default };
|
|
151
|
+
|
|
152
|
+
//# sourceMappingURL=no-raw-colors.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"no-raw-colors.mjs","names":[],"sources":["../src/no-raw-colors.ts"],"sourcesContent":["// Detect hardcoded Tailwind color classes that bypass semantic tokens.\n//\n// Semantic tokens (bg-background, bg-muted, text-foreground, bg-success/12, …)\n// adapt via CSS variables and stay legible across themes. Raw palette colors\n// (bg-stone-50, text-gray-900, bg-emerald-100, text-amber-800, bg-white, …)\n// either break dark mode (neutrals) or pin a component to a hue that ignores\n// the design system. Use the semantic equivalents instead.\n\ntype AstNode = { type: string; parent?: unknown } & Record<string, unknown>;\n\ntype RuleContext = {\n report: (diagnostic: {\n node: unknown;\n messageId: \"rawColor\";\n data?: { match: string };\n }) => void;\n};\n\nconst isAstNode = (node: unknown): node is AstNode =>\n typeof node === \"object\" &&\n node !== null &&\n \"type\" in node &&\n typeof node.type === \"string\";\n\nconst SHADED_PALETTE_COLORS = [\n \"red\",\n \"orange\",\n \"amber\",\n \"yellow\",\n \"lime\",\n \"green\",\n \"emerald\",\n \"teal\",\n \"cyan\",\n \"sky\",\n \"blue\",\n \"indigo\",\n \"violet\",\n \"purple\",\n \"fuchsia\",\n \"pink\",\n \"rose\",\n \"slate\",\n \"gray\",\n \"zinc\",\n \"neutral\",\n \"stone\",\n \"taupe\",\n \"mauve\",\n \"mist\",\n \"olive\",\n] as const;\nconst COLOR_SHADES = [\n \"50\",\n \"100\",\n \"200\",\n \"300\",\n \"400\",\n \"500\",\n \"600\",\n \"700\",\n \"800\",\n \"900\",\n \"950\",\n] as const;\nconst COLOR_UTILITY_PREFIXES = [\n \"accent\",\n \"bg\",\n \"border\",\n \"border-b\",\n \"border-e\",\n \"border-l\",\n \"border-r\",\n \"border-s\",\n \"border-t\",\n \"border-x\",\n \"border-y\",\n \"caret\",\n \"decoration\",\n \"divide\",\n \"drop-shadow\",\n \"fill\",\n \"from\",\n \"inset-ring\",\n \"inset-shadow\",\n \"marker\",\n \"outline\",\n \"placeholder\",\n \"ring\",\n \"ring-offset\",\n \"scrollbar-thumb\",\n \"scrollbar-track\",\n \"shadow\",\n \"stroke\",\n \"text\",\n \"text-shadow\",\n \"to\",\n \"via\",\n] as const;\nconst COLOR_PREFIXES = COLOR_UTILITY_PREFIXES.join(\"|\");\nconst SHADED_PALETTE_COLOR_PATTERN = SHADED_PALETTE_COLORS.join(\"|\");\nconst COLOR_SHADE_PATTERN = COLOR_SHADES.join(\"|\");\nconst CLASS_COLOR_BOUNDARY = \"(?:^|:)!?\";\n\nconst SHADED_PALETTE_PATTERN = new RegExp(\n `${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:${SHADED_PALETTE_COLOR_PATTERN})-(?:${COLOR_SHADE_PATTERN})(?![\\\\w-])`,\n);\n// Standalone white/black utilities; permit opacity (bg-white/20) and compounds\n// (bg-whitesmoke) so only the bare palette tokens fire.\nconst BW_PATTERN = new RegExp(\n `${CLASS_COLOR_BOUNDARY}(?:${COLOR_PREFIXES})-(?:white|black)(?![/\\\\w-])`,\n);\n\nconst isRawColorClass = (value: string): boolean =>\n SHADED_PALETTE_PATTERN.test(value) || BW_PATTERN.test(value);\n\nconst checkValue = (\n context: RuleContext,\n node: unknown,\n value: string,\n): void => {\n for (const token of value.split(/\\s+/)) {\n if (isRawColorClass(token)) {\n context.report({\n node,\n messageId: \"rawColor\",\n data: { match: token },\n });\n }\n }\n};\n\nconst IMPORT_EXPORT_SOURCE_PARENT_TYPES = new Set([\n \"ExportAllDeclaration\",\n \"ExportNamedDeclaration\",\n \"ImportDeclaration\",\n \"TSExternalModuleReference\",\n \"TSImportType\",\n]);\n\nconst isImportOrExportSource = (node: AstNode): boolean => {\n const parent = node.parent;\n return (\n isAstNode(parent) && IMPORT_EXPORT_SOURCE_PARENT_TYPES.has(parent.type)\n );\n};\n\nconst isDynamicImportCall = (node: AstNode): boolean => {\n if (node.type === \"ImportExpression\") {\n return true;\n }\n if (node.type !== \"CallExpression\") {\n return false;\n }\n const callee = node[\"callee\"];\n return isAstNode(callee) && callee.type === \"Import\";\n};\n\nconst isDynamicImportSource = (node: AstNode): boolean => {\n const parent = node.parent;\n if (!isAstNode(parent)) {\n return false;\n }\n if (isDynamicImportCall(parent)) {\n return true;\n }\n if (parent.type !== \"TemplateLiteral\") {\n return false;\n }\n const grandparent = parent.parent;\n return isAstNode(grandparent) && isDynamicImportCall(grandparent);\n};\n\nconst templateElementText = (node: AstNode): string | null => {\n const value = node[\"value\"];\n if (typeof value !== \"object\" || value === null) {\n return null;\n }\n const cooked = \"cooked\" in value ? value.cooked : null;\n if (typeof cooked === \"string\") {\n return cooked;\n }\n const raw = \"raw\" in value ? value.raw : null;\n return typeof raw === \"string\" ? raw : null;\n};\n\nexport default {\n meta: { name: \"no-raw-colors\" },\n rules: {\n \"no-raw-colors\": {\n meta: {\n type: \"problem\",\n messages: {\n rawColor:\n \"Hardcoded color '{{match}}' bypasses semantic tokens. Use semantic tokens (bg-muted, text-foreground, bg-success/12, bg-warning/12, bg-destructive/12, etc.) instead.\",\n },\n },\n create(context: RuleContext) {\n return {\n Literal(node: AstNode) {\n const value = node[\"value\"];\n if (typeof value !== \"string\") {\n return;\n }\n if (isImportOrExportSource(node) || isDynamicImportSource(node)) {\n return;\n }\n checkValue(context, node, value);\n },\n TemplateElement(node: AstNode) {\n if (isDynamicImportSource(node)) {\n return;\n }\n const value = templateElementText(node);\n if (value === null) {\n return;\n }\n checkValue(context, node, value);\n },\n };\n },\n },\n },\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.3.0",
|
|
4
4
|
"description": "Shared general oxlint configuration for stella packages.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -36,6 +36,17 @@
|
|
|
36
36
|
"default": "./dist/plugin.cjs"
|
|
37
37
|
},
|
|
38
38
|
"default": "./dist/plugin.mjs"
|
|
39
|
+
},
|
|
40
|
+
"./no-raw-colors": {
|
|
41
|
+
"import": {
|
|
42
|
+
"types": "./dist/no-raw-colors.d.mts",
|
|
43
|
+
"default": "./dist/no-raw-colors.mjs"
|
|
44
|
+
},
|
|
45
|
+
"require": {
|
|
46
|
+
"types": "./dist/no-raw-colors.d.cts",
|
|
47
|
+
"default": "./dist/no-raw-colors.cjs"
|
|
48
|
+
},
|
|
49
|
+
"default": "./dist/no-raw-colors.mjs"
|
|
39
50
|
}
|
|
40
51
|
},
|
|
41
52
|
"publishConfig": {
|
|
@@ -44,6 +55,7 @@
|
|
|
44
55
|
"scripts": {
|
|
45
56
|
"build": "tsdown",
|
|
46
57
|
"typecheck": "tsc --noEmit",
|
|
58
|
+
"test": "bun test",
|
|
47
59
|
"format": "oxfmt ."
|
|
48
60
|
},
|
|
49
61
|
"devDependencies": {
|