@likecoin/epubcheck-ts 0.1.0
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/LICENSE +674 -0
- package/README.md +339 -0
- package/dist/index.cjs +1904 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +523 -0
- package/dist/index.d.ts +523 -0
- package/dist/index.js +1895 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
- package/schemas/applications.rng +429 -0
- package/schemas/aria.rng +3355 -0
- package/schemas/block.rng +488 -0
- package/schemas/common.rng +1076 -0
- package/schemas/container.rng +24 -0
- package/schemas/core-scripting.rng +950 -0
- package/schemas/data.rng +161 -0
- package/schemas/datatypes.rng +401 -0
- package/schemas/embed.rng +980 -0
- package/schemas/epub-mathml3-inc.rng +161 -0
- package/schemas/epub-nav-30.rnc +44 -0
- package/schemas/epub-nav-30.rng +19985 -0
- package/schemas/epub-nav-30.sch +87 -0
- package/schemas/epub-prefix-attr.rng +17 -0
- package/schemas/epub-shared-inc.rng +29 -0
- package/schemas/epub-ssml-attrs.rng +17 -0
- package/schemas/epub-svg-30.rnc +17 -0
- package/schemas/epub-svg-30.rng +19903 -0
- package/schemas/epub-svg-30.sch +7 -0
- package/schemas/epub-svg-forgiving-inc.rng +315 -0
- package/schemas/epub-switch.rng +121 -0
- package/schemas/epub-trigger.rng +90 -0
- package/schemas/epub-type-attr.rng +12 -0
- package/schemas/epub-xhtml-30.rnc +6 -0
- package/schemas/epub-xhtml-30.rng +19882 -0
- package/schemas/epub-xhtml-30.sch +409 -0
- package/schemas/epub-xhtml-inc.rng +151 -0
- package/schemas/epub-xhtml-integration.rng +565 -0
- package/schemas/epub-xhtml-svg-mathml.rng +17 -0
- package/schemas/form-datatypes.rng +54 -0
- package/schemas/mathml3-common.rng +336 -0
- package/schemas/mathml3-content.rng +1552 -0
- package/schemas/mathml3-inc.rng +30 -0
- package/schemas/mathml3-presentation.rng +2341 -0
- package/schemas/mathml3-strict-content.rng +205 -0
- package/schemas/media.rng +374 -0
- package/schemas/meta.rng +754 -0
- package/schemas/microdata.rng +192 -0
- package/schemas/ncx.rng +308 -0
- package/schemas/ocf-container-30.rnc +37 -0
- package/schemas/ocf-container-30.rng +568 -0
- package/schemas/opf.rng +15 -0
- package/schemas/opf20.rng +513 -0
- package/schemas/package-30.rnc +133 -0
- package/schemas/package-30.rng +1153 -0
- package/schemas/package-30.sch +444 -0
- package/schemas/phrase.rng +746 -0
- package/schemas/rdfa.rng +552 -0
- package/schemas/revision.rng +106 -0
- package/schemas/ruby.rng +141 -0
- package/schemas/sectional.rng +278 -0
- package/schemas/structural.rng +298 -0
- package/schemas/tables.rng +420 -0
- package/schemas/web-components.rng +184 -0
- package/schemas/web-forms.rng +975 -0
- package/schemas/web-forms2.rng +1236 -0
package/README.md
ADDED
|
@@ -0,0 +1,339 @@
|
|
|
1
|
+
# epubcheck-ts
|
|
2
|
+
|
|
3
|
+
A TypeScript port of [EPUBCheck](https://github.com/w3c/epubcheck) - the official conformance checker for EPUB publications.
|
|
4
|
+
|
|
5
|
+
[](https://github.com/likecoin/epubcheck-ts/actions/workflows/ci.yml)
|
|
6
|
+
[](https://www.npmjs.com/package/@likecoin/epubcheck-ts)
|
|
7
|
+
[](./LICENSE)
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Cross-platform**: Works in Node.js (18+) and modern browsers
|
|
12
|
+
- **Partial EPUB validation**: Currently ~35% of EPUBCheck feature parity
|
|
13
|
+
- **Zero native dependencies**: Pure JavaScript/WebAssembly, no compilation required
|
|
14
|
+
- **TypeScript first**: Full type definitions included
|
|
15
|
+
- **Tree-shakable**: ESM with proper exports for optimal bundling
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm install @likecoin/epubcheck-ts
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Quick Start
|
|
24
|
+
|
|
25
|
+
### ES Modules (recommended)
|
|
26
|
+
|
|
27
|
+
```typescript
|
|
28
|
+
import { EpubCheck } from '@likecoin/epubcheck-ts';
|
|
29
|
+
import { readFile } from 'node:fs/promises';
|
|
30
|
+
|
|
31
|
+
// Load EPUB file
|
|
32
|
+
const epubData = await readFile('book.epub');
|
|
33
|
+
|
|
34
|
+
// Validate
|
|
35
|
+
const result = await EpubCheck.validate(epubData);
|
|
36
|
+
|
|
37
|
+
if (result.valid) {
|
|
38
|
+
console.log('EPUB is valid!');
|
|
39
|
+
} else {
|
|
40
|
+
console.log(`Found ${result.errorCount} errors and ${result.warningCount} warnings`);
|
|
41
|
+
|
|
42
|
+
for (const message of result.messages) {
|
|
43
|
+
console.log(`${message.severity}: ${message.message}`);
|
|
44
|
+
if (message.location) {
|
|
45
|
+
console.log(` at ${message.location.path}:${message.location.line}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### CommonJS
|
|
52
|
+
|
|
53
|
+
```javascript
|
|
54
|
+
const fs = require('node:fs');
|
|
55
|
+
|
|
56
|
+
async function validate() {
|
|
57
|
+
const { EpubCheck } = await import('epubcheck-ts');
|
|
58
|
+
|
|
59
|
+
const epubData = fs.readFileSync('book.epub');
|
|
60
|
+
const result = await EpubCheck.validate(epubData);
|
|
61
|
+
|
|
62
|
+
console.log(result.valid ? 'Valid!' : 'Invalid');
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
validate();
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Browser
|
|
69
|
+
|
|
70
|
+
```typescript
|
|
71
|
+
import { EpubCheck } from '@likecoin/epubcheck-ts';
|
|
72
|
+
|
|
73
|
+
// From file input
|
|
74
|
+
const fileInput = document.querySelector('input[type="file"]');
|
|
75
|
+
fileInput.addEventListener('change', async (event) => {
|
|
76
|
+
const file = event.target.files[0];
|
|
77
|
+
const data = new Uint8Array(await file.arrayBuffer());
|
|
78
|
+
|
|
79
|
+
const result = await EpubCheck.validate(data);
|
|
80
|
+
console.log(result);
|
|
81
|
+
});
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## API
|
|
85
|
+
|
|
86
|
+
### `EpubCheck.validate(data, options?)`
|
|
87
|
+
|
|
88
|
+
Static method to validate an EPUB file.
|
|
89
|
+
|
|
90
|
+
**Parameters:**
|
|
91
|
+
- `data: Uint8Array` - The EPUB file contents
|
|
92
|
+
- `options?: EpubCheckOptions` - Optional validation options
|
|
93
|
+
|
|
94
|
+
**Returns:** `Promise<EpubCheckResult>`
|
|
95
|
+
|
|
96
|
+
### `new EpubCheck(options?)`
|
|
97
|
+
|
|
98
|
+
Create a reusable validator instance.
|
|
99
|
+
|
|
100
|
+
```typescript
|
|
101
|
+
const checker = new EpubCheck({
|
|
102
|
+
version: '3.3',
|
|
103
|
+
profile: 'default',
|
|
104
|
+
locale: 'en',
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const result1 = await checker.check(epub1Data);
|
|
108
|
+
const result2 = await checker.check(epub2Data);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Options
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
interface EpubCheckOptions {
|
|
115
|
+
/** EPUB version to validate against (auto-detected if not specified) */
|
|
116
|
+
version?: '2.0' | '3.0' | '3.1' | '3.2' | '3.3';
|
|
117
|
+
|
|
118
|
+
/** Validation profile */
|
|
119
|
+
profile?: 'default' | 'edupub' | 'idx' | 'dict' | 'preview';
|
|
120
|
+
|
|
121
|
+
/** Include usage messages in results (default: false) */
|
|
122
|
+
includeUsage?: boolean;
|
|
123
|
+
|
|
124
|
+
/** Include info messages in results (default: true) */
|
|
125
|
+
includeInfo?: boolean;
|
|
126
|
+
|
|
127
|
+
/** Maximum errors before stopping, 0 = unlimited (default: 0) */
|
|
128
|
+
maxErrors?: number;
|
|
129
|
+
|
|
130
|
+
/** Locale for messages (default: 'en') */
|
|
131
|
+
locale?: string;
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Result
|
|
136
|
+
|
|
137
|
+
```typescript
|
|
138
|
+
interface EpubCheckResult {
|
|
139
|
+
/** Whether the EPUB is valid (no errors or fatal errors) */
|
|
140
|
+
valid: boolean;
|
|
141
|
+
|
|
142
|
+
/** All validation messages */
|
|
143
|
+
messages: ValidationMessage[];
|
|
144
|
+
|
|
145
|
+
/** Counts by severity */
|
|
146
|
+
fatalCount: number;
|
|
147
|
+
errorCount: number;
|
|
148
|
+
warningCount: number;
|
|
149
|
+
infoCount: number;
|
|
150
|
+
usageCount: number;
|
|
151
|
+
|
|
152
|
+
/** Detected EPUB version */
|
|
153
|
+
version?: string;
|
|
154
|
+
|
|
155
|
+
/** Validation time in milliseconds */
|
|
156
|
+
elapsedMs: number;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
interface ValidationMessage {
|
|
160
|
+
/** Unique message identifier (e.g., 'OPF-001') */
|
|
161
|
+
id: string;
|
|
162
|
+
|
|
163
|
+
/** Severity level */
|
|
164
|
+
severity: 'fatal' | 'error' | 'warning' | 'info' | 'usage';
|
|
165
|
+
|
|
166
|
+
/** Human-readable message */
|
|
167
|
+
message: string;
|
|
168
|
+
|
|
169
|
+
/** Location in the EPUB */
|
|
170
|
+
location?: {
|
|
171
|
+
path: string;
|
|
172
|
+
line?: number;
|
|
173
|
+
column?: number;
|
|
174
|
+
context?: string;
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/** Suggestion for fixing the issue */
|
|
178
|
+
suggestion?: string;
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
### JSON Report
|
|
183
|
+
|
|
184
|
+
Generate a JSON report compatible with the original EPUBCheck:
|
|
185
|
+
|
|
186
|
+
```typescript
|
|
187
|
+
import { EpubCheck, Report } from '@likecoin/epubcheck-ts';
|
|
188
|
+
|
|
189
|
+
const result = await EpubCheck.validate(data);
|
|
190
|
+
const jsonReport = Report.toJSON(result);
|
|
191
|
+
console.log(jsonReport);
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
## Supported Environments
|
|
195
|
+
|
|
196
|
+
| Environment | Version | Notes |
|
|
197
|
+
|-------------|---------|-------|
|
|
198
|
+
| Node.js | 18+ | Full support |
|
|
199
|
+
| Chrome | 89+ | Full support |
|
|
200
|
+
| Firefox | 89+ | Full support |
|
|
201
|
+
| Safari | 15+ | Full support |
|
|
202
|
+
| Edge | 89+ | Full support |
|
|
203
|
+
|
|
204
|
+
## Architecture
|
|
205
|
+
|
|
206
|
+
This library is a TypeScript port of the Java-based [EPUBCheck](https://github.com/w3c/epubcheck) tool maintained by the W3C. Key implementation details:
|
|
207
|
+
|
|
208
|
+
- **XML Processing**: Uses [libxml2-wasm](https://github.com/nicklasb/libxml2-wasm) for XML parsing and schema validation (RelaxNG, XSD) via WebAssembly
|
|
209
|
+
- **ZIP Handling**: Uses [fflate](https://github.com/101arrowz/fflate) for fast, lightweight EPUB container processing
|
|
210
|
+
- **CSS Validation**: Uses [css-tree](https://github.com/nicklasb/css-tree) for CSS parsing and validation
|
|
211
|
+
- **Schematron**: Uses [fontoxpath](https://github.com/FontoXML/fontoxpath) with [slimdom](https://github.com/bwrrp/slimdom.js) for XPath 3.1 evaluation
|
|
212
|
+
|
|
213
|
+
## Validation Coverage
|
|
214
|
+
|
|
215
|
+
| Component | Status | Completeness | Notes |
|
|
216
|
+
|-----------|--------|--------------|-------|
|
|
217
|
+
| OCF Container | 🟡 Partial | ~40% | ZIP structure, mimetype, container.xml |
|
|
218
|
+
| Package Document (OPF) | 🟡 Partial | ~40% | Metadata, manifest, spine, fallback chains |
|
|
219
|
+
| Content Documents | 🟡 Partial | ~25% | XML well-formedness, XHTML structure |
|
|
220
|
+
| Navigation Document | 🟡 Partial | ~30% | Nav structure, NCX validation |
|
|
221
|
+
| Schema Validation | 🟡 Partial | ~70% | RelaxNG, XSD, Schematron working |
|
|
222
|
+
| CSS | 🔴 Basic | ~5% | Parser available, validation minimal |
|
|
223
|
+
| Media Overlays | ❌ Not Started | 0% | Planned |
|
|
224
|
+
| Cross-reference Validation | 🔴 Basic | ~15% | Basic reference tracking |
|
|
225
|
+
| Accessibility Checks | ❌ Not Started | 0% | Alt text, etc. |
|
|
226
|
+
|
|
227
|
+
Legend: 🟢 Complete | 🟡 Partial | 🔴 Basic | ❌ Not Started
|
|
228
|
+
|
|
229
|
+
**Overall Progress: ~35% of Java EPUBCheck features**
|
|
230
|
+
|
|
231
|
+
See [PROJECT_STATUS.md](./PROJECT_STATUS.md) for detailed comparison.
|
|
232
|
+
|
|
233
|
+
## Development
|
|
234
|
+
|
|
235
|
+
### Prerequisites
|
|
236
|
+
|
|
237
|
+
- Node.js 18+
|
|
238
|
+
- npm 9+
|
|
239
|
+
|
|
240
|
+
### Setup
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
# Clone the repository
|
|
244
|
+
git clone https://github.com/likecoin/epubcheck-ts.git
|
|
245
|
+
cd epubcheck-ts
|
|
246
|
+
|
|
247
|
+
# Install dependencies
|
|
248
|
+
npm install
|
|
249
|
+
|
|
250
|
+
# Run tests
|
|
251
|
+
npm test
|
|
252
|
+
|
|
253
|
+
# Build
|
|
254
|
+
npm run build
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
### Scripts
|
|
258
|
+
|
|
259
|
+
| Script | Description |
|
|
260
|
+
|--------|-------------|
|
|
261
|
+
| `npm run build` | Build the library (ESM + CJS) |
|
|
262
|
+
| `npm run dev` | Build in watch mode |
|
|
263
|
+
| `npm test` | Run tests in watch mode |
|
|
264
|
+
| `npm run test:run` | Run tests once |
|
|
265
|
+
| `npm run test:coverage` | Run tests with coverage |
|
|
266
|
+
| `npm run lint` | Lint with ESLint |
|
|
267
|
+
| `npm run lint:fix` | Lint and auto-fix |
|
|
268
|
+
| `npm run format` | Format with Biome |
|
|
269
|
+
| `npm run typecheck` | TypeScript type checking |
|
|
270
|
+
| `npm run check` | Run all checks (format + typecheck) |
|
|
271
|
+
|
|
272
|
+
### Project Structure
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
epubcheck-ts/
|
|
276
|
+
├── src/
|
|
277
|
+
│ ├── index.ts # Public API exports
|
|
278
|
+
│ ├── checker.ts # Main EpubCheck class
|
|
279
|
+
│ ├── types.ts # TypeScript type definitions
|
|
280
|
+
│ ├── core/ # Core validation logic
|
|
281
|
+
│ ├── ocf/ # OCF container validation ✅
|
|
282
|
+
│ ├── opf/ # Package document validation ✅
|
|
283
|
+
│ ├── content/ # Content document validation ✅
|
|
284
|
+
│ ├── nav/ # Navigation validation ✅
|
|
285
|
+
│ ├── ncx/ # NCX validation (EPUB 2) ✅
|
|
286
|
+
│ ├── references/ # Cross-reference validation ✅
|
|
287
|
+
│ ├── schema/ # Schema validation ✅
|
|
288
|
+
│ │ ├── relaxng.ts # RelaxNG validation
|
|
289
|
+
│ │ ├── xsd.ts # XSD validation
|
|
290
|
+
│ │ ├── schematron.ts # Schematron validation
|
|
291
|
+
│ │ └── orchestrator.ts # Schema orchestration
|
|
292
|
+
│ └── messages/ # Error messages
|
|
293
|
+
├── schemas/ # Schema files (RNG, RNC, SCH)
|
|
294
|
+
├── test/
|
|
295
|
+
│ ├── fixtures/ # Test EPUB files
|
|
296
|
+
│ └── integration/ # Integration tests
|
|
297
|
+
├── examples/
|
|
298
|
+
│ └── web/ # Web demo ✅
|
|
299
|
+
└── dist/ # Build output
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Legend: ✅ Implemented
|
|
303
|
+
|
|
304
|
+
## Comparison with Java EPUBCheck
|
|
305
|
+
|
|
306
|
+
| Aspect | epubcheck-ts | EPUBCheck (Java) |
|
|
307
|
+
|--------|--------------|------------------|
|
|
308
|
+
| Runtime | Node.js / Browser | JVM |
|
|
309
|
+
| Feature Parity | ~35% | 100% |
|
|
310
|
+
| Bundle Size | ~55KB JS + ~1.5MB WASM | ~15MB |
|
|
311
|
+
| Installation | `npm install` | Download JAR |
|
|
312
|
+
| Integration | Native JS/TS | CLI or Java API |
|
|
313
|
+
| Performance | Comparable | Baseline |
|
|
314
|
+
|
|
315
|
+
**Note:** epubcheck-ts is currently in active development. See [PROJECT_STATUS.md](./PROJECT_STATUS.md) for detailed feature comparison.
|
|
316
|
+
|
|
317
|
+
## Contributing
|
|
318
|
+
|
|
319
|
+
Contributions are welcome! Please read [CONTRIBUTING.md](./CONTRIBUTING.md) for guidelines.
|
|
320
|
+
|
|
321
|
+
For AI agents contributing to this project, see [AGENTS.md](./AGENTS.md).
|
|
322
|
+
|
|
323
|
+
## License
|
|
324
|
+
|
|
325
|
+
[GPL-3.0](./LICENSE)
|
|
326
|
+
|
|
327
|
+
This is an independent TypeScript implementation inspired by the Java-based [EPUBCheck](https://github.com/w3c/epubcheck) (BSD-3-Clause). No code was directly copied from the original project.
|
|
328
|
+
|
|
329
|
+
## Acknowledgments
|
|
330
|
+
|
|
331
|
+
- [W3C EPUBCheck](https://github.com/w3c/epubcheck) - The original Java implementation
|
|
332
|
+
- [DAISY Consortium](https://daisy.org/) - Maintainers of EPUBCheck
|
|
333
|
+
- [libxml2-wasm](https://github.com/jameslan/libxml2-wasm) - WebAssembly XML processing
|
|
334
|
+
|
|
335
|
+
## Related Projects
|
|
336
|
+
|
|
337
|
+
- [EPUBCheck](https://github.com/w3c/epubcheck) - Official Java validator
|
|
338
|
+
- [epub.js](https://github.com/futurepress/epub.js) - EPUB reader library
|
|
339
|
+
- [r2-shared-js](https://github.com/nicklasb/r2-shared-js) - Readium shared models
|