@marktiderman/genesis-sites 0.1.0 → 0.3.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/README.md +241 -13
- package/dist/assets/islands.77d11f5697.js +1 -0
- package/dist/assets/sites-forms.732cc7e0c1.css +10 -0
- package/dist/assets/sites-forms.css +1 -1
- package/dist/assets/sites.716b4ac1a5.css +2 -0
- package/dist/assets/sites.css +1 -1
- package/dist/assets.generated-QSB7EJWX.js +3 -0
- package/dist/assets.generated-QSB7EJWX.js.map +1 -0
- package/dist/blocks.d.ts +1 -1
- package/dist/blocks.js +5 -1
- package/dist/blocks.js.map +1 -1
- package/dist/chunk-3VKTBE7S.js +69 -0
- package/dist/chunk-3VKTBE7S.js.map +1 -0
- package/dist/chunk-5IXDFFEG.js +465 -0
- package/dist/chunk-5IXDFFEG.js.map +1 -0
- package/dist/chunk-C375ZPU2.js +2241 -0
- package/dist/chunk-C375ZPU2.js.map +1 -0
- package/dist/{chunk-GA7U3CIN.js → chunk-FBQF2L7O.js} +317 -97
- package/dist/chunk-FBQF2L7O.js.map +1 -0
- package/dist/chunk-H6ED3K4R.js +18 -0
- package/dist/chunk-H6ED3K4R.js.map +1 -0
- package/dist/chunk-KPOX7D4S.js +250 -0
- package/dist/chunk-KPOX7D4S.js.map +1 -0
- package/dist/chunk-VZUDRPFG.js +13 -0
- package/dist/chunk-VZUDRPFG.js.map +1 -0
- package/dist/{chunk-KEF3V5ZN.js → chunk-ZGWGQGT2.js} +169 -73
- package/dist/chunk-ZGWGQGT2.js.map +1 -0
- package/dist/editor.d.ts +526 -0
- package/dist/editor.js +2480 -0
- package/dist/editor.js.map +1 -0
- package/dist/handler-QHH453YG.js +9 -0
- package/dist/handler-QHH453YG.js.map +1 -0
- package/dist/import.d.ts +130 -0
- package/dist/import.js +330 -0
- package/dist/import.js.map +1 -0
- package/dist/index.d.ts +47 -8
- package/dist/index.js +5 -250
- package/dist/index.js.map +1 -1
- package/dist/{registry-CdgVymsu.d.ts → registry-HBn1X60x.d.ts} +274 -8
- package/dist/sections.d.ts +422 -6
- package/dist/sections.js +4 -2
- package/dist/{store-BzGw2i5J.d.ts → store-BXiZeZzH.d.ts} +119 -53
- package/dist/supabase.d.ts +5 -5
- package/dist/supabase.js +115 -6
- package/dist/supabase.js.map +1 -1
- package/dist/web.d.ts +26 -8
- package/dist/web.js +7 -353
- package/dist/web.js.map +1 -1
- package/migrations/0001_genesis_sites.sql +64 -6
- package/migrations/0002_genesis_sites_posts.sql +404 -0
- package/migrations/tests/0001_genesis_sites.test.sql +30 -1
- package/migrations/tests/0002_genesis_sites_posts.test.sql +242 -0
- package/package.json +28 -10
- package/dist/assets/islands.230b20b9c4.js +0 -1
- package/dist/assets/sites-forms.5e6ebf31c3.css +0 -10
- package/dist/assets/sites.b28b796c6f.css +0 -2
- package/dist/chunk-43XUAO63.js +0 -1255
- package/dist/chunk-43XUAO63.js.map +0 -1
- package/dist/chunk-GA7U3CIN.js.map +0 -1
- package/dist/chunk-KEF3V5ZN.js.map +0 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export { B as BUILT_IN_SECTION_TYPES,
|
|
3
|
-
import {
|
|
4
|
-
export { A as Asset, a as AssetMeta,
|
|
1
|
+
import { f as SectionNode, a as PageDoc, A as AnySectionDefinition, g as SiteDoc, h as ReleasePage, i as PostSummary, L as LivePost, j as Redirect, k as Link, l as SiteDocInput, P as PageKind } from './registry-HBn1X60x.js';
|
|
2
|
+
export { B as BUILT_IN_SECTION_TYPES, m as BuiltInSectionType, C as Copy, n as FileRef, o as FontChoice, F as FormsResolver, p as FormsResolverContext, H as Href, I as Image, q as ImportPost, r as ImportPostsResult, s as Line, t as LinkEvent, M as MAX_DOC_BYTES, u as MAX_IMPORT_POSTS, v as MAX_LIVE_POSTS, w as MenuItem, b as PageMeta, x as PagePath, y as PostAuthor, z as PostDoc, D as PostDocInput, E as PostDraft, G as PostMeta, J as PostSlug, K as PostStatus, N as PostSummarySchema, O as PostsContext, Q as RegisterSectionOptions, R as Release, T as ReleaseMeta, U as ReleaseSnapshot, c as RenderContext, d as ResolvedForm, V as RichText, W as SECTION_CATEGORIES, X as SavePostInput, Y as SavePostResult, S as SectionCategory, Z as SectionDefinition, _ as SectionDefinitionError, $ as SectionId, a0 as SectionManifest, a1 as SectionPlacement, a2 as SectionPreset, a3 as SectionRenderProps, a4 as SectionVariant, e as Seo, a5 as SeoDefaults, a6 as Surface, a7 as TokenOverrides, a8 as defineSection, a9 as getSection, aa as isPlainEmail, ab as listSections, ac as mailtoHref, ad as newSectionId, ae as nodeFromPreset, af as opensInNewTab, ag as parseSnapshot, ah as postSummary, ai as registerBuiltInSection, aj as registerSection, ak as richTextPlain, al as sectionJsonSchema, am as sectionManifests, an as unregisterSection, ao as validatePostSlug } from './registry-HBn1X60x.js';
|
|
3
|
+
import { d as SiteBrand, B as BrandInput } from './store-BXiZeZzH.js';
|
|
4
|
+
export { e as ASSET_TYPES, A as Asset, a as AssetMeta, f as BrandSource, C as CheckReleaseOptions, D as DEFAULT_RESERVED_PATHS, F as FONT_CHOICES, g as FontInfo, I as InvalidationInfo, M as MAX_PAGE_PATH_LENGTH, h as MAX_URL_LENGTH, i as MemorySiteStore, j as MemoryStoreOptions, N as NewPage, k as NewSite, l as PAGE_PATH, m as PageDraft, n as PreparedRelease, o as PublishBlockedError, P as PublishOptions, R as ReservedPaths, c as SaveResult, p as SiteConflictError, q as SiteDraft, b as SiteIssue, S as SiteStore, r as SiteTheme, T as ThemePair, s as assetPath, t as brandDisplayName, u as checkBlog, v as checkContrast, w as checkHtmlOutline, x as checkPage, y as checkPost, z as checkRelease, E as checkSiteDoc, G as contrastRatio, H as createMemorySiteStore, J as formCacheTag, K as hexToHslTriplet, L as isConflict, O as isExternalHref, Q as isPublishable, U as isReservedPath, V as isSafeHref, W as isSafeImageSrc, X as isSiteBrand, Y as luminance, Z as mix, _ as normalizeRequestPath, $ as pagePathProblems, a0 as parseHex, a1 as prepareImportPost, a2 as prepareRelease, a3 as siteCacheTag, a4 as siteTheme, a5 as stableHash, a6 as themeCss, a7 as toCanonicalBrand, a8 as validatePagePath, a9 as withCacheInvalidation } from './store-BXiZeZzH.js';
|
|
5
5
|
import 'react';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import '@marktiderman/genesis-design-system';
|
|
@@ -27,14 +27,20 @@ interface MigratedNode {
|
|
|
27
27
|
node: (SectionNode & {
|
|
28
28
|
variant: string;
|
|
29
29
|
}) | null;
|
|
30
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Whether the stored node needs re-saving: its version or variant moved, or a
|
|
32
|
+
* migration step changed its props. Parsing alone is no change: zod's key
|
|
33
|
+
* order, its defaults and the keys it strips make the same section.
|
|
34
|
+
*/
|
|
31
35
|
changed: boolean;
|
|
32
36
|
issues: MigrationIssue[];
|
|
33
37
|
}
|
|
34
38
|
/** Bring one node up to its section's current version and check its props. */
|
|
35
39
|
declare function migrateNode(node: SectionNode, lookup?: (type: string) => AnySectionDefinition | undefined): MigratedNode;
|
|
36
40
|
interface MigratedPage {
|
|
41
|
+
/** The page with every node that can be shown parsed (what a release holds). */
|
|
37
42
|
doc: PageDoc;
|
|
43
|
+
/** Whether the draft needs re-saving (see `MigratedNode.changed`). */
|
|
38
44
|
changed: boolean;
|
|
39
45
|
issues: MigrationIssue[];
|
|
40
46
|
}
|
|
@@ -67,6 +73,13 @@ interface PageMetaInput {
|
|
|
67
73
|
basePath?: string;
|
|
68
74
|
/** A preview: always `noindex`. */
|
|
69
75
|
preview?: boolean;
|
|
76
|
+
/** The page is a blog post: Open Graph says `article`, with its dates. */
|
|
77
|
+
article?: {
|
|
78
|
+
publishedTime: string;
|
|
79
|
+
modifiedTime?: string;
|
|
80
|
+
author?: string;
|
|
81
|
+
section?: string;
|
|
82
|
+
};
|
|
70
83
|
}
|
|
71
84
|
interface PageMeta {
|
|
72
85
|
title: string;
|
|
@@ -85,11 +98,32 @@ declare function absoluteUrl(origin: string, basePath: string, path: string): st
|
|
|
85
98
|
*/
|
|
86
99
|
declare function pageTitle(site: SiteDoc, doc: PageDoc, _path: string): string;
|
|
87
100
|
/** Every meta value a page prints in its `<head>`. */
|
|
88
|
-
declare function pageMeta({ site, page, origin, basePath, preview }: PageMetaInput): PageMeta;
|
|
101
|
+
declare function pageMeta({ site, page, origin, basePath, preview, article }: PageMetaInput): PageMeta;
|
|
89
102
|
declare function organizationJsonLd(site: SiteDoc, origin: string, basePath?: string): Record<string, unknown>;
|
|
90
103
|
declare function websiteJsonLd(site: SiteDoc, origin: string, basePath?: string): Record<string, unknown>;
|
|
91
104
|
/** The trail from the home page to `page`, through every ancestor path that is a page. */
|
|
92
105
|
declare function breadcrumbJsonLd(pages: readonly ReleasePage[], page: ReleasePage, origin: string, basePath?: string): Record<string, unknown> | null;
|
|
106
|
+
/** The URL of a post: `<post page path>/<slug>`. */
|
|
107
|
+
declare function postPath(postsPath: string, slug: string): string;
|
|
108
|
+
/** `Article` JSON-LD for a blog post. */
|
|
109
|
+
declare function articleJsonLd(site: SiteDoc, post: LivePost, url: string, origin: string, basePath?: string): Record<string, unknown>;
|
|
110
|
+
interface RssInput {
|
|
111
|
+
site: SiteDoc;
|
|
112
|
+
/** Published posts, newest first. */
|
|
113
|
+
posts: readonly PostSummary[];
|
|
114
|
+
/** The post page's path (`/blog`). */
|
|
115
|
+
postsPath: string;
|
|
116
|
+
/** Its title, the feed's (default: the site's name). */
|
|
117
|
+
title?: string;
|
|
118
|
+
origin: string;
|
|
119
|
+
basePath?: string;
|
|
120
|
+
/** The most items (default 20). */
|
|
121
|
+
limit?: number;
|
|
122
|
+
}
|
|
123
|
+
/** The blog's RSS 2.0 feed: the newest posts, with their excerpts. */
|
|
124
|
+
declare function rssXml({ site, posts, postsPath, title, origin, basePath, limit }: RssInput): string;
|
|
125
|
+
/** A post's description for a feed or a page with no excerpt: its first words. */
|
|
126
|
+
declare const postDescription: (doc: LivePost["doc"]) => string | undefined;
|
|
93
127
|
/**
|
|
94
128
|
* JSON for a `<script type="application/ld+json">` (or any JSON inside HTML):
|
|
95
129
|
* `<`, `>`, `&` and the line separators are escaped as `\uXXXX`, so stored
|
|
@@ -104,9 +138,14 @@ interface SitemapInput {
|
|
|
104
138
|
basePath?: string;
|
|
105
139
|
/** The release's publish time, as every page's `lastmod`. */
|
|
106
140
|
lastModified?: string | null;
|
|
141
|
+
/** The blog: its post page's path and the published posts (each with its own `lastmod`). */
|
|
142
|
+
posts?: {
|
|
143
|
+
path: string;
|
|
144
|
+
items: readonly PostSummary[];
|
|
145
|
+
};
|
|
107
146
|
}
|
|
108
147
|
/** sitemap.xml: every indexable page (not `noindex`, not one whose canonical points elsewhere). */
|
|
109
|
-
declare function sitemapXml({ site, pages, origin, basePath, lastModified }: SitemapInput): string;
|
|
148
|
+
declare function sitemapXml({ site, pages, origin, basePath, lastModified, posts }: SitemapInput): string;
|
|
110
149
|
interface RobotsInput {
|
|
111
150
|
origin: string;
|
|
112
151
|
basePath?: string;
|
|
@@ -237,4 +276,4 @@ declare const exampleBrands: Readonly<{
|
|
|
237
276
|
};
|
|
238
277
|
}>;
|
|
239
278
|
|
|
240
|
-
export { AnySectionDefinition, BrandInput, Link, type MigratedNode, type MigratedPage, type MigrationIssue, type OnePageSiteInput, PageDoc, PageKind, type PageMetaInput, Redirect, ReleasePage, type RobotsInput, SectionNode, type PageMeta as SeoPageMeta, SiteBrand, SiteDoc, SiteDocInput, type SitemapInput, type TemplateInput, type TemplateMessage, type TemplateResult, absoluteUrl, breadcrumbJsonLd, escapeXml, exampleBrands, landingPage, matchRedirect, migrateNode, migratePage, migrateSite, onePageSite, organizationJsonLd, pageMeta, pageTitle, redirectsAfterMove, robotsTxt, safeJsonForHtml, sitemapXml, starterSite, websiteJsonLd };
|
|
279
|
+
export { AnySectionDefinition, BrandInput, Link, LivePost, type MigratedNode, type MigratedPage, type MigrationIssue, type OnePageSiteInput, PageDoc, PageKind, type PageMetaInput, PostSummary, Redirect, ReleasePage, type RobotsInput, type RssInput, SectionNode, type PageMeta as SeoPageMeta, SiteBrand, SiteDoc, SiteDocInput, type SitemapInput, type TemplateInput, type TemplateMessage, type TemplateResult, absoluteUrl, articleJsonLd, breadcrumbJsonLd, escapeXml, exampleBrands, landingPage, matchRedirect, migrateNode, migratePage, migrateSite, onePageSite, organizationJsonLd, pageMeta, pageTitle, postDescription, postPath, redirectsAfterMove, robotsTxt, rssXml, safeJsonForHtml, sitemapXml, starterSite, websiteJsonLd };
|
package/dist/index.js
CHANGED
|
@@ -1,252 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
export {
|
|
3
|
-
export {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
var year = () => (/* @__PURE__ */ new Date()).getUTCFullYear();
|
|
7
|
-
function node(id, type, variant, props, extra = {}) {
|
|
8
|
-
return { id, type, v: 1, variant, props, ...extra };
|
|
9
|
-
}
|
|
10
|
-
function footerNode(name, contact, variant = "simple") {
|
|
11
|
-
const links = [];
|
|
12
|
-
if (contact?.email) links.push({ label: contact.email, href: `mailto:${contact.email}` });
|
|
13
|
-
if (contact?.phone) links.push({ label: contact.phone, href: `tel:${contact.phone.replace(/[^+\d]/g, "")}` });
|
|
14
|
-
return node("footer", "footer", variant, {
|
|
15
|
-
...links.length ? { links } : {},
|
|
16
|
-
copyright: `\xA9 ${year()} ${name}`
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
function seo(name, message) {
|
|
20
|
-
return {
|
|
21
|
-
titleTemplate: `%s \xB7 ${name}`,
|
|
22
|
-
...message.subhead ? { description: message.subhead.slice(0, 200) } : {},
|
|
23
|
-
organization: { name }
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
function primaryCta(input) {
|
|
27
|
-
return input.message.cta ?? { label: "Get in touch", href: "#contact" };
|
|
28
|
-
}
|
|
29
|
-
function benefitsNode(message) {
|
|
30
|
-
if (message.benefits?.length) {
|
|
31
|
-
return node("features", "features", "grid", {
|
|
32
|
-
heading: "What you get",
|
|
33
|
-
items: message.benefits.slice(0, 12).map((b, i) => ({ title: b.title, body: b.body, icon: ["check", "star", "heart", "zap", "shield", "clock"][i % 6] }))
|
|
34
|
-
});
|
|
35
|
-
}
|
|
36
|
-
return node(
|
|
37
|
-
"features",
|
|
38
|
-
"features",
|
|
39
|
-
"grid",
|
|
40
|
-
{
|
|
41
|
-
heading: "What you get",
|
|
42
|
-
items: [
|
|
43
|
-
{ title: "Your first offer", body: "Say what someone gets and why it matters to them.", icon: "check" },
|
|
44
|
-
{ title: "Your second offer", body: "Keep each one to a sentence or two.", icon: "star" },
|
|
45
|
-
{ title: "Your third offer", body: "Three is plenty for a landing page.", icon: "heart" }
|
|
46
|
-
]
|
|
47
|
-
},
|
|
48
|
-
{ placeholder: true }
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
var testimonialsNode = () => node(
|
|
52
|
-
"testimonials",
|
|
53
|
-
"testimonials",
|
|
54
|
-
"grid",
|
|
55
|
-
{
|
|
56
|
-
heading: "What people say",
|
|
57
|
-
items: [
|
|
58
|
-
{ quote: "Add a quote from someone you have helped, in their words and with their permission.", name: "Their name", role: "What they did with you" },
|
|
59
|
-
{ quote: "A second quote, from someone different.", name: "Their name" }
|
|
60
|
-
]
|
|
61
|
-
},
|
|
62
|
-
{ placeholder: true }
|
|
63
|
-
);
|
|
64
|
-
function formNode(input) {
|
|
65
|
-
if (!input.form) return null;
|
|
66
|
-
return node("contact", "form-embed", "split", {
|
|
67
|
-
heading: input.form.heading ?? "Get in touch",
|
|
68
|
-
...input.form.body ? { body: input.form.body } : { body: "Tell us a little about yourself and we'll get back to you." },
|
|
69
|
-
form: input.form.slug,
|
|
70
|
-
anchor: "contact"
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
function landingPage(input) {
|
|
74
|
-
const name = brandDisplayName(input.brand);
|
|
75
|
-
const cta = primaryCta(input);
|
|
76
|
-
const form = formNode(input);
|
|
77
|
-
const content = [
|
|
78
|
-
node("hero", "hero", "centered", {
|
|
79
|
-
heading: input.message.headline,
|
|
80
|
-
...input.message.subhead ? { body: input.message.subhead } : {},
|
|
81
|
-
primaryCta: cta
|
|
82
|
-
}),
|
|
83
|
-
benefitsNode(input.message),
|
|
84
|
-
testimonialsNode(),
|
|
85
|
-
node("cta", "cta", "banner", { heading: "Ready when you are", primaryCta: cta, surface: "accent" })
|
|
86
|
-
];
|
|
87
|
-
if (form) content.push(form);
|
|
88
|
-
return {
|
|
89
|
-
site: {
|
|
90
|
-
schemaVersion: 1,
|
|
91
|
-
name,
|
|
92
|
-
header: [node("nav", "nav", "minimal", { cta })],
|
|
93
|
-
nav: [],
|
|
94
|
-
footer: [footerNode(name, input.contact, "minimal")],
|
|
95
|
-
seo: seo(name, input.message)
|
|
96
|
-
},
|
|
97
|
-
pages: [{ path: "/", kind: "landing", doc: { schemaVersion: 1, root: { props: { title: input.message.headline.slice(0, 120) } }, content, seo: input.message.subhead ? { description: input.message.subhead.slice(0, 200) } : void 0 } }]
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
function onePageSite(input) {
|
|
101
|
-
const brand = { name: input.name, colors: input.colors, ...input.fonts ? { fonts: input.fonts } : {}, ...input.logo ? { logo: input.logo } : {} };
|
|
102
|
-
const cta = input.message.cta ?? (input.contact?.email ? { label: "Email us", href: `mailto:${input.contact.email}` } : { label: "Get in touch", href: "#contact" });
|
|
103
|
-
return {
|
|
104
|
-
brand,
|
|
105
|
-
site: {
|
|
106
|
-
schemaVersion: 1,
|
|
107
|
-
name: input.name,
|
|
108
|
-
header: [node("nav", "nav", "minimal", { cta })],
|
|
109
|
-
nav: [],
|
|
110
|
-
footer: [footerNode(input.name, input.contact)],
|
|
111
|
-
seo: seo(input.name, input.message)
|
|
112
|
-
},
|
|
113
|
-
pages: [
|
|
114
|
-
{
|
|
115
|
-
path: "/",
|
|
116
|
-
kind: "page",
|
|
117
|
-
doc: {
|
|
118
|
-
schemaVersion: 1,
|
|
119
|
-
root: { props: { title: input.message.headline.slice(0, 120) } },
|
|
120
|
-
content: [
|
|
121
|
-
node("hero", "hero", "centered", {
|
|
122
|
-
heading: input.message.headline,
|
|
123
|
-
...input.message.subhead ? { body: input.message.subhead } : {},
|
|
124
|
-
primaryCta: cta
|
|
125
|
-
}),
|
|
126
|
-
node("contact", "cta", "card", { heading: `Talk to ${input.name}`, primaryCta: cta, anchor: "contact" })
|
|
127
|
-
],
|
|
128
|
-
...input.message.subhead ? { seo: { description: input.message.subhead.slice(0, 200) } } : {}
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
]
|
|
132
|
-
};
|
|
133
|
-
}
|
|
134
|
-
function starterSite(input) {
|
|
135
|
-
const name = brandDisplayName(input.brand);
|
|
136
|
-
const cta = input.message.cta ?? { label: "Contact us", href: "/contact" };
|
|
137
|
-
const form = formNode(input);
|
|
138
|
-
const page = (title, content, description) => ({
|
|
139
|
-
schemaVersion: 1,
|
|
140
|
-
root: { props: { title } },
|
|
141
|
-
content,
|
|
142
|
-
...description ? { seo: { description } } : {}
|
|
143
|
-
});
|
|
144
|
-
return {
|
|
145
|
-
site: {
|
|
146
|
-
schemaVersion: 1,
|
|
147
|
-
name,
|
|
148
|
-
header: [node("nav", "nav", "simple", { cta })],
|
|
149
|
-
nav: [
|
|
150
|
-
{ label: "Home", href: "/" },
|
|
151
|
-
{ label: "About", href: "/about" },
|
|
152
|
-
{ label: "Contact", href: "/contact" }
|
|
153
|
-
],
|
|
154
|
-
footer: [
|
|
155
|
-
node("footer", "footer", "columns", {
|
|
156
|
-
tagline: input.message.subhead?.slice(0, 200),
|
|
157
|
-
columns: [
|
|
158
|
-
{ heading: name, links: [{ label: "About", href: "/about" }, { label: "Contact", href: "/contact" }] },
|
|
159
|
-
...input.contact?.email || input.contact?.phone ? [
|
|
160
|
-
{
|
|
161
|
-
heading: "Get in touch",
|
|
162
|
-
links: [
|
|
163
|
-
...input.contact.email ? [{ label: input.contact.email, href: `mailto:${input.contact.email}` }] : [],
|
|
164
|
-
...input.contact.phone ? [{ label: input.contact.phone, href: `tel:${input.contact.phone.replace(/[^+\d]/g, "")}` }] : []
|
|
165
|
-
]
|
|
166
|
-
}
|
|
167
|
-
] : []
|
|
168
|
-
],
|
|
169
|
-
copyright: `\xA9 ${year()} ${name}`
|
|
170
|
-
})
|
|
171
|
-
],
|
|
172
|
-
seo: seo(name, input.message)
|
|
173
|
-
},
|
|
174
|
-
pages: [
|
|
175
|
-
{
|
|
176
|
-
path: "/",
|
|
177
|
-
kind: "page",
|
|
178
|
-
doc: page(
|
|
179
|
-
"Home",
|
|
180
|
-
[
|
|
181
|
-
node("hero", "hero", "split", {
|
|
182
|
-
heading: input.message.headline,
|
|
183
|
-
...input.message.subhead ? { body: input.message.subhead } : {},
|
|
184
|
-
primaryCta: cta,
|
|
185
|
-
secondaryCta: { label: "About us", href: "/about" }
|
|
186
|
-
}),
|
|
187
|
-
benefitsNode(input.message),
|
|
188
|
-
testimonialsNode(),
|
|
189
|
-
node("cta", "cta", "banner", { heading: "Come and see for yourself", primaryCta: cta, surface: "accent" })
|
|
190
|
-
],
|
|
191
|
-
input.message.subhead?.slice(0, 200)
|
|
192
|
-
)
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
path: "/about",
|
|
196
|
-
kind: "page",
|
|
197
|
-
doc: page(
|
|
198
|
-
"About",
|
|
199
|
-
[
|
|
200
|
-
node("hero", "hero", "centered", { eyebrow: "About", heading: `About ${name}` }),
|
|
201
|
-
node(
|
|
202
|
-
"story",
|
|
203
|
-
"rich-text",
|
|
204
|
-
"narrow",
|
|
205
|
-
{
|
|
206
|
-
body: {
|
|
207
|
-
type: "doc",
|
|
208
|
-
content: [
|
|
209
|
-
{ type: "heading", attrs: { level: 2 }, content: [{ type: "text", text: "Our story" }] },
|
|
210
|
-
{ type: "paragraph", content: [{ type: "text", text: "Tell people how you started, who you help and what you believe." }] }
|
|
211
|
-
]
|
|
212
|
-
}
|
|
213
|
-
},
|
|
214
|
-
{ placeholder: true }
|
|
215
|
-
)
|
|
216
|
-
],
|
|
217
|
-
`About ${name}.`
|
|
218
|
-
)
|
|
219
|
-
},
|
|
220
|
-
{
|
|
221
|
-
path: "/contact",
|
|
222
|
-
kind: "page",
|
|
223
|
-
doc: page(
|
|
224
|
-
"Contact",
|
|
225
|
-
[
|
|
226
|
-
node("hero", "hero", "centered", { eyebrow: "Contact", heading: "Get in touch", ...input.message.subhead ? { body: input.message.subhead } : {} }),
|
|
227
|
-
...form ? [form] : [node("contact", "cta", "card", { heading: `Talk to ${name}`, primaryCta: input.contact?.email ? { label: "Email us", href: `mailto:${input.contact.email}` } : cta })]
|
|
228
|
-
],
|
|
229
|
-
`How to reach ${name}.`
|
|
230
|
-
)
|
|
231
|
-
}
|
|
232
|
-
]
|
|
233
|
-
};
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
// src/core/examples.ts
|
|
237
|
-
var exampleBrands = Object.freeze({
|
|
238
|
-
riverside: {
|
|
239
|
-
name: "Riverside Gym",
|
|
240
|
-
colors: { primary: "#0f766e", primaryDark: "#2dd4bf" },
|
|
241
|
-
fonts: { heading: "space-grotesk", body: "inter" }
|
|
242
|
-
},
|
|
243
|
-
hilltop: {
|
|
244
|
-
name: "Hilltop Fitness",
|
|
245
|
-
colors: { primary: "#b45309", primaryDark: "#fbbf24" },
|
|
246
|
-
fonts: { heading: "playfair-display", body: "work-sans" }
|
|
247
|
-
}
|
|
248
|
-
});
|
|
249
|
-
|
|
250
|
-
export { exampleBrands, landingPage, onePageSite, starterSite };
|
|
1
|
+
export { exampleBrands, landingPage, onePageSite, starterSite } from './chunk-KPOX7D4S.js';
|
|
2
|
+
export { isPlainEmail, mailtoHref } from './chunk-VZUDRPFG.js';
|
|
3
|
+
export { ASSET_TYPES, FONT_CHOICES, PublishBlockedError, SiteConflictError, assetPath, brandDisplayName, checkBlog, checkContrast, checkHtmlOutline, checkPage, checkPost, checkRelease, checkSiteDoc, contrastRatio, createMemorySiteStore, formCacheTag, hexToHslTriplet, isConflict, isPublishable, isSiteBrand, luminance, migrateNode, migratePage, migrateSite, mix, parseHex, prepareImportPost, prepareRelease, siteCacheTag, siteTheme, stableHash, themeCss, toCanonicalBrand, withCacheInvalidation } from './chunk-FBQF2L7O.js';
|
|
4
|
+
export { BUILT_IN_SECTION_TYPES, Copy, FileRef, FontChoice, Href, Image, Line, Link, LinkEvent, MAX_DOC_BYTES, MAX_IMPORT_POSTS, MAX_LIVE_POSTS, MenuItem, PageDoc, PageKind, PagePath, PostAuthor, PostDoc, PostSlug, PostSummarySchema, Redirect, ReleasePage, ReleaseSnapshot, RichText, SECTION_CATEGORIES, SectionDefinitionError, SectionId, SectionNode, Seo, SeoDefaults, SiteDoc, Surface, TokenOverrides, absoluteUrl, articleJsonLd, breadcrumbJsonLd, defineSection, escapeXml, getSection, listSections, matchRedirect, newSectionId, nodeFromPreset, opensInNewTab, organizationJsonLd, pageMeta, pageTitle, parseSnapshot, postDescription, postPath, postSummary, redirectsAfterMove, registerBuiltInSection, registerSection, richTextPlain, robotsTxt, rssXml, safeJsonForHtml, sectionJsonSchema, sectionManifests, sitemapXml, unregisterSection, validatePostSlug, websiteJsonLd } from './chunk-ZGWGQGT2.js';
|
|
5
|
+
export { DEFAULT_RESERVED_PATHS, MAX_PAGE_PATH_LENGTH, MAX_URL_LENGTH, PAGE_PATH, isExternalHref, isReservedPath, isSafeHref, isSafeImageSrc, normalizeRequestPath, pagePathProblems, validatePagePath } from './chunk-3VKTBE7S.js';
|
|
251
6
|
//# sourceMappingURL=index.js.map
|
|
252
7
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/templates.ts","../src/core/examples.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Templates: whole sites from a little input.\n *\n * - `landingPage`: the one-click landing page from a brand and a message.\n * Nav, hero, features, testimonials, a call to action, a form embed and a\n * footer, on one page.\n * - `onePageSite`: the smallest site a brand with no site can be seeded\n * with: just a name, a logo, a message, and the brand's colours and fonts.\n * - `starterSite`: three pages (home, about, contact) with nav and footer.\n *\n * Each returns documents (`site`, `pages`) for any `SiteStore` to create.\n * Nothing is invented and passed off as real: copy a template can't know\n * (a client's quote, a statistic) is marked `placeholder`, and the publish\n * check refuses it until someone replaces it or hides the section.\n */\nimport type { Link, PageDoc, PageKind, SectionNode, SiteDocInput } from \"./schemas\";\nimport { brandDisplayName, type BrandInput, type SiteBrand } from \"./theme\";\n\nexport interface TemplateMessage {\n /** The hero's headline: what you do, for whom. */\n headline: string;\n /** One or two sentences under it. */\n subhead?: string;\n /** The main button. Default: \"Get in touch\", to the form (or `#contact`). */\n cta?: Link;\n /** What you offer, as the features band. Without it the band is a placeholder to fill in. */\n benefits?: { title: string; body: string }[];\n}\n\nexport interface TemplateInput {\n brand: BrandInput;\n message: TemplateMessage;\n /** A form to embed (its slug, for the host's forms resolver). */\n form?: { slug: string; heading?: string; body?: string };\n /** For the footer. */\n contact?: { email?: string; phone?: string };\n}\n\nexport interface TemplateResult {\n site: SiteDocInput;\n pages: { path: string; kind: PageKind; doc: PageDoc }[];\n}\n\nconst year = () => new Date().getUTCFullYear();\n\nfunction node(id: string, type: string, variant: string, props: Record<string, unknown>, extra: Partial<SectionNode> = {}): SectionNode {\n return { id, type, v: 1, variant, props, ...extra };\n}\n\nfunction footerNode(name: string, contact: TemplateInput[\"contact\"], variant = \"simple\"): SectionNode {\n const links: Link[] = [];\n if (contact?.email) links.push({ label: contact.email, href: `mailto:${contact.email}` });\n if (contact?.phone) links.push({ label: contact.phone, href: `tel:${contact.phone.replace(/[^+\\d]/g, \"\")}` });\n return node(\"footer\", \"footer\", variant, {\n ...(links.length ? { links } : {}),\n copyright: `© ${year()} ${name}`,\n });\n}\n\nfunction seo(name: string, message: TemplateMessage) {\n return {\n titleTemplate: `%s · ${name}`,\n ...(message.subhead ? { description: message.subhead.slice(0, 200) } : {}),\n organization: { name },\n };\n}\n\nfunction primaryCta(input: TemplateInput): Link {\n return input.message.cta ?? { label: \"Get in touch\", href: \"#contact\" };\n}\n\nfunction benefitsNode(message: TemplateMessage): SectionNode {\n if (message.benefits?.length) {\n return node(\"features\", \"features\", \"grid\", {\n heading: \"What you get\",\n items: message.benefits.slice(0, 12).map((b, i) => ({ title: b.title, body: b.body, icon: ([\"check\", \"star\", \"heart\", \"zap\", \"shield\", \"clock\"] as const)[i % 6] })),\n });\n }\n return node(\n \"features\",\n \"features\",\n \"grid\",\n {\n heading: \"What you get\",\n items: [\n { title: \"Your first offer\", body: \"Say what someone gets and why it matters to them.\", icon: \"check\" },\n { title: \"Your second offer\", body: \"Keep each one to a sentence or two.\", icon: \"star\" },\n { title: \"Your third offer\", body: \"Three is plenty for a landing page.\", icon: \"heart\" },\n ],\n },\n { placeholder: true },\n );\n}\n\nconst testimonialsNode = () =>\n node(\n \"testimonials\",\n \"testimonials\",\n \"grid\",\n {\n heading: \"What people say\",\n items: [\n { quote: \"Add a quote from someone you have helped, in their words and with their permission.\", name: \"Their name\", role: \"What they did with you\" },\n { quote: \"A second quote, from someone different.\", name: \"Their name\" },\n ],\n },\n { placeholder: true },\n );\n\nfunction formNode(input: TemplateInput): SectionNode | null {\n if (!input.form) return null;\n return node(\"contact\", \"form-embed\", \"split\", {\n heading: input.form.heading ?? \"Get in touch\",\n ...(input.form.body ? { body: input.form.body } : { body: \"Tell us a little about yourself and we'll get back to you.\" }),\n form: input.form.slug,\n anchor: \"contact\",\n });\n}\n\n/**\n * The one-click landing page: brand plus message, on one page.\n *\n * @stability Beta\n */\nexport function landingPage(input: TemplateInput): TemplateResult {\n const name = brandDisplayName(input.brand);\n const cta = primaryCta(input);\n const form = formNode(input);\n const content: SectionNode[] = [\n node(\"hero\", \"hero\", \"centered\", {\n heading: input.message.headline,\n ...(input.message.subhead ? { body: input.message.subhead } : {}),\n primaryCta: cta,\n }),\n benefitsNode(input.message),\n testimonialsNode(),\n node(\"cta\", \"cta\", \"banner\", { heading: \"Ready when you are\", primaryCta: cta, surface: \"accent\" }),\n ];\n if (form) content.push(form);\n return {\n site: {\n schemaVersion: 1,\n name,\n header: [node(\"nav\", \"nav\", \"minimal\", { cta })],\n nav: [],\n footer: [footerNode(name, input.contact, \"minimal\")],\n seo: seo(name, input.message),\n },\n pages: [{ path: \"/\", kind: \"landing\", doc: { schemaVersion: 1, root: { props: { title: input.message.headline.slice(0, 120) } }, content, seo: input.message.subhead ? { description: input.message.subhead.slice(0, 200) } : undefined } }],\n };\n}\n\nexport interface OnePageSiteInput {\n name: string;\n logo?: { src: string; alt?: string };\n message: TemplateMessage;\n /** The brand's colours and fonts. */\n colors: SiteBrand[\"colors\"];\n fonts?: SiteBrand[\"fonts\"];\n contact?: TemplateInput[\"contact\"];\n}\n\n/**\n * The smallest site, for seeding a brand that has none: a header, a hero,\n * a call to action and a footer. `brand` is the minimal brand to store\n * beside it (the host's `BrandSource` returns it).\n *\n * @stability Beta\n */\nexport function onePageSite(input: OnePageSiteInput): TemplateResult & { brand: SiteBrand } {\n const brand: SiteBrand = { name: input.name, colors: input.colors, ...(input.fonts ? { fonts: input.fonts } : {}), ...(input.logo ? { logo: input.logo } : {}) };\n const cta = input.message.cta ?? (input.contact?.email ? { label: \"Email us\", href: `mailto:${input.contact.email}` } : { label: \"Get in touch\", href: \"#contact\" });\n return {\n brand,\n site: {\n schemaVersion: 1,\n name: input.name,\n header: [node(\"nav\", \"nav\", \"minimal\", { cta })],\n nav: [],\n footer: [footerNode(input.name, input.contact)],\n seo: seo(input.name, input.message),\n },\n pages: [\n {\n path: \"/\",\n kind: \"page\",\n doc: {\n schemaVersion: 1,\n root: { props: { title: input.message.headline.slice(0, 120) } },\n content: [\n node(\"hero\", \"hero\", \"centered\", {\n heading: input.message.headline,\n ...(input.message.subhead ? { body: input.message.subhead } : {}),\n primaryCta: cta,\n }),\n node(\"contact\", \"cta\", \"card\", { heading: `Talk to ${input.name}`, primaryCta: cta, anchor: \"contact\" }),\n ],\n ...(input.message.subhead ? { seo: { description: input.message.subhead.slice(0, 200) } } : {}),\n },\n },\n ],\n };\n}\n\n/**\n * A three-page starter site: home, about and contact, with the menu, a\n * footer and redirects-ready paths.\n *\n * @stability Beta\n */\nexport function starterSite(input: TemplateInput): TemplateResult {\n const name = brandDisplayName(input.brand);\n const cta: Link = input.message.cta ?? { label: \"Contact us\", href: \"/contact\" };\n const form = formNode(input);\n const page = (title: string, content: SectionNode[], description?: string): PageDoc => ({\n schemaVersion: 1,\n root: { props: { title } },\n content,\n ...(description ? { seo: { description } } : {}),\n });\n return {\n site: {\n schemaVersion: 1,\n name,\n header: [node(\"nav\", \"nav\", \"simple\", { cta })],\n nav: [\n { label: \"Home\", href: \"/\" },\n { label: \"About\", href: \"/about\" },\n { label: \"Contact\", href: \"/contact\" },\n ],\n footer: [\n node(\"footer\", \"footer\", \"columns\", {\n tagline: input.message.subhead?.slice(0, 200),\n columns: [\n { heading: name, links: [{ label: \"About\", href: \"/about\" }, { label: \"Contact\", href: \"/contact\" }] },\n ...(input.contact?.email || input.contact?.phone\n ? [\n {\n heading: \"Get in touch\",\n links: [\n ...(input.contact.email ? [{ label: input.contact.email, href: `mailto:${input.contact.email}` }] : []),\n ...(input.contact.phone ? [{ label: input.contact.phone, href: `tel:${input.contact.phone.replace(/[^+\\d]/g, \"\")}` }] : []),\n ],\n },\n ]\n : []),\n ],\n copyright: `© ${year()} ${name}`,\n }),\n ],\n seo: seo(name, input.message),\n },\n pages: [\n {\n path: \"/\",\n kind: \"page\",\n doc: page(\n \"Home\",\n [\n node(\"hero\", \"hero\", \"split\", {\n heading: input.message.headline,\n ...(input.message.subhead ? { body: input.message.subhead } : {}),\n primaryCta: cta,\n secondaryCta: { label: \"About us\", href: \"/about\" },\n }),\n benefitsNode(input.message),\n testimonialsNode(),\n node(\"cta\", \"cta\", \"banner\", { heading: \"Come and see for yourself\", primaryCta: cta, surface: \"accent\" }),\n ],\n input.message.subhead?.slice(0, 200),\n ),\n },\n {\n path: \"/about\",\n kind: \"page\",\n doc: page(\n \"About\",\n [\n node(\"hero\", \"hero\", \"centered\", { eyebrow: \"About\", heading: `About ${name}` }),\n node(\n \"story\",\n \"rich-text\",\n \"narrow\",\n {\n body: {\n type: \"doc\",\n content: [\n { type: \"heading\", attrs: { level: 2 }, content: [{ type: \"text\", text: \"Our story\" }] },\n { type: \"paragraph\", content: [{ type: \"text\", text: \"Tell people how you started, who you help and what you believe.\" }] },\n ],\n },\n },\n { placeholder: true },\n ),\n ],\n `About ${name}.`,\n ),\n },\n {\n path: \"/contact\",\n kind: \"page\",\n doc: page(\n \"Contact\",\n [\n node(\"hero\", \"hero\", \"centered\", { eyebrow: \"Contact\", heading: \"Get in touch\", ...(input.message.subhead ? { body: input.message.subhead } : {}) }),\n ...(form ? [form] : [node(\"contact\", \"cta\", \"card\", { heading: `Talk to ${name}`, primaryCta: input.contact?.email ? { label: \"Email us\", href: `mailto:${input.contact.email}` } : cta })]),\n ],\n `How to reach ${name}.`,\n ),\n },\n ],\n };\n}\n","/**\n * Made-up brands for demos, tests and docs. They are not anyone's real\n * business.\n */\nimport type { SiteBrand } from \"./theme\";\n\nexport const exampleBrands = Object.freeze({\n riverside: {\n name: \"Riverside Gym\",\n colors: { primary: \"#0f766e\", primaryDark: \"#2dd4bf\" },\n fonts: { heading: \"space-grotesk\", body: \"inter\" },\n },\n hilltop: {\n name: \"Hilltop Fitness\",\n colors: { primary: \"#b45309\", primaryDark: \"#fbbf24\" },\n fonts: { heading: \"playfair-display\", body: \"work-sans\" },\n },\n} satisfies Record<string, SiteBrand>);\n"]}
|
|
1
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|