@gradial/aci 0.1.22 → 0.1.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.
Files changed (44) hide show
  1. package/bin/aci-darwin-arm64 +0 -0
  2. package/dist/content/assets.js +1 -1
  3. package/dist/dev/content-watch.js +1 -1
  4. package/dist/next/asset-route.d.ts +0 -1
  5. package/dist/next/asset-route.js +5 -6
  6. package/dist/next/config.js +25 -1
  7. package/dist/next/content-watch.js +1 -2
  8. package/dist/next/middleware.d.ts +2 -2
  9. package/dist/next/middleware.js +42 -25
  10. package/dist/next/page.d.ts +6 -0
  11. package/dist/next/page.js +34 -4
  12. package/dist/next/preview-mode.js +6 -7
  13. package/dist/next/server.js +4 -20
  14. package/dist/preview/core.d.ts +0 -2
  15. package/dist/preview/core.js +1 -3
  16. package/dist/react/Media.d.ts +1 -1
  17. package/dist/react/Media.js +1 -1
  18. package/dist/react/VideoPlayer.d.ts +307 -6
  19. package/dist/react/VideoPlayer.js +19 -5
  20. package/dist/react/index.d.ts +1 -1
  21. package/dist/types/image.d.ts +2 -2
  22. package/dist/types/media.d.ts +3 -0
  23. package/dist/types/video.d.ts +14 -8
  24. package/dist/types/video.js +3 -0
  25. package/package.json +2 -3
  26. package/src/cli/compile-registry.mjs +68 -43
  27. package/src/cli/verify-next-cdn-routes.mjs +101 -0
  28. package/src/types/component.ts +55 -0
  29. package/src/types/config.ts +37 -0
  30. package/src/types/data.ts +47 -0
  31. package/src/types/image.ts +4 -3
  32. package/src/types/index.ts +11 -0
  33. package/src/types/layout.ts +29 -0
  34. package/src/types/link.ts +100 -0
  35. package/src/types/media.ts +34 -0
  36. package/src/types/page.ts +47 -0
  37. package/src/types/render-mode.ts +10 -0
  38. package/src/types/renderer.ts +83 -0
  39. package/src/types/rich-text.ts +64 -0
  40. package/src/types/video.ts +76 -0
  41. package/templates/astro/template/package.json.tmpl +4 -5
  42. package/templates/nextjs/template/package.json.tmpl +4 -5
  43. package/templates/nextjs/template/src/app/gradial/assets/[...path]/route.ts +4 -0
  44. package/templates/nextjs/template/src/app/gradial/assets/[releaseId]/[...path]/route.ts +0 -31
