@gost-kit/eslint-config-svelte 0.1.0 → 0.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,55 @@
1
1
  # @gost-kit/eslint-config-svelte
2
2
 
3
+ ## 0.2.1
4
+
5
+ ### Patch Changes
6
+
7
+ - 9f59da3: Add the opt-in ready-boolean-condition rule for Svelte if/else-if conditions.
8
+ Accept ready boolean reads and literals, report computations/truthiness, and
9
+ require typed parser services with strictNullChecks for reads. The Svelte config
10
+ registers the rule off; projects select business/UI-Kit scopes explicitly.
11
+ - Updated dependencies [9f59da3]
12
+ - @gost-kit/eslint-plugin@0.2.0
13
+
14
+ ## 0.2.0
15
+
16
+ ### Minor Changes
17
+
18
+ - d6883b7: Add the typed require-feature-state-selector architecture rule for GOST Store
19
+ and explicit local Svelte raw state. Enable it in typed Svelte config scopes,
20
+ with conservative selector autofix and V2/V3 collision-safe names.
21
+
22
+ ### Patch Changes
23
+
24
+ - 11cc6af: Add opt-in no-component-state diagnostics for state and bindable rune creation,
25
+ with binding-aware empty bind:this ref exceptions and no autofix. Keep the
26
+ public Svelte factory policy unchanged; consumers select application and UI-Kit
27
+ scopes with explicit ESLint overrides.
28
+
29
+ Reuse value-namespace rune resolution in the existing selector rule so type-only
30
+ names/imports do not hide derived or raw-state diagnostics. Consolidate rune and
31
+ Svelte script matching; document explicit plugin registration for extra JS scopes.
32
+
33
+ - 6c74d68: Expose a composed TypeScript policy for framework adapters without an ESLint
34
+ reflection instance. Cover JSX/TSX with general checks and remove unused direct
35
+ config dependencies. Reject ambiguous combined Content-Type values while
36
+ preserving commas inside quoted parameters.
37
+ - 730b73a: Add opt-in single-intent-dispatch for typed business UI callbacks, using public
38
+ Dispatch declaration/signature provenance. Diagnose multiple dispatches or
39
+ conditional intent selection without autofix. Keep the shared Svelte factory
40
+ default off and allow consumer UI-Kit exclusions through ordinary overrides.
41
+
42
+ Include optional calls/accesses that gate Dispatch in conditional-delivery
43
+ diagnostics, without treating unrelated optional data reads as dispatch gates.
44
+ Document the on-prefix and whole-handler syntactic-policy boundaries explicitly.
45
+
46
+ - Updated dependencies [11cc6af]
47
+ - Updated dependencies [d6883b7]
48
+ - Updated dependencies [6c74d68]
49
+ - Updated dependencies [730b73a]
50
+ - @gost-kit/eslint-plugin@0.1.0
51
+ - @gost-kit/eslint-config@0.2.0
52
+
3
53
  ## 0.1.0
4
54
 
5
55
  ### Minor Changes
package/README.md CHANGED
@@ -34,8 +34,9 @@ not require a tsconfig. Component scripts use TypeScript (`lang="ts"`); componen
34
34
  without a script are permitted. TS/JS rune modules are supported. Globals are
35
35
  not supplied for browser, Node or test environments: scope them in the consumer.
36
36
 
37
- The asynchronous factory calculates the shared TypeScript policy using public
38
- ESLint APIs. It writes no files, invokes no application code and does not require
37
+ The asynchronous factory consumes the public `createTypeScriptPolicy` export
38
+ from `@gost-kit/eslint-config`. It does not instantiate ESLint, resolve a synthetic
39
+ filename or depend on private config names. It writes no files, invokes no application code and does not require
39
40
  a placeholder source file. Config/compiler options remain consumer overrides,
40
41
  for example `languageOptions.parserOptions.svelteConfig` for component files.
41
42
  Do not append the common factory again: it is already included.
@@ -63,11 +64,39 @@ component scripts. Svelte formatting is delegated to Prettier; this config does
63
64
  not execute the formatter. Use `@gost-kit/prettier-config` with
64
65
  `prettier-plugin-svelte` in the consuming project's Prettier config.
65
66
 
