@gradial/aci 0.1.20-preview.2 → 0.1.20
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 +48 -110
- package/bin/{aci → aci-darwin-arm64} +0 -0
- package/bin/aci.js +99 -6
- package/dist/assets/index.d.ts +3 -3
- package/dist/assets/index.js +3 -3
- package/dist/astro/index.d.ts +14 -3
- package/dist/astro/index.js +24 -5
- package/dist/content/assets.d.ts +17 -0
- package/dist/content/assets.js +65 -0
- package/dist/content/index.d.ts +2 -0
- package/dist/content/index.js +2 -0
- package/dist/content/provider.d.ts +19 -0
- package/dist/content/provider.js +7 -0
- package/dist/content/resolve-slots.d.ts +9 -0
- package/dist/content/resolve-slots.js +24 -0
- package/dist/content/types.d.ts +1 -1
- package/dist/define-component.d.ts +1 -2
- package/dist/define-component.js +73 -11
- package/dist/define-layout.d.ts +2 -0
- package/dist/define-layout.js +3 -0
- package/dist/dev/content-watch.d.ts +37 -0
- package/dist/dev/content-watch.js +154 -0
- package/dist/dev/index.d.ts +24 -43
- package/dist/dev/index.js +4 -169
- package/dist/index.d.ts +14 -5
- package/dist/index.js +8 -8
- package/dist/next/asset-route.d.ts +2 -0
- package/dist/next/asset-route.js +12 -4
- package/dist/next/config.d.ts +2 -2
- package/dist/next/config.js +6 -6
- package/dist/next/content-watch.js +6 -1
- package/dist/next/index.d.ts +2 -2
- package/dist/next/index.js +2 -2
- package/dist/next/middleware.d.ts +7 -3
- package/dist/next/middleware.js +12 -7
- package/dist/next/page.d.ts +16 -15
- package/dist/next/page.js +30 -10
- package/dist/next/render.d.ts +5 -0
- package/dist/next/render.js +17 -0
- package/dist/next/root-layout.d.ts +4 -0
- package/dist/next/root-layout.js +5 -0
- package/dist/next/server.d.ts +14 -13
- package/dist/next/server.js +13 -3
- package/dist/providers/file.d.ts +2 -0
- package/dist/providers/file.js +61 -1
- package/dist/providers/s3.d.ts +1 -0
- package/dist/providers/s3.js +14 -1
- package/dist/react/Media.d.ts +24 -0
- package/dist/react/Media.js +30 -0
- package/dist/react/Picture.d.ts +12 -0
- package/dist/react/Picture.js +11 -0
- package/dist/react/VideoPlayer.d.ts +13 -0
- package/dist/react/{GradialVideoPlayer.js → VideoPlayer.js} +6 -5
- package/dist/react/index.d.ts +333 -3
- package/dist/react/index.js +89 -3
- package/dist/registry.d.ts +15 -0
- package/dist/registry.js +10 -0
- package/dist/testing/index.d.ts +3 -0
- package/dist/testing/index.js +15 -2
- package/dist/types/block-ref.d.ts +26 -0
- package/dist/types/block-ref.js +28 -0
- package/dist/types/component.d.ts +36 -41
- package/dist/types/config.d.ts +1 -2
- package/dist/types/image.d.ts +33 -20
- package/dist/types/image.js +42 -50
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.js +1 -0
- package/dist/types/link.d.ts +38 -0
- package/dist/types/link.js +58 -0
- package/dist/types/media.d.ts +16 -35
- package/dist/types/media.js +15 -84
- package/dist/types/page.d.ts +1 -2
- package/dist/types/render-mode.d.ts +0 -1
- package/dist/types/renderer.d.ts +1 -1
- package/dist/types/rich-text.d.ts +40 -0
- package/dist/types/rich-text.js +39 -0
- package/dist/types/video.d.ts +7 -13
- package/dist/types/video.js +3 -3
- package/package.json +32 -74
- package/src/cli/compile-registry.mjs +236 -59
- package/src/cli/validate-content.mjs +38 -75
- package/src/types/image.ts +79 -60
- package/templates/astro/template/.aci.yaml +27 -0
- package/templates/astro/template/.storybook/main.ts +79 -0
- package/templates/astro/template/.storybook/manager.ts +6 -0
- package/templates/astro/template/.storybook/preview.ts +33 -0
- package/templates/astro/template/astro.config.mjs +37 -0
- package/templates/astro/template/package.json.tmpl +41 -0
- package/templates/astro/template/src/cms/contracts/layouts/index.ts +18 -0
- package/templates/astro/template/src/cms/registry.ts +28 -0
- package/templates/astro/template/src/components/chrome/Footer.astro +107 -0
- package/templates/astro/template/src/components/chrome/Header.astro +94 -0
- package/templates/astro/template/src/components/elements/AtomicBlock.astro +15 -0
- package/templates/astro/template/src/components/elements/AtomicBlocks.astro +16 -0
- package/templates/astro/template/src/components/elements/Button.astro +51 -0
- package/templates/astro/template/src/components/elements/ButtonBlock.astro +25 -0
- package/templates/astro/template/src/components/elements/Container.astro +11 -0
- package/templates/astro/template/src/components/elements/Icon.astro +31 -0
- package/templates/astro/template/src/components/elements/Logo.astro +29 -0
- package/templates/astro/template/src/components/elements/RemoteImage.astro +41 -0
- package/templates/astro/template/src/components/sections/ContainerSection.astro +32 -0
- package/templates/astro/template/src/components/sections/FeatureCard.astro +23 -0
- package/templates/astro/template/src/components/sections/FeatureGrid.astro +35 -0
- package/templates/astro/template/src/components/sections/HomeHero.astro +51 -0
- package/templates/astro/template/src/components/sections/StatsBar.astro +33 -0
- package/templates/astro/template/src/design-system/styles.css +399 -0
- package/templates/astro/template/src/design-system/tokens/colors.css +60 -0
- package/templates/astro/template/src/design-system/tokens/components.css +69 -0
- package/templates/astro/template/src/design-system/tokens/index.css +6 -0
- package/templates/astro/template/src/design-system/tokens/radii.css +5 -0
- package/templates/astro/template/src/design-system/tokens/shadows.css +5 -0
- package/templates/astro/template/src/design-system/tokens/spacing.css +13 -0
- package/templates/astro/template/src/design-system/tokens/typography.css +24 -0
- package/templates/astro/template/src/env.d.ts +1 -0
- package/templates/astro/template/src/fixtures/atomicBlocks.ts +33 -0
- package/templates/astro/template/src/fixtures/composition.ts +31 -0
- package/templates/astro/template/src/fixtures/index.ts +17 -0
- package/templates/astro/template/src/fixtures/sections.ts +39 -0
- package/templates/astro/template/src/layouts/SiteLayout.astro +30 -0
- package/templates/astro/template/src/pages/[...slug].astro +61 -0
- package/templates/astro/template/src/render/RenderPage.astro +66 -0
- package/templates/astro/template/src/stories/CompositionStoryFrame.astro +15 -0
- package/templates/astro/template/src/stories/HomeHero.stories.ts +24 -0
- package/templates/astro/template/src/stories/SectionStoryFrame.astro +16 -0
- package/templates/astro/template/src/stories/StoryDocFrame.astro +31 -0
- package/templates/astro/template/tsconfig.json +11 -0
- package/templates/common/.agents/AGENTS.md +37 -0
- package/templates/common/.agents/skills/aci/SKILL.md +162 -0
- package/templates/common/.agents/skills/authoring/SKILL.md +590 -0
- package/templates/common/.agents/skills/authoring/references/block-registry.md +151 -0
- package/templates/common/.agents/skills/authoring/references/contracts.md +153 -0
- package/templates/common/.agents/skills/authoring/references/design-system.md +171 -0
- package/templates/common/.agents/skills/authoring/references/image-assets.md +73 -0
- package/templates/common/.agents/skills/authoring/references/repo-structure.md +157 -0
- package/templates/common/.agents/skills/migration/SKILL.md +160 -0
- package/templates/common/.agents/skills/migration/references/analyzing-source.md +215 -0
- package/templates/common/.agents/skills/migration/references/component-migration.md +200 -0
- package/templates/common/.agents/skills/migration/references/selector-map.md +31 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/7f/bf/7fbfc7fe230ff12688c496f660119e41d9725c4504d82e310c15665c73c09292 +0 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/a0/f5/a0f506689de9b15a7055f70103a3f02cd3ba105771ae2de6754df2ede1210d3a +0 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/dd/b7/ddb7e9642be08317bcd4b2bd26b58ba8d0d34dd7239e03e684a4f3634fa3845b +0 -0
- package/templates/common/.content/.gradial-dam/blobs/sha256/fb/32/fb3260e8286ea8231ea1c77b9c0be92d6edd9026565731eb14cfdcfd6b1b75b3 +0 -0
- package/templates/common/.content/config/site.json +192 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/asset.json +9 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/editorial.json +14 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/governance.json +23 -0
- package/templates/common/.content/dam/folders/seed/ast_site_about_hero/versions/v0001.json +37 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/asset.json +9 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/editorial.json +14 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/governance.json +23 -0
- package/templates/common/.content/dam/folders/seed/ast_site_home_hero/versions/v0001.json +37 -0
- package/templates/common/.content/fragments/navbar/_index.json +25 -0
- package/templates/common/.content/fragments/site-footer/_index.json +62 -0
- package/templates/common/.content/pages/about/_index.json +51 -0
- package/templates/common/.content/pages/home/_index.json +112 -0
- package/templates/common/.content/schemas/site.schema.json +123 -0
- package/templates/common/README.md.tmpl +45 -0
- package/templates/common/contracts/components/button.contract.ts +19 -0
- package/templates/common/contracts/components/container.contract.ts +19 -0
- package/templates/common/contracts/components/featureCard.contract.ts +15 -0
- package/templates/common/contracts/components/featureGrid.contract.ts +16 -0
- package/templates/common/contracts/components/homeHero.contract.ts +36 -0
- package/templates/common/contracts/components/index.ts +21 -0
- package/templates/common/contracts/components/siteFooter.contract.ts +45 -0
- package/templates/common/contracts/components/siteNavigation.contract.ts +30 -0
- package/templates/common/contracts/components/statsBar.contract.ts +19 -0
- package/templates/common/design-system/styles.css +346 -0
- package/templates/common/design-system/tokens/colors.css +110 -0
- package/templates/common/design-system/tokens/components.css +86 -0
- package/templates/common/design-system/tokens/index.css +6 -0
- package/templates/common/design-system/tokens/radii.css +5 -0
- package/templates/common/design-system/tokens/shadows.css +9 -0
- package/templates/common/design-system/tokens/spacing.css +26 -0
- package/templates/common/design-system/tokens/typography.css +32 -0
- package/templates/common/eslint-rules/no-raw-tailwind-values.js +127 -0
- package/templates/common/public/assets/Dwire-model.png +0 -0
- package/templates/common/public/assets/bare-metal-logo.png +0 -0
- package/templates/common/public/assets/meridian-logo.svg +8 -0
- package/templates/common/public/assets/seattle.avif +0 -0
- package/templates/nextjs/template/.aci.yaml +25 -0
- package/templates/nextjs/template/.storybook/main.ts +13 -0
- package/templates/nextjs/template/.storybook/preview.ts +34 -0
- package/templates/nextjs/template/eslint.config.mjs +36 -0
- package/templates/nextjs/template/next-env.d.ts +6 -0
- package/templates/nextjs/template/next.config.ts +8 -0
- package/templates/nextjs/template/package.json.tmpl +46 -0
- package/templates/nextjs/template/postcss.config.mjs +7 -0
- package/templates/nextjs/template/src/app/[[...slug]]/page.tsx +8 -0
- package/templates/nextjs/template/src/app/gradial/assets/[releaseId]/[...path]/route.ts +31 -0
- package/templates/nextjs/template/src/app/layout.tsx +29 -0
- package/templates/nextjs/template/src/cms/contracts/components/button.contract.ts +19 -0
- package/templates/nextjs/template/src/cms/contracts/components/container.contract.ts +20 -0
- package/templates/nextjs/template/src/cms/contracts/components/homeHero.contract.ts +36 -0
- package/templates/nextjs/template/src/cms/contracts/components/index.ts +15 -0
- package/templates/nextjs/template/src/cms/contracts/components/siteFooter.contract.ts +45 -0
- package/templates/nextjs/template/src/cms/contracts/components/siteNavigation.contract.ts +30 -0
- package/templates/nextjs/template/src/cms/contracts/layouts/index.ts +16 -0
- package/templates/nextjs/template/src/cms/registry.ts +28 -0
- package/templates/nextjs/template/src/components/chrome/Footer.tsx +86 -0
- package/templates/nextjs/template/src/components/chrome/Header.tsx +74 -0
- package/templates/nextjs/template/src/components/elements/AtomicBlock.tsx +13 -0
- package/templates/nextjs/template/src/components/elements/Button.tsx +40 -0
- package/templates/nextjs/template/src/components/elements/ButtonBlock.tsx +18 -0
- package/templates/nextjs/template/src/components/elements/Container.tsx +14 -0
- package/templates/nextjs/template/src/components/elements/Icon.tsx +29 -0
- package/templates/nextjs/template/src/components/elements/Logo.tsx +38 -0
- package/templates/nextjs/template/src/components/sections/ContainerSection.tsx +28 -0
- package/templates/nextjs/template/src/components/sections/FeatureCard.tsx +25 -0
- package/templates/nextjs/template/src/components/sections/FeatureGrid.tsx +36 -0
- package/templates/nextjs/template/src/components/sections/HomeHero.tsx +62 -0
- package/templates/nextjs/template/src/components/sections/StatsBar.tsx +30 -0
- package/templates/nextjs/template/src/middleware.ts +4 -0
- package/templates/nextjs/template/src/stories/Button.stories.tsx +38 -0
- package/templates/nextjs/template/src/stories/Header.stories.tsx +30 -0
- package/templates/nextjs/template/src/stories/HomeHero.stories.tsx +33 -0
- package/templates/nextjs/template/tsconfig.json +23 -0
- package/templates/nextjs/template/vercel.json +6 -0
- package/dist/content/cache.test.d.ts +0 -1
- package/dist/content/cache.test.js +0 -86
- package/dist/content/contract.d.ts +0 -83
- package/dist/content/contract.js +0 -104
- package/dist/content/tailwind-validator.d.ts +0 -6
- package/dist/content/tailwind-validator.js +0 -31
- package/dist/content/validation.d.ts +0 -108
- package/dist/content/validation.js +0 -184
- package/dist/next/preview-banner.d.ts +0 -4
- package/dist/next/preview-banner.js +0 -51
- package/dist/next/preview.d.ts +0 -7
- package/dist/next/preview.js +0 -37
- package/dist/react/GradialMedia.d.ts +0 -24
- package/dist/react/GradialMedia.js +0 -31
- package/dist/react/GradialPicture.d.ts +0 -14
- package/dist/react/GradialPicture.js +0 -30
- package/dist/react/GradialVideoPlayer.d.ts +0 -13
- package/dist/sveltekit/index.d.ts +0 -23
- package/dist/sveltekit/index.js +0 -62
- package/dist/sveltekit/preview.d.ts +0 -5
- package/dist/sveltekit/preview.js +0 -33
- package/src/cli/verify-renderer.mjs +0 -73
- package/src/types/component.ts +0 -59
- package/src/types/config.ts +0 -38
- package/src/types/data.ts +0 -47
- package/src/types/index.ts +0 -10
- package/src/types/layout.ts +0 -29
- package/src/types/media.ts +0 -125
- package/src/types/page.ts +0 -48
- package/src/types/render-mode.ts +0 -18
- package/src/types/renderer.ts +0 -83
- package/src/types/video.ts +0 -66
package/README.md
CHANGED
|
@@ -1,149 +1,87 @@
|
|
|
1
1
|
# Agentic Content Infrastructure SDK
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
`@gradial/aci` `0.1.20` is a pre-1.0 public-surface reset for the ACI
|
|
4
|
+
client SDK. Breaking changes from the old `0.1.x` accidental surface are
|
|
5
|
+
intentional: the root import is framework-neutral, framework runtime behavior is
|
|
6
|
+
behind explicit subpaths, and the first required customer path is React/Next.
|
|
7
7
|
|
|
8
|
-
##
|
|
9
|
-
|
|
10
|
-
The fastest way to create a new ACI site is via the scaffolding script:
|
|
8
|
+
## Install
|
|
11
9
|
|
|
12
10
|
```bash
|
|
13
|
-
|
|
14
|
-
cd my-site
|
|
15
|
-
npm run dev
|
|
11
|
+
npm install @gradial/aci@0.1.20 zod@^4
|
|
16
12
|
```
|
|
17
13
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
Generated starters include:
|
|
21
|
-
- `.aci/docs/` — Understanding ACI, running, and testing guides
|
|
22
|
-
- `.aci/guides/` — Component development, design system, content authoring
|
|
23
|
-
- `.aci/migration/` — Migrating existing sites to ACI
|
|
24
|
-
- Design system tokens, ESLint rules, and demo content
|
|
25
|
-
|
|
26
|
-
See the [templates directory](templates/) for the canonical starter source.
|
|
27
|
-
|
|
28
|
-
## Installation
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
npm install @gradial/aci zod@^4
|
|
32
|
-
npm install -D typescript tsx
|
|
33
|
-
```
|
|
14
|
+
## Root Import
|
|
34
15
|
|
|
35
|
-
|
|
16
|
+
The root import is for framework-neutral contracts and value types only:
|
|
36
17
|
|
|
37
18
|
```ts
|
|
38
|
-
import {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
19
|
+
import {
|
|
20
|
+
ImageSchema,
|
|
21
|
+
HeadingSchema,
|
|
22
|
+
LinkSchema,
|
|
23
|
+
RichTextValueSchema,
|
|
24
|
+
defineComponentContract,
|
|
25
|
+
type Image,
|
|
26
|
+
type Heading,
|
|
27
|
+
type Link,
|
|
28
|
+
type RichTextValue,
|
|
29
|
+
} from '@gradial/aci';
|
|
43
30
|
```
|
|
44
31
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
`@gradial/aci/content/tailwind-validator`.
|
|
48
|
-
|
|
49
|
-
Framework helpers live under `@gradial/aci/astro`,
|
|
50
|
-
`@gradial/aci/next/server`, `@gradial/aci/next/middleware`,
|
|
51
|
-
`@gradial/aci/next/dev-refresh`, and `@gradial/aci/sveltekit`.
|
|
52
|
-
|
|
53
|
-
## Component Contracts vs Runtime Components
|
|
32
|
+
The root import does not load React, Next, Vite, Webpack, browser-only code, or
|
|
33
|
+
server providers.
|
|
54
34
|
|
|
55
|
-
|
|
56
|
-
The ACI compiler imports only contract files, so those files must not import
|
|
57
|
-
React, framework components, CSS, or browser-only code.
|
|
35
|
+
## React/Next
|
|
58
36
|
|
|
59
|
-
|
|
37
|
+
React renderers and bindings live under `@gradial/aci/react`:
|
|
60
38
|
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
src/cms/contracts/components/index.ts
|
|
64
|
-
src/cms/contracts/layouts/index.ts
|
|
65
|
-
src/components/Hero.tsx
|
|
66
|
-
src/cms/renderBlock.tsx
|
|
39
|
+
```tsx
|
|
40
|
+
import { Image, Link, Heading, RichText, bindReactComponent } from '@gradial/aci/react';
|
|
67
41
|
```
|
|
68
42
|
|
|
69
|
-
|
|
43
|
+
Next integration helpers live under explicit Next subpaths:
|
|
70
44
|
|
|
71
45
|
```ts
|
|
72
|
-
import {
|
|
73
|
-
import {
|
|
74
|
-
|
|
75
|
-
export const heroContract = defineComponentContract({
|
|
76
|
-
name: 'hero',
|
|
77
|
-
schema: z.object({
|
|
78
|
-
headline: z.string(),
|
|
79
|
-
image: GradialImageSchema,
|
|
80
|
-
}),
|
|
81
|
-
renderModes: { canStatic: true, canSSR: true, canClientIsland: false },
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
export type HeroProps = z.infer<typeof heroContract.schema>;
|
|
46
|
+
import { createPage, withAci } from '@gradial/aci/next';
|
|
47
|
+
import { createMiddleware } from '@gradial/aci/next/middleware';
|
|
48
|
+
import { DevRefresh } from '@gradial/aci/next/dev-refresh';
|
|
85
49
|
```
|
|
86
50
|
|
|
87
|
-
|
|
88
|
-
never import runtime components:
|
|
51
|
+
Astro public subpath is `@gradial/aci/astro`.
|
|
89
52
|
|
|
90
|
-
|
|
91
|
-
import type { HeroProps } from '../cms/contracts/components/hero.contract';
|
|
53
|
+
## Server-Side Content Providers
|
|
92
54
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
}
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Testing helpers live under `@gradial/aci/testing`:
|
|
55
|
+
File and S3 providers are public server-only APIs for custom server composition,
|
|
56
|
+
such as blogs, events, product detail pages, and route-specific loaders:
|
|
99
57
|
|
|
100
58
|
```ts
|
|
101
|
-
import {
|
|
102
|
-
|
|
103
|
-
const content = new FixtureContentProvider({
|
|
104
|
-
pages: {
|
|
105
|
-
'/': {
|
|
106
|
-
id: 'home',
|
|
107
|
-
$type: 'page',
|
|
108
|
-
status: 'published',
|
|
109
|
-
layout: 'marketing',
|
|
110
|
-
renderMode: 'static',
|
|
111
|
-
metadata: { title: 'Test Home' },
|
|
112
|
-
regions: { main: [] }
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
const input = await content.loadRenderInput('/');
|
|
59
|
+
import { FileContentProvider } from '@gradial/aci/providers/file';
|
|
60
|
+
import { S3ContentProvider } from '@gradial/aci/providers/s3';
|
|
118
61
|
```
|
|
119
62
|
|
|
120
|
-
|
|
121
|
-
|
|
63
|
+
These providers are not browser/client-side fetch APIs. Client-side fetch should
|
|
64
|
+
go through an app-owned HTTP endpoint backed server-side by a `ContentProvider`.
|
|
122
65
|
|
|
123
|
-
|
|
66
|
+
## Scaffold
|
|
67
|
+
|
|
68
|
+
The first RC scaffold path is Next:
|
|
124
69
|
|
|
125
70
|
```bash
|
|
126
|
-
|
|
71
|
+
npx @gradial/aci@0.1.20 init my-site --template next-starter
|
|
127
72
|
```
|
|
128
73
|
|
|
129
|
-
|
|
130
|
-
publishing.
|
|
74
|
+
List available templates:
|
|
131
75
|
|
|
132
|
-
|
|
76
|
+
```bash
|
|
77
|
+
npx @gradial/aci@0.1.20 init --list
|
|
78
|
+
```
|
|
133
79
|
|
|
134
|
-
|
|
135
|
-
package `files` mistakes where local source imports work from the repo but fail
|
|
136
|
-
after npm filters the packed files.
|
|
80
|
+
## Verify Locally
|
|
137
81
|
|
|
138
82
|
From `packages/sdk`:
|
|
139
83
|
|
|
140
84
|
```bash
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
tar -tzf "$tmpdir/$filename" | sort | rg '^(package/src/cli/|package/src/types/|package/dist/types/)'
|
|
144
|
-
echo "tarball=$tmpdir/$filename"
|
|
85
|
+
pnpm run build
|
|
86
|
+
pnpm run generate-starters
|
|
145
87
|
```
|
|
146
|
-
|
|
147
|
-
If a shipped source CLI imports another source file, make sure both paths appear
|
|
148
|
-
in the tarball. For example, `src/cli/compile-registry.mjs` imports
|
|
149
|
-
`src/types/image.ts`, so both files must be included by `package.json#files`.
|
|
Binary file
|
package/bin/aci.js
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { spawn } from 'node:child_process';
|
|
3
3
|
import { existsSync } from 'node:fs';
|
|
4
|
+
import { cp, mkdir, readdir, readFile, rename, stat, writeFile } from 'node:fs/promises';
|
|
4
5
|
import { createRequire } from 'node:module';
|
|
5
|
-
import { dirname, join, resolve } from 'node:path';
|
|
6
|
+
import { basename, dirname, join, relative, resolve } from 'node:path';
|
|
6
7
|
import { fileURLToPath } from 'node:url';
|
|
7
8
|
|
|
8
9
|
const require = createRequire(import.meta.url);
|
|
@@ -14,6 +15,7 @@ const platformPackages = {
|
|
|
14
15
|
'darwin-x64': '@gradial/aci-cli-darwin-x64',
|
|
15
16
|
'linux-arm64': '@gradial/aci-cli-linux-arm64',
|
|
16
17
|
'linux-x64': '@gradial/aci-cli-linux-x64',
|
|
18
|
+
'win32-arm64': '@gradial/aci-cli-win32-arm64',
|
|
17
19
|
'win32-x64': '@gradial/aci-cli-win32-x64',
|
|
18
20
|
};
|
|
19
21
|
|
|
@@ -21,7 +23,7 @@ const platformKey = `${process.platform}-${process.arch}`;
|
|
|
21
23
|
const packageName = platformPackages[platformKey];
|
|
22
24
|
|
|
23
25
|
if (!packageName) {
|
|
24
|
-
console.error(`Unsupported platform for aci: ${platformKey}`);
|
|
26
|
+
console.error(`Unsupported platform for gradial-aci: ${platformKey}`);
|
|
25
27
|
process.exit(1);
|
|
26
28
|
}
|
|
27
29
|
|
|
@@ -29,9 +31,17 @@ const binName = process.platform === 'win32' ? 'aci.exe' : 'aci';
|
|
|
29
31
|
const shimDir = dirname(fileURLToPath(import.meta.url));
|
|
30
32
|
const repoRoot = resolve(shimDir, '../../..');
|
|
31
33
|
|
|
34
|
+
if (argv[0] === 'init') {
|
|
35
|
+
await runInit(argv.slice(1));
|
|
36
|
+
process.exit(0);
|
|
37
|
+
}
|
|
38
|
+
|
|
32
39
|
function resolveBundledBinary() {
|
|
33
|
-
const binaryPath = join(shimDir,
|
|
34
|
-
|
|
40
|
+
const binaryPath = join(shimDir, `aci-${platformKey}${process.platform === 'win32' ? '.exe' : ''}`);
|
|
41
|
+
if (existsSync(binaryPath)) return binaryPath;
|
|
42
|
+
// Local development fallback for packages built before platform-suffixed bins.
|
|
43
|
+
const legacyPath = join(shimDir, binName);
|
|
44
|
+
return existsSync(legacyPath) ? legacyPath : null;
|
|
35
45
|
}
|
|
36
46
|
|
|
37
47
|
function resolvePackagedBinary() {
|
|
@@ -65,14 +75,24 @@ if (!binaryPath && !fallback) {
|
|
|
65
75
|
}
|
|
66
76
|
|
|
67
77
|
const child = binaryPath
|
|
68
|
-
? spawn(binaryPath, argv, {
|
|
78
|
+
? spawn(binaryPath, argv, {
|
|
79
|
+
env: {
|
|
80
|
+
...process.env,
|
|
81
|
+
ACI_PACKAGE_ROOT: resolve(shimDir, '..'),
|
|
82
|
+
},
|
|
83
|
+
stdio: 'inherit',
|
|
84
|
+
})
|
|
69
85
|
: spawn(fallback.command, fallback.args, {
|
|
70
86
|
cwd: fallback.cwd,
|
|
87
|
+
env: {
|
|
88
|
+
...process.env,
|
|
89
|
+
ACI_PACKAGE_ROOT: resolve(shimDir, '..'),
|
|
90
|
+
},
|
|
71
91
|
stdio: 'inherit',
|
|
72
92
|
});
|
|
73
93
|
|
|
74
94
|
child.on('error', (error) => {
|
|
75
|
-
console.error(`Failed to run aci: ${error.message}`);
|
|
95
|
+
console.error(`Failed to run gradial-aci: ${error.message}`);
|
|
76
96
|
process.exit(1);
|
|
77
97
|
});
|
|
78
98
|
|
|
@@ -155,3 +175,76 @@ function normalizePathArg(value) {
|
|
|
155
175
|
function isAbsolutePath(value) {
|
|
156
176
|
return value.startsWith('/') || /^[A-Za-z]:[\\/]/.test(value);
|
|
157
177
|
}
|
|
178
|
+
|
|
179
|
+
async function runInit(args) {
|
|
180
|
+
if (args.includes('--list')) {
|
|
181
|
+
console.log('next-starter');
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
const target = args.find((arg) => !arg.startsWith('-'));
|
|
186
|
+
const template = optionValue(args, '--template') || 'next-starter';
|
|
187
|
+
if (!target) {
|
|
188
|
+
throw new Error('usage: aci init <target> --template next-starter');
|
|
189
|
+
}
|
|
190
|
+
if (template !== 'next-starter') {
|
|
191
|
+
throw new Error(`unknown template "${template}". Available templates: next-starter`);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const targetDir = resolve(callerCwd, target);
|
|
195
|
+
await assertEmptyTarget(targetDir);
|
|
196
|
+
await mkdir(targetDir, { recursive: true });
|
|
197
|
+
|
|
198
|
+
const packageRoot = resolve(shimDir, '..');
|
|
199
|
+
await cp(join(packageRoot, 'templates', 'common'), targetDir, { recursive: true });
|
|
200
|
+
await cp(join(packageRoot, 'templates', 'nextjs', 'template'), targetDir, { recursive: true });
|
|
201
|
+
await renderTemplates(targetDir, {
|
|
202
|
+
siteName: basename(targetDir),
|
|
203
|
+
version: '0.1.0',
|
|
204
|
+
});
|
|
205
|
+
console.log(`Created ${relative(callerCwd, targetDir) || '.'} from next-starter`);
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function optionValue(args, name) {
|
|
209
|
+
for (let index = 0; index < args.length; index += 1) {
|
|
210
|
+
const arg = args[index];
|
|
211
|
+
if (arg === name) return args[index + 1] || '';
|
|
212
|
+
if (arg.startsWith(`${name}=`)) return arg.slice(name.length + 1);
|
|
213
|
+
}
|
|
214
|
+
return '';
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
async function assertEmptyTarget(targetDir) {
|
|
218
|
+
try {
|
|
219
|
+
const info = await stat(targetDir);
|
|
220
|
+
if (!info.isDirectory()) {
|
|
221
|
+
throw new Error(`target exists and is not a directory: ${targetDir}`);
|
|
222
|
+
}
|
|
223
|
+
const entries = await readdir(targetDir);
|
|
224
|
+
if (entries.length > 0) {
|
|
225
|
+
throw new Error(`target directory is not empty: ${targetDir}`);
|
|
226
|
+
}
|
|
227
|
+
} catch (error) {
|
|
228
|
+
if (error?.code === 'ENOENT') return;
|
|
229
|
+
throw error;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
async function renderTemplates(root, values) {
|
|
234
|
+
const entries = await readdir(root, { withFileTypes: true });
|
|
235
|
+
for (const entry of entries) {
|
|
236
|
+
const fullPath = join(root, entry.name);
|
|
237
|
+
if (entry.isDirectory()) {
|
|
238
|
+
await renderTemplates(fullPath, values);
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
if (!entry.name.endsWith('.tmpl')) {
|
|
242
|
+
continue;
|
|
243
|
+
}
|
|
244
|
+
const raw = await readFile(fullPath, 'utf-8');
|
|
245
|
+
const rendered = raw.replace(/\{\{\s*([A-Za-z0-9_]+)\s*\}\}/g, (_match, key) => values[key] ?? '');
|
|
246
|
+
const nextPath = fullPath.slice(0, -'.tmpl'.length);
|
|
247
|
+
await writeFile(fullPath, rendered);
|
|
248
|
+
await rename(fullPath, nextPath);
|
|
249
|
+
}
|
|
250
|
+
}
|
package/dist/assets/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { type
|
|
2
|
-
export { type
|
|
3
|
-
export { type
|
|
1
|
+
export { type Image, type ImageSource, type ImageAttrs, ImageSchema, imageAttrs, primaryImageSource, } from '../types/image.js';
|
|
2
|
+
export { type Video, type VideoSource, VideoSchema, VideoSourceSchema, } from '../types/video.js';
|
|
3
|
+
export { type Asset, AssetSchema, isImage, isVideo, isAsset, } from '../types/media.js';
|
package/dist/assets/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
1
|
+
export { ImageSchema, imageAttrs, primaryImageSource, } from '../types/image.js';
|
|
2
|
+
export { VideoSchema, VideoSourceSchema, } from '../types/video.js';
|
|
3
|
+
export { AssetSchema, isImage, isVideo, isAsset, } from '../types/media.js';
|
package/dist/astro/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { RenderInput } from '../content/types.js';
|
|
2
|
-
import { type
|
|
2
|
+
import { type ContentWatchOptions } from '../dev/content-watch.js';
|
|
3
|
+
import type { Registry, AnyComponent } from '../registry.js';
|
|
4
|
+
import type { BlockRef } from '../types/block-ref.js';
|
|
3
5
|
interface AstroConfigSetupParams {
|
|
4
6
|
injectScript(stage: 'head-inline' | 'page' | 'page-ssr', content: string): void;
|
|
5
7
|
updateConfig(config: {
|
|
@@ -33,9 +35,18 @@ export declare function getGradialStaticPaths(): Promise<Array<{
|
|
|
33
35
|
};
|
|
34
36
|
}>>;
|
|
35
37
|
export declare function getPageRuntimeRenderInput(request: Request): RenderInput | null;
|
|
38
|
+
export { createRegistry, registryLookup } from '../registry.js';
|
|
39
|
+
export type { Registry, RegistryEntry, AnyComponent } from '../registry.js';
|
|
40
|
+
export type { BlockRef } from '../types/block-ref.js';
|
|
41
|
+
export interface RenderableBlock {
|
|
42
|
+
Component: AnyComponent | undefined;
|
|
43
|
+
props: Record<string, unknown>;
|
|
44
|
+
}
|
|
45
|
+
export type RenderChildren = (blocks: readonly BlockRef[]) => RenderableBlock[];
|
|
46
|
+
export declare function createRenderChildren(registry: Registry): RenderChildren;
|
|
36
47
|
export { getPreviewMode, createPreviewBannerHTML, createPreviewCookies, type PreviewContext, type PreviewCookie, } from './preview.js';
|
|
37
|
-
export interface
|
|
48
|
+
export interface AstroOptions extends ContentWatchOptions {
|
|
38
49
|
/** Path to compiled content root. Defaults to ACI_CONTENT_ROOT env or '.aci/compiled' */
|
|
39
50
|
compiledRoot?: string;
|
|
40
51
|
}
|
|
41
|
-
export declare function
|
|
52
|
+
export declare function withAci(options?: AstroOptions): AstroIntegrationLike;
|
package/dist/astro/index.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import fs from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
3
|
import { getPendingRenderInputFromHeaders } from '../runtime/page.js';
|
|
4
|
-
import {
|
|
4
|
+
import { contentWatchPlugin, damAssetPlugin, devRefreshPort, } from '../dev/content-watch.js';
|
|
5
|
+
import { createDevRefreshBrowserScript } from '../dev/index.js';
|
|
5
6
|
// ---------------------------------------------------------------------------
|
|
6
7
|
// Static paths helper — for Astro SSG
|
|
7
8
|
// ---------------------------------------------------------------------------
|
|
@@ -32,23 +33,41 @@ export function getPageRuntimeRenderInput(request) {
|
|
|
32
33
|
return getPendingRenderInputFromHeaders(request.headers);
|
|
33
34
|
}
|
|
34
35
|
// ---------------------------------------------------------------------------
|
|
36
|
+
// Registry helpers
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
export { createRegistry, registryLookup } from '../registry.js';
|
|
39
|
+
export function createRenderChildren(registry) {
|
|
40
|
+
function renderChildren(blocks) {
|
|
41
|
+
return blocks.map((block) => {
|
|
42
|
+
const entry = registry.find((r) => r.id === block.component);
|
|
43
|
+
const hasBlockSlots = !!entry?.contract.blockSlots;
|
|
44
|
+
const props = { ...block.props };
|
|
45
|
+
if (hasBlockSlots) {
|
|
46
|
+
props.renderChildren = renderChildren;
|
|
47
|
+
}
|
|
48
|
+
return { Component: entry?.component, props };
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
return renderChildren;
|
|
52
|
+
}
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
35
54
|
// Preview support
|
|
36
55
|
// ---------------------------------------------------------------------------
|
|
37
56
|
export { getPreviewMode, createPreviewBannerHTML, createPreviewCookies, } from './preview.js';
|
|
38
|
-
export function
|
|
57
|
+
export function withAci(options = {}) {
|
|
39
58
|
return {
|
|
40
|
-
name: '
|
|
59
|
+
name: 'aci-astro',
|
|
41
60
|
hooks: {
|
|
42
61
|
'astro:config:setup'({ injectScript, updateConfig }) {
|
|
43
62
|
if (process.env.NODE_ENV === 'production') {
|
|
44
63
|
return;
|
|
45
64
|
}
|
|
46
65
|
if (devRefreshPort(options) > 0) {
|
|
47
|
-
injectScript('page',
|
|
66
|
+
injectScript('page', createDevRefreshBrowserScript(options));
|
|
48
67
|
}
|
|
49
68
|
updateConfig({
|
|
50
69
|
vite: {
|
|
51
|
-
plugins: [
|
|
70
|
+
plugins: [damAssetPlugin(options), contentWatchPlugin(options)],
|
|
52
71
|
},
|
|
53
72
|
});
|
|
54
73
|
},
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface ReleaseAssetConfig {
|
|
2
|
+
bucket?: string;
|
|
3
|
+
keyPrefix?: string;
|
|
4
|
+
region?: string;
|
|
5
|
+
accessKeyId?: string;
|
|
6
|
+
secretAccessKey?: string;
|
|
7
|
+
sessionToken?: string;
|
|
8
|
+
endpoint?: string;
|
|
9
|
+
}
|
|
10
|
+
export declare class ReleaseAssetNotFoundError extends Error {
|
|
11
|
+
constructor(releaseId: string, assetPath: string, cause?: unknown);
|
|
12
|
+
}
|
|
13
|
+
export declare function getReleaseAssetResponse(input: {
|
|
14
|
+
releaseId: string;
|
|
15
|
+
assetPath: string;
|
|
16
|
+
config?: ReleaseAssetConfig;
|
|
17
|
+
}): Promise<Response>;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { S3ContentProvider } from '../providers/s3.js';
|
|
2
|
+
export class ReleaseAssetNotFoundError extends Error {
|
|
3
|
+
constructor(releaseId, assetPath, cause) {
|
|
4
|
+
super(`ACI release asset not found: ${releaseId}/${assetPath}`);
|
|
5
|
+
this.name = 'ReleaseAssetNotFoundError';
|
|
6
|
+
this.cause = cause;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export async function getReleaseAssetResponse(input) {
|
|
10
|
+
const clean = cleanAssetPath(input.assetPath);
|
|
11
|
+
if (!input.releaseId || !clean) {
|
|
12
|
+
throw new ReleaseAssetNotFoundError(input.releaseId, input.assetPath);
|
|
13
|
+
}
|
|
14
|
+
const config = input.config ?? {};
|
|
15
|
+
const provider = new S3ContentProvider({
|
|
16
|
+
bucket: config.bucket,
|
|
17
|
+
keyPrefix: releaseKey(config, input.releaseId),
|
|
18
|
+
region: config.region,
|
|
19
|
+
accessKeyId: config.accessKeyId,
|
|
20
|
+
secretAccessKey: config.secretAccessKey,
|
|
21
|
+
sessionToken: config.sessionToken,
|
|
22
|
+
endpoint: config.endpoint,
|
|
23
|
+
});
|
|
24
|
+
const key = joinKey(provider.config.keyPrefix, 'assets', clean);
|
|
25
|
+
const res = await provider.fetchRaw(key);
|
|
26
|
+
if (!res.ok || !res.body) {
|
|
27
|
+
throw new ReleaseAssetNotFoundError(input.releaseId, clean, await safeResponseText(res));
|
|
28
|
+
}
|
|
29
|
+
const headers = new Headers();
|
|
30
|
+
copyHeader(res.headers, headers, 'content-type');
|
|
31
|
+
copyHeader(res.headers, headers, 'content-length');
|
|
32
|
+
copyHeader(res.headers, headers, 'etag');
|
|
33
|
+
copyHeader(res.headers, headers, 'last-modified');
|
|
34
|
+
headers.set('cache-control', 'public, max-age=31536000, immutable');
|
|
35
|
+
return new Response(res.body, { status: 200, headers });
|
|
36
|
+
}
|
|
37
|
+
function cleanAssetPath(value) {
|
|
38
|
+
const clean = value.replace(/^\/+|\/+$/g, '').replace(/\/+/g, '/');
|
|
39
|
+
if (!clean || clean.split('/').some((segment) => segment === '..' || segment === '.'))
|
|
40
|
+
return '';
|
|
41
|
+
return clean;
|
|
42
|
+
}
|
|
43
|
+
function copyHeader(from, to, name) {
|
|
44
|
+
const value = from.get(name);
|
|
45
|
+
if (value)
|
|
46
|
+
to.set(name, value);
|
|
47
|
+
}
|
|
48
|
+
async function safeResponseText(res) {
|
|
49
|
+
try {
|
|
50
|
+
return await res.text();
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
function releaseKey(config, releaseId) {
|
|
57
|
+
return joinKey(config.keyPrefix || process.env.ACI_S3_KEY_PREFIX || '', 'releases', releaseId);
|
|
58
|
+
}
|
|
59
|
+
function joinKey(...parts) {
|
|
60
|
+
return parts
|
|
61
|
+
.filter(Boolean)
|
|
62
|
+
.map((part) => part.replace(/^\/+|\/+$/g, ''))
|
|
63
|
+
.filter(Boolean)
|
|
64
|
+
.join('/');
|
|
65
|
+
}
|
package/dist/content/index.d.ts
CHANGED
package/dist/content/index.js
CHANGED
|
@@ -12,17 +12,33 @@ export interface FragmentEntry {
|
|
|
12
12
|
digest: string;
|
|
13
13
|
fragmentRefs?: string[];
|
|
14
14
|
}
|
|
15
|
+
export interface LayoutEntry {
|
|
16
|
+
name: string;
|
|
17
|
+
slots: LayoutSlot[];
|
|
18
|
+
defaults?: Record<string, FragmentRef[]>;
|
|
19
|
+
}
|
|
20
|
+
export interface LayoutSlot {
|
|
21
|
+
name: string;
|
|
22
|
+
required: boolean;
|
|
23
|
+
}
|
|
24
|
+
export interface FragmentRef {
|
|
25
|
+
kind: string;
|
|
26
|
+
fragmentId: string;
|
|
27
|
+
inline: boolean;
|
|
28
|
+
}
|
|
15
29
|
export interface CompiledManifest {
|
|
16
30
|
manifestVersion: string;
|
|
17
31
|
buildDigest: string;
|
|
18
32
|
siteConfigRef: string;
|
|
19
33
|
routes: Record<string, RouteEntry>;
|
|
20
34
|
fragments: Record<string, FragmentEntry>;
|
|
35
|
+
layouts?: Record<string, LayoutEntry>;
|
|
21
36
|
}
|
|
22
37
|
export interface ContentProvider {
|
|
23
38
|
getSiteConfig<T = unknown>(): Promise<T>;
|
|
24
39
|
getPage<T = unknown>(route: string): Promise<T>;
|
|
25
40
|
getFragment<T = unknown>(id: string): Promise<T>;
|
|
41
|
+
getLayout<T = unknown>(name: string): Promise<T>;
|
|
26
42
|
listRoutes(): Promise<RouteEntry[]>;
|
|
27
43
|
}
|
|
28
44
|
export declare class PageNotFoundError extends Error {
|
|
@@ -31,6 +47,9 @@ export declare class PageNotFoundError extends Error {
|
|
|
31
47
|
export declare class FragmentNotFoundError extends Error {
|
|
32
48
|
constructor(id: string, cause?: unknown);
|
|
33
49
|
}
|
|
50
|
+
export declare class LayoutNotFoundError extends Error {
|
|
51
|
+
constructor(name: string, cause?: unknown);
|
|
52
|
+
}
|
|
34
53
|
export interface RenderInputOptions {
|
|
35
54
|
domain?: string;
|
|
36
55
|
locale?: string;
|
package/dist/content/provider.js
CHANGED
|
@@ -16,6 +16,13 @@ export class FragmentNotFoundError extends Error {
|
|
|
16
16
|
this.cause = cause;
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
+
export class LayoutNotFoundError extends Error {
|
|
20
|
+
constructor(name, cause) {
|
|
21
|
+
super(`Layout not found: ${name}`);
|
|
22
|
+
this.name = 'LayoutNotFoundError';
|
|
23
|
+
this.cause = cause;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
19
26
|
import { getCachedSiteConfig } from './cache.js';
|
|
20
27
|
export async function loadRenderInput(provider, route = '/', options = {}) {
|
|
21
28
|
const normalized = normalizeRoute(route);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { LayoutEntry } from './provider.js';
|
|
2
|
+
import type { KernelPageBlock } from './types.js';
|
|
3
|
+
export interface FragmentData {
|
|
4
|
+
id: string;
|
|
5
|
+
component: string;
|
|
6
|
+
props?: Record<string, unknown>;
|
|
7
|
+
}
|
|
8
|
+
export type FragmentLoader = (id: string) => Promise<FragmentData>;
|
|
9
|
+
export declare function resolveSlots(layout: LayoutEntry, pageRegions: Record<string, KernelPageBlock[]>, getFragment: FragmentLoader): Promise<Record<string, KernelPageBlock[]>>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export async function resolveSlots(layout, pageRegions, getFragment) {
|
|
2
|
+
const resolved = {};
|
|
3
|
+
for (const slot of layout.slots) {
|
|
4
|
+
const pageBlocks = pageRegions[slot.name];
|
|
5
|
+
if (pageBlocks && pageBlocks.length > 0) {
|
|
6
|
+
resolved[slot.name] = pageBlocks;
|
|
7
|
+
continue;
|
|
8
|
+
}
|
|
9
|
+
const defaults = layout.defaults?.[slot.name];
|
|
10
|
+
if (defaults?.length) {
|
|
11
|
+
const blocks = [];
|
|
12
|
+
for (const ref of defaults) {
|
|
13
|
+
const fragment = await getFragment(ref.fragmentId);
|
|
14
|
+
blocks.push({
|
|
15
|
+
id: fragment.id,
|
|
16
|
+
component: fragment.component,
|
|
17
|
+
props: fragment.props || {},
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
resolved[slot.name] = blocks;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
return resolved;
|
|
24
|
+
}
|
package/dist/content/types.d.ts
CHANGED
|
@@ -55,7 +55,6 @@ export interface KernelPage {
|
|
|
55
55
|
$type: 'page';
|
|
56
56
|
status: string;
|
|
57
57
|
layout: string;
|
|
58
|
-
renderMode: string;
|
|
59
58
|
metadata: KernelPageSeo;
|
|
60
59
|
regions: Record<string, KernelPageBlock[]>;
|
|
61
60
|
}
|
|
@@ -93,6 +92,7 @@ export interface RenderInput<TPage extends KernelPage = KernelPage, TSiteConfig
|
|
|
93
92
|
siteConfig: TSiteConfig;
|
|
94
93
|
page: TPage | null;
|
|
95
94
|
fragments?: Record<string, unknown>;
|
|
95
|
+
layouts?: Record<string, unknown>;
|
|
96
96
|
}
|
|
97
97
|
export interface RenderOutput {
|
|
98
98
|
route: string;
|