Skip to content

Secure npm dependencies and update packages#1247

Merged
microbit-grace merged 8 commits into
mainfrom
npm-update
Jul 15, 2026
Merged

Secure npm dependencies and update packages#1247
microbit-grace merged 8 commits into
mainfrom
npm-update

Conversation

@microbit-grace

@microbit-grace microbit-grace commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Security hardening

  • New .npmrc enforcing:
    • min-release-age=7 — a 7-day cooldown before a newly-published version can be installed (supply-chain protection), excluding our own @microbit/* and @microbit-foundation/* scopes
    • allow-git/remote/file/directory=root — blocks transitive dependencies from non-registry sources
    • strict-allow-scripts=true — every dependency lifecycle script must be explicitly allow-listed
    • engine-strict=true — enforces the engines versions
  • allowScripts allowlist in package.json for the packages in our tree that request install scripts:
    • esbuild, fsevents → true (genuine native/build steps)
    • protobufjs, aws-sdk, core-js → false (cosmetic postinstalls — regenerating bundled files, maintenance/funding notices; the latter two come from the CI-only deploy tooling)
  • engines bumped to node >=24.0.0, npm >=11.18.0 (required for allowScripts).

Dependency update + type fixes

npm update bumped several packages. Fixes:

  • lunr / @types/lunr — the global declare namespace lunr augmentation no longer merges into the imported binding, and @types/lunr's export = can't be module-augmented. Describe the multiLanguage + per-language plugins that lunr-languages attaches at runtime via a LunrWithLanguages type and cast at the call sites.
  • @codemirror/view — ViewPlugin.extension now resolves to null unless the Arg type param is undefined; pin ViewPlugin.fromClass<…> so the drag-and-drop decorations plugin is an Extension again.
  • vscode-languageserver-protocol — Diagnostic.message is now string | MarkupContent (extract the string); SignatureHelp.activeParameter can be null (widen guard to != null).
  • vscode-jsonrpc — bumped the direct dependency to ^9 to dedupe against vscode-languageserver-protocol@3.18 (which requires vscode-jsonrpc@9), fixing the duplicate-MessageConnection type mismatch in pyright.ts.
  • vitest 4 — the async rejects matcher dropped toThrowError; use toThrow.
  • Fix hover over the dot in the margin no longer shows the diagnostic tooltip. @codemirror/view 6.43 hides any tooltip whose measured position falls outside the visible content area, unless Tooltip.clip === false
  • Fix code mirror tooltip text spacing. Override whiteSpace: pre-line in code mirror tooltip

Test config

  • vscode-jsonrpc@9's ./browser subpath only declares a browser export condition. The app build applies it, but vitest resolves in node mode and can't — added a test-scoped alias in vite.config.ts pointing at the browser entry.

CI (build.yml)

  • Install npm@11 after setup-node so CI meets the new engines/allowScripts requirements.
  • Bump the Playwright Docker image to v1.61.1-noble to match the Playwright version npm update resolved to (fixes "browser executable doesn't exist").

.npmrc (new file) — the security block from ml-trainer PR #921, with the exclude scopes adapted to this repo (@microbit/* and @microbit-foundation/*):
- min-release-age=7 — 7-day cooldown before installing newly-published versions (supply-chain protection), excluding your own scopes
- allow-git/remote/file/directory=root — blocks transitive deps from non-registry sources
- strict-allow-scripts=true — every dependency lifecycle script must be explicitly allowed
- engine-strict=true — enforces the engines versions

package.json:
- engines: node >=24.0.0, npm >=11.18.0 (was >=24.0 / >=10.0)
- Added allowScripts allowlist. Unlike ml-trainer, this repo's only install-script dependencies are esbuild and fsevents (I parsed hasInstallScript from your lockfile — none of ml-trainer's packages like better-sqlite3/core-js/@sentry/capacitor exist here), so:
"allowScripts": {
  "esbuild": true,
  "fsevents": true
}

.github/workflows/build.yml — added npm install -g npm@11 --registry=https://registry.npmjs.org right after setup-node, before npm ci (matches the PR; your checkout@v6, setup-node@v6, upload-artifact@v7 are already current). The pr-url.yml workflow has no npm steps, so it's untouched.
The npm update bumped several packages with stricter or changed type
definitions. Resolve the resulting tsc errors:

- lunr / @types/lunr: the global `declare namespace lunr` augmentation no
  longer merges into the imported binding, and @types/lunr's `export =`
  cannot be module-augmented. Describe the multiLanguage and per-language
  plugins that lunr-languages attaches at runtime via a `LunrWithLanguages`
  type and cast at the call sites instead.

- @codemirror/view: ViewPlugin.extension now resolves to `null` unless the
  `Arg` type param is `undefined`. Pin `ViewPlugin.fromClass<...>` so the
  drag-and-drop decorations plugin is treated as an Extension again.

- vscode-languageserver-protocol: Diagnostic.message is now
  `string | MarkupContent`; extract the string. SignatureHelp's
  activeParameter can be `null`; widen the guard to `!= null`.

- vscode-jsonrpc: bump the direct dependency to ^9 to dedupe against
  vscode-languageserver-protocol@3.18, fixing the duplicate
  MessageConnection type mismatch in pyright.ts.

- vitest 4: the async `rejects` matcher dropped `toThrowError`; use
  `toThrow`.
@microbit-matt-hillsdon

Copy link
Copy Markdown
Collaborator

The .npmrc parts of this all look good.

The lock file changes upgrade CodeMirror through quite a few minor versions at once. I think we need to do a manual testing pass for this to build confidence. Suggested areas:

  • autocomplete
  • signature help
  • error diagnostics
  • structure highlighting (including scrolling/resizing/editing)
  • dnd of snippets
  • and for the Lunr bits, check non-English search

@microbit-matt-hillsdon

Copy link
Copy Markdown
Collaborator

Branch: https://review-python-editor-v3.microbit.org/npm-update/

Not sure why no PR link.

@microbit-matt-hillsdon

Copy link
Copy Markdown
Collaborator

Old:
image

New:
image

Help/API are there if you scroll.

@microbit-matt-hillsdon

Copy link
Copy Markdown
Collaborator

Hover over the dot in the margin no longer shows the diagnostic tooltip:

image

…ooltip.

@codemirror/view 6.43 hides any tooltip whose measured position falls outside the visible content area, unless Tooltip.clip === false
Override whiteSpace: pre-line in code mirror tooltip
@microbit-grace

Copy link
Copy Markdown
Contributor Author

Manual test checklist

  1. Autocomplete — @codemirror/autocomplete + language-server/autocompletion.ts
  • Type display. → completion li type, Enter/click inserts.
  • Completion docs panel renders alongside the list.
  • Trigger mid-identifier (ctrl + space) correctly (no clipping/offset when text is at the edge of the editor).
  1. Signature help — language-server/d the activeParameter null guard)
  • Type display.scroll( → signature popup shows, active param is highlighted, and updates as you move across commas.
  • A function with no parameters still pops without error (was changed from undefined -> null case).
  1. Error diagnostics — language-server/diagnostics.ts (message extraction changed from string | MarkupContent)
  • Introduce a syntax/name error → red underline appears at the right span; hover shows the message text
  • V2-only API on a V1 board still shows the version warning; fix the error → underline clears.
  1. Structure highlighting — structure-highlighting/ (viewport-driven ViewPlugin)
  • Nested blocks get their highlight bands. Then stress the viewport recomputation:
    • Scroll a long file — bands ss.
    • Resize the editor pane.
    • Edit (add/remove indentation, split a block) — bands update live.
  1. Drag-and-drop snippets — dnd.ts + dnd-decorations.ts (pinned the ViewPlugin.fromClass type arg)
  • Drag a snippet from the reference — preview highlight while hovering, code inserts at the drop line, drop highlight shows then fades out.
  • The fade-out is the timeoutEffect path — confirm it still animates and clears.
  1. Non-English search — search.worker.ts (I replaced the lunr plugin access with a typed cast — same runtime object)
  • Switch UI language and search the reference/API. Cover at least one non-English and Japanese. Confirm results return and are relevant.
  • Also spot-check e.g. German/Fr

@microbit-grace
microbit-grace merged commit 925f3b2 into main Jul 15, 2026
1 check passed
@microbit-grace
microbit-grace deleted the npm-update branch July 15, 2026 09:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants