@visual-platform/contracts 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/classes.d.ts +11 -0
- package/dist/classes.d.ts.map +1 -0
- package/dist/classes.js +34 -0
- package/dist/classes.js.map +1 -0
- package/dist/component.d.ts +135 -0
- package/dist/component.d.ts.map +1 -0
- package/dist/component.js +176 -0
- package/dist/component.js.map +1 -0
- package/dist/data.d.ts +160 -0
- package/dist/data.d.ts.map +1 -0
- package/dist/data.js +363 -0
- package/dist/data.js.map +1 -0
- package/dist/design.d.ts +139 -0
- package/dist/design.d.ts.map +1 -0
- package/dist/design.js +226 -0
- package/dist/design.js.map +1 -0
- package/dist/events.d.ts +36 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +46 -0
- package/dist/events.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/locales.d.ts +37 -0
- package/dist/locales.d.ts.map +1 -0
- package/dist/locales.js +36 -0
- package/dist/locales.js.map +1 -0
- package/dist/page-document.d.ts +203 -0
- package/dist/page-document.d.ts.map +1 -0
- package/dist/page-document.js +73 -0
- package/dist/page-document.js.map +1 -0
- package/dist/published.d.ts +353 -0
- package/dist/published.d.ts.map +1 -0
- package/dist/published.js +66 -0
- package/dist/published.js.map +1 -0
- package/dist/references.d.ts +51 -0
- package/dist/references.d.ts.map +1 -0
- package/dist/references.js +35 -0
- package/dist/references.js.map +1 -0
- package/dist/responsive.d.ts +19 -0
- package/dist/responsive.d.ts.map +1 -0
- package/dist/responsive.js +18 -0
- package/dist/responsive.js.map +1 -0
- package/dist/section.d.ts +33 -0
- package/dist/section.d.ts.map +1 -0
- package/dist/section.js +53 -0
- package/dist/section.js.map +1 -0
- package/dist/seo.d.ts +98 -0
- package/dist/seo.d.ts.map +1 -0
- package/dist/seo.js +71 -0
- package/dist/seo.js.map +1 -0
- package/dist/tables.d.ts +134 -0
- package/dist/tables.d.ts.map +1 -0
- package/dist/tables.js +438 -0
- package/dist/tables.js.map +1 -0
- package/package.json +31 -3
- package/README.md +0 -3
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { LocaleMapSchema } from "./locales.js";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { PageDocumentSchema } from "./page-document.js";
|
|
4
|
+
import { PageSeoSchema } from "./seo.js";
|
|
5
|
+
import { DesignSnapshotSchema } from "./design.js";
|
|
6
|
+
import { ComponentDocumentSchema } from "./component.js";
|
|
7
|
+
/** Published API contract `/v1` (blueprint 71 §3). Shared by apps/delivery-api and the SDK. */
|
|
8
|
+
export const PUBLISHED_API_VERSION = "v1";
|
|
9
|
+
export const ReleaseRefSchema = z.object({
|
|
10
|
+
id: z.string(),
|
|
11
|
+
sequence: z.number().int(),
|
|
12
|
+
manifestHash: z.string(),
|
|
13
|
+
});
|
|
14
|
+
export const ResolvedPageSchema = z.object({
|
|
15
|
+
project: z.object({ id: z.string() }),
|
|
16
|
+
release: ReleaseRefSchema,
|
|
17
|
+
/** dir: text direction of the content locale (ADR-035); older releases omit it. */
|
|
18
|
+
locale: z.object({ requested: z.string(), content: z.string(), dir: z.enum(["ltr", "rtl"]).optional() }),
|
|
19
|
+
page: z.object({
|
|
20
|
+
pageKey: z.string(),
|
|
21
|
+
slug: z.string(),
|
|
22
|
+
artifactId: z.string(),
|
|
23
|
+
versionId: z.string(),
|
|
24
|
+
versionNumber: z.number().int(),
|
|
25
|
+
schemaVersion: z.number().int(),
|
|
26
|
+
document: PageDocumentSchema,
|
|
27
|
+
}),
|
|
28
|
+
seo: PageSeoSchema,
|
|
29
|
+
/** The same page in the release's other languages (hreflang, language switchers). */
|
|
30
|
+
alternates: z.array(z.object({ locale: z.string(), slug: z.string() })).optional(),
|
|
31
|
+
/** Project default language (hreflang x-default). */
|
|
32
|
+
defaultLocale: z.string().nullable().optional(),
|
|
33
|
+
/** Results of the page's data-table inputs (ADR-041), by input name. */
|
|
34
|
+
data: z.record(z.string(), z.unknown()).optional(),
|
|
35
|
+
/** Design pinned by the release (tokens, themes, fonts). Absent/null → SDK default tokens. */
|
|
36
|
+
design: DesignSnapshotSchema.nullable().optional(),
|
|
37
|
+
/** Compiled CSS for the Tailwind classes in the release, scoped to [data-vp-root] (ADR-029). */
|
|
38
|
+
styles: z.string().nullable().optional(),
|
|
39
|
+
compatibility: z.object({ schemaVersion: z.number().int(), minimumSdkVersion: z.string() }),
|
|
40
|
+
});
|
|
41
|
+
export const PageListSchema = z.object({
|
|
42
|
+
release: ReleaseRefSchema,
|
|
43
|
+
pages: z.array(z.object({ pageKey: z.string(), locale: z.string(), slug: z.string() })),
|
|
44
|
+
});
|
|
45
|
+
export const ApiErrorSchema = z.object({ error: z.object({ code: z.string(), message: z.string() }) });
|
|
46
|
+
/** `GET /v1/projects/:projectId/components/:id/resolved` — a composed component pinned by the current release (ADR-028). */
|
|
47
|
+
export const ResolvedComponentSchema = z.object({
|
|
48
|
+
project: z.object({ id: z.string() }),
|
|
49
|
+
release: ReleaseRefSchema,
|
|
50
|
+
component: z.object({ id: z.string(), versionId: z.string(), versionNumber: z.number().int(), document: ComponentDocumentSchema }),
|
|
51
|
+
design: DesignSnapshotSchema.nullable().optional(),
|
|
52
|
+
styles: z.string().nullable().optional(),
|
|
53
|
+
/** Locales of the release with their text direction (ADR-035). */
|
|
54
|
+
locales: z.lazy(() => LocaleMapSchema).nullable().optional(),
|
|
55
|
+
/** Results of the component's data-table inputs (ADR-041). */
|
|
56
|
+
data: z.record(z.string(), z.unknown()).optional(),
|
|
57
|
+
});
|
|
58
|
+
/** `GET /v1/projects/:projectId/classes` — Tailwind classes used by the current release (for apps that build their own CSS). */
|
|
59
|
+
export const ReleaseClassesSchema = z.object({ release: ReleaseRefSchema, classes: z.array(z.string()) });
|
|
60
|
+
/** `GET /v1/projects/:projectId/locales` — languages of the current release (ADR-035). */
|
|
61
|
+
export const LocaleListSchema = z.object({
|
|
62
|
+
release: ReleaseRefSchema,
|
|
63
|
+
defaultLocale: z.string().nullable().optional(),
|
|
64
|
+
locales: z.array(z.object({ code: z.string(), name: z.string(), nativeName: z.string(), dir: z.enum(["ltr", "rtl"]) })),
|
|
65
|
+
});
|
|
66
|
+
//# sourceMappingURL=published.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"published.js","sourceRoot":"","sources":["../src/published.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Reference to another artifact (blueprint 22 §2). `latest` is an alias policy, never a version. */
|
|
3
|
+
export declare const ArtifactReferenceSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
4
|
+
mode: z.ZodLiteral<"fixed">;
|
|
5
|
+
artifactId: z.ZodString;
|
|
6
|
+
versionId: z.ZodString;
|
|
7
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
8
|
+
mode: z.ZodLiteral<"alias">;
|
|
9
|
+
aliasKey: z.ZodString;
|
|
10
|
+
}, z.core.$strict>], "mode">;
|
|
11
|
+
export type ArtifactReference = z.infer<typeof ArtifactReferenceSchema>;
|
|
12
|
+
/** Asset field value (blueprint 27, 32 field type `asset`). */
|
|
13
|
+
export declare const AssetRefSchema: z.ZodObject<{
|
|
14
|
+
assetId: z.ZodString;
|
|
15
|
+
alt: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
16
|
+
decorative: z.ZodOptional<z.ZodBoolean>;
|
|
17
|
+
focal: z.ZodOptional<z.ZodObject<{
|
|
18
|
+
x: z.ZodNumber;
|
|
19
|
+
y: z.ZodNumber;
|
|
20
|
+
}, z.core.$strict>>;
|
|
21
|
+
}, z.core.$strict>;
|
|
22
|
+
export type AssetRef = z.infer<typeof AssetRefSchema>;
|
|
23
|
+
/** Link field value (blueprint 32 field type `link`, rule `link.protocol`). */
|
|
24
|
+
export declare const LinkRefSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
25
|
+
kind: z.ZodLiteral<"page">;
|
|
26
|
+
pageKey: z.ZodString;
|
|
27
|
+
anchor: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
29
|
+
kind: z.ZodLiteral<"url">;
|
|
30
|
+
href: z.ZodString;
|
|
31
|
+
}, z.core.$strict>], "kind">;
|
|
32
|
+
export type LinkRef = z.infer<typeof LinkRefSchema>;
|
|
33
|
+
/**
|
|
34
|
+
* Icon field value (Lucide, ADR-026): the SVG geometry is embedded so customer apps need no icon
|
|
35
|
+
* library. Only plain shape elements with geometry attributes — no script, style, href or events.
|
|
36
|
+
*/
|
|
37
|
+
export declare const IconValueSchema: z.ZodObject<{
|
|
38
|
+
set: z.ZodLiteral<"lucide">;
|
|
39
|
+
name: z.ZodString;
|
|
40
|
+
nodes: z.ZodArray<z.ZodTuple<[z.ZodEnum<{
|
|
41
|
+
circle: "circle";
|
|
42
|
+
ellipse: "ellipse";
|
|
43
|
+
line: "line";
|
|
44
|
+
path: "path";
|
|
45
|
+
polygon: "polygon";
|
|
46
|
+
polyline: "polyline";
|
|
47
|
+
rect: "rect";
|
|
48
|
+
}>, z.ZodRecord<z.ZodString, z.ZodString>], null>>;
|
|
49
|
+
}, z.core.$strict>;
|
|
50
|
+
export type IconValue = z.infer<typeof IconValueSchema>;
|
|
51
|
+
//# sourceMappingURL=references.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"references.d.ts","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,qGAAqG;AACrG,eAAO,MAAM,uBAAuB;;;;;;;4BAGlC,CAAC;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,uBAAuB,CAAC,CAAC;AAExE,+DAA+D;AAC/D,eAAO,MAAM,cAAc;;;;;;;;kBAOhB,CAAC;AACZ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAItD,+EAA+E;AAC/E,eAAO,MAAM,aAAa;;;;;;;4BAGxB,CAAC;AACH,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAGpD;;;GAGG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;kBAOjB,CAAC;AACZ,MAAM,MAAM,SAAS,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,eAAe,CAAC,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Reference to another artifact (blueprint 22 §2). `latest` is an alias policy, never a version. */
|
|
3
|
+
export const ArtifactReferenceSchema = z.discriminatedUnion("mode", [
|
|
4
|
+
z.object({ mode: z.literal("fixed"), artifactId: z.string().min(1), versionId: z.string().min(1) }).strict(),
|
|
5
|
+
z.object({ mode: z.literal("alias"), aliasKey: z.string().min(1) }).strict(),
|
|
6
|
+
]);
|
|
7
|
+
/** Asset field value (blueprint 27, 32 field type `asset`). */
|
|
8
|
+
export const AssetRefSchema = z
|
|
9
|
+
.object({
|
|
10
|
+
assetId: z.string().min(1),
|
|
11
|
+
alt: z.record(z.string(), z.string()).optional(),
|
|
12
|
+
decorative: z.boolean().optional(),
|
|
13
|
+
focal: z.object({ x: z.number().min(0).max(1), y: z.number().min(0).max(1) }).strict().optional(),
|
|
14
|
+
})
|
|
15
|
+
.strict();
|
|
16
|
+
const SAFE_URL = /^(https:\/\/|mailto:|tel:)/i;
|
|
17
|
+
/** Link field value (blueprint 32 field type `link`, rule `link.protocol`). */
|
|
18
|
+
export const LinkRefSchema = z.discriminatedUnion("kind", [
|
|
19
|
+
z.object({ kind: z.literal("page"), pageKey: z.string().min(1), anchor: z.string().optional() }).strict(),
|
|
20
|
+
z.object({ kind: z.literal("url"), href: z.string().regex(SAFE_URL, "only https, mailto and tel links are allowed") }).strict(),
|
|
21
|
+
]);
|
|
22
|
+
const ICON_TAGS = ["path", "circle", "rect", "line", "polyline", "polygon", "ellipse"];
|
|
23
|
+
/**
|
|
24
|
+
* Icon field value (Lucide, ADR-026): the SVG geometry is embedded so customer apps need no icon
|
|
25
|
+
* library. Only plain shape elements with geometry attributes — no script, style, href or events.
|
|
26
|
+
*/
|
|
27
|
+
export const IconValueSchema = z.object({
|
|
28
|
+
set: z.literal("lucide"),
|
|
29
|
+
name: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/),
|
|
30
|
+
nodes: z.array(z.tuple([
|
|
31
|
+
z.enum(ICON_TAGS),
|
|
32
|
+
z.record(z.string().regex(/^(?:d|cx|cy|r|rx|ry|x|y|x1|y1|x2|y2|width|height|points)$/), z.string().regex(/^[0-9a-zA-Z .,-]{1,2000}$/)),
|
|
33
|
+
])).min(1).max(40),
|
|
34
|
+
}).strict();
|
|
35
|
+
//# sourceMappingURL=references.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"references.js","sourceRoot":"","sources":["../src/references.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Breakpoint keys come from the design system (blueprint 26 §3). `base` is mandatory there. */
|
|
3
|
+
export declare const BreakpointKeySchema: z.ZodString;
|
|
4
|
+
export type BreakpointKey = z.infer<typeof BreakpointKeySchema>;
|
|
5
|
+
/**
|
|
6
|
+
* A prop value that may vary per breakpoint (blueprint 26 §4):
|
|
7
|
+
* T | { "$responsive": { base?: T, md?: T, ... } }
|
|
8
|
+
* Missing breakpoints inherit from the nearest smaller one.
|
|
9
|
+
*/
|
|
10
|
+
export declare function responsive<T extends z.ZodType>(value: T): z.ZodUnion<readonly [T, z.ZodObject<{
|
|
11
|
+
$responsive: z.ZodRecord<z.ZodString, T>;
|
|
12
|
+
}, z.core.$strict>]>;
|
|
13
|
+
export type ResponsiveValue<T> = T | {
|
|
14
|
+
$responsive: Partial<Record<BreakpointKey, T>>;
|
|
15
|
+
};
|
|
16
|
+
export declare function isResponsive<T>(v: ResponsiveValue<T>): v is {
|
|
17
|
+
$responsive: Partial<Record<BreakpointKey, T>>;
|
|
18
|
+
};
|
|
19
|
+
//# sourceMappingURL=responsive.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responsive.d.ts","sourceRoot":"","sources":["../src/responsive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gGAAgG;AAChG,eAAO,MAAM,mBAAmB,aAAsE,CAAC;AACvG,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC;;qBAKvD;AAED,MAAM,MAAM,eAAe,CAAC,CAAC,IAAI,CAAC,GAAG;IAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAA;CAAE,CAAC;AAExF,wBAAgB,YAAY,CAAC,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI;IAAE,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CAAA;CAAE,CAE9G"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Breakpoint keys come from the design system (blueprint 26 §3). `base` is mandatory there. */
|
|
3
|
+
export const BreakpointKeySchema = z.string().regex(/^[a-z0-9]+$/, "breakpoint key must be [a-z0-9]+");
|
|
4
|
+
/**
|
|
5
|
+
* A prop value that may vary per breakpoint (blueprint 26 §4):
|
|
6
|
+
* T | { "$responsive": { base?: T, md?: T, ... } }
|
|
7
|
+
* Missing breakpoints inherit from the nearest smaller one.
|
|
8
|
+
*/
|
|
9
|
+
export function responsive(value) {
|
|
10
|
+
return z.union([
|
|
11
|
+
value,
|
|
12
|
+
z.object({ $responsive: z.record(BreakpointKeySchema, value) }).strict(),
|
|
13
|
+
]);
|
|
14
|
+
}
|
|
15
|
+
export function isResponsive(v) {
|
|
16
|
+
return typeof v === "object" && v !== null && "$responsive" in v;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=responsive.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"responsive.js","sourceRoot":"","sources":["../src/responsive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,gGAAgG;AAChG,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,kCAAkC,CAAC,CAAC;AAGvG;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAsB,KAAQ;IACtD,OAAO,CAAC,CAAC,KAAK,CAAC;QACb,KAAK;QACL,CAAC,CAAC,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE;KACzE,CAAC,CAAC;AACL,CAAC;AAID,MAAM,UAAU,YAAY,CAAI,CAAqB;IACnD,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,aAAa,IAAI,CAAC,CAAC;AACnE,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { type ComponentNode } from "./page-document.js";
|
|
3
|
+
/** Reusable section stored at Project scope (blueprint 22, 24). No SEO/locale: pages own those. */
|
|
4
|
+
export declare const SectionDocumentSchema: z.ZodObject<{
|
|
5
|
+
schemaVersion: z.ZodLiteral<1>;
|
|
6
|
+
nodes: z.ZodArray<z.ZodType<ComponentNode, unknown, z.core.$ZodTypeInternals<ComponentNode, unknown>>>;
|
|
7
|
+
}, z.core.$strict>;
|
|
8
|
+
export type SectionDocument = z.infer<typeof SectionDocumentSchema>;
|
|
9
|
+
/** Node type that places a shared section on a page. */
|
|
10
|
+
export declare const SECTION_REF_TYPE = "SectionRef";
|
|
11
|
+
/**
|
|
12
|
+
* `follow`: use the section's latest published version at each release of the page's site (alias-like).
|
|
13
|
+
* `fixed`: pin one immutable version.
|
|
14
|
+
*/
|
|
15
|
+
export declare const SectionRefPropsSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
16
|
+
mode: z.ZodLiteral<"follow">;
|
|
17
|
+
sectionId: z.ZodString;
|
|
18
|
+
}, z.core.$loose>, z.ZodObject<{
|
|
19
|
+
mode: z.ZodLiteral<"fixed">;
|
|
20
|
+
sectionId: z.ZodString;
|
|
21
|
+
versionId: z.ZodString;
|
|
22
|
+
}, z.core.$loose>], "mode">;
|
|
23
|
+
export type SectionRefProps = z.infer<typeof SectionRefPropsSchema>;
|
|
24
|
+
export declare function sectionRefs(nodes: readonly ComponentNode[]): {
|
|
25
|
+
nodeId: string;
|
|
26
|
+
props: SectionRefProps | null;
|
|
27
|
+
}[];
|
|
28
|
+
/**
|
|
29
|
+
* Replace SectionRef nodes with the section's nodes (delivery-time expansion). Child ids are
|
|
30
|
+
* namespaced with the ref id so they stay unique when a section is used twice on a page.
|
|
31
|
+
*/
|
|
32
|
+
export declare function expandSectionRefs(nodes: readonly ComponentNode[], resolve: (ref: SectionRefProps) => ComponentNode[] | null): ComponentNode[];
|
|
33
|
+
//# sourceMappingURL=section.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section.d.ts","sourceRoot":"","sources":["../src/section.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAgE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEtH,mGAAmG;AACnG,eAAO,MAAM,qBAAqB;;;kBAO9B,CAAC;AACL,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,wDAAwD;AACxD,eAAO,MAAM,gBAAgB,eAAe,CAAC;AAE7C;;;GAGG;AACH,eAAO,MAAM,qBAAqB;;;;;;;2BAGhC,CAAC;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAEpE,wBAAgB,WAAW,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAAA;CAAE,EAAE,CAQhH;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,eAAe,KAAK,aAAa,EAAE,GAAG,IAAI,GAAG,aAAa,EAAE,CAgB7I"}
|
package/dist/section.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { ComponentNodeSchema, PAGE_DOCUMENT_SCHEMA_VERSION, walkNodes } from "./page-document.js";
|
|
3
|
+
/** Reusable section stored at Project scope (blueprint 22, 24). No SEO/locale: pages own those. */
|
|
4
|
+
export const SectionDocumentSchema = z
|
|
5
|
+
.object({ schemaVersion: z.literal(PAGE_DOCUMENT_SCHEMA_VERSION), nodes: z.array(ComponentNodeSchema).min(1, "a section needs at least one block") })
|
|
6
|
+
.strict()
|
|
7
|
+
.superRefine((doc, ctx) => {
|
|
8
|
+
for (const n of walkNodes(doc.nodes)) {
|
|
9
|
+
if (n.type === SECTION_REF_TYPE)
|
|
10
|
+
ctx.addIssue({ code: "custom", path: ["nodes"], message: "sections cannot contain other sections (no nesting in v1)" });
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
/** Node type that places a shared section on a page. */
|
|
14
|
+
export const SECTION_REF_TYPE = "SectionRef";
|
|
15
|
+
/**
|
|
16
|
+
* `follow`: use the section's latest published version at each release of the page's site (alias-like).
|
|
17
|
+
* `fixed`: pin one immutable version.
|
|
18
|
+
*/
|
|
19
|
+
export const SectionRefPropsSchema = z.discriminatedUnion("mode", [
|
|
20
|
+
z.object({ mode: z.literal("follow"), sectionId: z.string().uuid() }).passthrough(),
|
|
21
|
+
z.object({ mode: z.literal("fixed"), sectionId: z.string().uuid(), versionId: z.string().uuid() }).passthrough(),
|
|
22
|
+
]);
|
|
23
|
+
export function sectionRefs(nodes) {
|
|
24
|
+
const out = [];
|
|
25
|
+
for (const n of walkNodes(nodes)) {
|
|
26
|
+
if (n.type !== SECTION_REF_TYPE)
|
|
27
|
+
continue;
|
|
28
|
+
const r = SectionRefPropsSchema.safeParse(n.props);
|
|
29
|
+
out.push({ nodeId: n.id, props: r.success ? r.data : null });
|
|
30
|
+
}
|
|
31
|
+
return out;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Replace SectionRef nodes with the section's nodes (delivery-time expansion). Child ids are
|
|
35
|
+
* namespaced with the ref id so they stay unique when a section is used twice on a page.
|
|
36
|
+
*/
|
|
37
|
+
export function expandSectionRefs(nodes, resolve) {
|
|
38
|
+
const prefix = (refId, n) => {
|
|
39
|
+
const id = `${refId}_${n.id.replace(/^n_/, "")}`;
|
|
40
|
+
const slots = n.slots ? Object.fromEntries(Object.entries(n.slots).map(([k, v]) => [k, v.map((c) => prefix(refId, c))])) : undefined;
|
|
41
|
+
return { ...n, id, ...(slots ? { slots } : {}) };
|
|
42
|
+
};
|
|
43
|
+
const walk = (list) => list.flatMap((n) => {
|
|
44
|
+
if (n.type === SECTION_REF_TYPE) {
|
|
45
|
+
const r = SectionRefPropsSchema.safeParse(n.props);
|
|
46
|
+
const resolved = r.success ? resolve(r.data) : null;
|
|
47
|
+
return resolved ? resolved.map((c) => prefix(n.id, c)) : [];
|
|
48
|
+
}
|
|
49
|
+
return n.slots ? [{ ...n, slots: Object.fromEntries(Object.entries(n.slots).map(([k, v]) => [k, walk(v)])) }] : [n];
|
|
50
|
+
});
|
|
51
|
+
return walk(nodes);
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=section.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"section.js","sourceRoot":"","sources":["../src/section.ts"],"names":[],"mappings":"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"}
|
package/dist/seo.d.ts
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
/** Allowlisted JSON-LD templates (blueprint 51 §A3). Free-form JSON-LD is not allowed. */
|
|
3
|
+
export declare const StructuredDataTemplateSchema: z.ZodEnum<{
|
|
4
|
+
Article: "Article";
|
|
5
|
+
BreadcrumbList: "BreadcrumbList";
|
|
6
|
+
Event: "Event";
|
|
7
|
+
FAQPage: "FAQPage";
|
|
8
|
+
Offer: "Offer";
|
|
9
|
+
Organization: "Organization";
|
|
10
|
+
Product: "Product";
|
|
11
|
+
}>;
|
|
12
|
+
export declare const RobotsSchema: z.ZodObject<{
|
|
13
|
+
index: z.ZodBoolean;
|
|
14
|
+
follow: z.ZodBoolean;
|
|
15
|
+
}, z.core.$strict>;
|
|
16
|
+
/** Social image by URL (https; usually from the asset library, which also records assetId/size). */
|
|
17
|
+
export declare const SeoImageSchema: z.ZodObject<{
|
|
18
|
+
url: z.ZodString;
|
|
19
|
+
alt: z.ZodOptional<z.ZodString>;
|
|
20
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
21
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
22
|
+
assetId: z.ZodOptional<z.ZodString>;
|
|
23
|
+
}, z.core.$strict>;
|
|
24
|
+
export type SeoImage = z.infer<typeof SeoImageSchema>;
|
|
25
|
+
/**
|
|
26
|
+
* JSON-LD block from an allowlisted schema.org type (blueprint 51 §A3): `fields` become the object's
|
|
27
|
+
* properties, `@context`/`@type` are added on output. Plain JSON only, at most 20 KB.
|
|
28
|
+
*/
|
|
29
|
+
export declare const StructuredDataSchema: z.ZodObject<{
|
|
30
|
+
template: z.ZodEnum<{
|
|
31
|
+
Article: "Article";
|
|
32
|
+
BreadcrumbList: "BreadcrumbList";
|
|
33
|
+
Event: "Event";
|
|
34
|
+
FAQPage: "FAQPage";
|
|
35
|
+
Offer: "Offer";
|
|
36
|
+
Organization: "Organization";
|
|
37
|
+
Product: "Product";
|
|
38
|
+
}>;
|
|
39
|
+
fields: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
40
|
+
}, z.core.$strict>;
|
|
41
|
+
export type StructuredData = z.infer<typeof StructuredDataSchema>;
|
|
42
|
+
/** The JSON-LD object for one block (escape `<` when embedding in HTML). */
|
|
43
|
+
export declare const jsonLd: (b: StructuredData) => {
|
|
44
|
+
"@context": string;
|
|
45
|
+
"@type": "Article" | "BreadcrumbList" | "Event" | "FAQPage" | "Offer" | "Organization" | "Product";
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* All blocks of a page as ONE JSON-LD document (one `<script>`): a single block is returned as is,
|
|
49
|
+
* several become `{ "@context", "@graph": [...] }` (schema.org's way to describe several things).
|
|
50
|
+
* Null when the page has none.
|
|
51
|
+
*/
|
|
52
|
+
export declare const jsonLdDocument: (blocks: readonly StructuredData[] | undefined | null) => Record<string, unknown> | null;
|
|
53
|
+
/** Starter fields per template, for editors. */
|
|
54
|
+
export declare const STRUCTURED_DATA_STARTERS: Record<z.infer<typeof StructuredDataTemplateSchema>, Record<string, unknown>>;
|
|
55
|
+
/** Page-level SEO at `root.props.seo`. `null` means "inherit from site defaults". */
|
|
56
|
+
export declare const PageSeoSchema: z.ZodObject<{
|
|
57
|
+
slug: z.ZodString;
|
|
58
|
+
title: z.ZodString;
|
|
59
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
60
|
+
canonical: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
61
|
+
robots: z.ZodOptional<z.ZodNullable<z.ZodObject<{
|
|
62
|
+
index: z.ZodBoolean;
|
|
63
|
+
follow: z.ZodBoolean;
|
|
64
|
+
}, z.core.$strict>>>;
|
|
65
|
+
og: z.ZodOptional<z.ZodObject<{
|
|
66
|
+
title: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
67
|
+
description: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
68
|
+
image: z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodObject<{
|
|
69
|
+
url: z.ZodString;
|
|
70
|
+
alt: z.ZodOptional<z.ZodString>;
|
|
71
|
+
width: z.ZodOptional<z.ZodNumber>;
|
|
72
|
+
height: z.ZodOptional<z.ZodNumber>;
|
|
73
|
+
assetId: z.ZodOptional<z.ZodString>;
|
|
74
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
75
|
+
assetId: z.ZodString;
|
|
76
|
+
alt: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
|
|
77
|
+
decorative: z.ZodOptional<z.ZodBoolean>;
|
|
78
|
+
focal: z.ZodOptional<z.ZodObject<{
|
|
79
|
+
x: z.ZodNumber;
|
|
80
|
+
y: z.ZodNumber;
|
|
81
|
+
}, z.core.$strict>>;
|
|
82
|
+
}, z.core.$strict>]>>>;
|
|
83
|
+
}, z.core.$strict>>;
|
|
84
|
+
structuredData: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
85
|
+
template: z.ZodEnum<{
|
|
86
|
+
Article: "Article";
|
|
87
|
+
BreadcrumbList: "BreadcrumbList";
|
|
88
|
+
Event: "Event";
|
|
89
|
+
FAQPage: "FAQPage";
|
|
90
|
+
Offer: "Offer";
|
|
91
|
+
Organization: "Organization";
|
|
92
|
+
Product: "Product";
|
|
93
|
+
}>;
|
|
94
|
+
fields: z.ZodRecord<z.ZodString, z.ZodUnknown>;
|
|
95
|
+
}, z.core.$strict>>>;
|
|
96
|
+
}, z.core.$strict>;
|
|
97
|
+
export type PageSeo = z.infer<typeof PageSeoSchema>;
|
|
98
|
+
//# sourceMappingURL=seo.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo.d.ts","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,0FAA0F;AAC1F,eAAO,MAAM,4BAA4B;;;;;;;;EAEvC,CAAC;AAEH,eAAO,MAAM,YAAY;;;kBAAiE,CAAC;AAE3F,oGAAoG;AACpG,eAAO,MAAM,cAAc;;;;;;kBAMhB,CAAC;AACZ,MAAM,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,cAAc,CAAC,CAAC;AAEtD;;;GAGG;AACH,eAAO,MAAM,oBAAoB;;;;;;;;;;;kBAK7B,CAAC;AACL,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAC;AAElE,4EAA4E;AAC5E,eAAO,MAAM,MAAM,MAAO,cAAc;;;CAA6E,CAAC;AAEtH;;;;GAIG;AACH,eAAO,MAAM,cAAc,WAAY,SAAS,cAAc,EAAE,GAAG,SAAS,GAAG,IAAI,KAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAI/G,CAAC;AAEF,gDAAgD;AAChD,eAAO,MAAM,wBAAwB,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,4BAA4B,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAQlH,CAAC;AAEF,qFAAqF;AACrF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAiBf,CAAC;AACZ,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC"}
|
package/dist/seo.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { AssetRefSchema } from "./references.js";
|
|
3
|
+
/** Allowlisted JSON-LD templates (blueprint 51 §A3). Free-form JSON-LD is not allowed. */
|
|
4
|
+
export const StructuredDataTemplateSchema = z.enum([
|
|
5
|
+
"Article", "Product", "Offer", "FAQPage", "BreadcrumbList", "Organization", "Event",
|
|
6
|
+
]);
|
|
7
|
+
export const RobotsSchema = z.object({ index: z.boolean(), follow: z.boolean() }).strict();
|
|
8
|
+
/** Social image by URL (https; usually from the asset library, which also records assetId/size). */
|
|
9
|
+
export const SeoImageSchema = z.object({
|
|
10
|
+
url: z.string().regex(/^https:\/\/\S+$/, "the image must be an https URL"),
|
|
11
|
+
alt: z.string().max(200).optional(),
|
|
12
|
+
width: z.number().int().positive().optional(),
|
|
13
|
+
height: z.number().int().positive().optional(),
|
|
14
|
+
assetId: z.string().optional(),
|
|
15
|
+
}).strict();
|
|
16
|
+
/**
|
|
17
|
+
* JSON-LD block from an allowlisted schema.org type (blueprint 51 §A3): `fields` become the object's
|
|
18
|
+
* properties, `@context`/`@type` are added on output. Plain JSON only, at most 20 KB.
|
|
19
|
+
*/
|
|
20
|
+
export const StructuredDataSchema = z.object({ template: StructuredDataTemplateSchema, fields: z.record(z.string(), z.unknown()) }).strict()
|
|
21
|
+
.superRefine((b, ctx) => {
|
|
22
|
+
const text = JSON.stringify(b.fields);
|
|
23
|
+
if (text.length > 20_000)
|
|
24
|
+
ctx.addIssue({ code: "custom", message: "structured data is limited to 20 KB" });
|
|
25
|
+
if (Object.keys(b.fields).some((k) => k.startsWith("@") && k !== "@id"))
|
|
26
|
+
ctx.addIssue({ code: "custom", message: "@context and @type are added automatically" });
|
|
27
|
+
});
|
|
28
|
+
/** The JSON-LD object for one block (escape `<` when embedding in HTML). */
|
|
29
|
+
export const jsonLd = (b) => ({ "@context": "https://schema.org", "@type": b.template, ...b.fields });
|
|
30
|
+
/**
|
|
31
|
+
* All blocks of a page as ONE JSON-LD document (one `<script>`): a single block is returned as is,
|
|
32
|
+
* several become `{ "@context", "@graph": [...] }` (schema.org's way to describe several things).
|
|
33
|
+
* Null when the page has none.
|
|
34
|
+
*/
|
|
35
|
+
export const jsonLdDocument = (blocks) => {
|
|
36
|
+
if (!blocks?.length)
|
|
37
|
+
return null;
|
|
38
|
+
if (blocks.length === 1)
|
|
39
|
+
return jsonLd(blocks[0]);
|
|
40
|
+
return { "@context": "https://schema.org", "@graph": blocks.map((b) => ({ "@type": b.template, ...b.fields })) };
|
|
41
|
+
};
|
|
42
|
+
/** Starter fields per template, for editors. */
|
|
43
|
+
export const STRUCTURED_DATA_STARTERS = {
|
|
44
|
+
Article: { headline: "", description: "", image: "", datePublished: "", author: { "@type": "Organization", name: "" } },
|
|
45
|
+
Product: { name: "", description: "", image: "", brand: { "@type": "Brand", name: "" }, offers: { "@type": "Offer", price: "", priceCurrency: "VND", availability: "https://schema.org/InStock" } },
|
|
46
|
+
Offer: { name: "", price: "", priceCurrency: "VND", availability: "https://schema.org/InStock", url: "" },
|
|
47
|
+
FAQPage: { mainEntity: [{ "@type": "Question", name: "", acceptedAnswer: { "@type": "Answer", text: "" } }] },
|
|
48
|
+
BreadcrumbList: { itemListElement: [{ "@type": "ListItem", position: 1, name: "", item: "" }] },
|
|
49
|
+
Organization: { name: "", url: "", logo: "", sameAs: [] },
|
|
50
|
+
Event: { name: "", startDate: "", endDate: "", location: { "@type": "Place", name: "", address: "" }, image: "", description: "" },
|
|
51
|
+
};
|
|
52
|
+
/** Page-level SEO at `root.props.seo`. `null` means "inherit from site defaults". */
|
|
53
|
+
export const PageSeoSchema = z
|
|
54
|
+
.object({
|
|
55
|
+
slug: z.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "slug must be lowercase kebab-case"),
|
|
56
|
+
title: z.string().min(1).max(120),
|
|
57
|
+
description: z.string().max(320).nullable().optional(),
|
|
58
|
+
canonical: z.string().url().nullable().optional(),
|
|
59
|
+
robots: RobotsSchema.nullable().optional(),
|
|
60
|
+
og: z
|
|
61
|
+
.object({
|
|
62
|
+
title: z.string().nullable().optional(),
|
|
63
|
+
description: z.string().nullable().optional(),
|
|
64
|
+
image: z.union([SeoImageSchema, AssetRefSchema]).nullable().optional(),
|
|
65
|
+
})
|
|
66
|
+
.strict()
|
|
67
|
+
.optional(),
|
|
68
|
+
structuredData: z.array(StructuredDataSchema).max(10).optional(),
|
|
69
|
+
})
|
|
70
|
+
.strict();
|
|
71
|
+
//# sourceMappingURL=seo.js.map
|
package/dist/seo.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seo.js","sourceRoot":"","sources":["../src/seo.ts"],"names":[],"mappings":"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"}
|