Skip to content

feat(web-client): key custom props by namespace - #3301

Draft
dschmidt wants to merge 2 commits into
mainfrom
feat/clark-notation-extra-props
Draft

feat(web-client): key custom props by namespace#3301
dschmidt wants to merge 2 commits into
mainfrom
feat/clark-notation-extra-props

Conversation

@dschmidt

@dschmidt dschmidt commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

Description

Custom WebDAV properties were parsed with their namespaces stripped, so two apps using the same property name in different namespaces collapsed onto one key and their values were merged into an array. registerExtraProp documented that as "Make sure to use unique tag names despite differing namespaces", which only works as long as every app knows every other app.

Responses are now parsed in Clark notation ({namespace}name) and extra props are looked up under the namespace they were registered with:

webdav.registerExtraProp('{https://apps.example/project}color')
webdav.registerExtraProp('{https://apps.example/review}color')

resource.extraProps['{https://apps.example/project}color'] // 'red'
resource.extraProps['{https://apps.example/review}color']  // 'approved'

The older myapp:color spelling keeps working unchanged, there the prefix doubles as the namespace, which is what the server has stored so far. registerExtraProp keeps its signature, the request goes on the wire exactly as before (xmlns:myapp="myapp", <myapp:color/>), and the value still arrives on extraProps under the name it was registered with. Covered by tests.

The one thing that does change: the parsed props themselves key a custom prop by its namespace ({myapp}color) instead of the bare local name. Anything reading extraProps is unaffected, only code reaching into the raw props for a custom property would need to follow.

Notes:

  • The two well-known namespaces are stripped back off after parsing, so Resource.props and the WebDAV library's prepareFileFromProps keep addressing DAV: and oc: props by their bare name. Nothing outside the extra-prop path changes.
  • Prefixes on the request are generated (ns0, ns1, ...). The server identifies a property by its namespace, not by the prefix.
  • Drive-by fix: oc:name carries the file name and was not covered by the WebDAV library's displayname guard, so a file called 2024.10 arrived as the number 2024.1. It gets a parser now, since the parser context had to be set up anyway.

Draft: needs a webdav bump. The clarkNotationProps option is merged upstream (perry-mitchell/webdav-client#410) but unreleased, and displaynameTagParser needs perry-mitchell/webdav-client#415 on top. Until both are released, the branch only builds with a local override:

# pnpm-workspace.yaml, not part of this PR
overrides:
  webdav: 'link:../../webdav-client'

Related Issue

  • Fixes <issue_link>

How Has This Been Tested?

  • test environment: unit suite, plus a throwaway OpenCloud 7.2.0 container for the round-trip
  • test case 1: packages/web-client/tests/unit/webdav/client/parsers.spec.ts, two apps register the same name in different namespaces, the PROPFIND body asks for both under their own namespace and each app gets its own value back
  • test case 2: same, against a recorded server response (tests/__fixtures__/propfind-custom-namespaces.xml). Both properties were PROPPATCHed onto a real server and read back, the server serialises them with an inline default xmlns
  • test case 3: a prefix-serialised property lands under the same key as an inline-xmlns one
  • test case 4: well-known props stay addressable by bare name, including a file named 2024.10
  • test case 5: buildResource keeps one name in two namespaces apart (functions.spec.ts)
  • reverting the option makes 4 of the 7 new cases fail, full unit suite is green (3814)

Types of changes

  • Bugfix
  • Enhancement (a change that doesn't break existing code or deployments)
  • Tests (adding or improving tests)

Props were parsed with namespaces stripped, so two apps using the same
property name in different namespaces collapsed onto one key and their values
were merged into an array. registerExtraProp documented that as "make sure to
use unique tag names", which does not scale beyond apps that know each other.

Parse in Clark notation instead and look extra props up under the namespace
they were registered with. An app can now bring a real namespace URI
({https://app.example/ns}color) or keep the older myapp:color spelling, where
the prefix doubles as the namespace, which is what the server has stored so
far. The two well-known namespaces are stripped back off after parsing, so
Resource.props and prepareFileFromProps keep addressing them by bare name.

Also guard oc:name from being interpreted while a parser context is set up
anyway: a file called "2024.10" was arriving as the number 2024.1.

Needs a webdav release containing the clarkNotationProps option
(perry-mitchell/webdav-client#410).
Registering a prop the old way has to keep working: same request on the wire,
same key on extraProps, and it must not collide with the same name in another
namespace. Also pins what does change, the parsed props key a custom prop by
its namespace now.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant