eslint-plugin-ts-type-forge 0.3.2 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,41 @@ configured TypeScript project is not required.
16
16
 
17
17
  ## Usage (flat config)
18
18
 
19
+ The plugin ships a `recommended` config preset that registers the plugin and
20
+ turns on **every** rule at `error`:
21
+
22
+ ```ts
23
+ // eslint.config.mts
24
+ import { eslintPluginTsTypeForge } from 'eslint-plugin-ts-type-forge';
25
+
26
+ export default [eslintPluginTsTypeForge.configs.recommended];
27
+ ```
28
+
29
+ Since the preset is a plain flat-config object, individual rules can be
30
+ adjusted by a later config entry — for instance to pass [options](#options):
31
+
32
+ ```ts
33
+ // eslint.config.mts
34
+ import {
35
+ eslintPluginTsTypeForge,
36
+ type EslintTsTypeForgeRules,
37
+ } from 'eslint-plugin-ts-type-forge';
38
+
39
+ export default [
40
+ eslintPluginTsTypeForge.configs.recommended,
41
+ {
42
+ rules: {
43
+ 'ts-type-forge/prefer-canonical-length-constrained-tuple': [
44
+ 'error',
45
+ { importStyle: 'named' },
46
+ ],
47
+ } satisfies Partial<EslintTsTypeForgeRules>,
48
+ },
49
+ ];
50
+ ```
51
+
52
+ Or register the plugin yourself and pick the rules one by one:
53
+
19
54
  ```ts
20
55
  // eslint.config.mts
21
56
  import {
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
1
1
  export { eslintPluginTsTypeForge } from './plugin.mjs';
2
2
  export type { EslintTsTypeForgeRules, EslintTsTypeForgeRulesOption, } from './rule-types.mjs';
3
3
  export { tsTypeForgeRules } from './rules/index.mjs';
4
- export { type ESLintPlugin } from './types.mjs';
4
+ export { type ESLintFlatConfig, type ESLintPlugin } from './types.mjs';
5
5
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EACV,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,YAAY,EACV,sBAAsB,EACtB,4BAA4B,GAC7B,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC"}
package/dist/plugin.d.mts CHANGED
@@ -1,3 +1,25 @@
1
1
  import { type ESLintPlugin } from './types.mjs';
2
- export declare const eslintPluginTsTypeForge: ESLintPlugin;
2
+ export declare const eslintPluginTsTypeForge: {
3
+ readonly meta: {
4
+ readonly name: 'eslint-plugin-ts-type-forge';
5
+ };
6
+ readonly rules: {
7
+ readonly 'prefer-canonical-length-constrained-tuple': import("@typescript-eslint/utils/ts-eslint").RuleModule<"useCanonicalTuple", readonly [(Readonly<{
8
+ importStyle?: 'global' | 'named';
9
+ maxLength?: number;
10
+ }> | undefined)?], unknown, import("@typescript-eslint/utils/ts-eslint").RuleListener>;
11
+ };
12
+ readonly configs: {
13
+ /** Enables every rule of this plugin at `error`. */
14
+ readonly recommended: {
15
+ readonly name: 'ts-type-forge/recommended';
16
+ readonly plugins: {
17
+ readonly 'ts-type-forge': ESLintPlugin;
18
+ };
19
+ readonly rules: {
20
+ readonly 'ts-type-forge/prefer-canonical-length-constrained-tuple': 'error';
21
+ };
22
+ };
23
+ };
24
+ };
3
25
  //# sourceMappingURL=plugin.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.mts","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AACA,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,eAAO,MAAM,uBAAuB,EAAE,YAK5B,CAAC"}
1
+ {"version":3,"file":"plugin.d.mts","sourceRoot":"","sources":["../src/plugin.mts"],"names":[],"mappings":"AACA,OAAO,EAAyB,KAAK,YAAY,EAAE,MAAM,aAAa,CAAC;AA8BvE,eAAO,MAAM,uBAAuB;;iBAEhC,IAAI,EAAE,6BAA6B;;;;;;;;;QAInC,oDAAoD;iBACpD,WAAW;2BAtBP,2BAA2B;;yBAQ3B,eAAe,EAAI,YAAY;;;oFAdsB,OAAO;;;;CA8BnC,CAAC"}
package/dist/plugin.mjs CHANGED
@@ -1,10 +1,32 @@
1
1
  import { tsTypeForgeRules } from './rules/rules.mjs';
2
2
 
3
+ const recommendedRules = {
4
+ "ts-type-forge/prefer-canonical-length-constrained-tuple": "error"
5
+ };
6
+ const recommendedConfig = {
7
+ name: "ts-type-forge/recommended",
8
+ plugins: {
9
+ // Resolved lazily so that this config registers the *same* object that
10
+ // `eslintPluginTsTypeForge` refers to. ESLint rejects a plugin name that
11
+ // maps to two different objects with `Cannot redefine plugin`, which is
12
+ // what a user combining this preset with their own
13
+ // `plugins: { 'ts-type-forge': eslintPluginTsTypeForge }` entry would hit
14
+ // if the preset embedded a separate copy of the plugin.
15
+ get "ts-type-forge"() {
16
+ return eslintPluginTsTypeForge;
17
+ }
18
+ },
19
+ rules: recommendedRules
20
+ };
3
21
  const eslintPluginTsTypeForge = {
4
22
  meta: {
5
23
  name: "eslint-plugin-ts-type-forge"
6
24
  },
7
- rules: tsTypeForgeRules
25
+ rules: tsTypeForgeRules,
26
+ configs: {
27
+ /** Enables every rule of this plugin at `error`. */
28
+ recommended: recommendedConfig
29
+ }
8
30
  };
9
31
 
10
32
  export { eslintPluginTsTypeForge };
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.mjs","sources":["../src/plugin.mts"],"sourcesContent":["import { tsTypeForgeRules } from './rules/index.mjs';\nimport { type ESLintPlugin } from './types.mjs';\n\nexport const eslintPluginTsTypeForge: ESLintPlugin = {\n meta: {\n name: 'eslint-plugin-ts-type-forge',\n },\n rules: tsTypeForgeRules,\n} as const;\n"],"names":[],"mappings":";;AAGO,MAAM,uBAAA,GAAwC;AAAA,EACnD,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM;AAAA,GACR;AAAA,EACA,KAAA,EAAO;AACT;;;;"}
1
+ {"version":3,"file":"plugin.mjs","sources":["../src/plugin.mts"],"sourcesContent":["import { tsTypeForgeRules } from './rules/index.mjs';\nimport { type ESLintFlatConfig, type ESLintPlugin } from './types.mjs';\n\n/**\n * Every rule this plugin ships, at `error`.\n *\n * The `satisfies` clause below is keyed off {@link tsTypeForgeRules}, so adding\n * a rule without listing it here fails to type-check.\n */\nconst recommendedRules = {\n 'ts-type-forge/prefer-canonical-length-constrained-tuple': 'error',\n} as const satisfies Readonly<\n Record<`ts-type-forge/${keyof typeof tsTypeForgeRules}`, 'error'>\n>;\n\nconst recommendedConfig = {\n name: 'ts-type-forge/recommended',\n plugins: {\n // Resolved lazily so that this config registers the *same* object that\n // `eslintPluginTsTypeForge` refers to. ESLint rejects a plugin name that\n // maps to two different objects with `Cannot redefine plugin`, which is\n // what a user combining this preset with their own\n // `plugins: { 'ts-type-forge': eslintPluginTsTypeForge }` entry would hit\n // if the preset embedded a separate copy of the plugin.\n get 'ts-type-forge'(): ESLintPlugin {\n return eslintPluginTsTypeForge;\n },\n },\n rules: recommendedRules,\n} as const satisfies ESLintFlatConfig;\n\nexport const eslintPluginTsTypeForge = {\n meta: {\n name: 'eslint-plugin-ts-type-forge',\n },\n rules: tsTypeForgeRules,\n configs: {\n /** Enables every rule of this plugin at `error`. */\n recommended: recommendedConfig,\n },\n} as const satisfies ESLintPlugin;\n"],"names":[],"mappings":";;AASA,MAAM,gBAAA,GAAmB;AAAA,EACvB,yDAAA,EAA2D;AAC7D,CAAA;AAIA,MAAM,iBAAA,GAAoB;AAAA,EACxB,IAAA,EAAM,2BAAA;AAAA,EACN,OAAA,EAAS;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOP,IAAI,eAAA,GAAgC;AAClC,MAAA,OAAO,uBAAA;AAAA,IACT;AAAA,GACF;AAAA,EACA,KAAA,EAAO;AACT,CAAA;AAEO,MAAM,uBAAA,GAA0B;AAAA,EACrC,IAAA,EAAM;AAAA,IACJ,IAAA,EAAM;AAAA,GACR;AAAA,EACA,KAAA,EAAO,gBAAA;AAAA,EACP,OAAA,EAAS;AAAA;AAAA,IAEP,WAAA,EAAa;AAAA;AAEjB;;;;"}
package/dist/types.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { type TSESLint } from '@typescript-eslint/utils';
2
2
  import { type DeepReadonly } from 'ts-type-forge';
3
3
  export type ESLintPlugin = DeepReadonly<TSESLint.FlatConfig.Plugin>;
4
+ export type ESLintFlatConfig = DeepReadonly<TSESLint.FlatConfig.Config>;
4
5
  //# sourceMappingURL=types.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC"}
1
+ {"version":3,"file":"types.d.mts","sourceRoot":"","sources":["../src/types.mts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,eAAe,CAAC;AAElD,MAAM,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;AAEpE,MAAM,MAAM,gBAAgB,GAAG,YAAY,CAAC,QAAQ,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eslint-plugin-ts-type-forge",
3
- "version": "0.3.2",
3
+ "version": "0.4.1",
4
4
  "private": false,
5
5
  "description": "ESLint rules that steer type declarations toward ts-type-forge idioms.",
6
6
  "keywords": [
@@ -36,7 +36,7 @@
36
36
  ],
37
37
  "dependencies": {
38
38
  "@typescript-eslint/utils": "8.65.0",
39
- "ts-type-forge": "8.1.0"
39
+ "ts-type-forge": "9.0.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@typescript-eslint/parser": "8.65.0",
package/src/index.mts CHANGED
@@ -4,4 +4,4 @@ export type {
4
4
  EslintTsTypeForgeRulesOption,
5
5
  } from './rule-types.mjs';
6
6
  export { tsTypeForgeRules } from './rules/index.mjs';
7
- export { type ESLintPlugin } from './types.mjs';
7
+ export { type ESLintFlatConfig, type ESLintPlugin } from './types.mjs';
package/src/plugin.mts CHANGED
@@ -1,9 +1,41 @@
1
1
  import { tsTypeForgeRules } from './rules/index.mjs';
2
- import { type ESLintPlugin } from './types.mjs';
2
+ import { type ESLintFlatConfig, type ESLintPlugin } from './types.mjs';
3
3
 
4
- export const eslintPluginTsTypeForge: ESLintPlugin = {
4
+ /**
5
+ * Every rule this plugin ships, at `error`.
6
+ *
7
+ * The `satisfies` clause below is keyed off {@link tsTypeForgeRules}, so adding
8
+ * a rule without listing it here fails to type-check.
9
+ */
10
+ const recommendedRules = {
11
+ 'ts-type-forge/prefer-canonical-length-constrained-tuple': 'error',
12
+ } as const satisfies Readonly<
13
+ Record<`ts-type-forge/${keyof typeof tsTypeForgeRules}`, 'error'>
14
+ >;
15
+
16
+ const recommendedConfig = {
17
+ name: 'ts-type-forge/recommended',
18
+ plugins: {
19
+ // Resolved lazily so that this config registers the *same* object that
20
+ // `eslintPluginTsTypeForge` refers to. ESLint rejects a plugin name that
21
+ // maps to two different objects with `Cannot redefine plugin`, which is
22
+ // what a user combining this preset with their own
23
+ // `plugins: { 'ts-type-forge': eslintPluginTsTypeForge }` entry would hit
24
+ // if the preset embedded a separate copy of the plugin.
25
+ get 'ts-type-forge'(): ESLintPlugin {
26
+ return eslintPluginTsTypeForge;
27
+ },
28
+ },
29
+ rules: recommendedRules,
30
+ } as const satisfies ESLintFlatConfig;
31
+
32
+ export const eslintPluginTsTypeForge = {
5
33
  meta: {
6
34
  name: 'eslint-plugin-ts-type-forge',
7
35
  },
8
36
  rules: tsTypeForgeRules,
9
- } as const;
37
+ configs: {
38
+ /** Enables every rule of this plugin at `error`. */
39
+ recommended: recommendedConfig,
40
+ },
41
+ } as const satisfies ESLintPlugin;
@@ -0,0 +1,24 @@
1
+ import { eslintPluginTsTypeForge } from './plugin.mjs';
2
+ import { tsTypeForgeRules } from './rules/index.mjs';
3
+
4
+ describe('eslintPluginTsTypeForge.configs.recommended', () => {
5
+ const recommended = eslintPluginTsTypeForge.configs.recommended;
6
+
7
+ test('enables every rule of the plugin, and nothing else, at "error"', () => {
8
+ assert.deepStrictEqual(
9
+ recommended.rules,
10
+ Object.fromEntries(
11
+ Object.keys(tsTypeForgeRules).map((name) => [
12
+ `ts-type-forge/${name}`,
13
+ 'error',
14
+ ]),
15
+ ),
16
+ );
17
+ });
18
+
19
+ test('registers the exported plugin object itself', () => {
20
+ // Registering a *copy* would make `Cannot redefine plugin` errors possible
21
+ // for users who also list the plugin in their own `plugins` record.
22
+ expect(recommended.plugins['ts-type-forge']).toBe(eslintPluginTsTypeForge);
23
+ });
24
+ });
package/src/types.mts CHANGED
@@ -2,3 +2,5 @@ import { type TSESLint } from '@typescript-eslint/utils';
2
2
  import { type DeepReadonly } from 'ts-type-forge';
3
3
 
4
4
  export type ESLintPlugin = DeepReadonly<TSESLint.FlatConfig.Plugin>;
5
+
6
+ export type ESLintFlatConfig = DeepReadonly<TSESLint.FlatConfig.Config>;