@seamlet/astro 0.12.1 → 1.1.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/CHANGELOG.md +37 -0
- package/README.md +84 -2
- package/dist/bridge.d.ts +2 -2
- package/dist/bridge.js +3 -2
- package/dist/chunk-G6Z44LGA.js +67 -0
- package/dist/{chunk-ZS32CW5F.js → chunk-I3HOJE3S.js} +365 -6
- package/dist/{chunk-SSECNMAD.js → chunk-PLNPM2D3.js} +1 -1
- package/dist/{chunk-QL4K4HR6.js → chunk-QXPXIMIM.js} +41 -0
- package/dist/cli.js +4 -4
- package/dist/index.js +8 -7
- package/dist/{messages-CvZhLRSE.d.ts → messages-Bqgs_mic.d.ts} +1 -1
- package/dist/{parse-content-Eg8yRq_t.d.ts → parse-content-IOJxgKLB.d.ts} +25 -4
- package/dist/preview-requests.d.ts +15 -1
- package/dist/preview-requests.js +7 -1
- package/dist/protocol.d.ts +3 -3
- package/dist/protocol.js +2 -2
- package/dist/routes/media.js +3 -1
- package/dist/schema.d.ts +24 -22
- package/dist/schema.js +33 -1
- package/dist/site-description-BuEpga8p.d.ts +245 -0
- package/dist/site.d.ts +49 -4
- package/dist/site.js +53 -9
- package/package.json +3 -2
- package/routes/preview.astro +23 -9
- package/dist/site-description-Cg5KNhhG.d.ts +0 -112
package/dist/site.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ImageMetadata } from 'astro';
|
|
2
2
|
import { AstroComponentFactory } from 'astro/runtime/server/index.js';
|
|
3
|
-
import { F as Fields,
|
|
4
|
-
import { S as SiteDescription } from './site-description-
|
|
3
|
+
import { C as Content, F as Fields, b as ContentOf } from './parse-content-IOJxgKLB.js';
|
|
4
|
+
import { a as SiteRecordPageDescription, S as SiteDescription } from './site-description-BuEpga8p.js';
|
|
5
5
|
|
|
6
6
|
/** A page of the site: how the editor names it, and the component that renders it. */
|
|
7
7
|
interface SeamletPage {
|
|
@@ -11,6 +11,36 @@ interface SeamletPage {
|
|
|
11
11
|
/** Where the content holds the page's title and description for search engines (`seo.menu`). */
|
|
12
12
|
readonly searchTexts?: string;
|
|
13
13
|
}
|
|
14
|
+
/** The pages of the records of a collection, and the component that renders each of them. */
|
|
15
|
+
interface SeamletRecordPage {
|
|
16
|
+
/** Which records have pages and where: `recordPages(schema, { collection, path })`. */
|
|
17
|
+
readonly pages: SiteRecordPageDescription;
|
|
18
|
+
/**
|
|
19
|
+
* A component that takes the site's content, the record and its place in its collection as its
|
|
20
|
+
* `content`, `record` and `index` props.
|
|
21
|
+
*/
|
|
22
|
+
readonly component: AstroComponentFactory;
|
|
23
|
+
}
|
|
24
|
+
/** What renders a page: its component, and the props to give it. */
|
|
25
|
+
interface RenderedPage {
|
|
26
|
+
readonly component: AstroComponentFactory;
|
|
27
|
+
readonly props: PageProps;
|
|
28
|
+
}
|
|
29
|
+
type PageProps = {
|
|
30
|
+
readonly content: Content;
|
|
31
|
+
} | {
|
|
32
|
+
readonly content: Content;
|
|
33
|
+
readonly record: Content;
|
|
34
|
+
readonly index: number;
|
|
35
|
+
};
|
|
36
|
+
/** A page that `getStaticPaths` of a site's `[...page]` route builds. */
|
|
37
|
+
interface StaticPage {
|
|
38
|
+
readonly params: {
|
|
39
|
+
readonly page: string | undefined;
|
|
40
|
+
};
|
|
41
|
+
readonly props: RenderedPage;
|
|
42
|
+
}
|
|
43
|
+
|
|
14
44
|
/** The site's content and pages; its id and title come from `seamlet.json`. */
|
|
15
45
|
interface SeamletSiteDefinition<F extends Fields> {
|
|
16
46
|
readonly schema: F;
|
|
@@ -18,6 +48,11 @@ interface SeamletSiteDefinition<F extends Fields> {
|
|
|
18
48
|
readonly initialContent: ContentOf<F>;
|
|
19
49
|
/** The pages of the site by their address (`/`, `/menu`); the home page `/` comes first. */
|
|
20
50
|
readonly pages: Readonly<Record<string, SeamletPage>>;
|
|
51
|
+
/**
|
|
52
|
+
* A page of every record of a collection, each kind with the component that renders it:
|
|
53
|
+
* `[{ pages: recordPages(schema, { collection: "menu", path: "/menu/[record]" }), component }]`.
|
|
54
|
+
*/
|
|
55
|
+
readonly recordPages?: readonly SeamletRecordPage[];
|
|
21
56
|
/**
|
|
22
57
|
* The site's own photo at the address its content gives it (`/menu/cafe/01.jpg`), so the CMS's
|
|
23
58
|
* editor can show it in the photo's field. A site without own photos leaves it out.
|
|
@@ -27,8 +62,18 @@ interface SeamletSiteDefinition<F extends Fields> {
|
|
|
27
62
|
interface SeamletSite<F extends Fields = Fields> {
|
|
28
63
|
readonly id: string;
|
|
29
64
|
readonly schema: F;
|
|
30
|
-
/**
|
|
65
|
+
/**
|
|
66
|
+
* The page at the rest of an address: nothing is the first page, `menu` the page at /menu.
|
|
67
|
+
* @deprecated The site's own pages only: `pageOf` renders the pages of records too.
|
|
68
|
+
*/
|
|
31
69
|
readonly pageAt: (rest: string | undefined) => AstroComponentFactory | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* What renders the page at the rest of an address (`[...page]`) with the content: nothing is the
|
|
72
|
+
* first page, `menu/latte` the page of the record at /menu/latte. Undefined when there is none.
|
|
73
|
+
*/
|
|
74
|
+
readonly pageOf: (rest: string | undefined, content: ContentOf<F>) => RenderedPage | undefined;
|
|
75
|
+
/** Every page of the site with the content, for `getStaticPaths` of a `[...page]` route. */
|
|
76
|
+
readonly staticPaths: (content: ContentOf<F>) => readonly StaticPage[];
|
|
32
77
|
/** What the CMS published: the site's initial content until the first publication. */
|
|
33
78
|
readonly loadPublishedContent: () => Promise<ContentOf<F>>;
|
|
34
79
|
/** The site's own photo at an address its content gives it, if it has one there. */
|
|
@@ -45,4 +90,4 @@ declare function defineSeamletSite<F extends Fields>(definition: SeamletSiteDefi
|
|
|
45
90
|
*/
|
|
46
91
|
declare function loadPublishedContent<F extends Fields>(schema: F): Promise<ContentOf<F>>;
|
|
47
92
|
|
|
48
|
-
export { type SeamletPage, type SeamletSite, type SeamletSiteDefinition, defineSeamletSite, loadPublishedContent };
|
|
93
|
+
export { type PageProps, type RenderedPage, type SeamletPage, type SeamletRecordPage, type SeamletSite, type SeamletSiteDefinition, type StaticPage, defineSeamletSite, loadPublishedContent };
|
package/dist/site.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
SITE_MODULE_FILE
|
|
3
|
+
} from "./chunk-QCVWHHJC.js";
|
|
4
|
+
import {
|
|
5
|
+
pagePathOf,
|
|
6
|
+
renderedPageAt,
|
|
7
|
+
staticPagesOf
|
|
8
|
+
} from "./chunk-G6Z44LGA.js";
|
|
9
|
+
import {
|
|
3
10
|
checkSiteDescription,
|
|
4
11
|
formatFieldPath,
|
|
5
12
|
parseContent
|
|
6
|
-
} from "./chunk-
|
|
7
|
-
import {
|
|
8
|
-
SITE_MODULE_FILE
|
|
9
|
-
} from "./chunk-QCVWHHJC.js";
|
|
13
|
+
} from "./chunk-I3HOJE3S.js";
|
|
10
14
|
|
|
11
15
|
// src/site.ts
|
|
12
16
|
import { cmsOrigin, siteId, siteTitle } from "virtual:seamlet/config";
|
|
@@ -56,12 +60,22 @@ function describeSite(identity, definition) {
|
|
|
56
60
|
...page.searchTexts === void 0 ? {} : { searchTexts: page.searchTexts }
|
|
57
61
|
})
|
|
58
62
|
);
|
|
63
|
+
const recordPages = (definition.recordPages ?? []).map(
|
|
64
|
+
({
|
|
65
|
+
pages: { path, collection, searchTexts }
|
|
66
|
+
}) => ({
|
|
67
|
+
path,
|
|
68
|
+
collection,
|
|
69
|
+
...searchTexts === void 0 ? {} : { searchTexts }
|
|
70
|
+
})
|
|
71
|
+
);
|
|
59
72
|
const description = {
|
|
60
73
|
id: identity.id,
|
|
61
74
|
title: identity.title,
|
|
62
75
|
schema: definition.schema,
|
|
63
76
|
initialContent: definition.initialContent,
|
|
64
|
-
pages
|
|
77
|
+
pages,
|
|
78
|
+
...recordPages.length === 0 ? {} : { recordPages }
|
|
65
79
|
};
|
|
66
80
|
const asSent = JSON.parse(JSON.stringify(description));
|
|
67
81
|
const reading = checkSiteDescription(asSent);
|
|
@@ -100,6 +114,18 @@ function problemText(problem) {
|
|
|
100
114
|
return 'the first of the pages is not the home page "/"';
|
|
101
115
|
case "repeated-page-path":
|
|
102
116
|
return `the page "${problem.path}" is named twice`;
|
|
117
|
+
case "invalid-record-pages":
|
|
118
|
+
return "recordPages is not a list";
|
|
119
|
+
case "invalid-record-page":
|
|
120
|
+
return `record pages ${String(problem.index + 1)}: ${RECORD_PAGE_PROBLEM_TEXTS[problem.reason]}`;
|
|
121
|
+
case "repeated-record-pages":
|
|
122
|
+
return `the records of "${problem.collection}" have pages twice: a record has one page`;
|
|
123
|
+
case "page-among-record-pages":
|
|
124
|
+
return `the page "${problem.path}" is where the pages of records are: give it another address`;
|
|
125
|
+
case "record-without-address":
|
|
126
|
+
return `record ${String(problem.index + 1)} of "${problem.collection}" in the initial content has neither a slug nor an id for its page`;
|
|
127
|
+
case "repeated-record-address":
|
|
128
|
+
return `two records of "${problem.collection}" in the initial content have their pages at "${problem.address}": give them other ids or slugs`;
|
|
103
129
|
}
|
|
104
130
|
}
|
|
105
131
|
var SCHEMA_PROBLEM_TEXTS = {
|
|
@@ -111,7 +137,8 @@ var SCHEMA_PROBLEM_TEXTS = {
|
|
|
111
137
|
"invalid-choice-options": "its options are not a list of { value, label }",
|
|
112
138
|
"record-id-field": "a record has its own id: name the field otherwise",
|
|
113
139
|
"invalid-item-title": "itemTitle names no text or link field of the record",
|
|
114
|
-
"unknown-collection": "it refers to a collection the schema does not have"
|
|
140
|
+
"unknown-collection": "it refers to a collection the schema does not have",
|
|
141
|
+
"misplaced-slug": "a slug is a field of a record of a collection, one per record"
|
|
115
142
|
};
|
|
116
143
|
var PAGE_PROBLEM_TEXTS = {
|
|
117
144
|
"not-a-page": "not a page",
|
|
@@ -119,17 +146,34 @@ var PAGE_PROBLEM_TEXTS = {
|
|
|
119
146
|
"invalid-title": "its title is empty",
|
|
120
147
|
"invalid-search-texts": "searchTexts names no group of a title and a description text"
|
|
121
148
|
};
|
|
149
|
+
var RECORD_PAGE_PROBLEM_TEXTS = {
|
|
150
|
+
"not-a-page": "not pages of records",
|
|
151
|
+
"invalid-path": 'its address is not lower-case segments, then "/[record]", such as "/menu/[record]"',
|
|
152
|
+
"unknown-collection": "it names a collection the schema does not have",
|
|
153
|
+
"invalid-search-texts": "searchTexts names no group of a title and a description text of the record"
|
|
154
|
+
};
|
|
122
155
|
function issueText(issue) {
|
|
123
156
|
return `"${formatFieldPath(issue.path)}" is ${issue.code}`;
|
|
124
157
|
}
|
|
125
158
|
|
|
126
159
|
// src/site.ts
|
|
127
160
|
function defineSeamletSite(definition) {
|
|
128
|
-
const
|
|
161
|
+
const sitePages = {
|
|
162
|
+
schema: definition.schema,
|
|
163
|
+
pages: definition.pages,
|
|
164
|
+
recordPages: definition.recordPages ?? []
|
|
165
|
+
};
|
|
166
|
+
const contentOf = (content) => content;
|
|
129
167
|
return {
|
|
130
168
|
id: siteId,
|
|
131
169
|
schema: definition.schema,
|
|
132
|
-
pageAt: (rest) =>
|
|
170
|
+
pageAt: (rest) => {
|
|
171
|
+
const path = pagePathOf(rest);
|
|
172
|
+
const page = Object.hasOwn(definition.pages, path) ? definition.pages[path] : void 0;
|
|
173
|
+
return page?.component;
|
|
174
|
+
},
|
|
175
|
+
pageOf: (rest, content) => renderedPageAt(sitePages, pagePathOf(rest), contentOf(content)),
|
|
176
|
+
staticPaths: (content) => staticPagesOf(sitePages, contentOf(content)),
|
|
133
177
|
loadPublishedContent: () => loadPublishedContent(definition.schema),
|
|
134
178
|
ownPhotoAt: (src) => definition.photos?.(src),
|
|
135
179
|
description: describeSite({ id: siteId, title: siteTitle }, definition)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seamlet/astro",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Connects an Astro site to the Seamlet CMS: the schema of its content, the preview the editor frames, and its published content.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -59,7 +59,8 @@
|
|
|
59
59
|
"files": [
|
|
60
60
|
"dist",
|
|
61
61
|
"routes",
|
|
62
|
-
"components"
|
|
62
|
+
"components",
|
|
63
|
+
"CHANGELOG.md"
|
|
63
64
|
],
|
|
64
65
|
"scripts": {
|
|
65
66
|
"build": "tsup"
|
package/routes/preview.astro
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
// The preview the CMS's editor frames: a page of the site with the bridge to the editor.
|
|
3
|
-
// `/preview` is the first page, `/preview/menu` the page at /menu
|
|
4
|
-
// content; POST shows the content in its JSON body, never saved:
|
|
5
|
-
// draft this way.
|
|
3
|
+
// `/preview` is the first page, `/preview/menu` the page at /menu, `/preview/menu/latte` the page of
|
|
4
|
+
// a record. GET shows the published content; POST shows the content in its JSON body, never saved:
|
|
5
|
+
// the bridge renders the editor's draft this way.
|
|
6
6
|
import { parseContent } from "@seamlet/astro/schema";
|
|
7
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
isPageAddress,
|
|
9
|
+
previewContentAt,
|
|
10
|
+
previewHeadersOf,
|
|
11
|
+
readDraft,
|
|
12
|
+
} from "@seamlet/astro/preview-requests";
|
|
8
13
|
import { cmsOrigin } from "virtual:seamlet/config";
|
|
9
14
|
import site from "virtual:seamlet/site";
|
|
10
15
|
|
|
@@ -15,11 +20,10 @@ for (const [name, value] of Object.entries(headers)) {
|
|
|
15
20
|
Astro.response.headers.set(name, value);
|
|
16
21
|
}
|
|
17
22
|
|
|
18
|
-
const
|
|
19
|
-
if (
|
|
23
|
+
const rest = Astro.params.page;
|
|
24
|
+
if (!isPageAddress(site.description, rest)) {
|
|
20
25
|
return new Response(null, { status: NOT_FOUND, headers });
|
|
21
26
|
}
|
|
22
|
-
|
|
23
27
|
const reading =
|
|
24
28
|
Astro.request.method === "POST" ? await readDraft(Astro.request) : undefined;
|
|
25
29
|
if (reading !== undefined && !reading.isRead) {
|
|
@@ -27,8 +31,18 @@ if (reading !== undefined && !reading.isRead) {
|
|
|
27
31
|
}
|
|
28
32
|
const content =
|
|
29
33
|
reading === undefined
|
|
30
|
-
?
|
|
34
|
+
? previewContentAt(
|
|
35
|
+
site.description,
|
|
36
|
+
await site.loadPublishedContent(),
|
|
37
|
+
rest,
|
|
38
|
+
)
|
|
31
39
|
: parseContent(site.schema, reading.draft).content;
|
|
40
|
+
|
|
41
|
+
const page = site.pageOf(rest, content);
|
|
42
|
+
if (page === undefined) {
|
|
43
|
+
return new Response(null, { status: NOT_FOUND, headers });
|
|
44
|
+
}
|
|
45
|
+
const { component: Page, props } = page;
|
|
32
46
|
---
|
|
33
47
|
|
|
34
|
-
<Page
|
|
48
|
+
<Page {...props} />
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
import { F as Fields, a as Content, c as ContentIssue } from './parse-content-Eg8yRq_t.js';
|
|
2
|
-
|
|
3
|
-
/** Why a schema cannot be read. */
|
|
4
|
-
type SchemaProblemReason =
|
|
5
|
-
/** Not an object of fields, or a field that is not an object. */
|
|
6
|
-
"not-fields"
|
|
7
|
-
/** A name that is empty, holds the separator of paths (`.`) or is a number, which a path reads as a record. */
|
|
8
|
-
| "invalid-name" | "invalid-label" | "unknown-kind"
|
|
9
|
-
/** An option of the field (`maxLength`, `inline`…) is there but not of its kind. */
|
|
10
|
-
| "invalid-option" | "invalid-choice-options"
|
|
11
|
-
/** A record has a field named `id`, which is the record's own. */
|
|
12
|
-
| "record-id-field"
|
|
13
|
-
/** `itemTitle` names no text or link field of the record. */
|
|
14
|
-
| "invalid-item-title"
|
|
15
|
-
/** A reference names a collection the schema does not have. */
|
|
16
|
-
| "unknown-collection";
|
|
17
|
-
interface SchemaProblem {
|
|
18
|
-
/** The names of the fields down to the field with the problem; empty for the schema itself. */
|
|
19
|
-
readonly path: readonly string[];
|
|
20
|
-
readonly reason: SchemaProblemReason;
|
|
21
|
-
}
|
|
22
|
-
type FieldsReading = {
|
|
23
|
-
readonly status: "read";
|
|
24
|
-
readonly fields: Fields;
|
|
25
|
-
} | {
|
|
26
|
-
readonly status: "invalid";
|
|
27
|
-
readonly problem: SchemaProblem;
|
|
28
|
-
};
|
|
29
|
-
/** The schema the input describes, or undefined when it is not one. */
|
|
30
|
-
declare function readFields(input: unknown): Fields | undefined;
|
|
31
|
-
/** The schema the input describes, or the first problem that keeps it from being one. */
|
|
32
|
-
declare function checkFields(input: unknown): FieldsReading;
|
|
33
|
-
|
|
34
|
-
/** Where a site hands out its description, on the origin of its preview. */
|
|
35
|
-
declare const SITE_DESCRIPTION_PATH = "/seamlet/site.json";
|
|
36
|
-
/** A page of a site, which the site renders itself. */
|
|
37
|
-
interface SitePageDescription {
|
|
38
|
-
/** The address of the page on the site: `/` for the first page, `/menu` for others. */
|
|
39
|
-
readonly path: string;
|
|
40
|
-
/** How the editor names the page in its list of pages. */
|
|
41
|
-
readonly title: string;
|
|
42
|
-
/**
|
|
43
|
-
* Where the content holds what search engines and link previews show for the page
|
|
44
|
-
* (`seo.menu`): a group of a `title` and a `description` text.
|
|
45
|
-
*/
|
|
46
|
-
readonly searchTexts?: string;
|
|
47
|
-
}
|
|
48
|
-
interface SiteDescription {
|
|
49
|
-
/** The address of the site in the CMS (`/sites/<id>`). */
|
|
50
|
-
readonly id: string;
|
|
51
|
-
/** How the CMS names the site. */
|
|
52
|
-
readonly title: string;
|
|
53
|
-
readonly schema: Fields;
|
|
54
|
-
/** The content shown and edited until the first save. */
|
|
55
|
-
readonly initialContent: Content;
|
|
56
|
-
/** The pages of the site; the first is the home page at `/`. */
|
|
57
|
-
readonly pages: readonly [SitePageDescription, ...SitePageDescription[]];
|
|
58
|
-
}
|
|
59
|
-
/** Why a site's description cannot be read: what to fix in the site. */
|
|
60
|
-
type SiteDescriptionProblem = {
|
|
61
|
-
readonly code: "not-a-description";
|
|
62
|
-
} | {
|
|
63
|
-
readonly code: "invalid-id";
|
|
64
|
-
} | {
|
|
65
|
-
readonly code: "invalid-title";
|
|
66
|
-
} | {
|
|
67
|
-
readonly code: "invalid-schema";
|
|
68
|
-
readonly problem: SchemaProblem;
|
|
69
|
-
}
|
|
70
|
-
/** The initial content is not content the CMS could save. */
|
|
71
|
-
| {
|
|
72
|
-
readonly code: "invalid-initial-content";
|
|
73
|
-
readonly issues: readonly ContentIssue[];
|
|
74
|
-
} | {
|
|
75
|
-
readonly code: "no-pages";
|
|
76
|
-
}
|
|
77
|
-
/** The page at this place of the list is not a page, or its path or title is not one. */
|
|
78
|
-
| {
|
|
79
|
-
readonly code: "invalid-page";
|
|
80
|
-
readonly index: number;
|
|
81
|
-
readonly reason: PageProblemReason;
|
|
82
|
-
} | {
|
|
83
|
-
readonly code: "home-page-not-first";
|
|
84
|
-
} | {
|
|
85
|
-
readonly code: "repeated-page-path";
|
|
86
|
-
readonly path: string;
|
|
87
|
-
};
|
|
88
|
-
type PageProblemReason = "not-a-page"
|
|
89
|
-
/** Not `/`, or not lower-case segments without a trailing slash, such as `/menu`. */
|
|
90
|
-
| "invalid-path" | "invalid-title"
|
|
91
|
-
/** Not where the content holds a group of a `title` and a `description` text. */
|
|
92
|
-
| "invalid-search-texts";
|
|
93
|
-
type SiteDescriptionReading = {
|
|
94
|
-
readonly status: "read";
|
|
95
|
-
readonly description: SiteDescription;
|
|
96
|
-
} | {
|
|
97
|
-
readonly status: "invalid";
|
|
98
|
-
readonly problems: readonly SiteDescriptionProblem[];
|
|
99
|
-
};
|
|
100
|
-
/** The first page of every site. */
|
|
101
|
-
declare const HOME_PAGE_PATH = "/";
|
|
102
|
-
/**
|
|
103
|
-
* The description the input gives, or undefined when it is not a whole and sound one: a known
|
|
104
|
-
* schema, an initial content with nothing to fix, the home page first, each page once.
|
|
105
|
-
*/
|
|
106
|
-
declare function readSiteDescription(input: unknown): SiteDescription | undefined;
|
|
107
|
-
/** The description the input gives, or every problem that keeps it from being whole and sound. */
|
|
108
|
-
declare function checkSiteDescription(input: unknown): SiteDescriptionReading;
|
|
109
|
-
/** Whether the path names a group of a `title` and a `description` text. */
|
|
110
|
-
declare function isSearchTextsGroup(schema: Fields, path: string): boolean;
|
|
111
|
-
|
|
112
|
-
export { type FieldsReading as F, HOME_PAGE_PATH as H, type PageProblemReason as P, type SiteDescription as S, SITE_DESCRIPTION_PATH as a, type SchemaProblem as b, type SchemaProblemReason as c, type SiteDescriptionProblem as d, type SiteDescriptionReading as e, type SitePageDescription as f, checkFields as g, checkSiteDescription as h, isSearchTextsGroup as i, readSiteDescription as j, readFields as r };
|