Replace libxmljs2 with libxml2-wasm - #575
Merged
Merged
Conversation
required env vars
Running the integration tests against the Docker container requires temporarily setting "authLevel": "anonymous" in all five function.json files, because the container has no AzureWebJobsStorage and so cannot validate function keys. Committing that would leave the deployed endpoints reachable without a key. Adds a .husky/pre-commit check on staged content, and a matching check-auth-level job in develop-func-ci.yml which also gates automerge, so a Dependabot PR cannot merge with it set. The hook alone is insufficient: it can be bypassed with --no-verify and is absent in a fresh clone until npm install has run.
Tests added prior to replacing libxmljs2 - see js-validator-api#574 Adds schema-unit-tests/, the first coverage of the XSD schema path. Extend the rules:test glob so the new directory runs in existing CI with no workflow change. Five cases fail deliberately. They assert the corrected behaviour and go green when libxmljs2 is replaced. Two controls pass either side, guarding against the suite going green by not validating at all. Also adds an HTTP-level case to the newman collection.
Addresses issue #574 Now on libxml2-wasm 0.7.1 (libxml2 2.15.1), pinned exactly: a bump can change the bundled libxml2, so it is excluded from Dependabot and upgraded by hand. Behaviour: - Sign-only decimals are now reported; over-long decimals no longer are. - No currently published dataset changes verdict, tested against all 451 datasets the Dashboard reports as failing. - With ?details=true, errors carry only { line, column }. str1, code, level, domain and int1 are no longer available. Worth knowing when reading the diff: - utils/xmlParse.js restores libxmljs2's throw semantics. libxml2-wasm throws whenever libxml2 records any error, even when it still built a usable document, which would turn schema errors into parse errors. - Documents hold memory outside the JS heap and must be dispose()d. Schemas are compiled once by XsdValidator.fromDoc, not per activity. - getFileInformation moves to utils/iatiFile.js, split so that parsing owns document creation, and so the tests can reach it without importing utils.js and therefore Redis.
simon-20
approved these changes
Aug 20, 2026
Contributor
There was a problem hiding this comment.
This is excellent @arobson-ods - very thorough, and greatly improves the state of the app/repo.
I suggest two changes, but they are extremely minor so I'm marking as approved.
With respect to the decisions:
- I think the handling of
?details=trueis correct. I got an AI bot to scan the logs for this application, and IATI Publisher accounts for 93% of calls to the endpoint withdetails=true, and is the only consumer continuously accessing it, and Publisher doesn't read anything exceptdetails[i].error.lineso this PR doesn't affect Publisher. The other traffic was all ad hoc (couple of requests on a single day), so it nothing to worry about. So the approach you've taken is good. - On the version of
libxml-wasmused: I think we stick with the version that uses that fork for now, but revisit the next time it is updated. - Let's change the name of the
npm run rules:testcommand to make it slightly more general so that it captures the types of tests it now runs. - Could we add a
CHANGELOG.mdto this repo - that would be a great place to include a couple of bullet points describing the changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
This PR address issue #574 - Upgrade version of
libxmljs2used to bring in line with Dashboard validationWhat Changed?
libxmljs20.32.0 withlibxml2-wasm0.7.1.envfile that were previously preventing the application from booting up locally. Added a pre-commit hook and CI check to prevent inadvertent push of unsecured functions to remote. Applied linting fixes.Architectural & Scope Decisions
detailsobject is smaller. This affects only requests that pass?details=true.detailsis a documented query parameter —postman/schemas/index.yaml:93publishes it to developer.iatistandard.org as "Show all context information for advanced use and debugging". Details are additional to the error message e.g.Under
libxmljs2, the innermost object was the raw libxml2xmlErrorstruct, whateverhappened to be populated on it. Measured on
iati-org-schema-errors.xml:It is now exactly:
Field by field
Considered the benefits of migration outweighed this one (minor?) loss.
Verification & Testing
test:commit includes failing unit and integration tests. These turn green after the upgrade.developeven if schema validation was broken). To best target the bug I introduced schema unit tests (at least as a temporary measure) in this PR. This introduces a naming problem asnpm run rules:testnow runs a few schema tests as well as the ruleset tests.AA-AAA-123456789as org identifier in the existing fixtures.Notes for Reviewer
detailsinformation. However we are changing API behaviour. We need to assess how to approach loss of thecodeparam - a) nothing b) document c) patchlibxml2-wasmto recover this info.try/finally{ xmlDoc.dispose() }construct withusingwhen bump Node version.libxml-wasmis built from a submodule that points at the maintainer's own fork oflibxml2containing two (Windows related) commits. Don't know if we want to do that or go back to v0.6.0.docs:,ci:, andstyle:commits in a separate PR prior to migration.