@anthusai/papyrus 2.0.0-next.8 → 2.0.0-next.80

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 (211) hide show
  1. package/amplify/data/function-handler.js +20 -0
  2. package/amplify/data/function-handler.ts +40 -0
  3. package/amplify/data/resource.js +151 -61
  4. package/amplify/data/resource.ts +157 -61
  5. package/amplify/data/schema.js +2096 -1980
  6. package/amplify/data/schema.ts +198 -69
  7. package/amplify/functions/assignment-action/data-access.js +14 -15
  8. package/amplify/functions/assignment-action/data-access.ts +13 -14
  9. package/amplify/functions/assignment-action/handler.ts +1 -1
  10. package/amplify/functions/automation-view/handler.py +17 -0
  11. package/amplify/functions/automation-view/resource.js +24 -0
  12. package/amplify/functions/automation-view/resource.ts +34 -0
  13. package/amplify/functions/automation-view/schema.js +26 -0
  14. package/amplify/functions/automation-view/schema.ts +28 -0
  15. package/amplify/functions/automation-view/wire.js +56 -0
  16. package/amplify/functions/automation-view/wire.ts +76 -0
  17. package/amplify/functions/content-actions/handler.py +61 -2
  18. package/amplify/functions/content-actions/requirements.txt +1 -0
  19. package/amplify/functions/content-actions/resource.js +1 -1
  20. package/amplify/functions/content-actions/resource.ts +1 -1
  21. package/amplify/{plugins/editorial-checks/function → functions/editorial-checks}/handler.py +3 -3
  22. package/amplify/functions/editorial-checks/requirements.txt +1 -0
  23. package/amplify/{plugins/editorial-checks/function → functions/editorial-checks}/resource.js +7 -7
  24. package/amplify/{plugins/editorial-checks/function → functions/editorial-checks}/resource.ts +7 -7
  25. package/amplify/functions/editorial-checks/schema.js +122 -0
  26. package/amplify/{plugins → functions}/editorial-checks/schema.ts +40 -12
  27. package/amplify/functions/editorial-checks/wire.js +53 -0
  28. package/amplify/functions/editorial-checks/wire.ts +61 -0
  29. package/amplify/functions/monitoring-view/handler.py +11 -0
  30. package/amplify/functions/monitoring-view/resource.js +24 -0
  31. package/amplify/functions/monitoring-view/resource.ts +34 -0
  32. package/amplify/functions/monitoring-view/schema.js +17 -0
  33. package/amplify/functions/monitoring-view/schema.ts +19 -0
  34. package/amplify/functions/monitoring-view/wire.js +37 -0
  35. package/amplify/functions/monitoring-view/wire.ts +47 -0
  36. package/amplify/functions/public-forms/core.js +247 -0
  37. package/amplify/functions/public-forms/core.ts +310 -0
  38. package/amplify/functions/public-forms/handler.ts +41 -0
  39. package/amplify/functions/public-forms/origins.js +35 -0
  40. package/amplify/functions/public-forms/origins.ts +43 -0
  41. package/amplify/functions/public-forms/resource.js +9 -0
  42. package/amplify/functions/public-forms/resource.ts +10 -0
  43. package/amplify/functions/public-forms/wire.js +25 -0
  44. package/amplify/functions/public-forms/wire.ts +32 -0
  45. package/amplify/functions/shared/editorial-context.ts +63 -4
  46. package/amplify/functions/shared/python-bundle.js +20 -14
  47. package/amplify/functions/shared/python-bundle.ts +25 -18
  48. package/amplify/plugins/newsletter/config.js +245 -0
  49. package/amplify/plugins/newsletter/config.ts +305 -0
  50. package/amplify/plugins/newsletter/function/handler.py +6 -0
  51. package/amplify/plugins/newsletter/function/requirements.txt +5 -0
  52. package/amplify/plugins/newsletter/ops/handler.py +12 -0
  53. package/amplify/plugins/newsletter/ops/resource.js +27 -0
  54. package/amplify/plugins/newsletter/ops/resource.ts +37 -0
  55. package/amplify/plugins/newsletter/papyrus.plugin.js +263 -0
  56. package/amplify/plugins/newsletter/papyrus.plugin.ts +311 -0
  57. package/amplify/plugins/newsletter/schema.js +57 -0
  58. package/amplify/plugins/newsletter/schema.ts +62 -0
  59. package/amplify/plugins/newsletter/secure-string-parameter.js +107 -0
  60. package/amplify/plugins/newsletter/secure-string-parameter.ts +120 -0
  61. package/amplify/plugins/newsletter/sending.js +140 -0
  62. package/amplify/plugins/newsletter/sending.ts +186 -0
  63. package/amplify/plugins/reader-steering/config.js +182 -0
  64. package/amplify/plugins/reader-steering/config.ts +290 -0
  65. package/amplify/plugins/reader-steering/function/ai_moderation.py +246 -0
  66. package/amplify/plugins/reader-steering/function/handler.py +1554 -0
  67. package/amplify/plugins/reader-steering/function/moderation-prompt.md +27 -0
  68. package/amplify/plugins/reader-steering/function/moderation.py +316 -0
  69. package/amplify/plugins/reader-steering/function/proposals.py +255 -0
  70. package/amplify/plugins/reader-steering/function/resource.js +27 -0
  71. package/amplify/plugins/reader-steering/function/resource.ts +35 -0
  72. package/amplify/plugins/reader-steering/papyrus.plugin.js +186 -0
  73. package/amplify/plugins/reader-steering/papyrus.plugin.ts +212 -0
  74. package/amplify/plugins/reader-steering/schema.js +205 -0
  75. package/amplify/plugins/reader-steering/schema.ts +207 -0
  76. package/amplify/plugins/registry.js +4 -2
  77. package/amplify/plugins/registry.ts +4 -2
  78. package/amplify/plugins/signup/schema.js +2 -1
  79. package/amplify/plugins/signup/schema.ts +2 -1
  80. package/amplify/plugins/types.ts +5 -0
  81. package/amplify/plugins/wire.js +1 -0
  82. package/amplify/plugins/wire.ts +1 -0
  83. package/amplify/publication/projection-lease.js +30 -0
  84. package/amplify/publication/projection-lease.ts +39 -0
  85. package/amplify/publication/redirect-and-index.js +105 -0
  86. package/amplify/publication/redirect-rules.js +73 -0
  87. package/amplify/publication/redirect-rules.ts +93 -0
  88. package/amplify/publication/s3-projection.js +7 -1
  89. package/amplify/publication/s3-projection.ts +9 -1
  90. package/amplify/site-backend-config.ts +18 -1
  91. package/amplify/site-backend-names.js +4 -2
  92. package/amplify/site-backend-names.ts +4 -2
  93. package/amplify/site-backend.js +41 -2
  94. package/amplify/site-backend.ts +46 -2
  95. package/app/api/auth/prospectus/sign-in/route.ts +4 -0
  96. package/app/api/newsletter/confirm/route.ts +13 -0
  97. package/app/api/newsletter/preferences/route.ts +13 -0
  98. package/app/api/newsletter/state/route.ts +9 -0
  99. package/app/api/newsletter/subscribe/route.ts +9 -0
  100. package/app/api/newsletter/unsubscribe/route.ts +13 -0
  101. package/app/api/newsroom/curation/context/route.ts +9 -0
  102. package/app/api/newsroom/curation/priming/route.ts +9 -0
  103. package/app/api/newsroom/curation/publication/route.ts +9 -0
  104. package/app/api/reader/comment/delete/route.ts +9 -0
  105. package/app/api/reader/comment/edit/route.ts +9 -0
  106. package/app/api/reader/comment/route.ts +9 -0
  107. package/app/api/reader/flag/route.ts +9 -0
  108. package/app/api/reader/handle/route.ts +9 -0
  109. package/app/api/reader/me/route.ts +9 -0
  110. package/app/api/reader/rating/route.ts +9 -0
  111. package/app/api/reader/report/route.ts +9 -0
  112. package/app/api/reader/retired/route.ts +9 -0
  113. package/app/api/reader/submit/route.ts +9 -0
  114. package/app/api/reader/vote/route.ts +9 -0
  115. package/bin/papyrus-infra.mjs +20 -1
  116. package/components/automation-panel.tsx +49 -0
  117. package/components/automation-run-now.tsx +97 -0
  118. package/components/automation-view.tsx +192 -0
  119. package/components/editorial-checks-admin-panel.tsx +36 -11
  120. package/components/moderation-panel.tsx +248 -0
  121. package/components/monitoring-overview-view.tsx +241 -0
  122. package/components/monitoring-panel.tsx +40 -0
  123. package/components/news-desk-client-provider.tsx +18 -18
  124. package/components/news-desk-taxonomy-client.ts +28 -8
  125. package/components/newsletter-panel.tsx +474 -0
  126. package/components/newsletter-sections.tsx +163 -0
  127. package/components/newsroom-access-gate.tsx +15 -1
  128. package/components/newsroom-article-editor.tsx +6 -6
  129. package/components/newsroom-articles-view.tsx +6 -6
  130. package/components/newsroom-board-view.tsx +8 -3
  131. package/components/newsroom-curation-bootstrap.tsx +45 -0
  132. package/components/newsroom-ops-overview.tsx +22 -92
  133. package/components/newsroom-ops-shell.tsx +2 -2
  134. package/components/newsroom-organizer.css +33 -0
  135. package/components/newsroom-overview-skeleton.tsx +25 -0
  136. package/components/newsroom-references-view.tsx +192 -49
  137. package/components/notification-center.tsx +273 -0
  138. package/components/publication-cyclotron-panel.tsx +15 -10
  139. package/components/reader-auth-state.ts +1 -1
  140. package/components/reference-add-entry.tsx +75 -0
  141. package/components/reference-curation-controls.tsx +31 -22
  142. package/components/reference-cyclotron-priming.tsx +58 -19
  143. package/components/reference-cyclotron-suggestion.tsx +10 -6
  144. package/components/reference-priming.tsx +14 -10
  145. package/components/reference-relevance-review.tsx +3 -3
  146. package/components/reference-section-suggestion.tsx +1 -1
  147. package/components/topic-steering-workspace.tsx +223 -144
  148. package/components/use-editorial-checks.ts +12 -10
  149. package/infra/amplify-app-shell.js +94 -16
  150. package/infra/amplify-app-shell.ts +106 -18
  151. package/infra/cloud-email-config.js +32 -0
  152. package/infra/cloud-email-config.ts +39 -0
  153. package/infra/cloud-email.js +57 -0
  154. package/infra/cloud-email.test.js +69 -0
  155. package/infra/cloud-email.test.ts +66 -0
  156. package/infra/cloud-email.ts +60 -0
  157. package/infra/index.js +1 -0
  158. package/infra/secure-string-parameter-handler.js +41 -0
  159. package/infra/secure-string-parameter-handler.ts +41 -0
  160. package/infra/secure-string-parameter.js +79 -0
  161. package/infra/secure-string-parameter.ts +91 -0
  162. package/infra/site-config.js +88 -6
  163. package/infra/site-config.ts +134 -6
  164. package/lib/automation-client.ts +54 -0
  165. package/lib/automation-fixture.ts +93 -0
  166. package/lib/automation-overview.ts +232 -0
  167. package/lib/category-repository.ts +11 -9
  168. package/lib/curation-routes.ts +345 -0
  169. package/lib/cyclotron-suggestions.ts +4 -4
  170. package/lib/editorial-checks-backend.ts +1 -1
  171. package/lib/editorial-checks-client.ts +19 -1
  172. package/lib/editorial-checks-demo.ts +2 -2
  173. package/lib/editorial-checks-settings.ts +3 -0
  174. package/lib/editorial-checks.ts +8 -11
  175. package/lib/editorial-preview.ts +5 -5
  176. package/lib/monitoring-client.ts +29 -0
  177. package/lib/monitoring-overview-fixture.ts +51 -0
  178. package/lib/monitoring-overview.ts +145 -0
  179. package/lib/news-desk-session.ts +12 -21
  180. package/lib/newsletter-api.ts +418 -0
  181. package/lib/newsletter-client.ts +46 -0
  182. package/lib/newsletter-fixture.ts +184 -0
  183. package/lib/newsletter-model.ts +202 -0
  184. package/lib/newsroom-organizer-nav.ts +2 -1
  185. package/lib/prospectus-session.ts +15 -14
  186. package/lib/prospectus-sign-in-routes.ts +84 -19
  187. package/lib/prospectus-site-identity.ts +24 -1
  188. package/lib/reader-api.ts +145 -0
  189. package/lib/reader-moderation.ts +220 -0
  190. package/lib/reader-retirement-route.ts +89 -0
  191. package/lib/reader-subject.md +29 -0
  192. package/lib/reader-subject.ts +53 -0
  193. package/lib/reference-review-details.ts +71 -0
  194. package/lib/reference-review-request.ts +14 -0
  195. package/lib/relevance-decisions.ts +42 -10
  196. package/lib/relevance-status.ts +2 -2
  197. package/lib/review-client.ts +99 -0
  198. package/lib/review-fixture.ts +45 -0
  199. package/lib/review-requests.ts +238 -0
  200. package/lib/semantic-graph.ts +2 -0
  201. package/lib/site-brand-tenant.ts +11 -6
  202. package/lib/site-brand.ts +6 -3
  203. package/lib/site-origin.ts +67 -0
  204. package/lib/use-reference-review-data.ts +44 -0
  205. package/middleware.ts +14 -3
  206. package/package.json +56 -3
  207. package/routes.manifest.json +215 -2
  208. package/amplify/plugins/editorial-checks/function/requirements.txt +0 -1
  209. package/amplify/plugins/editorial-checks/papyrus.plugin.js +0 -71
  210. package/amplify/plugins/editorial-checks/papyrus.plugin.ts +0 -87
  211. package/amplify/plugins/editorial-checks/schema.js +0 -94
