Skip to content

feat: add a check for the codeblocks in the tutorials - #3

Merged
mirceanis merged 5 commits into
mainfrom
add-codeblock-checks
Feb 25, 2026
Merged

feat: add a check for the codeblocks in the tutorials#3
mirceanis merged 5 commits into
mainfrom
add-codeblock-checks

Conversation

@mirceanis

Copy link
Copy Markdown

This adds a compilation check for the TypeScript codeblocks in the tutorials.

Additionally, this includes several improvements and updates across documentation, code formatting, and workflow configuration.

…o tsx for scripts

- Add scripts/check-codeblocks.sh and scripts/extract-and-check.ts to extract and type-check TypeScript code blocks in docs
- Add cytoscape-alias-plugin.js for ESM/UMD aliasing in Webpack
- Update tsconfig.json for ESNext and bundler module resolution
Copilot AI review requested due to automatic review settings February 25, 2026 13:05
@netlify

netlify Bot commented Feb 25, 2026

Copy link
Copy Markdown

Deploy Preview for veramo ready!

Name Link
🔨 Latest commit cff7a34
🔍 Latest deploy log https://app.netlify.com/projects/veramo/deploys/699ef3cd6d9cc00008a5c5d3
😎 Deploy Preview https://deploy-preview-3--veramo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@mirceanis
mirceanis merged commit eabc470 into main Feb 25, 2026
5 checks passed
@mirceanis
mirceanis deleted the add-codeblock-checks branch February 25, 2026 13:13

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds automated TypeScript codeblock compilation checking for tutorial/docs content, alongside tooling and documentation updates (Node version guidance, formatting adjustments) and Docusaurus configuration enhancements.

Changes:

  • Introduce scripts to extract TypeScript code fences from docs and run tsc --noEmit against them, with an optional baseline report.
  • Add a bootstrap script to provision an isolated temp/codeblocks dependency environment used for compilation checks.
  • Update Docusaurus config and dependencies (Mermaid theme + Cytoscape alias plugin), plus various doc formatting/updates.

Reviewed changes

Copilot reviewed 18 out of 21 changed files in this pull request and generated 11 comments.

Show a summary per file
File Description
tsconfig.json Extends Docusaurus TS config and adds explicit compiler options for ESNext/bundler resolution.
scripts/extract-and-check.ts New extractor/compiler script for docs TypeScript codeblocks (with optional report output).
scripts/check-codeblocks.sh New bootstrap runner to set up temp/codeblocks deps and execute the checker.
pnpm-lock.yaml Lockfile changes for added deps and overrides (including mermaid pin).
plugins/cytoscape-alias-plugin.js New Docusaurus plugin intended to alias Cytoscape UMD build to ESM build.
package.json Adds codeblock-check scripts, mermaid theme dependency + pnpm overrides, switches runtime tooling to tsx, updates Node engines.
docusaurus.config.js Enables Mermaid markdown and registers Mermaid theme + new Cytoscape alias plugin.
docs/veramo_agent/event_system.md Adds/adjusts example code and formatting.
docs/veramo_agent/configuration_internals.md Adds // filename: markers for codeblock compilation.
docs/veramo_agent/cli_tool.md Updates Node prerequisite text.
docs/react_native_tutorials/react_native_*.md Adds // filename: markers and import/formatting fixes for tutorial snippets.
docs/node_tutorials/node_setup_identifiers.md Adds // filename: markers and formatting adjustments in snippets.
docs/dev_tools/veramo_react.md Fixes/normalizes TSX snippets and query example formatting.
docs/dev_tools/agent_explorer_plugin.md Adjusts code fence language tags (ts -> tsx).
docs/basics/verifiable_data.md Re-formats JSON5 example.
docs/basics/identifiers.md Re-formats JSON5 DID document example.
.prettierignore Adds ignore rules for binary assets and build output.
.gitignore Broadens node_modules ignoring; ignores baseline report and some local docs/LLM files.
.github/workflows/rebuild-api.yml Runs formatting + adds a codeblocks check step in the rebuild workflow.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (2)

scripts/check-codeblocks.sh:56

  • The bootstrap installs many dependencies using @latest, which makes runs non-reproducible and can unexpectedly break (or change results) as upstream releases change. Consider pinning versions (or reusing the repo lockfile) so check:codeblocks is deterministic and cacheable in CI.
    @veramo/credential-status@latest \
    @veramo/data-store@latest \
    @veramo/data-store-json@latest \
    @veramo/did-comm@latest \
    @veramo/did-discovery@latest \
    @veramo/did-jwt@latest \
    @veramo/did-manager@latest \
    @veramo/did-provider-ethr@latest \
    @veramo/did-provider-ion@latest \
    @veramo/did-provider-jwk@latest \
    @veramo/did-provider-key@latest \
    @veramo/did-provider-peer@latest \
    @veramo/did-provider-pkh@latest \
    @veramo/did-provider-web@latest \
    @veramo/did-resolver@latest \
    @veramo/key-manager@latest \
    @veramo/kms-local@latest \
    @veramo/kms-web3@latest \
    @veramo/message-handler@latest \
    @veramo/remote-client@latest \
    @veramo/remote-server@latest \
    @veramo/selective-disclosure@latest \
    @veramo/url-handler@latest \
    @veramo/utils@latest \
    ethr-did-resolver@latest \
    web-did-resolver@latest \
    express@^4 \
    typeorm@latest
