@gradial/aci 0.1.20-preview.3 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +48 -108
- 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 +12 -3
- package/dist/astro/index.js +20 -5
- package/dist/content/assets.d.ts +17 -0
- package/dist/content/assets.js +65 -0
- package/dist/content/index.d.ts +1 -0
- package/dist/content/index.js +1 -0
- package/dist/define-component.d.ts +1 -2
- package/dist/define-component.js +73 -5
- 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 -6
- package/dist/index.js +8 -9
- package/dist/next/asset-route.js +2 -2
- package/dist/next/config.d.ts +2 -2
- package/dist/next/config.js +5 -5
- 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 +1 -0
- package/dist/next/middleware.js +49 -8
- package/dist/next/page.d.ts +1 -1
- package/dist/next/page.js +14 -12
- package/dist/next/render.d.ts +3 -3
- package/dist/next/render.js +11 -9
- package/dist/next/server.d.ts +12 -12
- package/dist/next/server.js +1 -1
- package/dist/preview/core.d.ts +5 -0
- package/dist/preview/core.js +1 -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 +2 -2
- package/dist/registry.js +3 -3
- package/dist/types/block-ref.d.ts +26 -0
- package/dist/types/block-ref.js +28 -0
- package/dist/types/component.d.ts +36 -32
- package/dist/types/config.d.ts +1 -1
- 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/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 +29 -76
- package/src/cli/compile-registry.mjs +120 -63
- package/src/cli/validate-content.mjs +38 -75
- package/src/types/block-ref.ts +74 -0
- package/src/types/image.ts +79 -60
- package/templates/astro/template/.aci.yaml +28 -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 +26 -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/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 -183
- 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 -25
- package/dist/sveltekit/index.js +0 -66
- package/dist/sveltekit/preview.d.ts +0 -5
- package/dist/sveltekit/preview.js +0 -33
- package/src/types/component.ts +0 -49
- package/src/types/config.ts +0 -37
- 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 -47
- package/src/types/render-mode.ts +0 -10
- package/src/types/renderer.ts +0 -83
- package/src/types/video.ts +0 -66
package/README.md
CHANGED
|
@@ -1,147 +1,87 @@
|
|
|
1
1
|
# Agentic Content Infrastructure SDK
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
`@gradial/aci` `0.1.21` 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
|
-
pnpm run dev
|
|
11
|
+
npm install @gradial/aci@0.1.21 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
|
-
pnpm add @gradial/aci zod@^4
|
|
32
|
-
pnpm add -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
|
-
});
|
|
82
|
-
|
|
83
|
-
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';
|
|
84
49
|
```
|
|
85
50
|
|
|
86
|
-
|
|
87
|
-
never import runtime components:
|
|
51
|
+
Astro public subpath is `@gradial/aci/astro`.
|
|
88
52
|
|
|
89
|
-
|
|
90
|
-
import type { HeroProps } from '../cms/contracts/components/hero.contract';
|
|
53
|
+
## Server-Side Content Providers
|
|
91
54
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
}
|
|
95
|
-
```
|
|
96
|
-
|
|
97
|
-
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:
|
|
98
57
|
|
|
99
58
|
```ts
|
|
100
|
-
import {
|
|
101
|
-
|
|
102
|
-
const content = new FixtureContentProvider({
|
|
103
|
-
pages: {
|
|
104
|
-
'/': {
|
|
105
|
-
id: 'home',
|
|
106
|
-
$type: 'page',
|
|
107
|
-
status: 'published',
|
|
108
|
-
layout: 'marketing',
|
|
109
|
-
metadata: { title: 'Test Home' },
|
|
110
|
-
regions: { main: [] }
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
const input = await content.loadRenderInput('/');
|
|
59
|
+
import { FileContentProvider } from '@gradial/aci/providers/file';
|
|
60
|
+
import { S3ContentProvider } from '@gradial/aci/providers/s3';
|
|
116
61
|
```
|
|
117
62
|
|
|
118
|
-
|
|
119
|
-
|
|
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`.
|
|
120
65
|
|
|
121
|
-
|
|
66
|
+
## Scaffold
|
|
67
|
+
|
|
68
|
+
The first RC scaffold path is Next:
|
|
122
69
|
|
|
123
70
|
```bash
|
|
124
|
-
|
|
71
|
+
npx @gradial/aci@0.1.21 init my-site --template next-starter
|
|
125
72
|
```
|
|
126
73
|
|
|
127
|
-
|
|
128
|
-
publishing.
|
|
74
|
+
List available templates:
|
|
129
75
|
|
|
130
|
-
|
|
76
|
+
```bash
|
|
77
|
+
npx @gradial/aci@0.1.21 init --list
|
|
78
|
+
```
|
|
131
79
|
|
|
132
|
-
|
|
133
|
-
package `files` mistakes where local source imports work from the repo but fail
|
|
134
|
-
after pnpm filters the packed files.
|
|
80
|
+
## Verify Locally
|
|
135
81
|
|
|
136
82
|
From `packages/sdk`:
|
|
137
83
|
|
|
138
84
|
```bash
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
tar -tzf "$tmpdir/$filename" | sort | rg '^(package/src/cli/|package/src/types/|package/dist/types/)'
|
|
142
|
-
echo "tarball=$tmpdir/$filename"
|
|
85
|
+
pnpm run build
|
|
86
|
+
pnpm run generate-starters
|
|
143
87
|
```
|
|
144
|
-
|
|
145
|
-
If a shipped source CLI imports another source file, make sure both paths appear
|
|
146
|
-
in the tarball. For example, `src/cli/compile-registry.mjs` imports
|
|
147
|
-
`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: {
|
|
@@ -35,9 +37,16 @@ export declare function getGradialStaticPaths(): Promise<Array<{
|
|
|
35
37
|
export declare function getPageRuntimeRenderInput(request: Request): RenderInput | null;
|
|
36
38
|
export { createRegistry, registryLookup } from '../registry.js';
|
|
37
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;
|
|
38
47
|
export { getPreviewMode, createPreviewBannerHTML, createPreviewCookies, type PreviewContext, type PreviewCookie, } from './preview.js';
|
|
39
|
-
export interface
|
|
48
|
+
export interface AstroOptions extends ContentWatchOptions {
|
|
40
49
|
/** Path to compiled content root. Defaults to ACI_CONTENT_ROOT env or '.aci/compiled' */
|
|
41
50
|
compiledRoot?: string;
|
|
42
51
|
}
|
|
43
|
-
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
|
// ---------------------------------------------------------------------------
|
|
@@ -35,24 +36,38 @@ export function getPageRuntimeRenderInput(request) {
|
|
|
35
36
|
// Registry helpers
|
|
36
37
|
// ---------------------------------------------------------------------------
|
|
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
|
+
}
|
|
38
53
|
// ---------------------------------------------------------------------------
|
|
39
54
|
// Preview support
|
|
40
55
|
// ---------------------------------------------------------------------------
|
|
41
56
|
export { getPreviewMode, createPreviewBannerHTML, createPreviewCookies, } from './preview.js';
|
|
42
|
-
export function
|
|
57
|
+
export function withAci(options = {}) {
|
|
43
58
|
return {
|
|
44
|
-
name: '
|
|
59
|
+
name: 'aci-astro',
|
|
45
60
|
hooks: {
|
|
46
61
|
'astro:config:setup'({ injectScript, updateConfig }) {
|
|
47
62
|
if (process.env.NODE_ENV === 'production') {
|
|
48
63
|
return;
|
|
49
64
|
}
|
|
50
65
|
if (devRefreshPort(options) > 0) {
|
|
51
|
-
injectScript('page',
|
|
66
|
+
injectScript('page', createDevRefreshBrowserScript(options));
|
|
52
67
|
}
|
|
53
68
|
updateConfig({
|
|
54
69
|
vite: {
|
|
55
|
-
plugins: [
|
|
70
|
+
plugins: [damAssetPlugin(options), contentWatchPlugin(options)],
|
|
56
71
|
},
|
|
57
72
|
});
|
|
58
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
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
import type { ComponentContract, ComponentDefinition } from './types/component.js';
|
|
2
|
-
export declare function
|
|
3
|
-
export declare const defineComponentContract: typeof defineComponent;
|
|
2
|
+
export declare function defineComponentContract<const TId extends string, TSchema = unknown>(definition: ComponentDefinition<TId, TSchema>): ComponentContract<TId, TSchema>;
|
package/dist/define-component.js
CHANGED
|
@@ -1,8 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
import { getBlockRefMeta } from './types/block-ref.js';
|
|
2
|
+
export function defineComponentContract(definition) {
|
|
2
3
|
return {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
id: definition.id,
|
|
5
|
+
...(definition.displayName ? { displayName: definition.displayName } : {}),
|
|
6
|
+
props: definition.props,
|
|
7
|
+
...scanBlockSlots(definition.props),
|
|
8
|
+
...(definition.imageSlots ? { imageSlots: definition.imageSlots } : {}),
|
|
9
|
+
validate: definition.validate ?? [],
|
|
6
10
|
};
|
|
7
11
|
}
|
|
8
|
-
|
|
12
|
+
function scanBlockSlots(schema) {
|
|
13
|
+
const slots = {};
|
|
14
|
+
const shape = getSchemaShape(schema);
|
|
15
|
+
if (!shape)
|
|
16
|
+
return {};
|
|
17
|
+
for (const [key, fieldSchema] of Object.entries(shape)) {
|
|
18
|
+
const unwrapped = unwrapOptional(fieldSchema);
|
|
19
|
+
const meta = getBlockRefMeta(unwrapped) ?? getBlockRefMeta(unwrapArray(unwrapped));
|
|
20
|
+
if (meta) {
|
|
21
|
+
slots[key] = meta;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return Object.keys(slots).length ? { blockSlots: slots } : {};
|
|
25
|
+
}
|
|
26
|
+
function unwrapOptional(schema) {
|
|
27
|
+
let current = schema;
|
|
28
|
+
const seen = new Set();
|
|
29
|
+
while (current && typeof current === 'object' && !seen.has(current)) {
|
|
30
|
+
seen.add(current);
|
|
31
|
+
const def = current._def;
|
|
32
|
+
if (!def || typeof def !== 'object')
|
|
33
|
+
break;
|
|
34
|
+
const type = def.type;
|
|
35
|
+
const typeName = def.typeName;
|
|
36
|
+
if (type === 'optional' || type === 'nullable' || type === 'default' ||
|
|
37
|
+
typeName === 'ZodOptional' || typeName === 'ZodNullable' || typeName === 'ZodDefault') {
|
|
38
|
+
const inner = def.innerType ?? def.schema;
|
|
39
|
+
if (inner) {
|
|
40
|
+
current = inner;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
break;
|
|
45
|
+
}
|
|
46
|
+
return current;
|
|
47
|
+
}
|
|
48
|
+
function getSchemaShape(schema) {
|
|
49
|
+
if (!schema || typeof schema !== 'object')
|
|
50
|
+
return null;
|
|
51
|
+
const def = schema._def;
|
|
52
|
+
if (!def || typeof def !== 'object')
|
|
53
|
+
return null;
|
|
54
|
+
const shape = def.shape;
|
|
55
|
+
if (typeof shape === 'function') {
|
|
56
|
+
return shape.call(def);
|
|
57
|
+
}
|
|
58
|
+
if (shape && typeof shape === 'object') {
|
|
59
|
+
return shape;
|
|
60
|
+
}
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
function unwrapArray(schema) {
|
|
64
|
+
if (!schema || typeof schema !== 'object')
|
|
65
|
+
return null;
|
|
66
|
+
const def = schema._def;
|
|
67
|
+
if (!def || typeof def !== 'object')
|
|
68
|
+
return null;
|
|
69
|
+
const type = def.type;
|
|
70
|
+
const typeName = def.typeName;
|
|
71
|
+
if (type === 'array' && def.element)
|
|
72
|
+
return def.element;
|
|
73
|
+
if (typeName === 'ZodArray' && def.type)
|
|
74
|
+
return def.type;
|
|
75
|
+
return null;
|
|
76
|
+
}
|