66
- Architecture policies are separate work: component state ownership (#16),
67
- UI dispatch (#17), boolean conditions (#18), derived calculations (#19) and
68
- feature-state selection (#6). This package does not claim to enforce those
69
- contracts yet. Existing `$state.raw` shell bindings and feature selectors remain
70
- valid; the Svelte compiler/type checker still verifies compilation/accessibility.
67
+ The bundled `@gost-kit/eslint-plugin` enables
68
+ `gost/require-feature-state-selector` on typed components and `.svelte.ts`.
69
+ It recognizes public GOST Store state and explicit local `$state.raw` bindings;
70
+ select the branch with `$derived` before passing it to a reactive computation.
71
+ Simple cases support conservative autofix with V2/V3 name collision suffixes.
72
+ See the installed plugin's RULES.md or the [source inventory](../eslint-plugin/RULES.md)
73
+ for exact supported forms and limitations. JS-script/stateless components are skipped;
74
+ mixed components check only the scripts marked `lang="ts"`.
75
+ The typed architecture rule is not enabled for `.svelte.js`.
76
+
77
+ The bundled `gost/no-component-state` rule is off by default. Enable it for
78
+ application components and exclude independent UI components with ordinary
79
+ ESLint overrides, as shown in the plugin inventory. It diagnoses direct
80
+ `$state`, `$state.raw` and `$bindable` creation, allowing simple empty `bind:this`
81
+ refs. It has no autofix and does not analyze all mutations. The repository's
82
+ private adapter explicitly enables it for `src/**/*.svelte`; the public factory
83
+ does not impose that ownership policy.
84
+
85
+ The bundled `gost/single-intent-dispatch` rule is also off by default. It checks
86
+ real GOST Dispatch calls in typed instance callbacks passed through `on*` props
87
+ or legacy events: one intent per handler, without conditional selection. UI-Kit
88
+ owns browser-event adaptation and may opt out through file overrides. This is
89
+ not a blanket browser API detector, and there is no autofix. Consult the plugin
90
+ inventory for supported aliases and scope limits.
91
+
92
+ The bundled `gost/ready-boolean-condition` rule is off by default. Enable it for
93
+ business components to require ready boolean if/else-if conditions; strictNullChecks
94
+ and typed parser services are required for reads. Boolean literals are allowed;
95
+ comparisons, calls, nullable truthiness and dynamic keys are reported. UI-Kit
96
+ paths can override it off. The check does not prove presenter provenance and
97
+ has no autofix. Presentation computations outside conditions remain #19. Existing `$state.raw`
98
+ shell bindings and feature selectors remain valid; the Svelte compiler/type
99
+ checker still verifies compilation/accessibility.
71
100
 
72
101
  ## Overrides and verification
73
102
 
package/RULES.md CHANGED
@@ -38,9 +38,31 @@ and `**/*.svelte.js` where the upstream rule supports the corresponding syntax.
38
38
 
39
39
  Not enabled: AS04 DOM/listener restrictions, AS05 SSR browser-global restrictions,
40
40
  AS06 prefer-svelte-reactivity, legacy recommended/experimental rules and SvelteKit
41
- routing rules. Prettier owns HTML/CSS formatting. Custom architecture checks #6
42
- and #16–#19 are separate outcomes and are not bundled here.
41
+ routing rules. Prettier owns HTML/CSS formatting. Presentation computations outside conditions remain a separate outcome (#19).
42
+
43
+ The bundled GOST plugin additionally enables `gost/require-feature-state-selector`
44
+ at error for TypeScript component scripts and `.svelte.ts`. It checks public
45
+ Store state and explicit local `$state.raw` before reactive computation calls,
46
+ with limited autofix. JS scripts and `.svelte.js` are excluded from this typed
47
+ rule. See [the plugin inventory](../eslint-plugin/RULES.md) for its boundaries.
43
48
 
44
49
  Sources: [rule catalog](https://sveltejs.github.io/eslint-plugin-svelte/rules/),
45
50
  [configuration boundaries](https://sveltejs.github.io/eslint-plugin-svelte/user-guide/).
46
51
  Recalculate configs and review selected/inherited rule changes when upgrading.
52
+
53
+ `gost/no-component-state` is registered but off by default. Consumers can enable
54
+ it for selected component paths and turn it off in later UI-Kit overrides.
55
+ It checks direct state/bindable rune creation, with a simple `bind:this` ref
56
+ exception and no autofix. See the plugin inventory for exact boundaries.
57
+
58
+ `gost/single-intent-dispatch` is registered but off by default. It checks direct
59
+ GOST Dispatch calls and conditional intent selection in typed instance `on*`
60
+ callbacks. Business/UI-Kit scopes use explicit consumer overrides. It requires
61
+ type services and has no autofix; see the plugin inventory for limits.
62
+
63
+ `gost/ready-boolean-condition` is registered explicitly off. Opt in for business
64
+ components; boolean literals and ready boolean identifier/static member reads
65
+ are allowed. Computations, nonboolean/nullable/any/unknown/never conditions are
66
+ reported. Reads require type services and strictNullChecks; missing configuration
67
+ fails explicitly. JS/stateless template reads are checked when typed services are
68
+ available. There is no autofix or proof of presenter origin; see plugin inventory.
@@ -1,3 +1,3 @@
1
- import { type Linter } from 'eslint';
1
+ import type { Linter } from 'eslint';
2
2
  import { type ConfigOptions } from '@gost-kit/eslint-config';
3
3
  export declare const createSvelteConfig: ({ tsconfigRootDir, }: ConfigOptions) => Promise<Linter.Config[]>;
@@ -1,17 +1,11 @@
1
- import { ESLint } from 'eslint';
2
- import { createConfig } from '@gost-kit/eslint-config';
1
+ import { plugin } from '@gost-kit/eslint-plugin';
2
+ import { createConfig, createTypeScriptPolicy, } from '@gost-kit/eslint-config';
3
3
  import svelte from 'eslint-plugin-svelte';
4
4
  import ts from 'typescript-eslint';
5
- import { join } from 'node:path';
6
5
  import { svelteRules } from './rules.js';
7
6
  export const createSvelteConfig = async ({ tsconfigRootDir, }) => {
8
7
  const shared = createConfig({ tsconfigRootDir });
9
- const eslint = new ESLint({
10
- cwd: tsconfigRootDir,
11
- overrideConfigFile: true,
12
- overrideConfig: shared,
13
- });
14
- const policy = await eslint.calculateConfigForFile(join(tsconfigRootDir, '__gost_svelte_policy__.ts'));
8
+ const policy = createTypeScriptPolicy({ tsconfigRootDir });
15
9
  return [
16
10
  { name: 'gost-svelte/ignores', ignores: ['**/.svelte-kit/**'] },
17
11
  ...shared,
@@ -19,7 +13,7 @@ export const createSvelteConfig = async ({ tsconfigRootDir, }) => {
19
13
  ...svelte.configs.prettier,
20
14
  {
21
15
  name: 'gost-svelte/typescript-project',
22
- files: ['**/*.{ts,mts,cts}', '**/*.svelte'],
16
+ files: ['**/*.{ts,tsx,mts,cts}', '**/*.svelte'],
23
17
  languageOptions: { parserOptions: { extraFileExtensions: ['.svelte'] } },
24
18
  },
25
19
  {
@@ -30,10 +24,7 @@ export const createSvelteConfig = async ({ tsconfigRootDir, }) => {
30
24
  {
31
25
  name: 'gost-svelte/component-typescript',
32
26
  files: ['**/*.svelte'],
33
- plugins: Object.fromEntries(Object.entries(policy.plugins ?? {}).filter(([name]) => {
34
- // ESLint owns this plugin; distinct consumer instances have different identities.
35
- return name !== '@';
36
- })),
27
+ plugins: policy.plugins,
37
28
  rules: policy.rules,
38
29
  languageOptions: {
39
30
  parserOptions: {
@@ -44,6 +35,15 @@ export const createSvelteConfig = async ({ tsconfigRootDir, }) => {
44
35
  },
45
36
  },
46
37
  },
38
+ {
39
+ name: 'gost-svelte/architecture',
40
+ files: ['**/*.svelte', '**/*.svelte.ts'],
41
+ plugins: { gost: plugin },
42
+ rules: {
43
+ 'gost/require-feature-state-selector': 'error',
44
+ 'gost/ready-boolean-condition': 'off',
45
+ },
46
+ },
47
47
  {
48
48
  name: 'gost-svelte/selected-rules',
49
49
  files: ['**/*.svelte', '**/*.svelte.ts', '**/*.svelte.js'],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gost-kit/eslint-config-svelte",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "description": "Shared Svelte 5 ESLint configuration with the GOST JavaScript and TypeScript baseline.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -46,10 +46,11 @@
46
46
  "prettier-plugin-svelte": "4.1.1"
47
47
  },
48
48
  "dependencies": {
49
- "@gost-kit/eslint-config": "0.1.0",
49
+ "@gost-kit/eslint-config": "0.2.0",
50
50
  "eslint-plugin-svelte": "3.24.0",
51
51
  "svelte-eslint-parser": "1.10.1",
52
- "typescript-eslint": "8.72.1"
52
+ "typescript-eslint": "8.72.1",
53
+ "@gost-kit/eslint-plugin": "0.2.0"
53
54
  },
54
55
  "peerDependencies": {
55
56
  "eslint": "^10.14.0",