@openrails/contentkit-ui 0.92.1 → 0.93.1

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.
Files changed (83) hide show
  1. package/README.md +8 -6
  2. package/dist/client/client.d.ts +2 -2
  3. package/dist/client/client.js +2 -2
  4. package/dist/client/client.js.map +1 -1
  5. package/dist/client/content/comments.js +3 -3
  6. package/dist/client/content/comments.js.map +1 -1
  7. package/dist/client/content/favorites.d.ts +2 -2
  8. package/dist/client/content/favorites.js +2 -2
  9. package/dist/client/content/favorites.js.map +1 -1
  10. package/dist/client/content/reactions.js +2 -2
  11. package/dist/client/content/reactions.js.map +1 -1
  12. package/dist/client/content/types.d.ts +2 -2
  13. package/dist/client/content/types.js.map +1 -1
  14. package/dist/client/contents.d.ts +4 -2
  15. package/dist/client/contents.js +7 -2
  16. package/dist/client/contents.js.map +1 -1
  17. package/dist/client/discovery.d.ts +2 -2
  18. package/dist/client/discovery.js +2 -2
  19. package/dist/client/discovery.js.map +1 -1
  20. package/dist/client/{groups.d.ts → entities.d.ts} +14 -14
  21. package/dist/client/{groups.js → entities.js} +19 -19
  22. package/dist/client/entities.js.map +1 -0
  23. package/dist/client/generated/error-codes.d.ts +1 -1
  24. package/dist/client/generated/error-codes.js +28 -0
  25. package/dist/client/generated/error-codes.js.map +1 -1
  26. package/dist/client/generated/routes.d.ts +151 -99
  27. package/dist/client/generated/routes.js +184 -100
  28. package/dist/client/generated/routes.js.map +1 -1
  29. package/dist/client/generated/wire.d.ts +75 -12
  30. package/dist/client/generated/wire.js.map +1 -1
  31. package/dist/client/http.d.ts +4 -2
  32. package/dist/client/http.js.map +1 -1
  33. package/dist/client/index.d.ts +1 -1
  34. package/dist/client/offers.js +4 -4
  35. package/dist/client/offers.js.map +1 -1
  36. package/dist/client.js +2 -2
  37. package/dist/components/admin/content-admin.js +1 -1
  38. package/dist/components/admin/content-admin.js.map +1 -1
  39. package/dist/components/admin/group-manager.js +2 -2
  40. package/dist/components/admin/group-manager.js.map +1 -1
  41. package/dist/components/content/card.js +3 -3
  42. package/dist/components/content/card.js.map +1 -1
  43. package/dist/components/content/editors.js +2 -2
  44. package/dist/components/content/editors.js.map +1 -1
  45. package/dist/components/content/filters.js +6 -6
  46. package/dist/components/content/filters.js.map +1 -1
  47. package/dist/components/content/search.js +3 -3
  48. package/dist/components/content/search.js.map +1 -1
  49. package/dist/components/groups/banner.d.ts +2 -2
  50. package/dist/components/groups/banner.js.map +1 -1
  51. package/dist/components/groups/editor.js +2 -2
  52. package/dist/components/groups/editor.js.map +1 -1
  53. package/dist/components/groups/header.js +1 -1
  54. package/dist/components/groups/header.js.map +1 -1
  55. package/dist/components/groups/memberships.js +6 -6
  56. package/dist/components/groups/memberships.js.map +1 -1
  57. package/dist/components/groups/parts.js +4 -4
  58. package/dist/components/groups/parts.js.map +1 -1
  59. package/dist/locales/de.js +7 -0
  60. package/dist/locales/de.js.map +1 -1
  61. package/dist/locales/en.d.ts +7 -0
  62. package/dist/locales/en.js +7 -0
  63. package/dist/locales/en.js.map +1 -1
  64. package/dist/locales/es.js +7 -0
  65. package/dist/locales/es.js.map +1 -1
  66. package/dist/locales/ja.js +7 -0
  67. package/dist/locales/ja.js.map +1 -1
  68. package/dist/locales/ko.js +7 -0
  69. package/dist/locales/ko.js.map +1 -1
  70. package/dist/locales/zh.js +7 -0
  71. package/dist/locales/zh.js.map +1 -1
  72. package/dist/react/admin.js +1 -1
  73. package/dist/react/admin.js.map +1 -1
  74. package/dist/react/discovery.d.ts +1 -1
  75. package/dist/react/discovery.js +5 -5
  76. package/dist/react/discovery.js.map +1 -1
  77. package/dist/react/groups.d.ts +5 -5
  78. package/dist/react/groups.js +21 -21
  79. package/dist/react/groups.js.map +1 -1
  80. package/dist/react/resources.js +1 -1
  81. package/dist/react/resources.js.map +1 -1
  82. package/package.json +1 -1
  83. package/dist/client/groups.js.map +0 -1
package/README.md CHANGED
@@ -74,7 +74,7 @@ the second `subscribe` / `onChange` argument, or `null` when the scope changed d
74
74
  operation. This does not change the operation's result or its authentication.
75
75
 
76
76
  - **Mounts.** Without `mounts`, modules live under `{baseUrl}/v1`: content,
77
- groups and the content model at its root, `/media` (reads, HLS),
77
+ entities and the content model at its root, `/media` (reads, HLS),
78
78
  `/media/upload`, `/codes`. A mount is a module's full base URL.
79
79
  - **`client.media`**: `upload`, `put` (upload, commit, wait), `commit`, `read`,
80
80
  `waitFor`, `editorView`, `getFrame`, `hlsBase(ref, dir)`, `discard`, and
@@ -87,13 +87,15 @@ operation. This does not change the operation's result or its authentication.
87
87
  - **Content modules**, one per resource, each method one route of the
88
88
  generated route table with its generated types: `contents`, `catalog`, `comments`,
89
89
  `reactions`, `favorites`, `polls`, `bans` (`"owner"` or `"global"`; `get("global", user)`),
