@anthusai/papyrus 1.0.0-next.3 → 1.0.0-next.4

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/middleware.ts CHANGED
@@ -1,6 +1,8 @@
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 { getSiteEnv, isIndexable } from "./lib/site-env";
5
+ import { getStagingAccess } from "./lib/staging-gate";
4
6
 
5
7
  function usesNewsroomRootPaths(): boolean {
6
8
  const brand = getSiteBrand();
@@ -17,7 +19,14 @@ function isStaticOrApiPath(pathname: string): boolean {
17
19
  );
18
20
  }
19
21
 
20
- export function middleware(request: NextRequest) {
22
+ function isStagingGatedPath(pathname: string): boolean {
23
+ if (isStaticOrApiPath(pathname)) return false;
24
+ if (pathname === "/robots.txt") return false;
25
+ if (pathname === "/newsroom" || pathname.startsWith("/newsroom/")) return false;
26
+ return true;
27
+ }
28
+
29
+ function routeRequest(request: NextRequest): NextResponse {
21
30
  if (!usesNewsroomRootPaths()) {
22
31
  return NextResponse.next();
23
32
  }
@@ -48,6 +57,34 @@ export function middleware(request: NextRequest) {
48
57
  return NextResponse.next();
49
58
  }
50
59
 
60
+ export async function middleware(request: NextRequest): Promise<NextResponse> {
61
+ let sessionResponse: NextResponse | null = null;
62
+ if (getSiteEnv() === "staging" && isStagingGatedPath(request.nextUrl.pathname)) {
63
+ sessionResponse = NextResponse.next();
64
+ const access = await getStagingAccess(request, sessionResponse);
65
+ if (access === "anonymous") {
66
+ return withRobotsHeader(NextResponse.redirect(new URL("/newsroom", request.url)));
67
+ }
68
+ if (access === "forbidden") {
69
+ return withRobotsHeader(new NextResponse("Staging is limited to editors and admins.", { status: 403 }));
70
+ }
71
+ }
72
+
73
+ const response = routeRequest(request);
74
+ if (sessionResponse) {
75
+ for (const cookie of sessionResponse.headers.getSetCookie()) {
76
+ response.headers.append("set-cookie", cookie);
77
+ }
78
+ }
79
+ return withRobotsHeader(response);
80
+ }
81
+
82
+ function withRobotsHeader(response: NextResponse): NextResponse {
83
+ if (!isIndexable()) response.headers.set("X-Robots-Tag", "noindex, nofollow");
84
+ return response;
85
+ }
86
+
51
87
  export const config = {
88
+ runtime: "nodejs",
52
89
  matcher: ["/((?!_next/static|_next/image|favicon.ico|icon).*)"],
53
90
  };
package/package.json CHANGED
@@ -95,6 +95,7 @@
95
95
  "./components/reader-theme-control": "./components/reader-theme-control.tsx",
96
96
  "./components/reference-source-preview": "./components/reference-source-preview.tsx",
97
97
  "./components/settings-page": "./components/settings-page.tsx",
98
+ "./components/staging-banner": "./components/staging-banner.tsx",
98
99
  "./components/topic-steering-workspace": "./components/topic-steering-workspace.tsx",
99
100
  "./components/ui/badge": "./components/ui/badge.tsx",
100
101
  "./components/ui/button-group": "./components/ui/button-group.tsx",
@@ -129,6 +130,7 @@
129
130
  "./lib/content-actions-client": "./lib/content-actions-client.ts",
130
131
  "./lib/content-load-timing": "./lib/content-load-timing.ts",
131
132
  "./lib/content-repository": "./lib/content-repository.ts",
133
+ "./lib/content-source-context": "./lib/content-source-context.ts",
132
134
  "./lib/content-types": "./lib/content-types.ts",
133
135
  "./lib/define-site": "./lib/define-site.ts",
134
136
  "./lib/demo-amplify-outputs": "./lib/demo-amplify-outputs.ts",
@@ -181,8 +183,10 @@
181
183
  "./lib/semantic-graph": "./lib/semantic-graph.ts",
182
184
  "./lib/site-brand-tenant": "./lib/site-brand-tenant.ts",
183
185
  "./lib/site-brand": "./lib/site-brand.ts",
186
+ "./lib/site-env": "./lib/site-env.ts",
184
187
  "./lib/site-renderer": "./lib/site-renderer.ts",
185
188
  "./lib/site-stack": "./lib/site-stack.ts",
189
+ "./lib/staging-gate": "./lib/staging-gate.ts",
186
190
  "./lib/themed-image": "./lib/themed-image.ts",
187
191
  "./lib/utils": "./lib/utils.ts",
188
192
  "./renderers/markus/index": "./renderers/markus/index.ts",
@@ -257,7 +261,7 @@
257
261
  "optional": true
258
262
  }
259
263
  },
260
- "version": "1.0.0-next.3",
264
+ "version": "1.0.0-next.4",
261
265
  "dependencies": {
262
266
  "@aws-amplify/adapter-nextjs": "^1.7.3",
263
267
  "@aws-sdk/client-cognito-identity-provider": "3.1045.0",
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.0.0-next.3",
2
+ "version": "1.0.0-next.4",
3
3
  "routes": [
4
4
  {
5
5
  "file": "app/[year]/[month]/[day]/[articleSlug]/page.tsx",