@@ -0,0 +1,44 @@
1
+ "use client";
2
+
3
+ import { useCallback, useEffect, useState } from "react";
4
+
5
+ /** Load persisted predictions and attributed review history without cancelling on a loading rerender. */
6
+ export function useReferenceReviewData<Relation, Message>({
7
+ enabled,
8
+ loadRelations,
9
+ loadMessages,
10
+ onRelations,
11
+ onMessages,
12
+ }: {
13
+ enabled: boolean;
14
+ loadRelations: () => Promise<Relation[]>;
15
+ loadMessages: () => Promise<Message[]>;
16
+ onRelations: (relations: Relation[]) => void;
17
+ onMessages: (messages: Message[]) => void;
18
+ }) {
19
+ const [state, setState] = useState<"loading" | "ready" | "error">(enabled ? "loading" : "ready");
20
+ const [error, setError] = useState<string | null>(null);
21
+ const [attempt, setAttempt] = useState(0);
22
+ const retry = useCallback(() => setAttempt((current) => current + 1), []);
23
+ useEffect(() => {
24
+ if (!enabled) return;
25
+ let active = true;
26
+ setState("loading");
27
+ setError(null);
28
+ void Promise.allSettled([loadRelations(), loadMessages()]).then(([relations, history]) => {
29
+ if (!active) return;
30
+ if (relations.status === "fulfilled") onRelations(relations.value);
31
+ if (history.status === "fulfilled") onMessages(history.value);
32
+ const failure = relations.status === "rejected" ? relations.reason : history.status === "rejected" ? history.reason : null;
33
+ if (failure) {
34
+ const subject = relations.status === "rejected" ? "Predictions" : "Review history";
35
+ setError(`${subject} could not be loaded. ${failure instanceof Error ? failure.message : "Try again."}`);
36
+ setState("error");
37
+ } else {
38
+ setState("ready");
39
+ }
40
+ });
41
+ return () => { active = false; };
42
+ }, [enabled, loadRelations, loadMessages, onRelations, onMessages, attempt]);
43
+ return { state, error, retry };
44
+ }
package/middleware.ts CHANGED
@@ -5,6 +5,7 @@ import { newsroomHref } from "./lib/newsroom-base-path";
5
5
  import { getReaderBasePath } from "./lib/reader-base-path";
