@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
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Agentic Content Infrastructure SDK
2
2
 
3
- `@gradial/aci` `0.1.52-rc.16` is a pre-1.0 public-surface reset for the ACI
3
+ `@gradial/aci` `0.1.52-rc.21` is a pre-1.0 public-surface reset for the ACI
4
4
  client SDK. Breaking changes from the old `0.1.x` accidental surface are
5
5
  intentional: the root import is framework-neutral, framework runtime behavior is
6
6
  behind explicit subpaths, and the first required customer path is React/Next.
@@ -8,7 +8,7 @@ behind explicit subpaths, and the first required customer path is React/Next.
8
8
  ## Install
9
9
 
10
10
  ```bash
11
- npm install @gradial/aci@0.1.52-rc.16 zod@^4
11
+ npm install @gradial/aci@0.1.52-rc.21 zod@^4
12
12
  ```
13
13
 
14
14
  ## Root Import
@@ -78,13 +78,13 @@ host bundles select and serve immutable release artifacts.
78
78
  The first RC scaffold path is Next:
79
79
 
80
80
  ```bash
81
- npx @gradial/aci@0.1.52-rc.16 init my-site --template next-starter
81
+ npx @gradial/aci@0.1.52-rc.21 init my-site --template next-starter
82
82
  ```
83
83
 
84
84
  List available templates:
85
85
 
86
86
  ```bash
87
- npx @gradial/aci@0.1.52-rc.16 init --list
87
+ npx @gradial/aci@0.1.52-rc.21 init --list
88
88
  ```
89
89
 
90
90
  ## Personalization: The One-Tag Install
@@ -1,9 +1,9 @@
1
- import { extractPreviewToken, resolvePreviewContext, createPreviewBannerHTML as coreCreatePreviewBannerHTML, createPreviewCookies as coreCreatePreviewCookies, previewSignKey, } from '../preview/core.js';
1
+ import { extractPreviewToken, parseCookies, resolvePreviewContext, createPreviewBannerHTML as coreCreatePreviewBannerHTML, createPreviewCookies as coreCreatePreviewCookies, previewSignKey, } from '../preview/core.js';
2
2
  export async function getPreviewMode(request, siteId) {
3
3
  const url = new URL(request.url);
4
4
  const token = extractPreviewToken({
5
5
  query: url.searchParams,
6
- cookies: parseCookieHeader(request.headers.get('cookie') || ''),
6
+ cookies: parseCookies(request.headers.get('cookie') || ''),
7
7
  authorization: request.headers.get('authorization') || undefined,
8
8
  });
9
9
  if (!token)
@@ -16,18 +16,3 @@ export function createPreviewBannerHTML(releaseId) {
16
16
  export function createPreviewCookies(token, releaseId) {
17
17
  return coreCreatePreviewCookies(token, releaseId);
18
18
  }
19
- function parseCookieHeader(header) {
20
- const cookies = new Map();
21
- for (const part of header.split(';')) {
22
- const trimmed = part.trim();
23
- if (!trimmed)
24
- continue;
25
- const idx = trimmed.indexOf('=');
26
- if (idx < 0)
27
- continue;
28
- const name = trimmed.slice(0, idx).trim();
29
- const value = trimmed.slice(idx + 1).trim();
30
- cookies.set(name, decodeURIComponent(value));
31
- }
32
- return cookies;
33
- }
@@ -1,4 +1,5 @@
1
1
  import { z } from 'zod';
2
+ export declare const expressionOperators: readonly ["equals", "contains", "startsWith", "exists", "greaterThan", "greaterThanOrEqual", "lessThan", "lessThanOrEqual", "before", "after", "between", "in"];
2
3
  export declare const segmentDataModel: import("./index.js").DataModelContract<z.ZodObject<{
3
4
  id: z.ZodString;
4
5
  displayName: z.ZodString;
@@ -299,22 +300,44 @@ export declare const audienceRuleDataModel: import("./index.js").DataModelContra
299
300
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
300
301
  field: z.ZodString;
301
302
  operator: z.ZodEnum<{
303
+ in: "in";
302
304
  equals: "equals";
303
305
  contains: "contains";
304
306
  startsWith: "startsWith";
305
307
  exists: "exists";
308
+ greaterThan: "greaterThan";
309
+ greaterThanOrEqual: "greaterThanOrEqual";
310
+ lessThan: "lessThan";
311
+ lessThanOrEqual: "lessThanOrEqual";
312
+ before: "before";
313
+ after: "after";
314
+ between: "between";
306
315
  }>;
307
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
316
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
317
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
318
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
319
+ }, z.core.$strict>]>>;
308
320
  }, z.core.$strip>>>;
