managarten/packages/shared-privacy
Till JS 5501f472ae feat(shared-privacy): M8.2 — unlisted-client + SharedLinkControls
Second milestone of the unlisted-share rollout. Backend endpoints
from M8.1 are now callable from the client, and a reusable
SharedLinkControls component is available for the detail views that
wire up in M8.3/M8.4.

Scope: shared primitives only. No module store integrates them yet —
that's the next step per module.

Changes:
- @mana/shared-privacy/unlisted-client.ts:
    publishUnlistedSnapshot(opts) → { token, url }
      Idempotent per (collection, recordId) — server reuses token on
      re-publish, so store code can call on every edit without caring
      whether it's first publish or refresh.
    revokeUnlistedSnapshot(opts)
      Idempotent — resolves silently even on { revoked: 0 }.
    buildShareUrl(origin, token)
      Convenience for UIs that already know the token.
    UnlistedApiError
      Thrown on non-2xx. Carries { status, code } so callers can
      distinguish 400 COLLECTION_NOT_ALLOWED vs 410 REVOKED vs
      500 UNKNOWN.
- @mana/shared-privacy/SharedLinkControls.svelte:
    Dumb presentational component. Props: token, url, expiresAt,
    onRegenerate, onRevoke, onExpiryChange (optional), disabled.
    Renders URL + copy, regenerate with confirm dialog, revoke,
    optional datetime-local expiry picker, debug token fingerprint.
    Clipboard-API fallback to prompt() for unsecure origins.
    QR-code button deferred to M8.5 polish.
- Exports added to index.ts: functions, error class, both types,
  SharedLinkControls component.
- 10 new unit tests (25 total): publish URL shape, headers, body,
  expiresAt serialisation, 4xx/5xx handling, trailing-slash
  trimming on apiUrl, revoke idempotence, buildShareUrl join.

Verified:
- pnpm --filter @mana/shared-privacy test: 25/25 green
- pnpm --filter @mana/shared-privacy check: 0 errors
- pnpm --filter @mana/web check: 7531 files, 0 errors

Next: M8.3 — wire Calendar through the new client.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-24 17:18:56 +02:00
..
src feat(shared-privacy): M8.2 — unlisted-client + SharedLinkControls 2026-04-24 17:18:56 +02:00
package.json feat(shared-privacy): M1 — visibility foundation package 2026-04-24 01:59:11 +02:00
tsconfig.json feat(shared-privacy): M1 — visibility foundation package 2026-04-24 01:59:11 +02:00