pro-editor-schema 0.2.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/README.md +98 -44
- package/dist/index.js +2 -2
- package/dist/index.mjs +2 -2
- package/package.json +7 -2
package/README.md
CHANGED
|
@@ -7,41 +7,64 @@ TypeScript library that defines XML/HTML schema rules used by the editor and pro
|
|
|
7
7
|
- Schema definitions for supported tags and schema codes.
|
|
8
8
|
- Shared schema constants and attribute helpers.
|
|
9
9
|
- Runtime schema lookup utilities.
|
|
10
|
-
- XML validation utilities (`validateXml
|
|
10
|
+
- XML validation utilities (`validateXml` and related validators).
|
|
11
11
|
- Type-safe element factory (`createElement`) based on schema definitions.
|
|
12
12
|
|
|
13
|
-
## Install
|
|
13
|
+
## Install
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
npm install
|
|
17
|
-
npm run typecheck
|
|
18
|
-
npm run test
|
|
19
|
-
npm run build
|
|
20
17
|
```
|
|
21
18
|
|
|
19
|
+
## Scripts
|
|
20
|
+
|
|
21
|
+
| Command | Description |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| `npm run dev` | Build in watch mode |
|
|
24
|
+
| `npm run build` | Build CJS, ESM, and type declarations |
|
|
25
|
+
| `npm run typecheck` | Run TypeScript without emitting files |
|
|
26
|
+
| `npm run lint` | Run ESLint on `src/` |
|
|
27
|
+
| `npm run test` | Run tests once with Vitest |
|
|
28
|
+
| `npm run test:watch` | Run tests in watch mode |
|
|
29
|
+
| `npm run check` | Run the full verification pipeline (`npm ci`, `typecheck`, `lint`, `test`, `build`) |
|
|
30
|
+
|
|
31
|
+
For local development, `npm run check` is the fastest way to verify everything before pushing.
|
|
32
|
+
|
|
33
|
+
## CI
|
|
34
|
+
|
|
35
|
+
GitHub Actions runs on push and pull requests to `main` / `master`:
|
|
36
|
+
|
|
37
|
+
- **Typecheck** — `npm run typecheck`
|
|
38
|
+
- **Lint** — `npm run lint`
|
|
39
|
+
- **Test** — `npm test`
|
|
40
|
+
|
|
41
|
+
Workflow file: `.github/workflows/ci.yml`
|
|
42
|
+
|
|
22
43
|
## Project structure
|
|
23
44
|
|
|
24
|
-
- `src/index.ts
|
|
25
|
-
- `src/schema/schema.types.ts
|
|
26
|
-
- `src/schema/schemas.ts
|
|
27
|
-
- `src/schema/elementSchemas/elements
|
|
28
|
-
- `src/schema/elementSchemas/atoms
|
|
29
|
-
- `src/schema/elementSchemas/inlineElements
|
|
30
|
-
- `src/schema/shared
|
|
31
|
-
- `src/schema/utils
|
|
32
|
-
- `src/validation
|
|
45
|
+
- `src/index.ts` — public exports for schemas, types, shared constants, and validation.
|
|
46
|
+
- `src/schema/schema.types.ts` — core schema and validation-related types.
|
|
47
|
+
- `src/schema/schemas.ts` — central `SCHEMAS` map (`code -> schema`).
|
|
48
|
+
- `src/schema/elementSchemas/elements` — element schema definitions and `ELEMENT_SCHEMAS`.
|
|
49
|
+
- `src/schema/elementSchemas/atoms` — atom schema definitions and `ATOM_SCHEMAS`.
|
|
50
|
+
- `src/schema/elementSchemas/inlineElements` — inline schema definitions and `INLINE_ELEMENT_SCHEMAS`.
|
|
51
|
+
- `src/schema/shared` — shared attribute and ignored-node constants.
|
|
52
|
+
- `src/schema/utils` — schema lookup, element creation, and label helpers.
|
|
53
|
+
- `src/validation` — document validation entrypoint and validation modules.
|
|
54
|
+
- `src/**/*.test.ts` — Vitest test files (run with `happy-dom`).
|
|
33
55
|
|
|
34
56
|
## Schema model
|
|
35
57
|
|
|
36
58
|
Each schema defines:
|
|
37
59
|
|
|
38
|
-
- `code
|
|
39
|
-
- `kind
|
|
40
|
-
- `tag
|
|
41
|
-
- `requiredAttributes
|
|
42
|
-
- `optionalAttributes
|
|
43
|
-
- `defaultChildCode
|
|
44
|
-
- `allowedChildrenCodes
|
|
60
|
+
- `code` — internal schema identifier.
|
|
61
|
+
- `kind` — schema category (`element`, `atom`, `inline`).
|
|
62
|
+
- `tag` — uppercase XML tag name used in documents.
|
|
63
|
+
- `requiredAttributes` — required attributes (free or restricted values).
|
|
64
|
+
- `optionalAttributes` — optional attributes (free or restricted values).
|
|
65
|
+
- `defaultChildCode` — preferred child tag (optional, used by some block-like schemas).
|
|
66
|
+
- `allowedChildrenCodes` — allowed child tags and whether each child is required.
|
|
67
|
+
- `matchesElement` — optional predicate to resolve elements that share the same tag (for example `SPAN`, `SECTION1`).
|
|
45
68
|
|
|
46
69
|
Schemas are combined in `SCHEMAS` from:
|
|
47
70
|
|
|
@@ -49,15 +72,29 @@ Schemas are combined in `SCHEMAS` from:
|
|
|
49
72
|
- `ATOM_SCHEMAS`
|
|
50
73
|
- `INLINE_ELEMENT_SCHEMAS`
|
|
51
74
|
|
|
75
|
+
### Resolving schemas from DOM elements
|
|
76
|
+
|
|
77
|
+
`findSchemaByElement` matches by tag name. When multiple schemas share a tag, the first schema with a matching `matchesElement` predicate wins.
|
|
78
|
+
|
|
79
|
+
Examples:
|
|
80
|
+
|
|
81
|
+
- `SPAN` with class `ins` → `insertion`
|
|
82
|
+
- `SPAN` with class `del` → `deletion`
|
|
83
|
+
- `SPAN` with class `cmtQurySection` → `commentQuerySection`
|
|
84
|
+
- `SECTION1` with `role="H1"` → `heading`
|
|
85
|
+
- `SECTION1` with `role="ch"` or a `FOOTNOTE` child → `footnoteSection`
|
|
86
|
+
|
|
87
|
+
When adding a new schema that reuses an existing tag, define `matchesElement` on every schema that shares that tag.
|
|
88
|
+
|
|
52
89
|
## Public API highlights
|
|
53
90
|
|
|
54
91
|
From `src/index.ts`, consumers can import:
|
|
55
92
|
|
|
56
|
-
- Types
|
|
57
|
-
- Maps
|
|
58
|
-
- Utilities
|
|
59
|
-
-
|
|
60
|
-
- Shared constants
|
|
93
|
+
- **Types:** `Schema`, `SchemaCode`, `ElementSchemaCode`, `AtomSchemaCode`, `InlineSchemaCode`, `ValidationError`
|
|
94
|
+
- **Maps:** `SCHEMAS`, `ELEMENT_SCHEMAS`, `ATOM_SCHEMAS`, `INLINE_ELEMENT_SCHEMAS`
|
|
95
|
+
- **Utilities:** `findSchemaByCode`, `findSchemaByElement`, `createElement`, `ElementLabel`
|
|
96
|
+
- **Validation:** `validateXml`
|
|
97
|
+
- **Shared constants:** ignored elements/attributes, global attribute constants, dependents forbidden elements
|
|
61
98
|
|
|
62
99
|
## Usage examples
|
|
63
100
|
|
|
@@ -79,7 +116,6 @@ const para = createElement({
|
|
|
79
116
|
attributes: {
|
|
80
117
|
store: "body",
|
|
81
118
|
"ele-id": "p-1",
|
|
82
|
-
role: "body",
|
|
83
119
|
},
|
|
84
120
|
});
|
|
85
121
|
```
|
|
@@ -89,23 +125,41 @@ const para = createElement({
|
|
|
89
125
|
```ts
|
|
90
126
|
import { validateXml } from "pro-editor-schema";
|
|
91
127
|
|
|
92
|
-
const errors = validateXml(
|
|
128
|
+
const errors = validateXml(
|
|
129
|
+
rootElement,
|
|
130
|
+
elementsToLink,
|
|
131
|
+
linkElements,
|
|
132
|
+
["para", "heading"],
|
|
133
|
+
);
|
|
93
134
|
```
|
|
94
135
|
|
|
95
|
-
`validateXml`
|
|
136
|
+
`validateXml` parameters:
|
|
137
|
+
|
|
138
|
+
- `xml` — root element to validate.
|
|
139
|
+
- `elementsToLink` — IDs available as `linkend` targets.
|
|
140
|
+
- `linkElements` — IDs cited by links (used for reference validation).
|
|
141
|
+
- `schemasToValidateAgainst` — schema codes to run attribute/child validation against.
|
|
142
|
+
|
|
143
|
+
`validateXml` always runs:
|
|
144
|
+
|
|
145
|
+
- Consecutive footnote number checks
|
|
146
|
+
- Consecutive footnote cue checks
|
|
147
|
+
|
|
148
|
+
It also runs per-element checks for:
|
|
149
|
+
|
|
150
|
+
- Link targets (`linkend`) on linkable elements
|
|
151
|
+
- Uncited bibliographic references
|
|
152
|
+
- Unreferenced footnotes
|
|
96
153
|
|
|
97
|
-
-
|
|
98
|
-
- Footnote cue sequence checks
|
|
99
|
-
- Link target checks (`linkend`)
|
|
100
|
-
- Optional schema-based attribute and child validation when enabled
|
|
154
|
+
Schema-based attribute and child validation only runs for codes listed in `schemasToValidateAgainst`.
|
|
101
155
|
|
|
102
156
|
## How validation works
|
|
103
157
|
|
|
104
158
|
- `validateXml` traverses the XML tree and delegates checks per element.
|
|
105
|
-
- `findSchemaByElement` resolves schema from
|
|
106
|
-
- `validateAttributes`
|
|
159
|
+
- `findSchemaByElement` resolves schema from tag and optional `matchesElement`.
|
|
160
|
+
- `validateAttributes` validates restricted attribute values.
|
|
107
161
|
- `validateChildren` ensures child tags are allowed and required children exist.
|
|
108
|
-
- `validateFootnotes` and `
|
|
162
|
+
- `validateFootnotes`, `validateLinkend`, and `validateReferenceCited` provide cross-reference integrity checks.
|
|
109
163
|
|
|
110
164
|
Validation results use `ValidationError`:
|
|
111
165
|
|
|
@@ -118,23 +172,23 @@ Validation results use `ValidationError`:
|
|
|
118
172
|
|
|
119
173
|
## Adding or updating a schema
|
|
120
174
|
|
|
121
|
-
1. Create or update schema file in one of:
|
|
175
|
+
1. Create or update a schema file in one of:
|
|
122
176
|
- `src/schema/elementSchemas/elements`
|
|
123
177
|
- `src/schema/elementSchemas/atoms`
|
|
124
178
|
- `src/schema/elementSchemas/inlineElements`
|
|
125
|
-
2. Define schema with `createSchema(...)`.
|
|
126
|
-
3.
|
|
179
|
+
2. Define the schema with `createSchema(...)`.
|
|
180
|
+
3. If the tag is already used by another schema, add a `matchesElement` predicate.
|
|
181
|
+
4. Register it in the corresponding map:
|
|
127
182
|
- `ELEMENT_SCHEMAS`
|
|
128
183
|
- `ATOM_SCHEMAS`
|
|
129
184
|
- `INLINE_ELEMENT_SCHEMAS`
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
- `npm run typecheck`
|
|
134
|
-
- `npm run test`
|
|
185
|
+
5. Ensure the schema code exists in the matching union type in `schema.types.ts`.
|
|
186
|
+
6. Add or update tests for any new validation or utility behavior.
|
|
187
|
+
7. Run `npm run check`.
|
|
135
188
|
|
|
136
189
|
## Notes
|
|
137
190
|
|
|
138
191
|
- Tag matching is done in uppercase in schema definitions and validation.
|
|
139
192
|
- Some schema codes represent block/group-like structures while still being typed as `kind: "element"` in the current model.
|
|
140
193
|
- Ignored attributes and ignored UI helper elements are excluded from strict validation by design.
|
|
194
|
+
- Track-changes atoms (`insertion`, `deletion`) are unwrapped when validating required children.
|
package/dist/index.js
CHANGED
|
@@ -2371,7 +2371,7 @@ var isIgnoredValidation = (code) => IGNORED_VALIDATION_ELEMENT_SELECTORS.include
|
|
|
2371
2371
|
var findSchemaByCode = (code) => SCHEMAS[code];
|
|
2372
2372
|
var findSchemaByElement = (element) => {
|
|
2373
2373
|
const schema = Object.values(SCHEMAS).find(
|
|
2374
|
-
(schema2) => schema2.tag == element.tagName && schema2.matchesElement
|
|
2374
|
+
(schema2) => schema2.tag == element.tagName && (!schema2.matchesElement || schema2.matchesElement(element))
|
|
2375
2375
|
);
|
|
2376
2376
|
return schema;
|
|
2377
2377
|
};
|
|
@@ -2400,7 +2400,7 @@ var createElement = ({
|
|
|
2400
2400
|
return element;
|
|
2401
2401
|
};
|
|
2402
2402
|
|
|
2403
|
-
// src/schema/
|
|
2403
|
+
// src/schema/shared/labelElements.ts
|
|
2404
2404
|
var ElementLabel = {
|
|
2405
2405
|
referenceBibliomixed: "Reference Bibliomixed",
|
|
2406
2406
|
referenceBibliography: "Reference Bibliography",
|
package/dist/index.mjs
CHANGED
|
@@ -2303,7 +2303,7 @@ var isIgnoredValidation = (code) => IGNORED_VALIDATION_ELEMENT_SELECTORS.include
|
|
|
2303
2303
|
var findSchemaByCode = (code) => SCHEMAS[code];
|
|
2304
2304
|
var findSchemaByElement = (element) => {
|
|
2305
2305
|
const schema = Object.values(SCHEMAS).find(
|
|
2306
|
-
(schema2) => schema2.tag == element.tagName && schema2.matchesElement
|
|
2306
|
+
(schema2) => schema2.tag == element.tagName && (!schema2.matchesElement || schema2.matchesElement(element))
|
|
2307
2307
|
);
|
|
2308
2308
|
return schema;
|
|
2309
2309
|
};
|
|
@@ -2332,7 +2332,7 @@ var createElement = ({
|
|
|
2332
2332
|
return element;
|
|
2333
2333
|
};
|
|
2334
2334
|
|
|
2335
|
-
// src/schema/
|
|
2335
|
+
// src/schema/shared/labelElements.ts
|
|
2336
2336
|
var ElementLabel = {
|
|
2337
2337
|
referenceBibliomixed: "Reference Bibliomixed",
|
|
2338
2338
|
referenceBibliography: "Reference Bibliography",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pro-editor-schema",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Pro Editor XML schemas",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -19,13 +19,18 @@
|
|
|
19
19
|
"build": "tsup src/index.ts --format cjs,esm --dts",
|
|
20
20
|
"dev": "tsup src/index.ts --format cjs,esm --dts --watch",
|
|
21
21
|
"typecheck": "tsc --noEmit",
|
|
22
|
+
"lint": "eslint src",
|
|
22
23
|
"test": "vitest run",
|
|
23
|
-
"test:watch": "vitest"
|
|
24
|
+
"test:watch": "vitest",
|
|
25
|
+
"check": "npm ci && npm run typecheck && npm run lint && npm run test && npm run build"
|
|
24
26
|
},
|
|
25
27
|
"devDependencies": {
|
|
28
|
+
"@eslint/js": "^10.0.1",
|
|
29
|
+
"eslint": "^10.6.0",
|
|
26
30
|
"happy-dom": "^20.0.10",
|
|
27
31
|
"tsup": "^8.0.0",
|
|
28
32
|
"typescript": "^5.0.0",
|
|
33
|
+
"typescript-eslint": "^8.62.1",
|
|
29
34
|
"vitest": "^3.2.4"
|
|
30
35
|
}
|
|
31
36
|
}
|