6
6
  import { isStagingGatedPath, isStaticOrApiPath } from "./lib/staging-gated-path";
7
7
  import { getSiteEnv, isIndexable } from "./lib/site-env";
8
+ import { SiteOriginNotConfiguredError, publicSiteUrl, siteOriginNotConfiguredResponse } from "./lib/site-origin";
8
9
  import { getStagingAccess } from "./lib/staging-gate";
9
10
  import {
10
11
  isPreviewGatedPath,
@@ -38,11 +39,11 @@ function routeRequest(request: NextRequest): NextResponse {
38
39
  }
39
40
 
40
41
  if (pathname === "/newsroom" || pathname === "/newsroom/") {
41
- return NextResponse.redirect(new URL(`/${request.nextUrl.search}`, request.url));
42
+ return NextResponse.redirect(publicSiteUrl(`/${request.nextUrl.search}`, request));
42
43
  }
43
44
  if (pathname.startsWith("/newsroom/")) {
44
45
  const target = pathname.slice("/newsroom".length) || "/";
45
- return NextResponse.redirect(new URL(`${target}${request.nextUrl.search}`, request.url));
46
+ return NextResponse.redirect(publicSiteUrl(`${target}${request.nextUrl.search}`, request));
46
47
  }
47
48
 
48
49
  if (pathname === "/" || pathname === "") {
@@ -59,6 +60,16 @@ function routeRequest(request: NextRequest): NextResponse {
59
60
  }
60
61
 
61
62
  export async function middleware(request: NextRequest): Promise<NextResponse> {
63
+ try {
64
+ return await handleRequest(request);
65
+ } catch (error) {
66
+ // Redirects name the site's public origin (request.url is localhost on Amplify); without it, fail closed.
67
+ if (error instanceof SiteOriginNotConfiguredError) return withRobotsHeader(siteOriginNotConfiguredResponse(error));
68
+ throw error;
69
+ }
70
+ }
71
+
72
+ async function handleRequest(request: NextRequest): Promise<NextResponse> {
62
73
  let sessionResponse: NextResponse | null = null;
63
74
  const { pathname } = request.nextUrl;
64
75
  const gated = isStaticPreviewEnabled()
@@ -68,7 +79,7 @@ export async function middleware(request: NextRequest): Promise<NextResponse> {
68
79
  sessionResponse = NextResponse.next();
69
80
  const access = await getStagingAccess(request, sessionResponse);
70
81
  if (access === "anonymous") {
71
- return withRobotsHeader(NextResponse.redirect(new URL(newsroomHref(), request.url)));
82
+ return withRobotsHeader(NextResponse.redirect(publicSiteUrl(newsroomHref(), request)));
72
83
  }
73
84
  if (access === "forbidden") {
74
85
  return withRobotsHeader(new NextResponse("Staging is limited to editors and admins.", { status: 403 }));
package/package.json CHANGED
@@ -75,6 +75,9 @@
75
75
  "./components/archive-grid": "./components/archive-grid.tsx",
76
76
  "./components/archive-shell": "./components/archive-shell.tsx",
77
77
  "./components/article-video": "./components/article-video.tsx",
78
+ "./components/automation-panel": "./components/automation-panel.tsx",
79
+ "./components/automation-run-now": "./components/automation-run-now.tsx",
80
+ "./components/automation-view": "./components/automation-view.tsx",
78
81
  "./components/blog-page-background": "./components/blog-page-background.tsx",
79
82
  "./components/curation-delegation-client": "./components/curation-delegation-client.ts",
80
83
  "./components/dev-sandbox-editor-sign-in": "./components/dev-sandbox-editor-sign-in.tsx",
@@ -85,9 +88,14 @@
85
88
  "./components/item-stream-view": "./components/item-stream-view.tsx",
86
89
  "./components/markus-body-editor": "./components/markus-body-editor.tsx",
87
90
  "./components/markus-ir-preview": "./components/markus-ir-preview.tsx",
91
+ "./components/moderation-panel": "./components/moderation-panel.tsx",
92
+ "./components/monitoring-overview-view": "./components/monitoring-overview-view.tsx",
93
+ "./components/monitoring-panel": "./components/monitoring-panel.tsx",
88
94
  "./components/news-desk-client-provider": "./components/news-desk-client-provider.tsx",
89
95
  "./components/news-desk-page": "./components/news-desk-page.tsx",
90
96
  "./components/news-desk-taxonomy-client": "./components/news-desk-taxonomy-client.ts",
97
+ "./components/newsletter-panel": "./components/newsletter-panel.tsx",
98
+ "./components/newsletter-sections": "./components/newsletter-sections.tsx",
91
99
  "./components/newspaper": "./components/newspaper.tsx",
92
100
  "./components/newsroom-access-gate": "./components/newsroom-access-gate.tsx",
93
101
  "./components/newsroom-article-editor": "./components/newsroom-article-editor.tsx",
@@ -96,9 +104,11 @@
96
104
  "./components/newsroom-assignments-view": "./components/newsroom-assignments-view.tsx",
97
105
  "./components/newsroom-board-view": "./components/newsroom-board-view.tsx",
98
106
  "./components/newsroom-client-shell": "./components/newsroom-client-shell.tsx",
107
+ "./components/newsroom-curation-bootstrap": "./components/newsroom-curation-bootstrap.tsx",
99
108
  "./components/newsroom-curation-provider": "./components/newsroom-curation-provider.tsx",
100
109
  "./components/newsroom-ops-overview": "./components/newsroom-ops-overview.tsx",
101
110
  "./components/newsroom-ops-shell": "./components/newsroom-ops-shell.tsx",
111
+ "./components/newsroom-overview-skeleton": "./components/newsroom-overview-skeleton.tsx",
102
112
  "./components/newsroom-references-view": "./components/newsroom-references-view.tsx",
103
113
  "./components/newsroom-theme-fonts/broadsheet-green": "./components/newsroom-theme-fonts/broadsheet-green.tsx",
104
114
  "./components/newsroom-theme-fonts/newspaper-gothic": "./components/newsroom-theme-fonts/newspaper-gothic.tsx",
@@ -106,6 +116,7 @@
106
116
  "./components/newsroom-theme-fonts/refined-newsprint": "./components/newsroom-theme-fonts/refined-newsprint.tsx",
107
117
  "./components/newsroom-theme": "./components/newsroom-theme.tsx",
108
118
  "./components/newsroom-topics-view": "./components/newsroom-topics-view.tsx",
119
+ "./components/notification-center": "./components/notification-center.tsx",
109
120
  "./components/papyrus-console-shell": "./components/papyrus-console-shell.tsx",
110
121
  "./components/pictogram-figure": "./components/pictogram-figure.tsx",
111
122
  "./components/presentation-footer": "./components/presentation-footer.tsx",
@@ -118,6 +129,7 @@
118
129
  "./components/reader-auth-state": "./components/reader-auth-state.ts",
119
130
  "./components/reader-settings": "./components/reader-settings.ts",
120
131
  "./components/reader-theme-control": "./components/reader-theme-control.tsx",
132
+ "./components/reference-add-entry": "./components/reference-add-entry.tsx",
121
133
  "./components/reference-curation-controls": "./components/reference-curation-controls.tsx",
122
134
  "./components/reference-cyclotron-priming": "./components/reference-cyclotron-priming.tsx",
123
135
  "./components/reference-cyclotron-status": "./components/reference-cyclotron-status.tsx",
@@ -169,6 +181,9 @@
169
181
  "./lib/article-flow": "./lib/article-flow.ts",
170
182
  "./lib/article-frame-solver": "./lib/article-frame-solver.ts",
171
183
  "./lib/articles": "./lib/articles.ts",
184
+ "./lib/automation-client": "./lib/automation-client.ts",
185
+ "./lib/automation-fixture": "./lib/automation-fixture.ts",
186
+ "./lib/automation-overview": "./lib/automation-overview.ts",
172
187
  "./lib/blog-feature-solver": "./lib/blog-feature-solver.ts",
173
188
  "./lib/blog-rhythm": "./lib/blog-rhythm.ts",
174
189
  "./lib/brand-fonts-watch": "./lib/brand-fonts-watch.ts",
@@ -188,6 +203,7 @@
188
203
  "./lib/content-types": "./lib/content-types.ts",
189
204
  "./lib/curation-client": "./lib/curation-client.ts",
190
205
  "./lib/curation-delegation-helpers": "./lib/curation-delegation-helpers.ts",
206
+ "./lib/curation-routes": "./lib/curation-routes.ts",
191
207
  "./lib/cyclotron-suggestions": "./lib/cyclotron-suggestions.ts",
192
208
  "./lib/define-site": "./lib/define-site.ts",
193
209
  "./lib/demo-amplify-outputs": "./lib/demo-amplify-outputs.ts",
@@ -224,7 +240,14 @@
224
240
  "./lib/markus-projection": "./lib/markus-projection.ts",
225
241
  "./lib/markus-to-article": "./lib/markus-to-article.ts",
226
242
  "./lib/media-route-response": "./lib/media-route-response.ts",
243
+ "./lib/monitoring-client": "./lib/monitoring-client.ts",
244
+ "./lib/monitoring-overview-fixture": "./lib/monitoring-overview-fixture.ts",
245
+ "./lib/monitoring-overview": "./lib/monitoring-overview.ts",
227
246
  "./lib/news-desk-session": "./lib/news-desk-session.ts",
247
+ "./lib/newsletter-api": "./lib/newsletter-api.ts",
248
+ "./lib/newsletter-client": "./lib/newsletter-client.ts",
249
+ "./lib/newsletter-fixture": "./lib/newsletter-fixture.ts",
250
+ "./lib/newsletter-model": "./lib/newsletter-model.ts",
228
251
  "./lib/newspaper-layout": "./lib/newspaper-layout.ts",
229
252
  "./lib/newsroom-articles": "./lib/newsroom-articles.ts",
230
253
  "./lib/newsroom-assignments": "./lib/newsroom-assignments.ts",
@@ -265,13 +288,19 @@
265
288
  "./lib/publication-cyclotron": "./lib/publication-cyclotron.ts",
266
289
  "./lib/publication-items": "./lib/publication-items.ts",
267
290
  "./lib/rate-limit-retry": "./lib/rate-limit-retry.ts",
291
+ "./lib/reader-api": "./lib/reader-api.ts",
268
292
  "./lib/reader-base-path": "./lib/reader-base-path.ts",
269
293
  "./lib/reader-cache-lifetime": "./lib/reader-cache-lifetime.ts",
294
+ "./lib/reader-moderation": "./lib/reader-moderation.ts",
295
+ "./lib/reader-retirement-route": "./lib/reader-retirement-route.ts",
270
296
  "./lib/reader-route-config": "./lib/reader-route-config.ts",
271
297
  "./lib/reader-static-params": "./lib/reader-static-params.ts",
272
298
  "./lib/reader-storage-url": "./lib/reader-storage-url.ts",
299
+ "./lib/reader-subject": "./lib/reader-subject.ts",
273
300
  "./lib/reference-display": "./lib/reference-display.ts",
274
301
  "./lib/reference-policy": "./lib/reference-policy.ts",
302
+ "./lib/reference-review-details": "./lib/reference-review-details.ts",
303
+ "./lib/reference-review-request": "./lib/reference-review-request.ts",
275
304
  "./lib/reference-source-preview": "./lib/reference-source-preview.ts",
276
305
  "./lib/relevance-decisions": "./lib/relevance-decisions.ts",
277
306
  "./lib/relevance-status": "./lib/relevance-status.ts",
@@ -280,6 +309,9 @@
280
309
  "./lib/reporting-story-budget": "./lib/reporting-story-budget.ts",
281
310
  "./lib/revalidate-prewarm": "./lib/revalidate-prewarm.ts",
282
311
  "./lib/revalidate-secret": "./lib/revalidate-secret.ts",
312
+ "./lib/review-client": "./lib/review-client.ts",
313
+ "./lib/review-fixture": "./lib/review-fixture.ts",
314
+ "./lib/review-requests": "./lib/review-requests.ts",
283
315
  "./lib/robots-policy": "./lib/robots-policy.ts",
284
316
  "./lib/root-route-redirect": "./lib/root-route-redirect.ts",
285
317
  "./lib/semantic-graph": "./lib/semantic-graph.ts",
@@ -288,6 +320,7 @@
288
320
  "./lib/site-brand-tenant": "./lib/site-brand-tenant.ts",
289
321
  "./lib/site-brand": "./lib/site-brand.ts",
290
322
  "./lib/site-env": "./lib/site-env.ts",
323
+ "./lib/site-origin": "./lib/site-origin.ts",
291
324
  "./lib/site-renderer": "./lib/site-renderer.ts",
292
325
  "./lib/site-section-suggestions": "./lib/site-section-suggestions.ts",
293
326
  "./lib/site-stack": "./lib/site-stack.ts",
@@ -299,6 +332,7 @@
299
332
  "./lib/test-editor-override": "./lib/test-editor-override.ts",
300
333
  "./lib/text-columns": "./lib/text-columns.ts",
301
334
  "./lib/themed-image": "./lib/themed-image.ts",
335
+ "./lib/use-reference-review-data": "./lib/use-reference-review-data.ts",
302
336
  "./lib/utils": "./lib/utils.ts",
303
337
  "./lib/video-loading": "./lib/video-loading.ts",
304
338
  "./lib/video-mode": "./lib/video-mode.ts",
@@ -330,6 +364,25 @@
330
364
  "./app/api/local-preview/derive/route": "./app/api/local-preview/derive/route.ts",
331
365
  "./app/api/local-preview/media/route": "./app/api/local-preview/media/route.ts",
332
366
  "./app/api/media/[...path]/route": "./app/api/media/[...path]/route.ts",
367
+ "./app/api/newsletter/confirm/route": "./app/api/newsletter/confirm/route.ts",
368
+ "./app/api/newsletter/preferences/route": "./app/api/newsletter/preferences/route.ts",
369
+ "./app/api/newsletter/state/route": "./app/api/newsletter/state/route.ts",
370
+ "./app/api/newsletter/subscribe/route": "./app/api/newsletter/subscribe/route.ts",
371
+ "./app/api/newsletter/unsubscribe/route": "./app/api/newsletter/unsubscribe/route.ts",
372
+ "./app/api/newsroom/curation/context/route": "./app/api/newsroom/curation/context/route.ts",
373
+ "./app/api/newsroom/curation/priming/route": "./app/api/newsroom/curation/priming/route.ts",
374
+ "./app/api/newsroom/curation/publication/route": "./app/api/newsroom/curation/publication/route.ts",
375
+ "./app/api/reader/comment/delete/route": "./app/api/reader/comment/delete/route.ts",
376
+ "./app/api/reader/comment/edit/route": "./app/api/reader/comment/edit/route.ts",
377
+ "./app/api/reader/comment/route": "./app/api/reader/comment/route.ts",
378
+ "./app/api/reader/flag/route": "./app/api/reader/flag/route.ts",
379
+ "./app/api/reader/handle/route": "./app/api/reader/handle/route.ts",
380
+ "./app/api/reader/me/route": "./app/api/reader/me/route.ts",
381
+ "./app/api/reader/rating/route": "./app/api/reader/rating/route.ts",
382
+ "./app/api/reader/report/route": "./app/api/reader/report/route.ts",
383
+ "./app/api/reader/retired/route": "./app/api/reader/retired/route.ts",
384
+ "./app/api/reader/submit/route": "./app/api/reader/submit/route.ts",
385
+ "./app/api/reader/vote/route": "./app/api/reader/vote/route.ts",
333
386
  "./app/api/revalidate/route": "./app/api/revalidate/route.ts",
334
387
  "./app/archive/page": "./app/archive/page.tsx",
335
388
  "./app/articles/[slug]/page": "./app/articles/[slug]/page.tsx",
@@ -395,14 +448,14 @@
395
448
  "optional": true
396
449
  }
397
450
  },
398
- "version": "2.0.0-next.8",
451
+ "version": "2.0.0-next.80",
399
452
  "dependencies": {
400
453
  "@aws-amplify/adapter-nextjs": "^1.7.3",
401
454
  "@aws-crypto/sha256-js": "5.2.0",
402
455
  "@aws-sdk/client-cognito-identity-provider": "3.1045.0",
456
+ "@aws-sdk/client-dynamodb": "^3.1045.0",
403
457
  "@aws-sdk/client-lambda": "^3.1045.0",
404
458
  "@aws-sdk/client-s3": "^3.1045.0",
405
- "@aws-sdk/client-secrets-manager": "3.1045.0",
406
459
  "@aws-sdk/client-ssm": "^3.1045.0",
407
460
  "@aws-sdk/credential-provider-node": "3.972.84",
408
461
  "@aws-sdk/s3-request-presigner": "^3.1045.0",
@@ -435,7 +488,7 @@
435
488
  "class-variance-authority": "^0.7.1",
436
489
  "clsx": "^2.1.1",
437
490
  "cmdk": "^1.1.1",
438
- "cyclotron": "https://github.com/AnthusAI/Cyclotron/releases/download/ui-v0.2.2/cyclotron-0.2.2.tgz",
491
+ "cyclotron": "https://github.com/AnthusAI/Cyclotron/releases/download/ui-v0.2.3/cyclotron-0.2.3.tgz",
439
492
  "d3": "^7.9.0",
440
493
  "esbuild": "^0.28.2",
441
494
  "framer-motion": "^14.3.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.0.0-next.8",
2
+ "version": "2.0.0-next.80",
3
3
  "routes": [
4
4
  {
5
5
  "file": "app/%5F_preview/[[...path]]/route.ts",
@@ -114,7 +114,8 @@
114
114
  "file": "app/api/auth/prospectus/sign-in/route.ts",
115
115
  "hasDefault": false,
116
116
  "exports": [
117
- "GET"
117
+ "GET",
118
+ "POST"
118
119
  ],
119
120
  "config": {
120
121
  "dynamic": "\"force-dynamic\"",
@@ -170,6 +171,218 @@
170
171
  "dynamic": "\"force-dynamic\""
171
172
  }
172
173
  },
174
+ {
175
+ "file": "app/api/newsletter/confirm/route.ts",
176
+ "hasDefault": false,
177
+ "exports": [
178
+ "GET",
179
+ "POST"
180
+ ],
181
+ "config": {
182
+ "dynamic": "\"force-dynamic\"",
183
+ "runtime": "\"nodejs\""
184
+ }
185
+ },
186
+ {
187
+ "file": "app/api/newsletter/preferences/route.ts",
188
+ "hasDefault": false,
189
+ "exports": [
190
+ "GET",
191
+ "POST"
192
+ ],
193
+ "config": {
194
+ "dynamic": "\"force-dynamic\"",
195
+ "runtime": "\"nodejs\""
196
+ }
197
+ },
198
+ {
199
+ "file": "app/api/newsletter/state/route.ts",
200
+ "hasDefault": false,
201
+ "exports": [
202
+ "GET"
203
+ ],
204
+ "config": {
205
+ "dynamic": "\"force-dynamic\"",
206
+ "runtime": "\"nodejs\""
207
+ }
208
+ },
209
+ {
210
+ "file": "app/api/newsletter/subscribe/route.ts",
211
+ "hasDefault": false,
212
+ "exports": [
213
+ "POST"
214
+ ],
215
+ "config": {
216
+ "dynamic": "\"force-dynamic\"",
217
+ "runtime": "\"nodejs\""
218
+ }
219
+ },
220
+ {
221
+ "file": "app/api/newsletter/unsubscribe/route.ts",
222
+ "hasDefault": false,
223
+ "exports": [
224
+ "GET",
225
+ "POST"
226
+ ],
227
+ "config": {
228
+ "dynamic": "\"force-dynamic\"",
229
+ "runtime": "\"nodejs\""
230
+ }
231
+ },
232
+ {
233
+ "file": "app/api/newsroom/curation/context/route.ts",
234
+ "hasDefault": false,
235
+ "exports": [
236
+ "GET"
237
+ ],
238
+ "config": {
239
+ "dynamic": "\"force-dynamic\"",
240
+ "runtime": "\"nodejs\""
241
+ }
242
+ },
243
+ {
244
+ "file": "app/api/newsroom/curation/priming/route.ts",
245
+ "hasDefault": false,
246
+ "exports": [
247
+ "POST"
248
+ ],
249
+ "config": {
250
+ "dynamic": "\"force-dynamic\"",
251
+ "runtime": "\"nodejs\""
252
+ }
253
+ },
254
+ {
255
+ "file": "app/api/newsroom/curation/publication/route.ts",
256
+ "hasDefault": false,
257
+ "exports": [
258
+ "POST"
259
+ ],
260
+ "config": {
261
+ "dynamic": "\"force-dynamic\"",
262
+ "runtime": "\"nodejs\""
263
+ }
264
+ },
265
+ {
266
+ "file": "app/api/reader/comment/delete/route.ts",
267
+ "hasDefault": false,
268
+ "exports": [
269
+ "POST"
270
+ ],
271
+ "config": {
272
+ "dynamic": "\"force-dynamic\"",
273
+ "runtime": "\"nodejs\""
274
+ }
275
+ },
276
+ {
277
+ "file": "app/api/reader/comment/edit/route.ts",
278
+ "hasDefault": false,
279
+ "exports": [
280
+ "POST"
281
+ ],
282
+ "config": {
283
+ "dynamic": "\"force-dynamic\"",
284
+ "runtime": "\"nodejs\""
285
+ }
286
+ },
287
+ {
288
+ "file": "app/api/reader/comment/route.ts",
289
+ "hasDefault": false,
290
+ "exports": [
291
+ "POST"
292
+ ],
293
+ "config": {
294
+ "dynamic": "\"force-dynamic\"",
295
+ "runtime": "\"nodejs\""
296
+ }
297
+ },
298
+ {
299
+ "file": "app/api/reader/flag/route.ts",
300
+ "hasDefault": false,
301
+ "exports": [
302
+ "POST"
303
+ ],
304
+ "config": {
305
+ "dynamic": "\"force-dynamic\"",
306
+ "runtime": "\"nodejs\""
307
+ }
308
+ },
309
+ {
310
+ "file": "app/api/reader/handle/route.ts",
311
+ "hasDefault": false,
312
+ "exports": [
313
+ "POST"
314
+ ],
315
+ "config": {
316
+ "dynamic": "\"force-dynamic\"",
317
+ "runtime": "\"nodejs\""
318
+ }
319
+ },
320
+ {
321
+ "file": "app/api/reader/me/route.ts",
322
+ "hasDefault": false,
323
+ "exports": [
324
+ "GET"
325
+ ],
326
+ "config": {
327
+ "dynamic": "\"force-dynamic\"",
328
+ "runtime": "\"nodejs\""
329
+ }
330
+ },
331
+ {
332
+ "file": "app/api/reader/rating/route.ts",
333
+ "hasDefault": false,
334
+ "exports": [
335
+ "POST"
336
+ ],
337
+ "config": {
338
+ "dynamic": "\"force-dynamic\"",
339
+ "runtime": "\"nodejs\""
340
+ }
341
+ },
342
+ {
343
+ "file": "app/api/reader/report/route.ts",
344
+ "hasDefault": false,
345
+ "exports": [
346
+ "POST"
347
+ ],
348
+ "config": {
349
+ "dynamic": "\"force-dynamic\"",
350
+ "runtime": "\"nodejs\""
351
+ }
352
+ },
353
+ {
354
+ "file": "app/api/reader/retired/route.ts",
355
+ "hasDefault": false,
356
+ "exports": [
357
+ "GET"
358
+ ],
359
+ "config": {
360
+ "dynamic": "\"force-dynamic\"",
361
+ "runtime": "\"nodejs\""
362
+ }
363
+ },
364
+ {
365
+ "file": "app/api/reader/submit/route.ts",
366
+ "hasDefault": false,
367
+ "exports": [
368
+ "POST"
369
+ ],
370
+ "config": {
371
+ "dynamic": "\"force-dynamic\"",
372
+ "runtime": "\"nodejs\""
373
+ }
374
+ },
375
+ {
376
+ "file": "app/api/reader/vote/route.ts",
377
+ "hasDefault": false,
378
+ "exports": [
379
+ "POST"
380
+ ],
381
+ "config": {
382
+ "dynamic": "\"force-dynamic\"",
383
+ "runtime": "\"nodejs\""
384
+ }
385
+ },
173
386
  {
174
387
  "file": "app/api/revalidate/route.ts",
175
388
  "hasDefault": false,
@@ -1 +0,0 @@
1
- limatus[jev]>=0.31,<0.32
@@ -1,71 +0,0 @@
1
- import { secret } from "@aws-amplify/backend";
2
- import { Stack } from "aws-cdk-lib";
3
- import { Effect, PolicyStatement } from "aws-cdk-lib/aws-iam";
4
- import { editorialChecks } from "./function/resource.js";
5
- import { editorialChecksSchemaDefinitions } from "./schema.js";
6
- export const EDITORIAL_CHECKS_QUERIES = ["checkEditorial", "suggestEditorialRewrite", "draftEditorialQuestions", "tryEditorialPolicy"];
7
- export const EDITORIAL_CHECKS_MUTATIONS = ["importEditorialStarterPack", "recalibrateEditorialPolicies"];
8
- /** The model operations the function performs with its own role. */
9
- export const EDITORIAL_CHECKS_FUNCTION_FIELDS = [
10
- "Query/fields/listKnowledgeCorporaByRoleAndName",
11
- "Query/fields/getEditorialContext",
12
- "Query/fields/listEditorialPolicies",
13
- "Query/fields/getEditorialCheckSettings",
14
- "Query/fields/listEditorialFeedbacks",
15
- "Mutation/fields/createEditorialPolicy",
16
- "Mutation/fields/updateEditorialPolicy",
17
- ];
18
- export const EDITORIAL_CHECKS_SECRETS = ["TYPESAFE_API_KEY", "OPENAI_API_KEY"];
19
- /**
20
- * SSM parameters holding the provider keys. A Python function reads its secret()
21
- * values itself (Amplify only resolves them for Node functions), so it needs read
22
- * access to the app's branch and shared secret paths, and to the sandbox paths.
23
- */
24
- export function editorialChecksSecretParameters(region, account, appId) {
25
- const arn = (path) => `arn:aws:ssm:${region}:${account}:parameter/amplify/${path}`;
26
- return EDITORIAL_CHECKS_SECRETS.flatMap((name) => [
27
- arn(`papyrus/*/${name}`),
28
- arn(`shared/papyrus/${name}`),
29
- ...(appId ? [arn(`${appId}/*/${name}`), arn(`shared/${appId}/${name}`)] : []),
30
- ]);
31
- }
32
- export const editorialChecksManifest = {
33
- name: "editorial-checks",
34
- contract: 1,
35
- models: ["EditorialPolicy", "EditorialCheckSettings", "EditorialFeedback"],
36
- mutations: [...EDITORIAL_CHECKS_QUERIES, ...EDITORIAL_CHECKS_MUTATIONS],
37
- guest: { mutations: [] },
38
- newsroomPanels: [{ id: "editorial-checks", label: "Editorial checks" }],
39
- staticAssets: [],
40
- };
41
- export function resolveEditorialChecksConfig(request) {
42
- const raw = typeof request === "string" ? { name: request } : request;
43
- const unknown = Object.keys(raw).filter((key) => key !== "name");
44
- if (unknown.length > 0)
45
- throw new Error(`Unknown editorial-checks plugin settings: ${unknown.join(", ")} (runtime settings are edited in the newsroom)`);
46
- return {};
47
- }
48
- export const editorialChecksPlugin = {
49
- manifest: editorialChecksManifest,
50
- resolveConfig: resolveEditorialChecksConfig,
51
- functions: () => ({ editorialChecks }),
52
- schemaDefinitions: editorialChecksSchemaDefinitions,
53
- publicSettings: () => ({ contract: editorialChecksManifest.contract }),
54
- wire(backend, _config, context) {
55
- const lambda = backend.editorialChecks.resources.lambda;
56
- const stack = Stack.of(lambda);
57
- lambda.addEnvironment("PAPYRUS_GRAPHQL_ENDPOINT", context.graphqlEndpoint);
58
- for (const name of EDITORIAL_CHECKS_SECRETS)
59
- backend.editorialChecks.addEnvironment(name, secret(name));
60
- lambda.addToRolePolicy(new PolicyStatement({
61
- effect: Effect.ALLOW,
62
- actions: ["ssm:GetParameter", "ssm:GetParameters"],
63
- resources: editorialChecksSecretParameters(stack.region, stack.account, (process.env.AWS_APP_ID ?? "").trim()),
64
- }));
65
- lambda.addToRolePolicy(new PolicyStatement({
66
- effect: Effect.ALLOW,
67
- actions: ["appsync:GraphQL"],
68
- resources: EDITORIAL_CHECKS_FUNCTION_FIELDS.map((field) => `arn:aws:appsync:${stack.region}:${stack.account}:apis/${context.graphqlApiId}/types/${field}`),
69
- }));
70
- },
71
- };