@@ -0,0 +1,83 @@
1
+ import type { PageDocument } from './page.js';
2
+ import type { VaryDimension } from './render-mode.js';
3
+
4
+ export interface RenderCapabilities {
5
+ staticRender: boolean;
6
+ ssr: boolean;
7
+ ssrIslands: boolean;
8
+ clientIslands: boolean;
9
+ fragmentRender: boolean;
10
+ }
11
+
12
+ export interface Renderer {
13
+ renderPage(request: RenderPageRequest): Promise<RenderPageResult>;
14
+ renderFragment?(request: RenderFragmentRequest): Promise<RenderResult>;
15
+ renderIsland?(request: RenderIslandRequest): Promise<RenderResult>;
16
+ }
17
+
18
+ export interface RenderPageRequest {
19
+ page: PageDocument;
20
+ requestContext?: RequestContext;
21
+ release: ReleaseContext;
22
+ }
23
+
24
+ export interface RequestContext {
25
+ url: string;
26
+ method: string;
27
+ headers: Record<string, string>;
28
+ cookies: Record<string, string>;
29
+ geo?: GeoContext;
30
+ }
31
+
32
+ export interface GeoContext {
33
+ country?: string;
34
+ region?: string;
35
+ city?: string;
36
+ }
37
+
38
+ export interface ReleaseContext {
39
+ releaseId: string;
40
+ codeDigest: string;
41
+ contentSnapshotId: string;
42
+ assetUrl(logicalPath: string): string;
43
+ }
44
+
45
+ export interface RenderFragmentRequest {
46
+ fragmentId: string;
47
+ content: unknown;
48
+ release: ReleaseContext;
49
+ }
50
+
51
+ export interface RenderIslandRequest {
52
+ islandId: string;
53
+ component: string;
54
+ props: Record<string, unknown>;
55
+ requestContext: RequestContext;
56
+ release: ReleaseContext;
57
+ }
58
+
59
+ export interface RenderResult {
60
+ html: string;
61
+ status?: number;
62
+ headers?: Record<string, string>;
63
+ cachePolicy?: CachePolicy;
64
+ }
65
+
66
+ export interface RenderPageResult extends RenderResult {
67
+ islands?: IslandDescriptor[];
68
+ }
69
+
70
+ export interface IslandDescriptor {
71
+ islandId: string;
72
+ component: string;
73
+ props: Record<string, unknown>;
74
+ mode: 'ssr' | 'client';
75
+ varyDimensions?: VaryDimension[];
76
+ }
77
+
78
+ export interface CachePolicy {
79
+ scope: 'public' | 'private' | 'no-store';
80
+ ttl?: number;
81
+ staleWhileRevalidate?: number;
82
+ tags?: string[];
83
+ }
@@ -0,0 +1,64 @@
1
+ import { z } from 'zod';
2
+
3
+ // ---------------------------------------------------------------------------
4
+ // Inline content nodes
5
+ // ---------------------------------------------------------------------------
6
+
7
+ export type InlineContent =
8
+ | { type: 'text'; text: string }
9
+ | { type: 'span'; content: InlineContent[]; variant?: string }
10
+ | { type: 'strong'; content: InlineContent[] }
11
+ | { type: 'em'; content: InlineContent[] }
12
+ | { type: 'link'; href: string; content: InlineContent[] };
13
+
14
+ export type Heading = {
15
+ type: 'heading';
16
+ level: 1 | 2 | 3 | 4 | 5 | 6;
17
+ content: InlineContent[];
18
+ variant?: string;
19
+ };
20
+
21
+ export type RichTextValue =
22
+ | { format: 'html'; html: string }
23
+ | { format: 'markdown'; markdown: string };
24
+
25
+ export const InlineContentSchema: z.ZodType<InlineContent> = z.lazy(() => z.object({
26
+ type: z.literal('text'),
27
+ text: z.string(),
28
+ }).or(z.object({
29
+ type: z.literal('span'),
30
+ content: z.array(InlineContentSchema),
31
+ variant: z.string().optional(),
32
+ })).or(z.object({
33
+ type: z.literal('strong'),
34
+ content: z.array(InlineContentSchema),
35
+ })).or(z.object({
36
+ type: z.literal('em'),
37
+ content: z.array(InlineContentSchema),
38
+ })).or(z.object({
39
+ type: z.literal('link'),
40
+ href: z.string().min(1),
41
+ content: z.array(InlineContentSchema),
42
+ })));
43
+
44
+ export const HeadingSchema = z.object({
45
+ type: z.literal('heading'),
46
+ level: z.union([
47
+ z.literal(1),
48
+ z.literal(2),
49
+ z.literal(3),
50
+ z.literal(4),
51
+ z.literal(5),
52
+ z.literal(6),
53
+ ]),
54
+ content: z.array(InlineContentSchema),
55
+ variant: z.string().optional(),
56
+ }) satisfies z.ZodType<Heading>;
57
+
58
+ export const RichTextValueSchema: z.ZodType<RichTextValue> = z.object({
59
+ format: z.literal('html'),
60
+ html: z.string(),
61
+ }).or(z.object({
62
+ format: z.literal('markdown'),
63
+ markdown: z.string(),
64
+ }));
@@ -0,0 +1,76 @@
1
+ import { z } from 'zod';
2
+ import { ImageSchema, type Image } from './image.js';
3
+
4
+ // ---------------------------------------------------------------------------
5
+ // Video source variant (format alternatives)
6
+ // ---------------------------------------------------------------------------
7
+
8
+ export interface VideoSource {
9
+ src: string;
10
+ type: string; // MIME type: video/mp4, video/webm
11
+ }
12
+
13
+ // ---------------------------------------------------------------------------
14
+ // Video — DAM-backed video asset with compiler-resolved derivatives
15
+ //
16
+ // Content authors write: { "$type": "dam.assetRef", ... }
17
+ // or for static files: { "$type": "static.assetRef", "src": "/path" }
18
+ // The compiler resolves both to this Video value.
19
+ // ---------------------------------------------------------------------------
20
+
21
+ export interface Video {
22
+ /** Discriminator — always 'gradial.video'. */
23
+ $type: 'gradial.video';
24
+ /** DAM asset identifier (or "static:<path>" for non-DAM assets). */
25
+ assetId: string;
26
+ /** DAM version identifier (or "static" for non-DAM assets). */
27
+ versionId: string;
28
+ /** Accessible description of the video content. */
29
+ alt: string;
30
+ /** Primary video URL (compiler-resolved). For embeds, this is the iframe URL. */
31
+ src: string;
32
+ /** MIME type (e.g. 'video/mp4'). 'text/html' for external embeds (YouTube, Vimeo). */
33
+ type: string;
34
+ /** Intrinsic width in pixels. */
35
+ width: number;
36
+ /** Intrinsic height in pixels. */
37
+ height: number;
38
+ /** Poster frame — a full Image with responsive srcset. */
39
+ poster?: Image;
40
+ /** Format variants (e.g. mp4 + webm). Maps to <video><source> elements. */
41
+ sources?: VideoSource[];
42
+ /** Duration in seconds (if known). */
43
+ duration?: number;
44
+ /** iframe allow attribute (for embeds only). */
45
+ allow?: string;
46
+ /** iframe referrerPolicy (for embeds only). */
47
+ referrerPolicy?: string;
48
+ /** iframe allowFullScreen (for embeds only). */
49
+ allowFullScreen?: boolean;
50
+ }
51
+
52
+ // ---------------------------------------------------------------------------
53
+ // Zod schema
54
+ // ---------------------------------------------------------------------------
55
+
56
+ export const VideoSourceSchema = z.object({
57
+ src: z.string().min(1),
58
+ type: z.string().min(1),
59
+ });
60
+
61
+ export const VideoSchema = z.object({
62
+ $type: z.literal('gradial.video'),
63
+ assetId: z.string().min(1),
64
+ versionId: z.string().min(1),
65
+ alt: z.string(),
66
+ src: z.string().min(1),
67
+ type: z.string().min(1),
68
+ width: z.number().int().nonnegative(),
69
+ height: z.number().int().nonnegative(),
70
+ poster: ImageSchema.optional(),
71
+ sources: z.array(VideoSourceSchema).optional(),
72
+ duration: z.number().nonnegative().optional(),
73
+ allow: z.string().optional(),
74
+ referrerPolicy: z.string().optional(),
75
+ allowFullScreen: z.boolean().optional(),
76
+ });
@@ -8,16 +8,15 @@
8
8
  "build": "astro build",
