@amplifyup/sdk 0.1.50 → 0.1.52

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.
@@ -4,6 +4,15 @@ export { A as AMPLIFYUP_EDITOR_ROUTE } from './reservedRoutes-aGgViBDM.mjs';
4
4
  /**
5
5
  * Next.js middleware: Composer preview rewrite + variant ISR rewrite.
6
6
  * Edge-runtime safe (no Node APIs).
7
+ *
8
+ * Soft-nav safety (Next.js <Link>):
9
+ * App Router client navigations (RSC flight + Link prefetch) must NOT rewrite
10
+ * to `/__p/{keys}/…` or Set-Cookie. Rewriting `/insights/slug` → `/__p/…/insights/slug`
11
+ * during soft nav commonly aborts the transition (preventDefault runs,
12
+ * location.pathname never changes; Ctrl/Cmd-click full loads still work).
13
+ *
14
+ * Personalized HTML for soft nav comes from the SDK client overlay
15
+ * (`/v1/select` + `/v1/resolve`). Full document loads still use `/__p/…` ISR.
7
16
  */
8
17
 
9
18
  declare const AMPLIFY_VARIANT_PREFIX = "/__p";
@@ -12,13 +21,15 @@ declare const AMPLIFY_SESSION_COOKIE = "amplifyup_session_id";
12
21
  declare const amplifyMiddlewareConfig: {
13
22
  matcher: string[];
14
23
  };
24
+ /** App Router flight / soft navigation (including Link prefetch). */
25
+ declare function isNextClientNavigation(request: NextRequest): boolean;
15
26
  /**
16
27
  * Preview stays dynamic. Personalized variants rewrite to `/__p/{keys}/…`
17
- * so Next can SSR the combo once and cache it (ISR). Default traffic is
18
- * unchanged SSG. Fail open to the default page on Edge errors/timeouts.
28
+ * on full document loads so Next can SSR the combo once and cache it (ISR).
29
+ * Soft nav / prefetch never rewrite — fail open to the public route.
19
30
  */
20
31
  declare function amplifyMiddleware(request: NextRequest, options?: {
21
32
  trackingId?: string;
22
33
  }): Promise<NextResponse>;
23
34
 
24
- export { AMPLIFY_ANON_COOKIE, AMPLIFY_SESSION_COOKIE, AMPLIFY_VARIANT_PREFIX, amplifyMiddleware, amplifyMiddlewareConfig };
35
+ export { AMPLIFY_ANON_COOKIE, AMPLIFY_SESSION_COOKIE, AMPLIFY_VARIANT_PREFIX, amplifyMiddleware, amplifyMiddlewareConfig, isNextClientNavigation };
@@ -4,6 +4,15 @@ export { A as AMPLIFYUP_EDITOR_ROUTE } from './reservedRoutes-aGgViBDM.js';
4
4
  /**
5
5
  * Next.js middleware: Composer preview rewrite + variant ISR rewrite.
6
6
  * Edge-runtime safe (no Node APIs).
7
+ *
8
+ * Soft-nav safety (Next.js <Link>):
9
+ * App Router client navigations (RSC flight + Link prefetch) must NOT rewrite
10
+ * to `/__p/{keys}/…` or Set-Cookie. Rewriting `/insights/slug` → `/__p/…/insights/slug`
11
+ * during soft nav commonly aborts the transition (preventDefault runs,
12
+ * location.pathname never changes; Ctrl/Cmd-click full loads still work).
13
+ *
14
+ * Personalized HTML for soft nav comes from the SDK client overlay
15
+ * (`/v1/select` + `/v1/resolve`). Full document loads still use `/__p/…` ISR.
7
16
  */
8
17
 
9
18
  declare const AMPLIFY_VARIANT_PREFIX = "/__p";
@@ -12,13 +21,15 @@ declare const AMPLIFY_SESSION_COOKIE = "amplifyup_session_id";
12
21
  declare const amplifyMiddlewareConfig: {
13
22
  matcher: string[];
14
23
  };
24
+ /** App Router flight / soft navigation (including Link prefetch). */
25
+ declare function isNextClientNavigation(request: NextRequest): boolean;
15
26
  /**
16
27
  * Preview stays dynamic. Personalized variants rewrite to `/__p/{keys}/…`
17
- * so Next can SSR the combo once and cache it (ISR). Default traffic is
18
- * unchanged SSG. Fail open to the default page on Edge errors/timeouts.
28
+ * on full document loads so Next can SSR the combo once and cache it (ISR).
29
+ * Soft nav / prefetch never rewrite — fail open to the public route.
19
30
  */
20
31
  declare function amplifyMiddleware(request: NextRequest, options?: {
21
32
  trackingId?: string;
22
33
  }): Promise<NextResponse>;
23
34
 
