@imranbarbhuiya/oxc-config 0.1.10 → 0.1.12
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/common.js +3 -9
- package/dist/common.js.map +1 -1
- package/dist/nest.js +2 -2
- package/dist/nest.js.map +1 -1
- package/dist/plugins/api-error.d.ts +2 -3
- package/dist/plugins/api-error.js +144 -135
- package/dist/plugins/api-error.js.map +1 -1
- package/dist/plugins/central-icons.d.ts +2 -3
- package/dist/plugins/central-icons.js +45 -47
- package/dist/plugins/central-icons.js.map +1 -1
- package/dist/plugins/i18n.d.ts +2 -3
- package/dist/plugins/i18n.js +46 -49
- package/dist/plugins/i18n.js.map +1 -1
- package/dist/plugins/native-tailwind.d.ts +2 -3
- package/dist/plugins/native-tailwind.js +93 -95
- package/dist/plugins/native-tailwind.js.map +1 -1
- package/dist/plugins/nest.d.ts +2 -3
- package/dist/plugins/nest.js +32 -27
- package/dist/plugins/nest.js.map +1 -1
- package/dist/plugins/restricted-syntax.d.ts +2 -3
- package/dist/plugins/restricted-syntax.js +100 -47
- package/dist/plugins/restricted-syntax.js.map +1 -1
- package/dist/tailwind.d.ts +4 -5
- package/dist/tailwind.js +5 -6
- package/dist/tailwind.js.map +1 -1
- package/package.json +69 -68
package/dist/common.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { localPlugin, nativePlugins
|
|
1
|
+
import { localPlugin, nativePlugins } from "./config.js";
|
|
2
2
|
import { defineConfig } from "oxlint";
|
|
3
3
|
|
|
4
4
|
//#region src/common.ts
|
|
5
5
|
const config = defineConfig({
|
|
6
6
|
plugins: nativePlugins,
|
|
7
|
-
jsPlugins: [localPlugin("mahir-restricted-syntax", "./plugins/restricted-syntax.js")
|
|
7
|
+
jsPlugins: [localPlugin("mahir-restricted-syntax", "./plugins/restricted-syntax.js")],
|
|
8
8
|
categories: { correctness: "off" },
|
|
9
9
|
options: { reportUnusedDisableDirectives: "warn" },
|
|
10
10
|
rules: {
|
|
@@ -37,15 +37,9 @@ const config = defineConfig({
|
|
|
37
37
|
"import/no-amd": 2,
|
|
38
38
|
"import/no-duplicates": 2,
|
|
39
39
|
"import/no-dynamic-require": 2,
|
|
40
|
-
"import-js/no-extraneous-dependencies": [2, {
|
|
41
|
-
devDependencies: true,
|
|
42
|
-
optionalDependencies: true,
|
|
43
|
-
peerDependencies: true
|
|
44
|
-
}],
|
|
45
40
|
"import/no-mutable-exports": 2,
|
|
46
41
|
"import/no-self-import": 2,
|
|
47
42
|
"import/no-webpack-loader-syntax": 2,
|
|
48
|
-
"import-js/order": 0,
|
|
49
43
|
"no-alert": 2,
|
|
50
44
|
"no-array-constructor": 2,
|
|
51
45
|
"no-async-promise-executor": 2,
|
|
@@ -174,7 +168,7 @@ const config = defineConfig({
|
|
|
174
168
|
"unicorn/new-for-builtins": 2,
|
|
175
169
|
"unicorn/no-abusive-eslint-disable": 2,
|
|
176
170
|
"unicorn/no-array-for-each": 1,
|
|
177
|
-
"unicorn/no-array-method-this-argument":
|
|
171
|
+
"unicorn/no-array-method-this-argument": 0,
|
|
178
172
|
"unicorn/no-await-in-promise-methods": 2,
|
|
179
173
|
"unicorn/no-document-cookie": 2,
|
|
180
174
|
"unicorn/no-empty-file": 2,
|
package/dist/common.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","names":[],"sources":["../src/common.ts"],"sourcesContent":["import { defineConfig } from 'oxlint';\n\nimport { localPlugin, nativePlugins, packagePlugin } from './config.js';\n\nimport type { OxlintConfig } from 'oxlint';\n\nconst rules: NonNullable<OxlintConfig['rules']> = {\n\t'array-callback-return': 2,\n\t'arrow-body-style': [2, 'as-needed'],\n\t'block-scoped-var': 2,\n\t'consistent-return': 2,\n\t'constructor-super': 2,\n\tcurly: [2, 'multi-or-nest'],\n\t'default-case': 2,\n\t'default-case-last': 2,\n\t'default-param-last': 2,\n\t'dot-notation': 2,\n\teqeqeq: 2,\n\t'for-direction': 2,\n\t'func-name-matching': 2,\n\t'func-names': [2, 'as-needed'],\n\t'func-style': [\n\t\t2,\n\t\t'declaration',\n\t\t{\n\t\t\tallowArrowFunctions: true,\n\t\t},\n\t],\n\t'getter-return': 2,\n\t'grouped-accessor-pairs': [2, 'getBeforeSet'],\n\t'guard-for-in': 2,\n\t'import/export': 2,\n\t'import/first': 2,\n\t'import/newline-after-import': 2,\n\t'import/no-absolute-path': 2,\n\t'import/no-amd': 2,\n\t'import/no-duplicates': 2,\n\t'import/no-dynamic-require': 2,\n\t'import-js/no-extraneous-dependencies': [\n\t\t2,\n\t\t{\n\t\t\tdevDependencies: true,\n\t\t\toptionalDependencies: true,\n\t\t\tpeerDependencies: true,\n\t\t},\n\t],\n\t'import/no-mutable-exports': 2,\n\t'import/no-self-import': 2,\n\t'import/no-webpack-loader-syntax': 2,\n\t'import-js/order': 0,\n\t'no-alert': 2,\n\t'no-array-constructor': 2,\n\t'no-async-promise-executor': 2,\n\t'no-caller': 2,\n\t'no-case-declarations': 2,\n\t'no-class-assign': 2,\n\t'no-compare-neg-zero': 2,\n\t'no-cond-assign': 2,\n\t'no-const-assign': 2,\n\t'no-constructor-return': 2,\n\t'no-control-regex': 2,\n\t'no-debugger': 2,\n\t'no-delete-var': 2,\n\t'no-dupe-class-members': 2,\n\t'no-dupe-else-if': 2,\n\t'no-dupe-keys': 2,\n\t'no-duplicate-case': 2,\n\t'no-empty-character-class': 2,\n\t'no-empty-pattern': 2,\n\t'no-eval': 2,\n\t'no-ex-assign': 2,\n\t'no-extend-native': 2,\n\t'no-extra-bind': 2,\n\t'no-extra-boolean-cast': 2,\n\t'no-extra-label': 2,\n\t'no-fallthrough': 2,\n\t'no-func-assign': 2,\n\t'no-global-assign': 2,\n\t'no-implicit-coercion': 2,\n\t'no-implicit-globals': 2,\n\t'no-implied-eval': 2,\n\t'no-import-assign': 2,\n\t'no-inner-declarations': 2,\n\t'no-invalid-regexp': 2,\n\t'no-irregular-whitespace': 2,\n\t'no-iterator': 2,\n\t'no-label-var': 2,\n\t'no-labels': 2,\n\t'no-lone-blocks': 2,\n\t'no-lonely-if': 2,\n\t'no-loss-of-precision': 2,\n\t'no-misleading-character-class': 2,\n\t'no-multi-assign': 2,\n\t'no-multi-str': 2,\n\t'no-new-func': 2,\n\t'no-new-wrappers': 2,\n\t'no-nonoctal-decimal-escape': 2,\n\t'no-obj-calls': 2,\n\t'no-promise-executor-return': 2,\n\t'no-proto': 2,\n\t'no-prototype-builtins': 2,\n\t'no-redeclare': [\n\t\t2,\n\t\t{\n\t\t\tbuiltinGlobals: true,\n\t\t},\n\t],\n\t'no-regex-spaces': 2,\n\t'no-return-assign': 2,\n\t'no-script-url': 2,\n\t'no-self-assign': 2,\n\t'no-self-compare': 2,\n\t'no-sequences': 2,\n\t'no-setter-return': 2,\n\t'no-shadow': [\n\t\t2,\n\t\t{\n\t\t\tbuiltinGlobals: false,\n\t\t\thoist: 'all',\n\t\t},\n\t],\n\t'no-shadow-restricted-names': 2,\n\t'no-template-curly-in-string': 2,\n\t'no-this-before-super': 2,\n\t'no-throw-literal': 2,\n\t'no-undef': 2,\n\t'no-unexpected-multiline': 2,\n\t'no-unmodified-loop-condition': 2,\n\t'no-unneeded-ternary': 2,\n\t'no-unreachable-loop': 2,\n\t'no-unsafe-finally': 2,\n\t'no-unsafe-negation': 2,\n\t'no-unsafe-optional-chaining': 2,\n\t'no-unused-expressions': 2,\n\t'no-unused-labels': 2,\n\t'no-unused-vars': 2,\n\t'no-use-before-define': [\n\t\t2,\n\t\t{\n\t\t\tclasses: true,\n\t\t\tfunctions: false,\n\t\t\tvariables: true,\n\t\t},\n\t],\n\t'no-useless-backreference': 2,\n\t'no-useless-call': 2,\n\t'no-useless-catch': 2,\n\t'no-useless-computed-key': 2,\n\t'no-useless-concat': 2,\n\t'no-useless-constructor': 2,\n\t'no-useless-escape': 2,\n\t'no-useless-rename': [\n\t\t2,\n\t\t{\n\t\t\tignoreDestructuring: false,\n\t\t\tignoreExport: false,\n\t\t\tignoreImport: false,\n\t\t},\n\t],\n\t'no-useless-return': 2,\n\t'no-var': 2,\n\t'no-with': 2,\n\t'object-shorthand': [2, 'always'],\n\t'one-var': [2, 'never'],\n\t'operator-assignment': [2, 'always'],\n\t'prefer-arrow-callback': 2,\n\t'prefer-const': 2,\n\t'prefer-exponentiation-operator': 2,\n\t'prefer-numeric-literals': 2,\n\t'prefer-object-has-own': 2,\n\t'prefer-object-spread': 2,\n\t'prefer-promise-reject-errors': 2,\n\t'prefer-regex-literals': [\n\t\t2,\n\t\t{\n\t\t\tdisallowRedundantWrapping: true,\n\t\t},\n\t],\n\t'prefer-rest-params': 2,\n\t'prefer-spread': 2,\n\t'promise/param-names': 2,\n\t'promise/prefer-await-to-callbacks': 1,\n\t'promise/prefer-await-to-then': 2,\n\t'promise/valid-params': 2,\n\tradix: 2,\n\t'require-yield': 2,\n\t'sort-vars': 2,\n\t'symbol-description': 2,\n\t'unicode-bom': [2, 'never'],\n\t'unicorn/catch-error-name': [\n\t\t2,\n\t\t{\n\t\t\tname: 'error',\n\t\t},\n\t],\n\t'unicorn/consistent-function-scoping': 2,\n\t'unicorn/empty-brace-spaces': 2,\n\t'unicorn/error-message': 2,\n\t'unicorn/escape-case': 2,\n\t'unicorn/new-for-builtins': 2,\n\t'unicorn/no-abusive-eslint-disable': 2,\n\t'unicorn/no-array-for-each': 1,\n\t'unicorn/no-array-method-this-argument': 2,\n\t'unicorn/no-await-in-promise-methods': 2,\n\t'unicorn/no-document-cookie': 2,\n\t'unicorn/no-empty-file': 2,\n\t'unicorn/no-instanceof-array': 2,\n\t'unicorn/no-invalid-remove-event-listener': 2,\n\t'unicorn/no-lonely-if': 2,\n\t'unicorn/no-negated-condition': 2,\n\t'unicorn/no-new-array': 2,\n\t'unicorn/no-new-buffer': 2,\n\t'unicorn/no-object-as-default-parameter': 2,\n\t'unicorn/no-single-promise-in-promise-methods': 2,\n\t'unicorn/no-static-only-class': 2,\n\t'unicorn/no-thenable': 2,\n\t'unicorn/no-this-assignment': 2,\n\t'unicorn/no-typeof-undefined': 2,\n\t'unicorn/no-unnecessary-await': 2,\n\t'unicorn/no-unreadable-iife': 2,\n\t'unicorn/no-useless-fallback-in-spread': 2,\n\t'unicorn/no-useless-length-check': 2,\n\t'unicorn/no-useless-promise-resolve-reject': 2,\n\t'unicorn/no-useless-spread': 2,\n\t'unicorn/no-useless-switch-case': 2,\n\t'unicorn/no-zero-fractions': 2,\n\t'unicorn/numeric-separators-style': [\n\t\t2,\n\t\t{\n\t\t\tbinary: {\n\t\t\t\tonlyIfContainsSeparator: true,\n\t\t\t},\n\t\t\thexadecimal: {\n\t\t\t\tonlyIfContainsSeparator: true,\n\t\t\t},\n\t\t\tnumber: {\n\t\t\t\tgroupLength: 3,\n\t\t\t\tminimumDigits: 0,\n\t\t\t},\n\t\t\toctal: {\n\t\t\t\tonlyIfContainsSeparator: true,\n\t\t\t},\n\t\t},\n\t],\n\t'unicorn/prefer-array-find': 2,\n\t'unicorn/prefer-array-flat': 2,\n\t'unicorn/prefer-array-flat-map': 2,\n\t'unicorn/prefer-array-index-of': 2,\n\t'unicorn/prefer-array-some': 2,\n\t'unicorn/prefer-code-point': 2,\n\t'unicorn/prefer-date-now': 2,\n\t'unicorn/prefer-default-parameters': 2,\n\t'unicorn/prefer-export-from': 2,\n\t'unicorn/prefer-includes': 2,\n\t'unicorn/prefer-math-trunc': 2,\n\t'unicorn/prefer-modern-math-apis': 2,\n\t'unicorn/prefer-native-coercion-functions': 2,\n\t'unicorn/prefer-number-properties': 2,\n\t'unicorn/prefer-object-from-entries': 2,\n\t'unicorn/prefer-optional-catch-binding': 2,\n\t'unicorn/prefer-query-selector': 2,\n\t'unicorn/prefer-reflect-apply': 2,\n\t'unicorn/prefer-regexp-test': 2,\n\t'unicorn/prefer-set-size': 2,\n\t'unicorn/prefer-string-replace-all': 2,\n\t'unicorn/prefer-string-slice': 2,\n\t'unicorn/prefer-string-starts-ends-with': 2,\n\t'unicorn/prefer-string-trim-start-end': 2,\n\t'unicorn/prefer-type-error': 2,\n\t'unicorn/relative-url-style': [2, 'never'],\n\t'unicorn/require-array-join-separator': 2,\n\t'unicorn/require-number-to-fixed-digits-argument': 2,\n\t'unicorn/require-post-message-target-origin': 2,\n\t'unicorn/text-encoding-identifier-case': 2,\n\t'unicorn/throw-new-error': 2,\n\t'use-isnan': 2,\n\t'valid-typeof': [\n\t\t2,\n\t\t{\n\t\t\trequireStringLiterals: true,\n\t\t},\n\t],\n\t'vars-on-top': 2,\n\tyoda: [2, 'never'],\n};\n\nconst config = defineConfig({\n\tplugins: nativePlugins,\n\tjsPlugins: [\n\t\tlocalPlugin('mahir-restricted-syntax', './plugins/restricted-syntax.js'),\n\t\tpackagePlugin('import-js', 'eslint-plugin-import-x'),\n\t],\n\tcategories: {\n\t\tcorrectness: 'off',\n\t},\n\toptions: {\n\t\treportUnusedDisableDirectives: 'warn',\n\t},\n\trules,\n});\n\nexport default config;\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"common.js","names":[],"sources":["../src/common.ts"],"sourcesContent":["import { defineConfig } from 'oxlint';\n\nimport { localPlugin, nativePlugins } from './config.js';\n\nimport type { OxlintConfig } from 'oxlint';\n\nconst rules: NonNullable<OxlintConfig['rules']> = {\n\t'array-callback-return': 2,\n\t'arrow-body-style': [2, 'as-needed'],\n\t'block-scoped-var': 2,\n\t'consistent-return': 2,\n\t'constructor-super': 2,\n\tcurly: [2, 'multi-or-nest'],\n\t'default-case': 2,\n\t'default-case-last': 2,\n\t'default-param-last': 2,\n\t'dot-notation': 2,\n\teqeqeq: 2,\n\t'for-direction': 2,\n\t'func-name-matching': 2,\n\t'func-names': [2, 'as-needed'],\n\t'func-style': [\n\t\t2,\n\t\t'declaration',\n\t\t{\n\t\t\tallowArrowFunctions: true,\n\t\t},\n\t],\n\t'getter-return': 2,\n\t'grouped-accessor-pairs': [2, 'getBeforeSet'],\n\t'guard-for-in': 2,\n\t'import/export': 2,\n\t'import/first': 2,\n\t'import/newline-after-import': 2,\n\t'import/no-absolute-path': 2,\n\t'import/no-amd': 2,\n\t'import/no-duplicates': 2,\n\t'import/no-dynamic-require': 2,\n\t'import/no-mutable-exports': 2,\n\t'import/no-self-import': 2,\n\t'import/no-webpack-loader-syntax': 2,\n\t'no-alert': 2,\n\t'no-array-constructor': 2,\n\t'no-async-promise-executor': 2,\n\t'no-caller': 2,\n\t'no-case-declarations': 2,\n\t'no-class-assign': 2,\n\t'no-compare-neg-zero': 2,\n\t'no-cond-assign': 2,\n\t'no-const-assign': 2,\n\t'no-constructor-return': 2,\n\t'no-control-regex': 2,\n\t'no-debugger': 2,\n\t'no-delete-var': 2,\n\t'no-dupe-class-members': 2,\n\t'no-dupe-else-if': 2,\n\t'no-dupe-keys': 2,\n\t'no-duplicate-case': 2,\n\t'no-empty-character-class': 2,\n\t'no-empty-pattern': 2,\n\t'no-eval': 2,\n\t'no-ex-assign': 2,\n\t'no-extend-native': 2,\n\t'no-extra-bind': 2,\n\t'no-extra-boolean-cast': 2,\n\t'no-extra-label': 2,\n\t'no-fallthrough': 2,\n\t'no-func-assign': 2,\n\t'no-global-assign': 2,\n\t'no-implicit-coercion': 2,\n\t'no-implicit-globals': 2,\n\t'no-implied-eval': 2,\n\t'no-import-assign': 2,\n\t'no-inner-declarations': 2,\n\t'no-invalid-regexp': 2,\n\t'no-irregular-whitespace': 2,\n\t'no-iterator': 2,\n\t'no-label-var': 2,\n\t'no-labels': 2,\n\t'no-lone-blocks': 2,\n\t'no-lonely-if': 2,\n\t'no-loss-of-precision': 2,\n\t'no-misleading-character-class': 2,\n\t'no-multi-assign': 2,\n\t'no-multi-str': 2,\n\t'no-new-func': 2,\n\t'no-new-wrappers': 2,\n\t'no-nonoctal-decimal-escape': 2,\n\t'no-obj-calls': 2,\n\t'no-promise-executor-return': 2,\n\t'no-proto': 2,\n\t'no-prototype-builtins': 2,\n\t'no-redeclare': [\n\t\t2,\n\t\t{\n\t\t\tbuiltinGlobals: true,\n\t\t},\n\t],\n\t'no-regex-spaces': 2,\n\t'no-return-assign': 2,\n\t'no-script-url': 2,\n\t'no-self-assign': 2,\n\t'no-self-compare': 2,\n\t'no-sequences': 2,\n\t'no-setter-return': 2,\n\t'no-shadow': [\n\t\t2,\n\t\t{\n\t\t\tbuiltinGlobals: false,\n\t\t\thoist: 'all',\n\t\t},\n\t],\n\t'no-shadow-restricted-names': 2,\n\t'no-template-curly-in-string': 2,\n\t'no-this-before-super': 2,\n\t'no-throw-literal': 2,\n\t'no-undef': 2,\n\t'no-unexpected-multiline': 2,\n\t'no-unmodified-loop-condition': 2,\n\t'no-unneeded-ternary': 2,\n\t'no-unreachable-loop': 2,\n\t'no-unsafe-finally': 2,\n\t'no-unsafe-negation': 2,\n\t'no-unsafe-optional-chaining': 2,\n\t'no-unused-expressions': 2,\n\t'no-unused-labels': 2,\n\t'no-unused-vars': 2,\n\t'no-use-before-define': [\n\t\t2,\n\t\t{\n\t\t\tclasses: true,\n\t\t\tfunctions: false,\n\t\t\tvariables: true,\n\t\t},\n\t],\n\t'no-useless-backreference': 2,\n\t'no-useless-call': 2,\n\t'no-useless-catch': 2,\n\t'no-useless-computed-key': 2,\n\t'no-useless-concat': 2,\n\t'no-useless-constructor': 2,\n\t'no-useless-escape': 2,\n\t'no-useless-rename': [\n\t\t2,\n\t\t{\n\t\t\tignoreDestructuring: false,\n\t\t\tignoreExport: false,\n\t\t\tignoreImport: false,\n\t\t},\n\t],\n\t'no-useless-return': 2,\n\t'no-var': 2,\n\t'no-with': 2,\n\t'object-shorthand': [2, 'always'],\n\t'one-var': [2, 'never'],\n\t'operator-assignment': [2, 'always'],\n\t'prefer-arrow-callback': 2,\n\t'prefer-const': 2,\n\t'prefer-exponentiation-operator': 2,\n\t'prefer-numeric-literals': 2,\n\t'prefer-object-has-own': 2,\n\t'prefer-object-spread': 2,\n\t'prefer-promise-reject-errors': 2,\n\t'prefer-regex-literals': [\n\t\t2,\n\t\t{\n\t\t\tdisallowRedundantWrapping: true,\n\t\t},\n\t],\n\t'prefer-rest-params': 2,\n\t'prefer-spread': 2,\n\t'promise/param-names': 2,\n\t'promise/prefer-await-to-callbacks': 1,\n\t'promise/prefer-await-to-then': 2,\n\t'promise/valid-params': 2,\n\tradix: 2,\n\t'require-yield': 2,\n\t'sort-vars': 2,\n\t'symbol-description': 2,\n\t'unicode-bom': [2, 'never'],\n\t'unicorn/catch-error-name': [\n\t\t2,\n\t\t{\n\t\t\tname: 'error',\n\t\t},\n\t],\n\t'unicorn/consistent-function-scoping': 2,\n\t'unicorn/empty-brace-spaces': 2,\n\t'unicorn/error-message': 2,\n\t'unicorn/escape-case': 2,\n\t'unicorn/new-for-builtins': 2,\n\t'unicorn/no-abusive-eslint-disable': 2,\n\t'unicorn/no-array-for-each': 1,\n\t'unicorn/no-array-method-this-argument': 0,\n\t'unicorn/no-await-in-promise-methods': 2,\n\t'unicorn/no-document-cookie': 2,\n\t'unicorn/no-empty-file': 2,\n\t'unicorn/no-instanceof-array': 2,\n\t'unicorn/no-invalid-remove-event-listener': 2,\n\t'unicorn/no-lonely-if': 2,\n\t'unicorn/no-negated-condition': 2,\n\t'unicorn/no-new-array': 2,\n\t'unicorn/no-new-buffer': 2,\n\t'unicorn/no-object-as-default-parameter': 2,\n\t'unicorn/no-single-promise-in-promise-methods': 2,\n\t'unicorn/no-static-only-class': 2,\n\t'unicorn/no-thenable': 2,\n\t'unicorn/no-this-assignment': 2,\n\t'unicorn/no-typeof-undefined': 2,\n\t'unicorn/no-unnecessary-await': 2,\n\t'unicorn/no-unreadable-iife': 2,\n\t'unicorn/no-useless-fallback-in-spread': 2,\n\t'unicorn/no-useless-length-check': 2,\n\t'unicorn/no-useless-promise-resolve-reject': 2,\n\t'unicorn/no-useless-spread': 2,\n\t'unicorn/no-useless-switch-case': 2,\n\t'unicorn/no-zero-fractions': 2,\n\t'unicorn/numeric-separators-style': [\n\t\t2,\n\t\t{\n\t\t\tbinary: {\n\t\t\t\tonlyIfContainsSeparator: true,\n\t\t\t},\n\t\t\thexadecimal: {\n\t\t\t\tonlyIfContainsSeparator: true,\n\t\t\t},\n\t\t\tnumber: {\n\t\t\t\tgroupLength: 3,\n\t\t\t\tminimumDigits: 0,\n\t\t\t},\n\t\t\toctal: {\n\t\t\t\tonlyIfContainsSeparator: true,\n\t\t\t},\n\t\t},\n\t],\n\t'unicorn/prefer-array-find': 2,\n\t'unicorn/prefer-array-flat': 2,\n\t'unicorn/prefer-array-flat-map': 2,\n\t'unicorn/prefer-array-index-of': 2,\n\t'unicorn/prefer-array-some': 2,\n\t'unicorn/prefer-code-point': 2,\n\t'unicorn/prefer-date-now': 2,\n\t'unicorn/prefer-default-parameters': 2,\n\t'unicorn/prefer-export-from': 2,\n\t'unicorn/prefer-includes': 2,\n\t'unicorn/prefer-math-trunc': 2,\n\t'unicorn/prefer-modern-math-apis': 2,\n\t'unicorn/prefer-native-coercion-functions': 2,\n\t'unicorn/prefer-number-properties': 2,\n\t'unicorn/prefer-object-from-entries': 2,\n\t'unicorn/prefer-optional-catch-binding': 2,\n\t'unicorn/prefer-query-selector': 2,\n\t'unicorn/prefer-reflect-apply': 2,\n\t'unicorn/prefer-regexp-test': 2,\n\t'unicorn/prefer-set-size': 2,\n\t'unicorn/prefer-string-replace-all': 2,\n\t'unicorn/prefer-string-slice': 2,\n\t'unicorn/prefer-string-starts-ends-with': 2,\n\t'unicorn/prefer-string-trim-start-end': 2,\n\t'unicorn/prefer-type-error': 2,\n\t'unicorn/relative-url-style': [2, 'never'],\n\t'unicorn/require-array-join-separator': 2,\n\t'unicorn/require-number-to-fixed-digits-argument': 2,\n\t'unicorn/require-post-message-target-origin': 2,\n\t'unicorn/text-encoding-identifier-case': 2,\n\t'unicorn/throw-new-error': 2,\n\t'use-isnan': 2,\n\t'valid-typeof': [\n\t\t2,\n\t\t{\n\t\t\trequireStringLiterals: true,\n\t\t},\n\t],\n\t'vars-on-top': 2,\n\tyoda: [2, 'never'],\n};\n\nconst config = defineConfig({\n\tplugins: nativePlugins,\n\tjsPlugins: [localPlugin('mahir-restricted-syntax', './plugins/restricted-syntax.js')],\n\tcategories: {\n\t\tcorrectness: 'off',\n\t},\n\toptions: {\n\t\treportUnusedDisableDirectives: 'warn',\n\t},\n\trules,\n});\n\nexport default config;\n"],"mappings":"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"}
|
package/dist/nest.js
CHANGED
|
@@ -4,8 +4,8 @@ import { defineConfig } from "oxlint";
|
|
|
4
4
|
//#region src/nest.ts
|
|
5
5
|
const config = defineConfig({
|
|
6
6
|
plugins: nativePlugins,
|
|
7
|
-
jsPlugins: [localPlugin("
|
|
8
|
-
rules: { "
|
|
7
|
+
jsPlugins: [localPlugin("mahir-nest", "./plugins/nest.js")],
|
|
8
|
+
rules: { "mahir-nest/sort-module-metadata-arrays": 2 }
|
|
9
9
|
});
|
|
10
10
|
|
|
11
11
|
//#endregion
|
package/dist/nest.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nest.js","names":[],"sources":["../src/nest.ts"],"sourcesContent":["import { defineConfig } from 'oxlint';\n\nimport { localPlugin, nativePlugins } from './config.js';\n\nimport type { OxlintConfig } from 'oxlint';\n\nconst rules: NonNullable<OxlintConfig['rules']> = {\n\t'
|
|
1
|
+
{"version":3,"file":"nest.js","names":[],"sources":["../src/nest.ts"],"sourcesContent":["import { defineConfig } from 'oxlint';\n\nimport { localPlugin, nativePlugins } from './config.js';\n\nimport type { OxlintConfig } from 'oxlint';\n\nconst rules: NonNullable<OxlintConfig['rules']> = {\n\t'mahir-nest/sort-module-metadata-arrays': 2,\n};\n\nconst config = defineConfig({\n\tplugins: nativePlugins,\n\tjsPlugins: [localPlugin('mahir-nest', './plugins/nest.js')],\n\trules,\n});\n\nexport default config;\n"],"mappings":";;;;AAUA,MAAM,SAAS,aAAa;CAC3B,SAAS;CACT,WAAW,CAAC,YAAY,cAAc,mBAAmB,CAAC;CAC1D,SANA,0CAA0C,EAMtC;AACL,CAAC"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { TSESLint } from "@typescript-eslint/utils";
|
|
2
1
|
//#region src/plugins/api-error.d.ts
|
|
3
|
-
declare const
|
|
2
|
+
declare const _default: import("@oxlint/plugins").Plugin;
|
|
4
3
|
//#endregion
|
|
5
|
-
export {
|
|
4
|
+
export { _default as default };
|
|
6
5
|
//# sourceMappingURL=api-error.d.ts.map
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { definePlugin, defineRule } from "@oxlint/plugins";
|
|
2
|
+
|
|
1
3
|
//#region src/plugins/api-error.ts
|
|
2
4
|
const DEFAULT_ALLOWED_ERRORS = ["ApiError", "FormValidationError"];
|
|
3
5
|
function getStaticFactoryCallee(arg) {
|
|
@@ -14,156 +16,163 @@ function getStaticFactoryCallee(arg) {
|
|
|
14
16
|
function isAstNode(value) {
|
|
15
17
|
return typeof value === "object" && value !== null && "type" in value && typeof value.type === "string";
|
|
16
18
|
}
|
|
17
|
-
const
|
|
19
|
+
const requireApiError = defineRule({
|
|
18
20
|
meta: {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
}],
|
|
39
|
-
messages: {
|
|
40
|
-
useApiError: "Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `new {{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.",
|
|
41
|
-
useApiErrorCall: "Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `{{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.",
|
|
42
|
-
useApiErrorMember: "Throw `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of re-throwing `{{thrown}}` directly inside {{fnType}}. The client error object may lose its HTTP status code in QueryCache/retry/error reporting."
|
|
43
|
-
}
|
|
21
|
+
type: "problem",
|
|
22
|
+
docs: { description: "Require an allowed API error instead of Error inside queryFn/mutationFn so status codes propagate to QueryCache error handling" },
|
|
23
|
+
schema: [{
|
|
24
|
+
type: "object",
|
|
25
|
+
additionalProperties: false,
|
|
26
|
+
properties: { allowedErrors: {
|
|
27
|
+
type: "array",
|
|
28
|
+
items: {
|
|
29
|
+
type: "string",
|
|
30
|
+
minLength: 1
|
|
31
|
+
},
|
|
32
|
+
minItems: 1,
|
|
33
|
+
uniqueItems: true
|
|
34
|
+
} }
|
|
35
|
+
}],
|
|
36
|
+
messages: {
|
|
37
|
+
useApiError: "Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `new {{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.",
|
|
38
|
+
useApiErrorCall: "Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `{{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.",
|
|
39
|
+
useApiErrorMember: "Throw `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of re-throwing `{{thrown}}` directly inside {{fnType}}. The client error object may lose its HTTP status code in QueryCache/retry/error reporting."
|
|
44
40
|
},
|
|
45
|
-
defaultOptions: [{ allowedErrors: [...DEFAULT_ALLOWED_ERRORS] }]
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
41
|
+
defaultOptions: [{ allowedErrors: [...DEFAULT_ALLOWED_ERRORS] }]
|
|
42
|
+
},
|
|
43
|
+
createOnce(context) {
|
|
44
|
+
let allowedErrors = new Set(DEFAULT_ALLOWED_ERRORS);
|
|
45
|
+
let allowedExample = DEFAULT_ALLOWED_ERRORS[0];
|
|
46
|
+
const fnStack = [];
|
|
47
|
+
const extractedRefs = [];
|
|
48
|
+
const moduleFns = /* @__PURE__ */ new Map();
|
|
49
|
+
function recordModuleFn(name, body) {
|
|
50
|
+
if (!name || !body) return;
|
|
51
|
+
if (!moduleFns.has(name)) moduleFns.set(name, body);
|
|
52
|
+
}
|
|
53
|
+
function isAllowedThrow(arg) {
|
|
54
|
+
if (arg.type === "NewExpression" && arg.callee.type === "Identifier") return allowedErrors.has(arg.callee.name);
|
|
55
|
+
const factory = getStaticFactoryCallee(arg);
|
|
56
|
+
return factory !== void 0 && allowedErrors.has(factory.name);
|
|
57
|
+
}
|
|
58
|
+
function checkThrowNode(node, fnType) {
|
|
59
|
+
const arg = node.argument;
|
|
60
|
+
if (isAllowedThrow(arg)) return;
|
|
61
|
+
if (arg.type === "NewExpression" && arg.callee.type === "Identifier") {
|
|
62
|
+
context.report({
|
|
63
|
+
node: arg,
|
|
64
|
+
messageId: "useApiError",
|
|
65
|
+
data: {
|
|
66
|
+
thrown: arg.callee.name,
|
|
67
|
+
fnType,
|
|
68
|
+
allowed: allowedExample
|
|
69
|
+
}
|
|
70
|
+
});
|
|
71
|
+
return;
|
|
62
72
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
if (arg.type === "NewExpression" && arg.callee.type === "Identifier") {
|
|
67
|
-
context.report({
|
|
68
|
-
node: arg,
|
|
69
|
-
messageId: "useApiError",
|
|
70
|
-
data: {
|
|
71
|
-
thrown: arg.callee.name,
|
|
72
|
-
fnType,
|
|
73
|
-
allowed: allowedExample
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const factory = getStaticFactoryCallee(arg);
|
|
79
|
-
if (factory) {
|
|
80
|
-
context.report({
|
|
81
|
-
node: arg,
|
|
82
|
-
messageId: "useApiErrorCall",
|
|
83
|
-
data: {
|
|
84
|
-
thrown: sourceCode.getText(factory.callee),
|
|
85
|
-
fnType,
|
|
86
|
-
allowed: allowedExample
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
return;
|
|
90
|
-
}
|
|
91
|
-
if (arg.type === "MemberExpression") context.report({
|
|
73
|
+
const factory = getStaticFactoryCallee(arg);
|
|
74
|
+
if (factory) {
|
|
75
|
+
context.report({
|
|
92
76
|
node: arg,
|
|
93
|
-
messageId: "
|
|
77
|
+
messageId: "useApiErrorCall",
|
|
94
78
|
data: {
|
|
95
|
-
thrown: sourceCode.getText(
|
|
79
|
+
thrown: context.sourceCode.getText(factory.callee),
|
|
96
80
|
fnType,
|
|
97
81
|
allowed: allowedExample
|
|
98
82
|
}
|
|
99
83
|
});
|
|
84
|
+
return;
|
|
100
85
|
}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
86
|
+
if (arg.type === "MemberExpression") context.report({
|
|
87
|
+
node: arg,
|
|
88
|
+
messageId: "useApiErrorMember",
|
|
89
|
+
data: {
|
|
90
|
+
thrown: context.sourceCode.getText(arg),
|
|
91
|
+
fnType,
|
|
92
|
+
allowed: allowedExample
|
|
107
93
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
for (const c of child) if (isAstNode(c)) walkThrows(c, fnType, visited);
|
|
117
|
-
} else if (isAstNode(child)) walkThrows(child, fnType, visited);
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
function enterQueryOrMutationFn(node) {
|
|
121
|
-
const parent = node.parent;
|
|
122
|
-
if (parent.type !== "Property" || parent.key.type !== "Identifier") return;
|
|
123
|
-
const name = parent.key.name;
|
|
124
|
-
if (name === "queryFn" || name === "mutationFn") fnStack.push(name);
|
|
125
|
-
}
|
|
126
|
-
function exitQueryOrMutationFn(node) {
|
|
127
|
-
const parent = node.parent;
|
|
128
|
-
if (parent.type !== "Property" || parent.key.type !== "Identifier") return;
|
|
129
|
-
const name = parent.key.name;
|
|
130
|
-
if (name === "queryFn" || name === "mutationFn") fnStack.pop();
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
function walkThrows(node, fnType, visited = /* @__PURE__ */ new Set()) {
|
|
97
|
+
if (!node || visited.has(node)) return;
|
|
98
|
+
visited.add(node);
|
|
99
|
+
if (node.type === "ThrowStatement") {
|
|
100
|
+
checkThrowNode(node, fnType);
|
|
101
|
+
return;
|
|
131
102
|
}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
103
|
+
if (node.type === "FunctionDeclaration" || node.type === "FunctionExpression" || node.type === "ArrowFunctionExpression") {
|
|
104
|
+
walkThrows(node.body, fnType, visited);
|
|
105
|
+
return;
|
|
135
106
|
}
|
|
136
|
-
|
|
137
|
-
if (
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
fnType
|
|
141
|
-
});
|
|
107
|
+
for (const key of Object.keys(node)) {
|
|
108
|
+
if (key === "parent" || key === "loc" || key === "range") continue;
|
|
109
|
+
const child = node[key];
|
|
110
|
+
if (Array.isArray(child)) {
|
|
111
|
+
for (const item of child) if (isAstNode(item)) walkThrows(item, fnType, visited);
|
|
112
|
+
} else if (isAstNode(child)) walkThrows(child, fnType, visited);
|
|
142
113
|
}
|
|
143
|
-
return {
|
|
144
|
-
"Program > FunctionDeclaration"(node) {
|
|
145
|
-
recordModuleFn(node.id?.name, node.body);
|
|
146
|
-
},
|
|
147
|
-
"Program > VariableDeclaration > VariableDeclarator"(node) {
|
|
148
|
-
if (node.id.type === "Identifier" && (node.init?.type === "ArrowFunctionExpression" || node.init?.type === "FunctionExpression")) recordModuleFn(node.id.name, node.init.body);
|
|
149
|
-
},
|
|
150
|
-
ArrowFunctionExpression: enterQueryOrMutationFn,
|
|
151
|
-
"ArrowFunctionExpression:exit": exitQueryOrMutationFn,
|
|
152
|
-
FunctionExpression: enterQueryOrMutationFn,
|
|
153
|
-
"FunctionExpression:exit": exitQueryOrMutationFn,
|
|
154
|
-
Property: recordExtractedRef,
|
|
155
|
-
ThrowStatement: checkThrowStatement,
|
|
156
|
-
"Program:exit"() {
|
|
157
|
-
for (const { name, fnType } of extractedRefs) {
|
|
158
|
-
const body = moduleFns.get(name);
|
|
159
|
-
if (body) walkThrows(body, fnType);
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
};
|
|
163
114
|
}
|
|
164
|
-
|
|
165
|
-
|
|
115
|
+
function enterQueryOrMutationFn(node) {
|
|
116
|
+
const parent = node.parent;
|
|
117
|
+
if (parent.type !== "Property" || parent.key.type !== "Identifier") return;
|
|
118
|
+
const name = parent.key.name;
|
|
119
|
+
if (name === "queryFn" || name === "mutationFn") fnStack.push(name);
|
|
120
|
+
}
|
|
121
|
+
function exitQueryOrMutationFn(node) {
|
|
122
|
+
const parent = node.parent;
|
|
123
|
+
if (parent.type !== "Property" || parent.key.type !== "Identifier") return;
|
|
124
|
+
const name = parent.key.name;
|
|
125
|
+
if (name === "queryFn" || name === "mutationFn") fnStack.pop();
|
|
126
|
+
}
|
|
127
|
+
function checkThrowStatement(node) {
|
|
128
|
+
if (fnStack.length === 0) return;
|
|
129
|
+
checkThrowNode(node, fnStack.at(-1) ?? "");
|
|
130
|
+
}
|
|
131
|
+
function recordExtractedRef(prop) {
|
|
132
|
+
if (prop.type !== "Property") return;
|
|
133
|
+
if (prop.key.type !== "Identifier" || prop.key.name !== "queryFn" && prop.key.name !== "mutationFn" || prop.value.type !== "Identifier") return;
|
|
134
|
+
extractedRefs.push({
|
|
135
|
+
name: prop.value.name,
|
|
136
|
+
fnType: prop.key.name
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return {
|
|
140
|
+
before() {
|
|
141
|
+
const allowedList = context.options[0]?.allowedErrors ?? DEFAULT_ALLOWED_ERRORS;
|
|
142
|
+
allowedErrors = new Set(allowedList);
|
|
143
|
+
allowedExample = allowedList[0] ?? DEFAULT_ALLOWED_ERRORS[0];
|
|
144
|
+
fnStack.length = 0;
|
|
145
|
+
extractedRefs.length = 0;
|
|
146
|
+
moduleFns.clear();
|
|
147
|
+
},
|
|
148
|
+
"Program > FunctionDeclaration"(node) {
|
|
149
|
+
if (node.type !== "FunctionDeclaration") return;
|
|
150
|
+
recordModuleFn(node.id?.name, node.body);
|
|
151
|
+
},
|
|
152
|
+
"Program > VariableDeclaration > VariableDeclarator"(node) {
|
|
153
|
+
if (node.type !== "VariableDeclarator") return;
|
|
154
|
+
if (node.id.type === "Identifier" && (node.init?.type === "ArrowFunctionExpression" || node.init?.type === "FunctionExpression")) recordModuleFn(node.id.name, node.init.body);
|
|
155
|
+
},
|
|
156
|
+
ArrowFunctionExpression: enterQueryOrMutationFn,
|
|
157
|
+
"ArrowFunctionExpression:exit": exitQueryOrMutationFn,
|
|
158
|
+
FunctionExpression: enterQueryOrMutationFn,
|
|
159
|
+
"FunctionExpression:exit": exitQueryOrMutationFn,
|
|
160
|
+
Property: recordExtractedRef,
|
|
161
|
+
ThrowStatement: checkThrowStatement,
|
|
162
|
+
"Program:exit"() {
|
|
163
|
+
for (const { name, fnType } of extractedRefs) {
|
|
164
|
+
const body = moduleFns.get(name);
|
|
165
|
+
if (body) walkThrows(body, fnType);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
var api_error_default = definePlugin({
|
|
172
|
+
meta: { name: "eslint-plugin-mahir-api-error" },
|
|
173
|
+
rules: { "require-api-error": requireApiError }
|
|
174
|
+
});
|
|
166
175
|
|
|
167
176
|
//#endregion
|
|
168
|
-
export {
|
|
177
|
+
export { api_error_default as default };
|
|
169
178
|
//# sourceMappingURL=api-error.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-error.js","names":[],"sources":["../../src/plugins/api-error.ts"],"sourcesContent":["import type { TSESLint, TSESTree } from '@typescript-eslint/utils';\n\nconst DEFAULT_ALLOWED_ERRORS = ['ApiError', 'FormValidationError'];\n\nfunction getStaticFactoryCallee(arg: TSESTree.ThrowStatement['argument']) {\n\tif (arg.type !== 'CallExpression') return undefined;\n\tconst { callee } = arg;\n\tif (callee.type !== 'MemberExpression' || callee.computed) return undefined;\n\tconst { object, property } = callee;\n\tif (object.type !== 'Identifier' || property.type !== 'Identifier') return undefined;\n\treturn { callee, name: object.name };\n}\n\nfunction isAstNode(value: unknown): value is TSESTree.Node {\n\treturn typeof value === 'object' && value !== null && 'type' in value && typeof value.type === 'string';\n}\n\ntype Options = [\n\t{\n\t\tallowedErrors?: string[];\n\t},\n];\n\nconst requireApiError: TSESLint.RuleModule<'useApiError' | 'useApiErrorCall' | 'useApiErrorMember', Options> = {\n\tmeta: {\n\t\ttype: 'problem',\n\t\tdocs: {\n\t\t\tdescription:\n\t\t\t\t'Require an allowed API error instead of Error inside queryFn/mutationFn so status codes propagate to QueryCache error handling',\n\t\t},\n\t\tschema: [\n\t\t\t{\n\t\t\t\ttype: 'object',\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tproperties: {\n\t\t\t\t\tallowedErrors: {\n\t\t\t\t\t\ttype: 'array',\n\t\t\t\t\t\titems: { type: 'string', minLength: 1 },\n\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\tuniqueItems: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tmessages: {\n\t\t\tuseApiError:\n\t\t\t\t'Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `new {{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.',\n\t\t\tuseApiErrorCall:\n\t\t\t\t'Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `{{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.',\n\t\t\tuseApiErrorMember:\n\t\t\t\t'Throw `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of re-throwing `{{thrown}}` directly inside {{fnType}}. The client error object may lose its HTTP status code in QueryCache/retry/error reporting.',\n\t\t},\n\t},\n\tdefaultOptions: [{ allowedErrors: [...DEFAULT_ALLOWED_ERRORS] }],\n\tcreate(context) {\n\t\tconst sourceCode = context.sourceCode;\n\t\t// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n\t\tconst allowedList = context.options[0]?.allowedErrors ?? DEFAULT_ALLOWED_ERRORS;\n\t\tconst allowedErrors = new Set(allowedList);\n\t\tconst allowedExample = allowedList[0] ?? DEFAULT_ALLOWED_ERRORS[0];\n\t\tconst fnStack: string[] = [];\n\t\tconst extractedRefs: { name: string; fnType: string }[] = [];\n\t\tconst moduleFns = new Map<string, TSESTree.Node>();\n\n\t\tfunction recordModuleFn(name: string | undefined, body: TSESTree.Node | null | undefined) {\n\t\t\tif (!name || !body) return;\n\t\t\tif (!moduleFns.has(name)) moduleFns.set(name, body);\n\t\t}\n\n\t\tfunction isAllowedThrow(arg: TSESTree.ThrowStatement['argument']) {\n\t\t\tif (arg.type === 'NewExpression' && arg.callee.type === 'Identifier') return allowedErrors.has(arg.callee.name);\n\n\t\t\tconst factory = getStaticFactoryCallee(arg);\n\t\t\treturn factory !== undefined && allowedErrors.has(factory.name);\n\t\t}\n\n\t\tfunction checkThrowNode(node: TSESTree.ThrowStatement, fnType: string) {\n\t\t\tconst arg = node.argument;\n\t\t\tif (isAllowedThrow(arg)) return;\n\n\t\t\tif (arg.type === 'NewExpression' && arg.callee.type === 'Identifier') {\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: arg,\n\t\t\t\t\tmessageId: 'useApiError',\n\t\t\t\t\tdata: { thrown: arg.callee.name, fnType, allowed: allowedExample },\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst factory = getStaticFactoryCallee(arg);\n\t\t\tif (factory) {\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: arg,\n\t\t\t\t\tmessageId: 'useApiErrorCall',\n\t\t\t\t\tdata: { thrown: sourceCode.getText(factory.callee), fnType, allowed: allowedExample },\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (arg.type === 'MemberExpression') {\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: arg,\n\t\t\t\t\tmessageId: 'useApiErrorMember',\n\t\t\t\t\tdata: { thrown: sourceCode.getText(arg), fnType, allowed: allowedExample },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction walkThrows(node: TSESTree.Node | null | undefined, fnType: string, visited = new Set<TSESTree.Node>()) {\n\t\t\tif (!node || visited.has(node)) return;\n\t\t\tvisited.add(node);\n\n\t\t\tif (node.type === 'ThrowStatement') {\n\t\t\t\tcheckThrowNode(node, fnType);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tnode.type === 'FunctionDeclaration' ||\n\t\t\t\tnode.type === 'FunctionExpression' ||\n\t\t\t\tnode.type === 'ArrowFunctionExpression'\n\t\t\t) {\n\t\t\t\twalkThrows(node.body, fnType, visited);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (const key of Object.keys(node)) {\n\t\t\t\tif (key === 'parent' || key === 'loc' || key === 'range') continue;\n\t\t\t\tconst child = (node as unknown as Record<string, unknown>)[key];\n\t\t\t\tif (Array.isArray(child)) {\n\t\t\t\t\tfor (const c of child) if (isAstNode(c)) walkThrows(c, fnType, visited);\n\t\t\t\t} else if (isAstNode(child)) walkThrows(child, fnType, visited);\n\t\t\t}\n\t\t}\n\n\t\tfunction enterQueryOrMutationFn(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression) {\n\t\t\tconst parent = node.parent;\n\t\t\tif (parent.type !== 'Property' || parent.key.type !== 'Identifier') return;\n\t\t\tconst name = parent.key.name;\n\t\t\tif (name === 'queryFn' || name === 'mutationFn') fnStack.push(name);\n\t\t}\n\n\t\tfunction exitQueryOrMutationFn(node: TSESTree.ArrowFunctionExpression | TSESTree.FunctionExpression) {\n\t\t\tconst parent = node.parent;\n\t\t\tif (parent.type !== 'Property' || parent.key.type !== 'Identifier') return;\n\t\t\tconst name = parent.key.name;\n\t\t\tif (name === 'queryFn' || name === 'mutationFn') fnStack.pop();\n\t\t}\n\n\t\tfunction checkThrowStatement(node: TSESTree.ThrowStatement) {\n\t\t\tif (fnStack.length === 0) return;\n\t\t\tcheckThrowNode(node, fnStack[fnStack.length - 1]);\n\t\t}\n\n\t\tfunction recordExtractedRef(prop: TSESTree.Property) {\n\t\t\tif (\n\t\t\t\tprop.key.type !== 'Identifier' ||\n\t\t\t\t(prop.key.name !== 'queryFn' && prop.key.name !== 'mutationFn') ||\n\t\t\t\tprop.value.type !== 'Identifier'\n\t\t\t)\n\t\t\t\treturn;\n\t\t\textractedRefs.push({ name: prop.value.name, fnType: prop.key.name });\n\t\t}\n\n\t\treturn {\n\t\t\t'Program > FunctionDeclaration'(node: TSESTree.FunctionDeclaration) {\n\t\t\t\trecordModuleFn(node.id?.name, node.body);\n\t\t\t},\n\t\t\t'Program > VariableDeclaration > VariableDeclarator'(node: TSESTree.VariableDeclarator) {\n\t\t\t\tif (\n\t\t\t\t\tnode.id.type === 'Identifier' &&\n\t\t\t\t\t(node.init?.type === 'ArrowFunctionExpression' || node.init?.type === 'FunctionExpression')\n\t\t\t\t)\n\t\t\t\t\trecordModuleFn(node.id.name, node.init.body);\n\t\t\t},\n\t\t\tArrowFunctionExpression: enterQueryOrMutationFn,\n\t\t\t'ArrowFunctionExpression:exit': exitQueryOrMutationFn,\n\t\t\tFunctionExpression: enterQueryOrMutationFn,\n\t\t\t'FunctionExpression:exit': exitQueryOrMutationFn,\n\t\t\tProperty: recordExtractedRef,\n\t\t\tThrowStatement: checkThrowStatement,\n\t\t\t'Program:exit'() {\n\t\t\t\tfor (const { name, fnType } of extractedRefs) {\n\t\t\t\t\tconst body = moduleFns.get(name);\n\t\t\t\t\tif (body) walkThrows(body, fnType);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t},\n};\n\nconst plugin: TSESLint.FlatConfig.Plugin = {\n\tmeta: {\n\t\tname: 'eslint-plugin-mahir-api-error',\n\t\tversion: '1.0.0',\n\t},\n\trules: {\n\t\t'require-api-error': requireApiError,\n\t},\n};\n\nexport default plugin;\n"],"mappings":";AAEA,MAAM,yBAAyB,CAAC,YAAY,qBAAqB;AAEjE,SAAS,uBAAuB,KAA0C;CACzE,IAAI,IAAI,SAAS,kBAAkB,OAAO;CAC1C,MAAM,EAAE,WAAW;CACnB,IAAI,OAAO,SAAS,sBAAsB,OAAO,UAAU,OAAO;CAClE,MAAM,EAAE,QAAQ,aAAa;CAC7B,IAAI,OAAO,SAAS,gBAAgB,SAAS,SAAS,cAAc,OAAO;CAC3E,OAAO;EAAE;EAAQ,MAAM,OAAO;CAAK;AACpC;AAEA,SAAS,UAAU,OAAwC;CAC1D,OAAO,OAAO,UAAU,YAAY,UAAU,QAAQ,UAAU,SAAS,OAAO,MAAM,SAAS;AAChG;AAgLA,MAAM,SAAqC;CAC1C,MAAM;EACL,MAAM;EACN,SAAS;CACV;CACA,OAAO,EACN,qBAAqB;EA7KtB,MAAM;GACL,MAAM;GACN,MAAM,EACL,aACC,iIACF;GACA,QAAQ,CACP;IACC,MAAM;IACN,sBAAsB;IACtB,YAAY,EACX,eAAe;KACd,MAAM;KACN,OAAO;MAAE,MAAM;MAAU,WAAW;KAAE;KACtC,UAAU;KACV,aAAa;IACd,EACD;GACD,CACD;GACA,UAAU;IACT,aACC;IACD,iBACC;IACD,mBACC;GACF;EACD;EACA,gBAAgB,CAAC,EAAE,eAAe,CAAC,GAAG,sBAAsB,EAAE,CAAC;EAC/D,OAAO,SAAS;GACf,MAAM,aAAa,QAAQ;GAE3B,MAAM,cAAc,QAAQ,QAAQ,EAAE,EAAE,iBAAiB;GACzD,MAAM,gBAAgB,IAAI,IAAI,WAAW;GACzC,MAAM,iBAAiB,YAAY,MAAM,uBAAuB;GAChE,MAAM,UAAoB,CAAC;GAC3B,MAAM,gBAAoD,CAAC;GAC3D,MAAM,4BAAY,IAAI,IAA2B;GAEjD,SAAS,eAAe,MAA0B,MAAwC;IACzF,IAAI,CAAC,QAAQ,CAAC,MAAM;IACpB,IAAI,CAAC,UAAU,IAAI,IAAI,GAAG,UAAU,IAAI,MAAM,IAAI;GACnD;GAEA,SAAS,eAAe,KAA0C;IACjE,IAAI,IAAI,SAAS,mBAAmB,IAAI,OAAO,SAAS,cAAc,OAAO,cAAc,IAAI,IAAI,OAAO,IAAI;IAE9G,MAAM,UAAU,uBAAuB,GAAG;IAC1C,OAAO,YAAY,UAAa,cAAc,IAAI,QAAQ,IAAI;GAC/D;GAEA,SAAS,eAAe,MAA+B,QAAgB;IACtE,MAAM,MAAM,KAAK;IACjB,IAAI,eAAe,GAAG,GAAG;IAEzB,IAAI,IAAI,SAAS,mBAAmB,IAAI,OAAO,SAAS,cAAc;KACrE,QAAQ,OAAO;MACd,MAAM;MACN,WAAW;MACX,MAAM;OAAE,QAAQ,IAAI,OAAO;OAAM;OAAQ,SAAS;MAAe;KAClE,CAAC;KACD;IACD;IAEA,MAAM,UAAU,uBAAuB,GAAG;IAC1C,IAAI,SAAS;KACZ,QAAQ,OAAO;MACd,MAAM;MACN,WAAW;MACX,MAAM;OAAE,QAAQ,WAAW,QAAQ,QAAQ,MAAM;OAAG;OAAQ,SAAS;MAAe;KACrF,CAAC;KACD;IACD;IAEA,IAAI,IAAI,SAAS,oBAChB,QAAQ,OAAO;KACd,MAAM;KACN,WAAW;KACX,MAAM;MAAE,QAAQ,WAAW,QAAQ,GAAG;MAAG;MAAQ,SAAS;KAAe;IAC1E,CAAC;GAEH;GAEA,SAAS,WAAW,MAAwC,QAAgB,0BAAU,IAAI,IAAmB,GAAG;IAC/G,IAAI,CAAC,QAAQ,QAAQ,IAAI,IAAI,GAAG;IAChC,QAAQ,IAAI,IAAI;IAEhB,IAAI,KAAK,SAAS,kBAAkB;KACnC,eAAe,MAAM,MAAM;KAC3B;IACD;IAEA,IACC,KAAK,SAAS,yBACd,KAAK,SAAS,wBACd,KAAK,SAAS,2BACb;KACD,WAAW,KAAK,MAAM,QAAQ,OAAO;KACrC;IACD;IAEA,KAAK,MAAM,OAAO,OAAO,KAAK,IAAI,GAAG;KACpC,IAAI,QAAQ,YAAY,QAAQ,SAAS,QAAQ,SAAS;KAC1D,MAAM,QAAS,KAA4C;KAC3D,IAAI,MAAM,QAAQ,KAAK,GACtB;WAAK,MAAM,KAAK,OAAO,IAAI,UAAU,CAAC,GAAG,WAAW,GAAG,QAAQ,OAAO;KAAC,OACjE,IAAI,UAAU,KAAK,GAAG,WAAW,OAAO,QAAQ,OAAO;IAC/D;GACD;GAEA,SAAS,uBAAuB,MAAsE;IACrG,MAAM,SAAS,KAAK;IACpB,IAAI,OAAO,SAAS,cAAc,OAAO,IAAI,SAAS,cAAc;IACpE,MAAM,OAAO,OAAO,IAAI;IACxB,IAAI,SAAS,aAAa,SAAS,cAAc,QAAQ,KAAK,IAAI;GACnE;GAEA,SAAS,sBAAsB,MAAsE;IACpG,MAAM,SAAS,KAAK;IACpB,IAAI,OAAO,SAAS,cAAc,OAAO,IAAI,SAAS,cAAc;IACpE,MAAM,OAAO,OAAO,IAAI;IACxB,IAAI,SAAS,aAAa,SAAS,cAAc,QAAQ,IAAI;GAC9D;GAEA,SAAS,oBAAoB,MAA+B;IAC3D,IAAI,QAAQ,WAAW,GAAG;IAC1B,eAAe,MAAM,QAAQ,QAAQ,SAAS,EAAE;GACjD;GAEA,SAAS,mBAAmB,MAAyB;IACpD,IACC,KAAK,IAAI,SAAS,gBACjB,KAAK,IAAI,SAAS,aAAa,KAAK,IAAI,SAAS,gBAClD,KAAK,MAAM,SAAS,cAEpB;IACD,cAAc,KAAK;KAAE,MAAM,KAAK,MAAM;KAAM,QAAQ,KAAK,IAAI;IAAK,CAAC;GACpE;GAEA,OAAO;IACN,gCAAgC,MAAoC;KACnE,eAAe,KAAK,IAAI,MAAM,KAAK,IAAI;IACxC;IACA,qDAAqD,MAAmC;KACvF,IACC,KAAK,GAAG,SAAS,iBAChB,KAAK,MAAM,SAAS,6BAA6B,KAAK,MAAM,SAAS,uBAEtE,eAAe,KAAK,GAAG,MAAM,KAAK,KAAK,IAAI;IAC7C;IACA,yBAAyB;IACzB,gCAAgC;IAChC,oBAAoB;IACpB,2BAA2B;IAC3B,UAAU;IACV,gBAAgB;IAChB,iBAAiB;KAChB,KAAK,MAAM,EAAE,MAAM,YAAY,eAAe;MAC7C,MAAM,OAAO,UAAU,IAAI,IAAI;MAC/B,IAAI,MAAM,WAAW,MAAM,MAAM;KAClC;IACD;GACD;EACD;CASoC,EACpC;AACD"}
|
|
1
|
+
{"version":3,"file":"api-error.js","names":[],"sources":["../../src/plugins/api-error.ts"],"sourcesContent":["import { definePlugin, defineRule } from '@oxlint/plugins';\n\nimport type { ESTree } from '@oxlint/plugins';\n\nconst DEFAULT_ALLOWED_ERRORS = ['ApiError', 'FormValidationError'];\n\nfunction getStaticFactoryCallee(arg: ESTree.Node) {\n\tif (arg.type !== 'CallExpression') return undefined;\n\tconst { callee } = arg;\n\tif (callee.type !== 'MemberExpression' || callee.computed) return undefined;\n\tconst { object, property } = callee;\n\tif (object.type !== 'Identifier' || property.type !== 'Identifier') return undefined;\n\treturn { callee, name: object.name };\n}\n\nfunction isAstNode(value: unknown): value is ESTree.Node {\n\treturn typeof value === 'object' && value !== null && 'type' in value && typeof (value as { type: unknown }).type === 'string';\n}\n\nconst requireApiError = defineRule({\n\tmeta: {\n\t\ttype: 'problem',\n\t\tdocs: {\n\t\t\tdescription:\n\t\t\t\t'Require an allowed API error instead of Error inside queryFn/mutationFn so status codes propagate to QueryCache error handling',\n\t\t},\n\t\tschema: [\n\t\t\t{\n\t\t\t\ttype: 'object',\n\t\t\t\tadditionalProperties: false,\n\t\t\t\tproperties: {\n\t\t\t\t\tallowedErrors: {\n\t\t\t\t\t\ttype: 'array',\n\t\t\t\t\t\titems: { type: 'string', minLength: 1 },\n\t\t\t\t\t\tminItems: 1,\n\t\t\t\t\t\tuniqueItems: true,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t],\n\t\tmessages: {\n\t\t\tuseApiError:\n\t\t\t\t'Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `new {{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.',\n\t\t\tuseApiErrorCall:\n\t\t\t\t'Use `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of `{{thrown}}(...)` inside {{fnType}}. This ensures the HTTP status code is available in QueryCache/retry/error reporting.',\n\t\t\tuseApiErrorMember:\n\t\t\t\t'Throw `new {{allowed}}(...)` or `{{allowed}}.from(...)` instead of re-throwing `{{thrown}}` directly inside {{fnType}}. The client error object may lose its HTTP status code in QueryCache/retry/error reporting.',\n\t\t},\n\t\tdefaultOptions: [{ allowedErrors: [...DEFAULT_ALLOWED_ERRORS] }],\n\t},\n\tcreateOnce(context) {\n\t\tlet allowedErrors = new Set(DEFAULT_ALLOWED_ERRORS);\n\t\tlet allowedExample = DEFAULT_ALLOWED_ERRORS[0];\n\t\tconst fnStack: string[] = [];\n\t\tconst extractedRefs: { name: string; fnType: string }[] = [];\n\t\tconst moduleFns = new Map<string, ESTree.Node>();\n\n\t\tfunction recordModuleFn(name: string | undefined, body: ESTree.Node | null | undefined) {\n\t\t\tif (!name || !body) return;\n\t\t\tif (!moduleFns.has(name)) moduleFns.set(name, body);\n\t\t}\n\n\t\tfunction isAllowedThrow(arg: ESTree.Node) {\n\t\t\tif (arg.type === 'NewExpression' && arg.callee.type === 'Identifier') return allowedErrors.has(arg.callee.name);\n\t\t\tconst factory = getStaticFactoryCallee(arg);\n\t\t\treturn factory !== undefined && allowedErrors.has(factory.name);\n\t\t}\n\n\t\tfunction checkThrowNode(node: ESTree.ThrowStatement, fnType: string) {\n\t\t\tconst arg = node.argument;\n\t\t\tif (isAllowedThrow(arg)) return;\n\n\t\t\tif (arg.type === 'NewExpression' && arg.callee.type === 'Identifier') {\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: arg,\n\t\t\t\t\tmessageId: 'useApiError',\n\t\t\t\t\tdata: { thrown: arg.callee.name, fnType, allowed: allowedExample },\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst factory = getStaticFactoryCallee(arg);\n\t\t\tif (factory) {\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: arg,\n\t\t\t\t\tmessageId: 'useApiErrorCall',\n\t\t\t\t\tdata: { thrown: context.sourceCode.getText(factory.callee), fnType, allowed: allowedExample },\n\t\t\t\t});\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (arg.type === 'MemberExpression') {\n\t\t\t\tcontext.report({\n\t\t\t\t\tnode: arg,\n\t\t\t\t\tmessageId: 'useApiErrorMember',\n\t\t\t\t\tdata: { thrown: context.sourceCode.getText(arg), fnType, allowed: allowedExample },\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction walkThrows(node: ESTree.Node | null | undefined, fnType: string, visited = new Set<ESTree.Node>()) {\n\t\t\tif (!node || visited.has(node)) return;\n\t\t\tvisited.add(node);\n\n\t\t\tif (node.type === 'ThrowStatement') {\n\t\t\t\tcheckThrowNode(node, fnType);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (\n\t\t\t\tnode.type === 'FunctionDeclaration' ||\n\t\t\t\tnode.type === 'FunctionExpression' ||\n\t\t\t\tnode.type === 'ArrowFunctionExpression'\n\t\t\t) {\n\t\t\t\twalkThrows(node.body, fnType, visited);\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tfor (const key of Object.keys(node)) {\n\t\t\t\tif (key === 'parent' || key === 'loc' || key === 'range') continue;\n\t\t\t\tconst child = (node as unknown as Record<string, unknown>)[key];\n\t\t\t\tif (Array.isArray(child)) {\n\t\t\t\t\tfor (const item of child) if (isAstNode(item)) walkThrows(item, fnType, visited);\n\t\t\t\t} else if (isAstNode(child)) walkThrows(child, fnType, visited);\n\t\t\t}\n\t\t}\n\n\t\tfunction enterQueryOrMutationFn(node: ESTree.ArrowFunctionExpression | ESTree.Function) {\n\t\t\tconst parent = node.parent;\n\t\t\tif (parent.type !== 'Property' || parent.key.type !== 'Identifier') return;\n\t\t\tconst name = parent.key.name;\n\t\t\tif (name === 'queryFn' || name === 'mutationFn') fnStack.push(name);\n\t\t}\n\n\t\tfunction exitQueryOrMutationFn(node: ESTree.ArrowFunctionExpression | ESTree.Function) {\n\t\t\tconst parent = node.parent;\n\t\t\tif (parent.type !== 'Property' || parent.key.type !== 'Identifier') return;\n\t\t\tconst name = parent.key.name;\n\t\t\tif (name === 'queryFn' || name === 'mutationFn') fnStack.pop();\n\t\t}\n\n\t\tfunction checkThrowStatement(node: ESTree.ThrowStatement) {\n\t\t\tif (fnStack.length === 0) return;\n\t\t\tcheckThrowNode(node, fnStack.at(-1) ?? '');\n\t\t}\n\n\t\tfunction recordExtractedRef(prop: ESTree.Node) {\n\t\t\tif (prop.type !== 'Property') return;\n\t\t\tif (\n\t\t\t\tprop.key.type !== 'Identifier' ||\n\t\t\t\t(prop.key.name !== 'queryFn' && prop.key.name !== 'mutationFn') ||\n\t\t\t\tprop.value.type !== 'Identifier'\n\t\t\t)\n\t\t\t\treturn;\n\t\t\textractedRefs.push({ name: prop.value.name, fnType: prop.key.name });\n\t\t}\n\n\t\treturn {\n\t\t\tbefore() {\n\t\t\t\tconst options = context.options[0] as { allowedErrors?: string[] } | undefined;\n\t\t\t\tconst allowedList = options?.allowedErrors ?? DEFAULT_ALLOWED_ERRORS;\n\t\t\t\tallowedErrors = new Set(allowedList);\n\t\t\t\tallowedExample = allowedList[0] ?? DEFAULT_ALLOWED_ERRORS[0];\n\t\t\t\tfnStack.length = 0;\n\t\t\t\textractedRefs.length = 0;\n\t\t\t\tmoduleFns.clear();\n\t\t\t},\n\t\t\t'Program > FunctionDeclaration'(node) {\n\t\t\t\tif (node.type !== 'FunctionDeclaration') return;\n\t\t\t\trecordModuleFn(node.id?.name, node.body);\n\t\t\t},\n\t\t\t'Program > VariableDeclaration > VariableDeclarator'(node) {\n\t\t\t\tif (node.type !== 'VariableDeclarator') return;\n\t\t\t\tif (\n\t\t\t\t\tnode.id.type === 'Identifier' &&\n\t\t\t\t\t(node.init?.type === 'ArrowFunctionExpression' || node.init?.type === 'FunctionExpression')\n\t\t\t\t)\n\t\t\t\t\trecordModuleFn(node.id.name, node.init.body);\n\t\t\t},\n\t\t\tArrowFunctionExpression: enterQueryOrMutationFn,\n\t\t\t'ArrowFunctionExpression:exit': exitQueryOrMutationFn,\n\t\t\tFunctionExpression: enterQueryOrMutationFn,\n\t\t\t'FunctionExpression:exit': exitQueryOrMutationFn,\n\t\t\tProperty: recordExtractedRef,\n\t\t\tThrowStatement: checkThrowStatement,\n\t\t\t'Program:exit'() {\n\t\t\t\tfor (const { name, fnType } of extractedRefs) {\n\t\t\t\t\tconst body = moduleFns.get(name);\n\t\t\t\t\tif (body) walkThrows(body, fnType);\n\t\t\t\t}\n\t\t\t},\n\t\t};\n\t},\n});\n\nexport default definePlugin({\n\tmeta: {\n\t\tname: 'eslint-plugin-mahir-api-error',\n\t},\n\trules: {\n\t\t'require-api-error': requireApiError,\n\t},\n});\n"],"mappings":"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"}
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { TSESLint } from "@typescript-eslint/utils";
|
|
2
1
|
//#region src/plugins/central-icons.d.ts
|
|
3
|
-
declare const
|
|
2
|
+
declare const _default: import("@oxlint/plugins").Plugin;
|
|
4
3
|
//#endregion
|
|
5
|
-
export {
|
|
4
|
+
export { _default as default };
|
|
6
5
|
//# sourceMappingURL=central-icons.d.ts.map
|
|
@@ -1,61 +1,59 @@
|
|
|
1
|
+
import { definePlugin, defineRule } from "@oxlint/plugins";
|
|
2
|
+
|
|
1
3
|
//#region src/plugins/central-icons.ts
|
|
2
4
|
const CENTRAL_ICONS_PACKAGE_RE = /^@central-icons-react(?:-native)?\/[^/]+$/;
|
|
3
5
|
function centralIconSubpath(iconName) {
|
|
4
6
|
if (iconName.endsWith("Default")) return iconName.slice(0, -7);
|
|
5
7
|
return iconName;
|
|
6
8
|
}
|
|
7
|
-
const
|
|
9
|
+
const noCentralIconsBarrelImport = defineRule({
|
|
8
10
|
meta: {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
+
type: "problem",
|
|
12
|
+
docs: { description: "Disallow barrel imports from @central-icons-react and @central-icons-react-native packages; use direct subpath imports instead" },
|
|
13
|
+
fixable: "code",
|
|
14
|
+
messages: {
|
|
15
|
+
barrelImport: "Avoid barrel imports from `{{source}}`. Import icons directly from `{{source}}/<IconName>` to keep the bundler from opening thousands of icon files.",
|
|
16
|
+
unsupportedImport: "Only named icon imports can be autofixed. Use direct subpath default imports from `{{source}}/<IconName>`."
|
|
17
|
+
}
|
|
11
18
|
},
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
messages: {
|
|
19
|
-
barrelImport: "Avoid barrel imports from `{{source}}`. Import icons directly from `{{source}}/<IconName>` to keep the bundler from opening thousands of icon files.",
|
|
20
|
-
unsupportedImport: "Only named icon imports can be autofixed. Use direct subpath default imports from `{{source}}/<IconName>`."
|
|
21
|
-
}
|
|
22
|
-
},
|
|
23
|
-
defaultOptions: [],
|
|
24
|
-
create(context) {
|
|
25
|
-
return { ImportDeclaration(node) {
|
|
26
|
-
const source = node.source.value;
|
|
27
|
-
if (typeof source !== "string" || !CENTRAL_ICONS_PACKAGE_RE.test(source)) return;
|
|
28
|
-
const namedSpecifiers = node.specifiers.filter((specifier) => specifier.type === "ImportSpecifier");
|
|
29
|
-
if (namedSpecifiers.length === 0 || namedSpecifiers.length !== node.specifiers.length) {
|
|
30
|
-
context.report({
|
|
31
|
-
node,
|
|
32
|
-
messageId: "unsupportedImport",
|
|
33
|
-
data: { source }
|
|
34
|
-
});
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
19
|
+
createOnce(context) {
|
|
20
|
+
return { ImportDeclaration(node) {
|
|
21
|
+
const source = node.source.value;
|
|
22
|
+
if (typeof source !== "string" || !CENTRAL_ICONS_PACKAGE_RE.test(source)) return;
|
|
23
|
+
const namedSpecifiers = node.specifiers.filter((specifier) => specifier.type === "ImportSpecifier");
|
|
24
|
+
if (namedSpecifiers.length === 0 || namedSpecifiers.length !== node.specifiers.length) {
|
|
37
25
|
context.report({
|
|
38
26
|
node,
|
|
39
|
-
messageId: "
|
|
40
|
-
data: { source }
|
|
41
|
-
fix(fixer) {
|
|
42
|
-
const quote = node.source.raw.startsWith("'") ? "'" : "\"";
|
|
43
|
-
const fixedImports = namedSpecifiers.map((specifier) => {
|
|
44
|
-
const imported = specifier.imported;
|
|
45
|
-
const importedName = imported.type === "Identifier" ? imported.name : imported.value;
|
|
46
|
-
const localName = specifier.local.name;
|
|
47
|
-
const typePrefix = node.importKind === "type" || specifier.importKind === "type" ? "type " : "";
|
|
48
|
-
const subpath = centralIconSubpath(importedName);
|
|
49
|
-
return `import ${typePrefix}${localName} from ${quote}${source}/${subpath}${quote};`;
|
|
50
|
-
});
|
|
51
|
-
return fixer.replaceText(node, fixedImports.join("\n"));
|
|
52
|
-
}
|
|
27
|
+
messageId: "unsupportedImport",
|
|
28
|
+
data: { source }
|
|
53
29
|
});
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
context.report({
|
|
33
|
+
node,
|
|
34
|
+
messageId: "barrelImport",
|
|
35
|
+
data: { source },
|
|
36
|
+
fix(fixer) {
|
|
37
|
+
const quote = (node.source.raw ?? "\"").startsWith("'") ? "'" : "\"";
|
|
38
|
+
const fixedImports = namedSpecifiers.map((specifier) => {
|
|
39
|
+
const imported = specifier.imported;
|
|
40
|
+
const importedName = imported.type === "Identifier" ? imported.name : imported.value;
|
|
41
|
+
const localName = specifier.local.name;
|
|
42
|
+
const typePrefix = node.importKind === "type" || specifier.importKind === "type" ? "type " : "";
|
|
43
|
+
const subpath = centralIconSubpath(importedName);
|
|
44
|
+
return `import ${typePrefix}${localName} from ${quote}${source}/${subpath}${quote};`;
|
|
45
|
+
});
|
|
46
|
+
return fixer.replaceText(node, fixedImports.join("\n"));
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
} };
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
var central_icons_default = definePlugin({
|
|
53
|
+
meta: { name: "eslint-plugin-mahir-central-icons" },
|
|
54
|
+
rules: { "no-central-icons-barrel-import": noCentralIconsBarrelImport }
|
|
55
|
+
});
|
|
58
56
|
|
|
59
57
|
//#endregion
|
|
60
|
-
export {
|
|
58
|
+
export { central_icons_default as default };
|
|
61
59
|
//# sourceMappingURL=central-icons.js.map
|