9
9
  "preview": "ACI_CONTENT_ROOT=./.aci/compiled astro preview --host 0.0.0.0",
10
10
  "typecheck": "ACI_CONTENT_ROOT=./.aci/compiled astro check --tsconfig ./tsconfig.json",
11
- "aci:compile": "node ./node_modules/@gradial/aci/bin/aci.js build --compile-only",
12
- "content:compile": "node ./node_modules/@gradial/aci/bin/aci.js build --skip-code --content ./.content --out ./.aci/compiled",
13
- "aci:build": "node ./node_modules/@gradial/aci/bin/aci.js build --content ./.content",
11
+ "aci:compile": "node ./node_modules/@gradial/aci/bin/aci.js content compile --content ./.content --out ./.aci",
12
+ "content:compile": "node ./node_modules/@gradial/aci/bin/aci.js content compile --content ./.content --out ./.aci/compiled",
14
13
  "aci:doctor": "node ./node_modules/@gradial/aci/bin/aci.js doctor",
15
- "aci:validate": "node ./node_modules/@gradial/aci/bin/aci.js build --validate-only",
14
+ "aci:validate": "node ./node_modules/@gradial/aci/bin/aci.js doctor",
16
15
  "storybook": "storybook dev -p 6006",
17
16
  "build:storybook": "storybook build"
