@gradial/aci 0.1.52-rc.21 → 0.1.52-rc.24
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/README.md +79 -5
- package/dist/astro/index.js +4 -0
- package/dist/audience-data-models.d.ts +12 -0
- package/dist/audience-data-models.js +3 -0
- package/dist/cli/mintlify-render.d.mts +1 -0
- 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 +3 -0
- package/dist/collect/api.js +19 -0
- package/dist/collect/assignments.d.ts +7 -9
- package/dist/collect/assignments.js +23 -32
- package/dist/collect/batcher.d.ts +3 -2
- 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 +10 -4
- package/dist/collect/index.js +66 -19
- 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/provider.d.ts +8 -0
- package/dist/index.d.ts +1 -1
- package/dist/internal/domain/edge/identity.d.ts +5 -0
- package/dist/internal/domain/edge/identity.js +49 -13
- package/dist/internal/domain/edge/mimic_token.d.ts +1 -0
- package/dist/internal/domain/edge/mimic_token.js +74 -7
- package/dist/internal/domain/edge/personalization-core.d.ts +8 -33
- package/dist/internal/domain/edge/personalization-core.js +151 -195
- package/dist/internal/domain/edge/personalization_index.d.ts +17 -0
- package/dist/internal/domain/edge/personalization_index.js +56 -0
- package/dist/internal/domain/edge/record/codec.d.ts +1 -30
- package/dist/internal/domain/edge/record/codec.js +1 -156
- package/dist/internal/domain/edge/resolve.js +55 -38
- package/dist/internal/domain/edge/types.d.ts +41 -32
- package/dist/internal/domain/edge/variant_key.d.ts +3 -0
- package/dist/internal/domain/edge/variant_key.js +44 -0
- package/dist/internal/platform/collectionstore/errors.d.ts +13 -0
- package/dist/internal/platform/collectionstore/errors.js +28 -0
- package/dist/mintlify/blocks.d.ts +6 -0
- package/dist/mintlify/blocks.js +198 -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 +12 -0
- package/dist/mintlify/materialize.js +159 -0
- package/dist/mintlify/types.d.ts +69 -0
- package/dist/mintlify/types.js +1 -0
- package/dist/mintlify/validate.d.ts +7 -0
- package/dist/mintlify/validate.js +252 -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-seat.js +3 -0
- package/dist/next/index.d.ts +1 -0
- package/dist/next/index.js +3 -0
- package/dist/next/render.js +8 -1
- package/dist/react/VideoPlayer.d.ts +1 -1
- package/dist/react/index.d.ts +1 -1
- 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 +12 -8
- package/dist/testing/conformance/root-identity.d.ts +31 -0
- package/dist/testing/conformance/root-identity.js +380 -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 +2 -2
- package/dist/testing/index.js +2 -2
- package/dist/types/component.d.ts +9 -0
- package/package.json +11 -7
- package/src/cli/mintlify-render.mjs +9 -0
- package/src/types/component.ts +10 -0
- 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/package.json.tmpl +4 -4
- package/templates/common/.agents/skills/aci/SKILL.md +50 -0
- package/templates/common/.agents/skills/authoring/SKILL.md +4 -3
- package/templates/common/.agents/skills/authoring/references/block-registry.md +15 -0
- package/templates/common/.agents/skills/migration/references/selector-map.md +1 -1
- package/templates/common/.content/schemas/site.schema.json +11 -1
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_home_hero → 000000000000000000000000101}/asset.json +1 -1
- package/templates/common/starter-content/.content/dam/folders/seed/{ast_site_about_hero → 000000000000000000000000102}/asset.json +1 -1
- package/templates/common/starter-content/.content/pages/404/_index.json +1 -1
- package/templates/common/starter-content/.content/pages/{home/_index.json → _index.json} +2 -2
- package/templates/common/starter-content/.content/pages/about/_index.json +1 -1
- package/templates/common/starter-content/.content/pages/error/_index.json +1 -1
- package/templates/common/starter-content/.content/patterns/components/button.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/container.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/feature_card.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/feature_grid.json +2 -2
- package/templates/common/starter-content/.content/patterns/components/home_hero.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/patterns/layouts/default.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/astro/starter-content/src/render/RenderPage.astro +0 -67
- package/templates/common/starter-content/.content/patterns/components/personalization_choice.json +0 -42
- package/templates/nextjs/starter-content/src/components/elements/AtomicBlock.tsx +0 -13
- /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
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Container from '../elements/Container.astro';
|
|
3
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
3
4
|
import type { RenderChildren, RenderableBlock } from '@gradial/aci/astro';
|
|
4
5
|
|
|
5
|
-
interface Props {
|
|
6
|
+
interface Props extends RootIdentityProps {
|
|
6
7
|
theme?: 'auto' | 'light' | 'dark';
|
|
7
8
|
className?: string;
|
|
8
9
|
content?: any[];
|
|
9
10
|
renderChildren?: RenderChildren;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const { theme = 'auto', className = '', content, renderChildren } = Astro.props;
|
|
13
|
+
const { theme = 'auto', className = '', content, renderChildren, ...root } = Astro.props;
|
|
13
14
|
const children: RenderableBlock[] = content && renderChildren ? renderChildren(content) : [];
|
|
14
15
|
const buttonCount = content?.filter((b: any) => b.component === 'button').length ?? 0;
|
|
15
16
|
const layout = buttonCount === 1
|
|
@@ -17,7 +18,7 @@ const layout = buttonCount === 1
|
|
|
17
18
|
: 'flex-col items-center sm:flex-row sm:justify-center sm:gap-4';
|
|
18
19
|
---
|
|
19
20
|
|
|
20
|
-
<section class={`theme-${theme} relative overflow-hidden py-[var(--spacing-section-y)] ${className}`}>
|
|
21
|
+
<section {...root} class={`theme-${theme} relative overflow-hidden py-[var(--spacing-section-y)] ${className}`}>
|
|
21
22
|
{theme === 'dark' ? (
|
|
22
23
|
<div class="pointer-events-none absolute inset-0 bg-[image:var(--gradient-hero-base)] opacity-30"></div>
|
|
23
24
|
) : null}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Icon from '../elements/Icon.astro';
|
|
3
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
3
4
|
|
|
4
|
-
interface Props {
|
|
5
|
+
interface Props extends RootIdentityProps {
|
|
5
6
|
icon?: string;
|
|
6
7
|
title: string;
|
|
7
8
|
description?: string;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
const { icon = '', title = '', description = '' } = Astro.props;
|
|
11
|
+
const { icon = '', title = '', description = '', ...root } = Astro.props;
|
|
11
12
|
---
|
|
12
13
|
|
|
13
|
-
<div class="rounded-card border border-[var(--color-edge-space)] bg-[var(--color-space-surface)] p-[var(--spacing-card)] transition-all duration-[var(--transition-duration-fast)] hover:border-[var(--color-edge-space-strong)] hover:bg-[var(--color-space-raised)] hover:shadow-[var(--shadow-card-default)]">
|
|
14
|
+
<div {...root} class="rounded-card border border-[var(--color-edge-space)] bg-[var(--color-space-surface)] p-[var(--spacing-card)] transition-all duration-[var(--transition-duration-fast)] hover:border-[var(--color-edge-space-strong)] hover:bg-[var(--color-space-raised)] hover:shadow-[var(--shadow-card-default)]">
|
|
14
15
|
{icon ? (
|
|
15
16
|
<div class="mb-6 flex h-12 w-12 items-center justify-center rounded-button bg-[color-mix(in_srgb,var(--color-brand-blue)_12%,transparent)] text-[var(--color-brand-blue-light)]">
|
|
16
17
|
<Icon name={icon} className="h-6 w-6" />
|
|
@@ -1,21 +1,22 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Container from '../elements/Container.astro';
|
|
3
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
3
4
|
import type { RenderChildren, RenderableBlock } from '@gradial/aci/astro';
|
|
4
5
|
|
|
5
|
-
interface Props {
|
|
6
|
+
interface Props extends RootIdentityProps {
|
|
6
7
|
title?: string;
|
|
7
8
|
subtitle?: string;
|
|
8
9
|
features?: any[];
|
|
9
10
|
renderChildren?: RenderChildren;
|
|
10
11
|
}
|
|
11
12
|
|
|
12
|
-
const { title = '', subtitle = '', features, renderChildren } = Astro.props;
|
|
13
|
+
const { title = '', subtitle = '', features, renderChildren, ...root } = Astro.props;
|
|
13
14
|
const children: RenderableBlock[] = features && renderChildren ? renderChildren(features) : [];
|
|
14
15
|
const count = features?.length ?? 0;
|
|
15
16
|
const cols = count <= 2 ? 'sm:grid-cols-2' : 'sm:grid-cols-2 lg:grid-cols-3';
|
|
16
17
|
---
|
|
17
18
|
|
|
18
|
-
<section class="theme-dark py-[var(--spacing-section-y)] bg-[var(--color-space-deep)]">
|
|
19
|
+
<section {...root} class="theme-dark py-[var(--spacing-section-y)] bg-[var(--color-space-deep)]">
|
|
19
20
|
<Container>
|
|
20
21
|
<div class="mb-12 max-w-[var(--max-width-container-narrow)]">
|
|
21
22
|
{title ? (
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Button from '../elements/Button.astro';
|
|
3
3
|
import Container from '../elements/Container.astro';
|
|
4
|
-
import { imageAttrs, type Image } from '@gradial/aci';
|
|
4
|
+
import { imageAttrs, type Image, type RootIdentityProps } from '@gradial/aci';
|
|
5
5
|
|
|
6
|
-
interface Props {
|
|
6
|
+
interface Props extends RootIdentityProps {
|
|
7
7
|
eyebrow?: string;
|
|
8
8
|
headline: string;
|
|
9
9
|
description?: string;
|
|
@@ -18,7 +18,8 @@ const {
|
|
|
18
18
|
description = '',
|
|
19
19
|
ctaLabel,
|
|
20
20
|
ctaHref,
|
|
21
|
-
image
|
|
21
|
+
image,
|
|
22
|
+
...root
|
|
22
23
|
} = Astro.props;
|
|
23
24
|
|
|
24
25
|
const imgAttrs = image ? imageAttrs(image, {
|
|
@@ -29,6 +30,7 @@ const imgAttrs = image ? imageAttrs(image, {
|
|
|
29
30
|
---
|
|
30
31
|
|
|
31
32
|
<section
|
|
33
|
+
{...root}
|
|
32
34
|
class="theme-dark relative min-h-[var(--height-hero-min)] overflow-hidden bg-black text-fg"
|
|
33
35
|
aria-label={image?.alt || headline}
|
|
34
36
|
>
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
---
|
|
2
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
2
3
|
import type { ContentProps } from '../../cms/contracts/components/personalizationChoice.contract';
|
|
3
4
|
|
|
4
|
-
type Props = ContentProps;
|
|
5
|
+
type Props = ContentProps & RootIdentityProps;
|
|
5
6
|
|
|
6
|
-
const { title, description, redLabel, blueLabel, refreshLabel } = Astro.props;
|
|
7
|
+
const { title, description, redLabel, blueLabel, refreshLabel, ...root } = Astro.props;
|
|
7
8
|
---
|
|
8
9
|
|
|
9
|
-
<section class="border-y border-[var(--color-border)] bg-[var(--color-surface)] py-[var(--spacing-section-y)]">
|
|
10
|
+
<section {...root} class="border-y border-[var(--color-border)] bg-[var(--color-surface)] py-[var(--spacing-section-y)]">
|
|
10
11
|
<div class="mx-auto max-w-[var(--layout-content-max)] px-[var(--layout-gutter)] text-center">
|
|
11
12
|
<h2 class="text-[length:var(--text-h2)] font-[var(--font-weight-semibold)] text-[var(--color-fg)]">{title}</h2>
|
|
12
13
|
{description ? <p class="mx-auto mt-3 max-w-2xl text-[var(--color-fg-muted)]">{description}</p> : null}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import Container from '../elements/Container.astro';
|
|
3
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
3
4
|
|
|
4
5
|
interface Stat {
|
|
5
6
|
label: string;
|
|
@@ -7,14 +8,14 @@ interface Stat {
|
|
|
7
8
|
suffix?: string;
|
|
8
9
|
}
|
|
9
10
|
|
|
10
|
-
interface Props {
|
|
11
|
+
interface Props extends RootIdentityProps {
|
|
11
12
|
stats?: Stat[];
|
|
12
13
|
}
|
|
13
14
|
|
|
14
|
-
const { stats = [] } = Astro.props;
|
|
15
|
+
const { stats = [], ...root } = Astro.props;
|
|
15
16
|
---
|
|
16
17
|
|
|
17
|
-
<section class="theme-dark border-y border-[var(--color-edge-space)] bg-[var(--color-space-surface)] py-[var(--spacing-section-y)]">
|
|
18
|
+
<section {...root} class="theme-dark border-y border-[var(--color-edge-space)] bg-[var(--color-space-surface)] py-[var(--spacing-section-y)]">
|
|
18
19
|
<Container>
|
|
19
20
|
<div class="grid gap-8 sm:grid-cols-2 lg:grid-cols-4">
|
|
20
21
|
{stats.map((stat) => (
|
|
@@ -25,7 +25,7 @@ export const sectionStoryFixtures: SectionStoryFixture[] = [
|
|
|
25
25
|
ctaHref: '/docs',
|
|
26
26
|
image: {
|
|
27
27
|
$type: 'gradial.image',
|
|
28
|
-
assetId: '
|
|
28
|
+
assetId: '3Ih26etWBTYfnAd0EjD0pP2h902',
|
|
29
29
|
versionId: 'v0001',
|
|
30
30
|
alt: 'Seattle skyline at dusk',
|
|
31
31
|
sources: [
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
import type { KernelPageBlock } from '@gradial/aci/content';
|
|
3
|
-
import
|
|
3
|
+
import { createRenderChildren } from '@gradial/aci/astro';
|
|
4
|
+
import { registry } from '../cms/registry';
|
|
4
5
|
|
|
5
6
|
interface Props {
|
|
6
7
|
block: KernelPageBlock;
|
|
@@ -8,8 +9,12 @@ interface Props {
|
|
|
8
9
|
}
|
|
9
10
|
|
|
10
11
|
const { block, direction = 'ltr' } = Astro.props;
|
|
12
|
+
// Stories render through the same seam as pages so the frame carries the
|
|
13
|
+
// block's root identity (sdk I-19, ADR 0051).
|
|
14
|
+
const [child] = createRenderChildren(registry)([block]);
|
|
15
|
+
const Comp = child.Component as any;
|
|
11
16
|
---
|
|
12
17
|
|
|
13
18
|
<div dir={direction}>
|
|
14
|
-
{
|
|
19
|
+
{Comp ? <Comp {...child.props} /> : null}
|
|
15
20
|
</div>
|
|
@@ -31,9 +31,9 @@
|
|
|
31
31
|
"tsx": "^4.20.0",
|
|
32
32
|
"typescript": "5.9.3",
|
|
33
33
|
"vite": "^7.2.7",
|
|
34
|
-
"storybook": "
|
|
35
|
-
"@storybook-astro/framework": "
|
|
36
|
-
"@storybook/addon-docs": "
|
|
37
|
-
"@storybook/builder-vite": "
|
|
34
|
+
"storybook": "10.5.10",
|
|
35
|
+
"@storybook-astro/framework": "1.11.0",
|
|
36
|
+
"@storybook/addon-docs": "10.5.10",
|
|
37
|
+
"@storybook/builder-vite": "10.5.10"
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -152,6 +152,56 @@ Optional (disabled by default):
|
|
|
152
152
|
|
|
153
153
|
## Troubleshooting
|
|
154
154
|
|
|
155
|
+
### Deploying a starter to a hosted Vercel tenant
|
|
156
|
+
|
|
157
|
+
Run the CLI from the starter repository root (where `.aci.yaml` lives), or
|
|
158
|
+
pass `--site-dir .` from that directory. Do not pass an absolute site path
|
|
159
|
+
from another working directory: older CLI versions can serialize it as a
|
|
160
|
+
`../../../tmp/...` source folder, which makes the server-side build fail with
|
|
161
|
+
a generic HTTP 500. The source ref must also be a pushed, cloneable branch;
|
|
162
|
+
`ref: HEAD` from a detached worktree is not cloneable by the build service.
|
|
163
|
+
|
|
164
|
+
The hosted publish sequence is:
|
|
165
|
+
|
|
166
|
+
1. `GRADIAL_CODE_SOURCE_TOKEN="$(gh auth token)" aci code-build --site-dir . --branch <test-branch> ...`
|
|
167
|
+
2. `aci branch land <test-branch>` to move the artifact link to `main`.
|
|
168
|
+
3. Promote `/config/site.json` and the content paths needed by the release.
|
|
169
|
+
4. Run `aci release publish --activate ...`.
|
|
170
|
+
|
|
171
|
+
Match the tenant rendering mode to the starter's actual route capability. A
|
|
172
|
+
Next starter with `dynamicParams = false` and no release-scoped runtime route
|
|
173
|
+
is an SSG starter and must use `rendering.mode = "ssg"`; `ssr` is only valid
|
|
174
|
+
when the frontend can resolve arbitrary host release routes at request time.
|
|
175
|
+
A mismatch can build successfully but then fail SSG rendering or return a
|
|
176
|
+
live Next 404 after the host rewrites a CMS page.
|
|
177
|
+
|
|
178
|
+
Injected platform functions must be dependency-closed inside their own
|
|
179
|
+
`.vercel/output/functions/<name>.func` mount. A prebuilt Vercel deploy does not
|
|
180
|
+
install a function-local `package.json` after upload. Native dependencies such
|
|
181
|
+
as `sharp` therefore belong to the host-function artifact, built for Vercel's
|
|
182
|
+
Linux/x64 runtime and injected beside the handler; never add them to the
|
|
183
|
+
starter's `package.json` merely to make a platform function resolve.
|
|
184
|
+
|
|
185
|
+
Publish validates `refs/heads/live`, not only `main`. If `main` deletes a
|
|
186
|
+
stale incompatible page or fragment that was previously promoted, promote
|
|
187
|
+
that same path from `main` with `aci promote --path ... --yes`; because the
|
|
188
|
+
source path is absent, the promote records a delete on `live`. This is the
|
|
189
|
+
API-safe way to remove old live content—direct writes to `live` are forbidden.
|
|
190
|
+
|
|
191
|
+
The same rule applies to breaking DAM identifier changes: every
|
|
192
|
+
`dam.assetRef` in `live` is resolved during publish, so one legacy identifier
|
|
193
|
+
blocks the release. Update the reference on a candidate branch through
|
|
194
|
+
`aci content push`, land it, and promote that exact content path before
|
|
195
|
+
publishing again. Do not weaken identifier validation or reactivate an old
|
|
196
|
+
release to bypass the content migration.
|
|
197
|
+
|
|
198
|
+
Legacy assets themselves are replaced through the product API, not rewritten
|
|
199
|
+
in storage: download or retain the needed source bytes, upload them again so
|
|
200
|
+
DAM creates fresh canonical IDs, approve them, replace every content reference,
|
|
201
|
+
then land, promote, and publish the affected paths. This is the supported
|
|
202
|
+
breaking cutover for pre-public tenants; there is no `ast_` alias or bulk
|
|
203
|
+
object-store migration path.
|
|
204
|
+
|
|
155
205
|
### "Unknown component" error during content compile
|
|
156
206
|
|
|
157
207
|
The content JSON references a `component` name that is not in the contract
|
|
@@ -78,12 +78,13 @@ Pages map to URL routes by their folder path under `/pages/`:
|
|
|
78
78
|
|
|
79
79
|
| Page Path | Route |
|
|
80
80
|
|-----------|-------|
|
|
81
|
-
| `/pages/
|
|
81
|
+
| `/pages/_index.json` | `/` |
|
|
82
82
|
| `/pages/about/_index.json` | `/about` |
|
|
83
83
|
| `/pages/products/_index.json` | `/products` |
|
|
84
84
|
| `/pages/products/shoes/_index.json` | `/products/shoes` |
|
|
85
85
|
|
|
86
|
-
The
|
|
86
|
+
The empty slug is the site root. Every named folder maps directly, including
|
|
87
|
+
`/pages/home/_index.json` at `/home`.
|
|
87
88
|
|
|
88
89
|
### Content Rules
|
|
89
90
|
|
|
@@ -486,7 +487,7 @@ framework.
|
|
|
486
487
|
#### 5. Add content
|
|
487
488
|
|
|
488
489
|
```json
|
|
489
|
-
// .content/pages/
|
|
490
|
+
// .content/pages/_index.json (inside regions.main)
|
|
490
491
|
{
|
|
491
492
|
"$type": "component",
|
|
492
493
|
"id": "features",
|
|
@@ -3,6 +3,21 @@
|
|
|
3
3
|
The component registry maps contract names to runtime components. It is built
|
|
4
4
|
using `createRegistry` from `@gradial/aci` with raw `[contract, component]` tuples.
|
|
5
5
|
|
|
6
|
+
Every registered component must extend `RootIdentityProps` (exported from
|
|
7
|
+
`@gradial/aci`) and spread the rest of its props onto its root element. The
|
|
8
|
+
renderer passes `data-aci-block` and `data-aci-component` to every block so
|
|
9
|
+
analytics can join events to content; a component that does not declare the
|
|
10
|
+
type fails `createRegistry` typecheck with
|
|
11
|
+
`<id>: props type must extend RootIdentityProps from @gradial/aci`, and one
|
|
12
|
+
that does not spread fails the `rootIdentity` conformance check under
|
|
13
|
+
`npm test`.
|
|
14
|
+
|
|
15
|
+
```tsx
|
|
16
|
+
export function StatsBar({ stats = [], ...root }: ContentProps & RootIdentityProps) {
|
|
17
|
+
return <section {...root} className="…">…</section>;
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
6
21
|
The tuple form provides **type-level validation** — the component must accept
|
|
7
22
|
at least the props derived from the contract's Zod schema. If you register a
|
|
8
23
|
component with the wrong prop type, TypeScript will fail at the call site.
|
|
@@ -13,7 +13,7 @@ Location: `artifacts/source-vs-target/selector-map.json`
|
|
|
13
13
|
"targetUrl": "http://localhost:3000/",
|
|
14
14
|
"breakpoints": [360, 768, 1024, 1280, 1400],
|
|
15
15
|
"entries": {
|
|
16
|
-
"content/pages/
|
|
16
|
+
"content/pages/_index.json blocks[\"home-hero\"]": {
|
|
17
17
|
"source": ".home-hero",
|
|
18
18
|
"target": ".home-hero",
|
|
19
19
|
"viewport": "both",
|
|
@@ -27,7 +27,17 @@
|
|
|
27
27
|
},
|
|
28
28
|
"overlayResolution": {
|
|
29
29
|
"type": "array",
|
|
30
|
-
"items": {
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"minLength": 1,
|
|
33
|
+
"pattern": "^[^;=/\u0009-\u000d\u0020\u0085\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]+$",
|
|
34
|
+
"not": {
|
|
35
|
+
"anyOf": [
|
|
36
|
+
{ "enum": [".", "..", "experiment", "experimentArm"] },
|
|
37
|
+
{ "pattern": "^experiment\\." }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
31
41
|
},
|
|
32
42
|
"brandHref": { "type": "string" },
|
|
33
43
|
"brandLogo": {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"status": "published",
|
|
5
5
|
"layout": "default",
|
|
6
6
|
"metadata": {
|
|
7
|
-
"title": "Meridian
|
|
7
|
+
"title": "Meridian — Global Satellite Internet",
|
|
8
8
|
"description": "Connect from anywhere on Earth. Low-latency satellite internet for homes, businesses, and beyond.",
|
|
9
9
|
"canonical": "https://www.meridian.local/"
|
|
10
10
|
},
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"ctaHref": "/plans/",
|
|
23
23
|
"image": {
|
|
24
24
|
"$type": "dam.assetRef",
|
|
25
|
-
"assetId": "
|
|
25
|
+
"assetId": "000000000000000000000000101",
|
|
26
26
|
"alt": "Light abstract hero background with satellite constellation"
|
|
27
27
|
}
|
|
28
28
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "button",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "container",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "feature_card",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "feature_grid",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "home_hero",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "site-footer",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "site-navigation",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "componentPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "stats_bar",
|
|
6
6
|
"schema": {
|
|
7
7
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$type": "layoutPattern",
|
|
3
|
-
"buildId": "
|
|
4
|
-
"codeDigest": "sha256:
|
|
3
|
+
"buildId": "codebuild_01a05a33-bcc6-76ac-95bf-0c35b4c55280",
|
|
4
|
+
"codeDigest": "sha256:a19097814cad924bba8b584241b77f19d40c1c70012603e0faf9710853438015",
|
|
5
5
|
"name": "default",
|
|
6
6
|
"slots": [
|
|
7
7
|
"header",
|
|
@@ -27,7 +27,17 @@
|
|
|
27
27
|
},
|
|
28
28
|
"overlayResolution": {
|
|
29
29
|
"type": "array",
|
|
30
|
-
"items": {
|
|
30
|
+
"items": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"minLength": 1,
|
|
33
|
+
"pattern": "^[^;=/\u0009-\u000d\u0020\u0085\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000]+$",
|
|
34
|
+
"not": {
|
|
35
|
+
"anyOf": [
|
|
36
|
+
{ "enum": [".", "..", "experiment", "experimentArm"] },
|
|
37
|
+
{ "pattern": "^experiment\\." }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
}
|
|
31
41
|
},
|
|
32
42
|
"brandHref": { "type": "string" },
|
|
33
43
|
"brandLogo": {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Container } from '@/components/elements/Container';
|
|
2
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
2
3
|
import { Logo } from '@/components/elements/Logo';
|
|
3
4
|
import type { FooterColumn, FooterGroup, FooterLink } from '@gradial/aci/content';
|
|
4
5
|
|
|
5
|
-
interface FooterProps {
|
|
6
|
+
interface FooterProps extends RootIdentityProps {
|
|
6
7
|
brandHref: string;
|
|
7
8
|
brandLabel: string;
|
|
8
9
|
brandLogo?: { src: string; alt?: string } | null;
|
|
@@ -17,9 +18,9 @@ function columnGroups(column: FooterColumn): FooterGroup[] {
|
|
|
17
18
|
return [{ id: column.id, title: column.title || '', links: column.links || [] }];
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
export function Footer({ brandHref, brandLabel, brandLogo = null, columns = [], social = [], legalLinks = [], copyright = '' }: FooterProps) {
|
|
21
|
+
export function Footer({ brandHref, brandLabel, brandLogo = null, columns = [], social = [], legalLinks = [], copyright = '', ...root }: FooterProps) {
|
|
21
22
|
return (
|
|
22
|
-
<footer className="bm-footer relative pt-[var(--spacing-footer-y)]" id="footer">
|
|
23
|
+
<footer {...root} className="bm-footer relative pt-[var(--spacing-footer-y)]" id="footer">
|
|
23
24
|
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-[var(--color-brand-500)] to-transparent opacity-50" />
|
|
24
25
|
<Container>
|
|
25
26
|
<div className="footer-main-grid grid grid-cols-1 gap-12 lg:grid-cols-2">
|
|
@@ -2,9 +2,10 @@ import { Button } from '@/components/elements/Button';
|
|
|
2
2
|
import { Container } from '@/components/elements/Container';
|
|
3
3
|
import { Icon } from '@/components/elements/Icon';
|
|
4
4
|
import { Logo } from '@/components/elements/Logo';
|
|
5
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
5
6
|
import type { NavItem, UtilityItem } from '@gradial/aci/content';
|
|
6
7
|
|
|
7
|
-
interface HeaderProps {
|
|
8
|
+
interface HeaderProps extends RootIdentityProps {
|
|
8
9
|
brandHref: string;
|
|
9
10
|
brandLabel: string;
|
|
10
11
|
brandLogo?: { src: string; alt?: string } | null;
|
|
@@ -12,9 +13,9 @@ interface HeaderProps {
|
|
|
12
13
|
utilities?: UtilityItem[];
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
export function Header({ brandHref, brandLabel, brandLogo = null, navigation = [], utilities = [] }: HeaderProps) {
|
|
16
|
+
export function Header({ brandHref, brandLabel, brandLogo = null, navigation = [], utilities = [], ...root }: HeaderProps) {
|
|
16
17
|
return (
|
|
17
|
-
<header className="bm-header fixed top-0 left-0 right-0 z-[var(--z-header)] border-b border-[var(--header-border)]">
|
|
18
|
+
<header {...root} className="bm-header fixed top-0 left-0 right-0 z-[var(--z-header)] border-b border-[var(--header-border)]">
|
|
18
19
|
<a href="#content-main" className="sr-only focus:not-sr-only focus:absolute focus:top-4 focus:left-4 focus:z-[var(--z-overlay)] focus:rounded-button focus:bg-[var(--color-space-900)] focus:px-4 focus:py-2 focus:text-[var(--color-white)]">
|
|
19
20
|
Skip to main content
|
|
20
21
|
</a>
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { ReactNode } from 'react';
|
|
1
|
+
import type { AnchorHTMLAttributes, ReactNode } from 'react';
|
|
2
2
|
import type { ButtonVariant } from '@gradial/aci/content';
|
|
3
3
|
|
|
4
4
|
type ButtonSize = 'default' | 'lg';
|
|
5
5
|
|
|
6
|
-
interface ButtonProps {
|
|
6
|
+
interface ButtonProps extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, 'href' | 'className' | 'target' | 'rel' | 'children'> {
|
|
7
7
|
href: string;
|
|
8
8
|
variant?: ButtonVariant;
|
|
9
9
|
size?: ButtonSize;
|
|
@@ -26,9 +26,10 @@ const sizeClasses: Record<ButtonSize, string> = {
|
|
|
26
26
|
lg: 'px-7 py-3.5 min-h-[3.5rem] text-[length:var(--text-size-body-large)]',
|
|
27
27
|
};
|
|
28
28
|
|
|
29
|
-
export function Button({ href, variant = 'primary', size = 'default', className = '', target, rel, children }: ButtonProps) {
|
|
29
|
+
export function Button({ href, variant = 'primary', size = 'default', className = '', target, rel, children, ...root }: ButtonProps) {
|
|
30
30
|
return (
|
|
31
31
|
<a
|
|
32
|
+
{...root}
|
|
32
33
|
className={`inline-flex items-center justify-center gap-2 rounded-button leading-button font-[var(--font-weight-semibold)] no-underline transition-all duration-[var(--transition-duration-fast)] ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}
|
|
33
34
|
href={href}
|
|
34
35
|
target={target}
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
import { Button } from '@/components/elements/Button';
|
|
2
2
|
import { Icon } from '@/components/elements/Icon';
|
|
3
|
+
import type { RootIdentityProps } from '@gradial/aci';
|
|
3
4
|
import type { ContentProps } from '@/cms/contracts/components/button.contract';
|
|
4
5
|
|
|
5
|
-
export type ButtonBlockProps = ContentProps;
|
|
6
|
+
export type ButtonBlockProps = ContentProps & RootIdentityProps;
|
|
6
7
|
|
|
7
|
-
export function ButtonBlock({ label = '', href = '#', variant = 'primary', newWindow = false, icon = '', iconPosition = 'before', className = '' }: ButtonBlockProps) {
|
|
8
|
+
export function ButtonBlock({ label = '', href = '#', variant = 'primary', newWindow = false, icon = '', iconPosition = 'before', className = '', ...root }: ButtonBlockProps) {
|
|
8
9
|
const target = newWindow ? '_blank' : undefined;
|
|
9
10
|
const rel = newWindow ? 'noreferrer' : undefined;
|
|
10
11
|
|
|
11
12
|
return (
|
|
12
|
-
<Button href={href} variant={variant} target={target} rel={rel} className={className}>
|
|
13
|
+
<Button href={href} variant={variant} target={target} rel={rel} className={className} {...root}>
|
|
13
14
|
{icon && iconPosition === 'before' ? <Icon name={icon} /> : null}
|
|
14
15
|
<span>{label}</span>
|
|
15
16
|
{icon && iconPosition === 'after' ? <Icon name={icon} /> : null}
|