@venizia/dev-configs 0.4.1 → 0.4.3

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.
Files changed (47) hide show
  1. package/README.md +5 -3
  2. package/dist/cli/clean.d.ts +2 -1
  3. package/dist/cli/clean.d.ts.map +1 -1
  4. package/dist/cli/clean.js +28 -1
  5. package/dist/cli/clean.js.map +1 -1
  6. package/dist/cli/codemod/files.d.ts +22 -0
  7. package/dist/cli/codemod/files.d.ts.map +1 -0
  8. package/dist/cli/codemod/files.js +68 -0
  9. package/dist/cli/codemod/files.js.map +1 -0
  10. package/dist/cli/codemod/index.d.ts +13 -0
  11. package/dist/cli/codemod/index.d.ts.map +1 -0
  12. package/dist/cli/codemod/index.js +106 -0
  13. package/dist/cli/codemod/index.js.map +1 -0
  14. package/dist/cli/codemod/model-settings.d.ts +34 -0
  15. package/dist/cli/codemod/model-settings.d.ts.map +1 -0
  16. package/dist/cli/codemod/model-settings.js +307 -0
  17. package/dist/cli/codemod/model-settings.js.map +1 -0
  18. package/dist/cli/index.js +17 -2
  19. package/dist/cli/index.js.map +1 -1
  20. package/dist/linters/house/common.d.ts +1 -0
  21. package/dist/linters/house/common.d.ts.map +1 -1
  22. package/dist/linters/house/common.js +1 -0
  23. package/dist/linters/house/common.js.map +1 -1
  24. package/dist/linters/house/configs.d.ts.map +1 -1
  25. package/dist/linters/house/configs.js +20 -1
  26. package/dist/linters/house/configs.js.map +1 -1
  27. package/dist/linters/house/const-class-values.rule.d.ts +7 -4
  28. package/dist/linters/house/const-class-values.rule.d.ts.map +1 -1
  29. package/dist/linters/house/const-class-values.rule.js +73 -21
  30. package/dist/linters/house/const-class-values.rule.js.map +1 -1
  31. package/dist/linters/rules/common.d.ts +48 -1
  32. package/dist/linters/rules/common.d.ts.map +1 -1
  33. package/dist/linters/rules/common.js +53 -0
  34. package/dist/linters/rules/common.js.map +1 -1
  35. package/dist/linters/rules/eqeqeq.rule.d.ts +2 -2
  36. package/dist/linters/rules/eqeqeq.rule.d.ts.map +1 -1
  37. package/dist/linters/rules/eqeqeq.rule.js +2 -1
  38. package/dist/linters/rules/eqeqeq.rule.js.map +1 -1
  39. package/dist/linters/rules/no-unused-vars.rule.d.ts +3 -3
  40. package/dist/linters/rules/no-unused-vars.rule.d.ts.map +1 -1
  41. package/dist/linters/rules/no-unused-vars.rule.js +2 -1
  42. package/dist/linters/rules/no-unused-vars.rule.js.map +1 -1
  43. package/dist/linters/rules/switch-case-braces.rule.d.ts +2 -2
  44. package/dist/linters/rules/switch-case-braces.rule.d.ts.map +1 -1
  45. package/dist/linters/rules/switch-case-braces.rule.js +2 -1
  46. package/dist/linters/rules/switch-case-braces.rule.js.map +1 -1
  47. package/package.json +1 -1
@@ -2,15 +2,55 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ConstClassValuesRule = void 0;
4
4
  const common_1 = require("./common");
5
+ /** Utility types whose type argument is a set of keys, not an enumerable value: `Pick<T, 'a' | 'b'>`. */
6
+ const KEY_SET_TYPES = new Set(['Pick', 'Omit', 'Extract', 'Exclude', 'Record']);
7
+ /** The union is a type argument of a key-set utility type, or the key range of a mapped type. */
8
+ const isKeySet = (opts) => {
9
+ const parent = (0, common_1.readField)({ node: opts.node, key: 'parent' });
10
+ if ((0, common_1.nodeType)({ node: parent }) === 'TSMappedType') {
11
+ return true;
12
+ }
13
+ if ((0, common_1.nodeType)({ node: parent }) !== 'TSTypeParameterInstantiation') {
14
+ return false;
15
+ }
16
+ const reference = (0, common_1.readField)({ node: parent, key: 'parent' });
17
+ const name = (0, common_1.readField)({ node: (0, common_1.readField)({ node: reference, key: 'typeName' }), key: 'name' });
18
+ return (0, common_1.nodeType)({ node: reference }) === 'TSTypeReference' && KEY_SET_TYPES.has(String(name));
19
+ };
20
+ /** The statement of the module that holds the node: the node's last ancestor before `Program`. */
21
+ const topLevelStatement = (opts) => {
22
+ let current = opts.node;
23
+ while (current) {
24
+ const parent = (0, common_1.readField)({ node: current, key: 'parent' });
25
+ if ((0, common_1.nodeType)({ node: parent }) === 'Program') {
26
+ return current;
27
+ }
28
+ current = parent;
29
+ }
30
+ return undefined;
31
+ };
32
+ const isStringLiteral = (opts) => {
33
+ const { member } = opts;
34
+ return ((0, common_1.nodeType)({ node: member }) === 'TSLiteralType' &&
35
+ typeof (0, common_1.readField)({ node: (0, common_1.readField)({ node: member, key: 'literal' }), key: 'value' }) ===
36
+ 'string');
37
+ };
38
+ const isNullish = (opts) => {
39
+ const type = (0, common_1.nodeType)({ node: opts.member });
40
+ return type === 'TSNullKeyword' || type === 'TSUndefinedKeyword';
41
+ };
5
42
  /**
6
43
  * `venizia/const-class-values`. An enumerable string is a const class plus `TConstValue<typeof X>`,
7
- * never an exported union of string literals. Only a type whose name ends like a logic value is
8
- * checked (`State`, `Status`, `Stage`, `Mode`, `Kind`, `Type` by default): any other string union may
9
- * be a plain parameter type.
44
+ * never a union of string literals in an exported declaration: a type alias, an interface member, a
45
+ * generic constraint, a parameter or a return type of an exported function or class.
46
+ *
47
+ * Not counted: a union that is not all string literals (a `null` or `undefined` member is ignored),
48
+ * a key set (`Pick`, `Omit`, `Extract`, `Exclude`, `Record` arguments and mapped-type keys), and a
49
+ * declaration that is not exported. `namePattern` narrows the rule to exported type aliases whose name
50
+ * matches it (`(State|Status)$`), for a project that adopts the rule one name at a time.
10
51
  */