309
321
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
310
322
  field: z.ZodString;
311
323
  operator: z.ZodEnum<{
324
+ in: "in";
312
325
  equals: "equals";
313
326
  contains: "contains";
314
327
  startsWith: "startsWith";
315
328
  exists: "exists";
329
+ greaterThan: "greaterThan";
330
+ greaterThanOrEqual: "greaterThanOrEqual";
331
+ lessThan: "lessThan";
332
+ lessThanOrEqual: "lessThanOrEqual";
333
+ before: "before";
334
+ after: "after";
335
+ between: "between";
316
336
  }>;
317
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
337
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
338
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
339
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
340
+ }, z.core.$strict>]>>;
318
341
  }, z.core.$strip>>>;
319
342
  }, z.core.$strip>;
320
343
  }, z.core.$strip>, "audience_rule">;
@@ -338,22 +361,44 @@ export declare const goalDataModel: import("./index.js").DataModelContract<z.Zod
338
361
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
339
362
  field: z.ZodString;
340
363
  operator: z.ZodEnum<{
364
+ in: "in";
341
365
  equals: "equals";
342
366
  contains: "contains";
343
367
  startsWith: "startsWith";
344
368
  exists: "exists";
369
+ greaterThan: "greaterThan";
370
+ greaterThanOrEqual: "greaterThanOrEqual";
371
+ lessThan: "lessThan";
372
+ lessThanOrEqual: "lessThanOrEqual";
373
+ before: "before";
374
+ after: "after";
375
+ between: "between";
345
376
  }>;
346
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
377
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
378
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
379
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
380
+ }, z.core.$strict>]>>;
347
381
  }, z.core.$strip>>>;
348
382
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
349
383
  field: z.ZodString;
350
384
  operator: z.ZodEnum<{
385
+ in: "in";
351
386
  equals: "equals";
352
387
  contains: "contains";
353
388
  startsWith: "startsWith";
354
389
  exists: "exists";
390
+ greaterThan: "greaterThan";
391
+ greaterThanOrEqual: "greaterThanOrEqual";
392
+ lessThan: "lessThan";
393
+ lessThanOrEqual: "lessThanOrEqual";
394
+ before: "before";
395
+ after: "after";
396
+ between: "between";
355
397
  }>;
356
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
398
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
399
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
400
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
401
+ }, z.core.$strict>]>>;
357
402
  }, z.core.$strip>>>;
358
403
  }, z.core.$strip>>;
359
404
  }, z.core.$strip>, "goal">;
@@ -399,22 +444,44 @@ export declare const experimentDataModel: import("./index.js").DataModelContract
399
444
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
400
445
  field: z.ZodString;
401
446
  operator: z.ZodEnum<{
447
+ in: "in";
402
448
  equals: "equals";
403
449
  contains: "contains";
404
450
  startsWith: "startsWith";
405
451
  exists: "exists";
452
+ greaterThan: "greaterThan";
453
+ greaterThanOrEqual: "greaterThanOrEqual";
454
+ lessThan: "lessThan";
455
+ lessThanOrEqual: "lessThanOrEqual";
456
+ before: "before";
457
+ after: "after";
458
+ between: "between";
406
459
  }>;
