@gradial/aci 0.1.12 → 0.1.14

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/dist/index.d.ts CHANGED
@@ -2,4 +2,3 @@ export * from './block-ref.js';
2
2
  export * from './define-component.js';
3
3
  export * from './define-layout.js';
4
4
  export * from './types/index.js';
5
- export * from './render.js';
package/dist/index.js CHANGED
@@ -2,7 +2,6 @@ export * from './block-ref.js';
2
2
  export * from './define-component.js';
3
3
  export * from './define-layout.js';
4
4
  export * from './types/index.js';
5
- export * from './render.js';
6
5
  // Note: content/ is NOT re-exported here because it imports node:path,
7
6
  // making it incompatible with client-side bundlers. Import server-only
8
7
  // content utilities from '@gradial/aci/content' explicitly.
@@ -1,8 +1,7 @@
1
- import { type NextRequest } from 'next/server.js';
1
+ import { NextResponse, type NextRequest } from 'next/server.js';
2
2
  export interface GradialMiddlewareConfig {
3
3
  siteId: string;
4
4
  edgeConfig?: string;
5
- previewSignKey?: string;
6
5
  deploymentId?: string;
7
6
  }
8
- export declare function createGradialMiddleware(config: GradialMiddlewareConfig): (request: NextRequest) => Promise<Response>;
7
+ export declare function createGradialMiddleware(config: GradialMiddlewareConfig): (request: NextRequest) => Promise<NextResponse<unknown>>;
@@ -7,6 +7,7 @@ const DISPATCH_HEADER = 'x-gradial-dispatch';
7
7
  export function createGradialMiddleware(config) {
8
8
  return async function gradialMiddleware(request) {
9
9
  const url = request.nextUrl;
10
+ // ?leave_preview=1 → clear cookies, redirect to clean URL
10
11
  if (url.searchParams.get('leave_preview') === '1') {
11
12
  const cleanUrl = new URL(url.pathname, url.origin);
12
13
  const response = NextResponse.redirect(cleanUrl);
@@ -15,30 +16,30 @@ export function createGradialMiddleware(config) {
15
16
  return response;
16
17
  }
17
18
  const requestHeaders = gradialHeaders(request.headers);
18
- const preview = await releaseFromPreviewToken(request, config);
19
- if (preview.invalid) {
20
- return new Response('invalid preview token', { status: 403 });
21
- }
22
- const releaseId = preview.releaseId || await activeReleaseFromEdgeConfig(config);
19
+ // Try preview token first; if valid, use that release.
20
+ // If no token or invalid, fall through to active release from edge config.
21
+ const previewReleaseId = await releaseIdFromPreviewToken(request, config);
22
+ const releaseId = previewReleaseId || await activeReleaseFromEdgeConfig(config);
23
23
  if (!releaseId) {
24
24
  return NextResponse.next({ request: { headers: requestHeaders } });
25
25
  }
26
26
  requestHeaders.set(RELEASE_HEADER, releaseId);
27
27
  requestHeaders.set(ROUTE_HEADER, url.pathname);
28
28
  requestHeaders.set(DISPATCH_HEADER, 'ssr-page');
29
- if (preview.releaseId) {
29
+ if (previewReleaseId) {
30
30
  requestHeaders.set('x-gradial-preview', '1');
31
31
  }
32
32
  const response = NextResponse.next({ request: { headers: requestHeaders } });
33
+ // Persist preview token as cookie so navigation stays in preview
33
34
  const queryToken = url.searchParams.get('preview_token');
34
- if (queryToken && preview.releaseId) {
35
+ if (queryToken && previewReleaseId) {
35
36
  response.cookies.set('aci_preview', queryToken, {
36
37
  httpOnly: true,
37
38
  sameSite: 'lax',
38
39
  maxAge: 60 * 60,
39
40
  path: '/',
40
41
  });
41
- response.cookies.set('aci_preview_release', preview.releaseId, {
42
+ response.cookies.set('aci_preview_release', previewReleaseId, {
42
43
  httpOnly: false,
43
44
  sameSite: 'lax',
44
45
  maxAge: 60 * 60,
@@ -125,23 +126,23 @@ function clampRelease(activeReleaseId, activeSequence, compatibility) {
125
126
  function edgeKeySegment(value) {
126
127
  return value.replace(/[^A-Za-z0-9_-]/g, '_');
127
128
  }
128
- async function releaseFromPreviewToken(request, config) {
129
+ async function releaseIdFromPreviewToken(request, config) {
129
130
  const token = previewTokenFromRequest(request);
130
131
  if (!token)
131
- return { releaseId: '', invalid: false };
132
- const signKey = config.previewSignKey || process.env.ACI_PREVIEW_SIGN_KEY || process.env.GRADIAL_PREVIEW_SIGN_KEY || '';
132
+ return '';
133
+ const signKey = process.env.GRADIAL_PREVIEW_SIGN_KEY || '';
133
134
  if (!signKey) {
134
- console.warn('[gradial] preview sign key not set (ACI_PREVIEW_SIGN_KEY or GRADIAL_PREVIEW_SIGN_KEY) preview token ignored');
135
- return { releaseId: '', invalid: false };
135
+ console.warn('[gradial] GRADIAL_PREVIEW_SIGN_KEY not set preview tokens will be ignored');
136
+ return '';
136
137
  }
137
138
  const claims = await validatePreviewToken(token, signKey);
138
139
  if (!claims || claims.scope !== 'preview' || !claims.releaseId)
139
- return { releaseId: '', invalid: true };
140
+ return '';
140
141
  if (claims.siteId && config.siteId && claims.siteId !== config.siteId)
141
- return { releaseId: '', invalid: true };
142
+ return '';
142
143
  if (!claims.expiresAt || Date.parse(claims.expiresAt) <= Date.now())
143
- return { releaseId: '', invalid: true };
144
- return { releaseId: claims.releaseId, invalid: false };
144
+ return '';
145
+ return claims.releaseId;
145
146
  }
146
147
  function previewTokenFromRequest(request) {
147
148
  const queryToken = request.nextUrl.searchParams.get('preview_token');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradial/aci",
3
- "version": "0.1.12",
3
+ "version": "0.1.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",