@nextcommerce/campaigns-os 1.60.0 → 1.62.0
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/AGENTS.md +2 -1
- package/CHANGELOG.md +244 -0
- package/README.md +86 -438
- package/agents/claude/CLAUDE.md +20 -0
- package/agents/codex/AGENTS.md +19 -0
- package/agents/copilot/copilot-instructions.md +19 -0
- package/agents/cursor/campaigns-os.mdc +21 -0
- package/campaign-spec/README.md +7 -0
- package/campaign-spec/dist/analytics-vendors.d.ts +40 -0
- package/campaign-spec/dist/analytics-vendors.js +44 -0
- package/campaign-spec/dist/checkout-flow.d.ts +18 -0
- package/campaign-spec/dist/checkout-flow.js +28 -0
- package/campaign-spec/dist/index.d.ts +4 -2
- package/campaign-spec/dist/index.js +5 -1
- package/campaign-spec/dist/rules/analytics-contract-shape.d.ts +8 -0
- package/campaign-spec/dist/rules/analytics-contract-shape.js +39 -0
- package/campaign-spec/dist/rules/campaign-currencies.d.ts +29 -0
- package/campaign-spec/dist/rules/campaign-currencies.js +130 -0
- package/campaign-spec/dist/rules/checkout-path-has-packages.d.ts +31 -0
- package/campaign-spec/dist/rules/checkout-path-has-packages.js +79 -0
- package/campaign-spec/dist/rules/index.d.ts +2 -0
- package/campaign-spec/dist/rules/index.js +6 -0
- package/campaign-spec/dist/types.d.ts +43 -9
- package/compatibility.json +1 -1
- package/contracts/brand-theme-target-tokens.next-core.v0.json +95 -25
- package/contracts/campaign-cart-sdk-support-policy.v0.json +2 -2
- package/contracts/commerce-surface-catalog.json +68 -61
- package/contracts/effects.v1.json +549 -165
- package/contracts/fixtures/runtime-recipe/accept/current.json +3 -0
- package/contracts/fixtures/runtime-recipe/accept/minimal.json +3 -0
- package/contracts/fixtures/runtime-recipe/dist-states.json +1 -1
- package/contracts/fixtures/runtime-recipe/reject/advisory-enforcement.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/allowlist-without-hosts.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/committed-output-claim.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/engines-disagreement-warns.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/lifecycle-scripts-enabled.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-kind.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-network-policy.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-output-check.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-revision.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unknown-step-id.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unperformable-check-skipped.json +3 -0
- package/contracts/fixtures/runtime-recipe/reject/unpinned-lockfile.json +3 -0
- package/contracts/release-ledger.json +1767 -0
- package/contracts/runtime-recipe.campaigns-os-node-v1.json +3 -0
- package/contracts/supported-surface.json +10 -10
- package/contracts/template-brand-contract.shared-commerce.v0.json +23 -1
- package/docs/access-model.md +20 -0
- package/docs/brand-theme-bridge.md +62 -3
- package/docs/build-packet.md +456 -36
- package/docs/campaign-build-brief.md +16 -0
- package/docs/campaign-standardization-report.md +4 -4
- package/docs/campaigns-os-build-flow.md +112 -2
- package/docs/campaignspec-authoring-examples.md +141 -0
- package/docs/design-source-package.md +64 -8
- package/docs/effects.md +17 -9
- package/docs/entry-points.md +188 -0
- package/docs/local-setup.md +1 -1
- package/docs/orientation-contract-reference.md +1 -1
- package/docs/polish-evidence.md +42 -2
- package/docs/progress-snapshots.md +7 -4
- package/docs/qa-and-test-orders.md +197 -3
- package/docs/quickstart.md +438 -0
- package/docs/readback.md +154 -6
- package/docs/runtime-readiness.md +6 -3
- package/docs/sdk-storage-compatibility.md +4 -2
- package/docs/skills-revision.md +10 -10
- package/docs/source-adapters.md +213 -0
- package/package.json +10 -3
- package/schemas/campaign-design-source-package.v0.schema.json +8 -0
- package/schemas/campaign-runtime-build-context.v0.schema.json +9 -0
- package/schemas/campaign-runtime-build-packet.v0.schema.json +9 -0
- package/schemas/campaign-spec.v4.schema.json +19 -3
- package/schemas/campaign-spec.v5.schema.json +19 -3
- package/schemas/campaigns-os-readback.v2.schema.json +238 -1
- package/schemas/source-html-manifest.v0.schema.json +3 -0
- package/skills/campaign-lifecycle-orientation/SKILL.md +3 -3
- package/skills/campaign-readback-classification/SKILL.md +3 -3
- package/skills/campaign-run-evidence/SKILL.md +3 -3
- package/skills/contribution-intake/SKILL.md +3 -3
- package/skills/next-campaigns-build/SKILL.md +5 -4
- package/skills/next-campaigns-os/SKILL.md +7 -4
- package/skills/next-campaigns-os-setup/SKILL.md +5 -3
- package/skills/next-campaigns-polish/SKILL.md +8 -10
- package/skills/next-campaigns-qa/SKILL.md +7 -4
- package/skills/next-campaigns-sdk-bump/SKILL.md +151 -25
- package/skills.json +11 -11
- package/src/brand-theme.mjs +415 -9
- package/src/brief-summary.mjs +6 -2
- package/src/browser-launch.mjs +2 -1
- package/src/build-brief.mjs +13 -3
- package/src/built-site-scope.mjs +2 -2
- package/src/campaign-workspace.mjs +288 -15
- package/src/change-scope.mjs +284 -0
- package/src/cli.mjs +358 -97
- package/src/commercial-journey.mjs +16 -3
- package/src/commercial-parity.mjs +15 -7
- package/src/content-residue.mjs +4 -2
- package/src/design-file-reference.mjs +93 -0
- package/src/design-source-package.mjs +91 -1
- package/src/design-source-publication.mjs +9 -6
- package/src/directory-lock.mjs +73 -19
- package/src/doctor/checks.mjs +87 -81
- package/src/doctor/ci.mjs +177 -0
- package/src/doctor/inspect.mjs +41 -6
- package/src/doctor/next-step.mjs +7 -0
- package/src/doctor/source-provenance.mjs +74 -0
- package/src/doctor-sidecar.mjs +3 -2
- package/src/evidence-debt.mjs +159 -0
- package/src/finding-cause.mjs +12 -11
- package/src/input-refresh.mjs +339 -32
- package/src/invocation.mjs +7 -1
- package/src/live-campaign-refs.mjs +7 -2
- package/src/local-preview-policy.mjs +35 -2
- package/src/page-kit-analytics-vendors.mjs +132 -0
- package/src/parity/compare.mjs +316 -0
- package/src/parity/design-access.mjs +54 -0
- package/src/parity/element-parity-record.mjs +569 -0
- package/src/parity/probe.mjs +205 -0
- package/src/parity/snapshot.mjs +110 -0
- package/src/png-header.mjs +87 -0
- package/src/polish-browser.mjs +189 -10
- package/src/polish-captures-record.mjs +52 -0
- package/src/polish-deadline.mjs +14 -0
- package/src/polish-gate.mjs +25 -6
- package/src/polish-node.mjs +81 -7
- package/src/polish-readability.mjs +221 -9
- package/src/polish-visual-fixtures.mjs +74 -0
- package/src/polish-visual.mjs +613 -0
- package/src/progress-node.mjs +3 -2
- package/src/qa-analytics-correctness.mjs +14 -2
- package/src/qa-analytics-parity.mjs +111 -6
- package/src/qa-browser.mjs +40 -4
- package/src/qa-commercial-parity.mjs +50 -3
- package/src/qa-node.mjs +235 -22
- package/src/qa-publish.mjs +9 -8
- package/src/qa-sidecar.mjs +16 -4
- package/src/qa-vendor-beacons.mjs +232 -0
- package/src/qa-vendor-endpoints.mjs +306 -0
- package/src/qc-accept.mjs +176 -6
- package/src/qc-check-registry.mjs +42 -2
- package/src/qc-results.mjs +477 -42
- package/src/readback.mjs +113 -21
- package/src/route-identity.mjs +10 -0
- package/src/run-record.mjs +18 -10
- package/src/runtime-state-ignore.mjs +6 -2
- package/src/sdk-attribute-index.mjs +11 -11
- package/src/sdk-markup.mjs +77 -2
- package/src/sdk-storage-compatibility.mjs +115 -6
- package/src/source-html-intake.mjs +15 -1
- package/src/source-html-manifest.mjs +7 -0
- package/src/source-html-server.mjs +129 -0
- package/src/spec-derive-campaign.mjs +216 -0
- package/src/spec-derive.mjs +473 -53
- package/src/spec-identity.mjs +14 -0
- package/src/stage-ledger.mjs +40 -1
- package/src/stage-record.mjs +100 -17
- package/src/target-lock.mjs +11 -1
- package/src/theme-gate.mjs +2 -2
- package/src/visual-diff.mjs +296 -0
- package/src/visual-reference.mjs +126 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CheckoutPathHasPackages — every path from an entry page to a Checkout passes
|
|
3
|
+
* at least one page that sells a main-cart package (campaigns-os#711, #206).
|
|
4
|
+
*
|
|
5
|
+
* A Checkout the shopper reaches with nothing in the cart cannot take an
|
|
6
|
+
* order, and until this rule nothing said so before a test order failed. The
|
|
7
|
+
* selling page may be any page on the path up to and including the Checkout:
|
|
8
|
+
* a select page's bundle picker, a landing page's package cards, a checkout
|
|
9
|
+
* step, or the Checkout's own selector. So the rule counts per path, never per
|
|
10
|
+
* page: a Checkout with no packages of its own passes when every path into it
|
|
11
|
+
* sells first.
|
|
12
|
+
*
|
|
13
|
+
* "Main-cart package" is the ratified #206 contract (checkout-flow.ts
|
|
14
|
+
* `isMainCartPackage`, docs/template-family-contracts.md "Main-cart entry"):
|
|
15
|
+
* an entry with neither `is_upsell: true` nor `is_order_bump: true`. Bump rows
|
|
16
|
+
* alone sell nothing, `default_selected` never changes the role, and entries
|
|
17
|
+
* on upsell, downsell or thank-you pages never count.
|
|
18
|
+
*
|
|
19
|
+
* Paths are walked the way OneCheckoutPerPath walks them: both edges a page
|
|
20
|
+
* can traverse (routing.ts), starting at the funnel's entry pages
|
|
21
|
+
* (checkout-flow.ts `entryPages`). No page order or name is consulted. The
|
|
22
|
+
* search runs, per entry page, over (page, sold yet) states and stops at the
|
|
23
|
+
* first Checkout, so each empty Checkout is reported once per entry however
|
|
24
|
+
* many of that entry's paths reach it. A second Checkout on one path is
|
|
25
|
+
* OneCheckoutPerPath's to report.
|
|
26
|
+
*
|
|
27
|
+
* With build_scope.mode === 'partial' the finding is a warning: a partial
|
|
28
|
+
* build may ship a Checkout that a page outside the build fills.
|
|
29
|
+
*/
|
|
30
|
+
import { outgoingEdgeIds } from "../routing.js";
|
|
31
|
+
import { entryPages, isPaymentPage, resolveRouteTargetPage, sellsMainCartPackage } from "../checkout-flow.js";
|
|
32
|
+
export const CheckoutPathHasPackages = {
|
|
33
|
+
id: 'CheckoutPathHasPackages',
|
|
34
|
+
severity: 'error',
|
|
35
|
+
tags: ['structure', 'spec-only'],
|
|
36
|
+
check(spec) {
|
|
37
|
+
const violations = [];
|
|
38
|
+
const partial = spec.build_scope?.mode === 'partial';
|
|
39
|
+
spec.funnels.forEach((funnel, funnelIdx) => {
|
|
40
|
+
const pages = (funnel.pages ?? []).filter((page) => page && page.enabled !== false);
|
|
41
|
+
const indexOf = new Map();
|
|
42
|
+
(funnel.pages ?? []).forEach((page, idx) => indexOf.set(page, idx));
|
|
43
|
+
for (const entry of entryPages(funnel)) {
|
|
44
|
+
const seen = new Set();
|
|
45
|
+
const reported = new Set();
|
|
46
|
+
const stack = [[entry, false]];
|
|
47
|
+
while (stack.length) {
|
|
48
|
+
const [page, before] = stack.pop();
|
|
49
|
+
const sold = before || sellsMainCartPackage(page);
|
|
50
|
+
const key = `${indexOf.get(page)}:${sold}`;
|
|
51
|
+
if (seen.has(key))
|
|
52
|
+
continue;
|
|
53
|
+
seen.add(key);
|
|
54
|
+
if (isPaymentPage(page)) {
|
|
55
|
+
if (!sold && !reported.has(page)) {
|
|
56
|
+
reported.add(page);
|
|
57
|
+
violations.push({
|
|
58
|
+
ruleId: 'CheckoutPathHasPackages',
|
|
59
|
+
severity: partial ? 'warning' : 'error',
|
|
60
|
+
message: `A path from entry page "${entry.id}" reaches Checkout "${page.id}" without passing a page that sells a main-cart package, so the cart is empty and no order can be placed. ` +
|
|
61
|
+
'Add a package entry not marked is_upsell or is_order_bump to the Checkout or a page before it on this path.' +
|
|
62
|
+
(partial ? ' Valid for partial builds when a page outside this build fills the cart.' : ''),
|
|
63
|
+
path: `/funnels/${funnelIdx}/pages/${indexOf.get(page)}`,
|
|
64
|
+
data: { pageId: page.id, entryPageId: entry.id, isPartialScope: partial },
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
for (const target of outgoingEdgeIds(page)) {
|
|
70
|
+
const next = resolveRouteTargetPage(pages, target);
|
|
71
|
+
if (next)
|
|
72
|
+
stack.push([next, sold]);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
return violations;
|
|
78
|
+
},
|
|
79
|
+
};
|
|
@@ -35,11 +35,13 @@ export { CheckoutForwardTarget } from './checkout-forward-target.ts';
|
|
|
35
35
|
export { PrePaymentForwardTarget } from './pre-payment-forward-target.ts';
|
|
36
36
|
export { CheckoutStepReachesCheckout } from './checkout-step-reaches-checkout.ts';
|
|
37
37
|
export { OneCheckoutPerPath } from './one-checkout-per-path.ts';
|
|
38
|
+
export { CheckoutPathHasPackages } from './checkout-path-has-packages.ts';
|
|
38
39
|
export { UpsellWithoutCheckout } from './upsell-without-checkout.ts';
|
|
39
40
|
export { DownsellWithoutUpsell } from './downsell-without-upsell.ts';
|
|
40
41
|
export { PackagePricingSanity } from './package-pricing-sanity.ts';
|
|
41
42
|
export { ShippingMethodsPresent } from './shipping-methods-present.ts';
|
|
42
43
|
export { ShippingCountriesShape } from './shipping-countries-shape.ts';
|
|
44
|
+
export { CampaignCurrencies } from './campaign-currencies.ts';
|
|
43
45
|
export { OfferRefIntegrity } from './offer-ref-integrity.ts';
|
|
44
46
|
export { ExitIntentValidation } from './exit-intent-validation.ts';
|
|
45
47
|
export { PromoCodeInputValidation } from './promo-code-input-validation.ts';
|
|
@@ -34,11 +34,13 @@ import { CheckoutForwardTarget } from "./checkout-forward-target.js";
|
|
|
34
34
|
import { PrePaymentForwardTarget } from "./pre-payment-forward-target.js";
|
|
35
35
|
import { CheckoutStepReachesCheckout } from "./checkout-step-reaches-checkout.js";
|
|
36
36
|
import { OneCheckoutPerPath } from "./one-checkout-per-path.js";
|
|
37
|
+
import { CheckoutPathHasPackages } from "./checkout-path-has-packages.js";
|
|
37
38
|
import { UpsellWithoutCheckout } from "./upsell-without-checkout.js";
|
|
38
39
|
import { DownsellWithoutUpsell } from "./downsell-without-upsell.js";
|
|
39
40
|
import { CampaignMetadata } from "./campaign-metadata.js";
|
|
40
41
|
import { ShippingMethodsPresent } from "./shipping-methods-present.js";
|
|
41
42
|
import { ShippingCountriesShape } from "./shipping-countries-shape.js";
|
|
43
|
+
import { CampaignCurrencies } from "./campaign-currencies.js";
|
|
42
44
|
import { PackagePricingSanity } from "./package-pricing-sanity.js";
|
|
43
45
|
import { OfferRefIntegrity } from "./offer-ref-integrity.js";
|
|
44
46
|
import { ExitIntentValidation } from "./exit-intent-validation.js";
|
|
@@ -69,11 +71,13 @@ export { CheckoutForwardTarget } from "./checkout-forward-target.js";
|
|
|
69
71
|
export { PrePaymentForwardTarget } from "./pre-payment-forward-target.js";
|
|
70
72
|
export { CheckoutStepReachesCheckout } from "./checkout-step-reaches-checkout.js";
|
|
71
73
|
export { OneCheckoutPerPath } from "./one-checkout-per-path.js";
|
|
74
|
+
export { CheckoutPathHasPackages } from "./checkout-path-has-packages.js";
|
|
72
75
|
export { UpsellWithoutCheckout } from "./upsell-without-checkout.js";
|
|
73
76
|
export { DownsellWithoutUpsell } from "./downsell-without-upsell.js";
|
|
74
77
|
export { PackagePricingSanity } from "./package-pricing-sanity.js";
|
|
75
78
|
export { ShippingMethodsPresent } from "./shipping-methods-present.js";
|
|
76
79
|
export { ShippingCountriesShape } from "./shipping-countries-shape.js";
|
|
80
|
+
export { CampaignCurrencies } from "./campaign-currencies.js";
|
|
77
81
|
export { OfferRefIntegrity } from "./offer-ref-integrity.js";
|
|
78
82
|
export { ExitIntentValidation } from "./exit-intent-validation.js";
|
|
79
83
|
export { PromoCodeInputValidation } from "./promo-code-input-validation.js";
|
|
@@ -114,11 +118,13 @@ export const allRules = [
|
|
|
114
118
|
PrePaymentForwardTarget,
|
|
115
119
|
CheckoutStepReachesCheckout,
|
|
116
120
|
OneCheckoutPerPath,
|
|
121
|
+
CheckoutPathHasPackages,
|
|
117
122
|
UpsellWithoutCheckout,
|
|
118
123
|
DownsellWithoutUpsell,
|
|
119
124
|
PackagePricingSanity,
|
|
120
125
|
ShippingMethodsPresent,
|
|
121
126
|
ShippingCountriesShape,
|
|
127
|
+
CampaignCurrencies,
|
|
122
128
|
OfferRefIntegrity,
|
|
123
129
|
ExitIntentValidation,
|
|
124
130
|
PromoCodeInputValidation,
|
|
@@ -519,12 +519,17 @@ export interface Campaign {
|
|
|
519
519
|
*
|
|
520
520
|
* Modeled on real production-funnel usage, NOT the idealized "SDK fires the
|
|
521
521
|
* canonical dl_* set" view. The field reality the block must express:
|
|
522
|
-
* - Events
|
|
523
|
-
*
|
|
524
|
-
*
|
|
525
|
-
*
|
|
526
|
-
*
|
|
527
|
-
*
|
|
522
|
+
* - Events reach vendors four ways: SDK providers (`providers`: GTM, Meta,
|
|
523
|
+
* RudderStack, a custom endpoint, configured through config.js);
|
|
524
|
+
* SDK-blocked-then-manual (`blockedEvents` suppresses the SDK event, a
|
|
525
|
+
* side script re-fires it via raw fbq/gtag to control timing); the starter
|
|
526
|
+
* templates' vendor adapters (`vendors`: GA4, Axon, Taboola, Triple Whale,
|
|
527
|
+
* TikTok, Northbeam, Snapchat, Pinterest, switched on by a campaigns.json
|
|
528
|
+
* key, riding the SDK's dl_* stream through the template forwarder); and
|
|
529
|
+
* out-of-band pixels a merchant loads some other way, typically through
|
|
530
|
+
* their own GTM container (`out_of_band_pixels`, e.g. Everflow), which
|
|
531
|
+
* never touch the dataLayer. So outbound pixel fires, not dataLayer
|
|
532
|
+
* events, are the QA source of truth.
|
|
528
533
|
* - A custom provider may carry an endpoint + transform (cookie injection).
|
|
529
534
|
* - Querystring params split into two classes: CONTENT (param.* → visibility
|
|
530
535
|
* via data-next-hide) and TRACKING (utm params, gclid, fbclid, subN, click-ids that
|
|
@@ -549,8 +554,33 @@ export interface AnalyticsProvider {
|
|
|
549
554
|
blockedEvents?: string[];
|
|
550
555
|
[key: string]: unknown;
|
|
551
556
|
}
|
|
552
|
-
/**
|
|
553
|
-
*
|
|
557
|
+
/**
|
|
558
|
+
* One starter-template vendor adapter, keyed in `analytics.vendors` by the
|
|
559
|
+
* vendor key (ga4 | axon | taboola | triplewhale | tiktok | northbeam | snap |
|
|
560
|
+
* pinterest; registry: analytics-vendors.ts). This is the shape the Map
|
|
561
|
+
* Builder emits; its spec compiler writes the matching flat keys into the
|
|
562
|
+
* campaign's `_data/campaigns.json` entry, and `spec derive` mirrors the id
|
|
563
|
+
* back from there.
|
|
564
|
+
*/
|
|
565
|
+
export interface AnalyticsVendor {
|
|
566
|
+
/** false turns the vendor off (no campaigns.json key is compiled). */
|
|
567
|
+
enabled?: boolean;
|
|
568
|
+
/** The vendor id: the value of the vendor's campaigns.json id key (`ga4_id`, `triplewhale_name`, …). */
|
|
569
|
+
id?: string;
|
|
570
|
+
/** Triple Whale only: `triplewhale_platform` (e.g. SHOPIFY). The template default, custom-msp, is omitted. */
|
|
571
|
+
platform?: string;
|
|
572
|
+
/** Turns on the vendor's identity / advanced-matching flag (raw email and phone; the `*_enabled` key). */
|
|
573
|
+
identityEnabled?: boolean;
|
|
574
|
+
/** dl_* events the adapter forwards (`<vendor>_allowed_events`); absent means all. */
|
|
575
|
+
allowedEvents?: string[];
|
|
576
|
+
/** dl_* events the adapter drops (`<vendor>_blocked_events`), e.g. purchases on a Shop Sync store. */
|
|
577
|
+
blockedEvents?: string[];
|
|
578
|
+
[key: string]: unknown;
|
|
579
|
+
}
|
|
580
|
+
/** A pixel/tag fired OUTSIDE the SDK and the template adapters (via the
|
|
581
|
+
* merchant's GTM container or a raw snippet). QA must still expect it on a
|
|
582
|
+
* live run even though it never appears in the dataLayer. A vendor the starter
|
|
583
|
+
* templates ship an adapter for belongs in `vendors`, not here. */
|
|
554
584
|
export interface OutOfBandPixel {
|
|
555
585
|
vendor: string;
|
|
556
586
|
loaded_via?: 'gtm' | 'script' | (string & {});
|
|
@@ -595,9 +625,13 @@ export interface UtmTransfer {
|
|
|
595
625
|
excludedDomains?: string[];
|
|
596
626
|
}
|
|
597
627
|
export interface AnalyticsContract {
|
|
628
|
+
/** false turns the whole contract off, as mode "disabled" does. */
|
|
629
|
+
enabled?: boolean;
|
|
598
630
|
mode?: AnalyticsMode;
|
|
599
|
-
/**
|
|
631
|
+
/** SDK providers, keyed by provider kind: gtm | facebook | rudderstack | custom | … */
|
|
600
632
|
providers?: Record<string, AnalyticsProvider>;
|
|
633
|
+
/** Starter-template vendor adapters, keyed by vendor key (see AnalyticsVendor). */
|
|
634
|
+
vendors?: Record<string, AnalyticsVendor>;
|
|
601
635
|
out_of_band_pixels?: OutOfBandPixel[];
|
|
602
636
|
manual_events?: ManualEvent[];
|
|
603
637
|
utmTransfer?: UtmTransfer;
|
package/compatibility.json
CHANGED
|
@@ -24,42 +24,112 @@
|
|
|
24
24
|
"--brand--color--rating-star",
|
|
25
25
|
"--component--color--outline",
|
|
26
26
|
"--system-colors--success",
|
|
27
|
-
"--system-colors--destructive"
|
|
27
|
+
"--system-colors--destructive",
|
|
28
|
+
"--_text---font-family--heading",
|
|
29
|
+
"--_text---font-family--primary",
|
|
30
|
+
"--radius-size--buttons"
|
|
28
31
|
],
|
|
29
32
|
"source_mappings": {
|
|
30
|
-
"--brand-primary": [
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"--
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
"--
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
"--
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
"--
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
"--
|
|
33
|
+
"--brand-primary": [
|
|
34
|
+
"--brand--color--primary"
|
|
35
|
+
],
|
|
36
|
+
"--brand-accent": [
|
|
37
|
+
"--brand--color--accent"
|
|
38
|
+
],
|
|
39
|
+
"--brand-secondary": [
|
|
40
|
+
"--brand--color--secondary"
|
|
41
|
+
],
|
|
42
|
+
"--surface-bg": [
|
|
43
|
+
"--brand--color--background"
|
|
44
|
+
],
|
|
45
|
+
"--surface-card": [
|
|
46
|
+
"--brand--color--surface"
|
|
47
|
+
],
|
|
48
|
+
"--text-primary": [
|
|
49
|
+
"--brand--color--text-primary",
|
|
50
|
+
"--brand--color--foreground"
|
|
51
|
+
],
|
|
52
|
+
"--text-secondary": [
|
|
53
|
+
"--brand--color--text-secondary"
|
|
54
|
+
],
|
|
55
|
+
"--border-default": [
|
|
56
|
+
"--brand--color--border",
|
|
57
|
+
"--component--color--outline"
|
|
58
|
+
],
|
|
59
|
+
"--rating-star": [
|
|
60
|
+
"--brand--color--rating-star"
|
|
61
|
+
],
|
|
62
|
+
"--state-success": [
|
|
63
|
+
"--system-colors--success"
|
|
64
|
+
],
|
|
65
|
+
"--ui-success": [
|
|
66
|
+
"--system-colors--success"
|
|
67
|
+
],
|
|
68
|
+
"--state-error": [
|
|
69
|
+
"--system-colors--destructive"
|
|
70
|
+
],
|
|
71
|
+
"--ui-danger": [
|
|
72
|
+
"--system-colors--destructive"
|
|
73
|
+
],
|
|
74
|
+
"--brand-cta": [
|
|
75
|
+
"--brand--color--cta-primary"
|
|
76
|
+
],
|
|
77
|
+
"--cta-primary": [
|
|
78
|
+
"--brand--color--cta-primary"
|
|
79
|
+
],
|
|
80
|
+
"--button-primary-bg": [
|
|
81
|
+
"--brand--color--cta-primary"
|
|
82
|
+
]
|
|
46
83
|
},
|
|
47
84
|
"derived_mappings": {
|
|
48
85
|
"--brand-primary": {
|
|
49
|
-
"--brand--color--primary-dark": {
|
|
50
|
-
|
|
51
|
-
|
|
86
|
+
"--brand--color--primary-dark": {
|
|
87
|
+
"method": "mix-black",
|
|
88
|
+
"amount": 0.18
|
|
89
|
+
},
|
|
90
|
+
"--brand--color--primary-light": {
|
|
91
|
+
"method": "mix-white",
|
|
92
|
+
"amount": 0.2
|
|
93
|
+
},
|
|
94
|
+
"--brand--color--primary-lighter": {
|
|
95
|
+
"method": "mix-white",
|
|
96
|
+
"amount": 0.86
|
|
97
|
+
}
|
|
52
98
|
}
|
|
53
99
|
},
|
|
54
100
|
"foreground_derivations": {
|
|
55
101
|
"description": "Foreground/on-color tokens are derived from the luminance of the background they sit on, never copied blindly from a source --text-inverse token (which defaults to white and renders illegible on a light brand, e.g. white-on-yellow CTAs). Each foreground target picks the first paired background that was mapped and emits the readable choice from foreground_choices. next-core .button/.submit-button render their label with --brand--color--text-inverse, so text-inverse pairs with the CTA background first.",
|
|
56
|
-
"foreground_choices": {
|
|
102
|
+
"foreground_choices": {
|
|
103
|
+
"dark": "#0a0a0a",
|
|
104
|
+
"light": "#ffffff"
|
|
105
|
+
},
|
|
57
106
|
"min_contrast_ratio": 4.5,
|
|
58
107
|
"derivations": {
|
|
59
|
-
"--brand--color--cta-foreground": [
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
"--brand--color--
|
|
108
|
+
"--brand--color--cta-foreground": [
|
|
109
|
+
"--brand--color--cta-primary"
|
|
110
|
+
],
|
|
111
|
+
"--brand--color--text-inverse": [
|
|
112
|
+
"--brand--color--cta-primary",
|
|
113
|
+
"--brand--color--primary"
|
|
114
|
+
],
|
|
115
|
+
"--brand--color--primary-foreground": [
|
|
116
|
+
"--brand--color--primary"
|
|
117
|
+
],
|
|
118
|
+
"--brand--color--accent-foreground": [
|
|
119
|
+
"--brand--color--accent"
|
|
120
|
+
]
|
|
63
121
|
}
|
|
122
|
+
},
|
|
123
|
+
"typography": {
|
|
124
|
+
"description": "Typography targets. Font families are mapped only when the design source ships an @font-face for the family; the faces are written to brand-fonts.css beside brand-theme.css. next-core re-declares the font-family tokens on body inside its 991px, 767px and 479px media queries, so those tokens are emitted on `:root, body` to hold at every width.",
|
|
125
|
+
"targets": {
|
|
126
|
+
"heading_family": "--_text---font-family--heading",
|
|
127
|
+
"body_family": "--_text---font-family--primary",
|
|
128
|
+
"button_radius": "--radius-size--buttons"
|
|
129
|
+
},
|
|
130
|
+
"body_scoped_tokens": [
|
|
131
|
+
"--_text---font-family--heading",
|
|
132
|
+
"--_text---font-family--primary"
|
|
133
|
+
]
|
|
64
134
|
}
|
|
65
135
|
}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
"schema_version": "campaign-cart-sdk-support-policy/v0",
|
|
3
3
|
"provenance": {
|
|
4
4
|
"source": "NextCommerceCo/campaign-cart release tags",
|
|
5
|
-
"latest_known_release": "0.4.
|
|
6
|
-
"captured_at": "2026-10-
|
|
5
|
+
"latest_known_release": "0.4.43",
|
|
6
|
+
"captured_at": "2026-10-22"
|
|
7
7
|
},
|
|
8
8
|
"source": "contracts/campaign-cart-sdk-support-policy.v0.json",
|
|
9
9
|
"minimum_supported": "0.4.20",
|