@gradial/aci 0.1.52-rc.8 → 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.
- package/CHANGELOG.md +126 -0
- package/README.md +86 -5
- package/dist/astro/error-page.js +1 -0
- package/dist/astro/index.js +4 -0
- package/dist/astro/page.d.ts +5 -2
- package/dist/astro/page.js +35 -23
- package/dist/astro/preview.js +2 -17
- package/dist/audience-data-models.d.ts +308 -197
- package/dist/audience-data-models.js +313 -51
- package/dist/cli/compile-registry.mjs +6 -34
- package/dist/cli/mintlify-render.mjs +8 -0
- package/dist/collect/aci.js +1 -1
- package/dist/collect/aci.js.sha256 +1 -1
- package/dist/collect/api.d.ts +6 -7
- package/dist/collect/api.js +21 -8
- package/dist/collect/assignments.d.ts +7 -9
- package/dist/collect/assignments.js +23 -32
- package/dist/collect/batcher.d.ts +9 -7
- package/dist/collect/batcher.js +6 -5
- package/dist/collect/consent/envelope.d.ts +7 -1
- package/dist/collect/consent/envelope.js +3 -1
- package/dist/collect/consent/mapping.d.ts +2 -0
- package/dist/collect/consent/mapping.js +1 -0
- package/dist/collect/consenthold.d.ts +38 -0
- package/dist/collect/consenthold.js +82 -0
- package/dist/collect/declarative.js +7 -5
- package/dist/collect/gapbuffer.d.ts +13 -4
- package/dist/collect/gapbuffer.js +21 -10
- package/dist/collect/index.js +78 -21
- package/dist/collect/pageviews.d.ts +11 -11
- package/dist/collect/pageviews.js +27 -22
- package/dist/consent-banner/index.d.ts +17 -0
- package/dist/consent-banner/index.js +23 -0
- package/dist/content/index.d.ts +2 -1
- package/dist/content/index.js +4 -1
- package/dist/content/provider.d.ts +16 -2
- package/dist/content/provider.js +5 -1
- package/dist/content/resolve-slots.d.ts +24 -2
- package/dist/content/resolve-slots.js +127 -21
- package/dist/content/types.d.ts +5 -1
- package/dist/edge/expression-capabilities.v1.d.ts +106 -0
- package/dist/edge/expression-capabilities.v1.js +165 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +0 -1
- package/dist/internal/domain/edge/identity.d.ts +47 -4
- package/dist/internal/domain/edge/identity.js +130 -26
- package/dist/internal/domain/edge/index.d.ts +1 -1
- package/dist/internal/domain/edge/index.js +1 -1
- package/dist/internal/domain/edge/mimic_token.d.ts +14 -0
- package/dist/internal/domain/edge/mimic_token.js +125 -0
- package/dist/internal/domain/edge/personalization-core.d.ts +61 -22
- package/dist/internal/domain/edge/personalization-core.js +790 -200
- package/dist/internal/domain/edge/personalization_index.d.ts +17 -0
- package/dist/internal/domain/edge/personalization_index.js +55 -0
- package/dist/internal/domain/edge/resolve.js +76 -39
- package/dist/internal/domain/edge/testdata/flat_only_validator_v1.d.ts +10 -0
- package/dist/internal/domain/edge/testdata/flat_only_validator_v1.js +253 -0
- package/dist/internal/domain/edge/types.d.ts +82 -78
- package/dist/internal/domain/edge/types.js +3 -3
- package/dist/internal/domain/edge/variant_key.d.ts +4 -0
- package/dist/internal/domain/edge/variant_key.js +56 -0
- package/dist/internal/platform/collectionstore/errors.d.ts +24 -0
- package/dist/internal/platform/collectionstore/errors.js +48 -0
- package/dist/mintlify/blocks.d.ts +6 -0
- package/dist/mintlify/blocks.js +201 -0
- package/dist/mintlify/config.d.ts +3 -0
- package/dist/mintlify/config.js +77 -0
- package/dist/mintlify/index.d.ts +3 -0
- package/dist/mintlify/index.js +2 -0
- package/dist/mintlify/json.d.ts +8 -0
- package/dist/mintlify/json.js +37 -0
- package/dist/mintlify/materialize.d.ts +14 -0
- package/dist/mintlify/materialize.js +254 -0
- package/dist/mintlify/types.d.ts +74 -0
- package/dist/mintlify/types.js +1 -0
- package/dist/mintlify/validate.d.ts +7 -0
- package/dist/mintlify/validate.js +256 -0
- package/dist/next/assignments-navigation.d.ts +4 -0
- package/dist/next/assignments-navigation.js +18 -0
- package/dist/next/assignments-script.d.ts +3 -2
- package/dist/next/assignments-script.js +5 -5
- package/dist/next/error-pages.d.ts +4 -0
- package/dist/next/error-pages.js +4 -0
- package/dist/next/error-seat-payload.d.ts +2 -1
- package/dist/next/error-seat-payload.js +14 -24
- package/dist/next/error-seat.js +7 -2
- package/dist/next/index.d.ts +1 -1
- package/dist/next/index.js +3 -1
- package/dist/next/page.d.ts +2 -1
- package/dist/next/page.js +15 -4
- package/dist/next/release-context.d.ts +30 -0
- package/dist/next/release-context.js +56 -0
- package/dist/next/render.d.ts +1 -1
- package/dist/next/render.js +15 -5
- package/dist/next/server.d.ts +9 -3
- package/dist/next/server.js +17 -32
- package/dist/preview/core.d.ts +1 -0
- package/dist/preview/core.js +27 -0
- package/dist/react/VideoPlayer.d.ts +3 -3
- package/dist/react/index.d.ts +3 -3
- package/dist/registry.d.ts +4 -2
- package/dist/testing/conformance/checks.d.ts +2 -2
- package/dist/testing/conformance/checks.js +2 -0
- package/dist/testing/conformance/index.d.ts +1 -0
- package/dist/testing/conformance/index.js +1 -0
- package/dist/testing/conformance/next-stubs.d.ts +6 -0
- package/dist/testing/conformance/next-stubs.js +9 -0
- package/dist/testing/conformance/preset.d.ts +3 -2
- package/dist/testing/conformance/preset.js +15 -8
- package/dist/testing/conformance/root-identity.d.ts +31 -0
- package/dist/testing/conformance/root-identity.js +361 -0
- package/dist/testing/conformance/stubs/next-image.d.ts +7 -0
- package/dist/testing/conformance/stubs/next-image.js +5 -0
- package/dist/testing/conformance/stubs/next-link.d.ts +7 -0
- package/dist/testing/conformance/stubs/next-link.js +4 -0
- package/dist/testing/conformance/types.d.ts +5 -2
- package/dist/testing/index.d.ts +1 -1
- package/dist/testing/index.js +4 -3
- package/dist/types/block-ref.js +2 -2
- package/dist/types/component.d.ts +9 -0
- package/dist/types/config.d.ts +0 -1
- package/dist/types/index.d.ts +0 -1
- package/dist/types/index.js +0 -1
- package/dist/types/page.d.ts +0 -1
- package/migrations/conformance-registry.md +22 -0
- package/migrations/experiment-goal-ids.md +43 -0
- package/package.json +21 -7
- package/src/cli/compile-registry.mjs +6 -30
- package/src/cli/mintlify-render.mjs +9 -0
- package/src/types/block-ref.test.ts +16 -1
- package/src/types/block-ref.ts +2 -2
- package/src/types/component.ts +10 -0
- package/src/types/config.ts +0 -1
- package/src/types/index.ts +0 -1
- package/src/types/page.ts +0 -1
- package/templates/astro/starter-content/src/components/chrome/Footer.astro +5 -3
- package/templates/astro/starter-content/src/components/chrome/Header.astro +5 -3
- package/templates/astro/starter-content/src/components/elements/Button.astro +5 -2
- package/templates/astro/starter-content/src/components/elements/ButtonBlock.astro +5 -3
- package/templates/astro/starter-content/src/components/sections/ContainerSection.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/FeatureCard.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/FeatureGrid.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/HomeHero.astro +5 -3
- package/templates/astro/starter-content/src/components/sections/PersonalizationChoice.astro +4 -3
- package/templates/astro/starter-content/src/components/sections/StatsBar.astro +4 -3
- package/templates/astro/starter-content/src/fixtures/sections.ts +1 -1
- package/templates/astro/starter-content/src/stories/CompositionStoryFrame.astro +7 -2
- package/templates/astro/template/.aci.yaml.tmpl +0 -1
- package/templates/astro/template/package.json.tmpl +5 -5
- package/templates/astro/template/src/layouts/SiteLayout.astro +2 -2
- package/templates/common/.agents/skills/aci/SKILL.md +58 -1
- package/templates/common/.agents/skills/authoring/SKILL.md +194 -42
- package/templates/common/.agents/skills/authoring/references/block-registry.md +19 -3
- package/templates/common/.agents/skills/authoring/references/contracts.md +9 -30
- package/templates/common/.agents/skills/authoring/references/repo-structure.md +5 -4
- package/templates/common/.agents/skills/authoring/references/sdk-server-functions.md +3 -3
- package/templates/common/.agents/skills/dam-delivery/SKILL.md +216 -0
- package/templates/common/.agents/skills/dam-delivery/references/permalink-grammar.md +167 -0
- package/templates/common/.agents/skills/migration/references/canon-migration.md +18 -67
- package/templates/common/.agents/skills/migration/references/selector-map.md +1 -1
- package/templates/common/.content/fragments/navbar/_index.json +24 -0
- package/templates/common/.content/fragments/site-footer/_index.json +61 -0
- package/templates/common/.content/pages/404/_index.json +4 -2
- package/templates/common/.content/pages/_index.json +0 -1
- package/templates/common/.content/pages/error/_index.json +4 -2
- package/templates/common/.content/schemas/site.schema.json +11 -1
- package/templates/common/.content/templates/error.json +24 -0
- package/templates/common/.content/templates/home.json +28 -0
- package/templates/common/.content/templates/site.json +8 -0
- package/templates/common/.content/templates/standard.json +24 -0
- package/templates/common/.nvmrc +1 -1
- package/templates/common/starter-content/.content/config/site.json +1 -1
- package/templates/common/starter-content/.content/dam/README.md +74 -0
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/asset.json +1 -1
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/asset.json +1 -1
- package/templates/common/starter-content/.content/pages/404/_index.json +1 -2
- package/templates/common/starter-content/.content/pages/{home/_index.json → _index.json} +14 -3
- package/templates/common/starter-content/.content/pages/about/_index.json +2 -2
- package/templates/common/starter-content/.content/pages/error/_index.json +1 -2
- package/templates/common/starter-content/.content/patterns/components/button.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/container.json +8 -3
- package/templates/common/starter-content/.content/patterns/components/feature_card.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/feature_grid.json +5 -3
- package/templates/common/starter-content/.content/patterns/components/home_hero.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/site-footer.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/site-navigation.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/stats_bar.json +2 -2
- package/templates/common/starter-content/.content/schemas/site.schema.json +11 -1
- package/templates/nextjs/starter-content/src/components/chrome/Footer.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/chrome/Header.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/elements/Button.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/elements/ButtonBlock.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/ContainerSection.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/FeatureCard.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/FeatureGrid.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/HomeHero.tsx +4 -3
- package/templates/nextjs/starter-content/src/components/sections/PersonalizationChoice.tsx +4 -2
- package/templates/nextjs/starter-content/src/components/sections/StatsBar.tsx +4 -3
- package/templates/nextjs/template/.aci.yaml +0 -1
- package/templates/nextjs/template/.aci.yaml.tmpl +0 -1
- package/templates/nextjs/template/package.json.tmpl +4 -3
- package/templates/nextjs/template/src/app/_components/c15t-bridge.ts +30 -0
- package/templates/nextjs/template/src/app/_components/c15t-consent-ui.tsx +37 -0
- package/templates/nextjs/template/src/app/_components/consent-manager.css +63 -0
- package/templates/nextjs/template/src/app/_components/consent-manager.tsx +76 -0
- package/templates/nextjs/template/src/app/fonts/inter/OFL.txt +93 -0
- package/templates/nextjs/template/src/app/fonts/inter/inter-latin.woff2 +0 -0
- package/templates/nextjs/template/src/app/fonts/space-grotesk/OFL.txt +93 -0
- package/templates/nextjs/template/src/app/fonts/space-grotesk/space-grotesk-latin.woff2 +0 -0
- package/templates/nextjs/template/src/app/layout.tsx +12 -7
- package/templates/nextjs/template/tests/conformance.test.ts.tmpl +1 -0
- package/dist/define-layout.d.ts +0 -6
- package/dist/define-layout.js +0 -14
- package/dist/edge/personalization-core.d.ts +0 -11
- package/dist/edge/personalization-core.js +0 -269
- package/dist/internal/domain/edge/compose.d.ts +0 -24
- package/dist/internal/domain/edge/compose.js +0 -89
- package/dist/internal/domain/edge/record/codec.d.ts +0 -71
- package/dist/internal/domain/edge/record/codec.js +0 -401
- package/dist/next/collect-route.d.ts +0 -19
- package/dist/next/collect-route.js +0 -459
- package/dist/next/edge-config.d.ts +0 -1
- package/dist/next/edge-config.js +0 -92
- package/dist/next/envelope-digest.d.ts +0 -21
- package/dist/next/envelope-digest.js +0 -58
- package/dist/next/middleware.d.ts +0 -40
- package/dist/next/middleware.js +0 -475
- package/dist/next/personalization-host.d.ts +0 -134
- package/dist/next/personalization-host.js +0 -270
- package/dist/next/root-layout.d.ts +0 -4
- package/dist/next/root-layout.js +0 -5
- package/dist/next/vercel-collect-sdk-route.d.ts +0 -27
- package/dist/next/vercel-collect-sdk-route.js +0 -181
- package/dist/next/vercel-edge-projection-v1.d.ts +0 -24
- package/dist/next/vercel-edge-projection-v1.js +0 -880
- package/dist/next/vercel-personalization.d.ts +0 -4
- package/dist/next/vercel-personalization.js +0 -4
- package/dist/next/vercel-s3-personalization.d.ts +0 -79
- package/dist/next/vercel-s3-personalization.js +0 -570
- package/dist/types/layout.d.ts +0 -24
- package/src/types/layout.ts +0 -29
- package/templates/astro/starter-content/src/render/RenderPage.astro +0 -67
- package/templates/astro/template/src/cms/contracts/layouts/index.ts +0 -18
- package/templates/common/starter-content/.content/patterns/layouts/default.json +0 -14
- package/templates/nextjs/starter-content/src/components/elements/AtomicBlock.tsx +0 -13
- package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +0 -16
- /package/dist/{types/layout.js → cli/mintlify-render.d.mts} +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/editorial.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000101}/governance.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/versions/v0001.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/editorial.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000102}/governance.json +0 -0
- /package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/versions/v0001.json +0 -0
package/dist/next/middleware.js
DELETED
|
@@ -1,475 +0,0 @@
|
|
|
1
|
-
import { NextResponse } from 'next/server.js';
|
|
2
|
-
import { getUncachedEdgeConfigValue } from './edge-config.js';
|
|
3
|
-
import { PREVIEW_TOKEN_COOKIE, PREVIEW_RELEASE_COOKIE, extractPreviewToken, resolvePreviewContext, createPreviewCookies, previewSignKey, } from '../preview/core.js';
|
|
4
|
-
import { CONTENT_PATH_HEADER, CONTENT_PATH_CACHE_PARAM, ROUTED_PATH_HEADER, VARIANT_KEY_HEADER, resolvePersonalizationRequest, } from './personalization-host.js';
|
|
5
|
-
import { activeReleaseV1Key, clampDeploymentCompatibleReleaseV1, decodeActiveReleaseV1, decodeDeploymentCompatibilityV1, deploymentCompatibilityKey, } from './vercel-edge-projection-v1.js';
|
|
6
|
-
const RELEASE_SCOPED_PREFIX = '/__r';
|
|
7
|
-
const FRAMEWORK_ORIGIN_AUTH_HEADER = 'x-gradial-framework-origin-auth';
|
|
8
|
-
const FRAMEWORK_SITE_ID_HEADER = 'x-baremetal-site-id';
|
|
9
|
-
const FRAMEWORK_RELEASE_ID_HEADER = 'x-baremetal-release-id';
|
|
10
|
-
const FRAMEWORK_CONTENT_REF_HEADER = 'x-aci-content-ref';
|
|
11
|
-
const FRAMEWORK_CONTENT_BASE_URL_HEADER = 'x-baremetal-content-base-url';
|
|
12
|
-
const textEncoder = new TextEncoder();
|
|
13
|
-
const CMS_ASSET_PATHS = new Set(['/robots.txt', '/sitemap.xml']);
|
|
14
|
-
const FRAMEWORK_RUNTIME_PATHS = new Set(['/favicon.ico', '/_health']);
|
|
15
|
-
const FRAMEWORK_RUNTIME_PREFIXES = [
|
|
16
|
-
'/_next',
|
|
17
|
-
'/api',
|
|
18
|
-
'/collect',
|
|
19
|
-
'/gradial/assets',
|
|
20
|
-
'/dam',
|
|
21
|
-
];
|
|
22
|
-
const PUBLIC_PATHS = new Set(typeof __ACI_PUBLIC_PATHS__ !== 'undefined' ? __ACI_PUBLIC_PATHS__ : []);
|
|
23
|
-
const PASSTHROUGH_ROUTES = (typeof __ACI_PASSTHROUGH_ROUTES__ !== 'undefined' ? __ACI_PASSTHROUGH_ROUTES__ : []);
|
|
24
|
-
export function createGradialMiddleware(config = {}) {
|
|
25
|
-
return async function middleware(request) {
|
|
26
|
-
const url = request.nextUrl;
|
|
27
|
-
const frameworkDispatch = await resolveFrameworkDispatch(request, config);
|
|
28
|
-
if (frameworkDispatch.kind === 'rejected') {
|
|
29
|
-
return frameworkDispatch.response;
|
|
30
|
-
}
|
|
31
|
-
// The outer framework proxy authenticates every request with reserved
|
|
32
|
-
// dispatch headers, including Next/API/static runtime paths. Match those
|
|
33
|
-
// paths so the handoff is validated and reserved headers are stripped.
|
|
34
|
-
// Document rewrites retain only the validated, canonical content-path
|
|
35
|
-
// query because Vercel uses it as the selected payload's cache identity.
|
|
36
|
-
if (isFrameworkRuntimePath(url.pathname)) {
|
|
37
|
-
return passThroughResponse(request, frameworkDispatch);
|
|
38
|
-
}
|
|
39
|
-
// ?leave_preview=1 → clear cookies, redirect to clean URL
|
|
40
|
-
if (url.searchParams.get('leave_preview') === '1') {
|
|
41
|
-
const cleanUrl = new URL(url.pathname, url.origin);
|
|
42
|
-
const response = NextResponse.redirect(cleanUrl);
|
|
43
|
-
response.cookies.delete(PREVIEW_TOKEN_COOKIE);
|
|
44
|
-
response.cookies.delete(PREVIEW_RELEASE_COOKIE);
|
|
45
|
-
return response;
|
|
46
|
-
}
|
|
47
|
-
if (PUBLIC_PATHS.has(url.pathname)) {
|
|
48
|
-
return passThroughResponse(request, frameworkDispatch);
|
|
49
|
-
}
|
|
50
|
-
if (CMS_ASSET_PATHS.has(url.pathname)) {
|
|
51
|
-
return passThroughResponse(request, frameworkDispatch);
|
|
52
|
-
}
|
|
53
|
-
if (isPassthroughRoute(url.pathname)) {
|
|
54
|
-
return passThroughResponse(request, frameworkDispatch);
|
|
55
|
-
}
|
|
56
|
-
// Block direct access to /__r/... — only middleware rewrites may use it.
|
|
57
|
-
if (isReleaseScopedPath(url.pathname, RELEASE_SCOPED_PREFIX)) {
|
|
58
|
-
return new Response('not found', {
|
|
59
|
-
status: 404,
|
|
60
|
-
headers: { 'Cache-Control': 'private, no-store' },
|
|
61
|
-
});
|
|
62
|
-
}
|
|
63
|
-
if (frameworkDispatch.kind === 'trusted') {
|
|
64
|
-
const response = rewriteToReleaseScopedPath(request, frameworkDispatch.releaseId, false, {
|
|
65
|
-
contentPath: frameworkDispatch.contentPath,
|
|
66
|
-
requestHeaders: frameworkRequestHeaders(request, frameworkDispatch.contentPath),
|
|
67
|
-
});
|
|
68
|
-
enforceCookieCacheRule(response);
|
|
69
|
-
return response;
|
|
70
|
-
}
|
|
71
|
-
// Try preview token first; if valid, use that release.
|
|
72
|
-
// If no token or invalid, fall through to active release from edge config.
|
|
73
|
-
const preview = await resolvePreviewFromRequest(request, config);
|
|
74
|
-
// Local file-backed development has no release-indexed artifact tree. A
|
|
75
|
-
// valid preview token is still useful there—it proves signing, expiry, and
|
|
76
|
-
// cookie propagation—but rewriting to /__r/{release}/routes would create
|
|
77
|
-
// a path the file provider cannot serve. Keep the public route and mark
|
|
78
|
-
// the response private, matching preview's cache semantics.
|
|
79
|
-
if (process.env.ACI_CONTENT_PROVIDER === 'file') {
|
|
80
|
-
const response = NextResponse.next();
|
|
81
|
-
const previewReleaseID = preview?.releaseId;
|
|
82
|
-
if (preview?.token && preview.isPreview && previewReleaseID) {
|
|
83
|
-
response.headers.set('Cache-Control', 'private, no-store');
|
|
84
|
-
for (const cookie of createPreviewCookies(preview.token, previewReleaseID)) {
|
|
85
|
-
response.cookies.set(cookie.name, cookie.value, cookie.options);
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
enforceCookieCacheRule(response);
|
|
89
|
-
return response;
|
|
90
|
-
}
|
|
91
|
-
const releaseId = preview?.releaseId || await activeReleaseFromEdgeConfig(config);
|
|
92
|
-
if (!releaseId) {
|
|
93
|
-
if (!siteIdForConfig(config)) {
|
|
94
|
-
return new Response('ACI site id is not configured', {
|
|
95
|
-
status: 500,
|
|
96
|
-
headers: { 'Cache-Control': 'private, no-store' },
|
|
97
|
-
});
|
|
98
|
-
}
|
|
99
|
-
return new Response('no active release', {
|
|
100
|
-
status: 503,
|
|
101
|
-
headers: { 'Cache-Control': 'private, no-store' },
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
// Cross-deployment preview: if the token was staged on a different Vercel
|
|
105
|
-
// deployment, rewrite the request to that deployment. This keeps the browser
|
|
106
|
-
// on the production domain while the correct code runtime serves the request.
|
|
107
|
-
const rewriteTarget = preview ? previewRewriteTarget(request, preview, config) : null;
|
|
108
|
-
if (rewriteTarget) {
|
|
109
|
-
const response = NextResponse.rewrite(rewriteTarget);
|
|
110
|
-
if (preview?.token && preview.isPreview) {
|
|
111
|
-
for (const cookie of createPreviewCookies(preview.token, releaseId)) {
|
|
112
|
-
response.cookies.set(cookie.name, cookie.value, cookie.options);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
enforceCookieCacheRule(response);
|
|
116
|
-
return response;
|
|
117
|
-
}
|
|
118
|
-
// Rewrite public URL to release-scoped internal path for CDN cache isolation.
|
|
119
|
-
// Each release gets a unique URL (/__r/{releaseId}/routes/...) so the CDN
|
|
120
|
-
// cache key is per-release. New release = new URL = cache miss = fresh content.
|
|
121
|
-
let personalization;
|
|
122
|
-
if (config.personalization) {
|
|
123
|
-
const siteId = config.personalization.siteId || siteIdForConfig(config);
|
|
124
|
-
if (!siteId) {
|
|
125
|
-
return new Response('ACI site id is not configured', {
|
|
126
|
-
status: 500,
|
|
127
|
-
headers: { 'Cache-Control': 'private, no-store' },
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
try {
|
|
131
|
-
personalization = await resolvePersonalizationRequest(request, releaseId, {
|
|
132
|
-
...config.personalization,
|
|
133
|
-
siteId,
|
|
134
|
-
});
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
return new Response('personalization artifacts unavailable', {
|
|
138
|
-
status: 503,
|
|
139
|
-
headers: { 'Cache-Control': 'private, no-store' },
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
const response = rewriteToReleaseScopedPath(request, releaseId, Boolean(preview?.isPreview), personalization
|
|
144
|
-
? {
|
|
145
|
-
contentPath: personalization.contentPath,
|
|
146
|
-
requestHeaders: personalization.requestHeaders,
|
|
147
|
-
}
|
|
148
|
-
: undefined);
|
|
149
|
-
// Persist preview token as cookie so navigation stays in preview
|
|
150
|
-
if (preview?.token && preview.isPreview) {
|
|
151
|
-
for (const cookie of createPreviewCookies(preview.token, releaseId)) {
|
|
152
|
-
response.cookies.set(cookie.name, cookie.value, cookie.options);
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
if (personalization) {
|
|
156
|
-
for (const cookie of personalization.cookies) {
|
|
157
|
-
response.cookies.set(cookie.name, cookie.value, cookie.options);
|
|
158
|
-
}
|
|
159
|
-
if (personalization.variantKey) {
|
|
160
|
-
response.headers.set('X-ACI-Variant-Key', personalization.variantKey);
|
|
161
|
-
}
|
|
162
|
-
if (personalization.experiment) {
|
|
163
|
-
response.headers.set('X-ACI-Experiment-ID', personalization.experiment.id);
|
|
164
|
-
response.headers.set('X-ACI-Experiment-Arm', personalization.experiment.arm);
|
|
165
|
-
response.headers.set('X-ACI-Experiment-Allocation-Version', personalization.experiment.allocationVersion);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
enforceCookieCacheRule(response);
|
|
169
|
-
return response;
|
|
170
|
-
};
|
|
171
|
-
}
|
|
172
|
-
/**
|
|
173
|
-
* Any response that writes a cookie is per-visitor and must never enter a
|
|
174
|
-
* shared cache (anonymous-experiments REQ-3(a)): a CDN-cached Set-Cookie
|
|
175
|
-
* replays one visitor's identity/claims to everyone under that cache key.
|
|
176
|
-
* Per-variant CACHING itself stays legitimate — the variant travels in the
|
|
177
|
-
* cache-keyed query parameter, not in cookies.
|
|
178
|
-
*/
|
|
179
|
-
export function enforceCookieCacheRule(response) {
|
|
180
|
-
if (response.cookies.getAll().length === 0) {
|
|
181
|
-
return;
|
|
182
|
-
}
|
|
183
|
-
response.headers.set('Cache-Control', 'private, no-store');
|
|
184
|
-
response.headers.delete('CDN-Cache-Control');
|
|
185
|
-
response.headers.delete('Vercel-CDN-Cache-Control');
|
|
186
|
-
}
|
|
187
|
-
function rewriteToReleaseScopedPath(request, releaseId, isPreview, options) {
|
|
188
|
-
const rewriteURL = new URL(request.url);
|
|
189
|
-
rewriteURL.pathname = releaseScopedPath(RELEASE_SCOPED_PREFIX, releaseId, request.nextUrl.pathname);
|
|
190
|
-
rewriteURL.searchParams.delete(CONTENT_PATH_CACHE_PARAM);
|
|
191
|
-
if (options?.contentPath) {
|
|
192
|
-
rewriteURL.searchParams.set(CONTENT_PATH_CACHE_PARAM, options.contentPath);
|
|
193
|
-
}
|
|
194
|
-
const response = options?.requestHeaders
|
|
195
|
-
? NextResponse.rewrite(rewriteURL, { request: { headers: options.requestHeaders } })
|
|
196
|
-
: NextResponse.rewrite(rewriteURL);
|
|
197
|
-
if (isPreview) {
|
|
198
|
-
response.headers.set('Cache-Control', 'private, no-store');
|
|
199
|
-
}
|
|
200
|
-
else {
|
|
201
|
-
response.headers.set('Cache-Control', 'public, max-age=0, must-revalidate');
|
|
202
|
-
response.headers.set('CDN-Cache-Control', 'max-age=31536000');
|
|
203
|
-
response.headers.set('Vercel-CDN-Cache-Control', 'max-age=31536000');
|
|
204
|
-
}
|
|
205
|
-
return response;
|
|
206
|
-
}
|
|
207
|
-
async function resolveFrameworkDispatch(request, config) {
|
|
208
|
-
// The outer edge has already minted identity and selected a release/payload.
|
|
209
|
-
// A trusted handoff must use that exact decision; falling through would mint
|
|
210
|
-
// a second identity and may select a different experiment arm.
|
|
211
|
-
const originAuth = request.headers.get(FRAMEWORK_ORIGIN_AUTH_HEADER);
|
|
212
|
-
const forwardedSiteId = request.headers.get(FRAMEWORK_SITE_ID_HEADER);
|
|
213
|
-
const forwardedReleaseId = request.headers.get(FRAMEWORK_RELEASE_ID_HEADER);
|
|
214
|
-
const forwardedContentRef = request.headers.get(FRAMEWORK_CONTENT_REF_HEADER);
|
|
215
|
-
const contentPathValues = request.nextUrl.searchParams.getAll(CONTENT_PATH_CACHE_PARAM);
|
|
216
|
-
const hasReservedDispatch = originAuth !== null
|
|
217
|
-
|| forwardedSiteId !== null
|
|
218
|
-
|| forwardedReleaseId !== null
|
|
219
|
-
|| forwardedContentRef !== null
|
|
220
|
-
|| request.headers.has(FRAMEWORK_CONTENT_BASE_URL_HEADER)
|
|
221
|
-
|| request.headers.has(CONTENT_PATH_HEADER)
|
|
222
|
-
|| request.headers.has(ROUTED_PATH_HEADER)
|
|
223
|
-
|| request.headers.has(VARIANT_KEY_HEADER)
|
|
224
|
-
|| contentPathValues.length > 0;
|
|
225
|
-
if (!hasReservedDispatch) {
|
|
226
|
-
return { kind: 'direct' };
|
|
227
|
-
}
|
|
228
|
-
const expectedOriginAuth = config.frameworkOriginAuthToken
|
|
229
|
-
|| process.env.ACI_FRAMEWORK_ORIGIN_AUTH_TOKEN
|
|
230
|
-
|| '';
|
|
231
|
-
if (!expectedOriginAuth
|
|
232
|
-
|| originAuth === null
|
|
233
|
-
|| !(await secureStringEqual(expectedOriginAuth, originAuth))) {
|
|
234
|
-
return rejectedFrameworkDispatch(403, 'framework dispatch forbidden');
|
|
235
|
-
}
|
|
236
|
-
if (!forwardedSiteId || !forwardedReleaseId) {
|
|
237
|
-
return rejectedFrameworkDispatch(400, 'invalid framework dispatch');
|
|
238
|
-
}
|
|
239
|
-
const expectedSiteId = siteIdForConfig(config);
|
|
240
|
-
if (!expectedSiteId || forwardedSiteId !== expectedSiteId) {
|
|
241
|
-
return rejectedFrameworkDispatch(403, 'framework dispatch forbidden');
|
|
242
|
-
}
|
|
243
|
-
if (forwardedContentRef === null && contentPathValues.length === 0) {
|
|
244
|
-
return {
|
|
245
|
-
kind: 'trusted',
|
|
246
|
-
releaseId: forwardedReleaseId,
|
|
247
|
-
contentPath: '',
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
if (!forwardedContentRef
|
|
251
|
-
|| contentPathValues.length !== 1
|
|
252
|
-
|| contentPathValues[0] !== forwardedContentRef) {
|
|
253
|
-
return rejectedFrameworkDispatch(400, 'invalid framework dispatch');
|
|
254
|
-
}
|
|
255
|
-
return {
|
|
256
|
-
kind: 'trusted',
|
|
257
|
-
releaseId: forwardedReleaseId,
|
|
258
|
-
contentPath: forwardedContentRef,
|
|
259
|
-
};
|
|
260
|
-
}
|
|
261
|
-
function passThroughResponse(request, frameworkDispatch) {
|
|
262
|
-
if (frameworkDispatch.kind !== 'trusted') {
|
|
263
|
-
return NextResponse.next();
|
|
264
|
-
}
|
|
265
|
-
if (frameworkDispatch.contentPath) {
|
|
266
|
-
return new Response('invalid framework dispatch', {
|
|
267
|
-
status: 400,
|
|
268
|
-
headers: { 'Cache-Control': 'private, no-store' },
|
|
269
|
-
});
|
|
270
|
-
}
|
|
271
|
-
return NextResponse.next({
|
|
272
|
-
request: {
|
|
273
|
-
headers: sanitizedFrameworkRequestHeaders(request),
|
|
274
|
-
},
|
|
275
|
-
});
|
|
276
|
-
}
|
|
277
|
-
function frameworkRequestHeaders(request, contentPath) {
|
|
278
|
-
const requestHeaders = sanitizedFrameworkRequestHeaders(request);
|
|
279
|
-
if (contentPath) {
|
|
280
|
-
requestHeaders.set(CONTENT_PATH_HEADER, contentPath);
|
|
281
|
-
requestHeaders.set(ROUTED_PATH_HEADER, request.nextUrl.pathname);
|
|
282
|
-
}
|
|
283
|
-
return requestHeaders;
|
|
284
|
-
}
|
|
285
|
-
function sanitizedFrameworkRequestHeaders(request) {
|
|
286
|
-
const requestHeaders = new Headers(request.headers);
|
|
287
|
-
requestHeaders.delete(FRAMEWORK_ORIGIN_AUTH_HEADER);
|
|
288
|
-
requestHeaders.delete(FRAMEWORK_SITE_ID_HEADER);
|
|
289
|
-
requestHeaders.delete(FRAMEWORK_RELEASE_ID_HEADER);
|
|
290
|
-
requestHeaders.delete(FRAMEWORK_CONTENT_REF_HEADER);
|
|
291
|
-
requestHeaders.delete(FRAMEWORK_CONTENT_BASE_URL_HEADER);
|
|
292
|
-
requestHeaders.delete(CONTENT_PATH_HEADER);
|
|
293
|
-
requestHeaders.delete(ROUTED_PATH_HEADER);
|
|
294
|
-
requestHeaders.delete(VARIANT_KEY_HEADER);
|
|
295
|
-
return requestHeaders;
|
|
296
|
-
}
|
|
297
|
-
function rejectedFrameworkDispatch(status, message) {
|
|
298
|
-
return {
|
|
299
|
-
kind: 'rejected',
|
|
300
|
-
response: new Response(message, {
|
|
301
|
-
status,
|
|
302
|
-
headers: { 'Cache-Control': 'private, no-store' },
|
|
303
|
-
}),
|
|
304
|
-
};
|
|
305
|
-
}
|
|
306
|
-
async function secureStringEqual(expected, actual) {
|
|
307
|
-
const [expectedDigest, actualDigest] = await Promise.all([
|
|
308
|
-
crypto.subtle.digest('SHA-256', textEncoder.encode(expected)),
|
|
309
|
-
crypto.subtle.digest('SHA-256', textEncoder.encode(actual)),
|
|
310
|
-
]);
|
|
311
|
-
const expectedBytes = new Uint8Array(expectedDigest);
|
|
312
|
-
const actualBytes = new Uint8Array(actualDigest);
|
|
313
|
-
let different = 0;
|
|
314
|
-
for (let index = 0; index < expectedBytes.length; index += 1) {
|
|
315
|
-
different |= expectedBytes[index] ^ actualBytes[index];
|
|
316
|
-
}
|
|
317
|
-
return different === 0;
|
|
318
|
-
}
|
|
319
|
-
function isReleaseScopedPath(pathname, prefix) {
|
|
320
|
-
return pathname === prefix || pathname.startsWith(`${prefix}/`);
|
|
321
|
-
}
|
|
322
|
-
function releaseScopedPath(prefix, releaseId, pathname) {
|
|
323
|
-
const suffix = pathname === '/' ? '' : pathname;
|
|
324
|
-
return `${prefix}/${encodeURIComponent(releaseId)}/routes${suffix}`;
|
|
325
|
-
}
|
|
326
|
-
function previewRewriteTarget(request, preview, config) {
|
|
327
|
-
const claims = preview.claims;
|
|
328
|
-
if (!claims?.deploymentId || !claims?.deploymentUrl || !preview.token) {
|
|
329
|
-
return null;
|
|
330
|
-
}
|
|
331
|
-
const currentDeploymentId = config.deploymentId || process.env.VERCEL_DEPLOYMENT_ID || '';
|
|
332
|
-
if (!currentDeploymentId || currentDeploymentId === claims.deploymentId) {
|
|
333
|
-
return null;
|
|
334
|
-
}
|
|
335
|
-
const base = buildDeploymentUrl(claims.deploymentUrl);
|
|
336
|
-
const target = new URL(request.nextUrl.pathname + request.nextUrl.search, base);
|
|
337
|
-
if (!target.searchParams.has('preview_token')) {
|
|
338
|
-
target.searchParams.set('preview_token', preview.token);
|
|
339
|
-
}
|
|
340
|
-
const bypass = config.deploymentProtectionBypass || process.env.VERCEL_DEPLOYMENT_PROTECTION_BYPASS;
|
|
341
|
-
if (bypass) {
|
|
342
|
-
target.searchParams.set('x-vercel-protection-bypass', bypass);
|
|
343
|
-
}
|
|
344
|
-
return target;
|
|
345
|
-
}
|
|
346
|
-
function buildDeploymentUrl(value) {
|
|
347
|
-
if (value.startsWith('http://') || value.startsWith('https://')) {
|
|
348
|
-
return value;
|
|
349
|
-
}
|
|
350
|
-
return `https://${value}`;
|
|
351
|
-
}
|
|
352
|
-
async function resolvePreviewFromRequest(request, config) {
|
|
353
|
-
const token = extractPreviewToken({
|
|
354
|
-
query: request.nextUrl.searchParams,
|
|
355
|
-
cookies: cookieMap(request.cookies),
|
|
356
|
-
authorization: request.headers.get('authorization') || undefined,
|
|
357
|
-
});
|
|
358
|
-
if (!token)
|
|
359
|
-
return null;
|
|
360
|
-
const signKey = config.previewSignKey || previewSignKey();
|
|
361
|
-
if (!signKey) {
|
|
362
|
-
console.warn('[aci/mw] GRADIAL_PREVIEW_SIGN_KEY not set — preview tokens will be ignored');
|
|
363
|
-
return null;
|
|
364
|
-
}
|
|
365
|
-
return await resolvePreviewContext({ token, siteId: siteIdForConfig(config), signKey });
|
|
366
|
-
}
|
|
367
|
-
function cookieMap(cookies) {
|
|
368
|
-
const map = new Map();
|
|
369
|
-
for (const cookie of cookies.getAll()) {
|
|
370
|
-
map.set(cookie.name, cookie.value);
|
|
371
|
-
}
|
|
372
|
-
return map;
|
|
373
|
-
}
|
|
374
|
-
async function activeReleaseFromEdgeConfig(config) {
|
|
375
|
-
const edgeConfig = config.edgeConfig || process.env.EDGE_CONFIG || '';
|
|
376
|
-
const siteId = siteIdForConfig(config);
|
|
377
|
-
if (!edgeConfig || !siteId)
|
|
378
|
-
return '';
|
|
379
|
-
const active = await activeReleasePointer(edgeConfig, siteId);
|
|
380
|
-
if (active == null)
|
|
381
|
-
return '';
|
|
382
|
-
const deploymentId = config.deploymentId || process.env.VERCEL_DEPLOYMENT_ID || '';
|
|
383
|
-
if (!deploymentId)
|
|
384
|
-
return active.releaseId;
|
|
385
|
-
const compatibilityValue = await getEdgeConfigValue(edgeConfig, deploymentCompatibilityKey(siteId, deploymentId));
|
|
386
|
-
if (compatibilityValue == null)
|
|
387
|
-
return active.releaseId;
|
|
388
|
-
return clampDeploymentCompatibleReleaseV1(active, decodeDeploymentCompatibilityV1(compatibilityValue));
|
|
389
|
-
}
|
|
390
|
-
function siteIdForConfig(config) {
|
|
391
|
-
return config.siteId || process.env.ACI_SITE_ID || '';
|
|
392
|
-
}
|
|
393
|
-
async function getEdgeConfigValue(edgeConfig, key) {
|
|
394
|
-
return getUncachedEdgeConfigValue(edgeConfig, key);
|
|
395
|
-
}
|
|
396
|
-
async function activeReleasePointer(edgeConfig, siteId) {
|
|
397
|
-
const value = await getEdgeConfigValue(edgeConfig, activeReleaseV1Key(siteId));
|
|
398
|
-
if (value == null)
|
|
399
|
-
return null;
|
|
400
|
-
return decodeActiveReleaseV1(value);
|
|
401
|
-
}
|
|
402
|
-
function isPassthroughRoute(pathname) {
|
|
403
|
-
return PASSTHROUGH_ROUTES.some((route) => routeMatches(pathname, route));
|
|
404
|
-
}
|
|
405
|
-
function isFrameworkRuntimePath(pathname) {
|
|
406
|
-
if (FRAMEWORK_RUNTIME_PATHS.has(pathname)) {
|
|
407
|
-
return true;
|
|
408
|
-
}
|
|
409
|
-
return FRAMEWORK_RUNTIME_PREFIXES.some((prefix) => pathname === prefix || pathname.startsWith(`${prefix}/`));
|
|
410
|
-
}
|
|
411
|
-
function routeMatches(pathname, route) {
|
|
412
|
-
const cleanPath = normalizeRoutePath(pathname);
|
|
413
|
-
const cleanRoute = normalizeRoutePath(route);
|
|
414
|
-
if (!cleanRoute)
|
|
415
|
-
return false;
|
|
416
|
-
if (cleanRoute.endsWith('/:path*')) {
|
|
417
|
-
const prefix = cleanRoute.slice(0, -'/:path*'.length) || '/';
|
|
418
|
-
return cleanPath === prefix || cleanPath.startsWith(`${prefix}/`);
|
|
419
|
-
}
|
|
420
|
-
if (cleanRoute.endsWith('/*')) {
|
|
421
|
-
const prefix = cleanRoute.slice(0, -'/*'.length) || '/';
|
|
422
|
-
return cleanPath === prefix || cleanPath.startsWith(`${prefix}/`);
|
|
423
|
-
}
|
|
424
|
-
return cleanPath === cleanRoute;
|
|
425
|
-
}
|
|
426
|
-
function normalizeRoutePath(value) {
|
|
427
|
-
const trimmed = value.trim();
|
|
428
|
-
if (!trimmed)
|
|
429
|
-
return '';
|
|
430
|
-
const pathname = trimmed.startsWith('/') ? trimmed : `/${trimmed}`;
|
|
431
|
-
return pathname.replace(/\/{2,}/g, '/').replace(/\/$/, '') || '/';
|
|
432
|
-
}
|
|
433
|
-
export const aciMiddlewareMatcher = [
|
|
434
|
-
'/((?!_next(?:/|$)|api(?:/|$)|collect(?:/|$)|gradial/assets(?:/|$)|favicon\\.ico$).*)',
|
|
435
|
-
{
|
|
436
|
-
source: '/:path*',
|
|
437
|
-
has: [{ type: 'header', key: 'x-gradial-framework-origin-auth' }],
|
|
438
|
-
},
|
|
439
|
-
{
|
|
440
|
-
source: '/:path*',
|
|
441
|
-
has: [{ type: 'header', key: 'x-baremetal-site-id' }],
|
|
442
|
-
},
|
|
443
|
-
{
|
|
444
|
-
source: '/:path*',
|
|
445
|
-
has: [{ type: 'header', key: 'x-baremetal-release-id' }],
|
|
446
|
-
},
|
|
447
|
-
{
|
|
448
|
-
source: '/:path*',
|
|
449
|
-
has: [{ type: 'header', key: 'x-aci-content-ref' }],
|
|
450
|
-
},
|
|
451
|
-
{
|
|
452
|
-
source: '/:path*',
|
|
453
|
-
has: [{ type: 'header', key: 'x-baremetal-content-base-url' }],
|
|
454
|
-
},
|
|
455
|
-
{
|
|
456
|
-
source: '/:path*',
|
|
457
|
-
has: [{ type: 'header', key: 'x-aci-content-path' }],
|
|
458
|
-
},
|
|
459
|
-
{
|
|
460
|
-
source: '/:path*',
|
|
461
|
-
has: [{ type: 'header', key: 'x-aci-routed-path' }],
|
|
462
|
-
},
|
|
463
|
-
{
|
|
464
|
-
source: '/:path*',
|
|
465
|
-
has: [{ type: 'header', key: 'x-aci-variant-key' }],
|
|
466
|
-
},
|
|
467
|
-
{
|
|
468
|
-
source: '/:path*',
|
|
469
|
-
has: [{ type: 'query', key: '__aci_content_path' }],
|
|
470
|
-
},
|
|
471
|
-
];
|
|
472
|
-
export const config = {
|
|
473
|
-
runtime: 'nodejs',
|
|
474
|
-
matcher: aciMiddlewareMatcher,
|
|
475
|
-
};
|
|
@@ -1,134 +0,0 @@
|
|
|
1
|
-
import { type PersonalizationExperiment } from '../edge/personalization-core.js';
|
|
2
|
-
import { type PortableConsentSnapshot } from '../consent/portable-envelope.js';
|
|
3
|
-
export declare const CONTENT_PATH_HEADER = "x-aci-content-path";
|
|
4
|
-
export declare const CONTENT_PATH_CACHE_PARAM = "__aci_content_path";
|
|
5
|
-
export declare const ROUTED_PATH_HEADER = "x-aci-routed-path";
|
|
6
|
-
export declare const VARIANT_KEY_HEADER = "x-aci-variant-key";
|
|
7
|
-
export interface EdgeDispatch {
|
|
8
|
-
kind: 'static-direct' | 'compose-origin' | 'framework-origin' | string;
|
|
9
|
-
artifactPath?: string;
|
|
10
|
-
contentPath?: string;
|
|
11
|
-
}
|
|
12
|
-
export interface EdgeRuleCondition {
|
|
13
|
-
field: string;
|
|
14
|
-
operator: 'exists' | 'equals' | 'contains' | 'startsWith' | string;
|
|
15
|
-
value?: unknown;
|
|
16
|
-
}
|
|
17
|
-
export interface EdgeRuleExpression {
|
|
18
|
-
all?: EdgeRuleCondition[];
|
|
19
|
-
any?: EdgeRuleCondition[];
|
|
20
|
-
}
|
|
21
|
-
export interface EdgeRouteVariant {
|
|
22
|
-
variantKey: string;
|
|
23
|
-
variantValues?: Record<string, string>;
|
|
24
|
-
priority?: number;
|
|
25
|
-
rule?: EdgeRuleExpression;
|
|
26
|
-
dispatch: EdgeDispatch;
|
|
27
|
-
}
|
|
28
|
-
export interface EdgeRouteEntry {
|
|
29
|
-
pattern: string;
|
|
30
|
-
priority: number;
|
|
31
|
-
dispatch: EdgeDispatch;
|
|
32
|
-
variants?: Record<string, EdgeRouteVariant>;
|
|
33
|
-
}
|
|
34
|
-
export interface CollectSDKEntry {
|
|
35
|
-
hash: string;
|
|
36
|
-
path: string;
|
|
37
|
-
}
|
|
38
|
-
export interface EdgeRouteManifest {
|
|
39
|
-
manifestVersion: string;
|
|
40
|
-
releaseId: string;
|
|
41
|
-
siteId: string;
|
|
42
|
-
routes: Record<string, EdgeRouteEntry>;
|
|
43
|
-
experiments?: Record<string, PersonalizationExperiment>;
|
|
44
|
-
collectSdk?: CollectSDKEntry;
|
|
45
|
-
notFoundPage?: string;
|
|
46
|
-
errorPage?: string;
|
|
47
|
-
}
|
|
48
|
-
export interface PersonalizationEnvelopeWrite {
|
|
49
|
-
key: string;
|
|
50
|
-
envelopeId: string;
|
|
51
|
-
siteId: string;
|
|
52
|
-
identityNamespace: string;
|
|
53
|
-
identityHash: string;
|
|
54
|
-
records: readonly unknown[];
|
|
55
|
-
digest: string;
|
|
56
|
-
}
|
|
57
|
-
export declare class IdentityErasureFencedError extends Error {
|
|
58
|
-
readonly name = "IdentityErasureFencedError";
|
|
59
|
-
constructor();
|
|
60
|
-
}
|
|
61
|
-
/** Immutable release routing state read by an EdgeRouter. */
|
|
62
|
-
export interface PersonalizationRouteStore {
|
|
63
|
-
readEdgeManifest(releaseId: string): Promise<EdgeRouteManifest | null>;
|
|
64
|
-
}
|
|
65
|
-
/** Customer-owned collection state. This is deliberately not an EdgeRouter dependency. */
|
|
66
|
-
export interface PersonalizationCollectionStore {
|
|
67
|
-
readClaims(siteId: string, namespace: string, identityHash: string): Promise<string | null>;
|
|
68
|
-
appendEnvelope(write: PersonalizationEnvelopeWrite): Promise<void>;
|
|
69
|
-
putSuppression(key: string, record: unknown): Promise<void>;
|
|
70
|
-
}
|
|
71
|
-
/** @deprecated Use the narrower router or collection store at each boundary. */
|
|
72
|
-
export interface PersonalizationBlobStore extends PersonalizationRouteStore, PersonalizationCollectionStore {
|
|
73
|
-
}
|
|
74
|
-
export interface SigningKey {
|
|
75
|
-
kid: string;
|
|
76
|
-
secret: string;
|
|
77
|
-
}
|
|
78
|
-
export interface IdentitySigningKeys {
|
|
79
|
-
current: SigningKey;
|
|
80
|
-
previous?: SigningKey;
|
|
81
|
-
}
|
|
82
|
-
export interface PersonalizationHostConfig {
|
|
83
|
-
siteId: string;
|
|
84
|
-
store: PersonalizationRouteStore;
|
|
85
|
-
identityKeys: IdentitySigningKeys;
|
|
86
|
-
claimsKeys?: Record<string, string>;
|
|
87
|
-
identityCookieTTLSeconds?: number;
|
|
88
|
-
secureCookies?: boolean;
|
|
89
|
-
now?: () => Date;
|
|
90
|
-
randomBytes?: (length: number) => Uint8Array;
|
|
91
|
-
}
|
|
92
|
-
export interface CookieMutation {
|
|
93
|
-
name: string;
|
|
94
|
-
value: string;
|
|
95
|
-
options: {
|
|
96
|
-
path: '/';
|
|
97
|
-
httpOnly?: boolean;
|
|
98
|
-
secure?: boolean;
|
|
99
|
-
sameSite: 'lax';
|
|
100
|
-
maxAge: number;
|
|
101
|
-
expires?: Date;
|
|
102
|
-
};
|
|
103
|
-
}
|
|
104
|
-
export interface PersonalizationResolution {
|
|
105
|
-
requestHeaders: Headers;
|
|
106
|
-
contentPath: string;
|
|
107
|
-
variantKey: string;
|
|
108
|
-
experiment?: {
|
|
109
|
-
id: string;
|
|
110
|
-
arm: string;
|
|
111
|
-
allocationVersion: string;
|
|
112
|
-
};
|
|
113
|
-
cookies: CookieMutation[];
|
|
114
|
-
}
|
|
115
|
-
export type ConsentSnapshot = PortableConsentSnapshot;
|
|
116
|
-
interface ClaimsPayload {
|
|
117
|
-
aud?: string[];
|
|
118
|
-
seg?: string[];
|
|
119
|
-
iat: number;
|
|
120
|
-
exp: number;
|
|
121
|
-
}
|
|
122
|
-
export declare function resolvePersonalizationRequest(request: Request, releaseId: string, config: PersonalizationHostConfig): Promise<PersonalizationResolution>;
|
|
123
|
-
export declare function consentSignals(request: Request, cookies: Map<string, string>): {
|
|
124
|
-
hasConsent: boolean;
|
|
125
|
-
snapshot: ConsentSnapshot | null;
|
|
126
|
-
allowsIdentityTier: boolean;
|
|
127
|
-
privacyDenied: boolean;
|
|
128
|
-
};
|
|
129
|
-
export declare function parseCookieHeader(value: string | null): Map<string, string>;
|
|
130
|
-
export declare function verifyIdentityCookie(value: string, keys: IdentitySigningKeys): Promise<string | null>;
|
|
131
|
-
export declare function sha256Hex(value: string): Promise<string>;
|
|
132
|
-
export declare function identityHashHex(namespace: string, value: string): Promise<string>;
|
|
133
|
-
export declare function verifyClaims(value: string, keys: Record<string, string>, now: Date): Promise<ClaimsPayload | null>;
|
|
134
|
-
export {};
|