Files
Outpost/OutlineKit/Sources/OutlineKit/Models/OutlineShare.swift
T
Puranjay Savar Mattas 43f9d6052f fix(shares): match documented API shape, fill in list/revoke, harden share sheet
Share sheet errored "Got an unexpected response from the server" (a
client-side decode failure) on every open. OutlineShare only declared
5 fields against the real response's ~20, with url non-optional —
something in a real payload came back null and blew up the strict
decode, same class of bug as OutlinePin's history: self-hosted
responses keep diverging from what the hosted-app docs imply is
non-nullable.

- Rewrote OutlineShare to match the full documented shares.* response
  shape. Only id/published are trusted non-optional; everything else
  (documentTitle, sourceTitle, urlId, domain, title, iconUrl,
  includeChildDocuments, allowSubscriptions, allowIndexing,
  showLastUpdated, showTOC, views, createdBy, createdAt, updatedAt,
  lastAccessedAt) is optional so an unexpectedly-null field can't crash
  the decode again.
- shares.list and shares.revoke were never wrapped at all — added both.
- UpdateShareRequest was missing the documented title/iconUrl overrides.
- DocumentShareSheet: handles share.url being optional, adds a
  public-page title override field, adds a Revoke Link button
  (confirmation dialog, resets back to "Create Share Link" after).
- Removed dead DocumentReaderViewModel.share/loadShare()/
  createOrLoadShare() — never called by anything; DocumentShareSheet
  manages its own share state independently.
- Added a decode test using the exact payload from Outline's official
  shares.info docs, plus tests for shares.list and shares.revoke.

Branched fresh off main (post home-page merge) rather than continuing
on feature/home-page, to keep this its own PR.
2026-08-14 17:41:28 +01:00

42 lines
1.6 KiB
Swift

import Foundation
/// A public share link for a document or collection, backed by `shares.*`.
///
/// Only `id` and `published` are guaranteed present on every real share
/// object — everything else is modeled as optional even where the official
/// API docs don't explicitly mark it nullable, since self-hosted servers
/// have repeatedly diverged from the hosted app's documented response shape
/// (see `OutlinePin`'s history) and a single unexpectedly-null field used to
/// crash this decode entirely ("Got an unexpected response from the
/// server").
public struct OutlineShare: Decodable, Identifiable, Sendable {
public let id: String
public let published: Bool
public let documentId: String?
public let collectionId: String?
public let documentTitle: String?
public let documentUrl: String?
public let sourceTitle: String?
public let sourcePath: String?
public let urlId: String?
public let url: String?
public let domain: String?
/// Overrides the source document/collection title on the publicly
/// shared page, if set.
public let title: String?
/// Overrides the workspace branding icon on the publicly shared page,
/// if set.
public let iconUrl: String?
public let includeChildDocuments: Bool?
public let allowSubscriptions: Bool?
public let allowIndexing: Bool?
public let showLastUpdated: Bool?
public let showTOC: Bool?
public let views: Int?
public let createdBy: OutlineUser?
public let createdAt: Date?
public let updatedAt: Date?
public let lastAccessedAt: Date?
}