Test infrastructure uses the vite-plus stack: vp test (bundled Vitest 5),
jsdom environment configured in vite.config.ts, colocated web/src/*.test.ts
files that tsc type-checks, vp fmt formats, and the bundler never imports.
- markdown.test.ts pins the notes XSS defenses: parser-level html escaping,
DOMPurify FORBID_TAGS, scheme checks, footnote rendering, html->markdown
round-trips incl. the headingless-table rule.
- filter_builder.test.ts pins the deep-link wire contract (ruleToFlatParam),
smart-serialization rules (isFlatable), and pruneIncomplete semantics.
- password_validation.test.ts covers the rules fetch + fallback and the
full submit-gating matrix through the real DOM flow (debounce included).
- api.test.ts pins response/error contracts incl. the HTTP-status and
Unknown-error fallbacks and the 404-as-null progress contract.
- storage.test.ts covers token/theme/library round-trips, the __all__
sentinel, and the SSR cookie.
- toast.test.ts pins config completeness for every ToastType (the missing
'warning' entry regression) and render behavior.
Found + fixed while writing these: the no-useless-escape fix in
d7d14957 had de-escaped the ']' in hasSpecialChar's character class,
closing it early — special-character validation silently stopped
matching most specials. The new password suite caught it immediately.
jsdom chosen over happy-dom after empirical comparison: DOMPurify's
sanitizer output is mangled under happy-dom (forbidden tags survive),
which would have made the security suite test nothing.
Note: AGENTS.md gains a 'Web (TypeScript) tests' section documenting the
workflow and the happy-dom gotcha.
46 lines
1.7 KiB
JSON
46 lines
1.7 KiB
JSON
{
|
|
"name": "bookhoard",
|
|
"version": "1.0.0",
|
|
"description": "A self-hosted ebook management system",
|
|
"scripts": {
|
|
"build:css": "tailwindcss -i ./web/static/input.css -o ./web/static/style.css --watch",
|
|
"build:css:prod": "tailwindcss -i ./web/static/input.css -o ./web/static/style.css --minify",
|
|
"build:ts": "cp node_modules/htmx.org/dist/htmx.min.js web/static/htmx.min.js && vp build",
|
|
"build:ts:dev": "cp node_modules/htmx.org/dist/htmx.min.js web/static/htmx.min.js && vp build --mode development",
|
|
"build:ts:watch": "cp node_modules/htmx.org/dist/htmx.min.js web/static/htmx.min.js && vp build --watch",
|
|
"build": "npm run build:ts && npm run build:css:prod",
|
|
"dev": "npm run build:ts:dev && npm run build:css",
|
|
"test": "vp test web/src"
|
|
},
|
|
"dependencies": {
|
|
"@bookhoard/foliate-js": "git+https://git.linuxhg.com/Bookhoard/foliate-js.git#f622841",
|
|
"alpinejs": "^3.15.8",
|
|
"chart.js": "^4.5.1",
|
|
"dompurify": "^3.4.16",
|
|
"fflate": "^0.8.3",
|
|
"highlight.js": "^11.11.1",
|
|
"htmx.org": "^2.0.8",
|
|
"lunr": "^2.3.9",
|
|
"markdown-it": "^15.0.2",
|
|
"markdown-it-footnote": "^4.0.0",
|
|
"turndown": "^7.2.4",
|
|
"turndown-plugin-gfm": "^1.0.2"
|
|
},
|
|
"devDependencies": {
|
|
"@tailwindcss/forms": "^0.5.11",
|
|
"@tailwindcss/typography": "^0.5.19",
|
|
"@types/markdown-it": "^14.2.0",
|
|
"@types/turndown": "^5.0.6",
|
|
"autoprefixer": "^10.4.27",
|
|
"jsdom": "^30.1.3",
|
|
"playwright": "^1.64.1",
|
|
"tailwindcss": "^3.4.19",
|
|
"typescript": "^5.9.3",
|
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.3.0",
|
|
"vite-plus": "1.3.0"
|
|
},
|
|
"overrides": {
|
|
"vite": "npm:@voidzero-dev/vite-plus-core@1.3.0"
|
|
}
|
|
}
|