407
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
460
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
461
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
462
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
463
+ }, z.core.$strict>]>>;
408
464
  }, z.core.$strip>>>;
409
465
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
410
466
  field: z.ZodString;
411
467
  operator: z.ZodEnum<{
468
+ in: "in";
412
469
  equals: "equals";
413
470
  contains: "contains";
414
471
  startsWith: "startsWith";
415
472
  exists: "exists";
473
+ greaterThan: "greaterThan";
474
+ greaterThanOrEqual: "greaterThanOrEqual";
475
+ lessThan: "lessThan";
476
+ lessThanOrEqual: "lessThanOrEqual";
477
+ before: "before";
478
+ after: "after";
479
+ between: "between";
416
480
  }>;
417
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
481
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
482
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
483
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
484
+ }, z.core.$strict>]>>;
418
485
  }, z.core.$strip>>>;
419
486
  }, z.core.$strip>>;
420
487
  }, z.core.$strip>>;
@@ -432,22 +499,44 @@ export declare const experimentationDataModels: (import("./index.js").DataModelC
432
499
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
433
500
  field: z.ZodString;
434
501
  operator: z.ZodEnum<{
502
+ in: "in";
435
503
  equals: "equals";
436
504
  contains: "contains";
437
505
  startsWith: "startsWith";
438
506
  exists: "exists";
507
+ greaterThan: "greaterThan";
508
+ greaterThanOrEqual: "greaterThanOrEqual";
509
+ lessThan: "lessThan";
510
+ lessThanOrEqual: "lessThanOrEqual";
511
+ before: "before";
512
+ after: "after";
513
+ between: "between";
439
514
  }>;
440
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
515
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
516
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
517
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
518
+ }, z.core.$strict>]>>;
441
519
  }, z.core.$strip>>>;
442
520
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
443
521
  field: z.ZodString;
444
522
  operator: z.ZodEnum<{
523
+ in: "in";
445
524
  equals: "equals";
446
525
  contains: "contains";
447
526
  startsWith: "startsWith";
448
527
  exists: "exists";
528
+ greaterThan: "greaterThan";
529
+ greaterThanOrEqual: "greaterThanOrEqual";
530
+ lessThan: "lessThan";
531
+ lessThanOrEqual: "lessThanOrEqual";
532
+ before: "before";
533
+ after: "after";
534
+ between: "between";
449
535
  }>;
450
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
536
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
537
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
538
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
539
+ }, z.core.$strict>]>>;
451
540
  }, z.core.$strip>>>;
452
541
  }, z.core.$strip>>;
453
542
  }, z.core.$strip>, "goal"> | import("./index.js").DataModelContract<z.ZodObject<{
@@ -492,22 +581,44 @@ export declare const experimentationDataModels: (import("./index.js").DataModelC
492
581
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
493
582
  field: z.ZodString;
494
583
  operator: z.ZodEnum<{
584
+ in: "in";
495
585
  equals: "equals";
496
586
  contains: "contains";
497
587
  startsWith: "startsWith";
498
588
  exists: "exists";
589
+ greaterThan: "greaterThan";
590
+ greaterThanOrEqual: "greaterThanOrEqual";
591
+ lessThan: "lessThan";
592
+ lessThanOrEqual: "lessThanOrEqual";
593
+ before: "before";
594
+ after: "after";
595
+ between: "between";
499
596
  }>;
500
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
597
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
598
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
599
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
600
+ }, z.core.$strict>]>>;
501
601
  }, z.core.$strip>>>;
502
602
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
503
603
  field: z.ZodString;
504
604
  operator: z.ZodEnum<{
605
+ in: "in";
505
606
  equals: "equals";
506
607
  contains: "contains";
507
608
  startsWith: "startsWith";
508
609
  exists: "exists";
610
+ greaterThan: "greaterThan";
611
+ greaterThanOrEqual: "greaterThanOrEqual";
612
+ lessThan: "lessThan";
613
+ lessThanOrEqual: "lessThanOrEqual";
614
+ before: "before";
615
+ after: "after";
616
+ between: "between";
509
617
  }>;