90
- `moderation`, `groups`, `codes`. Lists take `limit`/`offset` (the review
90
+ `moderation`, `entities`, `codes`. Lists take `limit`/`offset` (the review
91
91
  queue and group listings a `cursor`); `contents.manage` lists what the caller
92
92
  manages (`kind`, `state` incl. `deleted` for `contents.restore`, `q`); `catalog.totals({kinds, languages})`
93
93
  counts what is open; staff lists are `polls.adminList` (`state`, `q`),
94
- `comments.adminList` (`contentKind`, `author`); `groups.members(id)` pages
95
- a group's memberships, `groups.ofContent(id)` / `setOfContent` a content's,
96
- `groups.uploadCover(group, file)` its cover; `client.kinds()` the content model.
94
+ `comments.adminList` (`contentKind`, `author`); `entities.members(id)` pages
95
+ an entity's memberships, `entities.ofContent(id)` / `setOfContent` a content's,
96
+ `entities.uploadImage(entity, "cover", file)` its cover; `client.kinds()` the content model.
97
+ `contents.manage({kind: "gallery"})` uses `/manage/gallery`; omitting `kind`
98
+ lists manageable content across kinds at `/manage`.
97
99
  - **Images of content and polls** go to the item's server-named upload path:
98
100
  `media.uploadNamed(ref, file)` resolves the name content routes take
99
101
  (`contents.setCover(id, version, name)`: every file of a content lives in a
@@ -293,7 +295,7 @@ Every card list (`ContentGrid`, `ContentListing`, `ContentRail`,
293
295
  the host's badges, drawn over the cover (place them yourself; clicks reach
294
296
  the card, and click signals stay intact). Cards carry what badges need:
295
297
  `access.level` and `access.tiers` (the effective rule, the same for every
296
- reader), `version.has_audio`, `viewer.favorited` and `groups`.
298
+ reader), `version.has_audio`, `viewer.favorited` and `entities`.
297
299
 
298
300
  `ContentGrid` and `ContentListing` take `locked`: `show` (default) marks the
299
301
  cards the reader doesn't open, `hide` leaves them out, and `collapse` lists
@@ -9,7 +9,7 @@ import { PollsClient } from './content/polls.js';
9
9
  import { ReactionsClient } from './content/reactions.js';
10
10
  import { Batch, Config, ContentModel, RefBody, Result } from './generated/wire.js';
11
11
  import { DiscoveryClient } from './discovery.js';
12
- import { GroupsClient } from './groups.js';
12
+ import { EntitiesClient } from './entities.js';
13
13
  import { OffersClient } from './offers.js';
14
14
  import { StatsClient } from './stats.js';
15
15
  import { VersionsClient } from './versions.js';
@@ -46,7 +46,7 @@ export interface ContentKitClient {
46
46
  /** The review queue of held comments and content. */
47
47
  readonly moderation: ModerationClient;
48
48
  /** Groups: listings, pages, staff writes and memberships. */
49
- readonly groups: GroupsClient;
49
+ readonly entities: EntitiesClient;
50
50
  /** Lists, search, typeahead, rails, release dates, content filters, history, signals and exposures. */
51
51
  readonly discovery: DiscoveryClient;
52
52
  /** Content versions: reader plans, reader metadata, forks and downloads. */
@@ -10,7 +10,7 @@ import { FavoritesClient as c } from "./content/favorites.js";
10
10
  import { ModerationClient as l } from "./content/moderation.js";
11
11
  import { PollsClient as u } from "./content/polls.js";
12
12
  import { ReactionsClient as d } from "./content/reactions.js";
13
- import { GroupsClient as f } from "./groups.js";
13
+ import { EntitiesClient as f } from "./entities.js";
14
14
  import { OffersClient as p } from "./offers.js";
15
15
  import { StatsClient as m } from "./stats.js";
16
16
  import { VersionsClient as h } from "./versions.js";
@@ -29,7 +29,7 @@ function v(v) {
29
29
  polls: new u(S, C),
30
30
  bans: new a(S),
31
31
  moderation: new l(S),
32
- groups: new f(S, C),
32
+ entities: new f(S, C),
33
33
  discovery: new s(S),
34
34
  versions: new h(S),
35
35
  offers: new p(S),
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","names":[],"sources":["../../src/client/client.ts"],"sourcesContent":["import { CatalogClient } from \"./catalog.js\";\nimport { CodesClient } from \"./codes.js\";\nimport { ContentsClient } from \"./contents.js\";\nimport { BansClient } from \"./content/bans.js\";\nimport { CommentsClient } from \"./content/comments.js\";\nimport { FavoritesClient } from \"./content/favorites.js\";\nimport { ModerationClient } from \"./content/moderation.js\";\nimport { PollsClient } from \"./content/polls.js\";\nimport { ReactionsClient } from \"./content/reactions.js\";\nimport type { Batch, Config, ContentModel, RefBody, Result } from \"./generated/wire.js\";\nimport { DiscoveryClient } from \"./discovery.js\";\nimport { GroupsClient } from \"./groups.js\";\nimport { OffersClient } from \"./offers.js\";\nimport { StatsClient } from \"./stats.js\";\nimport { VersionsClient } from \"./versions.js\";\nimport { Http, type ContentKitChange, type ContentKitModule, type HttpOptions } from \"./http.js\";\nimport { MediaClient, type ContentFolders, type MediaOptions } from \"./media/client.js\";\nimport { call } from \"./route.js\";\nimport { NotificationsClient } from \"./notifications.js\";\n\nexport interface ContentKitClientOptions extends HttpOptions {\n /** Upload tuning (transport, part concurrency, retries). */\n media?: MediaOptions;\n /** The media kind of poll folders, when the host renamed it (content.Media). */\n folders?: ContentFolders;\n}\n\n/**\n * One ContentKit deployment as the browser sees it. Each module is a property\n * over one shared transport (mounts, auth, language, errors, change events).\n */\nexport interface ContentKitClient {\n /** Uploads, multipart, commits, reads, frames, HLS bases, the HLS loader and inline images. */\n readonly media: MediaClient;\n /** Content items: reads, and writes for their creators, owner-group editors and staff. */\n readonly contents: ContentsClient;\n /** The catalog's totals by kind, language and audience. */\n readonly catalog: CatalogClient;\n /** Threads, replies, edits, tombstones, reactions, standing, the latest feed, moderation. */\n readonly comments: CommentsClient;\n /** Likes and dislikes of an item. */\n readonly reactions: ReactionsClient;\n /** The signed-in caller's favorites. */\n readonly favorites: FavoritesClient;\n /** Polls: votes, free-text answers and the staff editor. */\n readonly polls: PollsClient;\n /** Comment bans, owner and global. */\n readonly bans: BansClient;\n /** The review queue of held comments and content. */\n readonly moderation: ModerationClient;\n /** Groups: listings, pages, staff writes and memberships. */\n readonly groups: GroupsClient;\n /** Lists, search, typeahead, rails, release dates, content filters, history, signals and exposures. */\n readonly discovery: DiscoveryClient;\n /** Content versions: reader plans, reader metadata, forks and downloads. */\n readonly versions: VersionsClient;\n /** Offers on contents, versions and groups; group joins; the reader's library. */\n readonly offers: OffersClient;\n /** Content-code lookup. */\n readonly codes: CodesClient;\n /** Staff activity and rankings; the signed-in reader's own statistics. */\n readonly stats: StatsClient;\n /** The signed-in person's native and imported notifications. */\n readonly notifications: NotificationsClient;\n\n /** What the content module allows: which interactions signed-out visitors may make. */\n config(signal?: AbortSignal): Promise<Config>;\n /** The site's content model: languages, tiers, kinds, group kinds and content filters. */\n kinds(signal?: AbortSignal): Promise<ContentModel>;\n /** Staff bulk import (root:import:write): groups, contents, memberships, offers and aliases, idempotent per source. */\n import(batch: Batch): Promise<Result>;\n /** A module's base URL as configured (no trailing slash). */\n url(module: ContentKitModule, ref?: RefBody): string;\n /** Cache context only, not authentication. The React provider keeps this in sync. */\n setReadScope(scope: string): void;\n /** Every successful mutation; a null scope means its data predates a context change. */\n subscribe(listener: (change: ContentKitChange, scope: string | null) => void): () => void;\n}\n\nexport function createContentKitClient(options: ContentKitClientOptions): ContentKitClient {\n const { media: mediaOptions, folders, ...http } = options;\n const h = new Http(http);\n const media = new MediaClient(h, mediaOptions, folders);\n return {\n media,\n contents: new ContentsClient(h),\n catalog: new CatalogClient(h),\n comments: new CommentsClient(h),\n reactions: new ReactionsClient(h),\n favorites: new FavoritesClient(h),\n polls: new PollsClient(h, media),\n bans: new BansClient(h),\n moderation: new ModerationClient(h),\n groups: new GroupsClient(h, media),\n discovery: new DiscoveryClient(h),\n versions: new VersionsClient(h),\n offers: new OffersClient(h),\n codes: new CodesClient(h),\n stats: new StatsClient(h),\n notifications: new NotificationsClient(h),\n config: (signal) => call(h, \"GET\", \"/config\", { signal }),\n kinds: (signal) => call(h, \"GET\", \"/kinds\", { signal }),\n import: (batch) => call(h, \"POST\", \"/import\", { body: batch }),\n url: (module, ref) => h.mount(module, ref),\n setReadScope: (scope) => h.setReadScope(scope),\n subscribe: (listener) => h.subscribe(listener),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA+EA,SAAgB,EAAuB,GAAoD;CACzF,IAAM,EAAE,OAAO,GAAc,YAAS,GAAG,MAAS,GAC5C,IAAI,IAAI,EAAK,CAAI,GACjB,IAAQ,IAAI,EAAY,GAAG,GAAc,CAAO;CACtD,OAAO;EACL;EACA,UAAU,IAAI,EAAe,CAAC;EAC9B,SAAS,IAAI,EAAc,CAAC;EAC5B,UAAU,IAAI,EAAe,CAAC;EAC9B,WAAW,IAAI,EAAgB,CAAC;EAChC,WAAW,IAAI,EAAgB,CAAC;EAChC,OAAO,IAAI,EAAY,GAAG,CAAK;EAC/B,MAAM,IAAI,EAAW,CAAC;EACtB,YAAY,IAAI,EAAiB,CAAC;EAClC,QAAQ,IAAI,EAAa,GAAG,CAAK;EACjC,WAAW,IAAI,EAAgB,CAAC;EAChC,UAAU,IAAI,EAAe,CAAC;EAC9B,QAAQ,IAAI,EAAa,CAAC;EAC1B,OAAO,IAAI,EAAY,CAAC;EACxB,OAAO,IAAI,EAAY,CAAC;EACxB,eAAe,IAAI,EAAoB,CAAC;EACxC,SAAS,MAAW,EAAK,GAAG,OAAO,WAAW,EAAE,UAAO,CAAC;EACxD,QAAQ,MAAW,EAAK,GAAG,OAAO,UAAU,EAAE,UAAO,CAAC;EACtD,SAAS,MAAU,EAAK,GAAG,QAAQ,WAAW,EAAE,MAAM,EAAM,CAAC;EAC7D,MAAM,GAAQ,MAAQ,EAAE,MAAM,GAAQ,CAAG;EACzC,eAAe,MAAU,EAAE,aAAa,CAAK;EAC7C,YAAY,MAAa,EAAE,UAAU,CAAQ;CAC/C;AACF"}
1
+ {"version":3,"file":"client.js","names":[],"sources":["../../src/client/client.ts"],"sourcesContent":["import { CatalogClient } from \"./catalog.js\";\nimport { CodesClient } from \"./codes.js\";\nimport { ContentsClient } from \"./contents.js\";\nimport { BansClient } from \"./content/bans.js\";\nimport { CommentsClient } from \"./content/comments.js\";\nimport { FavoritesClient } from \"./content/favorites.js\";\nimport { ModerationClient } from \"./content/moderation.js\";\nimport { PollsClient } from \"./content/polls.js\";\nimport { ReactionsClient } from \"./content/reactions.js\";\nimport type { Batch, Config, ContentModel, RefBody, Result } from \"./generated/wire.js\";\nimport { DiscoveryClient } from \"./discovery.js\";\nimport { EntitiesClient } from \"./entities.js\";\nimport { OffersClient } from \"./offers.js\";\nimport { StatsClient } from \"./stats.js\";\nimport { VersionsClient } from \"./versions.js\";\nimport { Http, type ContentKitChange, type ContentKitModule, type HttpOptions } from \"./http.js\";\nimport { MediaClient, type ContentFolders, type MediaOptions } from \"./media/client.js\";\nimport { call } from \"./route.js\";\nimport { NotificationsClient } from \"./notifications.js\";\n\nexport interface ContentKitClientOptions extends HttpOptions {\n /** Upload tuning (transport, part concurrency, retries). */\n media?: MediaOptions;\n /** The media kind of poll folders, when the host renamed it (content.Media). */\n folders?: ContentFolders;\n}\n\n/**\n * One ContentKit deployment as the browser sees it. Each module is a property\n * over one shared transport (mounts, auth, language, errors, change events).\n */\nexport interface ContentKitClient {\n /** Uploads, multipart, commits, reads, frames, HLS bases, the HLS loader and inline images. */\n readonly media: MediaClient;\n /** Content items: reads, and writes for their creators, owner-group editors and staff. */\n readonly contents: ContentsClient;\n /** The catalog's totals by kind, language and audience. */\n readonly catalog: CatalogClient;\n /** Threads, replies, edits, tombstones, reactions, standing, the latest feed, moderation. */\n readonly comments: CommentsClient;\n /** Likes and dislikes of an item. */\n readonly reactions: ReactionsClient;\n /** The signed-in caller's favorites. */\n readonly favorites: FavoritesClient;\n /** Polls: votes, free-text answers and the staff editor. */\n readonly polls: PollsClient;\n /** Comment bans, owner and global. */\n readonly bans: BansClient;\n /** The review queue of held comments and content. */\n readonly moderation: ModerationClient;\n /** Groups: listings, pages, staff writes and memberships. */\n readonly entities: EntitiesClient;\n /** Lists, search, typeahead, rails, release dates, content filters, history, signals and exposures. */\n readonly discovery: DiscoveryClient;\n /** Content versions: reader plans, reader metadata, forks and downloads. */\n readonly versions: VersionsClient;\n /** Offers on contents, versions and groups; group joins; the reader's library. */\n readonly offers: OffersClient;\n /** Content-code lookup. */\n readonly codes: CodesClient;\n /** Staff activity and rankings; the signed-in reader's own statistics. */\n readonly stats: StatsClient;\n /** The signed-in person's native and imported notifications. */\n readonly notifications: NotificationsClient;\n\n /** What the content module allows: which interactions signed-out visitors may make. */\n config(signal?: AbortSignal): Promise<Config>;\n /** The site's content model: languages, tiers, kinds, group kinds and content filters. */\n kinds(signal?: AbortSignal): Promise<ContentModel>;\n /** Staff bulk import (root:import:write): groups, contents, memberships, offers and aliases, idempotent per source. */\n import(batch: Batch): Promise<Result>;\n /** A module's base URL as configured (no trailing slash). */\n url(module: ContentKitModule, ref?: RefBody): string;\n /** Cache context only, not authentication. The React provider keeps this in sync. */\n setReadScope(scope: string): void;\n /** Every successful mutation; a null scope means its data predates a context change. */\n subscribe(listener: (change: ContentKitChange, scope: string | null) => void): () => void;\n}\n\nexport function createContentKitClient(options: ContentKitClientOptions): ContentKitClient {\n const { media: mediaOptions, folders, ...http } = options;\n const h = new Http(http);\n const media = new MediaClient(h, mediaOptions, folders);\n return {\n media,\n contents: new ContentsClient(h),\n catalog: new CatalogClient(h),\n comments: new CommentsClient(h),\n reactions: new ReactionsClient(h),\n favorites: new FavoritesClient(h),\n polls: new PollsClient(h, media),\n bans: new BansClient(h),\n moderation: new ModerationClient(h),\n entities: new EntitiesClient(h, media),\n discovery: new DiscoveryClient(h),\n versions: new VersionsClient(h),\n offers: new OffersClient(h),\n codes: new CodesClient(h),\n stats: new StatsClient(h),\n notifications: new NotificationsClient(h),\n config: (signal) => call(h, \"GET\", \"/config\", { signal }),\n kinds: (signal) => call(h, \"GET\", \"/kinds\", { signal }),\n import: (batch) => call(h, \"POST\", \"/import\", { body: batch }),\n url: (module, ref) => h.mount(module, ref),\n setReadScope: (scope) => h.setReadScope(scope),\n subscribe: (listener) => h.subscribe(listener),\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;AA+EA,SAAgB,EAAuB,GAAoD;CACzF,IAAM,EAAE,OAAO,GAAc,YAAS,GAAG,MAAS,GAC5C,IAAI,IAAI,EAAK,CAAI,GACjB,IAAQ,IAAI,EAAY,GAAG,GAAc,CAAO;CACtD,OAAO;EACL;EACA,UAAU,IAAI,EAAe,CAAC;EAC9B,SAAS,IAAI,EAAc,CAAC;EAC5B,UAAU,IAAI,EAAe,CAAC;EAC9B,WAAW,IAAI,EAAgB,CAAC;EAChC,WAAW,IAAI,EAAgB,CAAC;EAChC,OAAO,IAAI,EAAY,GAAG,CAAK;EAC/B,MAAM,IAAI,EAAW,CAAC;EACtB,YAAY,IAAI,EAAiB,CAAC;EAClC,UAAU,IAAI,EAAe,GAAG,CAAK;EACrC,WAAW,IAAI,EAAgB,CAAC;EAChC,UAAU,IAAI,EAAe,CAAC;EAC9B,QAAQ,IAAI,EAAa,CAAC;EAC1B,OAAO,IAAI,EAAY,CAAC;EACxB,OAAO,IAAI,EAAY,CAAC;EACxB,eAAe,IAAI,EAAoB,CAAC;EACxC,SAAS,MAAW,EAAK,GAAG,OAAO,WAAW,EAAE,UAAO,CAAC;EACxD,QAAQ,MAAW,EAAK,GAAG,OAAO,UAAU,EAAE,UAAO,CAAC;EACtD,SAAS,MAAU,EAAK,GAAG,QAAQ,WAAW,EAAE,MAAM,EAAM,CAAC;EAC7D,MAAM,GAAQ,MAAQ,EAAE,MAAM,GAAQ,CAAG;EACzC,eAAe,MAAU,EAAE,aAAa,CAAK;EAC7C,YAAY,MAAa,EAAE,UAAU,CAAQ;CAC/C;AACF"}
@@ -11,7 +11,7 @@ var n = class {
11
11
  params: { id: t.id },
12
12
  signal: r
13
13
  };
14
- return t.type === "groups" ? e(this.http, "GET", "/groups/{id}/comments", {
14
+ return t.type === "entities" ? e(this.http, "GET", "/entities/{id}/comments", {
15
15
  ...i,
16
16
  query: n
17
17
  }) : e(this.http, "GET", "/contents/{id}/comments", {
@@ -33,7 +33,7 @@ var n = class {
33
33
  let r = this.http.captureChanges(), i = {
34
34
  params: { id: t.id },
35
35
  body: n
36
- }, a = t.type === "groups" ? await e(this.http, "POST", "/groups/{id}/comments", i) : await e(this.http, "POST", "/contents/{id}/comments", {
36
+ }, a = t.type === "entities" ? await e(this.http, "POST", "/entities/{id}/comments", i) : await e(this.http, "POST", "/contents/{id}/comments", {
37
37
  ...i,
38
38
  query: { version: t.version }
39
39
  });
@@ -73,7 +73,7 @@ var n = class {
73
73
  params: { id: t.id },
74
74
  signal: n
75
75
  };
76
- return t.type === "groups" ? e(this.http, "GET", "/groups/{id}/can-comment", r) : e(this.http, "GET", "/contents/{id}/can-comment", {
76
+ return t.type === "entities" ? e(this.http, "GET", "/entities/{id}/can-comment", r) : e(this.http, "GET", "/contents/{id}/can-comment", {
77
77
  ...r,
78
78
  query: { version: t.version }
79
79
  });
@@ -1 +1 @@
1
- {"version":3,"file":"comments.js","names":[],"sources":["../../../src/client/content/comments.ts"],"sourcesContent":["import type { AdminComment, Comment, CommentInput, CommentStanding, FeedItem, ReactionCounts } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { call, type PageQuery } from \"../route.js\";\nimport { reactionVerb, type Reaction, type Sort, type Target } from \"./types.js\";\n\nexport interface CommentQuery extends PageQuery {\n sort?: Sort;\n /** Only this language's thread. */\n language?: string;\n}\n\nexport interface AdminCommentQuery extends PageQuery {\n /** Only comments on this content kind. */\n contentKind?: string;\n /** Only comments by this user id. */\n author?: string;\n}\n\n/** Comments on an item: threads, replies, edits, tombstones, reactions, standing, the latest feed and moderation. */\nexport class CommentsClient {\n constructor(private readonly http: Http) {}\n\n /** The target's top-level comments with reply counts; the caller also gets its own held and rejected ones. */\n list(t: Target, q: CommentQuery = {}, signal?: AbortSignal): Promise<Comment[]> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"groups\"\n ? call(this.http, \"GET\", \"/groups/{id}/comments\", { ...o, query: q })\n : call(this.http, \"GET\", \"/contents/{id}/comments\", { ...o, query: { ...q, version: t.version } });\n }\n /** A top-level comment's replies, oldest first. */\n replies(id: string, q: PageQuery = {}, signal?: AbortSignal): Promise<Comment[]> {\n return call(this.http, \"GET\", \"/comments/{cid}/replies\", { params: { cid: id }, query: q, signal });\n }\n /** Comments on the target in a language's thread, or replies to a top-level comment (reply_to_id); anonymous callers give anon_name. */\n async create(t: Target, input: CommentInput): Promise<Comment> {\n const emit = this.http.captureChanges();\n const o = { params: { id: t.id }, body: input };\n const comment: Comment =\n t.type === \"groups\" ? await call(this.http, \"POST\", \"/groups/{id}/comments\", o) : await call(this.http, \"POST\", \"/contents/{id}/comments\", { ...o, query: { version: t.version } });\n emit({ type: \"comment.created\", target: t, comment });\n return comment;\n }\n /** Replaces the body: its author, or a moderator. */\n async edit(id: string, body: string): Promise<Comment> {\n const emit = this.http.captureChanges();\n const comment: Comment = await call(this.http, \"PATCH\", \"/comments/{cid}\", { params: { cid: id }, body: { body } });\n emit({ type: \"comment.updated\", comment });\n return comment;\n }\n /** Leaves a tombstone: its author, or a moderator. */\n async delete(id: string): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/comments/{cid}\", { params: { cid: id } });\n emit({ type: \"comment.deleted\", id });\n }\n /** Sets the caller's reaction to a comment. */\n async react(id: string, value: Reaction): Promise<ReactionCounts> {\n const emit = this.http.captureChanges();\n const params = { cid: id };\n const counts: ReactionCounts =\n value === 0 ? await call(this.http, \"DELETE\", \"/comments/{cid}/reaction\", { params }) : await call(this.http, \"POST\", `/comments/{cid}/${reactionVerb(value)}` as const, { params });\n emit({ type: \"comment.reacted\", id, counts });\n return counts;\n }\n /** Whether the caller may comment on the item, the ban that stops it, and what it may do to others' comments. */\n standing(t: Target, signal?: AbortSignal): Promise<CommentStanding> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"groups\"\n ? call(this.http, \"GET\", \"/groups/{id}/can-comment\", o)\n : call(this.http, \"GET\", \"/contents/{id}/can-comment\", { ...o, query: { version: t.version } });\n }\n /** The newest published comments across the site, with their items; a page may under-fill. */\n latest(q: PageQuery & { language?: string } = {}, signal?: AbortSignal): Promise<FeedItem[]> {\n return call(this.http, \"GET\", \"/comments/latest\", { query: q, signal });\n }\n /** Every comment, newest first, deleted, held and rejected ones with their bodies (root:comments:moderate). */\n adminList(q: AdminCommentQuery = {}, signal?: AbortSignal): Promise<AdminComment[]> {\n const { contentKind, ...rest } = q;\n return call(this.http, \"GET\", \"/comments/admin\", { query: { ...rest, content_kind: contentKind }, signal });\n }\n /** Restores a deleted comment (root:comments:moderate). */\n async restore(id: string): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"POST\", \"/comments/{cid}/restore\", { params: { cid: id } });\n emit({ type: \"comment.restored\", id });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"comments.js","names":[],"sources":["../../../src/client/content/comments.ts"],"sourcesContent":["import type { AdminComment, Comment, CommentInput, CommentStanding, FeedItem, ReactionCounts } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { call, type PageQuery } from \"../route.js\";\nimport { reactionVerb, type Reaction, type Sort, type Target } from \"./types.js\";\n\nexport interface CommentQuery extends PageQuery {\n sort?: Sort;\n /** Only this language's thread. */\n language?: string;\n}\n\nexport interface AdminCommentQuery extends PageQuery {\n /** Only comments on this content kind. */\n contentKind?: string;\n /** Only comments by this user id. */\n author?: string;\n}\n\n/** Comments on an item: threads, replies, edits, tombstones, reactions, standing, the latest feed and moderation. */\nexport class CommentsClient {\n constructor(private readonly http: Http) {}\n\n /** The target's top-level comments with reply counts; the caller also gets its own held and rejected ones. */\n list(t: Target, q: CommentQuery = {}, signal?: AbortSignal): Promise<Comment[]> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"entities\"\n ? call(this.http, \"GET\", \"/entities/{id}/comments\", { ...o, query: q })\n : call(this.http, \"GET\", \"/contents/{id}/comments\", { ...o, query: { ...q, version: t.version } });\n }\n /** A top-level comment's replies, oldest first. */\n replies(id: string, q: PageQuery = {}, signal?: AbortSignal): Promise<Comment[]> {\n return call(this.http, \"GET\", \"/comments/{cid}/replies\", { params: { cid: id }, query: q, signal });\n }\n /** Comments on the target in a language's thread, or replies to a top-level comment (reply_to_id); anonymous callers give anon_name. */\n async create(t: Target, input: CommentInput): Promise<Comment> {\n const emit = this.http.captureChanges();\n const o = { params: { id: t.id }, body: input };\n const comment: Comment =\n t.type === \"entities\" ? await call(this.http, \"POST\", \"/entities/{id}/comments\", o) : await call(this.http, \"POST\", \"/contents/{id}/comments\", { ...o, query: { version: t.version } });\n emit({ type: \"comment.created\", target: t, comment });\n return comment;\n }\n /** Replaces the body: its author, or a moderator. */\n async edit(id: string, body: string): Promise<Comment> {\n const emit = this.http.captureChanges();\n const comment: Comment = await call(this.http, \"PATCH\", \"/comments/{cid}\", { params: { cid: id }, body: { body } });\n emit({ type: \"comment.updated\", comment });\n return comment;\n }\n /** Leaves a tombstone: its author, or a moderator. */\n async delete(id: string): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/comments/{cid}\", { params: { cid: id } });\n emit({ type: \"comment.deleted\", id });\n }\n /** Sets the caller's reaction to a comment. */\n async react(id: string, value: Reaction): Promise<ReactionCounts> {\n const emit = this.http.captureChanges();\n const params = { cid: id };\n const counts: ReactionCounts =\n value === 0 ? await call(this.http, \"DELETE\", \"/comments/{cid}/reaction\", { params }) : await call(this.http, \"POST\", `/comments/{cid}/${reactionVerb(value)}` as const, { params });\n emit({ type: \"comment.reacted\", id, counts });\n return counts;\n }\n /** Whether the caller may comment on the item, the ban that stops it, and what it may do to others' comments. */\n standing(t: Target, signal?: AbortSignal): Promise<CommentStanding> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"entities\"\n ? call(this.http, \"GET\", \"/entities/{id}/can-comment\", o)\n : call(this.http, \"GET\", \"/contents/{id}/can-comment\", { ...o, query: { version: t.version } });\n }\n /** The newest published comments across the site, with their items; a page may under-fill. */\n latest(q: PageQuery & { language?: string } = {}, signal?: AbortSignal): Promise<FeedItem[]> {\n return call(this.http, \"GET\", \"/comments/latest\", { query: q, signal });\n }\n /** Every comment, newest first, deleted, held and rejected ones with their bodies (root:comments:moderate). */\n adminList(q: AdminCommentQuery = {}, signal?: AbortSignal): Promise<AdminComment[]> {\n const { contentKind, ...rest } = q;\n return call(this.http, \"GET\", \"/comments/admin\", { query: { ...rest, content_kind: contentKind }, signal });\n }\n /** Restores a deleted comment (root:comments:moderate). */\n async restore(id: string): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"POST\", \"/comments/{cid}/restore\", { params: { cid: id } });\n emit({ type: \"comment.restored\", id });\n }\n}\n"],"mappings":"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"}
@@ -5,11 +5,11 @@ import { Target } from './types.js';
5
5
  /** A page of the caller's favorites or reactions. */
6
6
  export interface MineQuery {
7
7
  /** contents (the default) or groups. */
8
- target?: "contents" | "groups";
8
+ target?: "contents" | "entities";
9
9
  /** One content kind or group kind. */
10
10
  kind?: string;
11
11
  /** The group kinds each card names; every kind with a page by default. */
12
- card_groups?: readonly string[];
12
+ card_entities?: readonly string[];
13
13
  cursor?: string;
14
14
  limit?: number;
15
15
  language?: string;
@@ -11,13 +11,13 @@ var n = class {
11
11
  params: { id: t.id },
12
12
  signal: n
13
13
  };
14
- return t.type === "groups" ? e(this.http, "GET", "/groups/{id}/favorite", r) : e(this.http, "GET", "/contents/{id}/favorite", {
14
+ return t.type === "entities" ? e(this.http, "GET", "/entities/{id}/favorite", r) : e(this.http, "GET", "/contents/{id}/favorite", {
15
15
  ...r,
16
16
  query: { version: t.version }
17
17
  });
18
18
  }
19
19
  async set(t, n) {
20
- let r = this.http.captureChanges(), i = n ? "POST" : "DELETE", a = { params: { id: t.id } }, o = t.type === "groups" ? await e(this.http, i, "/groups/{id}/favorite", a) : await e(this.http, i, "/contents/{id}/favorite", {
20
+ let r = this.http.captureChanges(), i = n ? "POST" : "DELETE", a = { params: { id: t.id } }, o = t.type === "entities" ? await e(this.http, i, "/entities/{id}/favorite", a) : await e(this.http, i, "/contents/{id}/favorite", {
21
21
  ...a,
22
22
  query: { version: t.version }
23
23
  });
@@ -1 +1 @@
1
- {"version":3,"file":"favorites.js","names":[],"sources":["../../../src/client/content/favorites.ts"],"sourcesContent":["import type { FavoriteState, InteractionPage } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { query, type AccessMode } from \"../discovery.js\";\nimport { call } from \"../route.js\";\nimport type { Target } from \"./types.js\";\n\n/** A page of the caller's favorites or reactions. */\nexport interface MineQuery {\n /** contents (the default) or groups. */\n target?: \"contents\" | \"groups\";\n /** One content kind or group kind. */\n kind?: string;\n /** The group kinds each card names; every kind with a page by default. */\n card_groups?: readonly string[];\n cursor?: string;\n limit?: number;\n language?: string;\n display_language?: string;\n mode?: AccessMode;\n}\n\n/** Favorites: the target's count for everyone, the signed-in caller's own. */\nexport class FavoritesClient {\n constructor(private readonly http: Http) {}\n\n /** The target's favorite count and whether the caller favorited it (never, signed out). */\n get(t: Target, signal?: AbortSignal): Promise<FavoriteState> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"groups\" ? call(this.http, \"GET\", \"/groups/{id}/favorite\", o) : call(this.http, \"GET\", \"/contents/{id}/favorite\", { ...o, query: { version: t.version } });\n }\n /** Favorites or unfavorites the target (signed in); repeating is a no-op. Resolves with the new state and count. */\n async set(t: Target, favorited: boolean): Promise<FavoriteState> {\n const emit = this.http.captureChanges();\n const method = favorited ? \"POST\" : \"DELETE\";\n const o = { params: { id: t.id } };\n const state: FavoriteState =\n t.type === \"groups\" ? await call(this.http, method, \"/groups/{id}/favorite\", o) : await call(this.http, method, \"/contents/{id}/favorite\", { ...o, query: { version: t.version } });\n emit({ type: \"favorite.changed\", target: t, favorited: state.favorited, count: state.count });\n return state;\n }\n /** The caller's favorites, most recent first: content cards or groups. */\n mine(q: MineQuery = {}, signal?: AbortSignal): Promise<InteractionPage> {\n return call(this.http, \"GET\", \"/me/favorites\", { query: query(q) as never, signal });\n }\n}\n"],"mappings":";;;AAsBA,IAAa,IAAb,MAA6B;CACE;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,IAAI,GAAW,GAA8C;EAC3D,IAAM,IAAI;GAAE,QAAQ,EAAE,IAAI,EAAE,GAAG;GAAG;EAAO;EACzC,OAAO,EAAE,SAAS,WAAW,EAAK,KAAK,MAAM,OAAO,yBAAyB,CAAC,IAAI,EAAK,KAAK,MAAM,OAAO,2BAA2B;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,CAAC;CAC7K;CAEA,MAAM,IAAI,GAAW,GAA4C;EAC/D,IAAM,IAAO,KAAK,KAAK,eAAe,GAChC,IAAS,IAAY,SAAS,UAC9B,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAC3B,IACJ,EAAE,SAAS,WAAW,MAAM,EAAK,KAAK,MAAM,GAAQ,yBAAyB,CAAC,IAAI,MAAM,EAAK,KAAK,MAAM,GAAQ,2BAA2B;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,CAAC;EAEpL,OADA,EAAK;GAAE,MAAM;GAAoB,QAAQ;GAAG,WAAW,EAAM;GAAW,OAAO,EAAM;EAAM,CAAC,GACrF;CACT;CAEA,KAAK,IAAe,CAAC,GAAG,GAAgD;EACtE,OAAO,EAAK,KAAK,MAAM,OAAO,iBAAiB;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACrF;AACF"}
1
+ {"version":3,"file":"favorites.js","names":[],"sources":["../../../src/client/content/favorites.ts"],"sourcesContent":["import type { FavoriteState, InteractionPage } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { query, type AccessMode } from \"../discovery.js\";\nimport { call } from \"../route.js\";\nimport type { Target } from \"./types.js\";\n\n/** A page of the caller's favorites or reactions. */\nexport interface MineQuery {\n /** contents (the default) or groups. */\n target?: \"contents\" | \"entities\";\n /** One content kind or group kind. */\n kind?: string;\n /** The group kinds each card names; every kind with a page by default. */\n card_entities?: readonly string[];\n cursor?: string;\n limit?: number;\n language?: string;\n display_language?: string;\n mode?: AccessMode;\n}\n\n/** Favorites: the target's count for everyone, the signed-in caller's own. */\nexport class FavoritesClient {\n constructor(private readonly http: Http) {}\n\n /** The target's favorite count and whether the caller favorited it (never, signed out). */\n get(t: Target, signal?: AbortSignal): Promise<FavoriteState> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"entities\" ? call(this.http, \"GET\", \"/entities/{id}/favorite\", o) : call(this.http, \"GET\", \"/contents/{id}/favorite\", { ...o, query: { version: t.version } });\n }\n /** Favorites or unfavorites the target (signed in); repeating is a no-op. Resolves with the new state and count. */\n async set(t: Target, favorited: boolean): Promise<FavoriteState> {\n const emit = this.http.captureChanges();\n const method = favorited ? \"POST\" : \"DELETE\";\n const o = { params: { id: t.id } };\n const state: FavoriteState =\n t.type === \"entities\" ? await call(this.http, method, \"/entities/{id}/favorite\", o) : await call(this.http, method, \"/contents/{id}/favorite\", { ...o, query: { version: t.version } });\n emit({ type: \"favorite.changed\", target: t, favorited: state.favorited, count: state.count });\n return state;\n }\n /** The caller's favorites, most recent first: content cards or groups. */\n mine(q: MineQuery = {}, signal?: AbortSignal): Promise<InteractionPage> {\n return call(this.http, \"GET\", \"/me/favorites\", { query: query(q) as never, signal });\n }\n}\n"],"mappings":";;;AAsBA,IAAa,IAAb,MAA6B;CACE;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,IAAI,GAAW,GAA8C;EAC3D,IAAM,IAAI;GAAE,QAAQ,EAAE,IAAI,EAAE,GAAG;GAAG;EAAO;EACzC,OAAO,EAAE,SAAS,aAAa,EAAK,KAAK,MAAM,OAAO,2BAA2B,CAAC,IAAI,EAAK,KAAK,MAAM,OAAO,2BAA2B;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,CAAC;CACjL;CAEA,MAAM,IAAI,GAAW,GAA4C;EAC/D,IAAM,IAAO,KAAK,KAAK,eAAe,GAChC,IAAS,IAAY,SAAS,UAC9B,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAC3B,IACJ,EAAE,SAAS,aAAa,MAAM,EAAK,KAAK,MAAM,GAAQ,2BAA2B,CAAC,IAAI,MAAM,EAAK,KAAK,MAAM,GAAQ,2BAA2B;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,CAAC;EAExL,OADA,EAAK;GAAE,MAAM;GAAoB,QAAQ;GAAG,WAAW,EAAM;GAAW,OAAO,EAAM;EAAM,CAAC,GACrF;CACT;CAEA,KAAK,IAAe,CAAC,GAAG,GAAgD;EACtE,OAAO,EAAK,KAAK,MAAM,OAAO,iBAAiB;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACrF;AACF"}
@@ -12,7 +12,7 @@ var r = class {
12
12
  params: { id: t.id },
13
13
  signal: n
14
14
  };
15
- return t.type === "groups" ? e(this.http, "GET", "/groups/{id}/reaction", r) : e(this.http, "GET", "/contents/{id}/reaction", {
15
+ return t.type === "entities" ? e(this.http, "GET", "/entities/{id}/reaction", r) : e(this.http, "GET", "/contents/{id}/reaction", {
16
16
  ...r,
17
17
  query: { version: t.version }
18
18
  });
@@ -22,7 +22,7 @@ var r = class {
22
22
  ...a,
23
23
  query: { version: n.version }
24
24
  }, s;
25
- return s = n.type === "groups" ? r === 0 ? await e(this.http, "DELETE", "/groups/{id}/reaction", a) : await e(this.http, "POST", `/groups/{id}/${t(r)}`, a) : r === 0 ? await e(this.http, "DELETE", "/contents/{id}/reaction", o) : await e(this.http, "POST", `/contents/{id}/${t(r)}`, o), i({
25
+ return s = n.type === "entities" ? r === 0 ? await e(this.http, "DELETE", "/entities/{id}/reaction", a) : await e(this.http, "POST", `/entities/{id}/${t(r)}`, a) : r === 0 ? await e(this.http, "DELETE", "/contents/{id}/reaction", o) : await e(this.http, "POST", `/contents/{id}/${t(r)}`, o), i({
26
26
  type: "reaction.changed",
27
27
  target: n,
28
28
  counts: s
@@ -1 +1 @@
1
- {"version":3,"file":"reactions.js","names":[],"sources":["../../../src/client/content/reactions.ts"],"sourcesContent":["import type { InteractionPage, ReactionCounts } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { query } from \"../discovery.js\";\nimport { call } from \"../route.js\";\nimport { reactionVerb, type Reaction, type Target } from \"./types.js\";\nimport type { MineQuery } from \"./favorites.js\";\n\n/** Likes and dislikes of a content item, a version or a group. */\nexport class ReactionsClient {\n constructor(private readonly http: Http) {}\n\n /** The target's counts and the caller's own reaction. */\n get(t: Target, signal?: AbortSignal): Promise<ReactionCounts> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"groups\" ? call(this.http, \"GET\", \"/groups/{id}/reaction\", o) : call(this.http, \"GET\", \"/contents/{id}/reaction\", { ...o, query: { version: t.version } });\n }\n /** Sets the caller's reaction (0 clears it); resolves with the new counts. */\n async set(t: Target, value: Reaction): Promise<ReactionCounts> {\n const emit = this.http.captureChanges();\n const o = { params: { id: t.id } };\n const c = { ...o, query: { version: t.version } };\n let counts: ReactionCounts;\n if (t.type === \"groups\") {\n counts = value === 0 ? await call(this.http, \"DELETE\", \"/groups/{id}/reaction\", o) : await call(this.http, \"POST\", `/groups/{id}/${reactionVerb(value)}` as const, o);\n } else {\n counts = value === 0 ? await call(this.http, \"DELETE\", \"/contents/{id}/reaction\", c) : await call(this.http, \"POST\", `/contents/{id}/${reactionVerb(value)}` as const, c);\n }\n emit({ type: \"reaction.changed\", target: t, counts });\n return counts;\n }\n /** What the signed-in caller liked or disliked, most recent first: content cards or groups (tag preferences). */\n mine(q: MineQuery & { value?: \"like\" | \"dislike\" } = {}, signal?: AbortSignal): Promise<InteractionPage> {\n return call(this.http, \"GET\", \"/me/reactions\", { query: query(q) as never, signal });\n }\n}\n"],"mappings":";;;;AAQA,IAAa,IAAb,MAA6B;CACE;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,IAAI,GAAW,GAA+C;EAC5D,IAAM,IAAI;GAAE,QAAQ,EAAE,IAAI,EAAE,GAAG;GAAG;EAAO;EACzC,OAAO,EAAE,SAAS,WAAW,EAAK,KAAK,MAAM,OAAO,yBAAyB,CAAC,IAAI,EAAK,KAAK,MAAM,OAAO,2BAA2B;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,CAAC;CAC7K;CAEA,MAAM,IAAI,GAAW,GAA0C;EAC7D,IAAM,IAAO,KAAK,KAAK,eAAe,GAChC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAC3B,IAAI;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,GAC5C;EAOJ,OANA,AAGE,IAHE,EAAE,SAAS,WACJ,MAAU,IAAI,MAAM,EAAK,KAAK,MAAM,UAAU,yBAAyB,CAAC,IAAI,MAAM,EAAK,KAAK,MAAM,QAAQ,gBAAgB,EAAa,CAAK,KAAc,CAAC,IAE3J,MAAU,IAAI,MAAM,EAAK,KAAK,MAAM,UAAU,2BAA2B,CAAC,IAAI,MAAM,EAAK,KAAK,MAAM,QAAQ,kBAAkB,EAAa,CAAK,KAAc,CAAC,GAE1K,EAAK;GAAE,MAAM;GAAoB,QAAQ;GAAG;EAAO,CAAC,GAC7C;CACT;CAEA,KAAK,IAAgD,CAAC,GAAG,GAAgD;EACvG,OAAO,EAAK,KAAK,MAAM,OAAO,iBAAiB;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACrF;AACF"}
1
+ {"version":3,"file":"reactions.js","names":[],"sources":["../../../src/client/content/reactions.ts"],"sourcesContent":["import type { InteractionPage, ReactionCounts } from \"../generated/wire.js\";\nimport type { Http } from \"../http.js\";\nimport { query } from \"../discovery.js\";\nimport { call } from \"../route.js\";\nimport { reactionVerb, type Reaction, type Target } from \"./types.js\";\nimport type { MineQuery } from \"./favorites.js\";\n\n/** Likes and dislikes of a content item, a version or a group. */\nexport class ReactionsClient {\n constructor(private readonly http: Http) {}\n\n /** The target's counts and the caller's own reaction. */\n get(t: Target, signal?: AbortSignal): Promise<ReactionCounts> {\n const o = { params: { id: t.id }, signal };\n return t.type === \"entities\" ? call(this.http, \"GET\", \"/entities/{id}/reaction\", o) : call(this.http, \"GET\", \"/contents/{id}/reaction\", { ...o, query: { version: t.version } });\n }\n /** Sets the caller's reaction (0 clears it); resolves with the new counts. */\n async set(t: Target, value: Reaction): Promise<ReactionCounts> {\n const emit = this.http.captureChanges();\n const o = { params: { id: t.id } };\n const c = { ...o, query: { version: t.version } };\n let counts: ReactionCounts;\n if (t.type === \"entities\") {\n counts = value === 0 ? await call(this.http, \"DELETE\", \"/entities/{id}/reaction\", o) : await call(this.http, \"POST\", `/entities/{id}/${reactionVerb(value)}` as const, o);\n } else {\n counts = value === 0 ? await call(this.http, \"DELETE\", \"/contents/{id}/reaction\", c) : await call(this.http, \"POST\", `/contents/{id}/${reactionVerb(value)}` as const, c);\n }\n emit({ type: \"reaction.changed\", target: t, counts });\n return counts;\n }\n /** What the signed-in caller liked or disliked, most recent first: content cards or groups (tag preferences). */\n mine(q: MineQuery & { value?: \"like\" | \"dislike\" } = {}, signal?: AbortSignal): Promise<InteractionPage> {\n return call(this.http, \"GET\", \"/me/reactions\", { query: query(q) as never, signal });\n }\n}\n"],"mappings":";;;;AAQA,IAAa,IAAb,MAA6B;CACE;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,IAAI,GAAW,GAA+C;EAC5D,IAAM,IAAI;GAAE,QAAQ,EAAE,IAAI,EAAE,GAAG;GAAG;EAAO;EACzC,OAAO,EAAE,SAAS,aAAa,EAAK,KAAK,MAAM,OAAO,2BAA2B,CAAC,IAAI,EAAK,KAAK,MAAM,OAAO,2BAA2B;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,CAAC;CACjL;CAEA,MAAM,IAAI,GAAW,GAA0C;EAC7D,IAAM,IAAO,KAAK,KAAK,eAAe,GAChC,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAC3B,IAAI;GAAE,GAAG;GAAG,OAAO,EAAE,SAAS,EAAE,QAAQ;EAAE,GAC5C;EAOJ,OANA,AAGE,IAHE,EAAE,SAAS,aACJ,MAAU,IAAI,MAAM,EAAK,KAAK,MAAM,UAAU,2BAA2B,CAAC,IAAI,MAAM,EAAK,KAAK,MAAM,QAAQ,kBAAkB,EAAa,CAAK,KAAc,CAAC,IAE/J,MAAU,IAAI,MAAM,EAAK,KAAK,MAAM,UAAU,2BAA2B,CAAC,IAAI,MAAM,EAAK,KAAK,MAAM,QAAQ,kBAAkB,EAAa,CAAK,KAAc,CAAC,GAE1K,EAAK;GAAE,MAAM;GAAoB,QAAQ;GAAG;EAAO,CAAC,GAC7C;CACT;CAEA,KAAK,IAAgD,CAAC,GAAG,GAAgD;EACvG,OAAO,EAAK,KAAK,MAAM,OAAO,iBAAiB;GAAE,OAAO,EAAM,CAAC;GAAY;EAAO,CAAC;CACrF;AACF"}
@@ -1,7 +1,7 @@
1
1
  import { CommentBan, CommentStanding, Comment, Content, Poll, ReactionCounts, ResolveInput } from '../generated/wire.js';
2
2
  /** What an interaction targets: a content item (optionally one of its versions) or a group. */
3
3
  export interface Target {
4
- type: "contents" | "groups";
4
+ type: "contents" | "entities";
5
5
  id: string;
6
6
  /** One version of a content item. */
7
7
  version?: string;
@@ -107,7 +107,7 @@ export type ContentChange =
107
107
  content: string;
108
108
  version: string;
109
109
  } | {
110
- type: "groups.changed";
110
+ type: "entities.changed";
111
111
  }
112
112
  /** The reader's content filters changed: every list reads again. */
113
113
  | {
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","names":[],"sources":["../../../src/client/content/types.ts"],"sourcesContent":["import type { CommentBan, CommentStanding, Comment, Content, Poll, ReactionCounts, ResolveInput } from \"../generated/wire.js\";\n\n/** What an interaction targets: a content item (optionally one of its versions) or a group. */\nexport interface Target {\n type: \"contents\" | \"groups\";\n id: string;\n /** One version of a content item. */\n version?: string;\n}\n\n/** The same target. */\nexport function sameTarget(a?: Target, b?: Target): boolean {\n return !!a && !!b && a.type === b.type && a.id === b.id && (a.version ?? \"\") === (b.version ?? \"\");\n}\n\n/** A reaction: like 1, dislike -1, none 0. */\nexport type Reaction = -1 | 0 | 1;\n\n/** The route verb that sets a like or dislike; clearing is DELETE …/reaction. */\nexport function reactionVerb(value: -1 | 1): \"like\" | \"dislike\" {\n return value === 1 ? \"like\" : \"dislike\";\n}\n\n/** Comment order: newest (the default), likes (most liked) or best (Wilson lower bound). */\nexport type Sort = \"newest\" | \"likes\" | \"best\";\n\n/** A ban route family: \"owner\" bans from the caller's own content, \"global\" from the whole site. */\nexport type BanScope = CommentStanding[\"ban_scopes\"][number];\n\n/** What the review queue holds: comments and content items. */\nexport type HeldKind = \"comment\" | \"content\";\n\n/** The moderation rules: banned words or IP bans. */\nexport type RuleSet = \"words\" | \"ips\";\n\n/** A reviewer's decision on a held item. */\nexport type Decision = Exclude<ResolveInput[\"decision\"], \"review\">;\n\n/** A content-module mutation made through the client. */\nexport type ContentChange =\n /** Created or edited: the item as the server now answers it. */\n | { type: \"content.saved\"; content: Content }\n /** A version changed: refetch the item. */\n | { type: \"content.changed\"; id: string }\n | { type: \"content.deleted\"; id: string }\n /** target is the commented item. */\n | { type: \"comment.created\"; target: Target; comment: Comment }\n | { type: \"comment.updated\"; comment: Comment }\n | { type: \"comment.deleted\"; id: string }\n | { type: \"comment.restored\"; id: string }\n | { type: \"comment.reacted\"; id: string; counts: ReactionCounts }\n | { type: \"reaction.changed\"; target: Target; counts: ReactionCounts }\n /** count is absent where the target's kind's locked view hides it. */\n | { type: \"favorite.changed\"; target: Target; favorited: boolean; count?: number }\n /** Created, updated, voted or answered: the poll as the server now answers it. */\n | { type: \"poll.created\"; poll: Poll }\n | { type: \"poll.updated\"; poll: Poll }\n /** An option or image changed: refetch the poll. */\n | { type: \"poll.changed\"; id: string }\n | { type: \"poll.deleted\"; id: string }\n | { type: \"ban.saved\"; scope: BanScope; ban: CommentBan }\n | { type: \"ban.lifted\"; scope: BanScope; user: string }\n | { type: \"moderation.resolved\"; kind: HeldKind; id: string; decision: Decision }\n /** Banned words or IP bans changed. */\n | { type: \"rules.changed\"; rules: RuleSet }\n /** A version's reader metadata changed: its reader plan reads again. */\n | { type: \"reader.changed\"; content: string; version: string }\n | { type: \"groups.changed\" }\n /** The reader's content filters changed: every list reads again. */\n | { type: \"contentFilters.changed\" }\n | { type: \"history.changed\" }\n /** A search ran or recent searches were cleared. */\n | { type: \"searches.changed\" }\n /** The reader's keys changed (a join, a purchase the host reports): reads of access re-run. */\n | { type: \"access.changed\" };\n"],"mappings":";AAWA,SAAgB,EAAW,GAAY,GAAqB;CAC1D,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,SAAS,EAAE,WAAW;AACjG;AAMA,SAAgB,EAAa,GAAmC;CAC9D,OAAO,MAAU,IAAI,SAAS;AAChC"}
1
+ {"version":3,"file":"types.js","names":[],"sources":["../../../src/client/content/types.ts"],"sourcesContent":["import type { CommentBan, CommentStanding, Comment, Content, Poll, ReactionCounts, ResolveInput } from \"../generated/wire.js\";\n\n/** What an interaction targets: a content item (optionally one of its versions) or a group. */\nexport interface Target {\n type: \"contents\" | \"entities\";\n id: string;\n /** One version of a content item. */\n version?: string;\n}\n\n/** The same target. */\nexport function sameTarget(a?: Target, b?: Target): boolean {\n return !!a && !!b && a.type === b.type && a.id === b.id && (a.version ?? \"\") === (b.version ?? \"\");\n}\n\n/** A reaction: like 1, dislike -1, none 0. */\nexport type Reaction = -1 | 0 | 1;\n\n/** The route verb that sets a like or dislike; clearing is DELETE …/reaction. */\nexport function reactionVerb(value: -1 | 1): \"like\" | \"dislike\" {\n return value === 1 ? \"like\" : \"dislike\";\n}\n\n/** Comment order: newest (the default), likes (most liked) or best (Wilson lower bound). */\nexport type Sort = \"newest\" | \"likes\" | \"best\";\n\n/** A ban route family: \"owner\" bans from the caller's own content, \"global\" from the whole site. */\nexport type BanScope = CommentStanding[\"ban_scopes\"][number];\n\n/** What the review queue holds: comments and content items. */\nexport type HeldKind = \"comment\" | \"content\";\n\n/** The moderation rules: banned words or IP bans. */\nexport type RuleSet = \"words\" | \"ips\";\n\n/** A reviewer's decision on a held item. */\nexport type Decision = Exclude<ResolveInput[\"decision\"], \"review\">;\n\n/** A content-module mutation made through the client. */\nexport type ContentChange =\n /** Created or edited: the item as the server now answers it. */\n | { type: \"content.saved\"; content: Content }\n /** A version changed: refetch the item. */\n | { type: \"content.changed\"; id: string }\n | { type: \"content.deleted\"; id: string }\n /** target is the commented item. */\n | { type: \"comment.created\"; target: Target; comment: Comment }\n | { type: \"comment.updated\"; comment: Comment }\n | { type: \"comment.deleted\"; id: string }\n | { type: \"comment.restored\"; id: string }\n | { type: \"comment.reacted\"; id: string; counts: ReactionCounts }\n | { type: \"reaction.changed\"; target: Target; counts: ReactionCounts }\n /** count is absent where the target's kind's locked view hides it. */\n | { type: \"favorite.changed\"; target: Target; favorited: boolean; count?: number }\n /** Created, updated, voted or answered: the poll as the server now answers it. */\n | { type: \"poll.created\"; poll: Poll }\n | { type: \"poll.updated\"; poll: Poll }\n /** An option or image changed: refetch the poll. */\n | { type: \"poll.changed\"; id: string }\n | { type: \"poll.deleted\"; id: string }\n | { type: \"ban.saved\"; scope: BanScope; ban: CommentBan }\n | { type: \"ban.lifted\"; scope: BanScope; user: string }\n | { type: \"moderation.resolved\"; kind: HeldKind; id: string; decision: Decision }\n /** Banned words or IP bans changed. */\n | { type: \"rules.changed\"; rules: RuleSet }\n /** A version's reader metadata changed: its reader plan reads again. */\n | { type: \"reader.changed\"; content: string; version: string }\n | { type: \"entities.changed\" }\n /** The reader's content filters changed: every list reads again. */\n | { type: \"contentFilters.changed\" }\n | { type: \"history.changed\" }\n /** A search ran or recent searches were cleared. */\n | { type: \"searches.changed\" }\n /** The reader's keys changed (a join, a purchase the host reports): reads of access re-run. */\n | { type: \"access.changed\" };\n"],"mappings":";AAWA,SAAgB,EAAW,GAAY,GAAqB;CAC1D,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,SAAS,EAAE,WAAW;AACjG;AAMA,SAAgB,EAAa,GAAmC;CAC9D,OAAO,MAAU,IAAI,SAAS;AAChC"}
@@ -11,8 +11,10 @@ export declare const IMAGE_SCHEME = "contentkit:";
11
11
  export declare const imageRef: (name: string) => string;
12
12
  /** Matches every image reference; the name is group 1. */
13
13
  export declare const imageRefs: () => RegExp;
14
- /** GET /manage/contents filters, as the route names them. */
15
- export type ManageQuery = RouteQuery<"GET", "/manage/contents">;
14
+ /** Management filters; kind selects /manage/{kind}, otherwise /manage. */
15
+ export type ManageQuery = RouteQuery<"GET", "/manage"> & {
16
+ kind?: string;
17
+ };
16
18
  /**
17
19
  * Content items: a viewer's reads, and the writes of their creators, their
18
20
  * owner group's editors and root:content:write holders.
@@ -23,8 +23,13 @@ var t = "contentkit:", n = (e) => t + e, r = () => /contentkit:(i-[0-9a-f]{8}-[0
23
23
  });
24
24
  }
25
25
  manage(t = {}, n) {
26
- return e(this.http, "GET", "/manage/contents", {
27
- query: t,
26
+ let { kind: r, ...i } = t;
27
+ return r ? e(this.http, "GET", "/manage/{kind}", {
28
+ params: { kind: r },
29
+ query: i,
30
+ signal: n
31
+ }) : e(this.http, "GET", "/manage", {
32
+ query: i,
28
33
  signal: n
29
34
  });
30
35
  }
@@ -1 +1 @@
1
- {"version":3,"file":"contents.js","names":[],"sources":["../../src/client/contents.ts"],"sourcesContent":["import type {\n CatalogText,\n Content,\n ContentInput,\n ContentPatch,\n Creator,\n InlineImage,\n Segment,\n Version,\n VersionInput,\n} from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call, type RouteQuery } from \"./route.js\";\n\n/** The URL scheme of an image reference in a content body. */\nexport const IMAGE_SCHEME = \"contentkit:\";\n\n/**\n * The reference a body stores for one of its images, by name\n * (\"contentkit:i-{uuid}\"), where the image's URL would go: reads resolve it to\n * the image's current public file (`Content.images`).\n */\nexport const imageRef = (name: string) => IMAGE_SCHEME + name;\n\n/** Matches every image reference; the name is group 1. */\nexport const imageRefs = () => /contentkit:(i-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/g;\n\n/** GET /manage/contents filters, as the route names them. */\nexport type ManageQuery = RouteQuery<\"GET\", \"/manage/contents\">;\n\n/**\n * Content items: a viewer's reads, and the writes of their creators, their\n * owner group's editors and root:content:write holders.\n */\nexport class ContentsClient {\n constructor(private readonly http: Http) {}\n\n /** The item as the caller sees it; text in language, else the site's first, else any. */\n get(id: string, language?: string, signal?: AbortSignal): Promise<Content> {\n return call(this.http, \"GET\", \"/contents/{id}\", { params: { id }, query: { language }, signal });\n }\n version(id: string, vid: string, language?: string, signal?: AbortSignal): Promise<Version> {\n return call(this.http, \"GET\", \"/contents/{id}/versions/{vid}\", { params: { id, vid }, query: { language }, signal });\n }\n /** Items the caller manages, newest first: all for root:content:write holders, else theirs or an owner group's. */\n manage(q: ManageQuery = {}, signal?: AbortSignal): Promise<Content[]> {\n return call(this.http, \"GET\", \"/manage/contents\", { query: q, signal });\n }\n /** Creates a draft. */\n create(input: ContentInput): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents\", { body: input }));\n }\n update(id: string, patch: ContentPatch): Promise<Content> {\n return this.write(call(this.http, \"PATCH\", \"/contents/{id}\", { params: { id }, body: patch }));\n }\n /** Sets the text in one language; moderation \"held\" when the moderator holds the edit. */\n putText(id: string, language: string, text: CatalogText): Promise<Content> {\n return this.write(call(this.http, \"PUT\", \"/contents/{id}/text/{language}\", { params: { id, language }, body: text }));\n }\n deleteText(id: string, language: string): Promise<Content> {\n return this.write(call(this.http, \"DELETE\", \"/contents/{id}/text/{language}\", { params: { id, language } }));\n }\n setCreators(id: string, creators: Creator[]): Promise<Content> {\n return this.write(call(this.http, \"PUT\", \"/contents/{id}/creators\", { params: { id }, body: { creators } }));\n }\n /** Publishes now, or schedules for at; moderation \"held\" when the moderator holds it. */\n publish(id: string, at?: string): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents/{id}/publish\", { params: { id }, body: { publish_at: at } }));\n }\n unpublish(id: string): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents/{id}/unpublish\", { params: { id } }));\n }\n async remove(id: string): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/contents/{id}\", { params: { id } });\n emit({ type: \"content.deleted\", id });\n }\n restore(id: string): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents/{id}/restore\", { params: { id } }));\n }\n /** Selects a version's cover by the name (\"i-{uuid}\") of one of its cover uploads; null returns to its first. */\n setCover(id: string, vid: string, image: string | null): Promise<Version> {\n return this.updateVersion(id, vid, { cover: image ?? \"\" });\n }\n /**\n * A body image uploaded to version vid (its private files), copied into\n * every other version: the reference to store in the body and a URL that shows\n * it to the editor now (null while none exists).\n */\n inlineImage(id: string, vid: string, image: string, signal?: AbortSignal): Promise<InlineImage> {\n return call(this.http, \"POST\", \"/contents/{id}/images\", { params: { id }, body: { image, version: vid }, signal });\n }\n addVersion(id: string, input: VersionInput): Promise<Version> {\n return this.writeVersion(id, call(this.http, \"POST\", \"/contents/{id}/versions\", { params: { id }, body: input }));\n }\n updateVersion(id: string, vid: string, input: VersionInput): Promise<Version> {\n return this.writeVersion(id, call(this.http, \"PATCH\", \"/contents/{id}/versions/{vid}\", { params: { id, vid }, body: input }));\n }\n async removeVersion(id: string, vid: string): Promise<void> {\n await this.writeVersion(id, call(this.http, \"DELETE\", \"/contents/{id}/versions/{vid}\", { params: { id, vid } }));\n }\n /** Orders the versions: ids lists each version that is not deleted, first first. */\n orderVersions(id: string, ids: string[]): Promise<Content> {\n return this.write(call(this.http, \"PUT\", \"/contents/{id}/versions/order\", { params: { id }, body: { ids } }));\n }\n /** Replaces a version's segments (chapters). */\n setSegments(id: string, vid: string, segments: Segment[]): Promise<Version> {\n return this.writeVersion(id, call(this.http, \"PUT\", \"/contents/{id}/versions/{vid}/segments\", { params: { id, vid }, body: { segments } }));\n }\n\n private async write(p: Promise<Content>): Promise<Content> {\n const emit = this.http.captureChanges();\n const content = await p;\n emit({ type: \"content.saved\", content });\n return content;\n }\n\n private async writeVersion<T>(id: string, p: Promise<T>): Promise<T> {\n const emit = this.http.captureChanges();\n const out = await p;\n emit({ type: \"content.changed\", id });\n return out;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"contents.js","names":[],"sources":["../../src/client/contents.ts"],"sourcesContent":["import type {\n CatalogText,\n Content,\n ContentInput,\n ContentPatch,\n Creator,\n InlineImage,\n Segment,\n Version,\n VersionInput,\n} from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call, type RouteQuery } from \"./route.js\";\n\n/** The URL scheme of an image reference in a content body. */\nexport const IMAGE_SCHEME = \"contentkit:\";\n\n/**\n * The reference a body stores for one of its images, by name\n * (\"contentkit:i-{uuid}\"), where the image's URL would go: reads resolve it to\n * the image's current public file (`Content.images`).\n */\nexport const imageRef = (name: string) => IMAGE_SCHEME + name;\n\n/** Matches every image reference; the name is group 1. */\nexport const imageRefs = () => /contentkit:(i-[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/g;\n\n/** Management filters; kind selects /manage/{kind}, otherwise /manage. */\nexport type ManageQuery = RouteQuery<\"GET\", \"/manage\"> & { kind?: string };\n\n/**\n * Content items: a viewer's reads, and the writes of their creators, their\n * owner group's editors and root:content:write holders.\n */\nexport class ContentsClient {\n constructor(private readonly http: Http) {}\n\n /** The item as the caller sees it; text in language, else the site's first, else any. */\n get(id: string, language?: string, signal?: AbortSignal): Promise<Content> {\n return call(this.http, \"GET\", \"/contents/{id}\", { params: { id }, query: { language }, signal });\n }\n version(id: string, vid: string, language?: string, signal?: AbortSignal): Promise<Version> {\n return call(this.http, \"GET\", \"/contents/{id}/versions/{vid}\", { params: { id, vid }, query: { language }, signal });\n }\n /** Items the caller manages, newest first: all for root:content:write holders, else theirs or an owner group's. */\n manage(q: ManageQuery = {}, signal?: AbortSignal): Promise<Content[]> {\n const { kind, ...query } = q;\n return kind\n ? call(this.http, \"GET\", \"/manage/{kind}\", { params: { kind }, query, signal })\n : call(this.http, \"GET\", \"/manage\", { query, signal });\n }\n /** Creates a draft. */\n create(input: ContentInput): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents\", { body: input }));\n }\n update(id: string, patch: ContentPatch): Promise<Content> {\n return this.write(call(this.http, \"PATCH\", \"/contents/{id}\", { params: { id }, body: patch }));\n }\n /** Sets the text in one language; moderation \"held\" when the moderator holds the edit. */\n putText(id: string, language: string, text: CatalogText): Promise<Content> {\n return this.write(call(this.http, \"PUT\", \"/contents/{id}/text/{language}\", { params: { id, language }, body: text }));\n }\n deleteText(id: string, language: string): Promise<Content> {\n return this.write(call(this.http, \"DELETE\", \"/contents/{id}/text/{language}\", { params: { id, language } }));\n }\n setCreators(id: string, creators: Creator[]): Promise<Content> {\n return this.write(call(this.http, \"PUT\", \"/contents/{id}/creators\", { params: { id }, body: { creators } }));\n }\n /** Publishes now, or schedules for at; moderation \"held\" when the moderator holds it. */\n publish(id: string, at?: string): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents/{id}/publish\", { params: { id }, body: { publish_at: at } }));\n }\n unpublish(id: string): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents/{id}/unpublish\", { params: { id } }));\n }\n async remove(id: string): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/contents/{id}\", { params: { id } });\n emit({ type: \"content.deleted\", id });\n }\n restore(id: string): Promise<Content> {\n return this.write(call(this.http, \"POST\", \"/contents/{id}/restore\", { params: { id } }));\n }\n /** Selects a version's cover by the name (\"i-{uuid}\") of one of its cover uploads; null returns to its first. */\n setCover(id: string, vid: string, image: string | null): Promise<Version> {\n return this.updateVersion(id, vid, { cover: image ?? \"\" });\n }\n /**\n * A body image uploaded to version vid (its private files), copied into\n * every other version: the reference to store in the body and a URL that shows\n * it to the editor now (null while none exists).\n */\n inlineImage(id: string, vid: string, image: string, signal?: AbortSignal): Promise<InlineImage> {\n return call(this.http, \"POST\", \"/contents/{id}/images\", { params: { id }, body: { image, version: vid }, signal });\n }\n addVersion(id: string, input: VersionInput): Promise<Version> {\n return this.writeVersion(id, call(this.http, \"POST\", \"/contents/{id}/versions\", { params: { id }, body: input }));\n }\n updateVersion(id: string, vid: string, input: VersionInput): Promise<Version> {\n return this.writeVersion(id, call(this.http, \"PATCH\", \"/contents/{id}/versions/{vid}\", { params: { id, vid }, body: input }));\n }\n async removeVersion(id: string, vid: string): Promise<void> {\n await this.writeVersion(id, call(this.http, \"DELETE\", \"/contents/{id}/versions/{vid}\", { params: { id, vid } }));\n }\n /** Orders the versions: ids lists each version that is not deleted, first first. */\n orderVersions(id: string, ids: string[]): Promise<Content> {\n return this.write(call(this.http, \"PUT\", \"/contents/{id}/versions/order\", { params: { id }, body: { ids } }));\n }\n /** Replaces a version's segments (chapters). */\n setSegments(id: string, vid: string, segments: Segment[]): Promise<Version> {\n return this.writeVersion(id, call(this.http, \"PUT\", \"/contents/{id}/versions/{vid}/segments\", { params: { id, vid }, body: { segments } }));\n }\n\n private async write(p: Promise<Content>): Promise<Content> {\n const emit = this.http.captureChanges();\n const content = await p;\n emit({ type: \"content.saved\", content });\n return content;\n }\n\n private async writeVersion<T>(id: string, p: Promise<T>): Promise<T> {\n const emit = this.http.captureChanges();\n const out = await p;\n emit({ type: \"content.changed\", id });\n return out;\n }\n}\n"],"mappings":";;AAeA,IAAa,IAAe,eAOf,KAAY,MAAiB,IAAe,GAG5C,UAAkB,gFASlB,IAAb,MAA4B;CACG;CAA7B,YAAY,GAA6B;EAAZ,KAAA,OAAA;CAAa;CAG1C,IAAI,GAAY,GAAmB,GAAwC;EACzE,OAAO,EAAK,KAAK,MAAM,OAAO,kBAAkB;GAAE,QAAQ,EAAE,MAAG;GAAG,OAAO,EAAE,YAAS;GAAG;EAAO,CAAC;CACjG;CACA,QAAQ,GAAY,GAAa,GAAmB,GAAwC;EAC1F,OAAO,EAAK,KAAK,MAAM,OAAO,iCAAiC;GAAE,QAAQ;IAAE;IAAI;GAAI;GAAG,OAAO,EAAE,YAAS;GAAG;EAAO,CAAC;CACrH;CAEA,OAAO,IAAiB,CAAC,GAAG,GAA0C;EACpE,IAAM,EAAE,SAAM,GAAG,MAAU;EAC3B,OAAO,IACH,EAAK,KAAK,MAAM,OAAO,kBAAkB;GAAE,QAAQ,EAAE,QAAK;GAAG;GAAO;EAAO,CAAC,IAC5E,EAAK,KAAK,MAAM,OAAO,WAAW;GAAE;GAAO;EAAO,CAAC;CACzD;CAEA,OAAO,GAAuC;EAC5C,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,QAAQ,aAAa,EAAE,MAAM,EAAM,CAAC,CAAC;CACzE;CACA,OAAO,GAAY,GAAuC;EACxD,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,SAAS,kBAAkB;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM;EAAM,CAAC,CAAC;CAC/F;CAEA,QAAQ,GAAY,GAAkB,GAAqC;EACzE,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,OAAO,kCAAkC;GAAE,QAAQ;IAAE;IAAI;GAAS;GAAG,MAAM;EAAK,CAAC,CAAC;CACtH;CACA,WAAW,GAAY,GAAoC;EACzD,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,UAAU,kCAAkC,EAAE,QAAQ;GAAE;GAAI;EAAS,EAAE,CAAC,CAAC;CAC7G;CACA,YAAY,GAAY,GAAuC;EAC7D,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,OAAO,2BAA2B;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM,EAAE,YAAS;EAAE,CAAC,CAAC;CAC7G;CAEA,QAAQ,GAAY,GAA+B;EACjD,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,QAAQ,0BAA0B;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM,EAAE,YAAY,EAAG;EAAE,CAAC,CAAC;CACnH;CACA,UAAU,GAA8B;EACtC,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,QAAQ,4BAA4B,EAAE,QAAQ,EAAE,MAAG,EAAE,CAAC,CAAC;CAC3F;CACA,MAAM,OAAO,GAA2B;EACtC,IAAM,IAAO,KAAK,KAAK,eAAe;EAEtC,AADA,MAAM,EAAK,KAAK,MAAM,UAAU,kBAAkB,EAAE,QAAQ,EAAE,MAAG,EAAE,CAAC,GACpE,EAAK;GAAE,MAAM;GAAmB;EAAG,CAAC;CACtC;CACA,QAAQ,GAA8B;EACpC,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,QAAQ,0BAA0B,EAAE,QAAQ,EAAE,MAAG,EAAE,CAAC,CAAC;CACzF;CAEA,SAAS,GAAY,GAAa,GAAwC;EACxE,OAAO,KAAK,cAAc,GAAI,GAAK,EAAE,OAAO,KAAS,GAAG,CAAC;CAC3D;CAMA,YAAY,GAAY,GAAa,GAAe,GAA4C;EAC9F,OAAO,EAAK,KAAK,MAAM,QAAQ,yBAAyB;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM;IAAE;IAAO,SAAS;GAAI;GAAG;EAAO,CAAC;CACnH;CACA,WAAW,GAAY,GAAuC;EAC5D,OAAO,KAAK,aAAa,GAAI,EAAK,KAAK,MAAM,QAAQ,2BAA2B;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM;EAAM,CAAC,CAAC;CAClH;CACA,cAAc,GAAY,GAAa,GAAuC;EAC5E,OAAO,KAAK,aAAa,GAAI,EAAK,KAAK,MAAM,SAAS,iCAAiC;GAAE,QAAQ;IAAE;IAAI;GAAI;GAAG,MAAM;EAAM,CAAC,CAAC;CAC9H;CACA,MAAM,cAAc,GAAY,GAA4B;EAC1D,MAAM,KAAK,aAAa,GAAI,EAAK,KAAK,MAAM,UAAU,iCAAiC,EAAE,QAAQ;GAAE;GAAI;EAAI,EAAE,CAAC,CAAC;CACjH;CAEA,cAAc,GAAY,GAAiC;EACzD,OAAO,KAAK,MAAM,EAAK,KAAK,MAAM,OAAO,iCAAiC;GAAE,QAAQ,EAAE,MAAG;GAAG,MAAM,EAAE,OAAI;EAAE,CAAC,CAAC;CAC9G;CAEA,YAAY,GAAY,GAAa,GAAuC;EAC1E,OAAO,KAAK,aAAa,GAAI,EAAK,KAAK,MAAM,OAAO,0CAA0C;GAAE,QAAQ;IAAE;IAAI;GAAI;GAAG,MAAM,EAAE,YAAS;EAAE,CAAC,CAAC;CAC5I;CAEA,MAAc,MAAM,GAAuC;EACzD,IAAM,IAAO,KAAK,KAAK,eAAe,GAChC,IAAU,MAAM;EAEtB,OADA,EAAK;GAAE,MAAM;GAAiB;EAAQ,CAAC,GAChC;CACT;CAEA,MAAc,aAAgB,GAAY,GAA2B;EACnE,IAAM,IAAO,KAAK,KAAK,eAAe,GAChC,IAAM,MAAM;EAElB,OADA,EAAK;GAAE,MAAM;GAAmB;EAAG,CAAC,GAC7B;CACT;AACF"}
@@ -43,7 +43,7 @@ export interface ReaderQuery {
43
43
  }
44
44
  /** The group kinds cards name; every kind with a page by default. */
45
45
  export interface CardQuery {
46
- card_groups?: readonly string[];
46
+ card_entities?: readonly string[];
47
47
  }
48
48
  export interface PageQuery {
49
49
  cursor?: string;
@@ -80,7 +80,7 @@ export interface TypeaheadQuery extends ReaderQuery {
80
80
  /** Only contents of this kind. */
81
81
  kind?: string;
82
82
  /** The group kinds suggested; every kind with a page by default. */
83
- group_kinds?: readonly string[];
83
+ entity_kinds?: readonly string[];
84
84
  /** Per section: 8 by default, at most 20. */
85
85
  limit?: number;
86
86
  }
@@ -8,8 +8,8 @@ var n = /* @__PURE__ */ new Set([
8
8
  "access",
9
9
  "tiers",
10
10
  "traits",
11
- "card_groups",
12
- "group_kinds"
11
+ "card_entities",
12
+ "entity_kinds"
13
13
  ]);
14
14
  function r(e) {
15
15
  let t = {};
@@ -1 +1 @@
1
- {"version":3,"file":"discovery.js","names":[],"sources":["../../src/client/discovery.ts"],"sourcesContent":["import type {\n ContentFilters,\n ContentFiltersUpdate,\n ContentPage,\n ExposureInput,\n Exposures,\n RecentSearches,\n ReleaseDates,\n SignalInput,\n Signals,\n Typeahead,\n} from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call } from \"./route.js\";\nimport { browserSearchHistory, type BrowserSearchHistory } from \"./browser-search-history.js\";\n\n/** A popularity period. */\nexport type Period = \"7d\" | \"30d\" | \"90d\" | \"365d\" | \"all\";\n/** A list's order; position orders by the first of `groups` (an ordered group). */\nexport type ListSort = \"newest\" | \"oldest\" | \"title\" | \"popular\" | `popular:${Period}` | \"top_rated\" | `top_rated:${Period}` | \"most_favorited\" | \"most_viewed\" | \"position\" | \"random\";\n/** How locked contents list: marked (lock, the default) or left out (hide). */\nexport type AccessMode = \"lock\" | \"hide\";\n\n/** Which contents a list holds. */\nexport interface ContentFilterQuery {\n kind?: string;\n /** Group ids every listed version is in. */\n groups?: readonly string[];\n /** Group ids no listed version is in. */\n exclude_groups?: readonly string[];\n /** Only contents this group owns: a channel's feed. */\n owner_group?: string;\n /** User ids: only contents one of them is credited on. */\n creators?: readonly string[];\n /** public (anyone opens it now) or the level it stays locked at. */\n access?: readonly (\"public\" | \"tier\" | \"group\" | \"ppv\" | \"group_ppv\")[];\n /** Only contents locked behind one of these tiers. */\n tiers?: readonly string[];\n /** Version traits every listed version has. */\n traits?: readonly string[];\n /** \"name:value\" of the kind's filterable attributes. */\n attribute?: readonly string[];\n /** Published on this day (YYYY-MM-DD) or month (YYYY-MM). */\n released_on?: string;\n /** IANA time zone of released_on and release dates; UTC by default. */\n tz?: string;\n /** The signed-in reader's unseen, in-progress or completed contents. */\n view_status?: \"unseen\" | \"in_progress\" | \"completed\";\n}\n\n/** How a list reads to its reader. */\nexport interface ReaderQuery {\n /** Only content with a live version in this language. */\n language?: string;\n /** Titles, names and paths in this language, and each card's preferred version's; language by default. */\n display_language?: string;\n mode?: AccessMode;\n}\n\n/** The group kinds cards name; every kind with a page by default. */\nexport interface CardQuery {\n card_groups?: readonly string[];\n}\n\nexport interface PageQuery {\n cursor?: string;\n limit?: number;\n}\n\nexport type ContentQuery = ContentFilterQuery & ReaderQuery & CardQuery & PageQuery & { sort?: ListSort };\nexport type SearchQuery = ContentFilterQuery &\n ReaderQuery &\n CardQuery &\n PageQuery & {\n q: string;\n sort?: \"relevance\" | ListSort;\n personalize?: boolean;\n /** Explicit legacy server-side anonymous history. Omit for public search without server history. */\n session?: string;\n };\nexport interface RecentSearchesQuery {\n /** Explicit legacy server-side anonymous history; no anonymous session is created by default. */\n session?: string;\n /** 10 by default, at most 100. */\n limit?: number;\n}\nexport type RailQuery = ContentFilterQuery & ReaderQuery & CardQuery & { limit?: number };\nexport type ReleaseDatesQuery = ContentFilterQuery & ReaderQuery & PageQuery & { by?: \"month\" | \"day\" };\nexport type HistoryQuery = ReaderQuery & CardQuery & PageQuery & { kind?: string; status?: \"seen\" | \"in_progress\" | \"completed\" };\nexport interface TypeaheadQuery extends ReaderQuery {\n q: string;\n /** Only contents of this kind. */\n kind?: string;\n /** The group kinds suggested; every kind with a page by default. */\n group_kinds?: readonly string[];\n /** Per section: 8 by default, at most 20. */\n limit?: number;\n}\n\n// Comma-joined list parameters; `attribute` repeats instead.\nconst LISTS = new Set([\"groups\", \"exclude_groups\", \"creators\", \"access\", \"tiers\", \"traits\", \"card_groups\", \"group_kinds\"]);\n\n/** A query with its list parameters comma-joined, as discovery routes read them. */\nexport function query(q: object): Record<string, string | number | boolean | readonly string[] | undefined> {\n const out: Record<string, string | number | boolean | readonly string[] | undefined> = {};\n for (const [k, v] of Object.entries(q)) out[k] = LISTS.has(k) && Array.isArray(v) ? (v.length ? v.join(\",\") : undefined) : v;\n return out;\n}\n\n/**\n * Discovery: lists, search, typeahead, similar and recommended contents,\n * release dates, the reader's content filters and history, signals and exposures.\n */\nexport class DiscoveryClient {\n /** Local anonymous history, isolated from authenticated server history. */\n readonly browserSearches: BrowserSearchHistory;\n\n constructor(private readonly http: Http) {\n this.browserSearches = browserSearchHistory(http.mount(\"discovery\"));\n }\n\n /** Contents as cards, one per content item with the version that fits the reader. */\n list(q: ContentQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents\", { query: query(q) as never, signal });\n }\n /** A first page is kept among the reader's recent searches. */\n async search(q: SearchQuery, signal?: AbortSignal): Promise<ContentPage> {\n const emit = q.cursor ? null : this.http.captureChanges();\n const out: ContentPage = await call(this.http, \"GET\", \"/search\", { query: query(q) as never, signal });\n emit?.({ type: \"searches.changed\" });\n return out;\n }\n /** The reader's recent searches, newest first, since they last cleared them. */\n recentSearches(q: RecentSearchesQuery = {}, signal?: AbortSignal): Promise<RecentSearches> {\n return call(this.http, \"GET\", \"/me/searches\", { query: q, signal });\n }\n /** Clears one recent search, or all of them. */\n async clearSearches(o: { query?: string; session?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/searches\", { query: o });\n emit({ type: \"searches.changed\" });\n }\n /** Contents and groups while the reader types. */\n typeahead(q: TypeaheadQuery, signal?: AbortSignal): Promise<Typeahead> {\n return call(this.http, \"GET\", \"/typeahead\", { query: query(q) as never, signal });\n }\n /** Contents like one, of its kind unless q.kind names another. */\n similar(id: string, q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents/{id}/similar\", { params: { id }, query: query(q) as never, signal });\n }\n /** For the signed-in reader. */\n recommendations(q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/recommendations\", { query: query(q) as never, signal });\n }\n /** Per month or day, newest first: how many contents the reader's listing shows released then, and how many are free. */\n releaseDates(q: ReleaseDatesQuery = {}, signal?: AbortSignal): Promise<ReleaseDates> {\n return call(this.http, \"GET\", \"/release-dates\", { query: query(q) as never, signal });\n }\n contentFilters(language?: string, signal?: AbortSignal): Promise<ContentFilters> {\n return call(this.http, \"GET\", \"/me/content-filters\", { query: { language }, signal });\n }\n /** Replaces the reader's filter settings; every read applies them. */\n async setContentFilters(update: ContentFiltersUpdate, language?: string): Promise<ContentFilters> {\n const emit = this.http.captureChanges();\n const out: ContentFilters = await call(this.http, \"PUT\", \"/me/content-filters\", { query: { language }, body: update });\n emit({ type: \"contentFilters.changed\" });\n return out;\n }\n /** What the reader engaged with, most recent first. */\n history(q: HistoryQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/me/history\", { query: query(q) as never, signal });\n }\n /** Erases the reader's history: of one content item, one kind or everything. */\n async forgetHistory(o: { kind?: string; content_id?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/history\", { query: o });\n emit({ type: \"history.changed\" });\n }\n /** Views and clicks; signed out, of the session named. */\n signals(signals: SignalInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Signals = { session, signals };\n return call(this.http, \"POST\", \"/signals\", { body, keepalive: o.keepalive });\n }\n /** Result lists served, rendered or shown, for click attribution. */\n exposures(exposures: ExposureInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Exposures = { session, exposures };\n return call(this.http, \"POST\", \"/exposures\", { body, keepalive: o.keepalive });\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"discovery.js","names":[],"sources":["../../src/client/discovery.ts"],"sourcesContent":["import type {\n ContentFilters,\n ContentFiltersUpdate,\n ContentPage,\n ExposureInput,\n Exposures,\n RecentSearches,\n ReleaseDates,\n SignalInput,\n Signals,\n Typeahead,\n} from \"./generated/wire.js\";\nimport type { Http } from \"./http.js\";\nimport { call } from \"./route.js\";\nimport { browserSearchHistory, type BrowserSearchHistory } from \"./browser-search-history.js\";\n\n/** A popularity period. */\nexport type Period = \"7d\" | \"30d\" | \"90d\" | \"365d\" | \"all\";\n/** A list's order; position orders by the first of `groups` (an ordered group). */\nexport type ListSort = \"newest\" | \"oldest\" | \"title\" | \"popular\" | `popular:${Period}` | \"top_rated\" | `top_rated:${Period}` | \"most_favorited\" | \"most_viewed\" | \"position\" | \"random\";\n/** How locked contents list: marked (lock, the default) or left out (hide). */\nexport type AccessMode = \"lock\" | \"hide\";\n\n/** Which contents a list holds. */\nexport interface ContentFilterQuery {\n kind?: string;\n /** Group ids every listed version is in. */\n groups?: readonly string[];\n /** Group ids no listed version is in. */\n exclude_groups?: readonly string[];\n /** Only contents this group owns: a channel's feed. */\n owner_group?: string;\n /** User ids: only contents one of them is credited on. */\n creators?: readonly string[];\n /** public (anyone opens it now) or the level it stays locked at. */\n access?: readonly (\"public\" | \"tier\" | \"group\" | \"ppv\" | \"group_ppv\")[];\n /** Only contents locked behind one of these tiers. */\n tiers?: readonly string[];\n /** Version traits every listed version has. */\n traits?: readonly string[];\n /** \"name:value\" of the kind's filterable attributes. */\n attribute?: readonly string[];\n /** Published on this day (YYYY-MM-DD) or month (YYYY-MM). */\n released_on?: string;\n /** IANA time zone of released_on and release dates; UTC by default. */\n tz?: string;\n /** The signed-in reader's unseen, in-progress or completed contents. */\n view_status?: \"unseen\" | \"in_progress\" | \"completed\";\n}\n\n/** How a list reads to its reader. */\nexport interface ReaderQuery {\n /** Only content with a live version in this language. */\n language?: string;\n /** Titles, names and paths in this language, and each card's preferred version's; language by default. */\n display_language?: string;\n mode?: AccessMode;\n}\n\n/** The group kinds cards name; every kind with a page by default. */\nexport interface CardQuery {\n card_entities?: readonly string[];\n}\n\nexport interface PageQuery {\n cursor?: string;\n limit?: number;\n}\n\nexport type ContentQuery = ContentFilterQuery & ReaderQuery & CardQuery & PageQuery & { sort?: ListSort };\nexport type SearchQuery = ContentFilterQuery &\n ReaderQuery &\n CardQuery &\n PageQuery & {\n q: string;\n sort?: \"relevance\" | ListSort;\n personalize?: boolean;\n /** Explicit legacy server-side anonymous history. Omit for public search without server history. */\n session?: string;\n };\nexport interface RecentSearchesQuery {\n /** Explicit legacy server-side anonymous history; no anonymous session is created by default. */\n session?: string;\n /** 10 by default, at most 100. */\n limit?: number;\n}\nexport type RailQuery = ContentFilterQuery & ReaderQuery & CardQuery & { limit?: number };\nexport type ReleaseDatesQuery = ContentFilterQuery & ReaderQuery & PageQuery & { by?: \"month\" | \"day\" };\nexport type HistoryQuery = ReaderQuery & CardQuery & PageQuery & { kind?: string; status?: \"seen\" | \"in_progress\" | \"completed\" };\nexport interface TypeaheadQuery extends ReaderQuery {\n q: string;\n /** Only contents of this kind. */\n kind?: string;\n /** The group kinds suggested; every kind with a page by default. */\n entity_kinds?: readonly string[];\n /** Per section: 8 by default, at most 20. */\n limit?: number;\n}\n\n// Comma-joined list parameters; `attribute` repeats instead.\nconst LISTS = new Set([\"groups\", \"exclude_groups\", \"creators\", \"access\", \"tiers\", \"traits\", \"card_entities\", \"entity_kinds\"]);\n\n/** A query with its list parameters comma-joined, as discovery routes read them. */\nexport function query(q: object): Record<string, string | number | boolean | readonly string[] | undefined> {\n const out: Record<string, string | number | boolean | readonly string[] | undefined> = {};\n for (const [k, v] of Object.entries(q)) out[k] = LISTS.has(k) && Array.isArray(v) ? (v.length ? v.join(\",\") : undefined) : v;\n return out;\n}\n\n/**\n * Discovery: lists, search, typeahead, similar and recommended contents,\n * release dates, the reader's content filters and history, signals and exposures.\n */\nexport class DiscoveryClient {\n /** Local anonymous history, isolated from authenticated server history. */\n readonly browserSearches: BrowserSearchHistory;\n\n constructor(private readonly http: Http) {\n this.browserSearches = browserSearchHistory(http.mount(\"discovery\"));\n }\n\n /** Contents as cards, one per content item with the version that fits the reader. */\n list(q: ContentQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents\", { query: query(q) as never, signal });\n }\n /** A first page is kept among the reader's recent searches. */\n async search(q: SearchQuery, signal?: AbortSignal): Promise<ContentPage> {\n const emit = q.cursor ? null : this.http.captureChanges();\n const out: ContentPage = await call(this.http, \"GET\", \"/search\", { query: query(q) as never, signal });\n emit?.({ type: \"searches.changed\" });\n return out;\n }\n /** The reader's recent searches, newest first, since they last cleared them. */\n recentSearches(q: RecentSearchesQuery = {}, signal?: AbortSignal): Promise<RecentSearches> {\n return call(this.http, \"GET\", \"/me/searches\", { query: q, signal });\n }\n /** Clears one recent search, or all of them. */\n async clearSearches(o: { query?: string; session?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/searches\", { query: o });\n emit({ type: \"searches.changed\" });\n }\n /** Contents and groups while the reader types. */\n typeahead(q: TypeaheadQuery, signal?: AbortSignal): Promise<Typeahead> {\n return call(this.http, \"GET\", \"/typeahead\", { query: query(q) as never, signal });\n }\n /** Contents like one, of its kind unless q.kind names another. */\n similar(id: string, q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/contents/{id}/similar\", { params: { id }, query: query(q) as never, signal });\n }\n /** For the signed-in reader. */\n recommendations(q: RailQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/recommendations\", { query: query(q) as never, signal });\n }\n /** Per month or day, newest first: how many contents the reader's listing shows released then, and how many are free. */\n releaseDates(q: ReleaseDatesQuery = {}, signal?: AbortSignal): Promise<ReleaseDates> {\n return call(this.http, \"GET\", \"/release-dates\", { query: query(q) as never, signal });\n }\n contentFilters(language?: string, signal?: AbortSignal): Promise<ContentFilters> {\n return call(this.http, \"GET\", \"/me/content-filters\", { query: { language }, signal });\n }\n /** Replaces the reader's filter settings; every read applies them. */\n async setContentFilters(update: ContentFiltersUpdate, language?: string): Promise<ContentFilters> {\n const emit = this.http.captureChanges();\n const out: ContentFilters = await call(this.http, \"PUT\", \"/me/content-filters\", { query: { language }, body: update });\n emit({ type: \"contentFilters.changed\" });\n return out;\n }\n /** What the reader engaged with, most recent first. */\n history(q: HistoryQuery = {}, signal?: AbortSignal): Promise<ContentPage> {\n return call(this.http, \"GET\", \"/me/history\", { query: query(q) as never, signal });\n }\n /** Erases the reader's history: of one content item, one kind or everything. */\n async forgetHistory(o: { kind?: string; content_id?: string } = {}): Promise<void> {\n const emit = this.http.captureChanges();\n await call(this.http, \"DELETE\", \"/me/history\", { query: o });\n emit({ type: \"history.changed\" });\n }\n /** Views and clicks; signed out, of the session named. */\n signals(signals: SignalInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Signals = { session, signals };\n return call(this.http, \"POST\", \"/signals\", { body, keepalive: o.keepalive });\n }\n /** Result lists served, rendered or shown, for click attribution. */\n exposures(exposures: ExposureInput[], session?: string, o: { keepalive?: boolean } = {}): Promise<void> {\n const body: Exposures = { session, exposures };\n return call(this.http, \"POST\", \"/exposures\", { body, keepalive: o.keepalive });\n }\n}\n"],"mappings":"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"}
@@ -2,20 +2,20 @@ import { ContentGroups, ContentMemberships, Edge, EdgeInput, Group, GroupDetail,
2
2
  import { Http } from './http.js';
3
3
  import { MediaClient, NamedOptions } from './media/client.js';
4
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 {
5
+ /** GET /entities filters, as the route names them. */
6
+ export type EntityQuery = RouteQuery<"GET", "/entities">;
7
+ /** GET /me/entities filters. */
8
+ export type MyEntityQuery = RouteQuery<"GET", "/me/entities">;
9
+ /** An entity's image slots: every kind's cover, a user-owned kind's avatar. */
10
+ export type EntityImageSlot = "cover" | "avatar";
11
+ /** GET /entities/{id}/members paging. */
12
+ export type MemberQuery = RouteQuery<"GET", "/entities/{id}/members">;
13
+ /** Entities: public listings and pages; writes for staff (root:groups:write). */
14
+ export declare class EntitiesClient {
15
15
  private readonly http;
16
16
  private readonly media;
17
17
  constructor(http: Http, media: MediaClient);
18
- list(q?: GroupQuery, signal?: AbortSignal): Promise<GroupPage>;
18
+ list(q?: EntityQuery, signal?: AbortSignal): Promise<GroupPage>;
19
19
  /** A merged group answers with its survivor. */
20
20
  get(id: string, language?: string, signal?: AbortSignal): Promise<GroupDetail>;
21
21
  create(groups: GroupInput[]): Promise<Group[]>;
@@ -38,11 +38,11 @@ export declare class GroupsClient {
38
38
  uploadImage(group: {
39
39
  kind: string;
40
40
  id: string;
41
- }, slot: GroupImageSlot, file: Blob & {
41
+ }, slot: EntityImageSlot, file: Blob & {
42
42
  name?: string;
43
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>;
44
+ /** Entities the signed-in person owns, edits or belongs to. */
45
+ mine(q?: MyEntityQuery, signal?: AbortSignal): Promise<MyGroupPage>;
46
46
  merge(id: string, into: string): Promise<MergeReport>;
47
47
  /** The group's memberships in member order, a cursor page at a time. */
48
48
  members(id: string, q?: MemberQuery, signal?: AbortSignal): Promise<MemberPage>;