fi

exec pnpm tsx "$REPO_ROOT/scripts/extract-and-check.ts" "$@"

scripts/check-codeblocks.sh:56

  • The pnpm add step installs several third-party dependencies (ethr-did-resolver, web-did-resolver, express, typeorm) using mutable tags like @latest and ^4. This means every fresh run of this script (for example in CI) will automatically fetch and execute whatever code is currently published under those names, so a compromised or malicious release could execute with your CI/build permissions and access to secrets. To reduce supply-chain risk, pin these third-party packages to specific versions (or otherwise lock them down) and update them only via explicit, reviewed version bumps.
    @veramo/credential-status@latest \
    @veramo/data-store@latest \
    @veramo/data-store-json@latest \
    @veramo/did-comm@latest \
    @veramo/did-discovery@latest \
    @veramo/did-jwt@latest \
    @veramo/did-manager@latest \
    @veramo/did-provider-ethr@latest \
    @veramo/did-provider-ion@latest \
    @veramo/did-provider-jwk@latest \
    @veramo/did-provider-key@latest \
    @veramo/did-provider-peer@latest \
    @veramo/did-provider-pkh@latest \
    @veramo/did-provider-web@latest \
    @veramo/did-resolver@latest \
    @veramo/key-manager@latest \
    @veramo/kms-local@latest \
    @veramo/kms-web3@latest \
    @veramo/message-handler@latest \
    @veramo/remote-client@latest \
    @veramo/remote-server@latest \
    @veramo/selective-disclosure@latest \
    @veramo/url-handler@latest \
    @veramo/utils@latest \
    ethr-did-resolver@latest \
    web-did-resolver@latest \
    express@^4 \
    typeorm@latest
fi

exec pnpm tsx "$REPO_ROOT/scripts/extract-and-check.ts" "$@"


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

pnpm run format
- name: 'check codeblocks'
run: |
pnpm run check:codeblocks'

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The workflow step has a stray trailing quote in pnpm run check:codeblocks', which will cause the action to fail with a shell syntax/command-not-found error. Remove the extra ' so the script can run.

Suggested change
pnpm run check:codeblocks'
pnpm run check:codeblocks

Copilot uses AI. Check for mistakes.
# Bootstrap or refresh the isolated package environment
if [ ! -f "$CODEBLOCKS_DIR/package.json" ]; then
echo "Initialising package environment in $CODEBLOCKS_DIR..."
pnpm init --init-type module --bare --dir "$CODEBLOCKS_DIR"

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pnpm init --dir "$CODEBLOCKS_DIR" is interactive by default and may hang in CI/non-TTY environments. Use a non-interactive option (eg -y) or write a minimal package.json directly so the codeblocks check can run unattended.

Suggested change
pnpm init --init-type module --bare --dir "$CODEBLOCKS_DIR"
pnpm init -y --init-type module --bare --dir "$CODEBLOCKS_DIR"

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +41
const content = fs.readFileSync(path.join(repoRoot, mdFile), 'utf-8')
const codeBlockRegex = /```(ts|typescript)\n([\s\S]+?)\n```/g
let match

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

