@markuplint/ml-spec 4.9.6 → 4.9.7

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 (3) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +237 -8
  3. package/package.json +12 -13
package/CHANGELOG.md CHANGED
@@ -3,6 +3,12 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ ## [4.9.7](https://github.com/markuplint/markuplint/compare/@markuplint/ml-spec@4.9.6...@markuplint/ml-spec@4.9.7) (2025-08-13)
7
+
8
+ ### Bug Fixes
9
+
10
+ - ensure that each `clean` command correctly removes build files ([110b78e](https://github.com/markuplint/markuplint/commit/110b78e85379d29a84ca68325127344a87a570b6))
11
+
6
12
  ## [4.9.6](https://github.com/markuplint/markuplint/compare/@markuplint/ml-spec@4.9.5...@markuplint/ml-spec@4.9.6) (2025-04-13)
7
13
 
8
14
  **Note:** Version bump only for package @markuplint/ml-spec
package/README.md CHANGED
@@ -2,17 +2,246 @@
2
2
 
3
3
  [![npm version](https://badge.fury.io/js/%40markuplint%2Fml-spec.svg)](https://www.npmjs.com/package/@markuplint/ml-spec)
4
4
 
5
- ## Install
5
+ This package provides the HTML Schema (aka "Specs") shape definitions and utilities used by
6
+ markuplint, plus the generated TypeScript types derived from those schemas. The canonical HTML
7
+ element spec data itself is aggregated in `@markuplint/html-spec`.
6
8
 
7
- [`markuplint`](https://www.npmjs.com/package/markuplint) package includes this package.
9
+ ### Install
8
10
 
9
- <details>
10
- <summary>If you are installing purposely, how below:</summary>
11
+ `markuplint` already bundles this package. If you need to install it explicitly:
11
12
 
12
- ```shell
13
- $ npm install @markuplint/ml-spec
13
+ ```bash
14
+ npm install @markuplint/ml-spec
15
+ # or
16
+ yarn add @markuplint/ml-spec
17
+ ```
18
+
19
+ ### Terminology
20
+
21
+ - "HTML Schema" and "Specs" are used interchangeably in markuplint to mean the JSON Schema that
22
+ describes HTML element specs (attributes, ARIA, content models, etc) and their TypeScript types.
23
+
24
+ ### What’s in this package
25
+
26
+ - JSON Schemas (shape definitions):
27
+ - `schemas/element.schema.json`
28
+ - `schemas/aria.schema.json`
29
+ - `schemas/content-models.schema.json`
30
+ - `schemas/global-attributes.schema.json` (generated)
31
+ - `schemas/attributes.schema.json` (generated)
32
+ - Generated TypeScript types (do not edit):
33
+ - `src/types/attributes.ts`
34
+ - `src/types/aria.ts`
35
+ - `src/types/permitted-structures.ts`
36
+ - Schema generators:
37
+ - `gen/gen.ts` … builds `global-attributes.schema.json` and `attributes.schema.json`
38
+ - Global attribute categories data: `gen/global-attribute.data.*`
39
+ - Spec merger (runtime behavior):
40
+ - `src/specs/schema-to-spec.ts` … merges the main HTML spec with
41
+ extended specs provided by other packages (e.g. Vue/React/Svelte specs)
42
+
43
+ Note: Attribute value types are defined in `@markuplint/types`. The schemas here reference
44
+ `@markuplint/types/types.schema.json`.
45
+
46
+ ### Where is the base HTML spec data?
47
+
48
+ - Base HTML element specs live in `packages/@markuplint/html-spec/`:
49
+ - Built output: `packages/@markuplint/html-spec/index.json`
50
+ - Sources: `packages/@markuplint/html-spec/src/spec-*.json`
51
+ - Build script: `packages/@markuplint/html-spec/build.mjs` (invokes `@markuplint/spec-generator`)
52
+ - This `@markuplint/ml-spec` package defines the JSON Schema shapes and the merging logic that
53
+ consume that data, but does not contain the canonical HTML element dataset.
54
+
55
+ ### Editing workflow (HTML Schema/Specs)
56
+
57
+ 1. Make changes to the schemas
58
+
59
+ - Attributes schema shape: update `gen/gen.ts` if you need to change the structure of
60
+ `AttributeJSON`/`GlobalAttributes` (because `attributes.schema.json` is generated).
61
+ - ARIA schema shape: edit `schemas/aria.schema.json`.
62
+ - Content model schema shape: edit `schemas/content-models.schema.json`.
63
+ - Element schema aggregator: edit `schemas/element.schema.json` (it composes refs to the above).
64
+ - Global attribute categories/sets: edit `gen/global-attribute.data.*`, then regenerate via the commands below.
65
+
66
+ If you want to change the concrete HTML element data (e.g., add/update element- or attribute-level
67
+ entries), update `@markuplint/html-spec` (and, if necessary, `@markuplint/spec-generator`).
68
+
69
+ 2. Regenerate schemas and types
70
+
71
+ From the repository root (recommended):
72
+
73
+ ```bash
74
+ yarn up:schema
75
+ ```
76
+
77
+ or only for this package:
78
+
79
+ ```bash
80
+ yarn workspace @markuplint/ml-spec run schema
81
+ ```
82
+
83
+ This will:
84
+
85
+ - Run `gen/gen.ts` to output `global-attributes.schema.json` and `attributes.schema.json`
86
+ - Convert JSON Schema to TypeScript via `json2ts` into `src/types/*.ts`
87
+ - Format with Prettier and ESLint
88
+
89
+ #### What `yarn up:schema` does
90
+
91
+ From the repository root, this executes schema maintenance across packages in order:
92
+
93
+ 1. `@markuplint/types`
94
+
95
+ - Run `gen/types.ts` to build `types.schema.json` from css-tree keywords/types and
96
+ `gen/specific-schema.json`
97
+ - Generate TypeScript types: `types.schema.json` → `src/types.schema.ts` (via `json2ts`)
98
+ - Format (`prettier`/`eslint`) and build the package
99
+
100
+ 2. `@markuplint/ml-spec` (this package)
101
+
102
+ - Run `gen/gen.ts` to output `schemas/global-attributes.schema.json` and `schemas/attributes.schema.json`
103
+ - Generate TypeScript types from schemas:
104
+ - `schemas/content-models.schema.json` → `src/types/permitted-structures.ts`
105
+ - `schemas/attributes.schema.json` → `src/types/attributes.ts`
106
+ - `schemas/aria.schema.json` → `src/types/aria.ts`
107
+ - Format (`prettier`/`eslint`)
108
+
109
+ Dependency note: `schemas/attributes.schema.json` references
110
+ `@markuplint/types/types.schema.json#/definitions/type`. Updating types first ensures references stay
111
+ consistent; `yarn up:schema` takes care of this order.
112
+
113
+ 3. Build (optional) and sanity-check
114
+
115
+ ```bash
116
+ yarn build
117
+ ```
14
118
 
15
- $ yarn add @markuplint/ml-spec
119
+ ### Do not edit generated files
120
+
121
+ - Do not modify files under `src/types/*.ts` or `schemas/attributes.schema.json` directly.
122
+ Change the source schema or generator instead and re-run the generation scripts.
123
+
124
+ ### How schema merging works (Specs extension)
125
+
126
+ At runtime, markuplint can merge multiple specs. The merger in
127
+ `src/specs/schema-to-spec.ts` follows these rules:
128
+
129
+ - `def.#globalAttrs.#extends` from an extended spec augments the base `#HTMLGlobalAttrs` map.
130
+ - For a given element, if both base and extended specs define the same attribute, the extended spec
131
+ wins on conflicting fields (shallow override per attribute). Arrays like `categories` are merged.
132
+
133
+ This enables framework-specific specs (Vue/React/Svelte, etc.) to extend the HTML spec safely.
134
+
135
+ ### Relationship to @markuplint/types
136
+
137
+ - Attribute value types (CSS keywords, extended types such as `URL`, `JSON`, etc.) are defined in
138
+ `@markuplint/types` and exposed via `types.schema.json`.
139
+ - If you need a new attribute value type, modify `@markuplint/types` (e.g.
140
+ `packages/@markuplint/types/gen/specific-schema.json`) and regenerate that package first. Then
141
+ regenerate this package so references stay consistent.
142
+
143
+ ### Versioning policy
144
+
145
+ - HTML Schema/Specs are not part of the public API surface of markuplint. Changes here are treated
146
+ as a minor release. Publishing is handled by Lerna during the normal release process.
147
+
148
+ ### Common tasks (quick recipes)
149
+
150
+ - Add a new global attribute category or items
151
+ - Edit `gen/global-attribute.data.*`
152
+ - Run the generation script (see above)
153
+
154
+ - Add a new optional field to `AttributeJSON`
155
+ - Update the shape in `gen/gen.ts` under `AttributeJSON`
156
+ - Regenerate and ensure the new field appears in `schemas/attributes.schema.json` and in
157
+ `src/types/attributes.ts`
158
+
159
+ - Adjust ARIA fields (e.g., `permittedRoles` variants)
160
+ - Edit `schemas/aria.schema.json`
161
+ - Regenerate types via the schema scripts
162
+
163
+ ### Content model quick reference
164
+
165
+ Content models describe allowed children for each element. See the JSON Schema
166
+ `schemas/content-models.schema.json` and the generated TS types `src/types/permitted-structures.ts`.
167
+ Also refer to the website docs: [Rule: permitted-contents](https://markuplint.dev/rules/permitted-contents).
168
+
169
+ - Basic categories (strings): `"#flow"`, `"#phrasing"`, `"#interactive"`, …
170
+ - Model item forms:
171
+ - `require` | `optional` | `oneOrMore` | `zeroOrMore`: a string, category, or nested patterns
172
+ - `choice`: 2–5 alternative pattern arrays
173
+ - `transparent`: inherits parent model filtered by selector string
174
+
175
+ Examples:
176
+
177
+ ```json
178
+ {
179
+ "contentModel": {
180
+ "contents": [{ "require": "#phrasing" }, { "optional": [{ "oneOrMore": "#interactive" }] }]
181
+ }
182
+ }
183
+ ```
184
+
185
+ Transparent selector syntax
186
+
187
+ - A CSS-like selector string with an extra pseudo: `:model(<CATEGORY>)`
188
+ - You can combine standard selectors: type, class, id, attribute selectors, `:not(...)`, `:has(...)`,
189
+ combinators, etc.
190
+ - `:model(<CATEGORY>)` matches any element belonging to the specified content category.
191
+
192
+ Examples:
193
+
194
+ ```text
195
+ :not(:model(interactive))
196
+ :has(:model(interactive), a, [tabindex])
16
197
  ```
17
198
 
18
- </details>
199
+ SVG categories
200
+
201
+ The following categories are available for SVG elements (see `schemas/content-models.schema.json`):
202
+
203
+ - `#SVGAnimation`
204
+ - `#SVGBasicShapes`
205
+ - `#SVGContainer`
206
+ - `#SVGDescriptive`
207
+ - `#SVGFilterPrimitive`
208
+ - `#SVGFont`
209
+ - `#SVGGradient`
210
+ - `#SVGGraphics`
211
+ - `#SVGGraphicsReferencing`
212
+ - `#SVGLightSource`
213
+ - `#SVGNeverRendered`
214
+ - `#SVGNone`
215
+ - `#SVGPaintServer`
216
+ - `#SVGRenderable`
217
+ - `#SVGShape`
218
+ - `#SVGStructural`
219
+ - `#SVGStructurallyExternal`
220
+ - `#SVGTextContent`
221
+ - `#SVGTextContentChild`
222
+
223
+ ```json
224
+ {
225
+ "contentModel": {
226
+ "contents": [{ "choice": [[{ "oneOrMore": "#flow" }], [{ "require": "#phrasing" }]] }]
227
+ }
228
+ }
229
+ ```
230
+
231
+ ```json
232
+ {
233
+ "contentModel": {
234
+ "contents": [{ "transparent": ":not(:model(interactive))" }],
235
+ "conditional": [
236
+ {
237
+ "condition": "[type=button]",
238
+ "contents": [{ "require": "#phrasing" }]
239
+ }
240
+ ]
241
+ }
242
+ }
243
+ ```
244
+
245
+ ### License
246
+
247
+ MIT
package/package.json CHANGED
@@ -1,11 +1,10 @@
1
1
  {
2
2
  "name": "@markuplint/ml-spec",
3
- "version": "4.9.6",
3
+ "version": "4.9.7",
4
4
  "description": "Types and schema that specs of the Markup languages for markuplint",
5
5
  "repository": "git@github.com:markuplint/markuplint.git",
6
6
  "author": "Yusuke Hirao <yusukehirao@me.com>",
7
7
  "license": "MIT",
8
- "private": false,
9
8
  "type": "module",
10
9
  "exports": {
11
10
  ".": {
@@ -22,25 +21,25 @@
22
21
  "scripts": {
23
22
  "build": "tsc --project tsconfig.build.json",
24
23
  "dev": "tsc --watch --project tsconfig.build.json",
25
- "clean": "tsc --build --clean",
24
+ "clean": "tsc --build --clean tsconfig.build.json",
26
25
  "schema": "run-s schema:json schema:content-models schema:attributes schema:aria schema:prettier schema:eslint schema:prettier",
27
26
  "schema:json": "tsx ./gen/gen.ts",
28
- "schema:content-models": "json2ts ./schemas/content-models.schema.json > ./src/types/permitted-structures.ts",
29
- "schema:attributes": "json2ts ./schemas/attributes.schema.json --cwd ./schemas > ./src/types/attributes.ts",
30
- "schema:aria": "json2ts ./schemas/aria.schema.json --cwd ./schemas > ./src/types/aria.ts",
31
- "schema:eslint": "eslint --fix \"./src/types/*.ts\"",
32
- "schema:prettier": "prettier --write \"./schemas/*.json\" \"./src/types/*.ts\" --log-level warn"
27
+ "schema:content-models": "npx json2ts ./schemas/content-models.schema.json > ./src/types/permitted-structures.ts",
28
+ "schema:attributes": "npx json2ts ./schemas/attributes.schema.json --cwd ./schemas > ./src/types/attributes.ts",
29
+ "schema:aria": "npx json2ts ./schemas/aria.schema.json --cwd ./schemas > ./src/types/aria.ts",
30
+ "schema:eslint": "npx eslint --fix \"./src/types/*.ts\"",
31
+ "schema:prettier": "npx prettier --write \"./schemas/*.json\" \"./src/types/*.ts\" --log-level warn"
33
32
  },
34
33
  "dependencies": {
35
- "@markuplint/ml-ast": "4.4.9",
36
- "@markuplint/types": "4.7.6",
34
+ "@markuplint/ml-ast": "4.4.10",
35
+ "@markuplint/types": "4.7.7",
37
36
  "dom-accessibility-api": "0.7.0",
38
37
  "is-plain-object": "5.0.0",
39
- "type-fest": "4.39.1"
38
+ "type-fest": "4.41.0"
40
39
  },
41
40
  "devDependencies": {
42
- "@markuplint/test-tools": "4.5.19",
41
+ "@markuplint/test-tools": "4.5.20",
43
42
  "json-schema-to-typescript": "15.0.4"
44
43
  },
45
- "gitHead": "eb36d59f7e13d4e59ff3f3c4eabb5ec06c070eb0"
44
+ "gitHead": "acbf53f7e30d7a59f850a0f279b617383266dab3"
46
45
  }