Skip to content

feat(body)!: deliver array-typed and repeating form fields as arrays - #145

Open
line-o wants to merge 1 commit into
eeditiones:mainfrom
line-o:fix/144-form-body-array-wrap
Open

feat(body)!: deliver array-typed and repeating form fields as arrays#145
line-o wants to merge 1 commit into
eeditiones:mainfrom
line-o:fix/144-form-body-array-wrap

Conversation

@line-o

@line-o line-o commented Sep 2, 2026

Copy link
Copy Markdown
Member

Implements Option 1 from #144: form-body values declared as type: "array" — and repeating schemaless fields — are delivered to handlers as array(*) instead of XQuery sequences.

Why

eXist 7 made JSON serialization spec-compliant: the JSON output method now raises err:SERE0023 for a map entry whose value is a sequence of more than one item, where eXist ≤ 6.x silently coerced it to a JSON array. Any handler serializing $request?body from a form post with a repeating field therefore 500s on eXist 7 — this is what fails the two experimental CI jobs (existdb/existdb:latest / :release) on main.

Beyond the eXist 7 breakage, this fixes an internal inconsistency (see #144 comment): parameters:cast-array already returns array(*) for array-typed parameters, and JSON bodies naturally produce arrays — form bodies were the only place where the same declared schema type produced a sequence.

Changes

  • content/body.xqm
    • body:validate-value: a property declared type: "array" is wrapped in array { } when present (absent optional properties keep producing the empty sequence, matching parameters:cast-array).
    • body:additional-property (schemaless / undeclared fields): a repeating field is wrapped in an array; single values stay scalar (without a schema there is nothing that says "array").
  • test/app/modules/upload.xqm: upload:batch unpacks the array ($request?body?file?*).
  • doc/file-upload.md: batch examples updated accordingly.
  • test/mediatype.test.js: new test posting a single file to the batch route — a declared-array property must be an array even with one value. The previously failing urlencoded tests pass unchanged, since serialize(map { …, "array": [1,2,3] }, map { "method": "json" }) is valid on every eXist version.

Breaking change

Handlers reading multi-value form-data/urlencoded body fields must unpack an array now ($request?body?file?* instead of $request?body?file). Parameter handling and JSON bodies are unaffected — they were already arrays. The commit carries a BREAKING CHANGE: footer so semantic-release cuts a major version.

Verification

Full suite run against both engines via Docker containers:

Engine Result
eXist 6.4.1 197 passing, 0 failing
eXist 7.0.0-SNAPSHOT (existdb/existdb:latest) 197 passing, 0 failing (was 2 failing on main)

The experimental CI jobs should go green with this change.

Closes #144

🤖 Generated with Claude Code

https://claude.ai/code/session_01L13cpTBpxHDuvVSd78BDQw

Form-data and urlencoded body properties declared as type "array" in
the requestBody schema, and repeating additional (schemaless) fields,
are now wrapped in array(*) instead of being passed to handlers as
XQuery sequences.

This aligns $request?body with $request?parameters (parameters:cast-array
already returns array(*) for multi-value parameters) and with JSON bodies,
and makes the body map serializable with the JSON output method on
eXist 7, which raises err:SERE0023 for sequences of more than one item
as the serialization spec requires.

BREAKING CHANGE: handlers reading multi-value form-data or urlencoded
body fields must unpack an array now, e.g. $request?body?file?*
instead of $request?body?file.

Closes eeditiones#144

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01L13cpTBpxHDuvVSd78BDQw
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.

Multi-value form fields are sequences in $request?body — JSON serialization fails with SERE0023 on eXist 7 (now spec-compliant)

2 participants