@anthusai/papyrus 1.0.0-next.9 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/amplify/auth/prospectus-google-client.js +66 -0
- package/amplify/auth/prospectus-google-client.ts +71 -0
- package/amplify/auth/redirect-urls.js +54 -0
- package/amplify/auth/redirect-urls.ts +66 -0
- package/amplify/auth/resource.js +23 -5
- package/amplify/auth/resource.ts +31 -5
- package/amplify/data/resource.js +42 -80
- package/amplify/data/resource.ts +42 -80
- package/amplify/data/schema.js +45 -62
- package/amplify/data/schema.ts +47 -62
- package/amplify/functions/category-action/handler.ts +5 -3
- package/amplify/functions/console-chat-responder/py/execute_tactus_runner.py +0 -10
- package/amplify/functions/console-chat-responder/resource.js +0 -7
- package/amplify/functions/console-chat-responder/resource.ts +0 -8
- package/amplify/functions/console-chat-responder/src/main.rs +0 -9
- package/amplify/functions/content-actions/handler.py +143 -1
- package/amplify/functions/content-actions/requirements.txt +2 -1
- package/amplify/functions/content-actions/resource.js +6 -1
- package/amplify/functions/content-actions/resource.ts +9 -2
- package/amplify/functions/email-submission-processor/handler.py +3 -1
- package/amplify/functions/renditions/handler.py +120 -0
- package/amplify/functions/renditions/requirements.txt +4 -0
- package/amplify/functions/ses-inbound-receive/handler.ts +32 -4
- package/amplify/functions/shared/email-submission.ts +109 -1
- package/amplify/functions/shared/python-bundle.js +42 -2
- package/amplify/functions/shared/python-bundle.ts +47 -2
- package/amplify/functions/shared/reference-curation-metadata.ts +29 -0
- package/amplify/inbound-email/ses-intake.js +86 -0
- package/amplify/inbound-email/ses-intake.ts +110 -0
- package/amplify/plugins/registry.js +19 -0
- package/amplify/plugins/registry.ts +23 -0
- package/amplify/plugins/signup/function/handler.py +200 -0
- package/amplify/plugins/signup/function/resource.js +27 -0
- package/amplify/plugins/signup/function/resource.ts +35 -0
- package/amplify/plugins/signup/papyrus.plugin.js +59 -0
- package/amplify/plugins/signup/papyrus.plugin.ts +74 -0
- package/amplify/plugins/signup/schema.js +40 -0
- package/amplify/plugins/signup/schema.ts +41 -0
- package/amplify/plugins/signup/waf.js +48 -0
- package/amplify/plugins/signup/waf.ts +51 -0
- package/amplify/plugins/types.js +1 -0
- package/amplify/plugins/types.ts +39 -0
- package/amplify/plugins/wire.js +24 -0
- package/amplify/plugins/wire.ts +26 -0
- package/amplify/publication/default-publication.js +18 -0
- package/amplify/publication/default-publication.ts +20 -0
- package/amplify/publication/invalidation-alarm.js +26 -0
- package/amplify/publication/invalidation-alarm.ts +30 -0
- package/amplify/publication/redirect-and-index.js +37 -0
- package/amplify/publication/renditions-function.js +74 -0
- package/amplify/publication/renditions-function.ts +112 -0
- package/amplify/publication/renditions-settings.js +51 -0
- package/amplify/publication/renditions-settings.ts +58 -0
- package/amplify/publication/reproject-on-deploy.js +73 -0
- package/amplify/publication/reproject-on-deploy.ts +78 -0
- package/amplify/publication/s3-projection-settings.js +67 -0
- package/amplify/publication/s3-projection-settings.ts +101 -0
- package/amplify/publication/s3-projection.js +151 -0
- package/amplify/publication/s3-projection.ts +201 -0
- package/amplify/resolver-waves.js +26 -0
- package/amplify/resolver-waves.ts +34 -0
- package/amplify/revalidate-invalidation-settings.js +30 -0
- package/amplify/revalidate-invalidation-settings.ts +35 -0
- package/amplify/revalidate-secret-policy.js +13 -0
- package/amplify/revalidate-secret-policy.ts +19 -0
- package/amplify/site-backend-config.js +65 -1
- package/amplify/site-backend-config.ts +153 -2
- package/amplify/site-backend-names.js +103 -0
- package/amplify/site-backend-names.ts +166 -0
- package/amplify/site-backend.js +150 -176
- package/amplify/site-backend.ts +189 -201
- package/amplify/storage-backups/construct.js +31 -0
- package/amplify/storage-backups/construct.ts +47 -0
- package/app/[year]/[month]/[day]/[articleSlug]/page.tsx +8 -1
- package/app/[year]/[month]/[day]/edition-route-page.tsx +2 -0
- package/app/[year]/[month]/[day]/page/[pageNumber]/page.tsx +6 -1
- package/app/[year]/[month]/[day]/page.tsx +1 -1
- package/app/[year]/[month]/[day]/section/[sectionKey]/page.tsx +6 -1
- package/app/api/archive/editions/route.ts +1 -1
- package/app/api/auth/prospectus/callback/route.ts +9 -0
- package/app/api/auth/prospectus/selection/route.ts +9 -0
- package/app/api/auth/prospectus/session/route.ts +9 -0
- package/app/api/auth/prospectus/sign-in/route.ts +9 -0
- package/app/api/auth/prospectus/sign-out/route.ts +9 -0
- package/app/api/cyclotron/priming-proof/route.ts +11 -0
- package/app/api/media/[...path]/route.ts +5 -16
- package/app/api/revalidate/route.ts +15 -7
- package/app/archive/page.tsx +1 -1
- package/app/articles/[slug]/page.tsx +7 -5
- package/app/blog-rhythm.css +278 -0
- package/app/cyclotron/page.tsx +13 -0
- package/app/globals.css +2 -0
- package/app/layout.tsx +16 -0
- package/app/newsroom/[section]/[...selection]/page.tsx +9 -6
- package/app/newsroom/[section]/page.tsx +6 -3
- package/app/newsroom/layout.tsx +4 -9
- package/app/newsroom/settings/page.tsx +6 -0
- package/app/newsroom/work/page.tsx +10 -0
- package/app/page.tsx +22 -8
- package/app/robots.ts +2 -5
- package/app/tailwind.css +1 -6
- package/components/amplify-client-provider.tsx +5 -22
- package/components/archive-shell.tsx +2 -22
- package/components/article-video.tsx +152 -5
- package/components/blog-page-background.tsx +23 -6
- package/components/news-desk-page.tsx +4 -15
- package/components/news-desk-taxonomy-client.ts +90 -3
- package/components/newspaper.tsx +6 -2
- package/components/newsroom-access-gate.tsx +2 -1
- package/components/newsroom-board-view.tsx +99 -0
- package/components/newsroom-client-shell.tsx +12 -0
- package/components/newsroom-curation-provider.tsx +17 -0
- package/components/newsroom-fonts/playfair-display-700.ttf +0 -0
- package/components/newsroom-fonts/playfair-display-900.ttf +0 -0
- package/components/newsroom-fonts/playfair-display-OFL.txt +93 -0
- package/components/newsroom-fonts/plus-jakarta-sans-400.ttf +0 -0
- package/components/newsroom-fonts/plus-jakarta-sans-600.ttf +0 -0
- package/components/newsroom-fonts/plus-jakarta-sans-OFL.txt +93 -0
- package/components/newsroom-newsprint-board.css +48 -0
- package/components/newsroom-ops-overview.tsx +28 -11
- package/components/newsroom-ops-shell.tsx +7 -1
- package/components/newsroom-organizer-shell.tsx +130 -0
- package/components/newsroom-organizer.css +63 -0
- package/components/newsroom-references-view.tsx +92 -8
- package/components/papyrus-console-shell.tsx +4 -2
- package/components/pictogram-figure.tsx +9 -2
- package/components/presentation-header.tsx +135 -0
- package/components/presentation-rhythm-hrule.tsx +17 -0
- package/components/priming-proof-page.tsx +94 -0
- package/components/publication-cyclotron-panel.tsx +57 -0
- package/components/reader-auth-control.tsx +8 -5
- package/components/reference-curation-controls.tsx +77 -0
- package/components/reference-cyclotron-status.tsx +109 -0
- package/components/reference-priming.tsx +18 -0
- package/components/reference-relevance-review.tsx +75 -0
- package/components/settings-page.tsx +2 -1
- package/components/signup-entries-panel.tsx +94 -0
- package/components/topic-steering-workspace.tsx +78 -8
- package/components/use-blog-header-obstacles.ts +81 -0
- package/components/use-brand-fonts-ready.ts +28 -0
- package/components/use-near-viewport.ts +30 -0
- package/components/use-rhythm-overlay.ts +29 -0
- package/infra/amplify-app-shell.js +166 -27
- package/infra/amplify-app-shell.ts +180 -31
- package/infra/build-specs.js +23 -7
- package/infra/build-specs.ts +27 -10
- package/infra/site-config.js +248 -36
- package/infra/site-config.ts +313 -51
- package/lib/amplify-outputs-path.ts +5 -1
- package/lib/amplify-server-runtime.ts +36 -1
- package/lib/approved-priming-proof-reports.ts +6 -0
- package/lib/blog-feature-solver.ts +459 -0
- package/lib/blog-rhythm.ts +134 -0
- package/lib/brand-fonts-watch.ts +43 -0
- package/lib/brand-fonts.ts +112 -0
- package/lib/cached-content-repository.ts +12 -0
- package/lib/category-repository.ts +43 -93
- package/lib/content-item-lifecycle.ts +55 -0
- package/lib/content-repository.ts +3 -0
- package/lib/content-types.ts +4 -0
- package/lib/curation-client.ts +61 -0
- package/lib/edition-routes.ts +31 -29
- package/lib/graphql-content-repository.ts +56 -22
- package/lib/media-route-response.ts +45 -0
- package/lib/newspaper-layout.ts +3 -2
- package/lib/newsroom-base-path.ts +12 -3
- package/lib/newsroom-board.ts +99 -0
- package/lib/newsroom-category-drilldown.ts +3 -2
- package/lib/newsroom-forum-routes.ts +6 -4
- package/lib/newsroom-index-filters.ts +14 -10
- package/lib/newsroom-nav.ts +3 -1
- package/lib/newsroom-organizer-nav.ts +37 -0
- package/lib/newsroom-section-routing.ts +20 -0
- package/lib/oauth-redirect-priority.ts +40 -0
- package/lib/papyrus-web-locations.ts +7 -6
- package/lib/plugin-settings.ts +11 -0
- package/lib/presentation-footer.ts +3 -2
- package/lib/pretext-layout.ts +12 -3
- package/lib/priming-proof-report.ts +90 -0
- package/lib/prospectus-publication-access.ts +53 -0
- package/lib/prospectus-session.ts +196 -0
- package/lib/prospectus-sign-in-routes.ts +284 -0
- package/lib/prospectus-site-identity.ts +303 -0
- package/lib/publication-cyclotron.ts +74 -0
- package/lib/rate-limit-retry.ts +55 -0
- package/lib/reader-base-path.ts +24 -0
- package/lib/reader-cache-lifetime.ts +5 -0
- package/lib/reader-static-params.ts +85 -4
- package/lib/reader-storage-url.ts +9 -12
- package/lib/reference-policy.ts +5 -0
- package/lib/relevance-decisions.ts +103 -0
- package/lib/relevance-status.ts +63 -0
- package/lib/renderer.ts +7 -0
- package/lib/revalidate-prewarm.ts +53 -0
- package/lib/revalidate-secret.ts +59 -0
- package/lib/robots-policy.ts +14 -0
- package/lib/root-route-redirect.ts +16 -0
- package/lib/semantic-graph.ts +7 -0
- package/lib/shared-credentials-provider.ts +61 -0
- package/lib/signup-csv.ts +24 -0
- package/lib/site-brand.ts +59 -0
- package/lib/staging-gated-path.ts +23 -0
- package/lib/staging-preview-object.ts +21 -5
- package/lib/test-editor-override.ts +4 -0
- package/lib/video-loading.ts +22 -0
- package/lib/video-script.ts +14 -0
- package/middleware.ts +11 -19
- package/package.json +73 -8
- package/renderers/pretext/article-page.tsx +39 -3
- package/renderers/pretext/presentation-shared.tsx +113 -0
- package/renderers/pretext/presentation-shell.tsx +15 -102
- package/renderers/pretext/rhythm-article-page.tsx +165 -0
- package/renderers/pretext/rhythm-blog-presentation.tsx +279 -0
- package/renderers/pretext/rhythm-shell-style.ts +35 -0
- package/routes.manifest.json +123 -12
- package/src/sync.mjs +30 -6
- package/src/with-papyrus.d.mts +9 -0
- package/src/with-papyrus.mjs +48 -3
- package/amplify/functions/graphql-jwt-authorizer/handler.ts +0 -193
- package/amplify/functions/graphql-jwt-authorizer/resource.js +0 -14
- package/amplify/functions/graphql-jwt-authorizer/resource.ts +0 -15
- package/components/ai-elements/message.tsx +0 -360
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { withRateLimitRetry, type RateLimitRetryOptions } from "./rate-limit-retry";
|
|
2
|
+
|
|
3
|
+
export const CREDENTIAL_EXPIRY_SAFETY_MILLISECONDS = 5 * 60 * 1000;
|
|
4
|
+
|
|
5
|
+
export type CredentialsAndIdentityIdLike = {
|
|
6
|
+
credentials: { expiration?: Date };
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export type CredentialsProviderLike<Options, Result extends CredentialsAndIdentityIdLike> = {
|
|
10
|
+
getCredentialsAndIdentityId(options: Options): Promise<Result | undefined>;
|
|
11
|
+
clearCredentialsAndIdentityId(): void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export type SharedCredentialsProviderOptions = {
|
|
15
|
+
retry?: RateLimitRetryOptions;
|
|
16
|
+
expirySafetyMilliseconds?: number;
|
|
17
|
+
now?: () => number;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export function createSharedCredentialsProvider<
|
|
21
|
+
Options extends { forceRefresh?: boolean },
|
|
22
|
+
Result extends CredentialsAndIdentityIdLike,
|
|
23
|
+
>(
|
|
24
|
+
inner: CredentialsProviderLike<Options, Result>,
|
|
25
|
+
settings: SharedCredentialsProviderOptions = {},
|
|
26
|
+
): CredentialsProviderLike<Options, Result> {
|
|
27
|
+
const now = settings.now ?? Date.now;
|
|
28
|
+
const safety = settings.expirySafetyMilliseconds ?? CREDENTIAL_EXPIRY_SAFETY_MILLISECONDS;
|
|
29
|
+
let cached: Result | undefined;
|
|
30
|
+
let inflight: Promise<Result | undefined> | undefined;
|
|
31
|
+
|
|
32
|
+
const isFresh = (value: Result | undefined): value is Result => {
|
|
33
|
+
if (!value) return false;
|
|
34
|
+
const expiration = value.credentials.expiration;
|
|
35
|
+
return !expiration || expiration.getTime() - safety > now();
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
return {
|
|
39
|
+
async getCredentialsAndIdentityId(options) {
|
|
40
|
+
if (!options?.forceRefresh && isFresh(cached)) return cached;
|
|
41
|
+
if (inflight) return inflight;
|
|
42
|
+
const request = withRateLimitRetry(() => inner.getCredentialsAndIdentityId(options), {
|
|
43
|
+
now,
|
|
44
|
+
...settings.retry,
|
|
45
|
+
})
|
|
46
|
+
.then((result) => {
|
|
47
|
+
cached = result;
|
|
48
|
+
return result;
|
|
49
|
+
})
|
|
50
|
+
.finally(() => {
|
|
51
|
+
inflight = undefined;
|
|
52
|
+
});
|
|
53
|
+
inflight = request;
|
|
54
|
+
return request;
|
|
55
|
+
},
|
|
56
|
+
clearCredentialsAndIdentityId() {
|
|
57
|
+
cached = undefined;
|
|
58
|
+
inner.clearCredentialsAndIdentityId();
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export type SignupEntryRecord = {
|
|
2
|
+
id: string;
|
|
3
|
+
form: string;
|
|
4
|
+
value: string;
|
|
5
|
+
submittedAt: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const SIGNUP_CSV_HEADER = ["form", "value", "submittedAt"] as const;
|
|
9
|
+
const FORMULA_STARTS = new Set(["=", "+", "-", "@", "\t", "\r"]);
|
|
10
|
+
|
|
11
|
+
/** A spreadsheet runs a cell that starts with one of these as a formula; a leading quote makes it text. */
|
|
12
|
+
export function neutralizeFormula(cell: string): string {
|
|
13
|
+
return cell !== "" && FORMULA_STARTS.has(cell[0]) ? `'${cell}` : cell;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function csvCell(cell: string): string {
|
|
17
|
+
const safe = neutralizeFormula(cell);
|
|
18
|
+
return /[",\r\n]/.test(safe) ? `"${safe.replace(/"/g, '""')}"` : safe;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function signupEntriesToCsv(entries: SignupEntryRecord[]): string {
|
|
22
|
+
const rows = entries.map((entry) => SIGNUP_CSV_HEADER.map((column) => csvCell(String(entry[column] ?? ""))).join(","));
|
|
23
|
+
return `${[SIGNUP_CSV_HEADER.join(","), ...rows].join("\r\n")}\r\n`;
|
|
24
|
+
}
|
package/lib/site-brand.ts
CHANGED
|
@@ -2,6 +2,7 @@ import type { ComponentType } from "react";
|
|
|
2
2
|
import type { EditionPresentationFormat } from "./content-types";
|
|
3
3
|
import type { Article, ArticleVideoAsset } from "./articles";
|
|
4
4
|
import type { BlogPageBackgroundProps } from "../components/blog-page-background";
|
|
5
|
+
import type { SiteBrandFont } from "./brand-fonts";
|
|
5
6
|
import type { PictogramFigureProps } from "../components/pictogram-figure";
|
|
6
7
|
import papyrusSite from "papyrus-site";
|
|
7
8
|
import {
|
|
@@ -24,6 +25,23 @@ export type SiteBrandComponents = {
|
|
|
24
25
|
BlogPageBackground?: ComponentType<BlogPageBackgroundProps>;
|
|
25
26
|
};
|
|
26
27
|
|
|
28
|
+
/**
|
|
29
|
+
* One line of a brand's header tagline: an emphasized lead and a plain tail,
|
|
30
|
+
* e.g. `{ emphasis: "Practical advice", tail: "for staying secure" }`.
|
|
31
|
+
*/
|
|
32
|
+
export type SiteBrandTaglineLine = {
|
|
33
|
+
emphasis: string;
|
|
34
|
+
tail: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Blog presentation layout. `"classic"` (the default) is the original blog
|
|
39
|
+
* layout. `"rhythm"` snaps every height and gap to the vertical rhythm grid,
|
|
40
|
+
* floats featured images on the grid, draws rhythm rules between items, adds
|
|
41
|
+
* the eyebrow/tagline header and the rhythm overlay hotkey (Ctrl+=).
|
|
42
|
+
*/
|
|
43
|
+
export type SiteBrandBlogLayout = "classic" | "rhythm";
|
|
44
|
+
|
|
27
45
|
/** Default scenario content a brand supplies for the layout lab. */
|
|
28
46
|
export type SiteBrandDemoEdition = {
|
|
29
47
|
title: string;
|
|
@@ -46,6 +64,19 @@ export type SiteBrandVideo = {
|
|
|
46
64
|
rhythm?: Record<string, unknown>;
|
|
47
65
|
};
|
|
48
66
|
|
|
67
|
+
/**
|
|
68
|
+
* The publication's name for its one content item. A content item keeps one
|
|
69
|
+
* identity and one lifecycle from idea through research, reporting,
|
|
70
|
+
* copywriting and publication; only the word editors see changes per
|
|
71
|
+
* publication (for example Story, Article or Post).
|
|
72
|
+
*/
|
|
73
|
+
export type ContentItemName = {
|
|
74
|
+
singular: string;
|
|
75
|
+
plural: string;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const DEFAULT_CONTENT_ITEM_NAME: ContentItemName = { singular: "Story", plural: "Stories" };
|
|
79
|
+
|
|
49
80
|
export type SiteBrand = {
|
|
50
81
|
id: SiteBrandId;
|
|
51
82
|
appTitle: string;
|
|
@@ -53,8 +84,14 @@ export type SiteBrand = {
|
|
|
53
84
|
mastheadTitle: string;
|
|
54
85
|
mastheadSubtitle: string;
|
|
55
86
|
mastheadTagline?: string;
|
|
87
|
+
/** Rhythm blog layout only: small line above the masthead title, e.g. "Acme Research". The first word is emphasized. */
|
|
88
|
+
mastheadEyebrow?: string;
|
|
89
|
+
/** Rhythm blog layout only: structured tagline; `mastheadTagline` stays the plain-text fallback. */
|
|
90
|
+
mastheadTaglineLines?: SiteBrandTaglineLine[];
|
|
56
91
|
backToHomeLabel: string;
|
|
57
92
|
articleTitleSuffix: string;
|
|
93
|
+
/** Defaults to Story / Stories, the newsroom term. */
|
|
94
|
+
contentItemName?: ContentItemName;
|
|
58
95
|
placeholderByline: string;
|
|
59
96
|
defaultPresentation: EditionPresentationFormat;
|
|
60
97
|
forcedPresentation?: EditionPresentationFormat;
|
|
@@ -80,13 +117,31 @@ export type SiteBrand = {
|
|
|
80
117
|
rootRoute?: RootRouteConfig;
|
|
81
118
|
/** Public URL prefix for newsroom routes. Default `/newsroom`; use `""` on a CMS-only subdomain. */
|
|
82
119
|
newsroomBasePath?: string;
|
|
120
|
+
/** Public URL prefix for the Pretext reader (home, editions, articles, archive, settings). Default `""`; e.g. `/information`. */
|
|
121
|
+
readerBasePath?: string;
|
|
83
122
|
opsChrome: OpsChrome;
|
|
123
|
+
/** Opt-in CMS viewport layout; independent of the public reader renderer/theme. */
|
|
124
|
+
newsroomLayout?: "organizer";
|
|
84
125
|
corpusKey: string;
|
|
85
126
|
steeringConfigPath: string;
|
|
86
127
|
newsroomSectionsConfigPath: string;
|
|
87
128
|
analysisProfilesPath: string;
|
|
88
129
|
publicationName: string;
|
|
89
130
|
components?: SiteBrandComponents;
|
|
131
|
+
/**
|
|
132
|
+
* Video player chrome. `"native"` (default) is the browser's controls;
|
|
133
|
+
* `"framed"` wraps the media in `.article-video__media` and renders a
|
|
134
|
+
* "Play Video" button with a seek bar (`.article-video__cta*`), styled by the publication CSS.
|
|
135
|
+
*/
|
|
136
|
+
videoPlayer?: "native" | "framed";
|
|
137
|
+
/** Blog presentation layout. Default `"classic"`. See `SiteBrandBlogLayout`. */
|
|
138
|
+
blogLayout?: SiteBrandBlogLayout;
|
|
139
|
+
/**
|
|
140
|
+
* Brand font slot: families the root layout loads (Google Fonts stylesheet
|
|
141
|
+
* or self-hosted files) and exposes as CSS custom properties. See
|
|
142
|
+
* `lib/brand-fonts.ts` and docs/brand-slots.md.
|
|
143
|
+
*/
|
|
144
|
+
fonts?: SiteBrandFont[];
|
|
90
145
|
demoEdition?: SiteBrandDemoEdition;
|
|
91
146
|
video?: SiteBrandVideo;
|
|
92
147
|
};
|
|
@@ -164,6 +219,10 @@ export function getSiteBrand(id: SiteBrandId = resolveSiteBrandId()): SiteBrand
|
|
|
164
219
|
|
|
165
220
|
export const SITE_BRAND = getSiteBrand();
|
|
166
221
|
|
|
222
|
+
export function getContentItemName(brand: SiteBrand = SITE_BRAND): ContentItemName {
|
|
223
|
+
return brand.contentItemName ?? DEFAULT_CONTENT_ITEM_NAME;
|
|
224
|
+
}
|
|
225
|
+
|
|
167
226
|
/** Root-route config for a brand, defaulting to `{ kind: "reader" }`. */
|
|
168
227
|
export function getRootRoute(brand: SiteBrand = SITE_BRAND): RootRouteConfig {
|
|
169
228
|
return brand.rootRoute ?? { kind: "reader" };
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { normalizeReaderBasePath } from "./reader-base-path";
|
|
2
|
+
|
|
3
|
+
function isStaticOrApiPath(pathname: string): boolean {
|
|
4
|
+
return (
|
|
5
|
+
pathname.startsWith("/_next")
|
|
6
|
+
|| pathname.startsWith("/api")
|
|
7
|
+
|| pathname === "/favicon.ico"
|
|
8
|
+
|| pathname.startsWith("/icon")
|
|
9
|
+
|| /\.[a-zA-Z0-9]+$/.test(pathname)
|
|
10
|
+
);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export { isStaticOrApiPath };
|
|
14
|
+
|
|
15
|
+
export function isStagingGatedPath(pathname: string, readerBasePath: string = "", newsroomAtRoot: boolean = false): boolean {
|
|
16
|
+
if (newsroomAtRoot) return false;
|
|
17
|
+
if (isStaticOrApiPath(pathname)) return false;
|
|
18
|
+
if (pathname === "/robots.txt") return false;
|
|
19
|
+
if (pathname === "/newsroom" || pathname.startsWith("/newsroom/")) return false;
|
|
20
|
+
const base = normalizeReaderBasePath(readerBasePath);
|
|
21
|
+
if (base) return pathname === base || pathname.startsWith(`${base}/`);
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
@@ -8,6 +8,7 @@ export const PREVIEW_KEY_PREFIX = "preview/";
|
|
|
8
8
|
|
|
9
9
|
const PRESIGN_SECONDS = 60;
|
|
10
10
|
const NOT_FOUND_ERROR_NAMES = ["NotFound", "NoSuchKey"];
|
|
11
|
+
const FORBIDDEN_ERROR_NAMES = ["Forbidden", "AccessDenied"];
|
|
11
12
|
const PREVIEW_EXCLUDED_PREFIXES = ["/newsroom", "/api", "/_next", PREVIEW_ROUTE_PREFIX];
|
|
12
13
|
|
|
13
14
|
export function isStaticPreviewEnabled(environment: Record<string, string | undefined> = process.env): boolean {
|
|
@@ -32,13 +33,14 @@ export function previewCandidateKeys(requestPath: string): string[] | null {
|
|
|
32
33
|
return [base, `${base}.html`, `${base}/index.html`];
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
export function shouldRewriteToPreview(pathname: string): boolean {
|
|
36
|
+
export function shouldRewriteToPreview(pathname: string, newsroomAtRoot: boolean = false): boolean {
|
|
36
37
|
if (pathname === "/favicon.ico" || pathname === "/robots.txt" || pathname.startsWith("/icon")) return false;
|
|
37
|
-
|
|
38
|
+
if (PREVIEW_EXCLUDED_PREFIXES.some((prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`))) return false;
|
|
39
|
+
return !newsroomAtRoot || pathname.endsWith(".html");
|
|
38
40
|
}
|
|
39
41
|
|
|
40
|
-
export function isPreviewGatedPath(pathname: string): boolean {
|
|
41
|
-
return shouldRewriteToPreview(pathname) || pathname === PREVIEW_ROUTE_PREFIX || pathname.startsWith(`${PREVIEW_ROUTE_PREFIX}/`);
|
|
42
|
+
export function isPreviewGatedPath(pathname: string, newsroomAtRoot: boolean = false): boolean {
|
|
43
|
+
return shouldRewriteToPreview(pathname, newsroomAtRoot) || pathname === PREVIEW_ROUTE_PREFIX || pathname.startsWith(`${PREVIEW_ROUTE_PREFIX}/`);
|
|
42
44
|
}
|
|
43
45
|
|
|
44
46
|
export function previewRewritePathname(pathname: string): string {
|
|
@@ -54,6 +56,12 @@ function isNotFoundError(error: unknown): boolean {
|
|
|
54
56
|
return NOT_FOUND_ERROR_NAMES.includes(name);
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
function isForbiddenError(error: unknown): boolean {
|
|
60
|
+
const candidate = error as { name?: string; $metadata?: { httpStatusCode?: number }; metadata?: { httpStatusCode?: number } } | null;
|
|
61
|
+
const status = candidate?.$metadata?.httpStatusCode ?? candidate?.metadata?.httpStatusCode;
|
|
62
|
+
return status === 403 || FORBIDDEN_ERROR_NAMES.includes(candidate?.name ?? "");
|
|
63
|
+
}
|
|
64
|
+
|
|
57
65
|
async function presignFirstExistingKey(candidateKeys: string[]): Promise<URL | null> {
|
|
58
66
|
const { runWithAmplifyServerContext } = getAmplifyServerRuntime();
|
|
59
67
|
return runWithAmplifyServerContext({
|
|
@@ -83,7 +91,15 @@ export async function streamPreviewObject(pathname: string): Promise<Response> {
|
|
|
83
91
|
if (!isStaticPreviewEnabled()) return notFound();
|
|
84
92
|
const candidateKeys = previewCandidateKeys(previewRequestPath(pathname));
|
|
85
93
|
if (!candidateKeys) return notFound();
|
|
86
|
-
|
|
94
|
+
let presigned: URL | null;
|
|
95
|
+
try {
|
|
96
|
+
presigned = await presignFirstExistingKey(candidateKeys);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
if (isForbiddenError(error)) {
|
|
99
|
+
return new Response("Staging preview is limited to editors and admins.", { status: 403, headers: { "Cache-Control": "private, no-store" } });
|
|
100
|
+
}
|
|
101
|
+
throw error;
|
|
102
|
+
}
|
|
87
103
|
if (!presigned) return notFound();
|
|
88
104
|
const upstream = await fetch(presigned);
|
|
89
105
|
if (!upstream.ok || !upstream.body) return notFound();
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export type VideoPreload = "none" | "metadata";
|
|
2
|
+
|
|
3
|
+
export type VideoLoadingPlan = {
|
|
4
|
+
attachSource: boolean;
|
|
5
|
+
preload: VideoPreload;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type VideoLoadingInput = {
|
|
9
|
+
hasHydrated: boolean;
|
|
10
|
+
isNearViewport: boolean;
|
|
11
|
+
hasPoster: boolean;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export function planVideoLoading({ hasHydrated, isNearViewport, hasPoster }: VideoLoadingInput): VideoLoadingPlan {
|
|
15
|
+
const attachSource = hasHydrated && isNearViewport;
|
|
16
|
+
const preload: VideoPreload = attachSource && !hasPoster ? "metadata" : "none";
|
|
17
|
+
return { attachSource, preload };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function videoElementKey(attachSource: boolean, resolvedSource: string): string {
|
|
21
|
+
return attachSource ? resolvedSource : "unattached";
|
|
22
|
+
}
|
package/lib/video-script.ts
CHANGED
|
@@ -21,6 +21,20 @@ export type VideoScriptRef = {
|
|
|
21
21
|
targetKind: VideoScriptTargetKind;
|
|
22
22
|
};
|
|
23
23
|
|
|
24
|
+
export const EDITION_OVERVIEW_VIDEO_KEY = "edition-overview";
|
|
25
|
+
|
|
26
|
+
export function collectVideoScriptTargets(
|
|
27
|
+
items: ReadonlyArray<{ slug: string; video?: unknown }>,
|
|
28
|
+
hasEditionVideo: boolean,
|
|
29
|
+
): string[] {
|
|
30
|
+
const targets = new Set<string>();
|
|
31
|
+
if (hasEditionVideo) targets.add(EDITION_OVERVIEW_VIDEO_KEY);
|
|
32
|
+
for (const item of items) {
|
|
33
|
+
if (item.video) targets.add(item.slug);
|
|
34
|
+
}
|
|
35
|
+
return [...targets];
|
|
36
|
+
}
|
|
37
|
+
|
|
24
38
|
export function videomlItemSlug(targetSlug: string): string {
|
|
25
39
|
return `${targetSlug}--videoml`;
|
|
26
40
|
}
|
package/middleware.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { NextRequest } from "next/server";
|
|
2
2
|
import { NextResponse } from "next/server";
|
|
3
3
|
import { getSiteBrand } from "./lib/site-brand";
|
|
4
|
+
import { newsroomHref } from "./lib/newsroom-base-path";
|
|
5
|
+
import { getReaderBasePath } from "./lib/reader-base-path";
|
|
6
|
+
import { isStagingGatedPath, isStaticOrApiPath } from "./lib/staging-gated-path";
|
|
4
7
|
import { getSiteEnv, isIndexable } from "./lib/site-env";
|
|
5
8
|
import { getStagingAccess } from "./lib/staging-gate";
|
|
6
9
|
import {
|
|
@@ -15,25 +18,12 @@ function usesNewsroomRootPaths(): boolean {
|
|
|
15
18
|
return brand.rootRoute?.kind === "newsroom" && brand.newsroomBasePath === "";
|
|
16
19
|
}
|
|
17
20
|
|
|
18
|
-
function
|
|
19
|
-
return (
|
|
20
|
-
pathname.startsWith("/_next")
|
|
21
|
-
|| pathname.startsWith("/api")
|
|
22
|
-
|| pathname === "/favicon.ico"
|
|
23
|
-
|| pathname.startsWith("/icon")
|
|
24
|
-
|| /\.[a-zA-Z0-9]+$/.test(pathname)
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function isStagingGatedPath(pathname: string): boolean {
|
|
29
|
-
if (isStaticOrApiPath(pathname)) return false;
|
|
30
|
-
if (pathname === "/robots.txt") return false;
|
|
31
|
-
if (pathname === "/newsroom" || pathname.startsWith("/newsroom/")) return false;
|
|
32
|
-
return true;
|
|
21
|
+
function isStagingGatedPathForBrand(pathname: string): boolean {
|
|
22
|
+
return isStagingGatedPath(pathname, getReaderBasePath(), usesNewsroomRootPaths());
|
|
33
23
|
}
|
|
34
24
|
|
|
35
25
|
function routeRequest(request: NextRequest): NextResponse {
|
|
36
|
-
if (isStaticPreviewEnabled() && shouldRewriteToPreview(request.nextUrl.pathname)) {
|
|
26
|
+
if (isStaticPreviewEnabled() && shouldRewriteToPreview(request.nextUrl.pathname, usesNewsroomRootPaths())) {
|
|
37
27
|
const rewriteUrl = request.nextUrl.clone();
|
|
38
28
|
rewriteUrl.pathname = previewRewritePathname(request.nextUrl.pathname);
|
|
39
29
|
return NextResponse.rewrite(rewriteUrl);
|
|
@@ -48,7 +38,7 @@ function routeRequest(request: NextRequest): NextResponse {
|
|
|
48
38
|
}
|
|
49
39
|
|
|
50
40
|
if (pathname === "/newsroom" || pathname === "/newsroom/") {
|
|
51
|
-
return NextResponse.redirect(new URL(
|
|
41
|
+
return NextResponse.redirect(new URL(`/${request.nextUrl.search}`, request.url));
|
|
52
42
|
}
|
|
53
43
|
if (pathname.startsWith("/newsroom/")) {
|
|
54
44
|
const target = pathname.slice("/newsroom".length) || "/";
|
|
@@ -71,12 +61,14 @@ function routeRequest(request: NextRequest): NextResponse {
|
|
|
71
61
|
export async function middleware(request: NextRequest): Promise<NextResponse> {
|
|
72
62
|
let sessionResponse: NextResponse | null = null;
|
|
73
63
|
const { pathname } = request.nextUrl;
|
|
74
|
-
const gated = isStaticPreviewEnabled()
|
|
64
|
+
const gated = isStaticPreviewEnabled()
|
|
65
|
+
? isPreviewGatedPath(pathname, usesNewsroomRootPaths())
|
|
66
|
+
: isStagingGatedPathForBrand(pathname);
|
|
75
67
|
if (getSiteEnv() === "staging" && gated) {
|
|
76
68
|
sessionResponse = NextResponse.next();
|
|
77
69
|
const access = await getStagingAccess(request, sessionResponse);
|
|
78
70
|
if (access === "anonymous") {
|
|
79
|
-
return withRobotsHeader(NextResponse.redirect(new URL(
|
|
71
|
+
return withRobotsHeader(NextResponse.redirect(new URL(newsroomHref(), request.url)));
|
|
80
72
|
}
|
|
81
73
|
if (access === "forbidden") {
|
|
82
74
|
return withRobotsHeader(new NextResponse("Staging is limited to editors and admins.", { status: 403 }));
|
package/package.json
CHANGED
|
@@ -65,7 +65,6 @@
|
|
|
65
65
|
"default": "./infra/index.js"
|
|
66
66
|
},
|
|
67
67
|
"./components/ai-elements/conversation": "./components/ai-elements/conversation.tsx",
|
|
68
|
-
"./components/ai-elements/message": "./components/ai-elements/message.tsx",
|
|
69
68
|
"./components/ai-elements/model-selector": "./components/ai-elements/model-selector.tsx",
|
|
70
69
|
"./components/ai-elements/prompt-input": "./components/ai-elements/prompt-input.tsx",
|
|
71
70
|
"./components/ai-elements/shimmer": "./components/ai-elements/shimmer.tsx",
|
|
@@ -86,19 +85,32 @@
|
|
|
86
85
|
"./components/newsroom-article-editor": "./components/newsroom-article-editor.tsx",
|
|
87
86
|
"./components/newsroom-articles-view": "./components/newsroom-articles-view.tsx",
|
|
88
87
|
"./components/newsroom-assignments-view": "./components/newsroom-assignments-view.tsx",
|
|
88
|
+
"./components/newsroom-board-view": "./components/newsroom-board-view.tsx",
|
|
89
|
+
"./components/newsroom-client-shell": "./components/newsroom-client-shell.tsx",
|
|
90
|
+
"./components/newsroom-curation-provider": "./components/newsroom-curation-provider.tsx",
|
|
89
91
|
"./components/newsroom-ops-overview": "./components/newsroom-ops-overview.tsx",
|
|
90
92
|
"./components/newsroom-ops-shell": "./components/newsroom-ops-shell.tsx",
|
|
93
|
+
"./components/newsroom-organizer-shell": "./components/newsroom-organizer-shell.tsx",
|
|
91
94
|
"./components/newsroom-references-view": "./components/newsroom-references-view.tsx",
|
|
92
95
|
"./components/newsroom-topics-view": "./components/newsroom-topics-view.tsx",
|
|
93
96
|
"./components/papyrus-console-shell": "./components/papyrus-console-shell.tsx",
|
|
94
97
|
"./components/pictogram-figure": "./components/pictogram-figure.tsx",
|
|
95
98
|
"./components/presentation-footer": "./components/presentation-footer.tsx",
|
|
99
|
+
"./components/presentation-header": "./components/presentation-header.tsx",
|
|
100
|
+
"./components/presentation-rhythm-hrule": "./components/presentation-rhythm-hrule.tsx",
|
|
101
|
+
"./components/priming-proof-page": "./components/priming-proof-page.tsx",
|
|
102
|
+
"./components/publication-cyclotron-panel": "./components/publication-cyclotron-panel.tsx",
|
|
96
103
|
"./components/reader-auth-control": "./components/reader-auth-control.tsx",
|
|
97
104
|
"./components/reader-auth-state": "./components/reader-auth-state.ts",
|
|
98
105
|
"./components/reader-settings": "./components/reader-settings.ts",
|
|
99
106
|
"./components/reader-theme-control": "./components/reader-theme-control.tsx",
|
|
107
|
+
"./components/reference-curation-controls": "./components/reference-curation-controls.tsx",
|
|
108
|
+
"./components/reference-cyclotron-status": "./components/reference-cyclotron-status.tsx",
|
|
109
|
+
"./components/reference-priming": "./components/reference-priming.tsx",
|
|
110
|
+
"./components/reference-relevance-review": "./components/reference-relevance-review.tsx",
|
|
100
111
|
"./components/reference-source-preview": "./components/reference-source-preview.tsx",
|
|
101
112
|
"./components/settings-page": "./components/settings-page.tsx",
|
|
113
|
+
"./components/signup-entries-panel": "./components/signup-entries-panel.tsx",
|
|
102
114
|
"./components/staging-banner": "./components/staging-banner.tsx",
|
|
103
115
|
"./components/topic-steering-workspace": "./components/topic-steering-workspace.tsx",
|
|
104
116
|
"./components/ui/badge": "./components/ui/badge.tsx",
|
|
@@ -119,13 +131,22 @@
|
|
|
119
131
|
"./components/ui/tabs": "./components/ui/tabs.tsx",
|
|
120
132
|
"./components/ui/textarea": "./components/ui/textarea.tsx",
|
|
121
133
|
"./components/ui/tooltip": "./components/ui/tooltip.tsx",
|
|
134
|
+
"./components/use-blog-header-obstacles": "./components/use-blog-header-obstacles.ts",
|
|
135
|
+
"./components/use-brand-fonts-ready": "./components/use-brand-fonts-ready.ts",
|
|
136
|
+
"./components/use-near-viewport": "./components/use-near-viewport.ts",
|
|
122
137
|
"./components/use-resolved-papyrus-theme": "./components/use-resolved-papyrus-theme.ts",
|
|
138
|
+
"./components/use-rhythm-overlay": "./components/use-rhythm-overlay.ts",
|
|
123
139
|
"./lib/amplify-outputs-guard": "./lib/amplify-outputs-guard.ts",
|
|
124
140
|
"./lib/amplify-outputs-path": "./lib/amplify-outputs-path.ts",
|
|
125
141
|
"./lib/amplify-server-runtime": "./lib/amplify-server-runtime.ts",
|
|
142
|
+
"./lib/approved-priming-proof-reports": "./lib/approved-priming-proof-reports.ts",
|
|
126
143
|
"./lib/archive-data": "./lib/archive-data.ts",
|
|
127
144
|
"./lib/archive-types": "./lib/archive-types.ts",
|
|
128
145
|
"./lib/articles": "./lib/articles.ts",
|
|
146
|
+
"./lib/blog-feature-solver": "./lib/blog-feature-solver.ts",
|
|
147
|
+
"./lib/blog-rhythm": "./lib/blog-rhythm.ts",
|
|
148
|
+
"./lib/brand-fonts-watch": "./lib/brand-fonts-watch.ts",
|
|
149
|
+
"./lib/brand-fonts": "./lib/brand-fonts.ts",
|
|
129
150
|
"./lib/cached-content-repository": "./lib/cached-content-repository.ts",
|
|
130
151
|
"./lib/category-dashboard": "./lib/category-dashboard.ts",
|
|
131
152
|
"./lib/category-repository": "./lib/category-repository.ts",
|
|
@@ -133,10 +154,12 @@
|
|
|
133
154
|
"./lib/console-web-context": "./lib/console-web-context.ts",
|
|
134
155
|
"./lib/content-actions-client": "./lib/content-actions-client.ts",
|
|
135
156
|
"./lib/content-actions-demo": "./lib/content-actions-demo.ts",
|
|
157
|
+
"./lib/content-item-lifecycle": "./lib/content-item-lifecycle.ts",
|
|
136
158
|
"./lib/content-load-timing": "./lib/content-load-timing.ts",
|
|
137
159
|
"./lib/content-repository": "./lib/content-repository.ts",
|
|
138
160
|
"./lib/content-source-context": "./lib/content-source-context.ts",
|
|
139
161
|
"./lib/content-types": "./lib/content-types.ts",
|
|
162
|
+
"./lib/curation-client": "./lib/curation-client.ts",
|
|
140
163
|
"./lib/define-site": "./lib/define-site.ts",
|
|
141
164
|
"./lib/demo-amplify-outputs": "./lib/demo-amplify-outputs.ts",
|
|
142
165
|
"./lib/dev-sandbox-editor-auth": "./lib/dev-sandbox-editor-auth.ts",
|
|
@@ -153,11 +176,13 @@
|
|
|
153
176
|
"./lib/markus-ir": "./lib/markus-ir.ts",
|
|
154
177
|
"./lib/markus-projection": "./lib/markus-projection.ts",
|
|
155
178
|
"./lib/markus-to-article": "./lib/markus-to-article.ts",
|
|
179
|
+
"./lib/media-route-response": "./lib/media-route-response.ts",
|
|
156
180
|
"./lib/news-desk-session": "./lib/news-desk-session.ts",
|
|
157
181
|
"./lib/newspaper-layout": "./lib/newspaper-layout.ts",
|
|
158
182
|
"./lib/newsroom-articles": "./lib/newsroom-articles.ts",
|
|
159
183
|
"./lib/newsroom-assignments": "./lib/newsroom-assignments.ts",
|
|
160
184
|
"./lib/newsroom-base-path": "./lib/newsroom-base-path.ts",
|
|
185
|
+
"./lib/newsroom-board": "./lib/newsroom-board.ts",
|
|
161
186
|
"./lib/newsroom-card-layout": "./lib/newsroom-card-layout.ts",
|
|
162
187
|
"./lib/newsroom-category-drilldown": "./lib/newsroom-category-drilldown.ts",
|
|
163
188
|
"./lib/newsroom-demo-articles": "./lib/newsroom-demo-articles.ts",
|
|
@@ -170,35 +195,59 @@
|
|
|
170
195
|
"./lib/newsroom-media-backend": "./lib/newsroom-media-backend.ts",
|
|
171
196
|
"./lib/newsroom-media": "./lib/newsroom-media.ts",
|
|
172
197
|
"./lib/newsroom-nav": "./lib/newsroom-nav.ts",
|
|
198
|
+
"./lib/newsroom-organizer-nav": "./lib/newsroom-organizer-nav.ts",
|
|
173
199
|
"./lib/newsroom-references": "./lib/newsroom-references.ts",
|
|
200
|
+
"./lib/newsroom-section-routing": "./lib/newsroom-section-routing.ts",
|
|
174
201
|
"./lib/newsroom-sections": "./lib/newsroom-sections.ts",
|
|
175
202
|
"./lib/newsroom-topics": "./lib/newsroom-topics.ts",
|
|
203
|
+
"./lib/oauth-redirect-priority": "./lib/oauth-redirect-priority.ts",
|
|
176
204
|
"./lib/papyrus-object-kinds": "./lib/papyrus-object-kinds.ts",
|
|
177
205
|
"./lib/papyrus-web-locations": "./lib/papyrus-web-locations.ts",
|
|
178
206
|
"./lib/pilobol-sample": "./lib/pilobol-sample.ts",
|
|
207
|
+
"./lib/plugin-settings": "./lib/plugin-settings.ts",
|
|
179
208
|
"./lib/presentation-footer": "./lib/presentation-footer.ts",
|
|
180
209
|
"./lib/pretext-layout": "./lib/pretext-layout.ts",
|
|
210
|
+
"./lib/priming-proof-report": "./lib/priming-proof-report.ts",
|
|
211
|
+
"./lib/prospectus-publication-access": "./lib/prospectus-publication-access.ts",
|
|
212
|
+
"./lib/prospectus-session": "./lib/prospectus-session.ts",
|
|
213
|
+
"./lib/prospectus-sign-in-routes": "./lib/prospectus-sign-in-routes.ts",
|
|
214
|
+
"./lib/prospectus-site-identity": "./lib/prospectus-site-identity.ts",
|
|
181
215
|
"./lib/public-placeholder-config": "./lib/public-placeholder-config.ts",
|
|
216
|
+
"./lib/publication-cyclotron": "./lib/publication-cyclotron.ts",
|
|
182
217
|
"./lib/publication-items": "./lib/publication-items.ts",
|
|
218
|
+
"./lib/rate-limit-retry": "./lib/rate-limit-retry.ts",
|
|
219
|
+
"./lib/reader-base-path": "./lib/reader-base-path.ts",
|
|
220
|
+
"./lib/reader-cache-lifetime": "./lib/reader-cache-lifetime.ts",
|
|
183
221
|
"./lib/reader-route-config": "./lib/reader-route-config.ts",
|
|
184
222
|
"./lib/reader-static-params": "./lib/reader-static-params.ts",
|
|
185
223
|
"./lib/reader-storage-url": "./lib/reader-storage-url.ts",
|
|
186
224
|
"./lib/reference-display": "./lib/reference-display.ts",
|
|
187
225
|
"./lib/reference-policy": "./lib/reference-policy.ts",
|
|
188
226
|
"./lib/reference-source-preview": "./lib/reference-source-preview.ts",
|
|
227
|
+
"./lib/relevance-decisions": "./lib/relevance-decisions.ts",
|
|
228
|
+
"./lib/relevance-status": "./lib/relevance-status.ts",
|
|
189
229
|
"./lib/renderer-config": "./lib/renderer-config.ts",
|
|
190
230
|
"./lib/renderer": "./lib/renderer.ts",
|
|
191
231
|
"./lib/reporting-story-budget": "./lib/reporting-story-budget.ts",
|
|
232
|
+
"./lib/revalidate-prewarm": "./lib/revalidate-prewarm.ts",
|
|
233
|
+
"./lib/revalidate-secret": "./lib/revalidate-secret.ts",
|
|
234
|
+
"./lib/robots-policy": "./lib/robots-policy.ts",
|
|
235
|
+
"./lib/root-route-redirect": "./lib/root-route-redirect.ts",
|
|
192
236
|
"./lib/semantic-graph": "./lib/semantic-graph.ts",
|
|
237
|
+
"./lib/shared-credentials-provider": "./lib/shared-credentials-provider.ts",
|
|
238
|
+
"./lib/signup-csv": "./lib/signup-csv.ts",
|
|
193
239
|
"./lib/site-brand-tenant": "./lib/site-brand-tenant.ts",
|
|
194
240
|
"./lib/site-brand": "./lib/site-brand.ts",
|
|
195
241
|
"./lib/site-env": "./lib/site-env.ts",
|
|
196
242
|
"./lib/site-renderer": "./lib/site-renderer.ts",
|
|
197
243
|
"./lib/site-stack": "./lib/site-stack.ts",
|
|
198
244
|
"./lib/staging-gate": "./lib/staging-gate.ts",
|
|
245
|
+
"./lib/staging-gated-path": "./lib/staging-gated-path.ts",
|
|
199
246
|
"./lib/staging-preview-object": "./lib/staging-preview-object.ts",
|
|
247
|
+
"./lib/test-editor-override": "./lib/test-editor-override.ts",
|
|
200
248
|
"./lib/themed-image": "./lib/themed-image.ts",
|
|
201
249
|
"./lib/utils": "./lib/utils.ts",
|
|
250
|
+
"./lib/video-loading": "./lib/video-loading.ts",
|
|
202
251
|
"./lib/video-mode": "./lib/video-mode.ts",
|
|
203
252
|
"./lib/video-script": "./lib/video-script.ts",
|
|
204
253
|
"./renderers/markus/index": "./renderers/markus/index.ts",
|
|
@@ -206,17 +255,28 @@
|
|
|
206
255
|
"./renderers/pretext/article-page": "./renderers/pretext/article-page.tsx",
|
|
207
256
|
"./renderers/pretext/index": "./renderers/pretext/index.ts",
|
|
208
257
|
"./renderers/pretext/layouts": "./renderers/pretext/layouts.ts",
|
|
258
|
+
"./renderers/pretext/presentation-shared": "./renderers/pretext/presentation-shared.tsx",
|
|
209
259
|
"./renderers/pretext/presentation-shell": "./renderers/pretext/presentation-shell.tsx",
|
|
260
|
+
"./renderers/pretext/rhythm-article-page": "./renderers/pretext/rhythm-article-page.tsx",
|
|
261
|
+
"./renderers/pretext/rhythm-blog-presentation": "./renderers/pretext/rhythm-blog-presentation.tsx",
|
|
262
|
+
"./renderers/pretext/rhythm-shell-style": "./renderers/pretext/rhythm-shell-style.ts",
|
|
210
263
|
"./app/%5F_preview/[[...path]]/route": "./app/%5F_preview/[[...path]]/route.ts",
|
|
211
264
|
"./app/[year]/[month]/[day]/[articleSlug]/page": "./app/[year]/[month]/[day]/[articleSlug]/page.tsx",
|
|
212
265
|
"./app/[year]/[month]/[day]/page": "./app/[year]/[month]/[day]/page.tsx",
|
|
213
266
|
"./app/[year]/[month]/[day]/page/[pageNumber]/page": "./app/[year]/[month]/[day]/page/[pageNumber]/page.tsx",
|
|
214
267
|
"./app/[year]/[month]/[day]/section/[sectionKey]/page": "./app/[year]/[month]/[day]/section/[sectionKey]/page.tsx",
|
|
215
268
|
"./app/api/archive/editions/route": "./app/api/archive/editions/route.ts",
|
|
269
|
+
"./app/api/auth/prospectus/callback/route": "./app/api/auth/prospectus/callback/route.ts",
|
|
270
|
+
"./app/api/auth/prospectus/selection/route": "./app/api/auth/prospectus/selection/route.ts",
|
|
271
|
+
"./app/api/auth/prospectus/session/route": "./app/api/auth/prospectus/session/route.ts",
|
|
272
|
+
"./app/api/auth/prospectus/sign-in/route": "./app/api/auth/prospectus/sign-in/route.ts",
|
|
273
|
+
"./app/api/auth/prospectus/sign-out/route": "./app/api/auth/prospectus/sign-out/route.ts",
|
|
274
|
+
"./app/api/cyclotron/priming-proof/route": "./app/api/cyclotron/priming-proof/route.ts",
|
|
216
275
|
"./app/api/media/[...path]/route": "./app/api/media/[...path]/route.ts",
|
|
217
276
|
"./app/api/revalidate/route": "./app/api/revalidate/route.ts",
|
|
218
277
|
"./app/archive/page": "./app/archive/page.tsx",
|
|
219
278
|
"./app/articles/[slug]/page": "./app/articles/[slug]/page.tsx",
|
|
279
|
+
"./app/cyclotron/page": "./app/cyclotron/page.tsx",
|
|
220
280
|
"./app/layout": "./app/layout.tsx",
|
|
221
281
|
"./app/newsroom/[section]/[...selection]/page": "./app/newsroom/[section]/[...selection]/page.tsx",
|
|
222
282
|
"./app/newsroom/[section]/page": "./app/newsroom/[section]/page.tsx",
|
|
@@ -228,7 +288,10 @@
|
|
|
228
288
|
"./app/newsroom/layout": "./app/newsroom/layout.tsx",
|
|
229
289
|
"./app/newsroom/page": "./app/newsroom/page.tsx",
|
|
230
290
|
"./app/newsroom/sections/[sectionId]/page": "./app/newsroom/sections/[sectionId]/page.tsx",
|
|
291
|
+
"./app/newsroom/settings/page": "./app/newsroom/settings/page.tsx",
|
|
292
|
+
"./app/newsroom/work/page": "./app/newsroom/work/page.tsx",
|
|
231
293
|
"./app/page": "./app/page.tsx",
|
|
294
|
+
"./app/robots": "./app/robots.ts",
|
|
232
295
|
"./app/settings/page": "./app/settings/page.tsx"
|
|
233
296
|
},
|
|
234
297
|
"files": [
|
|
@@ -276,37 +339,39 @@
|
|
|
276
339
|
"optional": true
|
|
277
340
|
}
|
|
278
341
|
},
|
|
279
|
-
"version": "1.
|
|
342
|
+
"version": "1.1.0",
|
|
280
343
|
"dependencies": {
|
|
281
344
|
"@aws-amplify/adapter-nextjs": "^1.7.3",
|
|
345
|
+
"@aws-crypto/sha256-js": "5.2.0",
|
|
282
346
|
"@aws-sdk/client-cognito-identity-provider": "3.1045.0",
|
|
283
347
|
"@aws-sdk/client-lambda": "^3.1045.0",
|
|
284
348
|
"@aws-sdk/client-s3": "^3.1045.0",
|
|
349
|
+
"@aws-sdk/client-secrets-manager": "3.1045.0",
|
|
285
350
|
"@aws-sdk/client-ssm": "^3.1045.0",
|
|
351
|
+
"@aws-sdk/credential-provider-node": "3.972.84",
|
|
286
352
|
"@aws-sdk/s3-request-presigner": "^3.1045.0",
|
|
287
353
|
"@base-ui/react": "^1.5.0",
|
|
288
354
|
"@chenglou/pretext": "^0.0.7",
|
|
355
|
+
"@kanbus/ui": "https://github.com/AnthusAI/Kanbus/releases/download/ui-v0.2.0/kanbus-ui-0.2.0.tgz",
|
|
289
356
|
"@radix-ui/colors": "3.0.0",
|
|
290
|
-
"@
|
|
291
|
-
"@
|
|
292
|
-
"@streamdown/math": "^1.0.2",
|
|
293
|
-
"@streamdown/mermaid": "^1.0.2",
|
|
357
|
+
"@smithy/protocol-http": "5.4.1",
|
|
358
|
+
"@smithy/signature-v4": "5.7.4",
|
|
294
359
|
"@tailwindcss/postcss": "^4.3.0",
|
|
295
360
|
"ai": "^6.0.191",
|
|
296
361
|
"anthus-vultus": "github:AnthusAI/Vultus#af98d57",
|
|
297
362
|
"aws-amplify": "^6.17.0",
|
|
363
|
+
"aws-jwt-verify": "4.0.1",
|
|
298
364
|
"class-variance-authority": "^0.7.1",
|
|
299
365
|
"clsx": "^2.1.1",
|
|
300
366
|
"cmdk": "^1.1.1",
|
|
367
|
+
"cyclotron": "https://github.com/AnthusAI/Cyclotron/releases/download/ui-v0.2.2/cyclotron-0.2.2.tgz",
|
|
301
368
|
"esbuild": "^0.28.2",
|
|
302
369
|
"gray-matter": "^4.0.3",
|
|
303
370
|
"gsap": "^3.15.0",
|
|
304
|
-
"katex": "^0.17.0",
|
|
305
371
|
"lucide-react": "^1.16.0",
|
|
306
372
|
"motion": "^12.40.0",
|
|
307
373
|
"nanoid": "^5.1.11",
|
|
308
374
|
"shadcn": "^4.8.0",
|
|
309
|
-
"streamdown": "^2.5.0",
|
|
310
375
|
"tailwind-merge": "^3.6.0",
|
|
311
376
|
"tailwindcss": "^4.3.0",
|
|
312
377
|
"tsx": "^4.23.15",
|