510
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
618
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
619
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
620
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
621
+ }, z.core.$strict>]>>;
511
622
  }, z.core.$strip>>>;
512
623
  }, z.core.$strip>>;
513
624
  }, z.core.$strip>>;
@@ -809,22 +920,44 @@ export declare const audienceDataModels: (import("./index.js").DataModelContract
809
920
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
810
921
  field: z.ZodString;
811
922
  operator: z.ZodEnum<{
923
+ in: "in";
812
924
  equals: "equals";
813
925
  contains: "contains";
814
926
  startsWith: "startsWith";
815
927
  exists: "exists";
928
+ greaterThan: "greaterThan";
929
+ greaterThanOrEqual: "greaterThanOrEqual";
930
+ lessThan: "lessThan";
931
+ lessThanOrEqual: "lessThanOrEqual";
932
+ before: "before";
933
+ after: "after";
934
+ between: "between";
816
935
  }>;
817
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
936
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
937
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
938
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
939
+ }, z.core.$strict>]>>;
818
940
  }, z.core.$strip>>>;
819
941
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
820
942
  field: z.ZodString;
821
943
  operator: z.ZodEnum<{
944
+ in: "in";
822
945
  equals: "equals";
823
946
  contains: "contains";
824
947
  startsWith: "startsWith";
825
948
  exists: "exists";
949
+ greaterThan: "greaterThan";
950
+ greaterThanOrEqual: "greaterThanOrEqual";
951
+ lessThan: "lessThan";
952
+ lessThanOrEqual: "lessThanOrEqual";
953
+ before: "before";
954
+ after: "after";
955
+ between: "between";
826
956
  }>;
827
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
957
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
958
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
959
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
960
+ }, z.core.$strict>]>>;
828
961
  }, z.core.$strip>>>;
829
962
  }, z.core.$strip>;
830
963
  }, z.core.$strip>, "audience_rule"> | import("./index.js").DataModelContract<z.ZodObject<{
@@ -846,22 +979,44 @@ export declare const audienceDataModels: (import("./index.js").DataModelContract
846
979
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
847
980
  field: z.ZodString;
848
981
  operator: z.ZodEnum<{
982
+ in: "in";
849
983
  equals: "equals";
850
984
  contains: "contains";
851
985
  startsWith: "startsWith";
852
986
  exists: "exists";
987
+ greaterThan: "greaterThan";
988
+ greaterThanOrEqual: "greaterThanOrEqual";
989
+ lessThan: "lessThan";
990
+ lessThanOrEqual: "lessThanOrEqual";
991
+ before: "before";
992
+ after: "after";
993
+ between: "between";
853
994
  }>;
854
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
995
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
996
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
997
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
998
+ }, z.core.$strict>]>>;
855
999
  }, z.core.$strip>>>;
856
1000
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
857
1001
  field: z.ZodString;
858
1002
  operator: z.ZodEnum<{
1003
+ in: "in";
859
1004
  equals: "equals";
860
1005
  contains: "contains";
861
1006
  startsWith: "startsWith";
862
1007
  exists: "exists";
1008
+ greaterThan: "greaterThan";
1009
+ greaterThanOrEqual: "greaterThanOrEqual";
1010
+ lessThan: "lessThan";
1011
+ lessThanOrEqual: "lessThanOrEqual";
1012
+ before: "before";
1013
+ after: "after";
1014
+ between: "between";
863
1015
  }>;
864
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
1016
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
1017
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
1018
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
1019
+ }, z.core.$strict>]>>;
865
1020
  }, z.core.$strip>>>;
866
1021
  }, z.core.$strip>>;
