Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 14 additions & 5 deletions .agents/skills/add-vocab/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,8 @@ Generates `get<PluralName>()` async iterable and optionally a singular accessor.
Required: `pluralName`, `singularName`, `uri`, `description`, `range`

Optional: `singularAccessor` (default `false`), `compactName`, `subpropertyOf`,
`container` (`"graph"` or `"list"`), `embedContext`, `untyped`
`container` (`"graph"` or `"list"`), `embedContext`, `untyped`,
`redundantProperties`, `redundantPropertiesWrite`

### Functional property (exactly one value)

Expand All @@ -223,13 +224,21 @@ Generates a single `get<SingularName>()` / `<singularName>` accessor.
Required: `singularName`, `functional: true`, `uri`, `description`, `range`

Optional: `compactName`, `subpropertyOf`, `redundantProperties`, `untyped`,
`embedContext`
`embedContext`, `redundantPropertiesWrite`

### Redundant properties (functional only)
### Redundant properties

When a property has equivalent URIs from multiple vocabularies, use
`redundantProperties` to write all aliases on serialization and try them in
order on deserialization:
`redundantProperties` on functional or non-functional properties. Reading
selects the first non-empty raw value set, starting with the canonical property
and then aliases in declaration order, before decoding values and containers.
It never merges aliases or retries invalid values. Writing defaults to all
aliases; set `redundantPropertiesWrite: canonical` to write only the canonical
property. An alias without `compactName` uses the JSON-LD processor, as do
writable list and graph aliases. IRI-valued compact terms need
`"@type": "@id"` in the context.

For example:

~~~~ yaml
- singularName: quoteUrl
Expand Down
12 changes: 12 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,18 @@ To be released.
[#896]: https://github.com/fedify-dev/fedify/issues/896
[#1204]: https://github.com/fedify-dev/fedify/issues/1204

### @fedify/vocab-tools

- Added non-functional `redundantProperties` support with ordered fallback
to the first non-empty value set, preserving lists and graphs without
merging synonyms. Added `redundantPropertiesWrite: canonical` to write
only the canonical property while accepting synonyms. Fixed serialization
of synonyms without a compact name and validation of synonym definitions.
[[#1210], [#1215]]

[#1210]: https://github.com/fedify-dev/fedify/issues/1210
[#1215]: https://github.com/fedify-dev/fedify/pull/1215

Comment thread
coderabbitai[bot] marked this conversation as resolved.

Version 2.4.0
-------------
Expand Down
11 changes: 11 additions & 0 deletions changes.d/vocab-tools/redundant-properties.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
links:
'#1210': https://github.com/fedify-dev/fedify/issues/1210
'#1215': https://github.com/fedify-dev/fedify/pull/1215
---
- Added non-functional `redundantProperties` support with ordered fallback
to the first non-empty value set, preserving lists and graphs without
merging synonyms. Added `redundantPropertiesWrite: canonical` to write
only the canonical property while accepting synonyms. Fixed serialization
of synonyms without a compact name and validation of synonym definitions.
[[#1210], [#1215]]
40 changes: 40 additions & 0 deletions packages/vocab-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,43 @@ of trusting a matching origin. Locally constructed values, previously fetched
values, and the explicit `crossOrigin: "trust"` option retain their usual
behavior. This does not verify id-less embedded objects or establish publishing
authority.


Redundant properties
--------------------

Both functional and non-functional property schemas can declare synonyms in
`redundantProperties`. On reading, the canonical property takes precedence,
followed by synonyms in declaration order. The first non-empty raw value set
is decoded in full, preserving its order and multiplicity. Values from other
synonyms are never merged, even when the selected values fail range validation.
List and graph containers are decoded only after choosing the property.

`redundantPropertiesWrite` defaults to `all`, which writes the canonical
property and every synonym with the same complete container representation.
Set it to `canonical` to write only the canonical property while still accepting
synonyms on reading:

~~~~ yaml
- singularName: license
pluralName: licenses
uri: "https://example.com/license"
description: The licenses of the object.
range:
- "http://www.w3.org/2001/XMLSchema#anyURI"
redundantProperties:
- uri: "https://schema.org/license"
- uri: "http://creativecommons.org/ns#license"
redundantPropertiesWrite: canonical
~~~~

A synonym's `compactName` is optional. Without it, serialization uses the
JSON-LD processor to select a context term or retain the full URI. For IRI
values, context terms must declare `"@type": "@id"`; container terms must
carry the appropriate `@container`. Writable container synonyms also use the
processor to preserve their representation. Explicit caller contexts take
precedence over the default context.

As with other properties, an object parsed with `fromJsonLd()` retains its
original JSON-LD document for default serialization. Pass `format: "compact"`
or `format: "expand"` to serialize its decoded values under the write policy.
3 changes: 3 additions & 0 deletions packages/vocab-tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@
},
"license": "MIT",
"devDependencies": {
"@fedify/vocab-runtime": "workspace:^",
"@logtape/logtape": "catalog:",
"@opentelemetry/api": "catalog:",
"@types/node": "catalog:",
"tsdown": "catalog:",
"typescript": "catalog:"
Expand Down
Loading
Loading