Skip to content

Commit c68ba36

Browse files
committed
docs(pryv-cmc): document 1.1.0 additions (7 new errorIds + TTL bounds + features negotiation)
README now covers the @pryv/cmc@1.1.0 additions surfaced through the `errorIds` catalogue. Without these docs, app developers couldn't tell which errors were stable wire contracts vs which were ad-hoc strings they should ignore. - Error catalogue section: table of the 7 new ids with the kebab string and a one-line "when you'll see it" hint (CAPABILITY_TTL_OUT_OF_RANGE, HANDLER_MISSING_CAPABILITY_ID, CHAT_DISABLED, SYSTEM_MESSAGING_DISABLED, CLIENTDATA_CMC_FORBIDDEN, RESERVED_STREAM_UNDELETABLE, COUNTERPARTY_IDENTITY_MISSING). Count bumped from "24 stable kebab-case strings" to 31. - New "Capability TTL bounds" subsection: documents the [60s, 30d] server bound on `content.request.expiresAt` + the 7-day default when omitted + the rejection id (cmc-capability-ttl-out-of-range). Was previously a silent feature. - New "Features negotiation" subsection: documents `features.{chat, systemMessaging}` default-permit-on-omit semantics, the binding-on-both-sides-at-send-time behaviour, and the rejection ids (cmc-chat-disabled / cmc-system-messaging-disabled). Notes scope-request / scope-update remain permitted regardless of the flag, and observation scopes / revokeRelationship are unaffected. Source unchanged. Pairs with the @pryv/cmc@1.1.0 release (c7053e7).
1 parent c7053e7 commit c68ba36

1 file changed

Lines changed: 28 additions & 2 deletions

File tree

components/pryv-cmc/README.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,38 @@ cmc.parseCollectorStreamId(...); // → { ... } same sh
8484

8585
#### Error id catalogue
8686

87-
`cmc.errorIds` mirrors the server-side `CmcErrorIds` catalogue (24 stable kebab-case strings). Match on these constants when observing `trigger.content.failure.reason` instead of parsing English `error.message`.
87+
`cmc.errorIds` mirrors the server-side `CmcErrorIds` catalogue (31 stable kebab-case strings as of `@pryv/cmc@1.1.0`). Match on these constants when observing `trigger.content.failure.reason` or `error.data.id` from a failed `events.create` / `accesses.create` instead of parsing English `error.message`.
8888

89-
Examples: `cmc.errorIds.CAPABILITY_INVALID` (`'cmc-capability-invalid'`), `cmc.errorIds.CAPABILITY_CONSUMED`, `cmc.errorIds.CAPABILITY_INVALIDATED`, `cmc.errorIds.CAPABILITY_ALREADY_ACCEPTED_BY_YOU`, `cmc.errorIds.HANDLER_DELIVERY_FAILED`, etc. — see [`src/index.d.ts`](src/index.d.ts) for the full list.
89+
Lifecycle / handler / chat-routing examples: `cmc.errorIds.CAPABILITY_INVALID` (`'cmc-capability-invalid'`), `cmc.errorIds.CAPABILITY_CONSUMED`, `cmc.errorIds.CAPABILITY_INVALIDATED`, `cmc.errorIds.CAPABILITY_ALREADY_ACCEPTED_BY_YOU`, `cmc.errorIds.HANDLER_DELIVERY_FAILED`, `cmc.errorIds.CHAT_NO_REMOTE_APIENDPOINT`, etc.
90+
91+
**Added in `@pryv/cmc@1.1.0`** (server-side `open-pryv.io` ≥ 2.0.0-pre.4):
92+
93+
| Const | String | When you'll see it |
94+
|---|---|---|
95+
| `CAPABILITY_TTL_OUT_OF_RANGE` | `'cmc-capability-ttl-out-of-range'` | `createInvite({ expiresAt })` resolves to a TTL outside `[60s, 30d]`. Omit `expiresAt` to use the 7-day default. |
96+
| `HANDLER_MISSING_CAPABILITY_ID` | `'cmc-handler-missing-capability-id'` | Plugin handler couldn't find `content.capabilityId` on the trigger event. |
97+
| `CHAT_DISABLED` | `'cmc-chat-disabled'` | `sendChat` against a relationship whose negotiated `features.chat: false`. Default-permit on omission. |
98+
| `SYSTEM_MESSAGING_DISABLED` | `'cmc-system-messaging-disabled'` | `sendSystemAlert` / ack against `features.systemMessaging: false`. Scope-request / scope-update remain permitted regardless. |
99+
| `CLIENTDATA_CMC_FORBIDDEN` | `'cmc-clientdata-cmc-forbidden'` | `accesses.create` / `accesses.update` rejected user-supplied `clientData.cmc.*` (the namespace is plugin-owned). |
100+
| `RESERVED_STREAM_UNDELETABLE` | `'cmc-reserved-stream-undeletable'` | `streams.delete` rejected on a plugin-managed `:_cmc:*` parent (incl. personal-token deletes). |
101+
| `COUNTERPARTY_IDENTITY_MISSING` | `'cmc-counterparty-identity-missing'` | Peer-side `content.from` stamping hook rejected — the counterparty access lacks `{username,host}` (ops-level, shouldn't happen under normal flow). |
102+
103+
The full list lives in [`src/index.js`](src/index.js) (and the typed mirror in [`src/index.d.ts`](src/index.d.ts)).
90104

91105
`cmc.CmcError` is a typed `Error` subclass carrying `.id` (one of `errorIds.*`) and `.failure` (the server's raw `failure` object). It's thrown by `acceptInvite` on `status: 'failed'`.
92106

107+
#### Capability TTL bounds
108+
109+
The server bounds `content.request.expiresAt` (Unix seconds) to `[60s, 30d]` from now at mint time. Pass `expiresAt` to `cmc.createInvite()` to override the default 7-day lifetime; omit it for the default. Out-of-range values reject with `cmc-capability-ttl-out-of-range` before the capability access is minted.
110+
111+
#### Features negotiation
112+
113+
`cmc.createInvite({ features: { chat, systemMessaging } })` opts the relationship in or out of each cross-account channel.
114+
115+
- **Both default to `true`** when the key is omitted (matches the offer-side default).
116+
- Setting either to `false` is **binding on both sides at send time** — the recipient's plugin records the negotiation on the counterparty access's `clientData.cmc.features.*`, and subsequent `sendChat` / `sendSystemAlert` against the access reject with `cmc-chat-disabled` / `cmc-system-messaging-disabled` until a new invite negotiates it back on.
117+
- `cmc.scopes.{inbox, chats, collectors}` and `cmc.revokeRelationship` are unaffected — those are protocol surfaces, not message channels.
118+
93119
#### `pryv.utils.decomposeAPIEndpoint`
94120

95121
The companion `pryv.utils.decomposeAPIEndpoint(apiEndpoint, serviceInfoApi)` returns `{ token, username, host }` with `host` being the **canonical platform host** (no `<username>.` subdomain prefix). It's the right way to derive the `{ username, host }` arguments for `cmc.counterpartySlug`. It lives in `pryv.utils` (not `cmc.*`) because it's generally useful — see the [pryv README](../pryv#readme).

0 commit comments

Comments
 (0)