867
1022
  }, z.core.$strip>, "goal"> | import("./index.js").DataModelContract<z.ZodObject<{
@@ -906,22 +1061,44 @@ export declare const audienceDataModels: (import("./index.js").DataModelContract
906
1061
  all: z.ZodOptional<z.ZodArray<z.ZodObject<{
907
1062
  field: z.ZodString;
908
1063
  operator: z.ZodEnum<{
1064
+ in: "in";
909
1065
  equals: "equals";
910
1066
  contains: "contains";
911
1067
  startsWith: "startsWith";
912
1068
  exists: "exists";
1069
+ greaterThan: "greaterThan";
1070
+ greaterThanOrEqual: "greaterThanOrEqual";
1071
+ lessThan: "lessThan";
1072
+ lessThanOrEqual: "lessThanOrEqual";
1073
+ before: "before";
1074
+ after: "after";
1075
+ between: "between";
913
1076
  }>;
914
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
1077
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
1078
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
1079
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
1080
+ }, z.core.$strict>]>>;
915
1081
  }, z.core.$strip>>>;
916
1082
  any: z.ZodOptional<z.ZodArray<z.ZodObject<{
917
1083
  field: z.ZodString;
918
1084
  operator: z.ZodEnum<{
1085
+ in: "in";
919
1086
  equals: "equals";
920
1087
  contains: "contains";
921
1088
  startsWith: "startsWith";
922
1089
  exists: "exists";
1090
+ greaterThan: "greaterThan";
1091
+ greaterThanOrEqual: "greaterThanOrEqual";
1092
+ lessThan: "lessThan";
1093
+ lessThanOrEqual: "lessThanOrEqual";
1094
+ before: "before";
1095
+ after: "after";
1096
+ between: "between";
923
1097
  }>;
924
- value: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>;
1098
+ value: z.ZodOptional<z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>, z.ZodArray<z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean]>>, z.ZodObject<{
1099
+ min: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
1100
+ max: z.ZodUnion<readonly [z.ZodNumber, z.ZodString]>;
1101
+ }, z.core.$strict>]>>;
925
1102
  }, z.core.$strip>>>;
926
1103
  }, z.core.$strip>>;
927
1104
  }, z.core.$strip>>;
@@ -51,10 +51,55 @@ const segmentCriteriaSchema = z.union([
51
51
  none: z.array(segmentCriteriaConditionSchema).optional(),
52
52
  }).strict(),
53
53
  ]);
54
+ // Mirrors the ADR 0038 operator vocabulary for author-time DX; the expression
55
+ // kernel stays the authority, and the capability drift test pins this enum
56
+ // and the operand pairing to the generated artifact.
57
+ export const expressionOperators = [
58
+ 'equals', 'contains', 'startsWith', 'exists',
59
+ 'greaterThan', 'greaterThanOrEqual', 'lessThan', 'lessThanOrEqual',
60
+ 'before', 'after', 'between', 'in',
61
+ ];
62
+ const maxInValues = 32;
63
+ const rangeBoundValue = z.union([z.number(), z.string()]);
64
+ const conditionValueSchema = z.union([
65
+ scalarValue,
66
+ z.array(scalarValue).min(1).max(maxInValues),
67
+ z.object({ min: rangeBoundValue, max: rangeBoundValue }).strict(),
68
+ ]);
69
+ const scalarOperandOperators = new Set(['equals', 'contains', 'startsWith']);
70
+ const numberOperandOperators = new Set(['greaterThan', 'greaterThanOrEqual', 'lessThan', 'lessThanOrEqual']);
71
+ const timestampOperandOperators = new Set(['before', 'after']);
54
72
  const requestRuleConditionSchema = z.object({
55
73
  field: z.string().min(1),
56
- operator: z.enum(['equals', 'contains', 'startsWith', 'exists']),
57
- value: scalarValue.optional(),
74
+ operator: z.enum(expressionOperators),
75
+ value: conditionValueSchema.optional(),
76
+ }).superRefine((condition, context) => {
77
+ const { operator, value } = condition;
78
+ const fail = (message) => context.addIssue({ code: z.ZodIssueCode.custom, path: ['value'], message });
79
+ if (operator === 'exists') {
80
+ if (value !== undefined && typeof value !== 'boolean')
81
+ fail('exists takes an optional boolean value');
82
+ return;
83
+ }
84
+ if (value === undefined) {
85
+ fail(`value is required for operator ${operator}`);
86
+ return;
87
+ }
88
+ if (scalarOperandOperators.has(operator) && (typeof value === 'object')) {
89
+ fail(`${operator} takes one scalar value`);
90
+ }
91
+ else if (numberOperandOperators.has(operator) && typeof value !== 'number') {
92
+ fail(`${operator} takes one finite JSON number`);
93
+ }
94
+ else if (timestampOperandOperators.has(operator) && typeof value !== 'string') {
95
+ fail(`${operator} takes one RFC 3339 timestamp string`);
96
+ }
97
+ else if (operator === 'between' && (typeof value !== 'object' || Array.isArray(value))) {
98
+ fail('between takes a {min, max} object');
99
+ }
100
+ else if (operator === 'in' && !Array.isArray(value)) {
101
+ fail(`in takes an array of 1 to ${maxInValues} scalars`);
102
+ }
58
103
  });
