@formspec/eslint-plugin 0.1.0-alpha.10

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 (74) hide show
  1. package/README.md +237 -0
  2. package/dist/index.d.ts +71 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +117 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/rules/consistent-constraints.d.ts +22 -0
  7. package/dist/rules/consistent-constraints.d.ts.map +1 -0
  8. package/dist/rules/consistent-constraints.js +178 -0
  9. package/dist/rules/consistent-constraints.js.map +1 -0
  10. package/dist/rules/constraints/allowed-field-types.d.ts +16 -0
  11. package/dist/rules/constraints/allowed-field-types.d.ts.map +1 -0
  12. package/dist/rules/constraints/allowed-field-types.js +133 -0
  13. package/dist/rules/constraints/allowed-field-types.js.map +1 -0
  14. package/dist/rules/constraints/allowed-layouts.d.ts +17 -0
  15. package/dist/rules/constraints/allowed-layouts.d.ts.map +1 -0
  16. package/dist/rules/constraints/allowed-layouts.js +83 -0
  17. package/dist/rules/constraints/allowed-layouts.js.map +1 -0
  18. package/dist/rules/constraints/index.d.ts +9 -0
  19. package/dist/rules/constraints/index.d.ts.map +1 -0
  20. package/dist/rules/constraints/index.js +9 -0
  21. package/dist/rules/constraints/index.js.map +1 -0
  22. package/dist/rules/decorator-allowed-field-types.d.ts +17 -0
  23. package/dist/rules/decorator-allowed-field-types.d.ts.map +1 -0
  24. package/dist/rules/decorator-allowed-field-types.js +71 -0
  25. package/dist/rules/decorator-allowed-field-types.js.map +1 -0
  26. package/dist/rules/decorator-field-type-mismatch.d.ts +14 -0
  27. package/dist/rules/decorator-field-type-mismatch.d.ts.map +1 -0
  28. package/dist/rules/decorator-field-type-mismatch.js +116 -0
  29. package/dist/rules/decorator-field-type-mismatch.js.map +1 -0
  30. package/dist/rules/enum-options-match-type.d.ts +26 -0
  31. package/dist/rules/enum-options-match-type.d.ts.map +1 -0
  32. package/dist/rules/enum-options-match-type.js +115 -0
  33. package/dist/rules/enum-options-match-type.js.map +1 -0
  34. package/dist/rules/index.d.ts +13 -0
  35. package/dist/rules/index.d.ts.map +1 -0
  36. package/dist/rules/index.js +13 -0
  37. package/dist/rules/index.js.map +1 -0
  38. package/dist/rules/no-conflicting-decorators.d.ts +15 -0
  39. package/dist/rules/no-conflicting-decorators.d.ts.map +1 -0
  40. package/dist/rules/no-conflicting-decorators.js +72 -0
  41. package/dist/rules/no-conflicting-decorators.js.map +1 -0
  42. package/dist/rules/no-duplicate-decorators.d.ts +19 -0
  43. package/dist/rules/no-duplicate-decorators.d.ts.map +1 -0
  44. package/dist/rules/no-duplicate-decorators.js +59 -0
  45. package/dist/rules/no-duplicate-decorators.js.map +1 -0
  46. package/dist/rules/prefer-custom-decorator.d.ts +22 -0
  47. package/dist/rules/prefer-custom-decorator.d.ts.map +1 -0
  48. package/dist/rules/prefer-custom-decorator.js +72 -0
  49. package/dist/rules/prefer-custom-decorator.js.map +1 -0
  50. package/dist/rules/showwhen-field-exists.d.ts +21 -0
  51. package/dist/rules/showwhen-field-exists.d.ts.map +1 -0
  52. package/dist/rules/showwhen-field-exists.js +68 -0
  53. package/dist/rules/showwhen-field-exists.js.map +1 -0
  54. package/dist/rules/showwhen-suggests-optional.d.ts +19 -0
  55. package/dist/rules/showwhen-suggests-optional.d.ts.map +1 -0
  56. package/dist/rules/showwhen-suggests-optional.js +53 -0
  57. package/dist/rules/showwhen-suggests-optional.js.map +1 -0
  58. package/dist/utils/decorator-utils.d.ts +105 -0
  59. package/dist/utils/decorator-utils.d.ts.map +1 -0
  60. package/dist/utils/decorator-utils.js +216 -0
  61. package/dist/utils/decorator-utils.js.map +1 -0
  62. package/dist/utils/index.d.ts +6 -0
  63. package/dist/utils/index.d.ts.map +1 -0
  64. package/dist/utils/index.js +6 -0
  65. package/dist/utils/index.js.map +1 -0
  66. package/dist/utils/jsdoc-utils.d.ts +31 -0
  67. package/dist/utils/jsdoc-utils.d.ts.map +1 -0
  68. package/dist/utils/jsdoc-utils.js +81 -0
  69. package/dist/utils/jsdoc-utils.js.map +1 -0
  70. package/dist/utils/type-utils.d.ts +82 -0
  71. package/dist/utils/type-utils.d.ts.map +1 -0
  72. package/dist/utils/type-utils.js +216 -0
  73. package/dist/utils/type-utils.js.map +1 -0
  74. package/package.json +50 -0
package/README.md ADDED
@@ -0,0 +1,237 @@
1
+ # @your-org/eslint-plugin
2
+
3
+ ESLint rules for working with your schema/constraints.
4
+
5
+ ## Rules
6
+
7
+ | Rule name | Description |
8
+ | ----------------------- | --------------------------------------------------------------- |
9
+ | `consistent-constraints` | Enforces consistent min/max and related constraints in schemas. |
10
+
11
+ ## Rule details
12
+
13
+ ### `consistent-constraints`
14
+
15
+ This rule validates that constraint-related properties (such as minimum and maximum
16
+ values, lengths, or ranges) are used consistently and do not contradict each other.
17
+
18
+ It is intended as a replacement for the now-removed `min-max-valid-range` rule and
19
+ should be enabled wherever constraint consistency needs to be enforced.
20
+
21
+ <!-- Add additional rules and documentation here as needed. -->
22
+ # @formspec/eslint-plugin
23
+
24
+ ESLint plugin for validating FormSpec decorator DSL usage in TypeScript projects. This plugin catches common mistakes by ensuring decorators match their field types and enforcing consistency rules.
25
+
26
+ ## Installation
27
+
28
+ ```bash
29
+ npm install --save-dev @formspec/eslint-plugin
30
+ # or
31
+ pnpm add -D @formspec/eslint-plugin
32
+ ```
33
+
34
+ ## Requirements
35
+
36
+ - ESLint v9+ (flat config)
37
+ - TypeScript v5+
38
+
39
+ ## Usage
40
+
41
+ ### Recommended Configuration
42
+
43
+ Add the plugin to your `eslint.config.js`:
44
+
45
+ ```javascript
46
+ import formspec from "@formspec/eslint-plugin";
47
+
48
+ export default [
49
+ // ... other configs
50
+ ...formspec.configs.recommended,
51
+ ];
52
+ ```
53
+
54
+ ### Manual Configuration
55
+
56
+ ```javascript
57
+ import formspec from "@formspec/eslint-plugin";
58
+
59
+ export default [
60
+ {
61
+ plugins: {
62
+ "@formspec": formspec,
63
+ },
64
+ rules: {
65
+ "@formspec/decorator-field-type-mismatch": "error",
66
+ "@formspec/enum-options-match-type": "error",
67
+ "@formspec/showwhen-field-exists": "error",
68
+ "@formspec/showwhen-suggests-optional": "warn",
69
+ "@formspec/min-max-valid-range": "error",
70
+ "@formspec/no-conflicting-decorators": "error",
71
+ "@formspec/no-duplicate-decorators": "error",
72
+ },
73
+ },
74
+ ];
75
+ ```
76
+
77
+ ## Rules
78
+
79
+ | Rule | Description | Recommended | Strict |
80
+ | ----------------------------------------------------------------- | -------------------------------------------------------------- | ----------- | ------ |
81
+ | [`decorator-field-type-mismatch`](#decorator-field-type-mismatch) | Ensures decorators are applied to fields with compatible types | error | error |
82
+ | [`enum-options-match-type`](#enum-options-match-type) | Ensures @EnumOptions values match the field's union type | error | error |
83
+ | [`showwhen-field-exists`](#showwhen-field-exists) | Ensures @ShowWhen references a field that exists | error | error |
84
+ | [`showwhen-suggests-optional`](#showwhen-suggests-optional) | Suggests @ShowWhen fields should be optional | warn | error |
85
+ | [`min-max-valid-range`](#min-max-valid-range) | Ensures @Min/@Max have valid ranges | error | error |
86
+ | [`no-conflicting-decorators`](#no-conflicting-decorators) | Prevents decorators that imply conflicting types | error | error |
87
+ | [`no-duplicate-decorators`](#no-duplicate-decorators) | Prevents duplicate decorators on the same field | error | error |
88
+
89
+ ### decorator-field-type-mismatch
90
+
91
+ Ensures FormSpec decorators are applied to fields with compatible types.
92
+
93
+ ```typescript
94
+ // Valid
95
+ @Min(0)
96
+ @Max(100)
97
+ age!: number;
98
+
99
+ @Placeholder("Enter name")
100
+ name!: string;
101
+
102
+ @MinItems(1)
103
+ @MaxItems(10)
104
+ items!: string[];
105
+
106
+ // Invalid - @Min requires number field
107
+ @Min(0)
108
+ name!: string; // Error: @Min can only be used on number fields
109
+ ```
110
+
111
+ ### enum-options-match-type
112
+
113
+ Ensures @EnumOptions values match the field's TypeScript union type.
114
+
115
+ ```typescript
116
+ // Valid - options match type
117
+ @EnumOptions(["draft", "published", "archived"])
118
+ status!: "draft" | "published" | "archived";
119
+
120
+ // Valid - object options with id property
121
+ @EnumOptions([{ id: "a", label: "Option A" }, { id: "b", label: "Option B" }])
122
+ type!: "a" | "b";
123
+
124
+ // Valid - string type accepts any options
125
+ @EnumOptions(["any", "options"])
126
+ value!: string;
127
+
128
+ // Invalid - missing option "archived"
129
+ @EnumOptions(["draft", "published"])
130
+ status!: "draft" | "published" | "archived"; // Error: missing "archived"
131
+ ```
132
+
133
+ ### showwhen-field-exists
134
+
135
+ Ensures @ShowWhen references a field that exists in the same class.
136
+
137
+ ```typescript
138
+ // Valid
139
+ @EnumOptions(["a", "b"])
140
+ type!: "a" | "b";
141
+
142
+ @ShowWhen({ _predicate: "equals", field: "type", value: "a" })
143
+ conditionalField?: string;
144
+
145
+ // Invalid - "nonexistent" field doesn't exist
146
+ @ShowWhen({ _predicate: "equals", field: "nonexistent", value: "x" })
147
+ conditionalField?: string; // Error: field "nonexistent" does not exist
148
+ ```
149
+
150
+ ### showwhen-suggests-optional
151
+
152
+ Suggests that fields with @ShowWhen should be marked as optional since they may not be present in the output.
153
+
154
+ ```typescript
155
+ // Valid
156
+ @ShowWhen({ _predicate: "equals", field: "type", value: "a" })
157
+ conditionalField?: string; // Good - optional
158
+
159
+ // Warning
160
+ @ShowWhen({ _predicate: "equals", field: "type", value: "a" })
161
+ conditionalField!: string; // Warning: should be optional
162
+ ```
163
+
164
+ ### min-max-valid-range
165
+
166
+ Ensures @Min value is less than or equal to @Max value.
167
+
168
+ ```typescript
169
+ // Valid
170
+ @Min(0)
171
+ @Max(100)
172
+ value!: number;
173
+
174
+ @Min(5)
175
+ @Max(5) // Equal is valid
176
+ exact!: number;
177
+
178
+ // Invalid
179
+ @Min(100)
180
+ @Max(50) // Error: @Min(100) > @Max(50)
181
+ invalid!: number;
182
+ ```
183
+
184
+ ### no-conflicting-decorators
185
+
186
+ Prevents using decorators that imply conflicting field types.
187
+
188
+ ```typescript
189
+ // Valid - both imply number
190
+ @Min(0)
191
+ @Max(100)
192
+ value!: number;
193
+
194
+ // Invalid - @Min implies number, @Placeholder implies string
195
+ @Min(0)
196
+ @Placeholder("Enter value") // Error: conflicting decorators
197
+ field!: string;
198
+ ```
199
+
200
+ ### no-duplicate-decorators
201
+
202
+ Prevents applying the same decorator multiple times to a field.
203
+
204
+ ```typescript
205
+ // Valid
206
+ @Label("Name")
207
+ @Placeholder("Enter name")
208
+ name!: string;
209
+
210
+ // Invalid
211
+ @Label("First")
212
+ @Label("Second") // Error: duplicate @Label
213
+ name!: string;
214
+ ```
215
+
216
+ ## Configurations
217
+
218
+ ### Recommended
219
+
220
+ Sensible defaults for most projects:
221
+
222
+ - All type safety rules enabled as errors
223
+ - `showwhen-suggests-optional` as warning (not blocking)
224
+
225
+ ### Strict
226
+
227
+ All rules enabled as errors for maximum type safety enforcement.
228
+
229
+ ```javascript
230
+ import formspec from "@formspec/eslint-plugin";
231
+
232
+ export default [...formspec.configs.strict];
233
+ ```
234
+
235
+ ## License
236
+
237
+ UNLICENSED
@@ -0,0 +1,71 @@
1
+ /**
2
+ * @formspec/eslint-plugin
3
+ *
4
+ * ESLint plugin for FormSpec type safety and constraint validation.
5
+ *
6
+ * Provides rules to:
7
+ * - Catch common mistakes when using FormSpec decorators
8
+ * - Validate Chain DSL usage against project constraints
9
+ * - Ensure forms comply with target environment capabilities
10
+ */
11
+ import type { TSESLint } from "@typescript-eslint/utils";
12
+ import { decoratorFieldTypeMismatch } from "./rules/decorator-field-type-mismatch.js";
13
+ import { enumOptionsMatchType } from "./rules/enum-options-match-type.js";
14
+ import { showwhenFieldExists } from "./rules/showwhen-field-exists.js";
15
+ import { showwhenSuggestsOptional } from "./rules/showwhen-suggests-optional.js";
16
+ import { consistentConstraints } from "./rules/consistent-constraints.js";
17
+ import { noConflictingDecorators } from "./rules/no-conflicting-decorators.js";
18
+ import { noDuplicateDecorators } from "./rules/no-duplicate-decorators.js";
19
+ import { decoratorAllowedFieldTypes } from "./rules/decorator-allowed-field-types.js";
20
+ import { preferCustomDecorator } from "./rules/prefer-custom-decorator.js";
21
+ import { allowedFieldTypes, allowedLayouts } from "./rules/constraints/index.js";
22
+ /**
23
+ * The FormSpec ESLint plugin.
24
+ */
25
+ declare const plugin: {
26
+ meta: {
27
+ name: string;
28
+ };
29
+ rules: {
30
+ readonly "decorator-field-type-mismatch": TSESLint.RuleModule<"numericOnNonNumber" | "stringOnNonString", [], unknown, TSESLint.RuleListener> & {
31
+ name: string;
32
+ };
33
+ readonly "enum-options-match-type": TSESLint.RuleModule<"enumOptionsMismatch" | "enumOptionsMissing" | "enumOptionsExtra", [], unknown, TSESLint.RuleListener> & {
34
+ name: string;
35
+ };
36
+ readonly "showwhen-field-exists": TSESLint.RuleModule<"fieldDoesNotExist", [], unknown, TSESLint.RuleListener> & {
37
+ name: string;
38
+ };
39
+ readonly "showwhen-suggests-optional": TSESLint.RuleModule<"shouldBeOptional", [], unknown, TSESLint.RuleListener> & {
40
+ name: string;
41
+ };
42
+ readonly "consistent-constraints": TSESLint.RuleModule<"minimumGreaterThanMaximum" | "exclusiveMinGreaterOrEqualMax" | "minLengthGreaterThanMaxLength" | "conflictingMinimumBounds" | "conflictingMaximumBounds" | "exclusiveMaxLessOrEqualMin" | "maximumLessOrEqualExclusiveMin" | "duplicateConstraintSource", [], unknown, TSESLint.RuleListener> & {
43
+ name: string;
44
+ };
45
+ readonly "no-conflicting-decorators": TSESLint.RuleModule<"conflictingDecorators", [], unknown, TSESLint.RuleListener> & {
46
+ name: string;
47
+ };
48
+ readonly "no-duplicate-decorators": TSESLint.RuleModule<"duplicateDecorator", [], unknown, TSESLint.RuleListener> & {
49
+ name: string;
50
+ };
51
+ readonly "decorator-allowed-field-types": TSESLint.RuleModule<"disallowedFieldType", [import("./rules/decorator-allowed-field-types.js").DecoratorAllowedFieldTypesOptions], unknown, TSESLint.RuleListener> & {
52
+ name: string;
53
+ };
54
+ readonly "prefer-custom-decorator": TSESLint.RuleModule<"preferCustomDecorator", [import("./rules/prefer-custom-decorator.js").PreferCustomDecoratorOptions], unknown, TSESLint.RuleListener> & {
55
+ name: string;
56
+ };
57
+ readonly "constraints-allowed-field-types": TSESLint.RuleModule<"disallowedFieldType", import("./rules/constraints/allowed-field-types.js").Options, unknown, TSESLint.RuleListener> & {
58
+ name: string;
59
+ };
60
+ readonly "constraints-allowed-layouts": TSESLint.RuleModule<"disallowedGroup" | "disallowedConditional", import("./rules/constraints/allowed-layouts.js").Options, unknown, TSESLint.RuleListener> & {
61
+ name: string;
62
+ };
63
+ };
64
+ configs: {
65
+ recommended: TSESLint.FlatConfig.ConfigArray;
66
+ strict: TSESLint.FlatConfig.ConfigArray;
67
+ };
68
+ };
69
+ export default plugin;
70
+ export { decoratorFieldTypeMismatch, enumOptionsMatchType, showwhenFieldExists, showwhenSuggestsOptional, consistentConstraints, noConflictingDecorators, noDuplicateDecorators, decoratorAllowedFieldTypes, preferCustomDecorator, allowedFieldTypes, allowedLayouts, };
71
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAG3E,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAoFjF;;GAEG;AACH,QAAA,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOX,CAAC;AAEF,eAAe,MAAM,CAAC;AAGtB,OAAO,EAEL,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB,EAErB,iBAAiB,EACjB,cAAc,GACf,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,117 @@
1
+ /**
2
+ * @formspec/eslint-plugin
3
+ *
4
+ * ESLint plugin for FormSpec type safety and constraint validation.
5
+ *
6
+ * Provides rules to:
7
+ * - Catch common mistakes when using FormSpec decorators
8
+ * - Validate Chain DSL usage against project constraints
9
+ * - Ensure forms comply with target environment capabilities
10
+ */
11
+ import { decoratorFieldTypeMismatch } from "./rules/decorator-field-type-mismatch.js";
12
+ import { enumOptionsMatchType } from "./rules/enum-options-match-type.js";
13
+ import { showwhenFieldExists } from "./rules/showwhen-field-exists.js";
14
+ import { showwhenSuggestsOptional } from "./rules/showwhen-suggests-optional.js";
15
+ import { consistentConstraints } from "./rules/consistent-constraints.js";
16
+ import { noConflictingDecorators } from "./rules/no-conflicting-decorators.js";
17
+ import { noDuplicateDecorators } from "./rules/no-duplicate-decorators.js";
18
+ import { decoratorAllowedFieldTypes } from "./rules/decorator-allowed-field-types.js";
19
+ import { preferCustomDecorator } from "./rules/prefer-custom-decorator.js";
20
+ // Constraint rules for Chain DSL
21
+ import { allowedFieldTypes, allowedLayouts } from "./rules/constraints/index.js";
22
+ /**
23
+ * All rules provided by this plugin.
24
+ */
25
+ const rules = {
26
+ // Decorator DSL rules
27
+ "decorator-field-type-mismatch": decoratorFieldTypeMismatch,
28
+ "enum-options-match-type": enumOptionsMatchType,
29
+ "showwhen-field-exists": showwhenFieldExists,
30
+ "showwhen-suggests-optional": showwhenSuggestsOptional,
31
+ "consistent-constraints": consistentConstraints,
32
+ "no-conflicting-decorators": noConflictingDecorators,
33
+ "no-duplicate-decorators": noDuplicateDecorators,
34
+ "decorator-allowed-field-types": decoratorAllowedFieldTypes,
35
+ "prefer-custom-decorator": preferCustomDecorator,
36
+ // Constraint rules for Chain DSL
37
+ "constraints-allowed-field-types": allowedFieldTypes,
38
+ "constraints-allowed-layouts": allowedLayouts,
39
+ };
40
+ /**
41
+ * Plugin metadata.
42
+ */
43
+ const meta = {
44
+ name: "@formspec/eslint-plugin",
45
+ };
46
+ /**
47
+ * Recommended configuration for FormSpec projects.
48
+ *
49
+ * Usage:
50
+ * ```javascript
51
+ * import formspec from "@formspec/eslint-plugin";
52
+ *
53
+ * export default [
54
+ * ...formspec.configs.recommended,
55
+ * ];
56
+ * ```
57
+ */
58
+ const recommendedConfig = [
59
+ {
60
+ plugins: {
61
+ "@formspec": {
62
+ meta,
63
+ rules,
64
+ },
65
+ },
66
+ rules: {
67
+ "@formspec/decorator-field-type-mismatch": "error",
68
+ "@formspec/enum-options-match-type": "error",
69
+ "@formspec/showwhen-field-exists": "error",
70
+ "@formspec/showwhen-suggests-optional": "warn",
71
+ "@formspec/consistent-constraints": "error",
72
+ "@formspec/no-conflicting-decorators": "error",
73
+ "@formspec/no-duplicate-decorators": "error",
74
+ },
75
+ },
76
+ ];
77
+ /**
78
+ * Strict configuration - all rules as errors.
79
+ */
80
+ const strictConfig = [
81
+ {
82
+ plugins: {
83
+ "@formspec": {
84
+ meta,
85
+ rules,
86
+ },
87
+ },
88
+ rules: {
89
+ "@formspec/decorator-field-type-mismatch": "error",
90
+ "@formspec/enum-options-match-type": "error",
91
+ "@formspec/showwhen-field-exists": "error",
92
+ "@formspec/showwhen-suggests-optional": "error",
93
+ "@formspec/consistent-constraints": "error",
94
+ "@formspec/no-conflicting-decorators": "error",
95
+ "@formspec/no-duplicate-decorators": "error",
96
+ },
97
+ },
98
+ ];
99
+ /**
100
+ * The FormSpec ESLint plugin.
101
+ */
102
+ const plugin = {
103
+ meta,
104
+ rules,
105
+ configs: {
106
+ recommended: recommendedConfig,
107
+ strict: strictConfig,
108
+ },
109
+ };
110
+ export default plugin;
111
+ // Named exports for individual rules
112
+ export {
113
+ // Decorator DSL rules
114
+ decoratorFieldTypeMismatch, enumOptionsMatchType, showwhenFieldExists, showwhenSuggestsOptional, consistentConstraints, noConflictingDecorators, noDuplicateDecorators, decoratorAllowedFieldTypes, preferCustomDecorator,
115
+ // Constraint rules for Chain DSL
116
+ allowedFieldTypes, allowedLayouts, };
117
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,EAAE,qBAAqB,EAAE,MAAM,mCAAmC,CAAC;AAC1E,OAAO,EAAE,uBAAuB,EAAE,MAAM,sCAAsC,CAAC;AAC/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,0CAA0C,CAAC;AACtF,OAAO,EAAE,qBAAqB,EAAE,MAAM,oCAAoC,CAAC;AAE3E,iCAAiC;AACjC,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAEjF;;GAEG;AACH,MAAM,KAAK,GAAG;IACZ,sBAAsB;IACtB,+BAA+B,EAAE,0BAA0B;IAC3D,yBAAyB,EAAE,oBAAoB;IAC/C,uBAAuB,EAAE,mBAAmB;IAC5C,4BAA4B,EAAE,wBAAwB;IACtD,wBAAwB,EAAE,qBAAqB;IAC/C,2BAA2B,EAAE,uBAAuB;IACpD,yBAAyB,EAAE,qBAAqB;IAChD,+BAA+B,EAAE,0BAA0B;IAC3D,yBAAyB,EAAE,qBAAqB;IAEhD,iCAAiC;IACjC,iCAAiC,EAAE,iBAAiB;IACpD,6BAA6B,EAAE,cAAc;CACrC,CAAC;AAEX;;GAEG;AACH,MAAM,IAAI,GAAG;IACX,IAAI,EAAE,yBAAyB;CAChC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,iBAAiB,GAAoC;IACzD;QACE,OAAO,EAAE;YACP,WAAW,EAAE;gBACX,IAAI;gBACJ,KAAK;aACN;SACF;QACD,KAAK,EAAE;YACL,yCAAyC,EAAE,OAAO;YAClD,mCAAmC,EAAE,OAAO;YAC5C,iCAAiC,EAAE,OAAO;YAC1C,sCAAsC,EAAE,MAAM;YAC9C,kCAAkC,EAAE,OAAO;YAC3C,qCAAqC,EAAE,OAAO;YAC9C,mCAAmC,EAAE,OAAO;SAC7C;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,YAAY,GAAoC;IACpD;QACE,OAAO,EAAE;YACP,WAAW,EAAE;gBACX,IAAI;gBACJ,KAAK;aACN;SACF;QACD,KAAK,EAAE;YACL,yCAAyC,EAAE,OAAO;YAClD,mCAAmC,EAAE,OAAO;YAC5C,iCAAiC,EAAE,OAAO;YAC1C,sCAAsC,EAAE,OAAO;YAC/C,kCAAkC,EAAE,OAAO;YAC3C,qCAAqC,EAAE,OAAO;YAC9C,mCAAmC,EAAE,OAAO;SAC7C;KACF;CACF,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,GAAG;IACb,IAAI;IACJ,KAAK;IACL,OAAO,EAAE;QACP,WAAW,EAAE,iBAAiB;QAC9B,MAAM,EAAE,YAAY;KACrB;CACF,CAAC;AAEF,eAAe,MAAM,CAAC;AAEtB,qCAAqC;AACrC,OAAO;AACL,sBAAsB;AACtB,0BAA0B,EAC1B,oBAAoB,EACpB,mBAAmB,EACnB,wBAAwB,EACxB,qBAAqB,EACrB,uBAAuB,EACvB,qBAAqB,EACrB,0BAA0B,EAC1B,qBAAqB;AACrB,iCAAiC;AACjC,iBAAiB,EACjB,cAAc,GACf,CAAC"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Rule: consistent-constraints
3
+ *
4
+ * Ensures constraint decorator pairs have valid ranges and don't conflict:
5
+ * - @Minimum must be <= @Maximum
6
+ * - @ExclusiveMinimum must be < @ExclusiveMaximum
7
+ * - @MinLength must be <= @MaxLength
8
+ * - @Minimum and @ExclusiveMinimum must not both be present
9
+ * - @Maximum and @ExclusiveMaximum must not both be present
10
+ * - @Maximum(n) where n < @Minimum(m) is invalid
11
+ * - @ExclusiveMaximum(n) where n <= @Minimum(m) is invalid
12
+ *
13
+ * Constraints may come from decorators or JSDoc tags. If both a decorator
14
+ * and a JSDoc tag specify the same constraint, that is a lint error.
15
+ */
16
+ import { ESLintUtils } from "@typescript-eslint/utils";
17
+ type MessageIds = "minimumGreaterThanMaximum" | "exclusiveMinGreaterOrEqualMax" | "minLengthGreaterThanMaxLength" | "conflictingMinimumBounds" | "conflictingMaximumBounds" | "exclusiveMaxLessOrEqualMin" | "maximumLessOrEqualExclusiveMin" | "duplicateConstraintSource";
18
+ export declare const consistentConstraints: ESLintUtils.RuleModule<MessageIds, [], unknown, ESLintUtils.RuleListener> & {
19
+ name: string;
20
+ };
21
+ export {};
22
+ //# sourceMappingURL=consistent-constraints.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistent-constraints.d.ts","sourceRoot":"","sources":["../../src/rules/consistent-constraints.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAQvD,KAAK,UAAU,GACX,2BAA2B,GAC3B,+BAA+B,GAC/B,+BAA+B,GAC/B,0BAA0B,GAC1B,0BAA0B,GAC1B,4BAA4B,GAC5B,gCAAgC,GAChC,2BAA2B,CAAC;AAYhC,eAAO,MAAM,qBAAqB;;CAyLhC,CAAC"}
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Rule: consistent-constraints
3
+ *
4
+ * Ensures constraint decorator pairs have valid ranges and don't conflict:
5
+ * - @Minimum must be <= @Maximum
6
+ * - @ExclusiveMinimum must be < @ExclusiveMaximum
7
+ * - @MinLength must be <= @MaxLength
8
+ * - @Minimum and @ExclusiveMinimum must not both be present
9
+ * - @Maximum and @ExclusiveMaximum must not both be present
10
+ * - @Maximum(n) where n < @Minimum(m) is invalid
11
+ * - @ExclusiveMaximum(n) where n <= @Minimum(m) is invalid
12
+ *
13
+ * Constraints may come from decorators or JSDoc tags. If both a decorator
14
+ * and a JSDoc tag specify the same constraint, that is a lint error.
15
+ */
16
+ import { ESLintUtils } from "@typescript-eslint/utils";
17
+ import { findDecorator, getDecoratorLiteralArg } from "../utils/decorator-utils.js";
18
+ import { getJSDocConstraints, findJSDocConstraint } from "../utils/jsdoc-utils.js";
19
+ const createRule = ESLintUtils.RuleCreator((name) => `https://formspec.dev/eslint-plugin/rules/${name}`);
20
+ export const consistentConstraints = createRule({
21
+ name: "consistent-constraints",
22
+ meta: {
23
+ type: "problem",
24
+ docs: {
25
+ description: "Ensures constraint decorator pairs have valid ranges and don't conflict",
26
+ },
27
+ messages: {
28
+ minimumGreaterThanMaximum: "@Minimum({{min}}) is greater than @Maximum({{max}}). Minimum must be less than or equal to Maximum.",
29
+ exclusiveMinGreaterOrEqualMax: "@ExclusiveMinimum({{min}}) must be less than @ExclusiveMaximum({{max}}).",
30
+ minLengthGreaterThanMaxLength: "@MinLength({{min}}) is greater than @MaxLength({{max}}). MinLength must be less than or equal to MaxLength.",
31
+ conflictingMinimumBounds: "Field has both @Minimum and @ExclusiveMinimum. Use only one lower bound constraint.",
32
+ conflictingMaximumBounds: "Field has both @Maximum and @ExclusiveMaximum. Use only one upper bound constraint.",
33
+ exclusiveMaxLessOrEqualMin: "@ExclusiveMaximum({{max}}) must be greater than @Minimum({{min}}).",
34
+ maximumLessOrEqualExclusiveMin: "@Maximum({{max}}) must be greater than @ExclusiveMinimum({{min}}).",
35
+ duplicateConstraintSource: "Constraint '{{name}}' is specified via both a decorator and a TSDoc tag. Use one or the other.",
36
+ },
37
+ schema: [],
38
+ },
39
+ defaultOptions: [],
40
+ create(context) {
41
+ const sourceCode = context.sourceCode;
42
+ return {
43
+ PropertyDefinition(node) {
44
+ const jsdocConstraints = getJSDocConstraints(node, sourceCode);
45
+ // Track which constraints have already been reported as duplicates
46
+ const reportedDuplicates = new Set();
47
+ /**
48
+ * Gets a numeric constraint value from either a decorator or a JSDoc tag.
49
+ * Reports a conflict if both sources provide the same constraint.
50
+ * Returns null if the constraint is absent, ambiguous, or non-numeric.
51
+ */
52
+ function getConstraintValue(name) {
53
+ const dec = findDecorator(node, name);
54
+ const jsdoc = findJSDocConstraint(jsdocConstraints, name);
55
+ // Conflict: same constraint from both sources
56
+ if (dec && jsdoc) {
57
+ reportedDuplicates.add(name);
58
+ context.report({
59
+ node: dec.node,
60
+ messageId: "duplicateConstraintSource",
61
+ data: { name },
62
+ });
63
+ return null; // Don't validate range when ambiguous
64
+ }
65
+ if (dec) {
66
+ const val = getDecoratorLiteralArg(dec);
67
+ return typeof val === "number" ? { value: val, loc: dec.node.loc } : null;
68
+ }
69
+ if (jsdoc && typeof jsdoc.value === "number") {
70
+ return { value: jsdoc.value, loc: jsdoc.comment.loc };
71
+ }
72
+ return null;
73
+ }
74
+ /**
75
+ * Checks whether a constraint is present from either source.
76
+ * Only reports duplicate source if not already reported by getConstraintValue.
77
+ */
78
+ function hasConstraint(name) {
79
+ const dec = findDecorator(node, name);
80
+ const jsdoc = findJSDocConstraint(jsdocConstraints, name);
81
+ if (dec && jsdoc && !reportedDuplicates.has(name)) {
82
+ reportedDuplicates.add(name);
83
+ context.report({
84
+ node: dec.node,
85
+ messageId: "duplicateConstraintSource",
86
+ data: { name },
87
+ });
88
+ }
89
+ if (dec)
90
+ return { present: true, loc: dec.node.loc };
91
+ if (jsdoc)
92
+ return { present: true, loc: jsdoc.comment.loc };
93
+ return { present: false, loc: null };
94
+ }
95
+ // Check @Minimum/@Maximum range
96
+ const minimum = getConstraintValue("Minimum");
97
+ const maximum = getConstraintValue("Maximum");
98
+ if (minimum && maximum && minimum.value > maximum.value) {
99
+ context.report({
100
+ loc: minimum.loc,
101
+ messageId: "minimumGreaterThanMaximum",
102
+ data: {
103
+ min: String(minimum.value),
104
+ max: String(maximum.value),
105
+ },
106
+ });
107
+ }
108
+ // Check @ExclusiveMinimum/@ExclusiveMaximum range
109
+ const exclusiveMin = getConstraintValue("ExclusiveMinimum");
110
+ const exclusiveMax = getConstraintValue("ExclusiveMaximum");
111
+ if (exclusiveMin && exclusiveMax && exclusiveMin.value >= exclusiveMax.value) {
112
+ context.report({
113
+ loc: exclusiveMin.loc,
114
+ messageId: "exclusiveMinGreaterOrEqualMax",
115
+ data: {
116
+ min: String(exclusiveMin.value),
117
+ max: String(exclusiveMax.value),
118
+ },
119
+ });
120
+ }
121
+ // Check @MinLength/@MaxLength range
122
+ const minLength = getConstraintValue("MinLength");
123
+ const maxLength = getConstraintValue("MaxLength");
124
+ if (minLength && maxLength && minLength.value > maxLength.value) {
125
+ context.report({
126
+ loc: minLength.loc,
127
+ messageId: "minLengthGreaterThanMaxLength",
128
+ data: {
129
+ min: String(minLength.value),
130
+ max: String(maxLength.value),
131
+ },
132
+ });
133
+ }
134
+ // Check conflicting bound types: @Minimum + @ExclusiveMinimum
135
+ const hasMinimum = hasConstraint("Minimum");
136
+ const hasExclusiveMinimum = hasConstraint("ExclusiveMinimum");
137
+ if (hasMinimum.present && hasExclusiveMinimum.present) {
138
+ context.report({
139
+ loc: hasExclusiveMinimum.loc ?? node.loc,
140
+ messageId: "conflictingMinimumBounds",
141
+ });
142
+ }
143
+ // Check conflicting bound types: @Maximum + @ExclusiveMaximum
144
+ const hasMaximum = hasConstraint("Maximum");
145
+ const hasExclusiveMaximum = hasConstraint("ExclusiveMaximum");
146
+ if (hasMaximum.present && hasExclusiveMaximum.present) {
147
+ context.report({
148
+ loc: hasExclusiveMaximum.loc ?? node.loc,
149
+ messageId: "conflictingMaximumBounds",
150
+ });
151
+ }
152
+ // Check @ExclusiveMinimum(m) + @Maximum(n) where n <= m
153
+ if (exclusiveMin && maximum && maximum.value <= exclusiveMin.value) {
154
+ context.report({
155
+ loc: maximum.loc,
156
+ messageId: "maximumLessOrEqualExclusiveMin",
157
+ data: {
158
+ min: String(exclusiveMin.value),
159
+ max: String(maximum.value),
160
+ },
161
+ });
162
+ }
163
+ // Check @ExclusiveMaximum(n) where n <= @Minimum(m)
164
+ if (minimum && exclusiveMax && exclusiveMax.value <= minimum.value) {
165
+ context.report({
166
+ loc: exclusiveMax.loc,
167
+ messageId: "exclusiveMaxLessOrEqualMin",
168
+ data: {
169
+ min: String(minimum.value),
170
+ max: String(exclusiveMax.value),
171
+ },
172
+ });
173
+ }
174
+ },
175
+ };
176
+ },
177
+ });
178
+ //# sourceMappingURL=consistent-constraints.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consistent-constraints.js","sourceRoot":"","sources":["../../src/rules/consistent-constraints.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Rule: constraints/allowed-field-types
3
+ *
4
+ * Validates that field types used in the Chain DSL are allowed by the
5
+ * project's constraint configuration.
6
+ *
7
+ * Works with: field.text(), field.number(), field.boolean(), field.enum(),
8
+ * field.dynamicEnum(), field.dynamicSchema(), field.array(), field.object()
9
+ */
10
+ import { ESLintUtils } from "@typescript-eslint/utils";
11
+ import { type FieldTypeConstraints } from "@formspec/constraints/browser";
12
+ export type Options = [FieldTypeConstraints];
13
+ export declare const allowedFieldTypes: ESLintUtils.RuleModule<"disallowedFieldType", Options, unknown, ESLintUtils.RuleListener> & {
14
+ name: string;
15
+ };
16
+ //# sourceMappingURL=allowed-field-types.d.ts.map