@openrails/contentkit-ui 0.79.0 → 0.81.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -54
- package/dist/client/beacons.d.ts +53 -0
- package/dist/client/beacons.js +72 -0
- package/dist/client/beacons.js.map +1 -0
- package/dist/client/catalog.d.ts +2 -2
- package/dist/client/catalog.js +1 -1
- package/dist/client/catalog.js.map +1 -1
- package/dist/client/client.d.ts +24 -11
- package/dist/client/client.js +37 -29
- package/dist/client/client.js.map +1 -1
- package/dist/client/content/comments.d.ts +12 -8
- package/dist/client/content/comments.js +33 -20
- package/dist/client/content/comments.js.map +1 -1
- package/dist/client/content/favorites.d.ts +24 -9
- package/dist/client/content/favorites.js +21 -22
- package/dist/client/content/favorites.js.map +1 -1
- package/dist/client/content/moderation.d.ts +1 -1
- package/dist/client/content/moderation.js.map +1 -1
- package/dist/client/content/reactions.d.ts +11 -6
- package/dist/client/content/reactions.js +23 -18
- package/dist/client/content/reactions.js.map +1 -1
- package/dist/client/content/types.d.ts +40 -21
- package/dist/client/content/types.js +5 -2
- package/dist/client/content/types.js.map +1 -1
- package/dist/client/contents.d.ts +55 -0
- package/dist/client/contents.js +144 -0
- package/dist/client/contents.js.map +1 -0
- package/dist/client/discovery.d.ts +126 -0
- package/dist/client/discovery.js +125 -0
- package/dist/client/discovery.js.map +1 -0
- package/dist/client/generated/error-codes.d.ts +1 -1
- package/dist/client/generated/error-codes.js +12 -0
- package/dist/client/generated/error-codes.js.map +1 -1
- package/dist/client/generated/routes.d.ts +1244 -370
- package/dist/client/generated/routes.js +1870 -554
- package/dist/client/generated/routes.js.map +1 -1
- package/dist/client/generated/wire.d.ts +960 -134
- package/dist/client/generated/wire.js.map +1 -1
- package/dist/client/group-fields.d.ts +25 -0
- package/dist/client/group-fields.js +63 -0
- package/dist/client/group-fields.js.map +1 -0
- package/dist/client/groups.d.ts +58 -0
- package/dist/client/groups.js +119 -0
- package/dist/client/groups.js.map +1 -0
- package/dist/client/http.d.ts +24 -12
- package/dist/client/http.js +20 -24
- package/dist/client/http.js.map +1 -1
- package/dist/client/index.d.ts +11 -6
- package/dist/client/media/api.d.ts +1 -1
- package/dist/client/media/api.js +4 -2
- package/dist/client/media/api.js.map +1 -1
- package/dist/client/media/client.d.ts +8 -9
- package/dist/client/media/client.js +58 -71
- package/dist/client/media/client.js.map +1 -1
- package/dist/client/media/ref.d.ts +30 -0
- package/dist/client/media/ref.js +10 -3
- package/dist/client/media/ref.js.map +1 -1
- package/dist/client/offers.d.ts +41 -0
- package/dist/client/offers.js +66 -0
- package/dist/client/offers.js.map +1 -0
- package/dist/client/route.d.ts +2 -0
- package/dist/client/route.js +2 -1
- package/dist/client/route.js.map +1 -1
- package/dist/client/versions.d.ts +20 -0
- package/dist/client/versions.js +53 -0
- package/dist/client/versions.js.map +1 -0
- package/dist/client.js +35 -30
- package/dist/components/admin/content-manager.d.ts +80 -0
- package/dist/components/admin/content-manager.js +591 -0
- package/dist/components/admin/content-manager.js.map +1 -0
- package/dist/components/admin/group-manager.d.ts +24 -0
- package/dist/components/admin/group-manager.js +244 -0
- package/dist/components/admin/group-manager.js.map +1 -0
- package/dist/components/admin/media-item-panel.js +1 -1
- package/dist/components/admin/media-item-panel.js.map +1 -1
- package/dist/components/content/card.d.ts +44 -0
- package/dist/components/content/card.js +285 -0
- package/dist/components/content/card.js.map +1 -0
- package/dist/components/content/editors.d.ts +40 -0
- package/dist/components/content/editors.js +764 -0
- package/dist/components/content/editors.js.map +1 -0
- package/dist/components/content/filters.d.ts +28 -0
- package/dist/components/content/filters.js +134 -0
- package/dist/components/content/filters.js.map +1 -0
- package/dist/components/content/grid.d.ts +62 -0
- package/dist/components/content/grid.js +233 -0
- package/dist/components/content/grid.js.map +1 -0
- package/dist/components/content/index.d.ts +8 -0
- package/dist/components/content/listing.d.ts +20 -0
- package/dist/components/content/listing.js +150 -0
- package/dist/components/content/listing.js.map +1 -0
- package/dist/components/content/offer-fields.d.ts +8 -0
- package/dist/components/content/offer-fields.js +127 -0
- package/dist/components/content/offer-fields.js.map +1 -0
- package/dist/components/content/paywall.d.ts +53 -0
- package/dist/components/content/paywall.js +221 -0
- package/dist/components/content/paywall.js.map +1 -0
- package/dist/components/content/search.d.ts +27 -0
- package/dist/components/content/search.js +164 -0
- package/dist/components/content/search.js.map +1 -0
- package/dist/components/groups/banner.d.ts +51 -0
- package/dist/components/groups/banner.js +194 -0
- package/dist/components/groups/banner.js.map +1 -0
- package/dist/components/groups/directory.d.ts +37 -0
- package/dist/components/groups/directory.js +117 -0
- package/dist/components/groups/directory.js.map +1 -0
- package/dist/components/groups/editor.d.ts +44 -0
- package/dist/components/groups/editor.js +860 -0
- package/dist/components/groups/editor.js.map +1 -0
- package/dist/components/groups/fields.d.ts +13 -0
- package/dist/components/groups/fields.js +68 -0
- package/dist/components/groups/fields.js.map +1 -0
- package/dist/components/groups/header.d.ts +25 -0
- package/dist/components/groups/header.js +131 -0
- package/dist/components/groups/header.js.map +1 -0
- package/dist/components/groups/index.d.ts +6 -0
- package/dist/components/groups/memberships.d.ts +55 -0
- package/dist/components/groups/memberships.js +527 -0
- package/dist/components/groups/memberships.js.map +1 -0
- package/dist/components/groups/parts.d.ts +49 -0
- package/dist/components/groups/parts.js +172 -0
- package/dist/components/groups/parts.js.map +1 -0
- package/dist/components/media-folder-editor.js +153 -152
- package/dist/components/media-folder-editor.js.map +1 -1
- package/dist/components/social/comments.d.ts +7 -5
- package/dist/components/social/comments.js +6 -2
- package/dist/components/social/comments.js.map +1 -1
- package/dist/components/social/engagement.d.ts +4 -3
- package/dist/components/social/engagement.js.map +1 -1
- package/dist/components/social/moderation.d.ts +1 -1
- package/dist/components/social/moderation.js +3 -3
- package/dist/components/social/moderation.js.map +1 -1
- package/dist/editor/rich-text-editor.d.ts +4 -4
- package/dist/editor/rich-text-editor.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.js +23 -9
- package/dist/locales/admin/de.js +5 -66
- package/dist/locales/admin/de.js.map +1 -1
- package/dist/locales/admin/en.d.ts +5 -66
- package/dist/locales/admin/en.js +19 -80
- package/dist/locales/admin/en.js.map +1 -1
- package/dist/locales/admin/es.js +5 -66
- package/dist/locales/admin/es.js.map +1 -1
- package/dist/locales/admin/ja.js +5 -66
- package/dist/locales/admin/ja.js.map +1 -1
- package/dist/locales/admin/ko.js +5 -66
- package/dist/locales/admin/ko.js.map +1 -1
- package/dist/locales/admin/zh.js +5 -66
- package/dist/locales/admin/zh.js.map +1 -1
- package/dist/locales/content/de.d.ts +2 -0
- package/dist/locales/content/de.js +98 -0
- package/dist/locales/content/de.js.map +1 -0
- package/dist/locales/content/en.d.ts +93 -0
- package/dist/locales/content/en.js +98 -0
- package/dist/locales/content/en.js.map +1 -0
- package/dist/locales/content/es.d.ts +2 -0
- package/dist/locales/content/es.js +98 -0
- package/dist/locales/content/es.js.map +1 -0
- package/dist/locales/content/ja.d.ts +2 -0
- package/dist/locales/content/ja.js +98 -0
- package/dist/locales/content/ja.js.map +1 -0
- package/dist/locales/content/ko.d.ts +2 -0
- package/dist/locales/content/ko.js +98 -0
- package/dist/locales/content/ko.js.map +1 -0
- package/dist/locales/content/zh.d.ts +2 -0
- package/dist/locales/content/zh.js +98 -0
- package/dist/locales/content/zh.js.map +1 -0
- package/dist/locales/de.js +11 -2
- package/dist/locales/de.js.map +1 -1
- package/dist/locales/discovery/de.d.ts +2 -0
- package/dist/locales/discovery/de.js +68 -0
- package/dist/locales/discovery/de.js.map +1 -0
- package/dist/locales/discovery/en.d.ts +63 -0
- package/dist/locales/discovery/en.js +68 -0
- package/dist/locales/discovery/en.js.map +1 -0
- package/dist/locales/discovery/es.d.ts +2 -0
- package/dist/locales/discovery/es.js +68 -0
- package/dist/locales/discovery/es.js.map +1 -0
- package/dist/locales/discovery/ja.d.ts +2 -0
- package/dist/locales/discovery/ja.js +68 -0
- package/dist/locales/discovery/ja.js.map +1 -0
- package/dist/locales/discovery/ko.d.ts +2 -0
- package/dist/locales/discovery/ko.js +68 -0
- package/dist/locales/discovery/ko.js.map +1 -0
- package/dist/locales/discovery/zh.d.ts +2 -0
- package/dist/locales/discovery/zh.js +68 -0
- package/dist/locales/discovery/zh.js.map +1 -0
- package/dist/locales/en.d.ts +288 -67
- package/dist/locales/en.js +11 -2
- package/dist/locales/en.js.map +1 -1
- package/dist/locales/es.js +11 -2
- package/dist/locales/es.js.map +1 -1
- package/dist/locales/groups/de.d.ts +2 -0
- package/dist/locales/groups/de.js +133 -0
- package/dist/locales/groups/de.js.map +1 -0
- package/dist/locales/groups/en.d.ts +128 -0
- package/dist/locales/groups/en.js +133 -0
- package/dist/locales/groups/en.js.map +1 -0
- package/dist/locales/groups/es.d.ts +2 -0
- package/dist/locales/groups/es.js +133 -0
- package/dist/locales/groups/es.js.map +1 -0
- package/dist/locales/groups/ja.d.ts +2 -0
- package/dist/locales/groups/ja.js +133 -0
- package/dist/locales/groups/ja.js.map +1 -0
- package/dist/locales/groups/ko.d.ts +2 -0
- package/dist/locales/groups/ko.js +133 -0
- package/dist/locales/groups/ko.js.map +1 -0
- package/dist/locales/groups/zh.d.ts +2 -0
- package/dist/locales/groups/zh.js +133 -0
- package/dist/locales/groups/zh.js.map +1 -0
- package/dist/locales/ja.js +11 -2
- package/dist/locales/ja.js.map +1 -1
- package/dist/locales/ko.js +11 -2
- package/dist/locales/ko.js.map +1 -1
- package/dist/locales/social/de.js +2 -1
- package/dist/locales/social/de.js.map +1 -1
- package/dist/locales/social/en.d.ts +2 -1
- package/dist/locales/social/en.js +2 -1
- package/dist/locales/social/en.js.map +1 -1
- package/dist/locales/social/es.js +2 -1
- package/dist/locales/social/es.js.map +1 -1
- package/dist/locales/social/ja.js +2 -1
- package/dist/locales/social/ja.js.map +1 -1
- package/dist/locales/social/ko.js +2 -1
- package/dist/locales/social/ko.js.map +1 -1
- package/dist/locales/social/zh.js +2 -1
- package/dist/locales/social/zh.js.map +1 -1
- package/dist/locales/zh.js +11 -2
- package/dist/locales/zh.js.map +1 -1
- package/dist/react/admin.d.ts +1 -1
- package/dist/react/admin.js +8 -6
- package/dist/react/admin.js.map +1 -1
- package/dist/react/comments.d.ts +9 -7
- package/dist/react/comments.js +42 -27
- package/dist/react/comments.js.map +1 -1
- package/dist/react/contents.d.ts +57 -0
- package/dist/react/contents.js +214 -0
- package/dist/react/contents.js.map +1 -0
- package/dist/react/context.d.ts +1 -1
- package/dist/react/context.js.map +1 -1
- package/dist/react/crop.js +45 -44
- package/dist/react/crop.js.map +1 -1
- package/dist/react/detail.d.ts +30 -0
- package/dist/react/detail.js +42 -0
- package/dist/react/detail.js.map +1 -0
- package/dist/react/discovery.d.ts +138 -0
- package/dist/react/discovery.js +299 -0
- package/dist/react/discovery.js.map +1 -0
- package/dist/react/engagement.d.ts +5 -5
- package/dist/react/engagement.js +55 -41
- package/dist/react/engagement.js.map +1 -1
- package/dist/react/folder.js +54 -53
- package/dist/react/folder.js.map +1 -1
- package/dist/react/groups.d.ts +115 -0
- package/dist/react/groups.js +229 -0
- package/dist/react/groups.js.map +1 -0
- package/dist/react/index.d.ts +5 -1
- package/dist/react/public.d.ts +6 -5
- package/dist/react/public.js +19 -22
- package/dist/react/public.js.map +1 -1
- package/dist/react/read.js +105 -106
- package/dist/react/read.js.map +1 -1
- package/dist/react/resources.d.ts +2 -2
- package/dist/react/resources.js +69 -40
- package/dist/react/resources.js.map +1 -1
- package/dist/react/store.js +41 -39
- package/dist/react/store.js.map +1 -1
- package/dist/react/upload.js +54 -53
- package/dist/react/upload.js.map +1 -1
- package/dist/react/use-resource.d.ts +2 -1
- package/dist/react/use-resource.js +1 -0
- package/dist/react/use-resource.js.map +1 -1
- package/dist/react/versions.d.ts +57 -0
- package/dist/react/versions.js +94 -0
- package/dist/react/versions.js.map +1 -0
- package/dist/react/video.js +87 -86
- package/dist/react/video.js.map +1 -1
- package/dist/react.js +9 -5
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/dist/client/content/posts.d.ts +0 -52
- package/dist/client/content/posts.js +0 -84
- package/dist/client/content/posts.js.map +0 -1
- package/dist/client/taxonomy.d.ts +0 -34
- package/dist/client/taxonomy.js +0 -84
- package/dist/client/taxonomy.js.map +0 -1
- package/dist/components/admin/post-manager.d.ts +0 -45
- package/dist/components/admin/post-manager.js +0 -602
- package/dist/components/admin/post-manager.js.map +0 -1
- package/dist/components/admin/taxonomy-manager.d.ts +0 -54
- package/dist/components/admin/taxonomy-manager.js +0 -976
- package/dist/components/admin/taxonomy-manager.js.map +0 -1
- package/dist/react/posts.d.ts +0 -61
- package/dist/react/posts.js +0 -183
- package/dist/react/posts.js.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"wire.js","names":[],"sources":["../../../src/client/generated/wire.ts"],"sourcesContent":["// Generated by `go generate ./internal/contract` from ContentKit's route catalog. Do not edit.\n\nimport type { ErrorCode } from \"./error-codes.js\";\n\nexport type { ErrorCode };\n\n// Upload sizes: one PUT up to MAX_SINGLE_PUT bytes, else multipart parts.\nexport const MAX_SINGLE_PUT = 67108864;\nexport const MIN_PART_SIZE = 8388608;\nexport const MAX_PART_SIZE = 16777216;\n\nexport type OpName = \"put\" | \"edit\" | \"move\" | \"rename\" | \"remove\" | \"attach\" | \"copy\" | \"frame\" | \"meta\" | \"regenerate\";\nexport type Access = \"full\" | \"none\";\nexport type ItemState = \"ready\" | \"processing\" | \"failed\";\nexport type EncodePhase = \"queued\" | \"downloading\" | \"probing\" | \"encoding\" | \"muxing\" | \"uploading\" | \"publishing\" | \"images\";\nexport type PollKind = \"multiple_choice\" | \"free_text\";\nexport type ModerationState = \"approved\" | \"held\" | \"rejected\";\n\nexport interface AdminComment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n deleted_at?: string;\n}\n\nexport interface Anonymous {\n comments: boolean;\n reactions: boolean;\n votes: boolean;\n}\n\nexport interface Assignment {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n taxonomy_id: string;\n relation: string;\n state?: \"active\" | \"proposed\";\n source_revision: number;\n}\n\nexport interface AssignmentPage {\n assignments: Assignment[];\n next_cursor?: string;\n}\n\nexport interface AssignmentsWritten {\n assignments: number;\n}\n\nexport interface BanInput {\n reason?: string;\n until?: string;\n}\n\nexport interface BanNotice {\n scope: string;\n reason?: string;\n until?: string;\n}\n\nexport interface Comment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CommentBan {\n user_id: string;\n user?: PublicUser;\n scope: string;\n reason?: string;\n until?: string;\n banned_by: string;\n banned_at: string;\n expired: boolean;\n}\n\nexport interface CommentEdit {\n body: string;\n}\n\nexport interface CommentInput {\n body: string;\n reply_to_id?: string;\n anon_name?: string;\n}\n\nexport interface CommentStanding {\n can_comment: boolean;\n ban?: BanNotice;\n anonymous: boolean;\n max_length: number;\n user_id?: string;\n moderate: boolean;\n ban_scopes: (\"global\" | \"owner\")[];\n}\n\nexport interface CommitBody {\n ref: RefBody;\n operation_id: string;\n ops: Op[];\n}\n\nexport interface CommitReply {\n files: FileInfo[];\n}\n\nexport interface CompleteReply {\n blob: string;\n type: string;\n size: number;\n}\n\nexport interface Config {\n anonymous: Anonymous;\n comment_max_length: number;\n}\n\nexport interface ContentRef {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface CopyFrom {\n id: string;\n path: string;\n}\n\nexport interface Count {\n content_kind: string;\n language: string;\n count: number;\n}\n\nexport interface CountsRebuilt {\n nodes: number;\n}\n\nexport interface Crop {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface Edge {\n from_taxonomy_id: string;\n relation: \"alias_of\" | \"artist_of\" | \"child\" | \"member_of\" | \"parent\" | \"synonym\" | \"voice_of\";\n to_taxonomy_id: string;\n source_revision: number;\n}\n\nexport interface EdgesWritten {\n edges: number;\n}\n\nexport interface Edit {\n crop?: Crop;\n rotate?: number;\n}\n\nexport interface EffectiveTag {\n taxonomy_id: string;\n kind: string;\n slug: string;\n relation: string;\n scope: \"content\" | \"version\";\n}\n\nexport interface EffectiveTagsOf {\n content: ContentRef;\n tags: EffectiveTag[];\n}\n\nexport interface EncodeProgress {\n phase: EncodePhase;\n queue_position?: number;\n segments_done?: number;\n segments_total?: number;\n percent: number;\n speed?: number;\n eta?: number;\n at: number;\n stalled?: boolean;\n stage?: number;\n stages?: number;\n}\n\nexport interface ErrorDetails {\n width?: number;\n height?: number;\n min_width?: number;\n max_pixels?: number;\n type?: string;\n allowed?: string[];\n size?: number;\n max_bytes?: number;\n frames?: number;\n max_frames?: number;\n seconds?: number;\n max_seconds?: number;\n min_aspect?: number;\n max_aspect?: number;\n max?: number;\n}\n\nexport interface ErrorReply {\n error: string;\n code: ErrorCode;\n retry_after?: number;\n action?: \"comment\" | \"comment_reaction\" | \"favorite\" | \"poll_vote\" | \"post_reaction\" | \"reaction\";\n ban?: BanNotice;\n blobs?: string[];\n details?: ErrorDetails;\n}\n\nexport interface Failure {\n of: string;\n message: string;\n code?: ErrorCode;\n details?: ErrorDetails;\n}\n\nexport interface FavoriteItem {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n created_at: string;\n}\n\nexport interface FavoriteState {\n favorited: boolean;\n count: number;\n}\n\nexport interface FeedItem {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface FileInfo {\n path: string;\n type: string;\n size?: number;\n w?: number;\n h?: number;\n dur?: number;\n download?: string;\n url?: string;\n locked?: boolean;\n upload?: boolean;\n staged?: boolean;\n from?: string;\n edit?: Edit;\n frame?: Frame;\n meta?: Record<string, unknown>;\n unattached?: boolean;\n pending?: string[];\n failed?: Failure;\n editor_url?: string;\n progress?: EncodeProgress;\n}\n\nexport interface Frame {\n t?: number;\n auto?: boolean;\n of?: string;\n}\n\nexport interface Group {\n id: string;\n label: string;\n count: number;\n}\n\nexport interface HeldItem {\n kind: string;\n revision: number;\n id: string;\n ref: ContentRef;\n author_id?: string;\n author?: PublicUser;\n anon_name?: string;\n title?: string;\n body: string;\n reason: string;\n model?: string;\n prompt_version?: string;\n confidence?: number;\n error?: string;\n held_at: string;\n created_at: string;\n}\n\nexport interface HeldPage {\n items: HeldItem[];\n next?: string;\n}\n\nexport interface ImageInput {\n image?: string;\n}\n\nexport interface InlineImage {\n ref: string;\n url: string | null;\n}\n\nexport interface Item {\n id: string;\n recipient: Recipient;\n origin: Origin;\n kind: string;\n data: unknown;\n created_at: string;\n status?: string;\n action_requested?: boolean;\n severity?: string;\n read_at: string | null;\n dismissed_at: string | null;\n resolved_at: string | null;\n updated_at: string;\n revision: number;\n}\n\nexport interface LanguageTotal {\n public: number;\n tiers: Record<string, number>;\n}\n\nexport interface MergeInput {\n into_taxonomy_id: string;\n}\n\nexport interface MergeReport {\n from_taxonomy_id: string;\n into_taxonomy_id: string;\n assignments_moved: number;\n names_moved: number;\n edges_rewritten: number;\n assignments_merged: number;\n}\n\nexport interface MultipartReply {\n ticket: string;\n min_part_size: number;\n max_part_size: number;\n max_parts: number;\n}\n\nexport interface Name {\n language: string;\n kind: \"alias\" | \"name\";\n name: string;\n normalized?: string;\n source_revision: number;\n}\n\nexport interface Node {\n taxonomy_id: string;\n tenant_id: string;\n kind: string;\n slug: string;\n state: \"active\" | \"deleted\" | \"merged\";\n source_revision: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface NodeDetail {\n taxonomy_id: string;\n tenant_id: string;\n kind: string;\n slug: string;\n state: \"active\" | \"deleted\" | \"merged\";\n source_revision: number;\n created_at: string;\n updated_at: string;\n names: Name[];\n edges: Edge[];\n counts: Count[];\n}\n\nexport interface NodeInput {\n taxonomy_id?: string;\n kind: string;\n slug: string;\n names?: Name[];\n source_revision: number;\n}\n\nexport interface NodePage {\n nodes: NodeRow[];\n next_cursor?: string;\n total: number;\n}\n\nexport interface NodeRow {\n taxonomy_id: string;\n tenant_id: string;\n kind: string;\n slug: string;\n state: \"active\" | \"deleted\" | \"merged\";\n source_revision: number;\n created_at: string;\n updated_at: string;\n name?: string;\n name_language?: string;\n count: number;\n}\n\nexport interface NodeUpdate {\n slug?: string;\n state?: \"active\" | \"deleted\" | \"merged\";\n source_revision?: number;\n}\n\nexport interface Op {\n op: OpName;\n path?: string;\n blob?: string;\n create_id?: string;\n index?: number;\n meta?: Record<string, unknown>;\n edit?: Edit;\n unattached?: boolean;\n to?: string;\n from?: CopyFrom;\n t?: number;\n auto?: boolean;\n preset?: string;\n force?: boolean;\n takedown?: boolean;\n}\n\nexport interface Origin {\n system: string;\n scope: string;\n id: string;\n subject?: string;\n}\n\nexport interface Page {\n items: Item[];\n next_cursor?: string;\n}\n\nexport interface PartBody {\n number: number;\n size: number;\n sha256: string;\n}\n\nexport interface PartReply {\n number: number;\n size?: number;\n sha256?: string;\n request?: RequestReply;\n}\n\nexport interface PartsBody {\n ticket: string;\n parts: PartBody[];\n}\n\nexport interface PartsReply {\n parts: PartReply[];\n}\n\nexport interface Poll {\n id: string;\n kind: PollKind;\n question: string;\n language: string;\n is_active: boolean;\n image_url?: string;\n live_at: string;\n closes_at?: string;\n closed: boolean;\n total_votes: number;\n options: PollOption[];\n voted: boolean;\n my_option?: string;\n answer_count?: number;\n groups?: Group[];\n my_answer?: PollAnswer;\n}\n\nexport interface PollAnswer {\n id: string;\n text: string;\n classified: boolean;\n updated_at: string;\n}\n\nexport interface PollAnswerInput {\n text: string;\n}\n\nexport interface PollImage {\n image_url: string | null;\n}\n\nexport interface PollInput {\n kind?: PollKind;\n question: string;\n language: string;\n live_at?: string;\n closes_at?: string;\n options?: PollOptionInput[];\n}\n\nexport interface PollOption {\n id: string;\n label: string;\n image_url?: string;\n position: number;\n vote_count: number;\n}\n\nexport interface PollOptionInput {\n label: string;\n position: number;\n}\n\nexport interface PollOptionPatch {\n label?: string;\n position?: number;\n}\n\nexport interface PollUpdate {\n question?: string;\n is_active?: boolean;\n live_at?: string;\n closes_at?: string | null;\n}\n\nexport interface PollVote {\n option_id: string;\n}\n\nexport interface Post {\n id: string;\n author_id: string;\n title: string;\n slug?: string;\n body: string;\n excerpt?: string;\n cover?: string;\n cover_url?: string;\n images?: Record<string, string>;\n language: string;\n is_draft: boolean;\n live_at?: string;\n total_likes: number;\n total_dislikes: number;\n comment_count: number;\n moderation?: ModerationState;\n moderation_reason?: string;\n code: string;\n url_slug: string;\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\nexport interface PostCover {\n cover_url: string | null;\n}\n\nexport interface PostInput {\n title?: string;\n body?: string;\n excerpt?: string;\n language?: string;\n slug?: string;\n is_draft?: boolean;\n live_at?: string;\n}\n\nexport interface PresetRule {\n kind: string;\n name: string;\n from: string;\n base: string;\n namespace: string;\n to: string;\n widths: number[];\n aspect?: string;\n min_width?: number;\n first?: number;\n default: boolean;\n}\n\nexport interface PresignBody {\n ref: RefBody;\n path: string;\n type: string;\n size: number;\n sha256: string;\n}\n\nexport interface PresignReply {\n path: string;\n blob: string;\n exists?: boolean;\n put?: RequestReply;\n multipart?: MultipartReply;\n process_on_upload?: boolean;\n}\n\nexport interface PublicImage {\n from: string;\n preset: string;\n renditions: PublicRendition[];\n}\n\nexport interface PublicRendition {\n url: string;\n w: number;\n h: number;\n}\n\nexport interface PublicUser {\n id: string;\n name?: string;\n username: string;\n avatar?: string;\n avatar_srcset?: string;\n}\n\nexport interface ReactionCounts {\n likes: number;\n dislikes: number;\n mine: number;\n}\n\nexport interface ReadResult {\n access: Access;\n expires: number;\n meta?: Record<string, unknown>;\n previews?: string[];\n public?: PublicImage[];\n total: number;\n offset: number;\n limit: number;\n hls?: string[];\n state?: ItemState;\n full?: boolean;\n uploads?: UploadRule[];\n files: FileInfo[];\n}\n\nexport interface Recipient {\n audience: string;\n id: string;\n}\n\nexport interface RefBody {\n kind: string;\n id: string;\n}\n\nexport interface RequestReply {\n method: string;\n url: string;\n headers: Record<string, string>;\n expires: string;\n}\n\nexport interface ResolveInput {\n decision: \"approve\" | \"reject\" | \"review\";\n revision: number;\n reason?: string;\n}\n\nexport interface Resolved {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n code: string;\n slug: string;\n slugs?: Record<string, string>;\n path: string;\n}\n\nexport interface Restored {\n restored: boolean;\n}\n\nexport interface ReviewOutcome {\n decision: \"approve\" | \"reject\" | \"review\";\n}\n\nexport interface TicketBody {\n ticket: string;\n}\n\nexport interface Total {\n public: number;\n tiers: Record<string, number>;\n languages: Record<string, LanguageTotal>;\n}\n\nexport interface Totals {\n kinds: Record<string, Total>;\n}\n\nexport interface UploadRule {\n path: string;\n types: string[];\n max_bytes: number;\n max?: number;\n named?: boolean;\n frames?: string;\n aspect?: string;\n min_width?: number;\n video?: VideoLimits;\n min_aspect?: number;\n max_aspect?: number;\n}\n\nexport interface VideoLimits {\n max_seconds?: number;\n max_fps?: number;\n max_pixels?: number;\n max_work?: number;\n}\n"],"mappings":";AAOA,IAAa,IAAiB,UACjB,IAAgB,SAChB,IAAgB"}
|
|
1
|
+
{"version":3,"file":"wire.js","names":[],"sources":["../../../src/client/generated/wire.ts"],"sourcesContent":["// Generated by `go generate ./internal/contract` from ContentKit's route catalog. Do not edit.\n\nimport type { ErrorCode } from \"./error-codes.js\";\n\nexport type { ErrorCode };\n\n// Upload sizes: one PUT up to MAX_SINGLE_PUT bytes, else multipart parts.\nexport const MAX_SINGLE_PUT = 67108864;\nexport const MIN_PART_SIZE = 8388608;\nexport const MAX_PART_SIZE = 16777216;\n\nexport type OpName = \"put\" | \"edit\" | \"move\" | \"rename\" | \"remove\" | \"attach\" | \"copy\" | \"frame\" | \"meta\" | \"regenerate\";\nexport type Access = \"full\" | \"none\";\nexport type ItemState = \"ready\" | \"processing\" | \"failed\";\nexport type EncodePhase = \"queued\" | \"downloading\" | \"probing\" | \"encoding\" | \"muxing\" | \"uploading\" | \"publishing\" | \"images\";\nexport type PollKind = \"multiple_choice\" | \"free_text\";\nexport type ModerationState = \"approved\" | \"held\" | \"rejected\";\nexport type ContentState = \"draft\" | \"published\" | \"deleted\";\nexport type VersionState = \"draft\" | \"published\";\nexport type Listing = \"listed\" | \"members\" | \"unlisted\";\n\nexport interface AdminComment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n deleted_at?: string;\n}\n\nexport interface AliasRecord {\n kind: string;\n key: string;\n locator?: string;\n target: TargetRef;\n}\n\nexport interface Anchor {\n id: string;\n page: string;\n offset_percent: number;\n duration_seconds?: number;\n}\n\nexport interface Anonymous {\n comments: boolean;\n reactions: boolean;\n votes: boolean;\n}\n\nexport interface AnswerGroup {\n id: string;\n label: string;\n count: number;\n}\n\nexport interface AnswerRecord {\n poll: Ref;\n user_id: string;\n text: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface Attribute {\n type: string;\n values?: string[];\n filterable?: boolean;\n sortable?: boolean;\n}\n\nexport interface Avatar {\n image?: string;\n renditions?: Rendition[];\n}\n\nexport interface BackgroundCue {\n file: string;\n from_page?: string;\n to_page?: string;\n from_anchor?: string;\n to_anchor?: string;\n loop?: boolean;\n layer?: string;\n}\n\nexport interface BanInput {\n reason?: string;\n until?: string;\n}\n\nexport interface BanNotice {\n scope: string;\n reason?: string;\n until?: string;\n}\n\nexport interface BannedWord {\n word: string;\n action: \"mask\" | \"reject\";\n created_by: string;\n created_at: string;\n}\n\nexport interface BannedWordInput {\n word: string;\n action?: \"mask\" | \"reject\";\n}\n\nexport interface Batch {\n source: string;\n preference_floor?: number;\n provision_scopes?: boolean;\n groups?: GroupRecord[];\n contents?: ContentRecord[];\n memberships?: MembershipSet[];\n offers?: OfferRecord[];\n aliases?: AliasRecord[];\n comments?: CommentRecord[];\n reactions?: ReactionRecord[];\n favorites?: FavoriteRecord[];\n polls?: PollRecord[];\n votes?: VoteRecord[];\n answers?: AnswerRecord[];\n signals?: SignalRecord[];\n}\n\nexport interface Card {\n id: string;\n kind: string;\n code: string;\n path: string;\n title: string;\n language: string;\n cover: PublicRendition[];\n version: CardVersion;\n groups: Record<string, Chip[]>;\n owner?: GroupCard;\n counts: Counts;\n access: CardAccess;\n viewer?: ViewerState;\n published_at?: string;\n attributes: Record<string, unknown>;\n}\n\nexport interface CardAccess {\n allowed: boolean;\n unknown?: boolean;\n sell?: string[];\n requires?: string;\n preview?: Preview;\n free_after?: string;\n offers?: Sale[];\n}\n\nexport interface CardVersion {\n id: string;\n languages: string[];\n traits: string[];\n label?: string;\n pages?: number;\n duration_ms?: number;\n}\n\nexport interface CatalogCover {\n image: string;\n url?: string;\n}\n\nexport interface CatalogText {\n title: string;\n slug?: string;\n description?: string;\n body?: string;\n sort_key?: string;\n aliases?: string[];\n}\n\nexport interface Chip {\n id: string;\n slug: string;\n name: string;\n path?: string;\n}\n\nexport interface Comment {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CommentBan {\n user_id: string;\n user?: PublicUser;\n scope: string;\n reason?: string;\n until?: string;\n banned_by: string;\n banned_at: string;\n expired: boolean;\n}\n\nexport interface CommentEdit {\n body: string;\n}\n\nexport interface CommentInput {\n body: string;\n reply_to_id?: string;\n anon_name?: string;\n language?: string;\n}\n\nexport interface CommentRecord {\n external_id: string;\n id?: string;\n target: TargetRef;\n language?: string;\n reply_to?: Ref;\n user_id?: string;\n anon_name?: string;\n body: string;\n deleted_at?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface CommentStanding {\n can_comment: boolean;\n comments: string;\n ban?: BanNotice;\n anonymous: boolean;\n max_length: number;\n user_id?: string;\n moderate: boolean;\n ban_scopes: (\"global\" | \"owner\")[];\n}\n\nexport interface CommitBody {\n ref: RefBody;\n operation_id: string;\n ops: Op[];\n}\n\nexport interface CommitReply {\n files: FileInfo[];\n}\n\nexport interface CompleteReply {\n blob: string;\n type: string;\n size: number;\n}\n\nexport interface Config {\n anonymous: Anonymous;\n comment_max_length: number;\n}\n\nexport interface Content {\n id: string;\n kind: string;\n code: string;\n path: string;\n language: string;\n title: string;\n slug?: string;\n description?: string;\n body?: string;\n decision: Decision;\n images?: Record<string, string>;\n cover?: CatalogCover;\n state: ContentState;\n listing: Listing;\n comments: string;\n publish_at?: string;\n published_at?: string;\n live: boolean;\n access: Rule;\n restrictions: string[];\n attributes: Record<string, unknown>;\n owner_group_id?: string;\n owner?: GroupCard;\n creators: Creator[];\n groups: GroupSummary[];\n versions: Version[];\n editor: boolean;\n text?: Record<string, CatalogText>;\n moderation?: ModerationState;\n moderation_reason?: string;\n ever_sold?: boolean;\n offer?: Offer;\n revision: number;\n created_at: string;\n updated_at: string;\n deleted_at?: string;\n}\n\nexport interface ContentFilter {\n group: GroupRef;\n default_visible: boolean;\n labels?: Record<string, string>;\n}\n\nexport interface ContentFilterState {\n group: GroupCard;\n label: string;\n default_visible: boolean;\n visible: boolean;\n overridden: boolean;\n}\n\nexport interface ContentFilters {\n filters: ContentFilterState[];\n include_deleted: boolean;\n}\n\nexport interface ContentFiltersUpdate {\n filters: FilterSetting[];\n include_deleted: boolean;\n}\n\nexport interface ContentGroups {\n kinds?: string[];\n memberships: Membership[];\n}\n\nexport interface ContentInput {\n kind: string;\n text?: Record<string, CatalogText>;\n listing?: Listing;\n comments?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n owner_group_id?: string;\n creators?: Creator[];\n versions?: VersionInput[];\n}\n\nexport interface ContentMemberships {\n content_id: string;\n memberships: Membership[];\n groups: GroupCard[];\n}\n\nexport interface ContentModel {\n languages: string[];\n tiers: string[];\n kinds: Record<string, Kind>;\n group_kinds: Record<string, GroupKind>;\n content_filters: ContentFilter[];\n}\n\nexport interface ContentPage {\n contents: Card[];\n next_cursor?: string;\n}\n\nexport interface ContentPatch {\n listing?: Listing;\n comments?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n creators?: Creator[];\n cover?: string;\n revision?: number;\n}\n\nexport interface ContentRecord {\n external_id: string;\n id?: string;\n kind: string;\n state: string;\n publish_at?: string;\n published_at?: string;\n deleted_at?: string;\n listing?: string;\n access?: Rule;\n restrictions?: string[];\n attributes?: Record<string, unknown>;\n owner_group?: Ref;\n cover?: string;\n creators?: Creator[];\n text?: Record<string, CatalogText>;\n versions?: VersionRecord[];\n code?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ContentRef {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface CopyBody {\n ref: RefBody;\n files: CopyRequest[];\n}\n\nexport interface CopyFrom {\n id: string;\n version?: string;\n path: string;\n}\n\nexport interface CopyReply {\n files: StagedCopy[];\n}\n\nexport interface CopyRequest {\n path: string;\n type: string;\n from: string;\n size?: number;\n}\n\nexport interface Count {\n content_kind: string;\n language: string;\n count: number;\n}\n\nexport interface Counts {\n likes: number;\n dislikes: number;\n favorites: number;\n views: number;\n}\n\nexport interface Creator {\n user_id: string;\n role?: string;\n position: number;\n}\n\nexport interface CreatorsInput {\n creators: Creator[];\n}\n\nexport interface Crop {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface DateCount {\n date: string;\n count: number;\n free: number;\n}\n\nexport interface Decision {\n allowed: boolean;\n unknown?: boolean;\n sell?: string[];\n requires?: string;\n preview?: Preview;\n free_after?: string;\n offers?: Sale[];\n}\n\nexport interface Edge {\n from: string;\n relation: string;\n to: string;\n}\n\nexport interface EdgeInput {\n relation: string;\n to: string;\n}\n\nexport interface EdgeRecord {\n relation: string;\n to: Ref;\n}\n\nexport interface Edit {\n crop?: Crop;\n rotate?: number;\n}\n\nexport interface EncodeProgress {\n phase: EncodePhase;\n queue_position?: number;\n segments_done?: number;\n segments_total?: number;\n percent: number;\n speed?: number;\n eta?: number;\n at: number;\n stalled?: boolean;\n stage?: number;\n stages?: number;\n}\n\nexport interface ErrorDetails {\n width?: number;\n height?: number;\n min_width?: number;\n max_pixels?: number;\n type?: string;\n allowed?: string[];\n size?: number;\n max_bytes?: number;\n frames?: number;\n max_frames?: number;\n seconds?: number;\n max_seconds?: number;\n min_aspect?: number;\n max_aspect?: number;\n max?: number;\n}\n\nexport interface ErrorReply {\n error: string;\n code: ErrorCode;\n retry_after?: number;\n action?: \"comment\" | \"comment_reaction\" | \"favorite\" | \"poll_vote\" | \"reaction\";\n ban?: BanNotice;\n blobs?: string[];\n details?: ErrorDetails;\n}\n\nexport interface ExposureInput {\n render_id: string;\n stage: string;\n revision?: number;\n query_id?: string;\n surface?: string;\n ranker?: string;\n language?: string;\n occurred_at?: string;\n shown: Placement[];\n}\n\nexport interface Exposures {\n session?: string;\n exposures: ExposureInput[];\n}\n\nexport interface Failure {\n of: string;\n message: string;\n code?: ErrorCode;\n details?: ErrorDetails;\n}\n\nexport interface FavoriteRecord {\n target: TargetRef;\n user_id: string;\n created_at?: string;\n}\n\nexport interface FavoriteState {\n favorited: boolean;\n count: number;\n}\n\nexport interface FeedItem {\n id: string;\n reply_to_id?: string;\n user_id?: string;\n anon_name?: string;\n language?: string;\n body: string;\n deleted: boolean;\n likes: number;\n dislikes: number;\n mine: number;\n reply_count: number;\n author?: PublicUser;\n moderation?: ModerationState;\n moderation_reason?: string;\n created_at: string;\n updated_at: string;\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n}\n\nexport interface FileInfo {\n path: string;\n type: string;\n size?: number;\n w?: number;\n h?: number;\n dur?: number;\n download?: string;\n url?: string;\n locked?: boolean;\n upload?: boolean;\n staged?: boolean;\n from?: string;\n edit?: Edit;\n frame?: Frame;\n meta?: Record<string, unknown>;\n unattached?: boolean;\n pending?: string[];\n failed?: Failure;\n editor_url?: string;\n progress?: EncodeProgress;\n}\n\nexport interface FilterSetting {\n group_id: string;\n visible: boolean;\n}\n\nexport interface ForegroundCue {\n file: string;\n page?: string;\n anchor?: string;\n}\n\nexport interface ForkBody {\n from: string;\n playback?: boolean;\n segments?: boolean;\n}\n\nexport interface Frame {\n t?: number;\n auto?: boolean;\n of?: string;\n}\n\nexport interface Group {\n id: string;\n kind: string;\n slug: string;\n scope_id?: string;\n parent_id?: string;\n state: \"active\" | \"deleted\" | \"merged\";\n merged_into?: string;\n attributes: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n created_at: string;\n updated_at: string;\n revision: number;\n}\n\nexport interface GroupAccess {\n key: string;\n offer?: Sale;\n member: boolean;\n editor?: boolean;\n unknown?: boolean;\n}\n\nexport interface GroupCard {\n id: string;\n kind: string;\n slug: string;\n scope_id?: string;\n parent_id?: string;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n cover?: GroupsCover;\n avatar?: Avatar;\n count: number;\n attributes: Record<string, unknown>;\n access?: GroupAccess;\n created_at: string;\n}\n\nexport interface GroupDetail {\n id: string;\n kind: string;\n slug: string;\n scope_id?: string;\n parent_id?: string;\n state: \"active\" | \"deleted\" | \"merged\";\n merged_into?: string;\n attributes: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n created_at: string;\n updated_at: string;\n revision: number;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n names: Name[];\n text: GroupsText[];\n parent?: GroupCard;\n scope?: GroupCard;\n children: GroupCard[];\n edges: Edge[];\n counts: Count[];\n access?: GroupAccess;\n}\n\nexport interface GroupInput {\n id?: string;\n kind: string;\n slug: string;\n scope_id?: string;\n parent_id?: string;\n attributes?: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n names?: Name[];\n text?: GroupsText[];\n}\n\nexport interface GroupJoin {\n group_id: string;\n key: string;\n member: boolean;\n}\n\nexport interface GroupKind {\n route?: string;\n ordered?: boolean;\n parent?: string;\n scoped_by?: string;\n owner?: string;\n max_per_owner?: number;\n uploads?: UploadLimits;\n sellable?: boolean;\n auth_scope?: boolean;\n windows?: boolean;\n version_level?: boolean;\n roles?: string[];\n attributes?: Record<string, Attribute>;\n}\n\nexport interface GroupPage {\n groups: GroupCard[];\n next_cursor?: string;\n}\n\nexport interface GroupRecord {\n external_id: string;\n id?: string;\n kind: string;\n slug: string;\n scope?: Ref;\n parent?: Ref;\n state?: string;\n names?: Name[];\n text?: GroupsText[];\n attributes?: Record<string, unknown>;\n cover_image?: string;\n cover_content?: Ref;\n avatar?: string;\n owner_user_id?: string;\n auth_scope?: string;\n edges?: EdgeRecord[];\n code?: string;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface GroupRef {\n kind: string;\n slug: string;\n}\n\nexport interface GroupSummary {\n id: string;\n kind: string;\n slug: string;\n name: string;\n}\n\nexport interface GroupUpdate {\n slug?: string;\n scope_id?: string;\n parent_id?: string;\n state?: \"active\" | \"deleted\" | \"merged\";\n attributes?: Record<string, unknown>;\n cover?: GroupsCover;\n avatar?: Avatar;\n owner_user_id?: string;\n auth_scope?: string;\n names?: Name[];\n text?: GroupsText[];\n}\n\nexport interface GroupsCover {\n image?: string;\n content_id?: string;\n auto?: boolean;\n renditions?: Rendition[];\n}\n\nexport interface GroupsText {\n language: string;\n description?: string;\n sort_key?: string;\n}\n\nexport interface HeldItem {\n kind: string;\n revision: number;\n id: string;\n ref: ContentRef;\n author_id?: string;\n author?: PublicUser;\n anon_name?: string;\n title?: string;\n body: string;\n reason: string;\n model?: string;\n prompt_version?: string;\n confidence?: number;\n error?: string;\n held_at: string;\n created_at: string;\n}\n\nexport interface HeldPage {\n items: HeldItem[];\n next?: string;\n}\n\nexport interface IPBan {\n network: string;\n reason?: string;\n until?: string;\n banned_by: string;\n banned_at: string;\n expired: boolean;\n}\n\nexport interface IPBanInput {\n network: string;\n reason?: string;\n until?: string;\n}\n\nexport interface ImageInput {\n image?: string;\n}\n\nexport interface InlineImage {\n ref: string;\n url: string | null;\n}\n\nexport interface Input {\n recipient: Recipient;\n origin: Origin;\n kind: string;\n data: unknown;\n created_at: string;\n status?: string;\n action_requested?: boolean;\n severity?: string;\n}\n\nexport interface Interaction {\n content?: Card;\n group?: GroupCard;\n value: number;\n at: string;\n}\n\nexport interface InteractionPage {\n items: Interaction[];\n next_cursor?: string;\n}\n\nexport interface Item {\n id: string;\n recipient: Recipient;\n origin: Origin;\n kind: string;\n data: unknown;\n created_at: string;\n status?: string;\n action_requested?: boolean;\n severity?: string;\n read_at: string | null;\n dismissed_at: string | null;\n resolved_at: string | null;\n updated_at: string;\n revision: number;\n}\n\nexport interface Kind {\n route: string;\n presentation: string;\n versions: VersionRules;\n segments?: boolean;\n groups?: string[];\n attributes?: Record<string, Attribute>;\n sort?: string;\n draft_ttl?: number;\n}\n\nexport interface LanguageTotal {\n public: number;\n tiers: Record<string, number>;\n}\n\nexport interface LibraryItem {\n content_id: string;\n kind: string;\n title: string;\n language?: string;\n deleted: boolean;\n whole: boolean;\n version_ids: string[];\n}\n\nexport interface LibraryPage {\n items: LibraryItem[];\n next_cursor?: string;\n complete: boolean;\n}\n\nexport interface MemberPage {\n members: Membership[];\n next_cursor?: string;\n}\n\nexport interface MemberRef {\n content_id: string;\n version_id?: string;\n}\n\nexport interface Membership {\n group_id?: string;\n content_id?: string;\n version_id?: string;\n role?: string;\n position?: number;\n active_from?: string;\n active_until?: string;\n state?: \"active\" | \"proposed\";\n}\n\nexport interface MembershipRecord {\n group: Ref;\n version?: Ref;\n role?: string;\n position?: number;\n active_from?: string;\n active_until?: string;\n state?: string;\n}\n\nexport interface MembershipSet {\n content: Ref;\n kinds: string[];\n memberships: MembershipRecord[];\n}\n\nexport interface MergeInput {\n into: string;\n}\n\nexport interface MergeReport {\n from: string;\n into: string;\n memberships_moved: number;\n names_moved: number;\n edges_moved: number;\n groups_moved: number;\n}\n\nexport interface MultipartReply {\n ticket: string;\n min_part_size: number;\n max_part_size: number;\n max_parts: number;\n}\n\nexport interface MyGroup {\n id: string;\n kind: string;\n slug: string;\n scope_id?: string;\n parent_id?: string;\n name: string;\n name_language?: string;\n code?: string;\n path?: string;\n cover?: GroupsCover;\n avatar?: Avatar;\n count: number;\n attributes: Record<string, unknown>;\n access?: GroupAccess;\n created_at: string;\n owner: boolean;\n editor: boolean;\n writer: boolean;\n moderator: boolean;\n member: boolean;\n}\n\nexport interface MyGroupPage {\n groups: MyGroup[];\n next_cursor?: string;\n}\n\nexport interface Name {\n language: string;\n kind: \"alias\" | \"name\";\n name: string;\n}\n\nexport interface Offer {\n id: string;\n target: Target;\n key: string;\n terms: Terms;\n state: \"active\" | \"withdrawn\";\n synced: boolean;\n product_id?: string;\n price_id?: string;\n last_error?: string;\n revision: number;\n updated_at: string;\n}\n\nexport interface OfferPage {\n offers: Offer[];\n next_cursor?: string;\n}\n\nexport interface OfferRecord {\n target: TargetRef;\n terms: Terms;\n}\n\nexport interface Op {\n op: OpName;\n path?: string;\n blob?: string;\n create_id?: string;\n index?: number;\n meta?: Record<string, unknown>;\n edit?: Edit;\n unattached?: boolean;\n to?: string;\n from?: CopyFrom;\n t?: number;\n auto?: boolean;\n preset?: string;\n force?: boolean;\n takedown?: boolean;\n}\n\nexport interface Order {\n members: MemberRef[];\n}\n\nexport interface OrderInput {\n ids: string[];\n}\n\nexport interface Origin {\n system: string;\n scope: string;\n id: string;\n subject?: string;\n}\n\nexport interface Page {\n items: Item[];\n next_cursor?: string;\n}\n\nexport interface PartBody {\n number: number;\n size: number;\n sha256: string;\n}\n\nexport interface PartReply {\n number: number;\n size?: number;\n sha256?: string;\n request?: RequestReply;\n}\n\nexport interface PartsBody {\n ticket: string;\n parts: PartBody[];\n}\n\nexport interface PartsReply {\n parts: PartReply[];\n}\n\nexport interface Pending {\n status: string;\n}\n\nexport interface Placement {\n content_id: string;\n position: number;\n}\n\nexport interface PlanPage {\n name: string;\n w: number;\n h: number;\n files: Record<string, string>;\n}\n\nexport interface PlanPlayback {\n item: RefBody;\n tracks: PlanTrack[];\n}\n\nexport interface PlanPreview {\n index: number;\n name: string;\n url: string;\n w: number;\n h: number;\n}\n\nexport interface PlanSegment {\n position?: number;\n title?: string;\n start: number;\n end: number;\n released: boolean;\n release_at?: string;\n locked: boolean;\n item?: RefBody;\n pages?: PlanPage[];\n}\n\nexport interface PlanTrack {\n name: string;\n path: string;\n duration?: number;\n}\n\nexport interface Poll {\n id: string;\n kind: PollKind;\n question: string;\n language: string;\n is_active: boolean;\n image_url?: string;\n live_at: string;\n closes_at?: string;\n closed: boolean;\n total_votes: number;\n options: PollOption[];\n voted: boolean;\n my_option?: string;\n answer_count?: number;\n groups?: AnswerGroup[];\n my_answer?: PollAnswer;\n}\n\nexport interface PollAnswer {\n id: string;\n text: string;\n classified: boolean;\n updated_at: string;\n}\n\nexport interface PollAnswerInput {\n text: string;\n}\n\nexport interface PollImage {\n image_url: string | null;\n}\n\nexport interface PollInput {\n kind?: PollKind;\n question: string;\n language: string;\n live_at?: string;\n closes_at?: string;\n options?: PollOptionInput[];\n}\n\nexport interface PollOption {\n id: string;\n label: string;\n image_url?: string;\n position: number;\n vote_count: number;\n}\n\nexport interface PollOptionInput {\n label: string;\n position: number;\n}\n\nexport interface PollOptionPatch {\n label?: string;\n position?: number;\n}\n\nexport interface PollOptionRecord {\n external_id: string;\n id?: string;\n label: string;\n position: number;\n}\n\nexport interface PollRecord {\n external_id: string;\n id?: string;\n kind?: string;\n question: string;\n language?: string;\n active?: boolean;\n live_at?: string;\n closes_at?: string;\n deleted_at?: string;\n created_at?: string;\n updated_at?: string;\n options?: PollOptionRecord[];\n}\n\nexport interface PollUpdate {\n question?: string;\n is_active?: boolean;\n live_at?: string;\n closes_at?: string | null;\n}\n\nexport interface PollVote {\n option_id: string;\n}\n\nexport interface PresetRule {\n kind: string;\n name: string;\n from: string;\n base: string;\n namespace: string;\n to: string;\n widths: number[];\n aspect?: string;\n min_width?: number;\n first?: number;\n default: boolean;\n}\n\nexport interface PresignBody {\n ref: RefBody;\n path: string;\n type: string;\n size: number;\n sha256: string;\n}\n\nexport interface PresignReply {\n path: string;\n blob: string;\n exists?: boolean;\n put?: RequestReply;\n multipart?: MultipartReply;\n process_on_upload?: boolean;\n}\n\nexport interface Preview {\n pages?: number;\n segments?: number;\n}\n\nexport interface PublicImage {\n from: string;\n preset: string;\n renditions: PublicRendition[];\n}\n\nexport interface PublicRendition {\n url: string;\n w: number;\n h: number;\n}\n\nexport interface PublicUser {\n id: string;\n name?: string;\n username: string;\n avatar?: string;\n avatar_srcset?: string;\n}\n\nexport interface Publication {\n notifications: Input[];\n}\n\nexport interface PublishInput {\n publish_at?: string;\n}\n\nexport interface Published {\n items: Item[];\n}\n\nexport interface ReactionCounts {\n likes: number;\n dislikes: number;\n mine: number;\n}\n\nexport interface ReactionRecord {\n target: TargetRef;\n user_id?: string;\n ip?: string;\n value: number;\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface ReadResult {\n access: Access;\n expires: number;\n meta?: Record<string, unknown>;\n previews?: string[];\n public?: PublicImage[];\n total: number;\n offset: number;\n limit: number;\n hls?: string[];\n state?: ItemState;\n full?: boolean;\n uploads?: UploadRule[];\n files: FileInfo[];\n}\n\nexport interface ReaderDefaults {\n auto_advance_seconds?: number;\n}\n\nexport interface ReaderMeta {\n schema_version: number;\n defaults?: ReaderDefaults;\n anchors?: Anchor[];\n background?: BackgroundCue[];\n foreground?: ForegroundCue[];\n}\n\nexport interface ReaderPlan {\n content_id: string;\n version_id: string;\n publication_id: string;\n pages: number;\n segments: PlanSegment[];\n previews: PlanPreview[];\n playback?: PlanPlayback;\n reader?: ReaderMeta;\n}\n\nexport interface RecentSearch {\n query: string;\n results: number;\n searched_at: string;\n}\n\nexport interface RecentSearches {\n searches: RecentSearch[];\n}\n\nexport interface Recipient {\n audience: string;\n id: string;\n}\n\nexport interface RecordFailure {\n section: string;\n index: number;\n external_id?: string;\n code: string;\n error: string;\n}\n\nexport interface Ref {\n id?: string;\n external_id?: string;\n}\n\nexport interface RefBody {\n kind: string;\n id: string;\n version?: string;\n}\n\nexport interface ReleaseDates {\n dates: DateCount[];\n next_cursor?: string;\n}\n\nexport interface Rendition {\n url: string;\n w: number;\n h: number;\n}\n\nexport interface RequestReply {\n method: string;\n url: string;\n headers: Record<string, string>;\n expires: string;\n}\n\nexport interface ResolveInput {\n decision: \"approve\" | \"reject\" | \"review\";\n revision: number;\n reason?: string;\n}\n\nexport interface Resolved {\n tenant_id: string;\n content_kind: string;\n content_id: string;\n content_version_id?: string;\n code: string;\n slug: string;\n slugs?: Record<string, string>;\n path: string;\n}\n\nexport interface Restored {\n restored: boolean;\n}\n\nexport interface Result {\n written: Record<string, number>;\n skipped?: Record<string, number>;\n failed: RecordFailure[];\n ids: Record<string, Record<string, string>>;\n}\n\nexport interface ReviewOutcome {\n decision: \"approve\" | \"reject\" | \"review\";\n}\n\nexport interface Rule {\n level: \"group\" | \"group_ppv\" | \"ppv\" | \"public\" | \"tier\";\n tiers?: string[];\n group_id?: string;\n preview?: Preview;\n free_after?: string;\n}\n\nexport interface Sale {\n key: string;\n target: Target;\n terms: Terms;\n price_id?: string;\n}\n\nexport interface Segment {\n position: number;\n title?: string;\n start: number;\n end: number;\n release_at?: string;\n released: boolean;\n}\n\nexport interface SegmentsInput {\n segments: Segment[];\n}\n\nexport interface SignalInput {\n content_id: string;\n version_id?: string;\n type: string;\n event_id: string;\n revision?: number;\n occurred_at: string;\n duration_s?: number;\n progress?: number;\n resume?: string;\n render_id?: string;\n surface?: string;\n position?: number;\n}\n\nexport interface SignalRecord {\n target: TargetRef;\n user_id?: string;\n anon_key?: string;\n type: string;\n event_id: string;\n revision?: number;\n occurred_at: string;\n duration_s?: number;\n progress?: number;\n resume?: string;\n}\n\nexport interface Signals {\n session?: string;\n signals: SignalInput[];\n}\n\nexport interface StagedCopy {\n path: string;\n blob: string;\n size: number;\n}\n\nexport interface Target {\n kind: \"content\" | \"group\" | \"version\";\n id: string;\n content_id?: string;\n}\n\nexport interface TargetRef {\n content?: Ref;\n version?: Ref;\n group?: Ref;\n comment?: Ref;\n}\n\nexport interface Terms {\n amount: string;\n currency: string;\n access_hours?: number;\n renew_hours?: number;\n}\n\nexport interface TicketBody {\n ticket: string;\n}\n\nexport interface Total {\n public: number;\n tiers: Record<string, number>;\n languages: Record<string, LanguageTotal>;\n}\n\nexport interface Totals {\n kinds: Record<string, Total>;\n}\n\nexport interface Typeahead {\n contents: Card[];\n groups: GroupCard[];\n}\n\nexport interface UploadLimits {\n files_per_hour?: number;\n bytes_per_day?: number;\n quota_bytes?: number;\n}\n\nexport interface UploadRule {\n path: string;\n types: string[];\n max_bytes: number;\n max?: number;\n named?: boolean;\n frames?: string;\n aspect?: string;\n min_width?: number;\n video?: VideoLimits;\n min_aspect?: number;\n max_aspect?: number;\n}\n\nexport interface Version {\n id: string;\n position: number;\n languages: string[];\n traits: string[];\n label?: string;\n title?: string;\n description?: string;\n state?: ContentState;\n publish_at?: string;\n published_at?: string;\n live: boolean;\n access?: Rule;\n attributes: Record<string, unknown>;\n pages?: number;\n duration_ms?: number;\n width?: number;\n height?: number;\n has_audio: boolean;\n ordinal?: number;\n segments: Segment[];\n decision: Decision;\n text?: Record<string, VersionText>;\n offer?: Offer;\n}\n\nexport interface VersionFork {\n from: string;\n playback?: boolean;\n segments?: boolean;\n}\n\nexport interface VersionInput {\n languages?: string[];\n traits?: string[];\n label?: string;\n state?: VersionState;\n publish_at?: string;\n access?: Rule;\n clear_access?: boolean;\n attributes?: Record<string, unknown>;\n text?: Record<string, VersionText>;\n segments?: Segment[];\n ordinal?: number;\n fork?: VersionFork;\n}\n\nexport interface VersionRecord {\n external_id: string;\n id?: string;\n languages: string[];\n traits?: string[];\n label?: string;\n state?: string;\n publish_at?: string;\n published_at?: string;\n deleted_at?: string;\n access?: Rule;\n attributes?: Record<string, unknown>;\n ordinal?: number;\n text?: Record<string, VersionText>;\n segments?: Segment[];\n created_at?: string;\n updated_at?: string;\n}\n\nexport interface VersionRules {\n languages: string;\n traits?: string[];\n hidden?: boolean;\n}\n\nexport interface VersionText {\n title?: string;\n description?: string;\n}\n\nexport interface VideoLimits {\n max_seconds?: number;\n max_fps?: number;\n max_pixels?: number;\n max_work?: number;\n}\n\nexport interface ViewerState {\n favorited: boolean;\n seen: boolean;\n completed: boolean;\n progress: number;\n progress_max: number;\n resume?: string;\n last_view_at?: string;\n}\n\nexport interface VoteRecord {\n poll: Ref;\n option: Ref;\n user_id?: string;\n ip?: string;\n created_at?: string;\n}\n\nexport interface Written {\n count: number;\n}\n"],"mappings":";AAOA,IAAa,IAAiB,UACjB,IAAgB,SAChB,IAAgB"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { Attribute } from './generated/wire.js';
|
|
2
|
+
/** How ContentKit compares names (contentkit_keyword_normalize): accents dropped, lowercase, single spaces. */
|
|
3
|
+
export declare function fold(s: string): string;
|
|
4
|
+
/** The letter bucket a name lists under: its first letter a-z, else "#". */
|
|
5
|
+
export declare function letterOf(name: string): string;
|
|
6
|
+
/** The letter buckets of a directory, in order. */
|
|
7
|
+
export declare const LETTERS: readonly string[];
|
|
8
|
+
/** A slug from a name: lowercase words joined by dashes. */
|
|
9
|
+
export declare function slugify(name: string): string;
|
|
10
|
+
/** A datetime-local input's value for an instant, in local time ("" for none). */
|
|
11
|
+
export declare function toLocalInput(iso: string | null | undefined): string;
|
|
12
|
+
/** The instant a datetime-local input names, as RFC 3339; undefined when empty or invalid. */
|
|
13
|
+
export declare function fromLocalInput(value: string): string | undefined;
|
|
14
|
+
/** A form field's value for an attribute: text for the inputs, a boolean for a switch. */
|
|
15
|
+
export declare function attributeInput(spec: Attribute, value: unknown): string | boolean;
|
|
16
|
+
/**
|
|
17
|
+
* An attribute's value from its form field; undefined drops it (an empty
|
|
18
|
+
* field, an unchecked switch: absent reads as false). A value that is not of
|
|
19
|
+
* the attribute's type throws a RangeError.
|
|
20
|
+
*/
|
|
21
|
+
export declare function parseAttribute(spec: Attribute, input: string | boolean): unknown;
|
|
22
|
+
/** Every declared attribute's value from the form, undeclared ones dropped. */
|
|
23
|
+
export declare function parseAttributes(declared: Readonly<Record<string, Attribute>>, form: Readonly<Record<string, string | boolean>>): Record<string, unknown>;
|
|
24
|
+
/** "voice_actor" → "Voice actor": an identifier's fallback label. */
|
|
25
|
+
export declare function humanize(id: string): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
//#region src/client/group-fields.ts
|
|
2
|
+
function e(e) {
|
|
3
|
+
return e.normalize("NFKD").replace(/[̀-ͯ]/g, "").normalize("NFC").toLowerCase().replace(/\s+/g, " ").trim();
|
|
4
|
+
}
|
|
5
|
+
function t(t) {
|
|
6
|
+
let n = e(t).charAt(0);
|
|
7
|
+
return n >= "a" && n <= "z" ? n : "#";
|
|
8
|
+
}
|
|
9
|
+
var n = [..."abcdefghijklmnopqrstuvwxyz", "#"];
|
|
10
|
+
function r(t) {
|
|
11
|
+
return e(t).replace(/[\s/]+/g, "-").replace(/[^\p{L}\p{N}-]+/gu, "").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 200);
|
|
12
|
+
}
|
|
13
|
+
function i(e) {
|
|
14
|
+
if (!e) return "";
|
|
15
|
+
let t = new Date(e);
|
|
16
|
+
if (Number.isNaN(t.getTime())) return "";
|
|
17
|
+
let n = (e) => String(e).padStart(2, "0");
|
|
18
|
+
return `${t.getFullYear()}-${n(t.getMonth() + 1)}-${n(t.getDate())}T${n(t.getHours())}:${n(t.getMinutes())}`;
|
|
19
|
+
}
|
|
20
|
+
function a(e) {
|
|
21
|
+
if (!e) return;
|
|
22
|
+
let t = new Date(e);
|
|
23
|
+
return Number.isNaN(t.getTime()) ? void 0 : t.toISOString();
|
|
24
|
+
}
|
|
25
|
+
function o(e, t) {
|
|
26
|
+
return e.type === "bool" ? t === !0 : t == null ? "" : e.type === "time" ? i(String(t)) : String(t);
|
|
27
|
+
}
|
|
28
|
+
function s(e, t) {
|
|
29
|
+
if (e.type === "bool") return t === !0 || void 0;
|
|
30
|
+
let n = String(t).trim();
|
|
31
|
+
if (n) switch (e.type) {
|
|
32
|
+
case "int": {
|
|
33
|
+
let e = Number(n);
|
|
34
|
+
if (!Number.isSafeInteger(e)) throw RangeError(`${n} is not a whole number`);
|
|
35
|
+
return e;
|
|
36
|
+
}
|
|
37
|
+
case "enum":
|
|
38
|
+
if (!e.values?.includes(n)) throw RangeError(`${n} is not one of ${e.values?.join(", ")}`);
|
|
39
|
+
return n;
|
|
40
|
+
case "time": {
|
|
41
|
+
let e = a(n);
|
|
42
|
+
if (!e) throw RangeError(`${n} is not a time`);
|
|
43
|
+
return e;
|
|
44
|
+
}
|
|
45
|
+
default: return n;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function c(e, t) {
|
|
49
|
+
let n = {};
|
|
50
|
+
for (let [r, i] of Object.entries(e)) {
|
|
51
|
+
let e = r in t ? s(i, t[r]) : void 0;
|
|
52
|
+
e !== void 0 && (n[r] = e);
|
|
53
|
+
}
|
|
54
|
+
return n;
|
|
55
|
+
}
|
|
56
|
+
function l(e) {
|
|
57
|
+
let t = e.replace(/[_-]+/g, " ").trim();
|
|
58
|
+
return t.charAt(0).toUpperCase() + t.slice(1);
|
|
59
|
+
}
|
|
60
|
+
//#endregion
|
|
61
|
+
export { n as LETTERS, o as attributeInput, e as fold, a as fromLocalInput, l as humanize, t as letterOf, s as parseAttribute, c as parseAttributes, r as slugify, i as toLocalInput };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=group-fields.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"group-fields.js","names":[],"sources":["../../src/client/group-fields.ts"],"sourcesContent":["import type { Attribute } from \"./generated/wire.js\";\n\n/** How ContentKit compares names (contentkit_keyword_normalize): accents dropped, lowercase, single spaces. */\nexport function fold(s: string): string {\n return s.normalize(\"NFKD\").replace(/[̀-ͯ]/g, \"\").normalize(\"NFC\").toLowerCase().replace(/\\s+/g, \" \").trim();\n}\n\n/** The letter bucket a name lists under: its first letter a-z, else \"#\". */\nexport function letterOf(name: string): string {\n const c = fold(name).charAt(0);\n return c >= \"a\" && c <= \"z\" ? c : \"#\";\n}\n\n/** The letter buckets of a directory, in order. */\nexport const LETTERS: readonly string[] = [...\"abcdefghijklmnopqrstuvwxyz\", \"#\"];\n\n/** A slug from a name: lowercase words joined by dashes. */\nexport function slugify(name: string): string {\n return fold(name)\n .replace(/[\\s/]+/g, \"-\")\n .replace(/[^\\p{L}\\p{N}-]+/gu, \"\")\n .replace(/-+/g, \"-\")\n .replace(/^-|-$/g, \"\")\n .slice(0, 200);\n}\n\n/** A datetime-local input's value for an instant, in local time (\"\" for none). */\nexport function toLocalInput(iso: string | null | undefined): string {\n if (!iso) return \"\";\n const d = new Date(iso);\n if (Number.isNaN(d.getTime())) return \"\";\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}T${p(d.getHours())}:${p(d.getMinutes())}`;\n}\n\n/** The instant a datetime-local input names, as RFC 3339; undefined when empty or invalid. */\nexport function fromLocalInput(value: string): string | undefined {\n if (!value) return undefined;\n const d = new Date(value);\n return Number.isNaN(d.getTime()) ? undefined : d.toISOString();\n}\n\n/** A form field's value for an attribute: text for the inputs, a boolean for a switch. */\nexport function attributeInput(spec: Attribute, value: unknown): string | boolean {\n if (spec.type === \"bool\") return value === true;\n if (value === undefined || value === null) return \"\";\n return spec.type === \"time\" ? toLocalInput(String(value)) : String(value);\n}\n\n/**\n * An attribute's value from its form field; undefined drops it (an empty\n * field, an unchecked switch: absent reads as false). A value that is not of\n * the attribute's type throws a RangeError.\n */\nexport function parseAttribute(spec: Attribute, input: string | boolean): unknown {\n if (spec.type === \"bool\") return input === true || undefined;\n const s = String(input).trim();\n if (!s) return undefined;\n switch (spec.type) {\n case \"int\": {\n const n = Number(s);\n if (!Number.isSafeInteger(n)) throw new RangeError(`${s} is not a whole number`);\n return n;\n }\n case \"enum\":\n if (!spec.values?.includes(s)) throw new RangeError(`${s} is not one of ${spec.values?.join(\", \")}`);\n return s;\n case \"time\": {\n const t = fromLocalInput(s);\n if (!t) throw new RangeError(`${s} is not a time`);\n return t;\n }\n default:\n return s;\n }\n}\n\n/** Every declared attribute's value from the form, undeclared ones dropped. */\nexport function parseAttributes(declared: Readonly<Record<string, Attribute>>, form: Readonly<Record<string, string | boolean>>): Record<string, unknown> {\n const out: Record<string, unknown> = {};\n for (const [name, spec] of Object.entries(declared)) {\n const v = name in form ? parseAttribute(spec, form[name]!) : undefined;\n if (v !== undefined) out[name] = v;\n }\n return out;\n}\n\n/** \"voice_actor\" → \"Voice actor\": an identifier's fallback label. */\nexport function humanize(id: string): string {\n const s = id.replace(/[_-]+/g, \" \").trim();\n return s.charAt(0).toUpperCase() + s.slice(1);\n}\n"],"mappings":";AAGA,SAAgB,EAAK,GAAmB;CACtC,OAAO,EAAE,UAAU,MAAM,CAAC,CAAC,QAAQ,UAAU,EAAE,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,YAAY,CAAC,CAAC,QAAQ,QAAQ,GAAG,CAAC,CAAC,KAAK;AAC5G;AAGA,SAAgB,EAAS,GAAsB;CAC7C,IAAM,IAAI,EAAK,CAAI,CAAC,CAAC,OAAO,CAAC;CAC7B,OAAO,KAAK,OAAO,KAAK,MAAM,IAAI;AACpC;AAGA,IAAa,IAA6B,CAAC,GAAG,8BAA8B,GAAG;AAG/E,SAAgB,EAAQ,GAAsB;CAC5C,OAAO,EAAK,CAAI,CAAC,CACd,QAAQ,WAAW,GAAG,CAAC,CACvB,QAAQ,qBAAqB,EAAE,CAAC,CAChC,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,UAAU,EAAE,CAAC,CACrB,MAAM,GAAG,GAAG;AACjB;AAGA,SAAgB,EAAa,GAAwC;CACnE,IAAI,CAAC,GAAK,OAAO;CACjB,IAAM,IAAI,IAAI,KAAK,CAAG;CACtB,IAAI,OAAO,MAAM,EAAE,QAAQ,CAAC,GAAG,OAAO;CACtC,IAAM,KAAK,MAAc,OAAO,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG;CAClD,OAAO,GAAG,EAAE,YAAY,EAAE,GAAG,EAAE,EAAE,SAAS,IAAI,CAAC,EAAE,GAAG,EAAE,EAAE,QAAQ,CAAC,EAAE,GAAG,EAAE,EAAE,SAAS,CAAC,EAAE,GAAG,EAAE,EAAE,WAAW,CAAC;AAC3G;AAGA,SAAgB,EAAe,GAAmC;CAChE,IAAI,CAAC,GAAO;CACZ,IAAM,IAAI,IAAI,KAAK,CAAK;CACxB,OAAO,OAAO,MAAM,EAAE,QAAQ,CAAC,IAAI,KAAA,IAAY,EAAE,YAAY;AAC/D;AAGA,SAAgB,EAAe,GAAiB,GAAkC;CAGhF,OAFI,EAAK,SAAS,SAAe,MAAU,KACvC,KAAiC,OAAa,KAC3C,EAAK,SAAS,SAAS,EAAa,OAAO,CAAK,CAAC,IAAI,OAAO,CAAK;AAC1E;AAOA,SAAgB,EAAe,GAAiB,GAAkC;CAChF,IAAI,EAAK,SAAS,QAAQ,OAAO,MAAU,MAAQ,KAAA;CACnD,IAAM,IAAI,OAAO,CAAK,CAAC,CAAC,KAAK;CACxB,OACL,QAAQ,EAAK,MAAb;EACE,KAAK,OAAO;GACV,IAAM,IAAI,OAAO,CAAC;GAClB,IAAI,CAAC,OAAO,cAAc,CAAC,GAAG,MAAU,WAAW,GAAG,EAAE,uBAAuB;GAC/E,OAAO;EACT;EACA,KAAK;GACH,IAAI,CAAC,EAAK,QAAQ,SAAS,CAAC,GAAG,MAAU,WAAW,GAAG,EAAE,iBAAiB,EAAK,QAAQ,KAAK,IAAI,GAAG;GACnG,OAAO;EACT,KAAK,QAAQ;GACX,IAAM,IAAI,EAAe,CAAC;GAC1B,IAAI,CAAC,GAAG,MAAU,WAAW,GAAG,EAAE,eAAe;GACjD,OAAO;EACT;EACA,SACE,OAAO;CACX;AACF;AAGA,SAAgB,EAAgB,GAA+C,GAA2E;CACxJ,IAAM,IAA+B,CAAC;CACtC,KAAK,IAAM,CAAC,GAAM,MAAS,OAAO,QAAQ,CAAQ,GAAG;EACnD,IAAM,IAAI,KAAQ,IAAO,EAAe,GAAM,EAAK,EAAM,IAAI,KAAA;EAC7D,AAAI,MAAM,KAAA,MAAW,EAAI,KAAQ;CACnC;CACA,OAAO;AACT;AAGA,SAAgB,EAAS,GAAoB;CAC3C,IAAM,IAAI,EAAG,QAAQ,UAAU,GAAG,CAAC,CAAC,KAAK;CACzC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,EAAE,MAAM,CAAC;AAC9C"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { ContentGroups, ContentMemberships, Edge, EdgeInput, Group, GroupDetail, GroupInput, GroupPage, GroupUpdate, MemberPage, MemberRef, Membership, MergeReport, MyGroupPage, Name, RefBody, Written } from './generated/wire.js';
|
|
2
|
+
import { Http } from './http.js';
|
|
3
|
+
import { MediaClient, NamedOptions } from './media/client.js';
|
|
4
|
+
import { RouteQuery } from './route.js';
|
|
5
|
+
/** GET /groups filters, as the route names them. */
|
|
6
|
+
export type GroupQuery = RouteQuery<"GET", "/groups">;
|
|
7
|
+
/** GET /me/groups filters. */
|
|
8
|
+
export type MyGroupQuery = RouteQuery<"GET", "/me/groups">;
|
|
9
|
+
/** A group's image slots: every kind's cover, a user-owned kind's avatar. */
|
|
10
|
+
export type GroupImageSlot = "cover" | "avatar";
|
|
11
|
+
/** GET /groups/{id}/members paging. */
|
|
12
|
+
export type MemberQuery = RouteQuery<"GET", "/groups/{id}/members">;
|
|
13
|
+
/** Groups: public listings and pages; writes for staff (root:groups:write). */
|
|
14
|
+
export declare class GroupsClient {
|
|
15
|
+
private readonly http;
|
|
16
|
+
private readonly media;
|
|
17
|
+
constructor(http: Http, media: MediaClient);
|
|
18
|
+
list(q?: GroupQuery, signal?: AbortSignal): Promise<GroupPage>;
|
|
19
|
+
/** A merged group answers with its survivor. */
|
|
20
|
+
get(id: string, language?: string, signal?: AbortSignal): Promise<GroupDetail>;
|
|
21
|
+
create(groups: GroupInput[]): Promise<Group[]>;
|
|
22
|
+
update(id: string, patch: GroupUpdate): Promise<Group>;
|
|
23
|
+
/** Marks the group deleted. */
|
|
24
|
+
remove(id: string): Promise<Group>;
|
|
25
|
+
/** Replaces, adds or removes names and aliases; resolves with the group's names. */
|
|
26
|
+
names(id: string, op: "set" | "add" | "remove", names: Name[]): Promise<Name[]>;
|
|
27
|
+
/** Adds or removes edges from the group; resolves with every edge touching it. */
|
|
28
|
+
edges(id: string, op: "add" | "remove", edges: EdgeInput[]): Promise<Edge[]>;
|
|
29
|
+
/** The group's media folder: the media kind named after its group kind. */
|
|
30
|
+
folder(group: {
|
|
31
|
+
kind: string;
|
|
32
|
+
id: string;
|
|
33
|
+
}): RefBody;
|
|
34
|
+
/**
|
|
35
|
+
* Uploads an image to the folder's server-named `{slot}/{name}` and
|
|
36
|
+
* selects it as the group's cover or avatar (a user-owned kind's).
|
|
37
|
+
*/
|
|
38
|
+
uploadImage(group: {
|
|
39
|
+
kind: string;
|
|
40
|
+
id: string;
|
|
41
|
+
}, slot: GroupImageSlot, file: Blob & {
|
|
42
|
+
name?: string;
|
|
43
|
+
}, o?: Omit<NamedOptions, "path">): Promise<Group>;
|
|
44
|
+
/** Groups the signed-in person owns, edits or belongs to. */
|
|
45
|
+
mine(q?: MyGroupQuery, signal?: AbortSignal): Promise<MyGroupPage>;
|
|
46
|
+
merge(id: string, into: string): Promise<MergeReport>;
|
|
47
|
+
/** The group's memberships in member order, a cursor page at a time. */
|
|
48
|
+
members(id: string, q?: MemberQuery, signal?: AbortSignal): Promise<MemberPage>;
|
|
49
|
+
addMembers(id: string, members: Membership[]): Promise<Written>;
|
|
50
|
+
removeMembers(id: string, members: Membership[]): Promise<Written>;
|
|
51
|
+
/** Orders an ordered group: the listed members first, in list order. */
|
|
52
|
+
reorder(id: string, members: MemberRef[]): Promise<Written>;
|
|
53
|
+
/** A content's memberships, its versions' included, with their groups. */
|
|
54
|
+
ofContent(contentId: string, language?: string, signal?: AbortSignal): Promise<ContentMemberships>;
|
|
55
|
+
/** Replaces a content's memberships in the kinds named (every kind its kind joins by default). */
|
|
56
|
+
setOfContent(contentId: string, set: ContentGroups, language?: string): Promise<ContentMemberships>;
|
|
57
|
+
private write;
|
|
58
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { call as e } from "./route.js";
|
|
2
|
+
//#region src/client/groups.ts
|
|
3
|
+
var t = class {
|
|
4
|
+
http;
|
|
5
|
+
media;
|
|
6
|
+
constructor(e, t) {
|
|
7
|
+
this.http = e, this.media = t;
|
|
8
|
+
}
|
|
9
|
+
list(t = {}, n) {
|
|
10
|
+
return e(this.http, "GET", "/groups", {
|
|
11
|
+
query: t,
|
|
12
|
+
signal: n
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
get(t, n, r) {
|
|
16
|
+
return e(this.http, "GET", "/groups/{id}", {
|
|
17
|
+
params: { id: t },
|
|
18
|
+
query: { language: n },
|
|
19
|
+
signal: r
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
create(t) {
|
|
23
|
+
return this.write(e(this.http, "POST", "/groups", { body: t }));
|
|
24
|
+
}
|
|
25
|
+
update(t, n) {
|
|
26
|
+
return this.write(e(this.http, "PATCH", "/groups/{id}", {
|
|
27
|
+
params: { id: t },
|
|
28
|
+
body: n
|
|
29
|
+
}));
|
|
30
|
+
}
|
|
31
|
+
remove(t) {
|
|
32
|
+
return this.write(e(this.http, "DELETE", "/groups/{id}", { params: { id: t } }));
|
|
33
|
+
}
|
|
34
|
+
names(t, n, r) {
|
|
35
|
+
let i = n === "set" ? "PUT" : n === "add" ? "POST" : "DELETE";
|
|
36
|
+
return this.write(e(this.http, i, "/groups/{id}/names", {
|
|
37
|
+
params: { id: t },
|
|
38
|
+
body: r
|
|
39
|
+
}));
|
|
40
|
+
}
|
|
41
|
+
edges(t, n, r) {
|
|
42
|
+
return this.write(e(this.http, n === "add" ? "POST" : "DELETE", "/groups/{id}/edges", {
|
|
43
|
+
params: { id: t },
|
|
44
|
+
body: r
|
|
45
|
+
}));
|
|
46
|
+
}
|
|
47
|
+
folder(e) {
|
|
48
|
+
return {
|
|
49
|
+
kind: e.kind,
|
|
50
|
+
id: e.id
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
async uploadImage(e, t, n, r = {}) {
|
|
54
|
+
let i = await this.media.uploadNamed(this.folder(e), n, {
|
|
55
|
+
...r,
|
|
56
|
+
path: `${t}/${n.name || t}`
|
|
57
|
+
});
|
|
58
|
+
return this.update(e.id, { [t]: { image: i.name } });
|
|
59
|
+
}
|
|
60
|
+
mine(t = {}, n) {
|
|
61
|
+
return e(this.http, "GET", "/me/groups", {
|
|
62
|
+
query: t,
|
|
63
|
+
signal: n
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
merge(t, n) {
|
|
67
|
+
return this.write(e(this.http, "POST", "/groups/{id}/merge", {
|
|
68
|
+
params: { id: t },
|
|
69
|
+
body: { into: n }
|
|
70
|
+
}));
|
|
71
|
+
}
|
|
72
|
+
members(t, n = {}, r) {
|
|
73
|
+
return e(this.http, "GET", "/groups/{id}/members", {
|
|
74
|
+
params: { id: t },
|
|
75
|
+
query: n,
|
|
76
|
+
signal: r
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
addMembers(t, n) {
|
|
80
|
+
return this.write(e(this.http, "POST", "/groups/{id}/members", {
|
|
81
|
+
params: { id: t },
|
|
82
|
+
body: n
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
removeMembers(t, n) {
|
|
86
|
+
return this.write(e(this.http, "DELETE", "/groups/{id}/members", {
|
|
87
|
+
params: { id: t },
|
|
88
|
+
body: n
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
reorder(t, n) {
|
|
92
|
+
return this.write(e(this.http, "PUT", "/groups/{id}/members/order", {
|
|
93
|
+
params: { id: t },
|
|
94
|
+
body: { members: n }
|
|
95
|
+
}));
|
|
96
|
+
}
|
|
97
|
+
ofContent(t, n, r) {
|
|
98
|
+
return e(this.http, "GET", "/contents/{id}/groups", {
|
|
99
|
+
params: { id: t },
|
|
100
|
+
query: { language: n },
|
|
101
|
+
signal: r
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
setOfContent(t, n, r) {
|
|
105
|
+
return this.write(e(this.http, "PUT", "/contents/{id}/groups", {
|
|
106
|
+
params: { id: t },
|
|
107
|
+
query: { language: r },
|
|
108
|
+
body: n
|
|
109
|
+
}));
|
|
110
|
+
}
|
|
111
|
+
async write(e) {
|
|
112
|
+
let t = this.http.captureChanges(), n = await e;
|
|
113
|
+
return t({ type: "groups.changed" }), n;
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
//#endregion
|
|
117
|
+
export { t as GroupsClient };
|
|
118
|
+
|
|
119
|
+
//# sourceMappingURL=groups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"groups.js","names":[],"sources":["../../src/client/groups.ts"],"sourcesContent":["import type {\n ContentGroups,\n ContentMemberships,\n Edge,\n EdgeInput,\n Group,\n GroupDetail,\n GroupInput,\n GroupPage,\n GroupUpdate,\n MemberPage,\n MemberRef,\n Membership,\n MergeReport,\n MyGroupPage,\n Name,\n RefBody,\n Written,\n} from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport type { MediaClient, NamedOptions } from \"./media/client.js\";\nimport { call, type RouteQuery } from \"./route.js\";\n\n/** GET /groups filters, as the route names them. */\nexport type GroupQuery = RouteQuery<\"GET\", \"/groups\">;\n/** GET /me/groups filters. */\nexport type MyGroupQuery = RouteQuery<\"GET\", \"/me/groups\">;\n/** A group's image slots: every kind's cover, a user-owned kind's avatar. */\nexport type GroupImageSlot = \"cover\" | \"avatar\";\n/** GET /groups/{id}/members paging. */\nexport type MemberQuery = RouteQuery<\"GET\", \"/groups/{id}/members\">;\n\n/** Groups: public listings and pages; writes for staff (root:groups:write). */\nexport class GroupsClient {\n constructor(\n private readonly http: Http,\n private readonly media: MediaClient,\n ) {}\n\n list(q: GroupQuery = {}, signal?: AbortSignal): Promise<GroupPage> {\n return call(this.http, \"GET\", \"/groups\", { query: q, signal });\n }\n /** A merged group answers with its survivor. */\n get(id: string, language?: string, signal?: AbortSignal): Promise<GroupDetail> {\n return call(this.http, \"GET\", \"/groups/{id}\", { params: { id }, query: { language }, signal });\n }\n create(groups: GroupInput[]): Promise<Group[]> {\n return this.write(call(this.http, \"POST\", \"/groups\", { body: groups }));\n }\n update(id: string, patch: GroupUpdate): Promise<Group> {\n return this.write(call(this.http, \"PATCH\", \"/groups/{id}\", { params: { id }, body: patch }));\n }\n /** Marks the group deleted. */\n remove(id: string): Promise<Group> {\n return this.write(call(this.http, \"DELETE\", \"/groups/{id}\", { params: { id } }));\n }\n /** Replaces, adds or removes names and aliases; resolves with the group's names. */\n names(id: string, op: \"set\" | \"add\" | \"remove\", names: Name[]): Promise<Name[]> {\n const method = op === \"set\" ? \"PUT\" : op === \"add\" ? \"POST\" : \"DELETE\";\n return this.write(call(this.http, method, \"/groups/{id}/names\", { params: { id }, body: names }));\n }\n /** Adds or removes edges from the group; resolves with every edge touching it. */\n edges(id: string, op: \"add\" | \"remove\", edges: EdgeInput[]): Promise<Edge[]> {\n return this.write(call(this.http, op === \"add\" ? \"POST\" : \"DELETE\", \"/groups/{id}/edges\", { params: { id }, body: edges }));\n }\n /** The group's media folder: the media kind named after its group kind. */\n folder(group: { kind: string; id: string }): RefBody {\n return { kind: group.kind, id: group.id };\n }\n /**\n * Uploads an image to the folder's server-named `{slot}/{name}` and\n * selects it as the group's cover or avatar (a user-owned kind's).\n */\n async uploadImage(group: { kind: string; id: string }, slot: GroupImageSlot, file: Blob & { name?: string }, o: Omit<NamedOptions, \"path\"> = {}): Promise<Group> {\n const up = await this.media.uploadNamed(this.folder(group), file, { ...o, path: `${slot}/${file.name || slot}` });\n return this.update(group.id, { [slot]: { image: up.name } });\n }\n /** Groups the signed-in person owns, edits or belongs to. */\n mine(q: MyGroupQuery = {}, signal?: AbortSignal): Promise<MyGroupPage> {\n return call(this.http, \"GET\", \"/me/groups\", { query: q, signal });\n }\n merge(id: string, into: string): Promise<MergeReport> {\n return this.write(call(this.http, \"POST\", \"/groups/{id}/merge\", { params: { id }, body: { into } }));\n }\n /** The group's memberships in member order, a cursor page at a time. */\n members(id: string, q: MemberQuery = {}, signal?: AbortSignal): Promise<MemberPage> {\n return call(this.http, \"GET\", \"/groups/{id}/members\", { params: { id }, query: q, signal });\n }\n addMembers(id: string, members: Membership[]): Promise<Written> {\n return this.write(call(this.http, \"POST\", \"/groups/{id}/members\", { params: { id }, body: members }));\n }\n removeMembers(id: string, members: Membership[]): Promise<Written> {\n return this.write(call(this.http, \"DELETE\", \"/groups/{id}/members\", { params: { id }, body: members }));\n }\n /** Orders an ordered group: the listed members first, in list order. */\n reorder(id: string, members: MemberRef[]): Promise<Written> {\n return this.write(call(this.http, \"PUT\", \"/groups/{id}/members/order\", { params: { id }, body: { members } }));\n }\n /** A content's memberships, its versions' included, with their groups. */\n ofContent(contentId: string, language?: string, signal?: AbortSignal): Promise<ContentMemberships> {\n return call(this.http, \"GET\", \"/contents/{id}/groups\", { params: { id: contentId }, query: { language }, signal });\n }\n /** Replaces a content's memberships in the kinds named (every kind its kind joins by default). */\n setOfContent(contentId: string, set: ContentGroups, language?: string): Promise<ContentMemberships> {\n return this.write(call(this.http, \"PUT\", \"/contents/{id}/groups\", { params: { id: contentId }, query: { language }, body: set }));\n }\n\n private async write<T>(p: Promise<T>): Promise<T> {\n const emit = this.http.captureChanges();\n const out = await p;\n emit({ type: \"groups.changed\" });\n return out;\n }\n}\n"],"mappings":"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"}
|
package/dist/client/http.d.ts
CHANGED
|
@@ -4,23 +4,34 @@ import { FileInfo, Item, RefBody } from './generated/wire.js';
|
|
|
4
4
|
export type Mount = string | ((ref: RefBody) => string);
|
|
5
5
|
/**
|
|
6
6
|
* Where each module lives when the host does not serve them all under
|
|
7
|
-
* baseUrl's fixed sub-paths
|
|
7
|
+
* baseUrl's fixed sub-paths (CONTENTKIT_MODULES: the API version, then the
|
|
8
|
+
* module's path). A mount is the module's full base URL.
|
|
8
9
|
*/
|
|
9
10
|
export interface ContentKitMounts {
|
|
10
|
-
/**
|
|
11
|
+
/** Comments, reactions, favorites, polls, bans, moderation. Default `{baseUrl}/v1`. */
|
|
11
12
|
content?: string;
|
|
12
|
-
/**
|
|
13
|
+
/** Content items and catalog totals. Default `{baseUrl}/v1`. */
|
|
14
|
+
contents?: string;
|
|
15
|
+
/** Media reads and HLS playlists. Default `{baseUrl}/v1/media`. */
|
|
13
16
|
media?: Mount;
|
|
14
|
-
/** Uploads and commits. Default `{baseUrl}/media/upload`. */
|
|
17
|
+
/** Uploads and commits. Default `{baseUrl}/v1/media/upload`. */
|
|
15
18
|
upload?: Mount;
|
|
16
|
-
/** Content-code lookup. Default `{baseUrl}/codes`. */
|
|
19
|
+
/** Content-code lookup. Default `{baseUrl}/v1/codes`. */
|
|
17
20
|
codes?: string;
|
|
18
|
-
/**
|
|
19
|
-
|
|
20
|
-
/** The
|
|
21
|
-
|
|
22
|
-
/** User inbox. Default `{baseUrl}/notifications`. */
|
|
21
|
+
/** Groups. Default `{baseUrl}/v1`. */
|
|
22
|
+
groups?: string;
|
|
23
|
+
/** The site's content model. Default `{baseUrl}/v1`. */
|
|
24
|
+
kinds?: string;
|
|
25
|
+
/** User inbox. Default `{baseUrl}/v1/notifications`. */
|
|
23
26
|
notifications?: string;
|
|
27
|
+
/** Content versions: reader plans, reader metadata, forks, downloads. Default `{baseUrl}/v1`. */
|
|
28
|
+
versions?: string;
|
|
29
|
+
/** Offers, group joins and the library. Default `{baseUrl}/v1`. */
|
|
30
|
+
offers?: string;
|
|
31
|
+
/** Discovery: lists, search, typeahead, similar, recommendations, history, signals. Default `{baseUrl}/v1`. */
|
|
32
|
+
discovery?: string;
|
|
33
|
+
/** Bulk import (a service's). Default `{baseUrl}/v1`. */
|
|
34
|
+
import?: string;
|
|
24
35
|
}
|
|
25
36
|
export type ContentKitModule = keyof ContentKitMounts;
|
|
26
37
|
/** A mutation made through the client: the host's cache-invalidation hook gets each one. */
|
|
@@ -44,7 +55,7 @@ export type ContentKitChange =
|
|
|
44
55
|
} | ContentChange;
|
|
45
56
|
export type TokenSource = () => string | null | undefined | Promise<string | null | undefined>;
|
|
46
57
|
export interface HttpOptions {
|
|
47
|
-
/** Where the host mounts ContentKit, e.g. "/api/
|
|
58
|
+
/** Where the host mounts ContentKit's routes (contentkit.Routes.Prefix), e.g. "/api/contentkit". */
|
|
48
59
|
baseUrl: string;
|
|
49
60
|
mounts?: ContentKitMounts;
|
|
50
61
|
/** Transport for API calls; pass an authenticating fetch (auth-ui's authFetch). */
|
|
@@ -67,6 +78,7 @@ export interface RequestOptions {
|
|
|
67
78
|
signal?: AbortSignal;
|
|
68
79
|
/** Read the body as a Blob instead of JSON. */
|
|
69
80
|
blob?: boolean;
|
|
81
|
+
keepalive?: boolean;
|
|
70
82
|
}
|
|
71
83
|
/** The transport every module shares: mounts, auth, language, errors and change events. */
|
|
72
84
|
export declare class Http {
|
|
@@ -77,7 +89,7 @@ export declare class Http {
|
|
|
77
89
|
constructor(o: HttpOptions);
|
|
78
90
|
/** The module's base URL, without a trailing slash. */
|
|
79
91
|
mount(module: ContentKitModule, ref?: RefBody): string;
|
|
80
|
-
request<T>(url: string, { method, body, signal, blob }?: RequestOptions): Promise<T>;
|
|
92
|
+
request<T>(url: string, { method, body, signal, blob, keepalive }?: RequestOptions): Promise<T>;
|
|
81
93
|
/**
|
|
82
94
|
* hls.js `xhrSetup`: opens the request, sends cookies when credentials is
|
|
83
95
|
* "include", and adds the bearer only on the API's origin (never a media host).
|
package/dist/client/http.js
CHANGED
|
@@ -1,49 +1,45 @@
|
|
|
1
1
|
import { ContentKitError as e, aborted as t, readContentKitError as n } from "./errors.js";
|
|
2
|
+
import { CONTENTKIT_MODULES as r } from "./generated/routes.js";
|
|
2
3
|
//#region src/client/http.ts
|
|
3
|
-
var
|
|
4
|
+
var i = (e) => e.replace(/\/+$/, ""), a = class {
|
|
4
5
|
o;
|
|
5
6
|
listeners = /* @__PURE__ */ new Set();
|
|
6
7
|
readScope = { key: "{}" };
|
|
7
8
|
base;
|
|
8
9
|
constructor(e) {
|
|
9
10
|
if (this.o = e, typeof e.baseUrl != "string") throw Error("contentkit: createContentKitClient needs baseUrl");
|
|
10
|
-
this.base =
|
|
11
|
+
this.base = i(e.baseUrl);
|
|
11
12
|
}
|
|
12
13
|
mount(e, t) {
|
|
13
14
|
let n = this.o.mounts?.[e];
|
|
14
15
|
if (typeof n == "function") {
|
|
15
16
|
if (!t) throw Error(`contentkit: the ${e} mount is per item; pass a ref`);
|
|
16
|
-
return
|
|
17
|
-
}
|
|
18
|
-
if (n !== void 0) return r(n);
|
|
19
|
-
switch (e) {
|
|
20
|
-
case "content": return this.base;
|
|
21
|
-
case "media": return `${this.base}/media`;
|
|
22
|
-
case "upload": return `${this.base}/media/upload`;
|
|
23
|
-
default: return `${this.base}/${e}`;
|
|
17
|
+
return i(n(t));
|
|
24
18
|
}
|
|
19
|
+
return n === void 0 ? this.base + r[e] : i(n);
|
|
25
20
|
}
|
|
26
|
-
async request(r, { method: i, body: a, signal: o, blob: s } = {}) {
|
|
27
|
-
let
|
|
28
|
-
a !== void 0 &&
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
let
|
|
21
|
+
async request(r, { method: i, body: a, signal: o, blob: s, keepalive: c } = {}) {
|
|
22
|
+
let l = this.o.fetch ?? fetch, u = new Headers(await this.o.headers?.());
|
|
23
|
+
a !== void 0 && u.set("Content-Type", "application/json");
|
|
24
|
+
let d = await this.o.token?.();
|
|
25
|
+
d && !u.has("Authorization") && u.set("Authorization", `Bearer ${d}`);
|
|
26
|
+
let f = this.o.language?.();
|
|
27
|
+
f && u.set("Accept-Language", f);
|
|
28
|
+
let p;
|
|
34
29
|
try {
|
|
35
|
-
|
|
30
|
+
p = await l(r, {
|
|
36
31
|
method: i ?? (a === void 0 ? "GET" : "POST"),
|
|
37
|
-
headers:
|
|
32
|
+
headers: u,
|
|
38
33
|
body: a === void 0 ? null : JSON.stringify(a),
|
|
39
34
|
credentials: this.o.credentials ?? "same-origin",
|
|
40
|
-
signal: o ?? null
|
|
35
|
+
signal: o ?? null,
|
|
36
|
+
...c ? { keepalive: c } : {}
|
|
41
37
|
});
|
|
42
38
|
} catch (n) {
|
|
43
39
|
throw o?.aborted ? t(o) : new e("network", `ContentKit API ${new URL(r, "http://x").pathname} unreachable`, { cause: n });
|
|
44
40
|
}
|
|
45
|
-
if (!
|
|
46
|
-
return s ? await
|
|
41
|
+
if (!p.ok) throw await n(p);
|
|
42
|
+
return s ? await p.blob() : p.status === 204 ? void 0 : await p.json();
|
|
47
43
|
}
|
|
48
44
|
xhrSetup = async (e, t) => {
|
|
49
45
|
if (e.readyState || e.open("GET", t, !0), this.o.credentials === "include" && (e.withCredentials = !0), !this.onApiOrigin(t)) return;
|
|
@@ -77,6 +73,6 @@ var r = (e) => e.replace(/\/+$/, ""), i = class {
|
|
|
77
73
|
}
|
|
78
74
|
};
|
|
79
75
|
//#endregion
|
|
80
|
-
export {
|
|
76
|
+
export { a as Http };
|
|
81
77
|
|
|
82
78
|
//# sourceMappingURL=http.js.map
|
package/dist/client/http.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"http.js","names":[],"sources":["../../src/client/http.ts"],"sourcesContent":["import { ContentKitError, aborted, readContentKitError } from \"./errors.js\";\nimport type { ContentChange } from \"./content/types.js\";\nimport type { FileInfo, Item, RefBody } from \"./generated/wire.js\";\n\n/** A module's base URL, or one per item (a host that splits uploads by kind). */\nexport type Mount = string | ((ref: RefBody) => string);\n\n/**\n * Where each module lives when the host does not serve them all under\n * baseUrl's fixed sub-paths.\n */\nexport interface ContentKitMounts {\n /**
|
|
1
|
+
{"version":3,"file":"http.js","names":[],"sources":["../../src/client/http.ts"],"sourcesContent":["import { ContentKitError, aborted, readContentKitError } from \"./errors.js\";\nimport type { ContentChange } from \"./content/types.js\";\nimport { CONTENTKIT_MODULES } from \"./generated/routes.js\";\nimport type { FileInfo, Item, RefBody } from \"./generated/wire.js\";\n\n/** A module's base URL, or one per item (a host that splits uploads by kind). */\nexport type Mount = string | ((ref: RefBody) => string);\n\n/**\n * Where each module lives when the host does not serve them all under\n * baseUrl's fixed sub-paths (CONTENTKIT_MODULES: the API version, then the\n * module's path). A mount is the module's full base URL.\n */\nexport interface ContentKitMounts {\n /** Comments, reactions, favorites, polls, bans, moderation. Default `{baseUrl}/v1`. */\n content?: string;\n /** Content items and catalog totals. Default `{baseUrl}/v1`. */\n contents?: string;\n /** Media reads and HLS playlists. Default `{baseUrl}/v1/media`. */\n media?: Mount;\n /** Uploads and commits. Default `{baseUrl}/v1/media/upload`. */\n upload?: Mount;\n /** Content-code lookup. Default `{baseUrl}/v1/codes`. */\n codes?: string;\n /** Groups. Default `{baseUrl}/v1`. */\n groups?: string;\n /** The site's content model. Default `{baseUrl}/v1`. */\n kinds?: string;\n /** User inbox. Default `{baseUrl}/v1/notifications`. */\n notifications?: string;\n /** Content versions: reader plans, reader metadata, forks, downloads. Default `{baseUrl}/v1`. */\n versions?: string;\n /** Offers, group joins and the library. Default `{baseUrl}/v1`. */\n offers?: string;\n /** Discovery: lists, search, typeahead, similar, recommendations, history, signals. Default `{baseUrl}/v1`. */\n discovery?: string;\n /** Bulk import (a service's). Default `{baseUrl}/v1`. */\n import?: string;\n}\n\nexport type ContentKitModule = keyof ContentKitMounts;\n\n/** A mutation made through the client: the host's cache-invalidation hook gets each one. */\nexport type ContentKitChange =\n /** A commit applied; files are the item's uploads as an editor reads them, without URLs. */\n | { type: \"media.committed\"; ref: RefBody; files: FileInfo[] }\n /** An upload finished processing, as an editor read returns it. */\n | { type: \"media.processed\"; ref: RefBody; file: FileInfo }\n | { type: \"notifications.changed\" }\n | { type: \"notifications.updated\"; item: Item }\n | ContentChange;\n\nexport type TokenSource = () => string | null | undefined | Promise<string | null | undefined>;\n\nexport interface HttpOptions {\n /** Where the host mounts ContentKit's routes (contentkit.Routes.Prefix), e.g. \"/api/contentkit\". */\n baseUrl: string;\n mounts?: ContentKitMounts;\n /** Transport for API calls; pass an authenticating fetch (auth-ui's authFetch). */\n fetch?: typeof fetch;\n /**\n * Bearer for API calls and for HLS playlists on the API origin (hls.js\n * loads them with XHR, not fetch). An authenticating fetch overrides it.\n */\n token?: TokenSource;\n /** Sent as Accept-Language. */\n language?: () => string | null | undefined;\n /** Extra headers per call (CSRF). */\n headers?: () => HeadersInit | Promise<HeadersInit>;\n /** Default \"same-origin\"; \"include\" also sends cookies with HLS requests. */\n credentials?: RequestCredentials;\n}\n\nexport interface RequestOptions {\n method?: string;\n body?: unknown;\n signal?: AbortSignal;\n /** Read the body as a Blob instead of JSON. */\n blob?: boolean;\n keepalive?: boolean;\n}\n\nconst trim = (u: string) => u.replace(/\\/+$/, \"\");\n\n/** The transport every module shares: mounts, auth, language, errors and change events. */\nexport class Http {\n private readonly listeners = new Set<(change: ContentKitChange, scope: string | null) => void>();\n private readScope = { key: \"{}\" };\n private readonly base: string;\n\n constructor(private readonly o: HttpOptions) {\n if (typeof o.baseUrl !== \"string\") throw new Error(\"contentkit: createContentKitClient needs baseUrl\");\n this.base = trim(o.baseUrl);\n }\n\n /** The module's base URL, without a trailing slash. */\n mount(module: ContentKitModule, ref?: RefBody): string {\n const m = this.o.mounts?.[module];\n if (typeof m === \"function\") {\n if (!ref) throw new Error(`contentkit: the ${module} mount is per item; pass a ref`);\n return trim(m(ref));\n }\n if (m !== undefined) return trim(m);\n return this.base + CONTENTKIT_MODULES[module];\n }\n\n async request<T>(url: string, { method, body, signal, blob, keepalive }: RequestOptions = {}): Promise<T> {\n const f = this.o.fetch ?? fetch;\n const headers = new Headers(await this.o.headers?.());\n if (body !== undefined) headers.set(\"Content-Type\", \"application/json\");\n const token = await this.o.token?.();\n if (token && !headers.has(\"Authorization\")) headers.set(\"Authorization\", `Bearer ${token}`);\n const lang = this.o.language?.();\n if (lang) headers.set(\"Accept-Language\", lang);\n let res: Response;\n try {\n res = await f(url, {\n method: method ?? (body === undefined ? \"GET\" : \"POST\"),\n headers,\n body: body === undefined ? null : JSON.stringify(body),\n credentials: this.o.credentials ?? \"same-origin\",\n signal: signal ?? null,\n ...(keepalive ? { keepalive } : {}),\n });\n } catch (err) {\n if (signal?.aborted) throw aborted(signal);\n throw new ContentKitError(\"network\", `ContentKit API ${new URL(url, \"http://x\").pathname} unreachable`, { cause: err });\n }\n if (!res.ok) throw await readContentKitError(res);\n if (blob) return (await res.blob()) as T;\n return (res.status === 204 ? undefined : await res.json()) as T;\n }\n\n /**\n * hls.js `xhrSetup`: opens the request, sends cookies when credentials is\n * \"include\", and adds the bearer only on the API's origin (never a media host).\n */\n readonly xhrSetup = async (xhr: XMLHttpRequest, url: string): Promise<void> => {\n if (!xhr.readyState) xhr.open(\"GET\", url, true);\n if (this.o.credentials === \"include\") xhr.withCredentials = true;\n if (!this.onApiOrigin(url)) return;\n const token = await this.o.token?.();\n if (token) xhr.setRequestHeader(\"Authorization\", `Bearer ${token}`);\n };\n\n setReadScope(key: string): void {\n if (key !== this.readScope.key) this.readScope = { key };\n }\n\n /** Capture before awaiting a write; null tells caches to refetch after a scope change. */\n captureChanges(): (change: ContentKitChange) => void {\n const scope = this.readScope;\n return (change) => this.emit(change, scope === this.readScope ? scope.key : null);\n }\n\n subscribe(listener: (change: ContentKitChange, scope: string | null) => void): () => void {\n this.listeners.add(listener);\n return () => void this.listeners.delete(listener);\n }\n\n private emit(change: ContentKitChange, scope: string | null): void {\n for (const l of this.listeners) {\n try {\n l(change, scope);\n } catch (e) {\n // A host listener's fault must not fail the mutation that succeeded.\n console.error(\"contentkit: change listener failed\", e);\n }\n }\n }\n\n private onApiOrigin(url: string): boolean {\n const here = typeof location === \"undefined\" ? \"http://localhost\" : location.href;\n try {\n return new URL(url, here).origin === new URL(this.base || \"/\", here).origin;\n } catch {\n return false;\n }\n }\n}\n"],"mappings":";;;AAkFA,IAAM,KAAQ,MAAc,EAAE,QAAQ,QAAQ,EAAE,GAGnC,IAAb,MAAkB;CAKa;CAJ7B,4BAA6B,IAAI,IAA8D;CAC/F,YAAoB,EAAE,KAAK,KAAK;CAChC;CAEA,YAAY,GAAiC;EAC3C,IAD2B,KAAA,IAAA,GACvB,OAAO,EAAE,WAAY,UAAU,MAAU,MAAM,kDAAkD;EACrG,KAAK,OAAO,EAAK,EAAE,OAAO;CAC5B;CAGA,MAAM,GAA0B,GAAuB;EACrD,IAAM,IAAI,KAAK,EAAE,SAAS;EAC1B,IAAI,OAAO,KAAM,YAAY;GAC3B,IAAI,CAAC,GAAK,MAAU,MAAM,mBAAmB,EAAO,+BAA+B;GACnF,OAAO,EAAK,EAAE,CAAG,CAAC;EACpB;EAEA,OADI,MAAM,KAAA,IACH,KAAK,OAAO,EAAmB,KADV,EAAK,CAAC;CAEpC;CAEA,MAAM,QAAW,GAAa,EAAE,WAAQ,SAAM,WAAQ,SAAM,iBAA8B,CAAC,GAAe;EACxG,IAAM,IAAI,KAAK,EAAE,SAAS,OACpB,IAAU,IAAI,QAAQ,MAAM,KAAK,EAAE,UAAU,CAAC;EACpD,AAAI,MAAS,KAAA,KAAW,EAAQ,IAAI,gBAAgB,kBAAkB;EACtE,IAAM,IAAQ,MAAM,KAAK,EAAE,QAAQ;EACnC,AAAI,KAAS,CAAC,EAAQ,IAAI,eAAe,KAAG,EAAQ,IAAI,iBAAiB,UAAU,GAAO;EAC1F,IAAM,IAAO,KAAK,EAAE,WAAW;EAC/B,AAAI,KAAM,EAAQ,IAAI,mBAAmB,CAAI;EAC7C,IAAI;EACJ,IAAI;GACF,IAAM,MAAM,EAAE,GAAK;IACjB,QAAQ,MAAW,MAAS,KAAA,IAAY,QAAQ;IAChD;IACA,MAAM,MAAS,KAAA,IAAY,OAAO,KAAK,UAAU,CAAI;IACrD,aAAa,KAAK,EAAE,eAAe;IACnC,QAAQ,KAAU;IAClB,GAAI,IAAY,EAAE,aAAU,IAAI,CAAC;GACnC,CAAC;EACH,SAAS,GAAK;GAEZ,MADI,GAAQ,UAAe,EAAQ,CAAM,IACnC,IAAI,EAAgB,WAAW,kBAAkB,IAAI,IAAI,GAAK,UAAU,CAAC,CAAC,SAAS,eAAe,EAAE,OAAO,EAAI,CAAC;EACxH;EACA,IAAI,CAAC,EAAI,IAAI,MAAM,MAAM,EAAoB,CAAG;EAEhD,OADI,IAAc,MAAM,EAAI,KAAK,IACzB,EAAI,WAAW,MAAM,KAAA,IAAY,MAAM,EAAI,KAAK;CAC1D;CAMA,WAAoB,OAAO,GAAqB,MAA+B;EAG7E,IAFK,EAAI,cAAY,EAAI,KAAK,OAAO,GAAK,EAAI,GAC1C,KAAK,EAAE,gBAAgB,cAAW,EAAI,kBAAkB,KACxD,CAAC,KAAK,YAAY,CAAG,GAAG;EAC5B,IAAM,IAAQ,MAAM,KAAK,EAAE,QAAQ;EACnC,AAAI,KAAO,EAAI,iBAAiB,iBAAiB,UAAU,GAAO;CACpE;CAEA,aAAa,GAAmB;EAC9B,AAAI,MAAQ,KAAK,UAAU,QAAK,KAAK,YAAY,EAAE,OAAI;CACzD;CAGA,iBAAqD;EACnD,IAAM,IAAQ,KAAK;EACnB,QAAQ,MAAW,KAAK,KAAK,GAAQ,MAAU,KAAK,YAAY,EAAM,MAAM,IAAI;CAClF;CAEA,UAAU,GAAgF;EAExF,OADA,KAAK,UAAU,IAAI,CAAQ,SACd,KAAK,KAAK,UAAU,OAAO,CAAQ;CAClD;CAEA,KAAa,GAA0B,GAA4B;EACjE,KAAK,IAAM,KAAK,KAAK,WACnB,IAAI;GACF,EAAE,GAAQ,CAAK;EACjB,SAAS,GAAG;GAEV,QAAQ,MAAM,sCAAsC,CAAC;EACvD;CAEJ;CAEA,YAAoB,GAAsB;EACxC,IAAM,IAAO,OAAO,WAAa,MAAc,qBAAqB,SAAS;EAC7E,IAAI;GACF,OAAO,IAAI,IAAI,GAAK,CAAI,CAAC,CAAC,WAAW,IAAI,IAAI,KAAK,QAAQ,KAAK,CAAI,CAAC,CAAC;EACvE,QAAQ;GACN,OAAO;EACT;CACF;AACF"}
|