18
17
  },
19
18
  "dependencies": {
20
- "@gradial/aci": "^0.1.20",
19
+ "@gradial/aci": "0.1.23",
21
20
  "js-yaml": "^4.1.0",
22
21
  "marked": "^18.0.3",
23
22
  "zod": "^4.0.0"
@@ -8,17 +8,16 @@
8
8
  "build": "next build",
9
9
  "preview": "next start -H 0.0.0.0",
10
10
  "typecheck": "tsc --noEmit",
11
- "aci:compile": "node ./node_modules/@gradial/aci/bin/aci.js build --compile-only",
12
- "content:compile": "node ./node_modules/@gradial/aci/bin/aci.js build --skip-code --content ./.content --out ./.aci/compiled",
13
- "aci:build": "node ./node_modules/@gradial/aci/bin/aci.js build --content ./.content",
11
+ "aci:compile": "node ./node_modules/@gradial/aci/bin/aci.js content compile --content ./.content --out ./.aci",
12
+ "content:compile": "node ./node_modules/@gradial/aci/bin/aci.js content compile --content ./.content --out ./.aci/compiled",
14
13
  "aci:doctor": "node ./node_modules/@gradial/aci/bin/aci.js doctor",
15
- "aci:validate": "node ./node_modules/@gradial/aci/bin/aci.js build --validate-only",
14
+ "aci:validate": "node ./node_modules/@gradial/aci/bin/aci.js doctor",
16
15
  "lint": "eslint .",
17
16
  "storybook": "storybook dev -p 6006",
18
17
  "build:storybook": "storybook build"
19
18
  },
20
19
  "dependencies": {
21
- "@gradial/aci": "0.2.0-rc.0",
20
+ "@gradial/aci": "0.1.23",
22
21
  "js-yaml": "^4.1.1",
23
22
  "next": "^15.1.6",
24
23
  "react": "^19.0.0",
@@ -0,0 +1,4 @@
1
+ export { GET } from '@gradial/aci/next/asset-route';
2
+
3
+ export const runtime = 'nodejs';
4
+ export const dynamic = 'force-dynamic';
@@ -1,31 +0,0 @@
1
- import { getReleaseAssetResponse } from '@gradial/aci/content';
2
- import { FileContentProvider } from '@gradial/aci/providers/file';
3
-
4
- const LOCAL_RELEASE_ID = 'local';
5
-
6
- type AssetRouteContext = {
7
- params: Promise<{
8
- releaseId?: string;
9
- path?: string[];
10
- }>;
11
- };
12
-
13
- export const runtime = 'nodejs';
14
- export const dynamic = 'force-dynamic';
15
-
16
- export async function GET(_request: Request, { params }: AssetRouteContext): Promise<Response> {
17
- const resolvedParams = await params;
18
- const releaseId = resolvedParams.releaseId || '';
19
- const assetPath = '/' + (resolvedParams.path || []).join('/');
20
- if (!releaseId || assetPath === '/') {
21
- return new Response('asset not found', { status: 404 });
22
- }
23
- if (releaseId === LOCAL_RELEASE_ID) {
24
- return new FileContentProvider().fetchRaw(assetPath);
25
- }
26
- try {
27
- return await getReleaseAssetResponse({ releaseId, assetPath });
28
- } catch {
29
- return new Response('asset not found', { status: 404 });
30
- }
31
- }