codeBlockRegex only matches ts and typescript fences, so ```tsx blocks (common in the React/React Native tutorials) will be skipped and never type-checked. If the goal is to check TypeScript tutorial codeblocks broadly, include tsx in the supported fence languages.

Copilot uses AI. Check for mistakes.
Comment on lines +65 to +90
// --- Detect // filename: comment (first line of the block) ---
const firstLine = code.split('\n')[0].trim()
const filenameMatch = firstLine.match(/^\/\/\s*filename:\s*(.+)$/)
const virtualFilename = filenameMatch ? filenameMatch[1].trim() : null

if (virtualFilename) {
// Append this block's code (strip the filename comment line) to the virtual file
const codeWithoutComment = code.split('\n').slice(1).join('\n')
const existing = virtualFiles.get(virtualFilename) ?? ''
virtualFiles.set(virtualFilename, existing + (existing ? '\n' : '') + codeWithoutComment)

// Write ALL current virtual files to docDir so imports resolve
for (const [vPath, vCode] of virtualFiles) {
const absPath = path.join(docDir, vPath)
fs.mkdirSync(path.dirname(absPath), { recursive: true })
fs.writeFileSync(absPath, vCode)
}

// The file being checked is the one that was just updated
const targetFile = path.join(docDir, virtualFilename)

try {
execSync(
`tsc --noEmit --skipLibCheck --target esnext --module esnext --moduleResolution bundler ${targetFile}`,
{ stdio: 'pipe', encoding: 'utf-8', maxBuffer: 10 * 1024 * 1024 },
)

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

virtualFilename is taken directly from markdown content and is used to construct paths (path.join(docDir, vPath)) and to build the tsc command. Without validation/sanitization this allows path traversal (eg ../../...) and, because execSync runs via a shell, potential command injection if virtualFilename contains shell metacharacters. Validate that filenames are relative, stay within docDir, and invoke tsc via execFileSync/argument arrays (no shell) to avoid injection risks.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +18
modifyWebpackConfig(config) {
config.resolve = config.resolve || {};
config.resolve.alias = config.resolve.alias || {};
// Alias the UMD build to the ESM build to avoid export issues
config.resolve.alias['cytoscape/dist/cytoscape.umd.js'] = path.resolve(
__dirname,
'node_modules',
'cytoscape',
'dist',
'cytoscape.esm.mjs'
);
return config;

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Docusaurus v2 plugins use the configureWebpack hook; modifyWebpackConfig is a v1-era API and will not be called, so the alias likely won’t be applied. Rename to the supported hook (configureWebpack) and return the appropriate webpack config overrides.

Suggested change
modifyWebpackConfig(config) {
config.resolve = config.resolve || {};
config.resolve.alias = config.resolve.alias || {};
// Alias the UMD build to the ESM build to avoid export issues
config.resolve.alias['cytoscape/dist/cytoscape.umd.js'] = path.resolve(
__dirname,
'node_modules',
'cytoscape',
'dist',
'cytoscape.esm.mjs'
);
return config;
configureWebpack(config, isServer, utils) {
// Alias the UMD build to the ESM build to avoid export issues
return {
resolve: {
alias: {
'cytoscape/dist/cytoscape.umd.js': path.resolve(
__dirname,
'node_modules',
'cytoscape',
'dist',
'cytoscape.esm.mjs'
),
},
},
};

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +12
# Bootstrap or refresh the isolated package environment
if [ ! -f "$CODEBLOCKS_DIR/package.json" ]; then
echo "Initialising package environment in $CODEBLOCKS_DIR..."

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The bootstrap guard only checks for $CODEBLOCKS_DIR/package.json. If that file exists but node_modules was cleaned (eg by a CI cache miss or manual deletion), the script will skip reinstall and the codeblock compilation will fail. Consider checking for node_modules (or running pnpm install --dir ... each time) instead of only package.json.

Copilot uses AI. Check for mistakes.
Comment on lines +10 to +17
// Alias the UMD build to the ESM build to avoid export issues
config.resolve.alias['cytoscape/dist/cytoscape.umd.js'] = path.resolve(
__dirname,
'node_modules',
'cytoscape',
'dist',
'cytoscape.esm.mjs'
);

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The alias target path resolves from __dirname (the plugins/ directory) into plugins/node_modules/..., but dependencies are installed in the repo root node_modules/. This path will not exist at runtime. Resolve from the site directory (eg context.siteDir) or from process.cwd() / path.resolve(__dirname, '..', 'node_modules', ...) so the alias points at a real file.

Copilot uses AI. Check for mistakes.
Comment thread package.json
Comment on lines +30 to +34
"pnpm": {
"overrides": {
"mermaid": "8.13.8"
}
},

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PNPM override pins mermaid to 8.13.8, which in turn pulls in @braintree/sanitize-url@3.1.0 (deprecated for an XSS vulnerability per the lockfile). Consider upgrading mermaid to a version that doesn’t require the vulnerable sanitize-url (or add an override for sanitize-url to a patched major) so enabling mermaid doesn’t introduce a known vulnerable dependency.

Copilot uses AI. Check for mistakes.
Comment thread package.json
"check:codeblocks": "bash scripts/check-codeblocks.sh",
"baseline:docs": "bash scripts/check-codeblocks.sh --report",
"check:all": "pnpm run build:veramo && pnpm run format && pnpm run check:docs && pnpm run build",
"format": "prettier --write '{src,docs}/**/*'"

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The format script now targets only {src,docs}/**/*, but this PR adds new source files under scripts/ and plugins/ that won’t be covered by formatting checks/runs. Consider including these directories (or switching to a repo-wide prettier glob plus .prettierignore) to keep tooling scripts and plugins consistently formatted.

Suggested change
"format": "prettier --write '{src,docs}/**/*'"
"format": "prettier --write '{src,docs,scripts,plugins}/**/*'"

Copilot uses AI. Check for mistakes.
Comment on lines +1 to +6
const path = require('path');

module.exports = function cytoscapeAliasPlugin(context, options) {
return {
name: 'cytoscape-alias-plugin',

Copilot AI Feb 25, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This plugin file doesn’t follow the repository’s Prettier settings (eg semi: false, singleQuote: true), which makes it inconsistent with the rest of the codebase. Consider running Prettier on this file or adjusting the format script scope so new plugins/ files get formatted automatically.

Copilot uses AI. Check for mistakes.
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