@formspec/constraints 0.1.0-alpha.17 → 0.1.0-alpha.19

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 (2) hide show
  1. package/README.md +29 -233
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,263 +1,59 @@
1
1
  # @formspec/constraints
2
2
 
3
- Define and enforce constraints on which FormSpec DSL features are allowed in your project.
3
+ Constraint configuration and validation for FormSpec DSL usage.
4
4
 
5
- ## Overview
5
+ Use this package when you want project-level rules such as:
6
6
 
7
- The constraints package lets you restrict which parts of the FormSpec DSL can be used. This is useful for:
7
+ - disallowing certain field types
8
+ - limiting layout nesting
9
+ - restricting selected field options
10
+ - validating `.formspec.yml`-driven capability policies
8
11
 
9
- - **Standardization**: Enforce consistent form patterns across a team
10
- - **Compatibility**: Restrict to features your renderer supports
11
- - **Simplicity**: Keep forms simple by disallowing complex nesting or conditionals
12
- - **Linting**: Catch constraint violations at development time via ESLint
13
-
14
- ## Installation
12
+ ## Install
15
13
 
16
14
  ```bash
17
- npm install @formspec/constraints
18
- # or
19
15
  pnpm add @formspec/constraints
20
16
  ```
21
17
 
22
- ## Configuration
23
-
24
- Create a `.formspec.yml` file in your project root:
18
+ ## `.formspec.yml`
25
19
 
26
20
  ```yaml
27
21
  constraints:
28
22
  fieldTypes:
29
- text: off # Allow text fields
30
- number: off # Allow number fields
31
- boolean: off # Allow boolean fields
32
- staticEnum: off # Allow static enums
33
- dynamicEnum: warn # Warn on dynamic enums
34
- dynamicSchema: error # Disallow dynamic schemas
35
- array: off # Allow arrays
36
- object: off # Allow objects
23
+ dynamicEnum: warn
24
+ dynamicSchema: error
37
25
 
38
26
  layout:
39
- group: off # Allow groups
40
- conditionals: off # Allow when() conditionals
41
- maxNestingDepth: 3 # Max nesting depth (0 = flat only)
27
+ conditionals: off
28
+ maxNestingDepth: 2
42
29
 
43
30
  fieldOptions:
44
- label: off
45
31
  placeholder: off
46
- required: off
47
- minValue: off
48
- maxValue: off
49
- minItems: off
50
- maxItems: off
32
+ minItems: warn
51
33
  ```
52
34
 
53
- ### Severity Levels
54
-
55
- Each constraint can be set to:
56
-
57
- | Severity | Behavior |
58
- | --------- | ---------------------------- |
59
- | `"off"` | Feature is allowed (default) |
60
- | `"warn"` | Emit warning but allow |
61
- | `"error"` | Disallow - fail validation |
62
-
63
- ## Constraint Categories
64
-
65
- ### Field Types (`fieldTypes`)
66
-
67
- Control which DSL field builders are allowed:
35
+ ## Programmatic Use
68
36
 
69
- | Constraint | DSL Function |
70
- | --------------- | -------------------------------------------- |
71
- | `text` | `field.text()` |
72
- | `number` | `field.number()` |
73
- | `boolean` | `field.boolean()` |
74
- | `staticEnum` | `field.enum()` |
75
- | `dynamicEnum` | `field.dynamicEnum()` |
76
- | `dynamicSchema` | `field.dynamicSchema()` |
77
- | `array` | `field.array()`, `field.arrayWithConfig()` |
78
- | `object` | `field.object()`, `field.objectWithConfig()` |
37
+ ```ts
38
+ import { loadConfig, mergeWithDefaults, validateFormSpecElements } from "@formspec/constraints";
39
+ import { field, formspec } from "@formspec/dsl";
79
40
 
80
- ### Layout (`layout`)
81
-
82
- Control structure and nesting:
83
-
84
- | Constraint | Description |
85
- | ----------------- | --------------------------------------- |
86
- | `group` | `group()` visual grouping |
87
- | `conditionals` | `when()` conditional visibility |
88
- | `maxNestingDepth` | Maximum depth for nested objects/arrays |
89
-
90
- ### Field Options (`fieldOptions`)
91
-
92
- Control which field configuration options are allowed:
93
-
94
- | Constraint | Description |
95
- | ---------------------- | ------------------------- |
96
- | `label` | Field label text |
97
- | `placeholder` | Input placeholder |
98
- | `required` | Required field validation |
99
- | `minValue`, `maxValue` | Number field constraints |
100
- | `minItems`, `maxItems` | Array length constraints |
101
-
102
- ### UI Schema (`uiSchema`)
103
-
104
- Control JSON Forms-specific features:
105
-
106
- ```yaml
107
- constraints:
108
- uiSchema:
109
- layouts:
110
- VerticalLayout: off
111
- HorizontalLayout: off
112
- Group: off
113
- Categorization: error # Disallow tabbed interfaces
114
- Category: error
115
- rules:
116
- enabled: off
117
- effects:
118
- SHOW: off
119
- HIDE: off
120
- ENABLE: warn
121
- DISABLE: warn
122
- ```
123
-
124
- ## Programmatic Usage
125
-
126
- ### Loading Configuration
127
-
128
- ```typescript
129
- import { loadConfig, mergeWithDefaults } from "@formspec/constraints";
130
-
131
- // Load from .formspec.yml (searches up directory tree)
132
- const config = await loadConfig();
133
-
134
- // Or load from specific path
135
- const config = await loadConfig("/path/to/.formspec.yml");
136
-
137
- // Merge with defaults to get fully resolved config
41
+ const { config } = await loadConfig();
138
42
  const resolved = mergeWithDefaults(config.constraints);
139
- ```
140
43
 
141
- ### Validating Forms
142
-
143
- ```typescript
144
- import { validateFormSpec } from "@formspec/constraints";
145
- import { formspec, field, when, is } from "@formspec/dsl";
146
-
147
- const form = formspec(
148
- field.text("name"),
149
- field.dynamicEnum("country", "fetch_countries"),
150
- when(is("country", "US"), field.text("state"))
151
- );
152
-
153
- const result = validateFormSpec(form, resolved);
154
-
155
- if (!result.valid) {
156
- for (const issue of result.issues) {
157
- console.log(`${issue.severity}: ${issue.message}`);
158
- }
159
- }
44
+ const form = formspec(field.text("name"), field.dynamicEnum("country", "countries"));
45
+ const result = validateFormSpecElements(form.elements, { constraints: resolved });
160
46
  ```
161
47
 
162
- ### Validation Result
48
+ ## Main Exports
163
49
 
164
- ```typescript
165
- interface ValidationResult {
166
- valid: boolean; // true if no errors (warnings OK)
167
- issues: ValidationIssue[];
168
- }
50
+ - `loadConfig`
51
+ - `loadConfigFromString`
52
+ - `defineConstraints`
53
+ - `mergeWithDefaults`
54
+ - `validateFormSpecElements`
55
+ - `validateFormSpec`
169
56
 
170
- interface ValidationIssue {
171
- code: string; // e.g., "FIELD_TYPE_NOT_ALLOWED"
172
- message: string; // Human-readable description
173
- severity: "error" | "warning";
174
- category: "fieldTypes" | "layout" | "uiSchema" | "fieldOptions" | "controlOptions";
175
- path?: string; // JSON pointer to issue location
176
- fieldName?: string; // Affected field name
177
- fieldType?: string; // Affected field type
178
- }
179
- ```
57
+ ## License
180
58
 
181
- ## ESLint Integration
182
-
183
- Use `@formspec/eslint-plugin` to catch constraint violations at development time:
184
-
185
- ```javascript
186
- // eslint.config.js
187
- import formspec from "@formspec/eslint-plugin";
188
-
189
- export default [
190
- {
191
- plugins: { formspec },
192
- rules: {
193
- // Enforce allowed field types from .formspec.yml
194
- "formspec/constraints-allowed-field-types": "error",
195
- // Enforce allowed layouts from .formspec.yml
196
- "formspec/constraints-allowed-layouts": "error",
197
- },
198
- },
199
- ];
200
- ```
201
-
202
- The ESLint rules automatically load constraints from your `.formspec.yml` file.
203
-
204
- ## Example Configurations
205
-
206
- ### Simple Forms Only
207
-
208
- Restrict to flat forms with basic field types:
209
-
210
- ```yaml
211
- constraints:
212
- fieldTypes:
213
- array: error
214
- object: error
215
- dynamicEnum: error
216
- dynamicSchema: error
217
- layout:
218
- conditionals: error
219
- maxNestingDepth: 0
220
- ```
221
-
222
- ### JSON Forms Compatible
223
-
224
- Restrict to features supported by standard JSON Forms renderers:
225
-
226
- ```yaml
227
- constraints:
228
- fieldTypes:
229
- dynamicSchema: error # Not supported by JSON Forms
230
- uiSchema:
231
- layouts:
232
- Categorization: warn # May not be supported by all renderers
233
- ```
234
-
235
- ### Warn on Advanced Features
236
-
237
- Allow all features but warn on complex ones:
238
-
239
- ```yaml
240
- constraints:
241
- fieldTypes:
242
- dynamicEnum: warn
243
- dynamicSchema: warn
244
- array: warn
245
- object: warn
246
- layout:
247
- conditionals: warn
248
- maxNestingDepth: 2
249
- ```
250
-
251
- ## JSON Schema
252
-
253
- A JSON Schema for `.formspec.yml` is available for editor autocompletion:
254
-
255
- ```yaml
256
- # .formspec.yml
257
- # yaml-language-server: $schema=node_modules/@formspec/constraints/formspec.schema.json
258
-
259
- constraints:
260
- fieldTypes:
261
- text: off
262
- # ... autocomplete available
263
- ```
59
+ UNLICENSED
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@formspec/constraints",
3
- "version": "0.1.0-alpha.17",
3
+ "version": "0.1.0-alpha.19",
4
4
  "description": "Constraint validation for FormSpec - restrict features based on target environment capabilities",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -26,12 +26,12 @@
26
26
  ],
27
27
  "dependencies": {
28
28
  "yaml": "^2.7.0",
29
- "@formspec/core": "0.1.0-alpha.17"
29
+ "@formspec/core": "0.1.0-alpha.19"
30
30
  },
31
31
  "devDependencies": {
32
32
  "tsd": "^0.31.0",
33
33
  "vitest": "^3.0.0",
34
- "@formspec/dsl": "0.1.0-alpha.17"
34
+ "@formspec/dsl": "0.1.0-alpha.19"
35
35
  },
36
36
  "tsd": {
37
37
  "directory": "src/__tests__"