@missing-elements/h5p-verify 0.1.0 → 0.1.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.
Files changed (2) hide show
  1. package/lib/verify.mjs +17 -7
  2. package/package.json +7 -6
package/lib/verify.mjs CHANGED
@@ -200,23 +200,33 @@ function dedupe(messages) {
200
200
  return [...counts].map(([message, count]) => (count > 1 ? `${message} (×${count})` : message))
201
201
  }
202
202
 
203
- /** The player's `dist/`, from the installed package; the workspace needs it built first. */
203
+ /**
204
+ * The player's `dist/` and the runtime's, from the installed packages; the workspace needs both
205
+ * built first. The runtime is a package of its own (`@missing-elements/h5p-runtime`, GPL) and is
206
+ * served at `/frame-assets/`, which is where the element looks beside its own script.
207
+ */
204
208
  async function playerDist() {
205
209
  const element = require.resolve('@missing-elements/h5p-offline-player')
206
210
  const dist = dirname(element)
207
- if (!existsSync(join(dist, 'h5p-sw.js')) || !existsSync(join(dist, 'frame-assets', 'h5p.css'))) {
211
+ if (!existsSync(join(dist, 'h5p-sw.js'))) {
208
212
  throw new VerifyError(`The player is not built at ${dist} — run \`pnpm build\` in the workspace, or reinstall the package`)
209
213
  }
210
- return dist
214
+ const runtime = join(dirname(require.resolve('@missing-elements/h5p-runtime/package.json')), 'dist')
215
+ if (!existsSync(join(runtime, 'h5p.css')) || !existsSync(join(runtime, 'frame-boot.js'))) {
216
+ throw new VerifyError(`The H5P runtime is not built at ${runtime} — run \`pnpm build\` in the workspace, or reinstall @missing-elements/h5p-runtime`)
217
+ }
218
+ return { dist, runtime }
211
219
  }
212
220
 
213
- /** A static server for the player and the test page, on a free localhost port. */
214
- function serve(dist) {
221
+ /** A static server for the player, the runtime and the test page, on a free localhost port. */
222
+ function serve({ dist, runtime }) {
215
223
  const page = join(here, 'page.html')
224
+ const ASSETS = '/frame-assets/'
216
225
  const server = createServer(async (request, response) => {
217
226
  const path = decodeURIComponent(new URL(request.url ?? '/', 'http://localhost').pathname)
218
- const target = path === '/' ? page : join(dist, normalize(path).replace(/^(\.\.[/\\])+/, ''))
219
- if (target !== page && !target.startsWith(dist)) {
227
+ const safe = (root, rest) => join(root, normalize(rest).replace(/^(\.\.[/\\])+/, ''))
228
+ const target = path === '/' ? page : path.startsWith(ASSETS) ? safe(runtime, path.slice(ASSETS.length)) : safe(dist, path)
229
+ if (target !== page && !target.startsWith(dist) && !target.startsWith(runtime)) {
220
230
  response.writeHead(403).end()
221
231
  return
222
232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@missing-elements/h5p-verify",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Plays an .h5p package in a headless browser through h5p-offline-player and reports whether it works: start-up, errors, missing libraries, a screenshot. The last check before a generated package is handed to anyone.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,13 +39,14 @@
39
39
  ],
40
40
  "dependencies": {
41
41
  "playwright-core": "^1.50.0",
42
- "@missing-elements/h5p-offline-player": "^0.1.9"
42
+ "@missing-elements/h5p-offline-player": "^0.5.0",
43
+ "@missing-elements/h5p-runtime": "^0.1.0"
43
44
  },
44
45
  "devDependencies": {
45
- "@types/node": "^22.13.0",
46
- "@zip.js/zip.js": "^2.17.0",
47
- "typescript": "^5.7.3",
48
- "vitest": "^5.0.1"
46
+ "@types/node": "^26.6.4",
47
+ "@zip.js/zip.js": "^2.23.0",
48
+ "typescript": "^7.0.2",
49
+ "vitest": "^5.0.3"
49
50
  },
50
51
  "engines": {
51
52
  "node": ">=20"