@gradial/aci 0.1.52-rc.16 → 0.1.52-rc.21

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.
Files changed (48) hide show
  1. package/README.md +4 -4
  2. package/dist/astro/preview.js +2 -17
  3. package/dist/audience-data-models.d.ts +193 -16
  4. package/dist/audience-data-models.js +47 -2
  5. package/dist/collect/batcher.d.ts +6 -5
  6. package/dist/collect/batcher.js +6 -5
  7. package/dist/edge/expression-capabilities.v1.d.ts +106 -0
  8. package/dist/edge/expression-capabilities.v1.js +165 -0
  9. package/dist/internal/domain/edge/identity.js +1 -1
  10. package/dist/internal/domain/edge/mimic_token.js +1 -2
  11. package/dist/internal/domain/edge/personalization-core.d.ts +14 -4
  12. package/dist/internal/domain/edge/personalization-core.js +472 -54
  13. package/dist/internal/domain/edge/record/codec.d.ts +5 -2
  14. package/dist/internal/domain/edge/record/codec.js +83 -10
  15. package/dist/internal/domain/edge/resolve.js +13 -2
  16. package/dist/internal/domain/edge/testdata/flat_only_validator_v1.d.ts +10 -0
  17. package/dist/internal/domain/edge/testdata/flat_only_validator_v1.js +253 -0
  18. package/dist/internal/domain/edge/types.d.ts +36 -9
  19. package/dist/internal/domain/edge/types.js +3 -3
  20. package/dist/mimic/core.d.ts +0 -32
  21. package/dist/mimic/core.js +12 -108
  22. package/dist/next/vercel-edge-projection-v1.d.ts +0 -9
  23. package/dist/next/vercel-edge-projection-v1.js +9 -545
  24. package/dist/preview/core.d.ts +1 -0
  25. package/dist/preview/core.js +27 -0
  26. package/dist/react/VideoPlayer.d.ts +1 -1
  27. package/dist/react/index.d.ts +1 -1
  28. package/package.json +16 -7
  29. package/templates/common/.agents/skills/aci/SKILL.md +6 -0
  30. package/templates/common/.agents/skills/dam-delivery/SKILL.md +228 -0
  31. package/templates/common/.agents/skills/dam-delivery/references/parameter-contract.md +107 -0
  32. package/templates/common/.agents/skills/dam-delivery/references/permalink-grammar.md +131 -0
  33. package/dist/edge/personalization-core.d.ts +0 -35
  34. package/dist/edge/personalization-core.js +0 -483
  35. package/dist/next/collect-route.d.ts +0 -25
  36. package/dist/next/collect-route.js +0 -479
  37. package/dist/next/envelope-digest.d.ts +0 -21
  38. package/dist/next/envelope-digest.js +0 -58
  39. package/dist/next/personalization-host.d.ts +0 -138
  40. package/dist/next/personalization-host.js +0 -280
  41. package/dist/next/root-layout.d.ts +0 -4
  42. package/dist/next/root-layout.js +0 -5
  43. package/dist/next/vercel-collect-sdk-route.d.ts +0 -27
  44. package/dist/next/vercel-collect-sdk-route.js +0 -181
  45. package/dist/next/vercel-personalization.d.ts +0 -4
  46. package/dist/next/vercel-personalization.js +0 -4
  47. package/dist/next/vercel-s3-personalization.d.ts +0 -80
  48. package/dist/next/vercel-s3-personalization.js +0 -571