59
104
  const requestRuleExpressionSchema = z.object({
60
105
  all: z.array(requestRuleConditionSchema).optional(),
@@ -26,11 +26,12 @@ export type PendingEvent = Omit<CollectEvent, "eventId">;
26
26
  /** Planning threshold: full serialized envelope, UTF-8 bytes. */
27
27
  export declare const MAX_BATCH_BYTES: number;
28
28
  /**
29
- * Hard event-count cap per envelope. The Next collect-route imports this
30
- * constant and rejects larger envelopes (the Go handler enforces only the
31
- * 64KiB body cap today), so a byte-capped-only batch of small events (~400
32
- * fit in 60KiB) would 400 on that host and silently lose the whole flush.
33
- * The client caps at the strictest host.
29
+ * Hard event-count cap per envelope. The provider-neutral runtime collector
30
+ * (internal/domain/audience/runtime/collect.ts MAX_BATCH_EVENTS) enforces the
31
+ * same bound server-side (the Go handler enforces only the 64KiB body cap
32
+ * today), so a byte-capped-only batch of small events (~400 fit in 60KiB)
33
+ * would 400 on that host and silently lose the whole flush. The client caps
34
+ * at the strictest host; keep the two constants equal.
34
35
  */
35
36
  export declare const MAX_BATCH_EVENTS = 100;
36
37
  /** Flush interval (build-time constant, design/04 config table). */
@@ -7,11 +7,12 @@ import { ulid } from "./ulid.js";
7
7
  /** Planning threshold: full serialized envelope, UTF-8 bytes. */
8
8
  export const MAX_BATCH_BYTES = 60 * 1024;
9
9
  /**
10
- * Hard event-count cap per envelope. The Next collect-route imports this
11
- * constant and rejects larger envelopes (the Go handler enforces only the
12
- * 64KiB body cap today), so a byte-capped-only batch of small events (~400
13
- * fit in 60KiB) would 400 on that host and silently lose the whole flush.
14
- * The client caps at the strictest host.
10
+ * Hard event-count cap per envelope. The provider-neutral runtime collector
11
+ * (internal/domain/audience/runtime/collect.ts MAX_BATCH_EVENTS) enforces the
12
+ * same bound server-side (the Go handler enforces only the 64KiB body cap
13
+ * today), so a byte-capped-only batch of small events (~400 fit in 60KiB)
14
+ * would 400 on that host and silently lose the whole flush. The client caps
15
+ * at the strictest host; keep the two constants equal.
15
16
  */
16
17
  export const MAX_BATCH_EVENTS = 100;
17
18
  /** Flush interval (build-time constant, design/04 config table). */
@@ -0,0 +1,106 @@
1
+ export declare const expressionCapabilities: {
2
+ readonly schemaVersion: 1;
3
+ readonly contract: "personalization-expression";
4
+ readonly maxConditions: 64;
5
+ readonly maxDepth: 5;
6
+ readonly maxInValues: 32;
7
+ readonly grammars: {
8
+ readonly number: "^-?(0|[1-9][0-9]*)(\\.[0-9]+)?([eE][+-]?[0-9]+)?$";
9
+ readonly timestamp: "^(\\d{4})-(\\d{2})-(\\d{2})T(\\d{2}):(\\d{2}):(\\d{2})(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})$";
10
+ };
11
+ readonly operators: readonly [{
12
+ readonly name: "equals";
13
+ readonly operand: "scalar";
14
+ readonly compact: "eq";
15
+ }, {
16
+ readonly name: "contains";
17
+ readonly operand: "scalar";
18
+ readonly compact: "ct";
19
+ }, {
20
+ readonly name: "startsWith";
21
+ readonly operand: "scalar";
22
+ readonly compact: "sw";
23
+ }, {
24
+ readonly name: "exists";
25
+ readonly operand: "optionalBoolean";
26
+ readonly compact: "ex";
27
+ }, {
28
+ readonly name: "greaterThan";
29
+ readonly operand: "number";
30
+ readonly compact: "gt";
31
+ }, {
32
+ readonly name: "greaterThanOrEqual";
33
+ readonly operand: "number";
34
+ readonly compact: "ge";
35
+ }, {
36
+ readonly name: "lessThan";
37
+ readonly operand: "number";
38
+ readonly compact: "lt";
39
+ }, {
40
+ readonly name: "lessThanOrEqual";
41
+ readonly operand: "number";
42
+ readonly compact: "le";
43
+ }, {
44
+ readonly name: "before";
45
+ readonly operand: "timestamp";
46
+ readonly compact: "bf";
47
+ }, {
48
+ readonly name: "after";
49
+ readonly operand: "timestamp";
50
+ readonly compact: "af";
51
+ }, {
52
+ readonly name: "between";
53
+ readonly operand: "range";
54
+ readonly compact: "bt";
55
+ readonly range: {
56
+ readonly memberTypes: readonly ["number", "timestamp"];
57
+ readonly homogeneous: true;
58
+ readonly inclusive: true;
59
+ };
60
+ }, {
61
+ readonly name: "in";
62
+ readonly operand: "scalarList";
63
+ readonly compact: "in";
64
+ readonly maxValues: 32;
65
+ }];
66
+ readonly scopes: readonly [{
67
+ readonly scope: "request";
68
+ readonly allowsEmpty: false;
69
+ readonly fields: readonly [{
70
+ readonly field: "referrer";
71
+ }, {
72
+ readonly field: "query.*";
73
+ }, {
74
+ readonly field: "header.*";
75
+ }, {
76
+ readonly field: "cookie.*";
77
+ }, {
78
+ readonly field: "geo.*";
79
+ }, {
80
+ readonly field: "utm.*";
81
+ }, {
82
+ readonly field: "device.class";
83
+ readonly operators: readonly ["equals", "in", "exists"];
84
+ readonly values: readonly ["desktop", "mobile", "tablet", "unknown"];
85
+ }, {
86
+ readonly field: "time.now";
87
+ readonly operators: readonly ["before", "after", "between", "exists"];
88
+ readonly instant: true;
89
+ }, {
90
+ readonly field: "audience.memberships";
91
+ readonly operators: readonly ["equals", "in", "exists"];
92
+ }];
93
+ }, {
94
+ readonly scope: "event";
95
+ readonly allowsEmpty: true;
96
+ readonly fields: readonly [{
97
+ readonly field: "referrer";
98
+ }, {
99
+ readonly field: "page.path";
100
+ }, {
101
+ readonly field: "properties.*";
102
+ }, {
103
+ readonly field: "utm.*";
104
+ }];
105
+ }];
106
+ };