24
- export { AMPLIFY_ANON_COOKIE, AMPLIFY_SESSION_COOKIE, AMPLIFY_VARIANT_PREFIX, amplifyMiddleware, amplifyMiddlewareConfig };
35
+ export { AMPLIFY_ANON_COOKIE, AMPLIFY_SESSION_COOKIE, AMPLIFY_VARIANT_PREFIX, amplifyMiddleware, amplifyMiddlewareConfig, isNextClientNavigation };
@@ -144,6 +144,14 @@ var amplifyMiddlewareConfig = {
144
144
  function isPrefetch(request) {
145
145
  return request.headers.get("x-middleware-prefetch") === "1" || request.headers.get("Next-Router-Prefetch") === "1" || request.headers.get("purpose") === "prefetch" || request.headers.get("Purpose") === "prefetch";
146
146
  }
147
+ function isNextClientNavigation(request) {
148
+ if (isPrefetch(request)) return true;
149
+ const rsc = request.headers.get("rsc") || request.headers.get("RSC");
150
+ if (rsc === "1") return true;
151
+ if (request.headers.get("next-router-state-tree")) return true;
152
+ if (request.headers.get("Next-Router-State-Tree")) return true;
153
+ return false;
154
+ }
147
155
  function generateAnonId() {
148
156
  const uuid = typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(16).slice(2)}`;
149
157
  return `browser_${uuid}`;
@@ -173,7 +181,7 @@ async function amplifyMiddleware(request, options) {
173
181
  url.pathname = pathname === "/" ? "/__preview" : `/__preview${pathname}`;
174
182
  return server.NextResponse.rewrite(url);
175
183
  }
176
- if (isPrefetch(request)) {
184
+ if (isNextClientNavigation(request)) {
177
185
  return server.NextResponse.next();
178
186
  }
179
187
  const trackingId = options?.trackingId || (typeof searchParams.get("trackingId") === "string" ? searchParams.get("trackingId") : null) || process.env.NEXT_PUBLIC_AMPLIFYUP_TRACKING_ID || "";
@@ -219,5 +227,6 @@ exports.AMPLIFY_SESSION_COOKIE = AMPLIFY_SESSION_COOKIE;
219
227
  exports.AMPLIFY_VARIANT_PREFIX = AMPLIFY_VARIANT_PREFIX;
220
228
  exports.amplifyMiddleware = amplifyMiddleware;
221
229
  exports.amplifyMiddlewareConfig = amplifyMiddlewareConfig;
230
+ exports.isNextClientNavigation = isNextClientNavigation;
222
231
  //# sourceMappingURL=middleware.js.map
223
232
  //# sourceMappingURL=middleware.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/edge/fetchVariants.ts","../src/edge/variantKeys.ts","../src/edge/normalizeRoute.ts","../src/targets.ts","../src/reservedRoutes.ts","../src/middleware.ts"],"names":["orchestratorUrl","NextResponse"],"mappings":"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","file":"middleware.js","sourcesContent":["/**\n * Lightweight Edge call for Next middleware: variant keys only.\n */\n\nexport async function fetchEdgeVariants(options: {\n edgeUrl: string;\n trackingId: string;\n route: string;\n anonId: string;\n fetch?: typeof fetch;\n timeoutMs?: number;\n}): Promise<Record<string, string>> {\n const base = options.edgeUrl.replace(/\\/+$/, '');\n const params = new URLSearchParams({\n route: options.route,\n trackingId: options.trackingId,\n anonId: options.anonId,\n });\n const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 800);\n try {\n const res = await fetchFn(`${base}/v1/variants?${params.toString()}`, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n cache: 'no-store',\n signal: controller.signal,\n });\n if (!res.ok) return {};\n const body = (await res.json().catch(() => ({}))) as {\n variantKeys?: Record<string, string>;\n };\n return body.variantKeys && typeof body.variantKeys === 'object'\n ? body.variantKeys\n : {};\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Compact variant-key codec for URLs and Edge `variants` query params.\n * Default variants are omitted so equivalent assignments share one cache entry.\n */\n\nexport function serializeVariantKeys(\n keys: Record<string, string> | null | undefined\n): string {\n if (!keys) return '';\n const parts: string[] = [];\n const zoneIds = Object.keys(keys).sort();\n for (const zoneId of zoneIds) {\n const variant = keys[zoneId];\n if (!variant || variant === 'default') continue;\n parts.push(`${zoneId}:${variant}`);\n }\n return parts.join(',');\n}\n\nexport function parseVariantKeys(\n raw: string | null | undefined\n): Record<string, string> {\n const out: Record<string, string> = {};\n const text = (raw || '').trim();\n if (!text) return out;\n const decoded = safeDecode(text);\n for (const part of decoded.split(',')) {\n const i = part.indexOf(':');\n if (i <= 0) continue;\n const zoneId = part.slice(0, i).trim();\n const variant = part.slice(i + 1).trim();\n if (zoneId && variant) out[zoneId] = variant;\n }\n return out;\n}\n\nexport function isDefaultVariantKeys(\n keys: Record<string, string> | null | undefined\n): boolean {\n return serializeVariantKeys(keys) === '';\n}\n\nfunction safeDecode(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n","/**\n * Normalize a route path for Edge resolve requests.\n * Leading slash, no trailing slash (except root), query/hash stripped.\n */\nexport function normalizeRoute(route: string): string {\n let path = String(route || '').trim();\n if (!path) return '/';\n\n try {\n if (/^https?:\\/\\//i.test(path)) {\n path = new URL(path).pathname;\n }\n } catch {\n /* keep path */\n }\n\n const q = path.indexOf('?');\n if (q >= 0) path = path.slice(0, q);\n const h = path.indexOf('#');\n if (h >= 0) path = path.slice(0, h);\n\n if (!path.startsWith('/')) path = `/${path}`;\n if (path.length > 1 && path.endsWith('/')) {\n path = path.replace(/\\/+$/, '');\n }\n return path || '/';\n}\n","/**\n * AmplifyUp environment targets\n *\n * Two environments only:\n * - local: apps/config from localhost + Neon; events & personalize from AWS development\n * - production: all production AmplifyUp / AWS endpoints\n *\n * Controlled via `config.target` or `NEXT_PUBLIC_AMPLIFYUP_TARGET`.\n * Legacy value `dev` is treated as `local`.\n */\n\nexport type AmplifyUpTarget = 'local' | 'production';\n\n/** Accepted env/config strings (includes legacy `dev` → local). */\nexport type AmplifyUpTargetInput = AmplifyUpTarget | 'dev';\n\nexport interface AmplifyUpUrls {\n target: AmplifyUpTarget;\n apiGatewayUrl: string;\n orchestratorUrl: string;\n decisionApiUrl: string;\n edgeUrl: string;\n}\n\nconst AWS_DEV_API = 'https://api-dev.amplifyup.ai';\nconst AWS_PROD_API = 'https://api.amplifyup.ai';\nconst PROD_ORCHESTRATOR = 'https://amplifyup.ai';\nconst PROD_EDGE = 'https://edge.amplifyup.ai';\n\nexport function isAmplifyUpTarget(value: unknown): value is AmplifyUpTargetInput {\n return value === 'local' || value === 'dev' || value === 'production';\n}\n\nexport function normalizeAmplifyUpTarget(value: AmplifyUpTargetInput): AmplifyUpTarget {\n return value === 'dev' ? 'local' : value;\n}\n\n/**\n * Resolve which target to use.\n *\n * Priority:\n * 1. explicit config.target\n * 2. config.dev === true → 'local' (local apps + AWS-dev pipeline)\n * 3. NEXT_PUBLIC_AMPLIFYUP_TARGET\n * 4. unset → 'production' (live endpoints — hosting on localhost does NOT imply local)\n *\n * Use `local` only when developing against the AmplifyUp monorepo\n * (set NEXT_PUBLIC_AMPLIFYUP_TARGET=local in .env.local).\n */\nexport function resolveAmplifyUpTarget(options?: {\n configTarget?: AmplifyUpTargetInput;\n /** @deprecated Prefer NEXT_PUBLIC_AMPLIFYUP_TARGET=local. When true, resolves to local. */\n configDev?: boolean;\n}): AmplifyUpTarget {\n if (options?.configTarget && isAmplifyUpTarget(options.configTarget)) {\n return normalizeAmplifyUpTarget(options.configTarget);\n }\n\n if (options?.configDev === true) {\n return 'local';\n }\n\n const envTarget =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_TARGET\n : undefined;\n if (isAmplifyUpTarget(envTarget)) {\n return normalizeAmplifyUpTarget(envTarget);\n }\n\n return 'production';\n}\n\n/** True when the orchestrator origin is a remote AmplifyUp deployment (not localhost). */\nexport function isRemoteOrchestratorUrl(orchestratorUrl: string): boolean {\n try {\n const host = new URL(orchestratorUrl).hostname.toLowerCase();\n return host !== 'localhost' && host !== '127.0.0.1' && host !== '::1';\n } catch {\n return false;\n }\n}\n\nfunction localOrchestratorUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n return (fromEnv || 'http://localhost:5001').replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local→AWS-dev API base (events + personalize).\n * Defaults to https://api-dev.amplifyup.ai\n */\nfunction localAwsApiUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL\n : undefined;\n return (fromEnv || AWS_DEV_API).replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local Edge Worker URL.\n * Defaults to http://localhost:8787\n */\nfunction localEdgeUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL\n : undefined;\n return (fromEnv || 'http://localhost:8787').replace(/\\/$/, '');\n}\n\nexport function resolveAmplifyUpUrls(target: AmplifyUpTarget): AmplifyUpUrls {\n if (target === 'local') {\n const orchestratorUrl = localOrchestratorUrl();\n const apiGatewayUrl = localAwsApiUrl();\n return {\n target: 'local',\n // Layouts / site config / composer APIs → local orchestrator + Neon\n orchestratorUrl,\n // Events + personalize → AWS development stack\n apiGatewayUrl,\n decisionApiUrl: `${apiGatewayUrl}/v1/personalize`,\n edgeUrl: localEdgeUrl(),\n };\n }\n\n const resolvedApi =\n (typeof process !== 'undefined' &&\n process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL?.replace(/\\/$/, '')) ||\n AWS_PROD_API;\n\n const orchestratorFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n\n // Production: don't accidentally use a localhost orchestrator URL from a local env file\n const isLocalOrchestrator =\n !!orchestratorFromEnv &&\n (orchestratorFromEnv.includes('localhost') ||\n orchestratorFromEnv.includes('127.0.0.1'));\n\n const orchestratorUrl = isLocalOrchestrator || !orchestratorFromEnv\n ? PROD_ORCHESTRATOR\n : orchestratorFromEnv.replace(/\\/$/, '');\n\n const edgeFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL?.replace(/\\/$/, '')\n : undefined;\n const edgeUrl =\n edgeFromEnv &&\n !edgeFromEnv.includes('localhost') &&\n !edgeFromEnv.includes('127.0.0.1')\n ? edgeFromEnv\n : PROD_EDGE;\n\n return {\n target: 'production',\n apiGatewayUrl: resolvedApi,\n orchestratorUrl,\n decisionApiUrl: `${resolvedApi}/v1/personalize`,\n edgeUrl,\n };\n}\n","/**\n * Reserved customer-site pathnames owned by AmplifyUp (not marketing URLs).\n */\n\n/** Composer composition / layout editing. Live visitors must not see this page. */\nexport const AMPLIFYUP_EDITOR_ROUTE = '/__amplifyup/editor';\n\nexport function isAmplifyUpEditorRoute(pathname: string): boolean {\n return (\n pathname === AMPLIFYUP_EDITOR_ROUTE ||\n pathname.startsWith(`${AMPLIFYUP_EDITOR_ROUTE}/`)\n );\n}\n","/**\n * Next.js middleware: Composer preview rewrite + variant ISR rewrite.\n * Edge-runtime safe (no Node APIs).\n */\n\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport { fetchEdgeVariants } from './edge/fetchVariants';\nimport {\n isDefaultVariantKeys,\n serializeVariantKeys,\n} from './edge/variantKeys';\nimport { normalizeRoute } from './edge/normalizeRoute';\nimport { resolveAmplifyUpTarget, resolveAmplifyUpUrls } from './targets';\nimport {\n isAmplifyUpEditorRoute,\n} from './reservedRoutes';\n\nexport { AMPLIFYUP_EDITOR_ROUTE } from './reservedRoutes';\nexport const AMPLIFY_VARIANT_PREFIX = '/__p';\nexport const AMPLIFY_ANON_COOKIE = 'amplifyup_anon_id';\nexport const AMPLIFY_SESSION_COOKIE = 'amplifyup_session_id';\nconst SESSION_MAX_AGE_SECONDS = 30 * 60;\n\nexport const amplifyMiddlewareConfig = {\n matcher: ['/((?!api|_next/static|_next/image|favicon.ico|.*\\\\..*).*)'],\n};\n\nfunction isPrefetch(request: NextRequest): boolean {\n return (\n request.headers.get('x-middleware-prefetch') === '1' ||\n request.headers.get('Next-Router-Prefetch') === '1' ||\n request.headers.get('purpose') === 'prefetch' ||\n request.headers.get('Purpose') === 'prefetch'\n );\n}\n\nfunction generateAnonId(): string {\n const uuid =\n typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n return `browser_${uuid}`;\n}\n\nfunction generateSessionId(): string {\n return typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction withSessionCookie(res: NextResponse, existing?: string): NextResponse {\n res.cookies.set(AMPLIFY_SESSION_COOKIE, existing || generateSessionId(), {\n path: '/',\n maxAge: SESSION_MAX_AGE_SECONDS,\n sameSite: 'lax',\n });\n return res;\n}\n\n/**\n * Preview stays dynamic. Personalized variants rewrite to `/__p/{keys}/…`\n * so Next can SSR the combo once and cache it (ISR). Default traffic is\n * unchanged SSG. Fail open to the default page on Edge errors/timeouts.\n */\nexport async function amplifyMiddleware(\n request: NextRequest,\n options?: { trackingId?: string }\n): Promise<NextResponse> {\n const { pathname, searchParams } = request.nextUrl;\n\n if (\n pathname.startsWith('/__preview') ||\n pathname.startsWith(AMPLIFY_VARIANT_PREFIX)\n ) {\n return NextResponse.next();\n }\n\n const isPreview =\n searchParams.get('preview') === 'true' ||\n searchParams.get('visualEditor') === 'true';\n\n // Composer-only editor route: live visitors get 404; preview rewrites like any page.\n if (isAmplifyUpEditorRoute(pathname) && !isPreview) {\n return new NextResponse(null, { status: 404 });\n }\n\n if (isPreview) {\n const url = request.nextUrl.clone();\n url.pathname = pathname === '/' ? '/__preview' : `/__preview${pathname}`;\n return NextResponse.rewrite(url);\n }\n\n if (isPrefetch(request)) {\n return NextResponse.next();\n }\n\n const trackingId =\n options?.trackingId ||\n (typeof searchParams.get('trackingId') === 'string'\n ? searchParams.get('trackingId')\n : null) ||\n process.env.NEXT_PUBLIC_AMPLIFYUP_TRACKING_ID ||\n '';\n if (!trackingId) {\n return NextResponse.next();\n }\n\n const existingAnon = request.cookies.get(AMPLIFY_ANON_COOKIE)?.value || '';\n const existingSession = request.cookies.get(AMPLIFY_SESSION_COOKIE)?.value || '';\n if (!existingAnon) {\n const res = NextResponse.next();\n res.cookies.set(AMPLIFY_ANON_COOKIE, generateAnonId(), {\n path: '/',\n maxAge: 60 * 60 * 24 * 365,\n sameSite: 'lax',\n });\n return withSessionCookie(res, existingSession);\n }\n\n const target = resolveAmplifyUpTarget();\n const { edgeUrl } = resolveAmplifyUpUrls(target);\n const route = normalizeRoute(pathname);\n\n try {\n const variantKeys = await fetchEdgeVariants({\n edgeUrl,\n trackingId,\n route,\n anonId: existingAnon,\n });\n if (isDefaultVariantKeys(variantKeys)) {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n const sig = encodeURIComponent(serializeVariantKeys(variantKeys));\n const url = request.nextUrl.clone();\n url.pathname =\n pathname === '/'\n ? `${AMPLIFY_VARIANT_PREFIX}/${sig}`\n : `${AMPLIFY_VARIANT_PREFIX}/${sig}${pathname}`;\n return withSessionCookie(NextResponse.rewrite(url), existingSession);\n } catch {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/edge/fetchVariants.ts","../src/edge/variantKeys.ts","../src/edge/normalizeRoute.ts","../src/targets.ts","../src/reservedRoutes.ts","../src/middleware.ts"],"names":["orchestratorUrl","NextResponse"],"mappings":";;;;;;;;AAIA,eAAsB,kBAAkB,OAAA,EAOJ;AAClC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,OAAA,CAAQ,QAAQ,EAAE,CAAA;AAC/C,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB;AAAA,IACjC,OAAO,OAAA,CAAQ,KAAA;AAAA,IACf,YAAY,OAAA,CAAQ,UAAA;AAAA,IACpB,QAAQ,OAAA,CAAQ;AAAA,GACjB,CAAA;AACD,EAAA,MAAM,UAAU,OAAA,CAAQ,KAAA,IAAS,UAAA,CAAW,KAAA,CAAM,KAAK,UAAU,CAAA;AACjE,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,EAAA,MAAM,KAAA,GAAQ,WAAW,MAAM,UAAA,CAAW,OAAM,EAAG,OAAA,CAAQ,aAAa,GAAG,CAAA;AAC3E,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,MAAM,OAAA,CAAQ,CAAA,EAAG,IAAI,CAAA,aAAA,EAAgB,MAAA,CAAO,QAAA,EAAU,CAAA,CAAA,EAAI;AAAA,MACpE,MAAA,EAAQ,KAAA;AAAA,MACR,OAAA,EAAS,EAAE,MAAA,EAAQ,kBAAA,EAAmB;AAAA,MACtC,KAAA,EAAO,UAAA;AAAA,MACP,QAAQ,UAAA,CAAW;AAAA,KACpB,CAAA;AACD,IAAA,IAAI,CAAC,GAAA,CAAI,EAAA,EAAI,OAAO,EAAC;AACrB,IAAA,MAAM,IAAA,GAAQ,MAAM,GAAA,CAAI,IAAA,GAAO,KAAA,CAAM,OAAO,EAAC,CAAE,CAAA;AAG/C,IAAA,OAAO,IAAA,CAAK,eAAe,OAAO,IAAA,CAAK,gBAAgB,QAAA,GACnD,IAAA,CAAK,cACL,EAAC;AAAA,EACP,CAAA,SAAE;AACA,IAAA,YAAA,CAAa,KAAK,CAAA;AAAA,EACpB;AACF;;;ACjCO,SAAS,qBACd,IAAA,EACQ;AACR,EAAA,IAAI,CAAC,MAAM,OAAO,EAAA;AAClB,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,MAAM,OAAA,GAAU,MAAA,CAAO,IAAA,CAAK,IAAI,EAAE,IAAA,EAAK;AACvC,EAAA,KAAA,MAAW,UAAU,OAAA,EAAS;AAC5B,IAAA,MAAM,OAAA,GAAU,KAAK,MAAM,CAAA;AAC3B,IAAA,IAAI,CAAC,OAAA,IAAW,OAAA,KAAY,SAAA,EAAW;AACvC,IAAA,KAAA,CAAM,IAAA,CAAK,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAE,CAAA;AAAA,EACnC;AACA,EAAA,OAAO,KAAA,CAAM,KAAK,GAAG,CAAA;AACvB;AAmBO,SAAS,qBACd,IAAA,EACS;AACT,EAAA,OAAO,oBAAA,CAAqB,IAAI,CAAA,KAAM,EAAA;AACxC;;;ACpCO,SAAS,eAAe,KAAA,EAAuB;AACpD,EAAA,IAAI,IAAA,GAAO,MAAA,CAAO,KAAA,IAAS,EAAE,EAAE,IAAA,EAAK;AACpC,EAAA,IAAI,CAAC,MAAM,OAAO,GAAA;AAElB,EAAA,IAAI;AACF,IAAA,IAAI,eAAA,CAAgB,IAAA,CAAK,IAAI,CAAA,EAAG;AAC9B,MAAA,IAAA,GAAO,IAAI,GAAA,CAAI,IAAI,CAAA,CAAE,QAAA;AAAA,IACvB;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC1B,EAAA,IAAI,KAAK,CAAA,EAAG,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAClC,EAAA,MAAM,CAAA,GAAI,IAAA,CAAK,OAAA,CAAQ,GAAG,CAAA;AAC1B,EAAA,IAAI,KAAK,CAAA,EAAG,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAC,CAAA;AAElC,EAAA,IAAI,CAAC,IAAA,CAAK,UAAA,CAAW,GAAG,CAAA,EAAG,IAAA,GAAO,IAAI,IAAI,CAAA,CAAA;AAC1C,EAAA,IAAI,KAAK,MAAA,GAAS,CAAA,IAAK,IAAA,CAAK,QAAA,CAAS,GAAG,CAAA,EAAG;AACzC,IAAA,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,MAAA,EAAQ,EAAE,CAAA;AAAA,EAChC;AACA,EAAA,OAAO,IAAA,IAAQ,GAAA;AACjB;;;ACFA,IAAM,WAAA,GAAc,8BAAA;AACpB,IAAM,YAAA,GAAe,0BAAA;AACrB,IAAM,iBAAA,GAAoB,sBAAA;AAC1B,IAAM,SAAA,GAAY,2BAAA;AAEX,SAAS,kBAAkB,KAAA,EAA+C;AAC/E,EAAA,OAAO,KAAA,KAAU,OAAA,IAAW,KAAA,KAAU,KAAA,IAAS,KAAA,KAAU,YAAA;AAC3D;AAEO,SAAS,yBAAyB,KAAA,EAA8C;AACrF,EAAA,OAAO,KAAA,KAAU,QAAQ,OAAA,GAAU,KAAA;AACrC;AAcO,SAAS,uBAAuB,OAAA,EAInB;AASlB,EAAA,MAAM,YACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,CAAQ,IAAI,4BAAA,GACZ,MAAA;AACN,EAAA,IAAI,iBAAA,CAAkB,SAAS,CAAA,EAAG;AAChC,IAAA,OAAO,yBAAyB,SAAS,CAAA;AAAA,EAC3C;AAEA,EAAA,OAAO,YAAA;AACT;AAYA,SAAS,oBAAA,GAA+B;AACtC,EAAA,MAAM,UACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,CAAQ,IAAI,4BAAA,GACZ,MAAA;AACN,EAAA,OAAA,CAAQ,OAAA,IAAW,uBAAA,EAAyB,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAC/D;AAMA,SAAS,cAAA,GAAyB;AAChC,EAAA,MAAM,UACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,CAAQ,IAAI,6BAAA,GACZ,MAAA;AACN,EAAA,OAAA,CAAQ,OAAA,IAAW,WAAA,EAAa,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACnD;AAMA,SAAS,YAAA,GAAuB;AAC9B,EAAA,MAAM,UACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,CAAQ,IAAI,oBAAA,GACZ,MAAA;AACN,EAAA,OAAA,CAAQ,OAAA,IAAW,uBAAA,EAAyB,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AAC/D;AAEO,SAAS,qBAAqB,MAAA,EAAwC;AAC3E,EAAA,IAAI,WAAW,OAAA,EAAS;AACtB,IAAA,MAAMA,mBAAkB,oBAAA,EAAqB;AAC7C,IAAA,MAAM,gBAAgB,cAAA,EAAe;AACrC,IAAA,OAAO;AAAA,MACL,MAAA,EAAQ,OAAA;AAAA;AAAA,MAER,eAAA,EAAAA,gBAAAA;AAAA;AAAA,MAEA,aAAA;AAAA,MACA,cAAA,EAAgB,GAAG,aAAa,CAAA,eAAA,CAAA;AAAA,MAChC,SAAS,YAAA;AAAa,KACxB;AAAA,EACF;AAEA,EAAA,MAAM,WAAA,GACH,OAAO,OAAA,KAAY,WAAA,IAClB,OAAA,CAAQ,IAAI,6BAAA,EAA+B,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,IAC9D,YAAA;AAEF,EAAA,MAAM,sBACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,CAAQ,IAAI,4BAAA,GACZ,MAAA;AAGN,EAAA,MAAM,mBAAA,GACJ,CAAC,CAAC,mBAAA,KACD,mBAAA,CAAoB,SAAS,WAAW,CAAA,IACvC,mBAAA,CAAoB,QAAA,CAAS,WAAW,CAAA,CAAA;AAE5C,EAAA,MAAM,eAAA,GAAkB,uBAAuB,CAAC,mBAAA,GAC5C,oBACA,mBAAA,CAAoB,OAAA,CAAQ,OAAO,EAAE,CAAA;AAEzC,EAAA,MAAM,WAAA,GACJ,OAAO,OAAA,KAAY,WAAA,GACf,OAAA,CAAQ,IAAI,oBAAA,EAAsB,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA,GACnD,MAAA;AACN,EAAA,MAAM,OAAA,GACJ,WAAA,IACA,CAAC,WAAA,CAAY,QAAA,CAAS,WAAW,CAAA,IACjC,CAAC,WAAA,CAAY,QAAA,CAAS,WAAW,CAAA,GAC7B,WAAA,GACA,SAAA;AAEN,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,YAAA;AAAA,IACR,aAAA,EAAe,WAAA;AAAA,IACf,eAAA;AAAA,IACA,cAAA,EAAgB,GAAG,WAAW,CAAA,eAAA,CAAA;AAAA,IAC9B;AAAA,GACF;AACF;;;ACnKO,IAAM,sBAAA,GAAyB;AAE/B,SAAS,uBAAuB,QAAA,EAA2B;AAChE,EAAA,OACE,aAAa,sBAAA,IACb,QAAA,CAAS,UAAA,CAAW,CAAA,EAAG,sBAAsB,CAAA,CAAA,CAAG,CAAA;AAEpD;;;ACgBO,IAAM,sBAAA,GAAyB;AAC/B,IAAM,mBAAA,GAAsB;AAC5B,IAAM,sBAAA,GAAyB;AACtC,IAAM,0BAA0B,EAAA,GAAK,EAAA;AAE9B,IAAM,uBAAA,GAA0B;AAAA,EACrC,OAAA,EAAS,CAAC,2DAA2D;AACvE;AAEA,SAAS,WAAW,OAAA,EAA+B;AACjD,EAAA,OACE,OAAA,CAAQ,QAAQ,GAAA,CAAI,uBAAuB,MAAM,GAAA,IACjD,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,sBAAsB,CAAA,KAAM,OAChD,OAAA,CAAQ,OAAA,CAAQ,IAAI,SAAS,CAAA,KAAM,cACnC,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,SAAS,CAAA,KAAM,UAAA;AAEvC;AAGO,SAAS,uBAAuB,OAAA,EAA+B;AACpE,EAAA,IAAI,UAAA,CAAW,OAAO,CAAA,EAAG,OAAO,IAAA;AAChC,EAAA,MAAM,GAAA,GAAM,QAAQ,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA,IAAK,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,KAAK,CAAA;AACnE,EAAA,IAAI,GAAA,KAAQ,KAAK,OAAO,IAAA;AACxB,EAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,wBAAwB,GAAG,OAAO,IAAA;AAC1D,EAAA,IAAI,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,wBAAwB,GAAG,OAAO,IAAA;AAC1D,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,cAAA,GAAyB;AAChC,EAAA,MAAM,IAAA,GACJ,OAAO,MAAA,KAAW,WAAA,IAAe,gBAAgB,MAAA,GAC7C,MAAA,CAAO,UAAA,EAAW,GAClB,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,KAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAC1D,EAAA,OAAO,WAAW,IAAI,CAAA,CAAA;AACxB;AAEA,SAAS,iBAAA,GAA4B;AACnC,EAAA,OAAO,OAAO,WAAW,WAAA,IAAe,YAAA,IAAgB,SACpD,MAAA,CAAO,UAAA,KACP,CAAA,EAAG,IAAA,CAAK,KAAK,CAAA,CAAA,EAAI,KAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,KAAA,CAAM,CAAC,CAAC,CAAA,CAAA;AAC1D;AAEA,SAAS,iBAAA,CACP,KACA,QAAA,EACc;AACd,EAAA,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,sBAAA,EAAwB,QAAA,IAAY,mBAAkB,EAAG;AAAA,IACvE,IAAA,EAAM,GAAA;AAAA,IACN,MAAA,EAAQ,uBAAA;AAAA,IACR,QAAA,EAAU;AAAA,GACX,CAAA;AACD,EAAA,OAAO,GAAA;AACT;AAOA,eAAsB,iBAAA,CACpB,SACA,OAAA,EACuB;AACvB,EAAA,MAAM,EAAE,QAAA,EAAU,YAAA,EAAa,GAAI,OAAA,CAAQ,OAAA;AAE3C,EAAA,IACE,SAAS,UAAA,CAAW,YAAY,KAChC,QAAA,CAAS,UAAA,CAAW,sBAAsB,CAAA,EAC1C;AACA,IAAA,OAAOC,oBAAa,IAAA,EAAK;AAAA,EAC3B;AAEA,EAAA,MAAM,SAAA,GACJ,aAAa,GAAA,CAAI,SAAS,MAAM,MAAA,IAChC,YAAA,CAAa,GAAA,CAAI,cAAc,CAAA,KAAM,MAAA;AAGvC,EAAA,IAAI,sBAAA,CAAuB,QAAQ,CAAA,IAAK,CAAC,SAAA,EAAW;AAClD,IAAA,OAAO,IAAIA,mBAAA,CAAa,IAAA,EAAM,EAAE,MAAA,EAAQ,KAAK,CAAA;AAAA,EAC/C;AAEA,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,KAAA,EAAM;AAClC,IAAA,GAAA,CAAI,QAAA,GAAW,QAAA,KAAa,GAAA,GAAM,YAAA,GAAe,aAAa,QAAQ,CAAA,CAAA;AACtE,IAAA,OAAOA,mBAAA,CAAa,QAAQ,GAAG,CAAA;AAAA,EACjC;AAGA,EAAA,IAAI,sBAAA,CAAuB,OAAO,CAAA,EAAG;AACnC,IAAA,OAAOA,oBAAa,IAAA,EAAK;AAAA,EAC3B;AAEA,EAAA,MAAM,aACJ,OAAA,EAAS,UAAA,KACR,OAAO,YAAA,CAAa,IAAI,YAAY,CAAA,KAAM,QAAA,GACvC,YAAA,CAAa,IAAI,YAAY,CAAA,GAC7B,IAAA,CAAA,IACJ,OAAA,CAAQ,IAAI,iCAAA,IACZ,EAAA;AACF,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAOA,oBAAa,IAAA,EAAK;AAAA,EAC3B;AAEA,EAAA,MAAM,eAAe,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,mBAAmB,GAAG,KAAA,IAAS,EAAA;AACxE,EAAA,MAAM,kBACJ,OAAA,CAAQ,OAAA,CAAQ,GAAA,CAAI,sBAAsB,GAAG,KAAA,IAAS,EAAA;AAExD,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,MAAM,GAAA,GAAMA,oBAAa,IAAA,EAAK;AAC9B,IAAA,GAAA,CAAI,OAAA,CAAQ,GAAA,CAAI,mBAAA,EAAqB,cAAA,EAAe,EAAG;AAAA,MACrD,IAAA,EAAM,GAAA;AAAA,MACN,MAAA,EAAQ,EAAA,GAAK,EAAA,GAAK,EAAA,GAAK,GAAA;AAAA,MACvB,QAAA,EAAU;AAAA,KACX,CAAA;AACD,IAAA,OAAO,iBAAA,CAAkB,KAAK,eAAe,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,SAAS,sBAAA,EAAuB;AACtC,EAAA,MAAM,EAAE,OAAA,EAAQ,GAAI,oBAAA,CAAqB,MAAM,CAAA;AAC/C,EAAA,MAAM,KAAA,GAAQ,eAAe,QAAQ,CAAA;AAErC,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,MAAM,iBAAA,CAAkB;AAAA,MAC1C,OAAA;AAAA,MACA,UAAA;AAAA,MACA,KAAA;AAAA,MACA,MAAA,EAAQ;AAAA,KACT,CAAA;AACD,IAAA,IAAI,oBAAA,CAAqB,WAAW,CAAA,EAAG;AACrC,MAAA,OAAO,iBAAA,CAAkBA,mBAAA,CAAa,IAAA,EAAK,EAAG,eAAe,CAAA;AAAA,IAC/D;AACA,IAAA,MAAM,GAAA,GAAM,kBAAA,CAAmB,oBAAA,CAAqB,WAAW,CAAC,CAAA;AAChE,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,OAAA,CAAQ,KAAA,EAAM;AAClC,IAAA,GAAA,CAAI,QAAA,GACF,QAAA,KAAa,GAAA,GACT,CAAA,EAAG,sBAAsB,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAChC,CAAA,EAAG,sBAAsB,CAAA,CAAA,EAAI,GAAG,GAAG,QAAQ,CAAA,CAAA;AACjD,IAAA,OAAO,iBAAA,CAAkBA,mBAAA,CAAa,OAAA,CAAQ,GAAG,GAAG,eAAe,CAAA;AAAA,EACrE,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,iBAAA,CAAkBA,mBAAA,CAAa,IAAA,EAAK,EAAG,eAAe,CAAA;AAAA,EAC/D;AACF","file":"middleware.js","sourcesContent":["/**\n * Lightweight Edge call for Next middleware: variant keys only.\n */\n\nexport async function fetchEdgeVariants(options: {\n edgeUrl: string;\n trackingId: string;\n route: string;\n anonId: string;\n fetch?: typeof fetch;\n timeoutMs?: number;\n}): Promise<Record<string, string>> {\n const base = options.edgeUrl.replace(/\\/+$/, '');\n const params = new URLSearchParams({\n route: options.route,\n trackingId: options.trackingId,\n anonId: options.anonId,\n });\n const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 800);\n try {\n const res = await fetchFn(`${base}/v1/variants?${params.toString()}`, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n cache: 'no-store',\n signal: controller.signal,\n });\n if (!res.ok) return {};\n const body = (await res.json().catch(() => ({}))) as {\n variantKeys?: Record<string, string>;\n };\n return body.variantKeys && typeof body.variantKeys === 'object'\n ? body.variantKeys\n : {};\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Compact variant-key codec for URLs and Edge `variants` query params.\n * Default variants are omitted so equivalent assignments share one cache entry.\n */\n\nexport function serializeVariantKeys(\n keys: Record<string, string> | null | undefined\n): string {\n if (!keys) return '';\n const parts: string[] = [];\n const zoneIds = Object.keys(keys).sort();\n for (const zoneId of zoneIds) {\n const variant = keys[zoneId];\n if (!variant || variant === 'default') continue;\n parts.push(`${zoneId}:${variant}`);\n }\n return parts.join(',');\n}\n\nexport function parseVariantKeys(\n raw: string | null | undefined\n): Record<string, string> {\n const out: Record<string, string> = {};\n const text = (raw || '').trim();\n if (!text) return out;\n const decoded = safeDecode(text);\n for (const part of decoded.split(',')) {\n const i = part.indexOf(':');\n if (i <= 0) continue;\n const zoneId = part.slice(0, i).trim();\n const variant = part.slice(i + 1).trim();\n if (zoneId && variant) out[zoneId] = variant;\n }\n return out;\n}\n\nexport function isDefaultVariantKeys(\n keys: Record<string, string> | null | undefined\n): boolean {\n return serializeVariantKeys(keys) === '';\n}\n\nfunction safeDecode(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n","/**\n * Normalize a route path for Edge resolve requests.\n * Leading slash, no trailing slash (except root), query/hash stripped.\n */\nexport function normalizeRoute(route: string): string {\n let path = String(route || '').trim();\n if (!path) return '/';\n\n try {\n if (/^https?:\\/\\//i.test(path)) {\n path = new URL(path).pathname;\n }\n } catch {\n /* keep path */\n }\n\n const q = path.indexOf('?');\n if (q >= 0) path = path.slice(0, q);\n const h = path.indexOf('#');\n if (h >= 0) path = path.slice(0, h);\n\n if (!path.startsWith('/')) path = `/${path}`;\n if (path.length > 1 && path.endsWith('/')) {\n path = path.replace(/\\/+$/, '');\n }\n return path || '/';\n}\n","/**\n * AmplifyUp environment targets\n *\n * Two environments only:\n * - local: apps/config from localhost + Neon; events & personalize from AWS development\n * - production: all production AmplifyUp / AWS endpoints\n *\n * Controlled via `config.target` or `NEXT_PUBLIC_AMPLIFYUP_TARGET`.\n * Legacy value `dev` is treated as `local`.\n */\n\nexport type AmplifyUpTarget = 'local' | 'production';\n\n/** Accepted env/config strings (includes legacy `dev` → local). */\nexport type AmplifyUpTargetInput = AmplifyUpTarget | 'dev';\n\nexport interface AmplifyUpUrls {\n target: AmplifyUpTarget;\n apiGatewayUrl: string;\n orchestratorUrl: string;\n decisionApiUrl: string;\n edgeUrl: string;\n}\n\nconst AWS_DEV_API = 'https://api-dev.amplifyup.ai';\nconst AWS_PROD_API = 'https://api.amplifyup.ai';\nconst PROD_ORCHESTRATOR = 'https://amplifyup.ai';\nconst PROD_EDGE = 'https://edge.amplifyup.ai';\n\nexport function isAmplifyUpTarget(value: unknown): value is AmplifyUpTargetInput {\n return value === 'local' || value === 'dev' || value === 'production';\n}\n\nexport function normalizeAmplifyUpTarget(value: AmplifyUpTargetInput): AmplifyUpTarget {\n return value === 'dev' ? 'local' : value;\n}\n\n/**\n * Resolve which target to use.\n *\n * Priority:\n * 1. explicit config.target\n * 2. config.dev === true → 'local' (local apps + AWS-dev pipeline)\n * 3. NEXT_PUBLIC_AMPLIFYUP_TARGET\n * 4. unset → 'production' (live endpoints — hosting on localhost does NOT imply local)\n *\n * Use `local` only when developing against the AmplifyUp monorepo\n * (set NEXT_PUBLIC_AMPLIFYUP_TARGET=local in .env.local).\n */\nexport function resolveAmplifyUpTarget(options?: {\n configTarget?: AmplifyUpTargetInput;\n /** @deprecated Prefer NEXT_PUBLIC_AMPLIFYUP_TARGET=local. When true, resolves to local. */\n configDev?: boolean;\n}): AmplifyUpTarget {\n if (options?.configTarget && isAmplifyUpTarget(options.configTarget)) {\n return normalizeAmplifyUpTarget(options.configTarget);\n }\n\n if (options?.configDev === true) {\n return 'local';\n }\n\n const envTarget =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_TARGET\n : undefined;\n if (isAmplifyUpTarget(envTarget)) {\n return normalizeAmplifyUpTarget(envTarget);\n }\n\n return 'production';\n}\n\n/** True when the orchestrator origin is a remote AmplifyUp deployment (not localhost). */\nexport function isRemoteOrchestratorUrl(orchestratorUrl: string): boolean {\n try {\n const host = new URL(orchestratorUrl).hostname.toLowerCase();\n return host !== 'localhost' && host !== '127.0.0.1' && host !== '::1';\n } catch {\n return false;\n }\n}\n\nfunction localOrchestratorUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n return (fromEnv || 'http://localhost:5001').replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local→AWS-dev API base (events + personalize).\n * Defaults to https://api-dev.amplifyup.ai\n */\nfunction localAwsApiUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL\n : undefined;\n return (fromEnv || AWS_DEV_API).replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local Edge Worker URL.\n * Defaults to http://localhost:8787\n */\nfunction localEdgeUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL\n : undefined;\n return (fromEnv || 'http://localhost:8787').replace(/\\/$/, '');\n}\n\nexport function resolveAmplifyUpUrls(target: AmplifyUpTarget): AmplifyUpUrls {\n if (target === 'local') {\n const orchestratorUrl = localOrchestratorUrl();\n const apiGatewayUrl = localAwsApiUrl();\n return {\n target: 'local',\n // Layouts / site config / composer APIs → local orchestrator + Neon\n orchestratorUrl,\n // Events + personalize → AWS development stack\n apiGatewayUrl,\n decisionApiUrl: `${apiGatewayUrl}/v1/personalize`,\n edgeUrl: localEdgeUrl(),\n };\n }\n\n const resolvedApi =\n (typeof process !== 'undefined' &&\n process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL?.replace(/\\/$/, '')) ||\n AWS_PROD_API;\n\n const orchestratorFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n\n // Production: don't accidentally use a localhost orchestrator URL from a local env file\n const isLocalOrchestrator =\n !!orchestratorFromEnv &&\n (orchestratorFromEnv.includes('localhost') ||\n orchestratorFromEnv.includes('127.0.0.1'));\n\n const orchestratorUrl = isLocalOrchestrator || !orchestratorFromEnv\n ? PROD_ORCHESTRATOR\n : orchestratorFromEnv.replace(/\\/$/, '');\n\n const edgeFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL?.replace(/\\/$/, '')\n : undefined;\n const edgeUrl =\n edgeFromEnv &&\n !edgeFromEnv.includes('localhost') &&\n !edgeFromEnv.includes('127.0.0.1')\n ? edgeFromEnv\n : PROD_EDGE;\n\n return {\n target: 'production',\n apiGatewayUrl: resolvedApi,\n orchestratorUrl,\n decisionApiUrl: `${resolvedApi}/v1/personalize`,\n edgeUrl,\n };\n}\n","/**\n * Reserved customer-site pathnames owned by AmplifyUp (not marketing URLs).\n */\n\n/** Composer composition / layout editing. Live visitors must not see this page. */\nexport const AMPLIFYUP_EDITOR_ROUTE = '/__amplifyup/editor';\n\nexport function isAmplifyUpEditorRoute(pathname: string): boolean {\n return (\n pathname === AMPLIFYUP_EDITOR_ROUTE ||\n pathname.startsWith(`${AMPLIFYUP_EDITOR_ROUTE}/`)\n );\n}\n","/**\n * Next.js middleware: Composer preview rewrite + variant ISR rewrite.\n * Edge-runtime safe (no Node APIs).\n *\n * Soft-nav safety (Next.js <Link>):\n * App Router client navigations (RSC flight + Link prefetch) must NOT rewrite\n * to `/__p/{keys}/…` or Set-Cookie. Rewriting `/insights/slug` → `/__p/…/insights/slug`\n * during soft nav commonly aborts the transition (preventDefault runs,\n * location.pathname never changes; Ctrl/Cmd-click full loads still work).\n *\n * Personalized HTML for soft nav comes from the SDK client overlay\n * (`/v1/select` + `/v1/resolve`). Full document loads still use `/__p/…` ISR.\n */\n\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport { fetchEdgeVariants } from './edge/fetchVariants';\nimport {\n isDefaultVariantKeys,\n serializeVariantKeys,\n} from './edge/variantKeys';\nimport { normalizeRoute } from './edge/normalizeRoute';\nimport { resolveAmplifyUpTarget, resolveAmplifyUpUrls } from './targets';\nimport {\n isAmplifyUpEditorRoute,\n} from './reservedRoutes';\n\nexport { AMPLIFYUP_EDITOR_ROUTE } from './reservedRoutes';\nexport const AMPLIFY_VARIANT_PREFIX = '/__p';\nexport const AMPLIFY_ANON_COOKIE = 'amplifyup_anon_id';\nexport const AMPLIFY_SESSION_COOKIE = 'amplifyup_session_id';\nconst SESSION_MAX_AGE_SECONDS = 30 * 60;\n\nexport const amplifyMiddlewareConfig = {\n matcher: ['/((?!api|_next/static|_next/image|favicon.ico|.*\\\\..*).*)'],\n};\n\nfunction isPrefetch(request: NextRequest): boolean {\n return (\n request.headers.get('x-middleware-prefetch') === '1' ||\n request.headers.get('Next-Router-Prefetch') === '1' ||\n request.headers.get('purpose') === 'prefetch' ||\n request.headers.get('Purpose') === 'prefetch'\n );\n}\n\n/** App Router flight / soft navigation (including Link prefetch). */\nexport function isNextClientNavigation(request: NextRequest): boolean {\n if (isPrefetch(request)) return true;\n const rsc = request.headers.get('rsc') || request.headers.get('RSC');\n if (rsc === '1') return true;\n if (request.headers.get('next-router-state-tree')) return true;\n if (request.headers.get('Next-Router-State-Tree')) return true;\n return false;\n}\n\nfunction generateAnonId(): string {\n const uuid =\n typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n return `browser_${uuid}`;\n}\n\nfunction generateSessionId(): string {\n return typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction withSessionCookie(\n res: NextResponse,\n existing: string | undefined\n): NextResponse {\n res.cookies.set(AMPLIFY_SESSION_COOKIE, existing || generateSessionId(), {\n path: '/',\n maxAge: SESSION_MAX_AGE_SECONDS,\n sameSite: 'lax',\n });\n return res;\n}\n\n/**\n * Preview stays dynamic. Personalized variants rewrite to `/__p/{keys}/…`\n * on full document loads so Next can SSR the combo once and cache it (ISR).\n * Soft nav / prefetch never rewrite — fail open to the public route.\n */\nexport async function amplifyMiddleware(\n request: NextRequest,\n options?: { trackingId?: string }\n): Promise<NextResponse> {\n const { pathname, searchParams } = request.nextUrl;\n\n if (\n pathname.startsWith('/__preview') ||\n pathname.startsWith(AMPLIFY_VARIANT_PREFIX)\n ) {\n return NextResponse.next();\n }\n\n const isPreview =\n searchParams.get('preview') === 'true' ||\n searchParams.get('visualEditor') === 'true';\n\n // Composer-only editor route: live visitors get 404; preview rewrites like any page.\n if (isAmplifyUpEditorRoute(pathname) && !isPreview) {\n return new NextResponse(null, { status: 404 });\n }\n\n if (isPreview) {\n const url = request.nextUrl.clone();\n url.pathname = pathname === '/' ? '/__preview' : `/__preview${pathname}`;\n return NextResponse.rewrite(url);\n }\n\n // Soft nav / prefetch: never rewrite and never Set-Cookie.\n if (isNextClientNavigation(request)) {\n return NextResponse.next();\n }\n\n const trackingId =\n options?.trackingId ||\n (typeof searchParams.get('trackingId') === 'string'\n ? searchParams.get('trackingId')\n : null) ||\n process.env.NEXT_PUBLIC_AMPLIFYUP_TRACKING_ID ||\n '';\n if (!trackingId) {\n return NextResponse.next();\n }\n\n const existingAnon = request.cookies.get(AMPLIFY_ANON_COOKIE)?.value || '';\n const existingSession =\n request.cookies.get(AMPLIFY_SESSION_COOKIE)?.value || '';\n\n if (!existingAnon) {\n const res = NextResponse.next();\n res.cookies.set(AMPLIFY_ANON_COOKIE, generateAnonId(), {\n path: '/',\n maxAge: 60 * 60 * 24 * 365,\n sameSite: 'lax',\n });\n return withSessionCookie(res, existingSession);\n }\n\n const target = resolveAmplifyUpTarget();\n const { edgeUrl } = resolveAmplifyUpUrls(target);\n const route = normalizeRoute(pathname);\n\n try {\n const variantKeys = await fetchEdgeVariants({\n edgeUrl,\n trackingId,\n route,\n anonId: existingAnon,\n });\n if (isDefaultVariantKeys(variantKeys)) {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n const sig = encodeURIComponent(serializeVariantKeys(variantKeys));\n const url = request.nextUrl.clone();\n url.pathname =\n pathname === '/'\n ? `${AMPLIFY_VARIANT_PREFIX}/${sig}`\n : `${AMPLIFY_VARIANT_PREFIX}/${sig}${pathname}`;\n return withSessionCookie(NextResponse.rewrite(url), existingSession);\n } catch {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n}\n"]}
@@ -142,6 +142,14 @@ var amplifyMiddlewareConfig = {
142
142
  function isPrefetch(request) {
143
143
  return request.headers.get("x-middleware-prefetch") === "1" || request.headers.get("Next-Router-Prefetch") === "1" || request.headers.get("purpose") === "prefetch" || request.headers.get("Purpose") === "prefetch";
144
144
  }
145
+ function isNextClientNavigation(request) {
146
+ if (isPrefetch(request)) return true;
147
+ const rsc = request.headers.get("rsc") || request.headers.get("RSC");
148
+ if (rsc === "1") return true;
149
+ if (request.headers.get("next-router-state-tree")) return true;
150
+ if (request.headers.get("Next-Router-State-Tree")) return true;
151
+ return false;
152
+ }
145
153
  function generateAnonId() {
146
154
  const uuid = typeof crypto !== "undefined" && "randomUUID" in crypto ? crypto.randomUUID() : `${Date.now()}-${Math.random().toString(16).slice(2)}`;
147
155
  return `browser_${uuid}`;
@@ -171,7 +179,7 @@ async function amplifyMiddleware(request, options) {
171
179
  url.pathname = pathname === "/" ? "/__preview" : `/__preview${pathname}`;
172
180
  return NextResponse.rewrite(url);
173
181
  }
174
- if (isPrefetch(request)) {
182
+ if (isNextClientNavigation(request)) {
175
183
  return NextResponse.next();
176
184
  }
177
185
  const trackingId = options?.trackingId || (typeof searchParams.get("trackingId") === "string" ? searchParams.get("trackingId") : null) || process.env.NEXT_PUBLIC_AMPLIFYUP_TRACKING_ID || "";
@@ -211,6 +219,6 @@ async function amplifyMiddleware(request, options) {
211
219
  }
212
220
  }
213
221
 
214
- export { AMPLIFYUP_EDITOR_ROUTE, AMPLIFY_ANON_COOKIE, AMPLIFY_SESSION_COOKIE, AMPLIFY_VARIANT_PREFIX, amplifyMiddleware, amplifyMiddlewareConfig };
222
+ export { AMPLIFYUP_EDITOR_ROUTE, AMPLIFY_ANON_COOKIE, AMPLIFY_SESSION_COOKIE, AMPLIFY_VARIANT_PREFIX, amplifyMiddleware, amplifyMiddlewareConfig, isNextClientNavigation };
215
223
  //# sourceMappingURL=middleware.mjs.map
216
224
  //# sourceMappingURL=middleware.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/edge/fetchVariants.ts","../src/edge/variantKeys.ts","../src/edge/normalizeRoute.ts","../src/targets.ts","../src/reservedRoutes.ts","../src/middleware.ts"],"names":["orchestratorUrl"],"mappings":"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","file":"middleware.mjs","sourcesContent":["/**\n * Lightweight Edge call for Next middleware: variant keys only.\n */\n\nexport async function fetchEdgeVariants(options: {\n edgeUrl: string;\n trackingId: string;\n route: string;\n anonId: string;\n fetch?: typeof fetch;\n timeoutMs?: number;\n}): Promise<Record<string, string>> {\n const base = options.edgeUrl.replace(/\\/+$/, '');\n const params = new URLSearchParams({\n route: options.route,\n trackingId: options.trackingId,\n anonId: options.anonId,\n });\n const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 800);\n try {\n const res = await fetchFn(`${base}/v1/variants?${params.toString()}`, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n cache: 'no-store',\n signal: controller.signal,\n });\n if (!res.ok) return {};\n const body = (await res.json().catch(() => ({}))) as {\n variantKeys?: Record<string, string>;\n };\n return body.variantKeys && typeof body.variantKeys === 'object'\n ? body.variantKeys\n : {};\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Compact variant-key codec for URLs and Edge `variants` query params.\n * Default variants are omitted so equivalent assignments share one cache entry.\n */\n\nexport function serializeVariantKeys(\n keys: Record<string, string> | null | undefined\n): string {\n if (!keys) return '';\n const parts: string[] = [];\n const zoneIds = Object.keys(keys).sort();\n for (const zoneId of zoneIds) {\n const variant = keys[zoneId];\n if (!variant || variant === 'default') continue;\n parts.push(`${zoneId}:${variant}`);\n }\n return parts.join(',');\n}\n\nexport function parseVariantKeys(\n raw: string | null | undefined\n): Record<string, string> {\n const out: Record<string, string> = {};\n const text = (raw || '').trim();\n if (!text) return out;\n const decoded = safeDecode(text);\n for (const part of decoded.split(',')) {\n const i = part.indexOf(':');\n if (i <= 0) continue;\n const zoneId = part.slice(0, i).trim();\n const variant = part.slice(i + 1).trim();\n if (zoneId && variant) out[zoneId] = variant;\n }\n return out;\n}\n\nexport function isDefaultVariantKeys(\n keys: Record<string, string> | null | undefined\n): boolean {\n return serializeVariantKeys(keys) === '';\n}\n\nfunction safeDecode(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n","/**\n * Normalize a route path for Edge resolve requests.\n * Leading slash, no trailing slash (except root), query/hash stripped.\n */\nexport function normalizeRoute(route: string): string {\n let path = String(route || '').trim();\n if (!path) return '/';\n\n try {\n if (/^https?:\\/\\//i.test(path)) {\n path = new URL(path).pathname;\n }\n } catch {\n /* keep path */\n }\n\n const q = path.indexOf('?');\n if (q >= 0) path = path.slice(0, q);\n const h = path.indexOf('#');\n if (h >= 0) path = path.slice(0, h);\n\n if (!path.startsWith('/')) path = `/${path}`;\n if (path.length > 1 && path.endsWith('/')) {\n path = path.replace(/\\/+$/, '');\n }\n return path || '/';\n}\n","/**\n * AmplifyUp environment targets\n *\n * Two environments only:\n * - local: apps/config from localhost + Neon; events & personalize from AWS development\n * - production: all production AmplifyUp / AWS endpoints\n *\n * Controlled via `config.target` or `NEXT_PUBLIC_AMPLIFYUP_TARGET`.\n * Legacy value `dev` is treated as `local`.\n */\n\nexport type AmplifyUpTarget = 'local' | 'production';\n\n/** Accepted env/config strings (includes legacy `dev` → local). */\nexport type AmplifyUpTargetInput = AmplifyUpTarget | 'dev';\n\nexport interface AmplifyUpUrls {\n target: AmplifyUpTarget;\n apiGatewayUrl: string;\n orchestratorUrl: string;\n decisionApiUrl: string;\n edgeUrl: string;\n}\n\nconst AWS_DEV_API = 'https://api-dev.amplifyup.ai';\nconst AWS_PROD_API = 'https://api.amplifyup.ai';\nconst PROD_ORCHESTRATOR = 'https://amplifyup.ai';\nconst PROD_EDGE = 'https://edge.amplifyup.ai';\n\nexport function isAmplifyUpTarget(value: unknown): value is AmplifyUpTargetInput {\n return value === 'local' || value === 'dev' || value === 'production';\n}\n\nexport function normalizeAmplifyUpTarget(value: AmplifyUpTargetInput): AmplifyUpTarget {\n return value === 'dev' ? 'local' : value;\n}\n\n/**\n * Resolve which target to use.\n *\n * Priority:\n * 1. explicit config.target\n * 2. config.dev === true → 'local' (local apps + AWS-dev pipeline)\n * 3. NEXT_PUBLIC_AMPLIFYUP_TARGET\n * 4. unset → 'production' (live endpoints — hosting on localhost does NOT imply local)\n *\n * Use `local` only when developing against the AmplifyUp monorepo\n * (set NEXT_PUBLIC_AMPLIFYUP_TARGET=local in .env.local).\n */\nexport function resolveAmplifyUpTarget(options?: {\n configTarget?: AmplifyUpTargetInput;\n /** @deprecated Prefer NEXT_PUBLIC_AMPLIFYUP_TARGET=local. When true, resolves to local. */\n configDev?: boolean;\n}): AmplifyUpTarget {\n if (options?.configTarget && isAmplifyUpTarget(options.configTarget)) {\n return normalizeAmplifyUpTarget(options.configTarget);\n }\n\n if (options?.configDev === true) {\n return 'local';\n }\n\n const envTarget =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_TARGET\n : undefined;\n if (isAmplifyUpTarget(envTarget)) {\n return normalizeAmplifyUpTarget(envTarget);\n }\n\n return 'production';\n}\n\n/** True when the orchestrator origin is a remote AmplifyUp deployment (not localhost). */\nexport function isRemoteOrchestratorUrl(orchestratorUrl: string): boolean {\n try {\n const host = new URL(orchestratorUrl).hostname.toLowerCase();\n return host !== 'localhost' && host !== '127.0.0.1' && host !== '::1';\n } catch {\n return false;\n }\n}\n\nfunction localOrchestratorUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n return (fromEnv || 'http://localhost:5001').replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local→AWS-dev API base (events + personalize).\n * Defaults to https://api-dev.amplifyup.ai\n */\nfunction localAwsApiUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL\n : undefined;\n return (fromEnv || AWS_DEV_API).replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local Edge Worker URL.\n * Defaults to http://localhost:8787\n */\nfunction localEdgeUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL\n : undefined;\n return (fromEnv || 'http://localhost:8787').replace(/\\/$/, '');\n}\n\nexport function resolveAmplifyUpUrls(target: AmplifyUpTarget): AmplifyUpUrls {\n if (target === 'local') {\n const orchestratorUrl = localOrchestratorUrl();\n const apiGatewayUrl = localAwsApiUrl();\n return {\n target: 'local',\n // Layouts / site config / composer APIs → local orchestrator + Neon\n orchestratorUrl,\n // Events + personalize → AWS development stack\n apiGatewayUrl,\n decisionApiUrl: `${apiGatewayUrl}/v1/personalize`,\n edgeUrl: localEdgeUrl(),\n };\n }\n\n const resolvedApi =\n (typeof process !== 'undefined' &&\n process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL?.replace(/\\/$/, '')) ||\n AWS_PROD_API;\n\n const orchestratorFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n\n // Production: don't accidentally use a localhost orchestrator URL from a local env file\n const isLocalOrchestrator =\n !!orchestratorFromEnv &&\n (orchestratorFromEnv.includes('localhost') ||\n orchestratorFromEnv.includes('127.0.0.1'));\n\n const orchestratorUrl = isLocalOrchestrator || !orchestratorFromEnv\n ? PROD_ORCHESTRATOR\n : orchestratorFromEnv.replace(/\\/$/, '');\n\n const edgeFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL?.replace(/\\/$/, '')\n : undefined;\n const edgeUrl =\n edgeFromEnv &&\n !edgeFromEnv.includes('localhost') &&\n !edgeFromEnv.includes('127.0.0.1')\n ? edgeFromEnv\n : PROD_EDGE;\n\n return {\n target: 'production',\n apiGatewayUrl: resolvedApi,\n orchestratorUrl,\n decisionApiUrl: `${resolvedApi}/v1/personalize`,\n edgeUrl,\n };\n}\n","/**\n * Reserved customer-site pathnames owned by AmplifyUp (not marketing URLs).\n */\n\n/** Composer composition / layout editing. Live visitors must not see this page. */\nexport const AMPLIFYUP_EDITOR_ROUTE = '/__amplifyup/editor';\n\nexport function isAmplifyUpEditorRoute(pathname: string): boolean {\n return (\n pathname === AMPLIFYUP_EDITOR_ROUTE ||\n pathname.startsWith(`${AMPLIFYUP_EDITOR_ROUTE}/`)\n );\n}\n","/**\n * Next.js middleware: Composer preview rewrite + variant ISR rewrite.\n * Edge-runtime safe (no Node APIs).\n */\n\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport { fetchEdgeVariants } from './edge/fetchVariants';\nimport {\n isDefaultVariantKeys,\n serializeVariantKeys,\n} from './edge/variantKeys';\nimport { normalizeRoute } from './edge/normalizeRoute';\nimport { resolveAmplifyUpTarget, resolveAmplifyUpUrls } from './targets';\nimport {\n isAmplifyUpEditorRoute,\n} from './reservedRoutes';\n\nexport { AMPLIFYUP_EDITOR_ROUTE } from './reservedRoutes';\nexport const AMPLIFY_VARIANT_PREFIX = '/__p';\nexport const AMPLIFY_ANON_COOKIE = 'amplifyup_anon_id';\nexport const AMPLIFY_SESSION_COOKIE = 'amplifyup_session_id';\nconst SESSION_MAX_AGE_SECONDS = 30 * 60;\n\nexport const amplifyMiddlewareConfig = {\n matcher: ['/((?!api|_next/static|_next/image|favicon.ico|.*\\\\..*).*)'],\n};\n\nfunction isPrefetch(request: NextRequest): boolean {\n return (\n request.headers.get('x-middleware-prefetch') === '1' ||\n request.headers.get('Next-Router-Prefetch') === '1' ||\n request.headers.get('purpose') === 'prefetch' ||\n request.headers.get('Purpose') === 'prefetch'\n );\n}\n\nfunction generateAnonId(): string {\n const uuid =\n typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n return `browser_${uuid}`;\n}\n\nfunction generateSessionId(): string {\n return typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction withSessionCookie(res: NextResponse, existing?: string): NextResponse {\n res.cookies.set(AMPLIFY_SESSION_COOKIE, existing || generateSessionId(), {\n path: '/',\n maxAge: SESSION_MAX_AGE_SECONDS,\n sameSite: 'lax',\n });\n return res;\n}\n\n/**\n * Preview stays dynamic. Personalized variants rewrite to `/__p/{keys}/…`\n * so Next can SSR the combo once and cache it (ISR). Default traffic is\n * unchanged SSG. Fail open to the default page on Edge errors/timeouts.\n */\nexport async function amplifyMiddleware(\n request: NextRequest,\n options?: { trackingId?: string }\n): Promise<NextResponse> {\n const { pathname, searchParams } = request.nextUrl;\n\n if (\n pathname.startsWith('/__preview') ||\n pathname.startsWith(AMPLIFY_VARIANT_PREFIX)\n ) {\n return NextResponse.next();\n }\n\n const isPreview =\n searchParams.get('preview') === 'true' ||\n searchParams.get('visualEditor') === 'true';\n\n // Composer-only editor route: live visitors get 404; preview rewrites like any page.\n if (isAmplifyUpEditorRoute(pathname) && !isPreview) {\n return new NextResponse(null, { status: 404 });\n }\n\n if (isPreview) {\n const url = request.nextUrl.clone();\n url.pathname = pathname === '/' ? '/__preview' : `/__preview${pathname}`;\n return NextResponse.rewrite(url);\n }\n\n if (isPrefetch(request)) {\n return NextResponse.next();\n }\n\n const trackingId =\n options?.trackingId ||\n (typeof searchParams.get('trackingId') === 'string'\n ? searchParams.get('trackingId')\n : null) ||\n process.env.NEXT_PUBLIC_AMPLIFYUP_TRACKING_ID ||\n '';\n if (!trackingId) {\n return NextResponse.next();\n }\n\n const existingAnon = request.cookies.get(AMPLIFY_ANON_COOKIE)?.value || '';\n const existingSession = request.cookies.get(AMPLIFY_SESSION_COOKIE)?.value || '';\n if (!existingAnon) {\n const res = NextResponse.next();\n res.cookies.set(AMPLIFY_ANON_COOKIE, generateAnonId(), {\n path: '/',\n maxAge: 60 * 60 * 24 * 365,\n sameSite: 'lax',\n });\n return withSessionCookie(res, existingSession);\n }\n\n const target = resolveAmplifyUpTarget();\n const { edgeUrl } = resolveAmplifyUpUrls(target);\n const route = normalizeRoute(pathname);\n\n try {\n const variantKeys = await fetchEdgeVariants({\n edgeUrl,\n trackingId,\n route,\n anonId: existingAnon,\n });\n if (isDefaultVariantKeys(variantKeys)) {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n const sig = encodeURIComponent(serializeVariantKeys(variantKeys));\n const url = request.nextUrl.clone();\n url.pathname =\n pathname === '/'\n ? `${AMPLIFY_VARIANT_PREFIX}/${sig}`\n : `${AMPLIFY_VARIANT_PREFIX}/${sig}${pathname}`;\n return withSessionCookie(NextResponse.rewrite(url), existingSession);\n } catch {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/edge/fetchVariants.ts","../src/edge/variantKeys.ts","../src/edge/normalizeRoute.ts","../src/targets.ts","../src/reservedRoutes.ts","../src/middleware.ts"],"names":["orchestratorUrl"],"mappings":"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","file":"middleware.mjs","sourcesContent":["/**\n * Lightweight Edge call for Next middleware: variant keys only.\n */\n\nexport async function fetchEdgeVariants(options: {\n edgeUrl: string;\n trackingId: string;\n route: string;\n anonId: string;\n fetch?: typeof fetch;\n timeoutMs?: number;\n}): Promise<Record<string, string>> {\n const base = options.edgeUrl.replace(/\\/+$/, '');\n const params = new URLSearchParams({\n route: options.route,\n trackingId: options.trackingId,\n anonId: options.anonId,\n });\n const fetchFn = options.fetch ?? globalThis.fetch.bind(globalThis);\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? 800);\n try {\n const res = await fetchFn(`${base}/v1/variants?${params.toString()}`, {\n method: 'GET',\n headers: { Accept: 'application/json' },\n cache: 'no-store',\n signal: controller.signal,\n });\n if (!res.ok) return {};\n const body = (await res.json().catch(() => ({}))) as {\n variantKeys?: Record<string, string>;\n };\n return body.variantKeys && typeof body.variantKeys === 'object'\n ? body.variantKeys\n : {};\n } finally {\n clearTimeout(timer);\n }\n}\n","/**\n * Compact variant-key codec for URLs and Edge `variants` query params.\n * Default variants are omitted so equivalent assignments share one cache entry.\n */\n\nexport function serializeVariantKeys(\n keys: Record<string, string> | null | undefined\n): string {\n if (!keys) return '';\n const parts: string[] = [];\n const zoneIds = Object.keys(keys).sort();\n for (const zoneId of zoneIds) {\n const variant = keys[zoneId];\n if (!variant || variant === 'default') continue;\n parts.push(`${zoneId}:${variant}`);\n }\n return parts.join(',');\n}\n\nexport function parseVariantKeys(\n raw: string | null | undefined\n): Record<string, string> {\n const out: Record<string, string> = {};\n const text = (raw || '').trim();\n if (!text) return out;\n const decoded = safeDecode(text);\n for (const part of decoded.split(',')) {\n const i = part.indexOf(':');\n if (i <= 0) continue;\n const zoneId = part.slice(0, i).trim();\n const variant = part.slice(i + 1).trim();\n if (zoneId && variant) out[zoneId] = variant;\n }\n return out;\n}\n\nexport function isDefaultVariantKeys(\n keys: Record<string, string> | null | undefined\n): boolean {\n return serializeVariantKeys(keys) === '';\n}\n\nfunction safeDecode(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n","/**\n * Normalize a route path for Edge resolve requests.\n * Leading slash, no trailing slash (except root), query/hash stripped.\n */\nexport function normalizeRoute(route: string): string {\n let path = String(route || '').trim();\n if (!path) return '/';\n\n try {\n if (/^https?:\\/\\//i.test(path)) {\n path = new URL(path).pathname;\n }\n } catch {\n /* keep path */\n }\n\n const q = path.indexOf('?');\n if (q >= 0) path = path.slice(0, q);\n const h = path.indexOf('#');\n if (h >= 0) path = path.slice(0, h);\n\n if (!path.startsWith('/')) path = `/${path}`;\n if (path.length > 1 && path.endsWith('/')) {\n path = path.replace(/\\/+$/, '');\n }\n return path || '/';\n}\n","/**\n * AmplifyUp environment targets\n *\n * Two environments only:\n * - local: apps/config from localhost + Neon; events & personalize from AWS development\n * - production: all production AmplifyUp / AWS endpoints\n *\n * Controlled via `config.target` or `NEXT_PUBLIC_AMPLIFYUP_TARGET`.\n * Legacy value `dev` is treated as `local`.\n */\n\nexport type AmplifyUpTarget = 'local' | 'production';\n\n/** Accepted env/config strings (includes legacy `dev` → local). */\nexport type AmplifyUpTargetInput = AmplifyUpTarget | 'dev';\n\nexport interface AmplifyUpUrls {\n target: AmplifyUpTarget;\n apiGatewayUrl: string;\n orchestratorUrl: string;\n decisionApiUrl: string;\n edgeUrl: string;\n}\n\nconst AWS_DEV_API = 'https://api-dev.amplifyup.ai';\nconst AWS_PROD_API = 'https://api.amplifyup.ai';\nconst PROD_ORCHESTRATOR = 'https://amplifyup.ai';\nconst PROD_EDGE = 'https://edge.amplifyup.ai';\n\nexport function isAmplifyUpTarget(value: unknown): value is AmplifyUpTargetInput {\n return value === 'local' || value === 'dev' || value === 'production';\n}\n\nexport function normalizeAmplifyUpTarget(value: AmplifyUpTargetInput): AmplifyUpTarget {\n return value === 'dev' ? 'local' : value;\n}\n\n/**\n * Resolve which target to use.\n *\n * Priority:\n * 1. explicit config.target\n * 2. config.dev === true → 'local' (local apps + AWS-dev pipeline)\n * 3. NEXT_PUBLIC_AMPLIFYUP_TARGET\n * 4. unset → 'production' (live endpoints — hosting on localhost does NOT imply local)\n *\n * Use `local` only when developing against the AmplifyUp monorepo\n * (set NEXT_PUBLIC_AMPLIFYUP_TARGET=local in .env.local).\n */\nexport function resolveAmplifyUpTarget(options?: {\n configTarget?: AmplifyUpTargetInput;\n /** @deprecated Prefer NEXT_PUBLIC_AMPLIFYUP_TARGET=local. When true, resolves to local. */\n configDev?: boolean;\n}): AmplifyUpTarget {\n if (options?.configTarget && isAmplifyUpTarget(options.configTarget)) {\n return normalizeAmplifyUpTarget(options.configTarget);\n }\n\n if (options?.configDev === true) {\n return 'local';\n }\n\n const envTarget =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_TARGET\n : undefined;\n if (isAmplifyUpTarget(envTarget)) {\n return normalizeAmplifyUpTarget(envTarget);\n }\n\n return 'production';\n}\n\n/** True when the orchestrator origin is a remote AmplifyUp deployment (not localhost). */\nexport function isRemoteOrchestratorUrl(orchestratorUrl: string): boolean {\n try {\n const host = new URL(orchestratorUrl).hostname.toLowerCase();\n return host !== 'localhost' && host !== '127.0.0.1' && host !== '::1';\n } catch {\n return false;\n }\n}\n\nfunction localOrchestratorUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n return (fromEnv || 'http://localhost:5001').replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local→AWS-dev API base (events + personalize).\n * Defaults to https://api-dev.amplifyup.ai\n */\nfunction localAwsApiUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL\n : undefined;\n return (fromEnv || AWS_DEV_API).replace(/\\/$/, '');\n}\n\n/**\n * Optional override for the local Edge Worker URL.\n * Defaults to http://localhost:8787\n */\nfunction localEdgeUrl(): string {\n const fromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL\n : undefined;\n return (fromEnv || 'http://localhost:8787').replace(/\\/$/, '');\n}\n\nexport function resolveAmplifyUpUrls(target: AmplifyUpTarget): AmplifyUpUrls {\n if (target === 'local') {\n const orchestratorUrl = localOrchestratorUrl();\n const apiGatewayUrl = localAwsApiUrl();\n return {\n target: 'local',\n // Layouts / site config / composer APIs → local orchestrator + Neon\n orchestratorUrl,\n // Events + personalize → AWS development stack\n apiGatewayUrl,\n decisionApiUrl: `${apiGatewayUrl}/v1/personalize`,\n edgeUrl: localEdgeUrl(),\n };\n }\n\n const resolvedApi =\n (typeof process !== 'undefined' &&\n process.env.NEXT_PUBLIC_AMPLIFYUP_API_URL?.replace(/\\/$/, '')) ||\n AWS_PROD_API;\n\n const orchestratorFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_ORCHESTRATOR_URL\n : undefined;\n\n // Production: don't accidentally use a localhost orchestrator URL from a local env file\n const isLocalOrchestrator =\n !!orchestratorFromEnv &&\n (orchestratorFromEnv.includes('localhost') ||\n orchestratorFromEnv.includes('127.0.0.1'));\n\n const orchestratorUrl = isLocalOrchestrator || !orchestratorFromEnv\n ? PROD_ORCHESTRATOR\n : orchestratorFromEnv.replace(/\\/$/, '');\n\n const edgeFromEnv =\n typeof process !== 'undefined'\n ? process.env.NEXT_PUBLIC_EDGE_URL?.replace(/\\/$/, '')\n : undefined;\n const edgeUrl =\n edgeFromEnv &&\n !edgeFromEnv.includes('localhost') &&\n !edgeFromEnv.includes('127.0.0.1')\n ? edgeFromEnv\n : PROD_EDGE;\n\n return {\n target: 'production',\n apiGatewayUrl: resolvedApi,\n orchestratorUrl,\n decisionApiUrl: `${resolvedApi}/v1/personalize`,\n edgeUrl,\n };\n}\n","/**\n * Reserved customer-site pathnames owned by AmplifyUp (not marketing URLs).\n */\n\n/** Composer composition / layout editing. Live visitors must not see this page. */\nexport const AMPLIFYUP_EDITOR_ROUTE = '/__amplifyup/editor';\n\nexport function isAmplifyUpEditorRoute(pathname: string): boolean {\n return (\n pathname === AMPLIFYUP_EDITOR_ROUTE ||\n pathname.startsWith(`${AMPLIFYUP_EDITOR_ROUTE}/`)\n );\n}\n","/**\n * Next.js middleware: Composer preview rewrite + variant ISR rewrite.\n * Edge-runtime safe (no Node APIs).\n *\n * Soft-nav safety (Next.js <Link>):\n * App Router client navigations (RSC flight + Link prefetch) must NOT rewrite\n * to `/__p/{keys}/…` or Set-Cookie. Rewriting `/insights/slug` → `/__p/…/insights/slug`\n * during soft nav commonly aborts the transition (preventDefault runs,\n * location.pathname never changes; Ctrl/Cmd-click full loads still work).\n *\n * Personalized HTML for soft nav comes from the SDK client overlay\n * (`/v1/select` + `/v1/resolve`). Full document loads still use `/__p/…` ISR.\n */\n\nimport { NextResponse } from 'next/server';\nimport type { NextRequest } from 'next/server';\nimport { fetchEdgeVariants } from './edge/fetchVariants';\nimport {\n isDefaultVariantKeys,\n serializeVariantKeys,\n} from './edge/variantKeys';\nimport { normalizeRoute } from './edge/normalizeRoute';\nimport { resolveAmplifyUpTarget, resolveAmplifyUpUrls } from './targets';\nimport {\n isAmplifyUpEditorRoute,\n} from './reservedRoutes';\n\nexport { AMPLIFYUP_EDITOR_ROUTE } from './reservedRoutes';\nexport const AMPLIFY_VARIANT_PREFIX = '/__p';\nexport const AMPLIFY_ANON_COOKIE = 'amplifyup_anon_id';\nexport const AMPLIFY_SESSION_COOKIE = 'amplifyup_session_id';\nconst SESSION_MAX_AGE_SECONDS = 30 * 60;\n\nexport const amplifyMiddlewareConfig = {\n matcher: ['/((?!api|_next/static|_next/image|favicon.ico|.*\\\\..*).*)'],\n};\n\nfunction isPrefetch(request: NextRequest): boolean {\n return (\n request.headers.get('x-middleware-prefetch') === '1' ||\n request.headers.get('Next-Router-Prefetch') === '1' ||\n request.headers.get('purpose') === 'prefetch' ||\n request.headers.get('Purpose') === 'prefetch'\n );\n}\n\n/** App Router flight / soft navigation (including Link prefetch). */\nexport function isNextClientNavigation(request: NextRequest): boolean {\n if (isPrefetch(request)) return true;\n const rsc = request.headers.get('rsc') || request.headers.get('RSC');\n if (rsc === '1') return true;\n if (request.headers.get('next-router-state-tree')) return true;\n if (request.headers.get('Next-Router-State-Tree')) return true;\n return false;\n}\n\nfunction generateAnonId(): string {\n const uuid =\n typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n return `browser_${uuid}`;\n}\n\nfunction generateSessionId(): string {\n return typeof crypto !== 'undefined' && 'randomUUID' in crypto\n ? crypto.randomUUID()\n : `${Date.now()}-${Math.random().toString(16).slice(2)}`;\n}\n\nfunction withSessionCookie(\n res: NextResponse,\n existing: string | undefined\n): NextResponse {\n res.cookies.set(AMPLIFY_SESSION_COOKIE, existing || generateSessionId(), {\n path: '/',\n maxAge: SESSION_MAX_AGE_SECONDS,\n sameSite: 'lax',\n });\n return res;\n}\n\n/**\n * Preview stays dynamic. Personalized variants rewrite to `/__p/{keys}/…`\n * on full document loads so Next can SSR the combo once and cache it (ISR).\n * Soft nav / prefetch never rewrite — fail open to the public route.\n */\nexport async function amplifyMiddleware(\n request: NextRequest,\n options?: { trackingId?: string }\n): Promise<NextResponse> {\n const { pathname, searchParams } = request.nextUrl;\n\n if (\n pathname.startsWith('/__preview') ||\n pathname.startsWith(AMPLIFY_VARIANT_PREFIX)\n ) {\n return NextResponse.next();\n }\n\n const isPreview =\n searchParams.get('preview') === 'true' ||\n searchParams.get('visualEditor') === 'true';\n\n // Composer-only editor route: live visitors get 404; preview rewrites like any page.\n if (isAmplifyUpEditorRoute(pathname) && !isPreview) {\n return new NextResponse(null, { status: 404 });\n }\n\n if (isPreview) {\n const url = request.nextUrl.clone();\n url.pathname = pathname === '/' ? '/__preview' : `/__preview${pathname}`;\n return NextResponse.rewrite(url);\n }\n\n // Soft nav / prefetch: never rewrite and never Set-Cookie.\n if (isNextClientNavigation(request)) {\n return NextResponse.next();\n }\n\n const trackingId =\n options?.trackingId ||\n (typeof searchParams.get('trackingId') === 'string'\n ? searchParams.get('trackingId')\n : null) ||\n process.env.NEXT_PUBLIC_AMPLIFYUP_TRACKING_ID ||\n '';\n if (!trackingId) {\n return NextResponse.next();\n }\n\n const existingAnon = request.cookies.get(AMPLIFY_ANON_COOKIE)?.value || '';\n const existingSession =\n request.cookies.get(AMPLIFY_SESSION_COOKIE)?.value || '';\n\n if (!existingAnon) {\n const res = NextResponse.next();\n res.cookies.set(AMPLIFY_ANON_COOKIE, generateAnonId(), {\n path: '/',\n maxAge: 60 * 60 * 24 * 365,\n sameSite: 'lax',\n });\n return withSessionCookie(res, existingSession);\n }\n\n const target = resolveAmplifyUpTarget();\n const { edgeUrl } = resolveAmplifyUpUrls(target);\n const route = normalizeRoute(pathname);\n\n try {\n const variantKeys = await fetchEdgeVariants({\n edgeUrl,\n trackingId,\n route,\n anonId: existingAnon,\n });\n if (isDefaultVariantKeys(variantKeys)) {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n const sig = encodeURIComponent(serializeVariantKeys(variantKeys));\n const url = request.nextUrl.clone();\n url.pathname =\n pathname === '/'\n ? `${AMPLIFY_VARIANT_PREFIX}/${sig}`\n : `${AMPLIFY_VARIANT_PREFIX}/${sig}${pathname}`;\n return withSessionCookie(NextResponse.rewrite(url), existingSession);\n } catch {\n return withSessionCookie(NextResponse.next(), existingSession);\n }\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@amplifyup/sdk",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "description": "AmplifyUp Tracking SDK - CDP-agnostic event tracking library",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",