@@ -1,90 +1,16 @@
1
- // View-as-audience mimic session helpers (specs/features/audience-mimic).
2
- // Mirror of internal/domain/hosting/runtime/mimic.ts for SDK-hosted paths
3
- // (Next middleware); the token validator is the twin of
4
- // validateMimicToken in internal/domain/hosting/runtime/edge_router.ts and
5
- // internal/domain/edge/routing/mimic.go, pinned by the shared vector file
6
- // (internal/domain/edge/routing/testdata/mimic_token_vectors.json).
7
- export const MIMIC_PARAM = 'aci_mimic';
8
- export const MIMIC_COOKIE = 'aci_mimic';
9
- export const MIMIC_EXIT = 'exit';
10
- export const MIMIC_MAX_MEMBERSHIPS = 32;
11
- export const MIMIC_MAX_TOKEN_BYTES = 2048;
12
- export async function validateMimicToken(token, signKey, siteId) {
13
- try {
14
- if (!token || token.length > MIMIC_MAX_TOKEN_BYTES || !signKey || !siteId)
15
- return null;
16
- const parts = token.split('.');
17
- if (parts.length !== 3)
18
- return null;
19
- const signingInput = `${parts[0]}.${parts[1]}`;
20
- const signature = base64URLToBytes(parts[2]);
21
- const key = await crypto.subtle.importKey('raw', new TextEncoder().encode(signKey), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
22
- const expected = new Uint8Array(await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(signingInput)));
23
- if (!constantTimeEqual(signature, expected))
24
- return null;
25
- const claims = JSON.parse(new TextDecoder().decode(base64URLToBytes(parts[1])));
26
- if (claims.scope !== 'mimic')
27
- return null;
28
- if (typeof claims.siteId !== 'string' || claims.siteId !== siteId)
29
- return null;
30
- const aud = Array.isArray(claims.aud) ? claims.aud : [];
31
- const seg = Array.isArray(claims.seg) ? claims.seg : [];
32
- if (aud.length + seg.length === 0)
33
- return null;
34
- if (aud.length > MIMIC_MAX_MEMBERSHIPS || seg.length > MIMIC_MAX_MEMBERSHIPS)
35
- return null;
36
- const expiresAt = Date.parse(claims.expiresAt);
37
- if (Number.isNaN(expiresAt) || expiresAt <= Date.now())
38
- return null;
39
- return { ...claims, aud, seg };
40
- }
41
- catch {
42
- return null;
43
- }
44
- }
45
- // The session cookie dies with the token so an expired session self-clears
46
- // back to the genuine experience (D-12).
47
- export function createMimicEntryCookie(token, expiresAt, secure = true) {
48
- const maxAge = Math.max(1, Math.ceil((Date.parse(expiresAt) - Date.now()) / 1000));
49
- return {
50
- name: MIMIC_COOKIE,
51
- value: token,
52
- options: { httpOnly: true, sameSite: 'lax', maxAge, path: '/', secure },
53
- };
54
- }
55
- export function createMimicClearCookie(secure = true) {
56
- return {
57
- name: MIMIC_COOKIE,
58
- value: '',
59
- options: { httpOnly: true, sameSite: 'lax', maxAge: 0, path: '/', secure },
60
- };
61
- }
62
- // The banner is the truth signal (REQ-4): present on every mimic render,
63
- // absent otherwise. v1 lists raw IDs — the documented fallback (spec 04).
64
- export function createMimicBannerHTML(claims, expiresAt) {
65
- const names = [...(claims.aud ?? []), ...(claims.seg ?? [])]
66
- .map(escapeHTML)
67
- .join(', ');
68
- const remainingMinutes = Math.max(1, Math.ceil((Date.parse(expiresAt) - Date.now()) / 60000));
69
- return `<div role="alert" style="position:fixed;top:0;left:0;right:0;z-index:9999;display:flex;align-items:center;justify-content:center;gap:12px;padding:8px 16px;background-color:#0f2e1d;color:#fff;font-size:13px;font-family:system-ui,-apple-system,sans-serif;box-shadow:0 2px 8px rgba(0,0,0,0.3);">
70
- <span aria-hidden="true" style="display:inline-flex;align-items:center;justify-content:center;width:18px;height:18px;border-radius:50%;background-color:#10b981;color:#0f2e1d;font-weight:700;font-size:11px;flex-shrink:0;">M</span>
71
- <span style="font-weight:500;">Viewing as audience</span>
72
- <span style="font-family:monospace;opacity:0.85;font-size:12px;">${names}</span>
73
- <span style="opacity:0.7;font-size:12px;">expires in ${remainingMinutes} min</span>
74
- <a href="?${MIMIC_PARAM}=${MIMIC_EXIT}" style="margin-left:auto;padding:4px 12px;border-radius:6px;background-color:#dc2626;color:#fff;text-decoration:none;font-size:12px;font-weight:600;white-space:nowrap;">Exit</a>
75
- </div>`;
76
- }
77
- export function injectMimicBannerIntoHTML(html, banner) {
78
- return html.includes('</body>') ? html.replace('</body>', `${banner}</body>`) : html + banner;
79
- }
80
- // MIMIC_BANNER_HEADER carries the base64url-encoded banner HTML from the
81
- // middleware to the framework render (the MimicBanner component in
82
- // next/page.tsx). It is a reserved header: the middleware strips any inbound
83
- // copy and sets it only for a validated session.
1
+ // View-as-audience mimic banner contract (specs/features/audience-mimic).
2
+ // The platform edge router (internal/domain/hosting/runtime/mimic.ts) owns
3
+ // the mimic session — token validation, cookies, redirects, and banner
4
+ // creation. On body-less SSR rewrites it forwards the rendered banner to the
5
+ // framework host via MIMIC_BANNER_HEADER; this module is the framework-side
6
+ // leg that decodes it (the MimicBanner component in next/page.tsx). The
7
+ // middleware strips any inbound copy of the header and sets it only for a
8
+ // validated session, so the decoded HTML is trusted as authored.
9
+ //
10
+ // The SDK-side token validator that used to live here served the retired
11
+ // Next personalization-host lane (ADR 0041); the Go/TS validators in
12
+ // internal/domain/edge remain pinned by the shared vector file.
84
13
  export const MIMIC_BANNER_HEADER = 'x-aci-mimic-banner';
85
- export function encodeMimicBanner(claims) {
86
- return bytesToBase64URL(new TextEncoder().encode(createMimicBannerHTML(claims, claims.expiresAt)));
87
- }
88
14
  export function decodeMimicBanner(encoded) {
89
15
  try {
90
16
  return new TextDecoder().decode(base64URLToBytes(encoded));
@@ -93,12 +19,6 @@ export function decodeMimicBanner(encoded) {
93
19
  return '';
94
20
  }
95
21
  }
96
- function bytesToBase64URL(bytes) {
97
- let binary = '';
98
- for (const byte of bytes)
99
- binary += String.fromCharCode(byte);
100
- return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
101
- }
102
22
  function base64URLToBytes(value) {
103
23
  const base64 = value.replace(/-/g, '+').replace(/_/g, '/');
104
24
  const padded = base64.padEnd(Math.ceil(base64.length / 4) * 4, '=');
@@ -109,19 +29,3 @@ function base64URLToBytes(value) {
109
29
  }
110
30
  return bytes;
111
31
  }
112
- function constantTimeEqual(left, right) {
113
- if (left.length !== right.length)
114
- return false;
115
- let diff = 0;
116
- for (let i = 0; i < left.length; i++) {
117
- diff |= left[i] ^ right[i];
118
- }
119
- return diff === 0;
120
- }
121
- function escapeHTML(value) {
122
- return value
123
- .replace(/&/g, '&amp;')
124
- .replace(/</g, '&lt;')
125
- .replace(/>/g, '&gt;')
126
- .replace(/"/g, '&quot;');
127
- }
@@ -1,7 +1,3 @@
1
- import type { EdgeRouteManifest } from './personalization-host.js';
2
- export declare const VERCEL_EDGE_PROJECTION_SCHEMA_V1 = "gradial.vercel.edgeRoutes.v1";
3
- export declare const VERCEL_EDGE_PROJECTION_ENCODING_V1 = "gzip+base64";
4
- export declare const MAX_VERCEL_EDGE_MANIFEST_BYTES_V1: number;
5
1
  export interface ActiveReleasePointerV1 {
6
2
  releaseId: string;
7
3
  sequence: bigint;
@@ -13,12 +9,7 @@ export interface DeploymentCompatibilityV1 {
13
9
  maxSequence?: bigint;
14
10
  }
15
11
  export declare function activeReleaseV1Key(siteId: string): string;
16
- export declare function edgeRoutesV1Key(siteId: string, releaseId: string): string;
17
12
  export declare function deploymentCompatibilityKey(siteId: string, deploymentId: string): string;
18
13
  export declare function decodeActiveReleaseV1(value: unknown): ActiveReleasePointerV1;
19
14
  export declare function decodeDeploymentCompatibilityV1(value: unknown): DeploymentCompatibilityV1;
20
15
  export declare function clampDeploymentCompatibleReleaseV1(active: ActiveReleasePointerV1, compatibility: DeploymentCompatibilityV1): string;
21
- export declare function decodeEdgeRouteProjectionV1(value: unknown, expected: {
22
- siteId: string;
23
- releaseId: string;
24
- }): EdgeRouteManifest;