11
52
  class ConstClassValuesRule {
12
53
  static { this.NAME = `${common_1.HOUSE_PLUGIN_NAMESPACE}/const-class-values`; }
13
- static { this.DEFAULT_NAME_PATTERN = '(State|Status|Stage|Mode|Kind|Type)$'; }
14
54
  static { this.RULE = {
15
55
  meta: {
16
56
  type: 'suggestion',
@@ -22,30 +62,42 @@ class ConstClassValuesRule {
22
62
  create: (context) => {
23
63
  const options = context.options[0];
24
64
  const configured = (0, common_1.readField)({ node: options, key: 'namePattern' });
25
- const namePattern = new RegExp(typeof configured === 'string' ? configured : ConstClassValuesRule.DEFAULT_NAME_PATTERN);
26
- const isStringLiteral = (member) => (0, common_1.nodeType)({ node: member }) === 'TSLiteralType' &&
27
- typeof (0, common_1.readField)({ node: (0, common_1.readField)({ node: member, key: 'literal' }), key: 'value' }) ===
28
- 'string';
65
+ const namePattern = typeof configured === 'string' ? new RegExp(configured) : undefined;
66
+ const isNamed = (opts) => {
67
+ const { statement, node } = opts;
68
+ const declaration = (0, common_1.readField)({ node: statement, key: 'declaration' });
69
+ const name = (0, common_1.readField)({ node: (0, common_1.readField)({ node: declaration, key: 'id' }), key: 'name' });
70
+ return (namePattern === undefined ||
71
+ ((0, common_1.nodeType)({ node: declaration }) === 'TSTypeAliasDeclaration' &&
72
+ (0, common_1.readField)({ node: declaration, key: 'typeAnnotation' }) === node &&
73
+ typeof name === 'string' &&
74
+ namePattern.test(name)));
75
+ };
29
76
  return {
30
- [`${common_1.AstNodeTypes.EXPORT_NAMED_DECLARATION} > TSTypeAliasDeclaration`]: (node) => {
31
- const id = (0, common_1.readField)({ node, key: 'id' });
32
- const name = (0, common_1.readField)({ node: id, key: 'name' });
33
- const typeAnnotation = (0, common_1.readField)({ node, key: 'typeAnnotation' });
34
- const members = (0, common_1.readField)({ node: typeAnnotation, key: 'types' });
35
- if (typeof name === 'string' &&
36
- namePattern.test(name) &&
37
- (0, common_1.nodeType)({ node: typeAnnotation }) === 'TSUnionType' &&
38
- Array.isArray(members) &&
39
- members.every(isStringLiteral)) {
40
- context.report({ node, messageId: 'constClass' });
77
+ [common_1.AstNodeTypes.UNION_TYPE]: (node) => {
78
+ const members = (0, common_1.readField)({ node, key: 'types' });
79
+ if (!Array.isArray(members)) {
80
+ return;
81
+ }
82
+ const values = members.filter((member) => !isNullish({ member }));
83
+ if (values.length < 2 || !values.every((member) => isStringLiteral({ member }))) {
84
+ return;
85
+ }
86
+ const statement = topLevelStatement({ node });
87
+ const statementType = (0, common_1.nodeType)({ node: statement });
88
+ const isExported = statementType === common_1.AstNodeTypes.EXPORT_NAMED_DECLARATION ||
89
+ statementType === 'ExportDefaultDeclaration';
90
+ if (!isExported || isKeySet({ node }) || !isNamed({ statement, node })) {
91
+ return;
41
92
  }
93
+ context.report({ node, messageId: 'constClass' });
42
94
  },
43
95
  };
44
96
  },
45
97
  }; }
46
98
  static build(opts = {}) {
47
- const { severity = 'error', namePattern = ConstClassValuesRule.DEFAULT_NAME_PATTERN } = opts;
48
- return [severity, { namePattern }];
99
+ const { severity = 'error', namePattern } = opts;
100
+ return namePattern === undefined ? [severity] : [severity, { namePattern }];
49
101
  }
50
102
  }
51
103
  exports.ConstClassValuesRule = ConstClassValuesRule;
@@ -1 +1 @@
1
- {"version":3,"file":"const-class-values.rule.js","sourceRoot":"","sources":["../../../src/linters/house/const-class-values.rule.ts"],"names":[],"mappings":";;;AAEA,qCAAqF;AAErF;;;;;GAKG;AACH,MAAa,oBAAoB;aACf,SAAI,GAAG,GAAG,+BAAsB,qBAAqB,CAAC;aAEtD,yBAAoB,GAAG,sCAAsC,CAAC;aAE9D,SAAI,GAAoB;QACtC,IAAI,EAAE;YACJ,IAAI,EAAE,YAAY;YAClB,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,WAAW,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;YAC7E,QAAQ,EAAE;gBACR,UAAU,EACR,mGAAmG;aACtG;SACF;QACD,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE;YAClB,MAAM,OAAO,GAAY,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;YAC5C,MAAM,UAAU,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,aAAa,EAAE,CAAC,CAAC;YACpE,MAAM,WAAW,GAAG,IAAI,MAAM,CAC5B,OAAO,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,oBAAoB,CACxF,CAAC;YAEF,MAAM,eAAe,GAAG,CAAC,MAAe,EAAE,EAAE,CAC1C,IAAA,iBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,eAAe;gBAC9C,OAAO,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,SAAS,EAAE,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC;oBACnF,QAAQ,CAAC;YAEb,OAAO;gBACL,CAAC,GAAG,qBAAY,CAAC,wBAAwB,2BAA2B,CAAC,EAAE,CACrE,IAAe,EACf,EAAE;oBACF,MAAM,EAAE,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC;oBAC1C,MAAM,IAAI,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC;oBAClD,MAAM,cAAc,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,GAAG,EAAE,gBAAgB,EAAE,CAAC,CAAC;oBAClE,MAAM,OAAO,GAAG,IAAA,kBAAS,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,EAAE,CAAC,CAAC;oBAElE,IACE,OAAO,IAAI,KAAK,QAAQ;wBACxB,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC;wBACtB,IAAA,iBAAQ,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC,KAAK,aAAa;wBACpD,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC;wBACtB,OAAO,CAAC,KAAK,CAAC,eAAe,CAAC,EAC9B,CAAC;wBACD,OAAO,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;oBACpD,CAAC;gBACH,CAAC;aACF,CAAC;QACJ,CAAC;KACF,CAAC;IAEF,MAAM,CAAC,KAAK,CAAC,OAA2D,EAAE;QACxE,MAAM,EAAE,QAAQ,GAAG,OAAO,EAAE,WAAW,GAAG,oBAAoB,CAAC,oBAAoB,EAAE,GAAG,IAAI,CAAC;QAC7F,OAAO,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IACrC,CAAC;;AApDH,oDAqDC","sourcesContent":["import type { Linter, Rule } from 'eslint';\nimport type { TRuleSeverity } from '../rules/common';\nimport { AstNodeTypes, HOUSE_PLUGIN_NAMESPACE, nodeType, readField } from './common';\n\n/**\n * `venizia/const-class-values`. An enumerable string is a const class plus `TConstValue<typeof X>`,\n * never an exported union of string literals. Only a type whose name ends like a logic value is\n * checked (`State`, `Status`, `Stage`, `Mode`, `Kind`, `Type` by default): any other string union may\n * be a plain parameter type.\n */\nexport class ConstClassValuesRule {\n static readonly NAME = `${HOUSE_PLUGIN_NAMESPACE}/const-class-values`;\n\n static readonly DEFAULT_NAME_PATTERN = '(State|Status|Stage|Mode|Kind|Type)$';\n\n static readonly RULE: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n schema: [{ type: 'object', properties: { namePattern: { type: 'string' } } }],\n messages: {\n constClass:\n 'An enumerable string is a const class plus TConstValue<typeof X>, not a union of string literals.',\n },\n },\n create: (context) => {\n const options: unknown = context.options[0];\n const configured = readField({ node: options, key: 'namePattern' });\n const namePattern = new RegExp(\n typeof configured === 'string' ? configured : ConstClassValuesRule.DEFAULT_NAME_PATTERN,\n );\n\n const isStringLiteral = (member: unknown) =>\n nodeType({ node: member }) === 'TSLiteralType' &&\n typeof readField({ node: readField({ node: member, key: 'literal' }), key: 'value' }) ===\n 'string';\n\n return {\n [`${AstNodeTypes.EXPORT_NAMED_DECLARATION} > TSTypeAliasDeclaration`]: (\n node: Rule.Node,\n ) => {\n const id = readField({ node, key: 'id' });\n const name = readField({ node: id, key: 'name' });\n const typeAnnotation = readField({ node, key: 'typeAnnotation' });\n const members = readField({ node: typeAnnotation, key: 'types' });\n\n if (\n typeof name === 'string' &&\n namePattern.test(name) &&\n nodeType({ node: typeAnnotation }) === 'TSUnionType' &&\n Array.isArray(members) &&\n members.every(isStringLiteral)\n ) {\n context.report({ node, messageId: 'constClass' });\n }\n },\n };\n },\n };\n\n static build(opts: { severity?: TRuleSeverity; namePattern?: string } = {}): Linter.RuleEntry {\n const { severity = 'error', namePattern = ConstClassValuesRule.DEFAULT_NAME_PATTERN } = opts;\n return [severity, { namePattern }];\n }\n}\n"]}
1
+ {"version":3,"file":"const-class-values.rule.js","sourceRoot":"","sources":["../../../src/linters/house/const-class-values.rule.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Linter, Rule } from 'eslint';\nimport type { TRuleSeverity } from '../rules/common';\nimport { AstNodeTypes, HOUSE_PLUGIN_NAMESPACE, nodeType, readField } from './common';\n\n/** Utility types whose type argument is a set of keys, not an enumerable value: `Pick<T, 'a' | 'b'>`. */\nconst KEY_SET_TYPES = new Set(['Pick', 'Omit', 'Extract', 'Exclude', 'Record']);\n\n/** The union is a type argument of a key-set utility type, or the key range of a mapped type. */\nconst isKeySet = (opts: { node: unknown }): boolean => {\n const parent = readField({ node: opts.node, key: 'parent' });\n\n if (nodeType({ node: parent }) === 'TSMappedType') {\n return true;\n }\n\n if (nodeType({ node: parent }) !== 'TSTypeParameterInstantiation') {\n return false;\n }\n\n const reference = readField({ node: parent, key: 'parent' });\n const name = readField({ node: readField({ node: reference, key: 'typeName' }), key: 'name' });\n return nodeType({ node: reference }) === 'TSTypeReference' && KEY_SET_TYPES.has(String(name));\n};\n\n/** The statement of the module that holds the node: the node's last ancestor before `Program`. */\nconst topLevelStatement = (opts: { node: unknown }): unknown => {\n let current = opts.node;\n\n while (current) {\n const parent = readField({ node: current, key: 'parent' });\n if (nodeType({ node: parent }) === 'Program') {\n return current;\n }\n current = parent;\n }\n\n return undefined;\n};\n\nconst isStringLiteral = (opts: { member: unknown }): boolean => {\n const { member } = opts;\n return (\n nodeType({ node: member }) === 'TSLiteralType' &&\n typeof readField({ node: readField({ node: member, key: 'literal' }), key: 'value' }) ===\n 'string'\n );\n};\n\nconst isNullish = (opts: { member: unknown }): boolean => {\n const type = nodeType({ node: opts.member });\n return type === 'TSNullKeyword' || type === 'TSUndefinedKeyword';\n};\n\n/**\n * `venizia/const-class-values`. An enumerable string is a const class plus `TConstValue<typeof X>`,\n * never a union of string literals in an exported declaration: a type alias, an interface member, a\n * generic constraint, a parameter or a return type of an exported function or class.\n *\n * Not counted: a union that is not all string literals (a `null` or `undefined` member is ignored),\n * a key set (`Pick`, `Omit`, `Extract`, `Exclude`, `Record` arguments and mapped-type keys), and a\n * declaration that is not exported. `namePattern` narrows the rule to exported type aliases whose name\n * matches it (`(State|Status)$`), for a project that adopts the rule one name at a time.\n */\nexport class ConstClassValuesRule {\n static readonly NAME = `${HOUSE_PLUGIN_NAMESPACE}/const-class-values`;\n\n static readonly RULE: Rule.RuleModule = {\n meta: {\n type: 'suggestion',\n schema: [{ type: 'object', properties: { namePattern: { type: 'string' } } }],\n messages: {\n constClass:\n 'An enumerable string is a const class plus TConstValue<typeof X>, not a union of string literals.',\n },\n },\n create: (context) => {\n const options: unknown = context.options[0];\n const configured = readField({ node: options, key: 'namePattern' });\n const namePattern = typeof configured === 'string' ? new RegExp(configured) : undefined;\n\n const isNamed = (opts: { statement: unknown; node: unknown }) => {\n const { statement, node } = opts;\n const declaration = readField({ node: statement, key: 'declaration' });\n const name = readField({ node: readField({ node: declaration, key: 'id' }), key: 'name' });\n\n return (\n namePattern === undefined ||\n (nodeType({ node: declaration }) === 'TSTypeAliasDeclaration' &&\n readField({ node: declaration, key: 'typeAnnotation' }) === node &&\n typeof name === 'string' &&\n namePattern.test(name))\n );\n };\n\n return {\n [AstNodeTypes.UNION_TYPE]: (node: Rule.Node) => {\n const members = readField({ node, key: 'types' });\n if (!Array.isArray(members)) {\n return;\n }\n\n const values = members.filter((member) => !isNullish({ member }));\n if (values.length < 2 || !values.every((member) => isStringLiteral({ member }))) {\n return;\n }\n\n const statement = topLevelStatement({ node });\n const statementType = nodeType({ node: statement });\n const isExported =\n statementType === AstNodeTypes.EXPORT_NAMED_DECLARATION ||\n statementType === 'ExportDefaultDeclaration';\n\n if (!isExported || isKeySet({ node }) || !isNamed({ statement, node })) {\n return;\n }\n\n context.report({ node, messageId: 'constClass' });\n },\n };\n },\n };\n\n static build(opts: { severity?: TRuleSeverity; namePattern?: string } = {}): Linter.RuleEntry {\n const { severity = 'error', namePattern } = opts;\n return namePattern === undefined ? [severity] : [severity, { namePattern }];\n }\n}\n"]}
@@ -1,6 +1,53 @@
1
1
  import type { OxlintConfig } from 'oxlint';
2
+ /** The string values of a const class: its static members that are strings, as literal types. */
3
+ export type TConstValue<T> = Extract<T[keyof T], string> & {};
2
4
  /** A rule's severity, as both oxlint and ESLint accept it. */
3
- export type TRuleSeverity = 'off' | 'warn' | 'error';
5
+ export declare class RuleSeverities {
6
+ static readonly OFF = "off";
7
+ static readonly WARN = "warn";
8
+ static readonly ERROR = "error";
9
+ static readonly SCHEME_SET: Set<string>;
10
+ static isValid(value: string): value is TRuleSeverity;
11
+ }
12
+ /** Valid rule severity values. */
13
+ export type TRuleSeverity = TConstValue<typeof RuleSeverities>;
14
+ /** `eqeqeq` modes: ALWAYS wants `===` everywhere, SMART still allows `== null` and comparing two literals. */
15
+ export declare class EqeqeqModes {
16
+ static readonly ALWAYS = "always";
17
+ static readonly SMART = "smart";
18
+ static readonly SCHEME_SET: Set<string>;
19
+ static isValid(value: string): value is TEqeqeqMode;
20
+ }
21
+ /** Valid eqeqeq mode values. */
22
+ export type TEqeqeqMode = TConstValue<typeof EqeqeqModes>;
23
+ /** `no-unused-vars` `vars`: ALL checks globals too, LOCAL only the variables of the file. */
24
+ export declare class UnusedVarsScopes {
25
+ static readonly ALL = "all";
26
+ static readonly LOCAL = "local";
27
+ static readonly SCHEME_SET: Set<string>;
28
+ static isValid(value: string): value is TUnusedVarsScope;
29
+ }
30
+ /** Valid unused vars scope values. */
31
+ export type TUnusedVarsScope = TConstValue<typeof UnusedVarsScopes>;
32
+ /** `no-unused-vars` `args`: ALL checks every argument, AFTER_USED those after the last used one, NONE no argument. */
33
+ export declare class UnusedArgsModes {
34
+ static readonly ALL = "all";
35
+ static readonly AFTER_USED = "after-used";
36
+ static readonly NONE = "none";
37
+ static readonly SCHEME_SET: Set<string>;
38
+ static isValid(value: string): value is TUnusedArgsMode;
39
+ }
40
+ /** Valid unused args mode values. */
41
+ export type TUnusedArgsMode = TConstValue<typeof UnusedArgsModes>;
42
+ /** `switch-case-braces` modes: ALWAYS gives every case its own block, AVOID drops braces that hold nothing that needs a scope. */
43
+ export declare class SwitchCaseBracesModes {
44
+ static readonly ALWAYS = "always";
45
+ static readonly AVOID = "avoid";
46
+ static readonly SCHEME_SET: Set<string>;
47
+ static isValid(value: string): value is TSwitchCaseBracesMode;
48
+ }
49
+ /** Valid switch case braces mode values. */
50
+ export type TSwitchCaseBracesMode = TConstValue<typeof SwitchCaseBracesModes>;
4
51
  /** The entry oxlint's own types allow for rule `TName`, options included. */
5
52
  export type TOxlintRuleEntry<TName extends string> = NonNullable<NonNullable<OxlintConfig['rules']>[TName]>;
6
53
  //# sourceMappingURL=common.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE3C,8DAA8D;AAC9D,MAAM,MAAM,aAAa,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,MAAM,IAAI,WAAW,CAC9D,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAC1C,CAAC"}
1
+ {"version":3,"file":"common.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/common.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AAE3C,iGAAiG;AACjG,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,GAAG,EAAE,CAAC;AAE9D,8DAA8D;AAC9D,qBAAa,cAAc;IACzB,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAC5B,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU;IAC9B,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAAsD;IAEhF,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,aAAa;CAGtD;AAED,kCAAkC;AAClC,MAAM,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,cAAc,CAAC,CAAC;AAE/D,8GAA8G;AAC9G,qBAAa,WAAW;IACtB,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA8C;IAExE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,WAAW;CAGpD;AAED,gCAAgC;AAChC,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC,OAAO,WAAW,CAAC,CAAC;AAE1D,6FAA6F;AAC7F,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAC5B,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA2C;IAErE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,gBAAgB;CAGzD;AAED,sCAAsC;AACtC,MAAM,MAAM,gBAAgB,GAAG,WAAW,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAEpE,sHAAsH;AACtH,qBAAa,eAAe;IAC1B,MAAM,CAAC,QAAQ,CAAC,GAAG,SAAS;IAC5B,MAAM,CAAC,QAAQ,CAAC,UAAU,gBAAgB;IAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,UAAU;IAE9B,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA2D;IAErF,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,eAAe;CAGxD;AAED,qCAAqC;AACrC,MAAM,MAAM,eAAe,GAAG,WAAW,CAAC,OAAO,eAAe,CAAC,CAAC;AAElE,kIAAkI;AAClI,qBAAa,qBAAqB;IAChC,MAAM,CAAC,QAAQ,CAAC,MAAM,YAAY;IAClC,MAAM,CAAC,QAAQ,CAAC,KAAK,WAAW;IAEhC,MAAM,CAAC,QAAQ,CAAC,UAAU,cAA8C;IAExE,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,IAAI,qBAAqB;CAG9D;AAED,4CAA4C;AAC5C,MAAM,MAAM,qBAAqB,GAAG,WAAW,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAE9E,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,CAAC,KAAK,SAAS,MAAM,IAAI,WAAW,CAC9D,WAAW,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAC1C,CAAC"}
@@ -1,3 +1,56 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SwitchCaseBracesModes = exports.UnusedArgsModes = exports.UnusedVarsScopes = exports.EqeqeqModes = exports.RuleSeverities = void 0;
4
+ /** A rule's severity, as both oxlint and ESLint accept it. */
5
+ class RuleSeverities {
6
+ static { this.OFF = 'off'; }
7
+ static { this.WARN = 'warn'; }
8
+ static { this.ERROR = 'error'; }
9
+ static { this.SCHEME_SET = new Set([this.OFF, this.WARN, this.ERROR]); }
10
+ static isValid(value) {
11
+ return this.SCHEME_SET.has(value);
12
+ }
13
+ }
14
+ exports.RuleSeverities = RuleSeverities;
15
+ /** `eqeqeq` modes: ALWAYS wants `===` everywhere, SMART still allows `== null` and comparing two literals. */
16
+ class EqeqeqModes {
17
+ static { this.ALWAYS = 'always'; }
18
+ static { this.SMART = 'smart'; }
19
+ static { this.SCHEME_SET = new Set([this.ALWAYS, this.SMART]); }
20
+ static isValid(value) {
21
+ return this.SCHEME_SET.has(value);
22
+ }
23
+ }
24
+ exports.EqeqeqModes = EqeqeqModes;
25
+ /** `no-unused-vars` `vars`: ALL checks globals too, LOCAL only the variables of the file. */
26
+ class UnusedVarsScopes {
27
+ static { this.ALL = 'all'; }
28
+ static { this.LOCAL = 'local'; }
29
+ static { this.SCHEME_SET = new Set([this.ALL, this.LOCAL]); }
30
+ static isValid(value) {
31
+ return this.SCHEME_SET.has(value);
32
+ }
33
+ }
34
+ exports.UnusedVarsScopes = UnusedVarsScopes;
35
+ /** `no-unused-vars` `args`: ALL checks every argument, AFTER_USED those after the last used one, NONE no argument. */
36
+ class UnusedArgsModes {
37
+ static { this.ALL = 'all'; }
38
+ static { this.AFTER_USED = 'after-used'; }
39
+ static { this.NONE = 'none'; }
40
+ static { this.SCHEME_SET = new Set([this.ALL, this.AFTER_USED, this.NONE]); }
41
+ static isValid(value) {
42
+ return this.SCHEME_SET.has(value);
43
+ }
44
+ }
45
+ exports.UnusedArgsModes = UnusedArgsModes;
46
+ /** `switch-case-braces` modes: ALWAYS gives every case its own block, AVOID drops braces that hold nothing that needs a scope. */
47
+ class SwitchCaseBracesModes {
48
+ static { this.ALWAYS = 'always'; }
49
+ static { this.AVOID = 'avoid'; }
50
+ static { this.SCHEME_SET = new Set([this.ALWAYS, this.AVOID]); }
51
+ static isValid(value) {
52
+ return this.SCHEME_SET.has(value);
53
+ }
54
+ }
55
+ exports.SwitchCaseBracesModes = SwitchCaseBracesModes;
3
56
  //# sourceMappingURL=common.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/linters/rules/common.ts"],"names":[],"mappings":"","sourcesContent":["import type { OxlintConfig } from 'oxlint';\n\n/** A rule's severity, as both oxlint and ESLint accept it. */\nexport type TRuleSeverity = 'off' | 'warn' | 'error';\n\n/** The entry oxlint's own types allow for rule `TName`, options included. */\nexport type TOxlintRuleEntry<TName extends string> = NonNullable<\n NonNullable<OxlintConfig['rules']>[TName]\n>;\n"]}
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/linters/rules/common.ts"],"names":[],"mappings":";;;AAKA,8DAA8D;AAC9D,MAAa,cAAc;aACT,QAAG,GAAG,KAAK,CAAC;aACZ,SAAI,GAAG,MAAM,CAAC;aACd,UAAK,GAAG,OAAO,CAAC;aAEhB,eAAU,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAEhF,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;;AATH,wCAUC;AAKD,8GAA8G;AAC9G,MAAa,WAAW;aACN,WAAM,GAAG,QAAQ,CAAC;aAClB,UAAK,GAAG,OAAO,CAAC;aAEhB,eAAU,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAExE,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;;AARH,kCASC;AAKD,6FAA6F;AAC7F,MAAa,gBAAgB;aACX,QAAG,GAAG,KAAK,CAAC;aACZ,UAAK,GAAG,OAAO,CAAC;aAEhB,eAAU,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAErE,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;;AARH,4CASC;AAKD,sHAAsH;AACtH,MAAa,eAAe;aACV,QAAG,GAAG,KAAK,CAAC;aACZ,eAAU,GAAG,YAAY,CAAC;aAC1B,SAAI,GAAG,MAAM,CAAC;aAEd,eAAU,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAErF,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;;AATH,0CAUC;AAKD,kIAAkI;AAClI,MAAa,qBAAqB;aAChB,WAAM,GAAG,QAAQ,CAAC;aAClB,UAAK,GAAG,OAAO,CAAC;aAEhB,eAAU,GAAG,IAAI,GAAG,CAAS,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAExE,MAAM,CAAC,OAAO,CAAC,KAAa;QAC1B,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;;AARH,sDASC","sourcesContent":["import type { OxlintConfig } from 'oxlint';\n\n/** The string values of a const class: its static members that are strings, as literal types. */\nexport type TConstValue<T> = Extract<T[keyof T], string> & {};\n\n/** A rule's severity, as both oxlint and ESLint accept it. */\nexport class RuleSeverities {\n static readonly OFF = 'off';\n static readonly WARN = 'warn';\n static readonly ERROR = 'error';\n\n static readonly SCHEME_SET = new Set<string>([this.OFF, this.WARN, this.ERROR]);\n\n static isValid(value: string): value is TRuleSeverity {\n return this.SCHEME_SET.has(value);\n }\n}\n\n/** Valid rule severity values. */\nexport type TRuleSeverity = TConstValue<typeof RuleSeverities>;\n\n/** `eqeqeq` modes: ALWAYS wants `===` everywhere, SMART still allows `== null` and comparing two literals. */\nexport class EqeqeqModes {\n static readonly ALWAYS = 'always';\n static readonly SMART = 'smart';\n\n static readonly SCHEME_SET = new Set<string>([this.ALWAYS, this.SMART]);\n\n static isValid(value: string): value is TEqeqeqMode {\n return this.SCHEME_SET.has(value);\n }\n}\n\n/** Valid eqeqeq mode values. */\nexport type TEqeqeqMode = TConstValue<typeof EqeqeqModes>;\n\n/** `no-unused-vars` `vars`: ALL checks globals too, LOCAL only the variables of the file. */\nexport class UnusedVarsScopes {\n static readonly ALL = 'all';\n static readonly LOCAL = 'local';\n\n static readonly SCHEME_SET = new Set<string>([this.ALL, this.LOCAL]);\n\n static isValid(value: string): value is TUnusedVarsScope {\n return this.SCHEME_SET.has(value);\n }\n}\n\n/** Valid unused vars scope values. */\nexport type TUnusedVarsScope = TConstValue<typeof UnusedVarsScopes>;\n\n/** `no-unused-vars` `args`: ALL checks every argument, AFTER_USED those after the last used one, NONE no argument. */\nexport class UnusedArgsModes {\n static readonly ALL = 'all';\n static readonly AFTER_USED = 'after-used';\n static readonly NONE = 'none';\n\n static readonly SCHEME_SET = new Set<string>([this.ALL, this.AFTER_USED, this.NONE]);\n\n static isValid(value: string): value is TUnusedArgsMode {\n return this.SCHEME_SET.has(value);\n }\n}\n\n/** Valid unused args mode values. */\nexport type TUnusedArgsMode = TConstValue<typeof UnusedArgsModes>;\n\n/** `switch-case-braces` modes: ALWAYS gives every case its own block, AVOID drops braces that hold nothing that needs a scope. */\nexport class SwitchCaseBracesModes {\n static readonly ALWAYS = 'always';\n static readonly AVOID = 'avoid';\n\n static readonly SCHEME_SET = new Set<string>([this.ALWAYS, this.AVOID]);\n\n static isValid(value: string): value is TSwitchCaseBracesMode {\n return this.SCHEME_SET.has(value);\n }\n}\n\n/** Valid switch case braces mode values. */\nexport type TSwitchCaseBracesMode = TConstValue<typeof SwitchCaseBracesModes>;\n\n/** The entry oxlint's own types allow for rule `TName`, options included. */\nexport type TOxlintRuleEntry<TName extends string> = NonNullable<\n NonNullable<OxlintConfig['rules']>[TName]\n>;\n"]}
@@ -1,10 +1,10 @@
1
- import type { TOxlintRuleEntry, TRuleSeverity } from './common';
1
+ import { type TEqeqeqMode, type TOxlintRuleEntry, type TRuleSeverity } from './common';
2
2
  /** `eqeqeq`. `smart` still allows `== null` and comparing two literals. */
3
3
  export declare class EqeqeqRule {
4
4
  static readonly NAME = "eqeqeq";
5
5
  static build(opts?: {
6
6
  severity?: TRuleSeverity;
7
- mode?: 'always' | 'smart';
7
+ mode?: TEqeqeqMode;
8
8
  }): TOxlintRuleEntry<'eqeqeq'>;
9
9
  }
10
10
  //# sourceMappingURL=eqeqeq.rule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"eqeqeq.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/eqeqeq.rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhE,2EAA2E;AAC3E,qBAAa,UAAU;IACrB,MAAM,CAAC,QAAQ,CAAC,IAAI,YAAY;IAEhC,MAAM,CAAC,KAAK,CACV,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;KAAO,GACjE,gBAAgB,CAAC,QAAQ,CAAC;CAI9B"}
1
+ {"version":3,"file":"eqeqeq.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/eqeqeq.rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,WAAW,EAAE,KAAK,gBAAgB,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AAEpG,2EAA2E;AAC3E,qBAAa,UAAU;IACrB,MAAM,CAAC,QAAQ,CAAC,IAAI,YAAY;IAEhC,MAAM,CAAC,KAAK,CACV,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,WAAW,CAAA;KAAO,GAC1D,gBAAgB,CAAC,QAAQ,CAAC;CAI9B"}
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EqeqeqRule = void 0;
4
+ const common_1 = require("./common");
4
5
  /** `eqeqeq`. `smart` still allows `== null` and comparing two literals. */
5
6
  class EqeqeqRule {
6
7
  static { this.NAME = 'eqeqeq'; }
7
8
  static build(opts = {}) {
8
- const { severity = 'error', mode = 'smart' } = opts;
9
+ const { severity = 'error', mode = common_1.EqeqeqModes.SMART } = opts;
9
10
  return [severity, mode];
10
11
  }
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"eqeqeq.rule.js","sourceRoot":"","sources":["../../../src/linters/rules/eqeqeq.rule.ts"],"names":[],"mappings":";;;AAEA,2EAA2E;AAC3E,MAAa,UAAU;aACL,SAAI,GAAG,QAAQ,CAAC;IAEhC,MAAM,CAAC,KAAK,CACV,OAAgE,EAAE;QAElE,MAAM,EAAE,QAAQ,GAAG,OAAO,EAAE,IAAI,GAAG,OAAO,EAAE,GAAG,IAAI,CAAC;QACpD,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;;AARH,gCASC","sourcesContent":["import type { TOxlintRuleEntry, TRuleSeverity } from './common';\n\n/** `eqeqeq`. `smart` still allows `== null` and comparing two literals. */\nexport class EqeqeqRule {\n static readonly NAME = 'eqeqeq';\n\n static build(\n opts: { severity?: TRuleSeverity; mode?: 'always' | 'smart' } = {},\n ): TOxlintRuleEntry<'eqeqeq'> {\n const { severity = 'error', mode = 'smart' } = opts;\n return [severity, mode];\n }\n}\n"]}
1
+ {"version":3,"file":"eqeqeq.rule.js","sourceRoot":"","sources":["../../../src/linters/rules/eqeqeq.rule.ts"],"names":[],"mappings":";;;AAAA,qCAAoG;AAEpG,2EAA2E;AAC3E,MAAa,UAAU;aACL,SAAI,GAAG,QAAQ,CAAC;IAEhC,MAAM,CAAC,KAAK,CACV,OAAyD,EAAE;QAE3D,MAAM,EAAE,QAAQ,GAAG,OAAO,EAAE,IAAI,GAAG,oBAAW,CAAC,KAAK,EAAE,GAAG,IAAI,CAAC;QAC9D,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;;AARH,gCASC","sourcesContent":["import { EqeqeqModes, type TEqeqeqMode, type TOxlintRuleEntry, type TRuleSeverity } from './common';\n\n/** `eqeqeq`. `smart` still allows `== null` and comparing two literals. */\nexport class EqeqeqRule {\n static readonly NAME = 'eqeqeq';\n\n static build(\n opts: { severity?: TRuleSeverity; mode?: TEqeqeqMode } = {},\n ): TOxlintRuleEntry<'eqeqeq'> {\n const { severity = 'error', mode = EqeqeqModes.SMART } = opts;\n return [severity, mode];\n }\n}\n"]}
@@ -1,11 +1,11 @@
1
- import type { TOxlintRuleEntry, TRuleSeverity } from './common';
1
+ import { type TOxlintRuleEntry, type TRuleSeverity, type TUnusedArgsMode, type TUnusedVarsScope } from './common';
2
2
  /** `no-unused-vars`. Unused arguments pass by default: an override keeps its signature. A `_name` variable is an omitted value (`{ page: _page, ...rest }`) and passes too. */
3
3
  export declare class NoUnusedVarsRule {
4
4
  static readonly NAME = "no-unused-vars";
5
5
  static build(opts?: {
6
6
  severity?: TRuleSeverity;
7
- vars?: 'all' | 'local';
8
- args?: 'all' | 'after-used' | 'none';
7
+ vars?: TUnusedVarsScope;
8
+ args?: TUnusedArgsMode;
9
9
  ignoreRestSiblings?: boolean;
10
10
  /** Names that may stay unused, e.g. `^_` - a placeholder a signature needs. */
11
11
  argsIgnorePattern?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"no-unused-vars.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/no-unused-vars.rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhE,+KAA+K;AAC/K,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,IAAI,oBAAoB;IAExC,MAAM,CAAC,KAAK,CACV,IAAI,GAAE;QACJ,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB,IAAI,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,EAAE,KAAK,GAAG,YAAY,GAAG,MAAM,CAAC;QACrC,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,+EAA+E;QAC/E,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,8BAA8B,CAAC,EAAE,MAAM,CAAC;KACpC,GACL,gBAAgB,CAAC,gBAAgB,CAAC;CAWtC"}
1
+ {"version":3,"file":"no-unused-vars.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/no-unused-vars.rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,UAAU,CAAC;AAElB,+KAA+K;AAC/K,qBAAa,gBAAgB;IAC3B,MAAM,CAAC,QAAQ,CAAC,IAAI,oBAAoB;IAExC,MAAM,CAAC,KAAK,CACV,IAAI,GAAE;QACJ,QAAQ,CAAC,EAAE,aAAa,CAAC;QACzB,IAAI,CAAC,EAAE,gBAAgB,CAAC;QACxB,IAAI,CAAC,EAAE,eAAe,CAAC;QACvB,kBAAkB,CAAC,EAAE,OAAO,CAAC;QAC7B,+EAA+E;QAC/E,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,yBAAyB,CAAC,EAAE,MAAM,CAAC;QACnC,8BAA8B,CAAC,EAAE,MAAM,CAAC;KACpC,GACL,gBAAgB,CAAC,gBAAgB,CAAC;CAWtC"}
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.NoUnusedVarsRule = void 0;
4
+ const common_1 = require("./common");
4
5
  /** `no-unused-vars`. Unused arguments pass by default: an override keeps its signature. A `_name` variable is an omitted value (`{ page: _page, ...rest }`) and passes too. */
5
6
  class NoUnusedVarsRule {
6
7
  static { this.NAME = 'no-unused-vars'; }
7
8
  static build(opts = {}) {
8
- const { severity = 'error', vars = 'all', args = 'none', ignoreRestSiblings = false, varsIgnorePattern = '^_', ...patterns } = opts;
9
+ const { severity = 'error', vars = common_1.UnusedVarsScopes.ALL, args = common_1.UnusedArgsModes.NONE, ignoreRestSiblings = false, varsIgnorePattern = '^_', ...patterns } = opts;
9
10
  return [severity, { vars, args, ignoreRestSiblings, varsIgnorePattern, ...patterns }];
10
11
  }
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"no-unused-vars.rule.js","sourceRoot":"","sources":["../../../src/linters/rules/no-unused-vars.rule.ts"],"names":[],"mappings":";;;AAEA,+KAA+K;AAC/K,MAAa,gBAAgB;aACX,SAAI,GAAG,gBAAgB,CAAC;IAExC,MAAM,CAAC,KAAK,CACV,OAUI,EAAE;QAEN,MAAM,EACJ,QAAQ,GAAG,OAAO,EAClB,IAAI,GAAG,KAAK,EACZ,IAAI,GAAG,MAAM,EACb,kBAAkB,GAAG,KAAK,EAC1B,iBAAiB,GAAG,IAAI,EACxB,GAAG,QAAQ,EACZ,GAAG,IAAI,CAAC;QACT,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;IACxF,CAAC;;AAzBH,4CA0BC","sourcesContent":["import type { TOxlintRuleEntry, TRuleSeverity } from './common';\n\n/** `no-unused-vars`. Unused arguments pass by default: an override keeps its signature. A `_name` variable is an omitted value (`{ page: _page, ...rest }`) and passes too. */\nexport class NoUnusedVarsRule {\n static readonly NAME = 'no-unused-vars';\n\n static build(\n opts: {\n severity?: TRuleSeverity;\n vars?: 'all' | 'local';\n args?: 'all' | 'after-used' | 'none';\n ignoreRestSiblings?: boolean;\n /** Names that may stay unused, e.g. `^_` - a placeholder a signature needs. */\n argsIgnorePattern?: string;\n varsIgnorePattern?: string;\n caughtErrorsIgnorePattern?: string;\n destructuredArrayIgnorePattern?: string;\n } = {},\n ): TOxlintRuleEntry<'no-unused-vars'> {\n const {\n severity = 'error',\n vars = 'all',\n args = 'none',\n ignoreRestSiblings = false,\n varsIgnorePattern = '^_',\n ...patterns\n } = opts;\n return [severity, { vars, args, ignoreRestSiblings, varsIgnorePattern, ...patterns }];\n }\n}\n"]}
1
+ {"version":3,"file":"no-unused-vars.rule.js","sourceRoot":"","sources":["../../../src/linters/rules/no-unused-vars.rule.ts"],"names":[],"mappings":";;;AAAA,qCAOkB;AAElB,+KAA+K;AAC/K,MAAa,gBAAgB;aACX,SAAI,GAAG,gBAAgB,CAAC;IAExC,MAAM,CAAC,KAAK,CACV,OAUI,EAAE;QAEN,MAAM,EACJ,QAAQ,GAAG,OAAO,EAClB,IAAI,GAAG,yBAAgB,CAAC,GAAG,EAC3B,IAAI,GAAG,wBAAe,CAAC,IAAI,EAC3B,kBAAkB,GAAG,KAAK,EAC1B,iBAAiB,GAAG,IAAI,EACxB,GAAG,QAAQ,EACZ,GAAG,IAAI,CAAC;QACT,OAAO,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,GAAG,QAAQ,EAAE,CAAC,CAAC;IACxF,CAAC;;AAzBH,4CA0BC","sourcesContent":["import {\n UnusedArgsModes,\n UnusedVarsScopes,\n type TOxlintRuleEntry,\n type TRuleSeverity,\n type TUnusedArgsMode,\n type TUnusedVarsScope,\n} from './common';\n\n/** `no-unused-vars`. Unused arguments pass by default: an override keeps its signature. A `_name` variable is an omitted value (`{ page: _page, ...rest }`) and passes too. */\nexport class NoUnusedVarsRule {\n static readonly NAME = 'no-unused-vars';\n\n static build(\n opts: {\n severity?: TRuleSeverity;\n vars?: TUnusedVarsScope;\n args?: TUnusedArgsMode;\n ignoreRestSiblings?: boolean;\n /** Names that may stay unused, e.g. `^_` - a placeholder a signature needs. */\n argsIgnorePattern?: string;\n varsIgnorePattern?: string;\n caughtErrorsIgnorePattern?: string;\n destructuredArrayIgnorePattern?: string;\n } = {},\n ): TOxlintRuleEntry<'no-unused-vars'> {\n const {\n severity = 'error',\n vars = UnusedVarsScopes.ALL,\n args = UnusedArgsModes.NONE,\n ignoreRestSiblings = false,\n varsIgnorePattern = '^_',\n ...patterns\n } = opts;\n return [severity, { vars, args, ignoreRestSiblings, varsIgnorePattern, ...patterns }];\n }\n}\n"]}
@@ -1,10 +1,10 @@
1
- import type { TOxlintRuleEntry, TRuleSeverity } from './common';
1
+ import { type TOxlintRuleEntry, type TRuleSeverity, type TSwitchCaseBracesMode } from './common';
2
2
  /** `unicorn/switch-case-braces`. `always` gives every case its own block scope. */
3
3
  export declare class SwitchCaseBracesRule {
4
4
  static readonly NAME = "unicorn/switch-case-braces";
5
5
  static build(opts?: {
6
6
  severity?: TRuleSeverity;
7
- mode?: 'always' | 'avoid';
7
+ mode?: TSwitchCaseBracesMode;
8
8
  }): TOxlintRuleEntry<'unicorn/switch-case-braces'>;
9
9
  }
10
10
  //# sourceMappingURL=switch-case-braces.rule.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"switch-case-braces.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/switch-case-braces.rule.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEhE,mFAAmF;AACnF,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,gCAAgC;IAEpD,MAAM,CAAC,KAAK,CACV,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAA;KAAO,GACjE,gBAAgB,CAAC,4BAA4B,CAAC;CAIlD"}
1
+ {"version":3,"file":"switch-case-braces.rule.d.ts","sourceRoot":"","sources":["../../../src/linters/rules/switch-case-braces.rule.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,aAAa,EAClB,KAAK,qBAAqB,EAC3B,MAAM,UAAU,CAAC;AAElB,mFAAmF;AACnF,qBAAa,oBAAoB;IAC/B,MAAM,CAAC,QAAQ,CAAC,IAAI,gCAAgC;IAEpD,MAAM,CAAC,KAAK,CACV,IAAI,GAAE;QAAE,QAAQ,CAAC,EAAE,aAAa,CAAC;QAAC,IAAI,CAAC,EAAE,qBAAqB,CAAA;KAAO,GACpE,gBAAgB,CAAC,4BAA4B,CAAC;CAIlD"}
@@ -1,11 +1,12 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SwitchCaseBracesRule = void 0;
4
+ const common_1 = require("./common");
4
5
  /** `unicorn/switch-case-braces`. `always` gives every case its own block scope. */
5
6
  class SwitchCaseBracesRule {
6
7
  static { this.NAME = 'unicorn/switch-case-braces'; }
7
8
  static build(opts = {}) {
8
- const { severity = 'error', mode = 'always' } = opts;
9
+ const { severity = 'error', mode = common_1.SwitchCaseBracesModes.ALWAYS } = opts;
9
10
  return [severity, mode];
10
11
  }
11
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"switch-case-braces.rule.js","sourceRoot":"","sources":["../../../src/linters/rules/switch-case-braces.rule.ts"],"names":[],"mappings":";;;AAEA,mFAAmF;AACnF,MAAa,oBAAoB;aACf,SAAI,GAAG,4BAA4B,CAAC;IAEpD,MAAM,CAAC,KAAK,CACV,OAAgE,EAAE;QAElE,MAAM,EAAE,QAAQ,GAAG,OAAO,EAAE,IAAI,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC;QACrD,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;;AARH,oDASC","sourcesContent":["import type { TOxlintRuleEntry, TRuleSeverity } from './common';\n\n/** `unicorn/switch-case-braces`. `always` gives every case its own block scope. */\nexport class SwitchCaseBracesRule {\n static readonly NAME = 'unicorn/switch-case-braces';\n\n static build(\n opts: { severity?: TRuleSeverity; mode?: 'always' | 'avoid' } = {},\n ): TOxlintRuleEntry<'unicorn/switch-case-braces'> {\n const { severity = 'error', mode = 'always' } = opts;\n return [severity, mode];\n }\n}\n"]}
1
+ {"version":3,"file":"switch-case-braces.rule.js","sourceRoot":"","sources":["../../../src/linters/rules/switch-case-braces.rule.ts"],"names":[],"mappings":";;;AAAA,qCAKkB;AAElB,mFAAmF;AACnF,MAAa,oBAAoB;aACf,SAAI,GAAG,4BAA4B,CAAC;IAEpD,MAAM,CAAC,KAAK,CACV,OAAmE,EAAE;QAErE,MAAM,EAAE,QAAQ,GAAG,OAAO,EAAE,IAAI,GAAG,8BAAqB,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC;QACzE,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IAC1B,CAAC;;AARH,oDASC","sourcesContent":["import {\n SwitchCaseBracesModes,\n type TOxlintRuleEntry,\n type TRuleSeverity,\n type TSwitchCaseBracesMode,\n} from './common';\n\n/** `unicorn/switch-case-braces`. `always` gives every case its own block scope. */\nexport class SwitchCaseBracesRule {\n static readonly NAME = 'unicorn/switch-case-braces';\n\n static build(\n opts: { severity?: TRuleSeverity; mode?: TSwitchCaseBracesMode } = {},\n ): TOxlintRuleEntry<'unicorn/switch-case-braces'> {\n const { severity = 'error', mode = SwitchCaseBracesModes.ALWAYS } = opts;\n return [severity, mode];\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@venizia/dev-configs",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "Shareable development configurations for TypeScript projects: oxlint presets with per-rule builders, the ESLint naming-convention rule, the legacy ESLint flat config, and TypeScript compiler options with critical decorator support (experimentalDecorators, emitDecoratorMetadata, useDefineForClassFields). Single source of truth for consistent code style, type checking, and build settings across monorepo packages.",
5
5
  "keywords": [
6
6
  "build-tools",