@caltho/site-kit 0.2.11 → 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 +84 -3
- package/dist/behaviors/accordion.d.ts +4 -0
- package/dist/behaviors/accordion.js +56 -0
- package/dist/behaviors/carousel.d.ts +4 -0
- package/dist/behaviors/carousel.js +127 -0
- package/dist/behaviors/filter.d.ts +1 -0
- package/dist/behaviors/filter.js +25 -0
- package/dist/behaviors/index.d.ts +14 -0
- package/dist/behaviors/index.js +78 -0
- package/dist/behaviors/motion.d.ts +13 -0
- package/dist/behaviors/motion.js +88 -0
- package/dist/behaviors/tabs.d.ts +3 -0
- package/dist/behaviors/tabs.js +55 -0
- package/dist/built/css.d.ts +2 -0
- package/dist/built/css.js +26 -0
- package/dist/built/theme.d.ts +19 -0
- package/dist/built/theme.js +86 -0
- package/dist/built/tree.d.ts +24 -0
- package/dist/built/tree.js +96 -0
- package/dist/built.test.d.ts +1 -0
- package/dist/built.test.js +257 -0
- package/dist/consent.d.ts +33 -0
- package/dist/consent.js +36 -0
- package/dist/consent.test.d.ts +1 -0
- package/dist/consent.test.js +61 -0
- package/dist/content/index.d.ts +170 -40
- package/dist/content/index.js +155 -0
- package/dist/content/lists.d.ts +69 -0
- package/dist/content/lists.js +77 -0
- package/dist/content/lists.test.d.ts +1 -0
- package/dist/content/lists.test.js +257 -0
- package/dist/content/look.d.ts +13 -13
- package/dist/content-migrate.d.ts +51 -0
- package/dist/content-migrate.js +69 -0
- package/dist/finish.d.ts +1 -1
- package/dist/finish.js +18 -5
- package/dist/frame.test.js +25 -0
- package/dist/next/built.d.ts +40 -0
- package/dist/next/built.js +318 -0
- package/dist/next/consent.d.ts +4 -0
- package/dist/next/consent.js +13 -0
- package/dist/next/data.d.ts +2 -2
- package/dist/next/data.js +6 -4
- package/dist/next/frame.d.ts +9 -1
- package/dist/next/frame.js +5 -2
- package/dist/next/index.d.ts +2 -0
- package/dist/next/index.js +2 -0
- package/dist/next/metadata.js +3 -2
- package/dist/next/parts/Img.d.ts +6 -1
- package/dist/next/parts/Img.js +11 -3
- package/dist/next/preview.js +242 -15
- package/dist/next/sections.js +5 -0
- package/dist/policies.js +22 -4
- package/dist/prepare.d.ts +10 -0
- package/dist/prepare.js +67 -3
- package/dist/preview-match.d.ts +21 -0
- package/dist/preview-match.js +25 -0
- package/dist/schema.js +3 -1
- package/dist/sections/icons.d.ts +2 -0
- package/dist/sections/icons.js +4 -0
- package/dist/sections/index.d.ts +38 -16
- package/dist/sections/index.js +7 -2
- package/dist/sections.css +324 -0
- package/dist/seo.js +2 -1
- package/dist/tree/behaviors.d.ts +50 -0
- package/dist/tree/behaviors.js +67 -0
- package/dist/tree/classes.d.ts +24 -0
- package/dist/tree/classes.js +94 -0
- package/dist/tree/index.d.ts +145 -0
- package/dist/tree/index.js +196 -0
- package/dist/tree/messages.d.ts +45 -0
- package/dist/tree/messages.js +7 -0
- package/package.json +15 -1
package/dist/content/index.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { ShareOptions } from "../share.ts";
|
|
2
2
|
export type { CardNode, ShareCard, ShareFont, ShareOptions } from "../share.ts";
|
|
3
3
|
import { z } from "zod";
|
|
4
|
+
import { type Node } from "../tree/index.ts";
|
|
5
|
+
import { type Consent } from "../consent.ts";
|
|
4
6
|
import { type Look, type LookOptions } from "./look.ts";
|
|
5
7
|
export { COLOUR_ROLES, colourOf, contrast, HEADER_LAYOUTS, HEADER_STYLES, headerOf, isDark, KIT_FONTS, KIT_TYPE, lookCss, lookProblems, lookVars, swatchSlug, TYPE_ROLES, uploadedFontCss, buttonStyleClass, BUTTON_SIZES, MAX_BUTTON_STYLES, THEME_BUTTONS, type ButtonStyle, type ColourRole, type HeaderLayout, type HeaderLook, type HeaderStyle, type Look, type LookOptions, type Space, type Swatch, type TypeRole, type TypeScale, type TypeStyle, type UploadedFont, } from "./look.ts";
|
|
6
8
|
export { fontFaceCss, fontFiles, googleFamily, googleFont, googleFonts, isFontName, servedAt, type FontFile, type FontKind, type GoogleFont } from "../fonts-google.ts";
|
|
7
9
|
export { blockLabel, checkStructure, describePath, type StructureIssue } from "../schema.ts";
|
|
8
10
|
export { z };
|
|
11
|
+
export { allPages, FIELD_KINDS, fromList, itemOf, itemPages, itemPath, PAGE_LINK, THIS_ITEM, withListItems, type FieldKind, type FromList, type List, type ListField, type ListItem, type ListPage } from "./lists.ts";
|
|
9
12
|
export declare const text: z.ZodString;
|
|
10
13
|
/** Longer plain text: drawn as a text area. */
|
|
11
14
|
export declare const longText: z.ZodString;
|
|
@@ -57,19 +60,19 @@ export declare const placement: z.ZodObject<{
|
|
|
57
60
|
roomy: "roomy";
|
|
58
61
|
}>>;
|
|
59
62
|
show: z.ZodDefault<z.ZodEnum<{
|
|
60
|
-
phone: "phone";
|
|
61
63
|
all: "all";
|
|
64
|
+
phone: "phone";
|
|
62
65
|
desktop: "desktop";
|
|
63
66
|
}>>;
|
|
64
67
|
lines: z.ZodOptional<z.ZodEnum<{
|
|
65
|
-
both: "both";
|
|
66
|
-
none: "none";
|
|
67
68
|
top: "top";
|
|
69
|
+
none: "none";
|
|
70
|
+
both: "both";
|
|
68
71
|
bottom: "bottom";
|
|
69
72
|
}>>;
|
|
70
73
|
lineColour: z.ZodOptional<z.ZodEnum<{
|
|
71
|
-
quiet: "quiet";
|
|
72
74
|
strong: "strong";
|
|
75
|
+
quiet: "quiet";
|
|
73
76
|
}>>;
|
|
74
77
|
background: z.ZodOptional<z.ZodObject<{
|
|
75
78
|
color: z.ZodOptional<z.ZodString>;
|
|
@@ -79,8 +82,8 @@ export declare const placement: z.ZodObject<{
|
|
|
79
82
|
}, z.core.$strip>>;
|
|
80
83
|
overlay: z.ZodDefault<z.ZodEnum<{
|
|
81
84
|
dark: "dark";
|
|
82
|
-
light: "light";
|
|
83
85
|
none: "none";
|
|
86
|
+
light: "light";
|
|
84
87
|
}>>;
|
|
85
88
|
}, z.core.$strip>>;
|
|
86
89
|
}, z.core.$strip>;
|
|
@@ -223,6 +226,8 @@ export type Footer = {
|
|
|
223
226
|
note?: string;
|
|
224
227
|
};
|
|
225
228
|
export type SiteBase = {
|
|
229
|
+
format?: number; /** Whether it asks before counting visits, and its banner (../consent.ts). */
|
|
230
|
+
consent?: Consent;
|
|
226
231
|
url: string;
|
|
227
232
|
lang: string;
|
|
228
233
|
business: Business;
|
|
@@ -232,7 +237,8 @@ export type SiteBase = {
|
|
|
232
237
|
look?: Look;
|
|
233
238
|
redirects: Redirect[]; /** Whether page paths end in a slash (the default). */
|
|
234
239
|
trailingSlash?: boolean; /** Set by prepare, never in content: CalOS counts this site's visits (its pages carry the script), which its privacy policy says. */
|
|
235
|
-
countsVisits?: boolean;
|
|
240
|
+
countsVisits?: boolean; /** Set by prepare (and CalOS's preview), never in content: the business's forms' addresses by key, for a built form's sendTo. */
|
|
241
|
+
forms?: Record<string, string>;
|
|
236
242
|
};
|
|
237
243
|
/**
|
|
238
244
|
* The site's menu, as its header draws it: the one edited in CalOS (its links in order, one picked out,
|
|
@@ -283,12 +289,17 @@ export type DefineOptions = {
|
|
|
283
289
|
/** The site's Look, chosen in CalOS (fonts from the ones it carries, colours, corners, buttons), drawn through CSS variables (./look.ts). */
|
|
284
290
|
look?: LookOptions;
|
|
285
291
|
};
|
|
286
|
-
/**
|
|
287
|
-
* A site's content shape from its blocks: each a name and the fields it has. The site's own block
|
|
288
|
-
* type is `z.output<typeof content.schema>["pages"][number]["blocks"][number]`.
|
|
289
|
-
*/
|
|
290
292
|
export declare function defineSite<const B extends Record<string, z.ZodObject>>(blocks: B, o?: DefineOptions): {
|
|
291
293
|
schema: z.ZodObject<{
|
|
294
|
+
saved: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
295
|
+
name: z.ZodString;
|
|
296
|
+
block: z.ZodDiscriminatedUnion<[z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>, ...z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>[]], "type">;
|
|
297
|
+
}, z.core.$strip>>>;
|
|
298
|
+
components?: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
299
|
+
key: z.ZodString;
|
|
300
|
+
name: z.ZodString;
|
|
301
|
+
root: z.ZodType<Node, unknown, z.core.$ZodTypeInternals<Node, unknown>>;
|
|
302
|
+
}, z.core.$strip>>> | undefined;
|
|
292
303
|
pages: z.ZodArray<z.ZodObject<{
|
|
293
304
|
blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>, ...z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>[]], "type">>;
|
|
294
305
|
path: z.ZodString;
|
|
@@ -303,9 +314,38 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
303
314
|
shareText: z.ZodOptional<z.ZodString>;
|
|
304
315
|
noindex: z.ZodDefault<z.ZodBoolean>;
|
|
305
316
|
}, z.core.$strip>>;
|
|
306
|
-
|
|
317
|
+
lists: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
307
318
|
name: z.ZodString;
|
|
308
|
-
|
|
319
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
320
|
+
key: z.ZodString;
|
|
321
|
+
label: z.ZodString;
|
|
322
|
+
kind: z.ZodEnum<{
|
|
323
|
+
number: "number";
|
|
324
|
+
date: "date";
|
|
325
|
+
text: "text";
|
|
326
|
+
image: "image";
|
|
327
|
+
link: "link";
|
|
328
|
+
longText: "longText";
|
|
329
|
+
}>;
|
|
330
|
+
}, z.core.$strip>>;
|
|
331
|
+
items: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
332
|
+
id: z.ZodString;
|
|
333
|
+
slug: z.ZodString;
|
|
334
|
+
}, z.core.$catchall<z.ZodUnknown>>>>;
|
|
335
|
+
page: z.ZodOptional<z.ZodObject<{
|
|
336
|
+
path: z.ZodString;
|
|
337
|
+
title: z.ZodString;
|
|
338
|
+
description: z.ZodOptional<z.ZodString>;
|
|
339
|
+
blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>, ...z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>[]], "type">>;
|
|
340
|
+
}, z.core.$strip>>;
|
|
341
|
+
source: z.ZodOptional<z.ZodObject<{
|
|
342
|
+
table: z.ZodString;
|
|
343
|
+
fields: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
344
|
+
publish: z.ZodDefault<z.ZodEnum<{
|
|
345
|
+
draft: "draft";
|
|
346
|
+
auto: "auto";
|
|
347
|
+
}>>;
|
|
348
|
+
}, z.core.$strip>>;
|
|
309
349
|
}, z.core.$strip>>>;
|
|
310
350
|
look?: z.ZodOptional<z.ZodObject<{
|
|
311
351
|
uploadedFonts?: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -331,13 +371,13 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
331
371
|
floating: "floating";
|
|
332
372
|
}>>;
|
|
333
373
|
layout: z.ZodDefault<z.ZodEnum<{
|
|
374
|
+
left: "left";
|
|
334
375
|
spread: "spread";
|
|
335
376
|
centered: "centered";
|
|
336
|
-
left: "left";
|
|
337
377
|
}>>;
|
|
338
378
|
menuShows: z.ZodDefault<z.ZodEnum<{
|
|
339
|
-
both: "both";
|
|
340
379
|
icon: "icon";
|
|
380
|
+
both: "both";
|
|
341
381
|
word: "word";
|
|
342
382
|
}>>;
|
|
343
383
|
menuStyle: z.ZodOptional<z.ZodString>;
|
|
@@ -354,39 +394,39 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
354
394
|
color: z.ZodString;
|
|
355
395
|
}, z.core.$strip>>>;
|
|
356
396
|
type: z.ZodDefault<z.ZodObject<{
|
|
357
|
-
|
|
397
|
+
h1: z.ZodOptional<z.ZodObject<{
|
|
358
398
|
size: z.ZodOptional<z.ZodNumber>;
|
|
359
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
399
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
360
400
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
361
401
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
362
402
|
}, z.core.$strip>>;
|
|
363
|
-
|
|
403
|
+
h2: z.ZodOptional<z.ZodObject<{
|
|
364
404
|
size: z.ZodOptional<z.ZodNumber>;
|
|
365
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
405
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
366
406
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
367
407
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
368
408
|
}, z.core.$strip>>;
|
|
369
|
-
|
|
409
|
+
h3: z.ZodOptional<z.ZodObject<{
|
|
370
410
|
size: z.ZodOptional<z.ZodNumber>;
|
|
371
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
411
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
372
412
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
373
413
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
374
414
|
}, z.core.$strip>>;
|
|
375
|
-
|
|
415
|
+
small: z.ZodOptional<z.ZodObject<{
|
|
376
416
|
size: z.ZodOptional<z.ZodNumber>;
|
|
377
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
417
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
378
418
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
379
419
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
380
420
|
}, z.core.$strip>>;
|
|
381
421
|
body: z.ZodOptional<z.ZodObject<{
|
|
382
422
|
size: z.ZodOptional<z.ZodNumber>;
|
|
383
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
423
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
384
424
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
385
425
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
386
426
|
}, z.core.$strip>>;
|
|
387
|
-
|
|
427
|
+
display: z.ZodOptional<z.ZodObject<{
|
|
388
428
|
size: z.ZodOptional<z.ZodNumber>;
|
|
389
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
429
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
390
430
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
391
431
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
392
432
|
}, z.core.$strip>>;
|
|
@@ -432,6 +472,7 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
432
472
|
headingFont?: z.ZodDefault<z.ZodString> | undefined;
|
|
433
473
|
bodyFont?: z.ZodDefault<z.ZodString> | undefined;
|
|
434
474
|
}, z.core.$strip>> | undefined;
|
|
475
|
+
format: z.ZodOptional<z.ZodNumber>;
|
|
435
476
|
url: z.ZodURL;
|
|
436
477
|
lang: z.ZodDefault<z.ZodString>;
|
|
437
478
|
business: z.ZodObject<{
|
|
@@ -512,6 +553,31 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
512
553
|
}, z.core.$strip>>>;
|
|
513
554
|
note: z.ZodOptional<z.ZodString>;
|
|
514
555
|
}, z.core.$strip>>;
|
|
556
|
+
ownHeader: z.ZodOptional<z.ZodObject<{
|
|
557
|
+
name: z.ZodOptional<z.ZodString>;
|
|
558
|
+
root: z.ZodType<Node, unknown, z.core.$ZodTypeInternals<Node, unknown>>;
|
|
559
|
+
}, z.core.$strip>>;
|
|
560
|
+
ownFooter: z.ZodOptional<z.ZodObject<{
|
|
561
|
+
name: z.ZodOptional<z.ZodString>;
|
|
562
|
+
root: z.ZodType<Node, unknown, z.core.$ZodTypeInternals<Node, unknown>>;
|
|
563
|
+
}, z.core.$strip>>;
|
|
564
|
+
consent: z.ZodOptional<z.ZodObject<{
|
|
565
|
+
on: z.ZodDefault<z.ZodBoolean>;
|
|
566
|
+
text: z.ZodDefault<z.ZodString>;
|
|
567
|
+
accept: z.ZodDefault<z.ZodString>;
|
|
568
|
+
decline: z.ZodDefault<z.ZodString>;
|
|
569
|
+
policy: z.ZodOptional<z.ZodObject<{
|
|
570
|
+
label: z.ZodString;
|
|
571
|
+
href: z.ZodString;
|
|
572
|
+
}, z.core.$strip>>;
|
|
573
|
+
place: z.ZodDefault<z.ZodEnum<{
|
|
574
|
+
top: "top";
|
|
575
|
+
bottom: "bottom";
|
|
576
|
+
"bottom-left": "bottom-left";
|
|
577
|
+
"bottom-right": "bottom-right";
|
|
578
|
+
}>>;
|
|
579
|
+
design: z.ZodOptional<z.ZodString>;
|
|
580
|
+
}, z.core.$strip>>;
|
|
515
581
|
redirects: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
516
582
|
from: z.ZodString;
|
|
517
583
|
to: z.ZodString;
|
|
@@ -521,6 +587,15 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
521
587
|
/** The content checked, or every problem in it as "where: what" lines. */
|
|
522
588
|
parse(raw: unknown): {
|
|
523
589
|
site: z.output<z.ZodObject<{
|
|
590
|
+
saved: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
591
|
+
name: z.ZodString;
|
|
592
|
+
block: z.ZodDiscriminatedUnion<[z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>, ...z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>[]], "type">;
|
|
593
|
+
}, z.core.$strip>>>;
|
|
594
|
+
components?: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
595
|
+
key: z.ZodString;
|
|
596
|
+
name: z.ZodString;
|
|
597
|
+
root: z.ZodType<Node, unknown, z.core.$ZodTypeInternals<Node, unknown>>;
|
|
598
|
+
}, z.core.$strip>>> | undefined;
|
|
524
599
|
pages: z.ZodArray<z.ZodObject<{
|
|
525
600
|
blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>, ...z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>[]], "type">>;
|
|
526
601
|
path: z.ZodString;
|
|
@@ -535,9 +610,38 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
535
610
|
shareText: z.ZodOptional<z.ZodString>;
|
|
536
611
|
noindex: z.ZodDefault<z.ZodBoolean>;
|
|
537
612
|
}, z.core.$strip>>;
|
|
538
|
-
|
|
613
|
+
lists: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
|
|
539
614
|
name: z.ZodString;
|
|
540
|
-
|
|
615
|
+
fields: z.ZodArray<z.ZodObject<{
|
|
616
|
+
key: z.ZodString;
|
|
617
|
+
label: z.ZodString;
|
|
618
|
+
kind: z.ZodEnum<{
|
|
619
|
+
number: "number";
|
|
620
|
+
date: "date";
|
|
621
|
+
text: "text";
|
|
622
|
+
image: "image";
|
|
623
|
+
link: "link";
|
|
624
|
+
longText: "longText";
|
|
625
|
+
}>;
|
|
626
|
+
}, z.core.$strip>>;
|
|
627
|
+
items: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
628
|
+
id: z.ZodString;
|
|
629
|
+
slug: z.ZodString;
|
|
630
|
+
}, z.core.$catchall<z.ZodUnknown>>>>;
|
|
631
|
+
page: z.ZodOptional<z.ZodObject<{
|
|
632
|
+
path: z.ZodString;
|
|
633
|
+
title: z.ZodString;
|
|
634
|
+
description: z.ZodOptional<z.ZodString>;
|
|
635
|
+
blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>, ...z.ZodObject<z.core.$ZodLooseShape, z.core.$strip>[]], "type">>;
|
|
636
|
+
}, z.core.$strip>>;
|
|
637
|
+
source: z.ZodOptional<z.ZodObject<{
|
|
638
|
+
table: z.ZodString;
|
|
639
|
+
fields: z.ZodRecord<z.ZodString, z.ZodString>;
|
|
640
|
+
publish: z.ZodDefault<z.ZodEnum<{
|
|
641
|
+
draft: "draft";
|
|
642
|
+
auto: "auto";
|
|
643
|
+
}>>;
|
|
644
|
+
}, z.core.$strip>>;
|
|
541
645
|
}, z.core.$strip>>>;
|
|
542
646
|
look?: z.ZodOptional<z.ZodObject<{
|
|
543
647
|
uploadedFonts?: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
@@ -563,13 +667,13 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
563
667
|
floating: "floating";
|
|
564
668
|
}>>;
|
|
565
669
|
layout: z.ZodDefault<z.ZodEnum<{
|
|
670
|
+
left: "left";
|
|
566
671
|
spread: "spread";
|
|
567
672
|
centered: "centered";
|
|
568
|
-
left: "left";
|
|
569
673
|
}>>;
|
|
570
674
|
menuShows: z.ZodDefault<z.ZodEnum<{
|
|
571
|
-
both: "both";
|
|
572
675
|
icon: "icon";
|
|
676
|
+
both: "both";
|
|
573
677
|
word: "word";
|
|
574
678
|
}>>;
|
|
575
679
|
menuStyle: z.ZodOptional<z.ZodString>;
|
|
@@ -586,39 +690,39 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
586
690
|
color: z.ZodString;
|
|
587
691
|
}, z.core.$strip>>>;
|
|
588
692
|
type: z.ZodDefault<z.ZodObject<{
|
|
589
|
-
|
|
693
|
+
h1: z.ZodOptional<z.ZodObject<{
|
|
590
694
|
size: z.ZodOptional<z.ZodNumber>;
|
|
591
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
695
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
592
696
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
593
697
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
594
698
|
}, z.core.$strip>>;
|
|
595
|
-
|
|
699
|
+
h2: z.ZodOptional<z.ZodObject<{
|
|
596
700
|
size: z.ZodOptional<z.ZodNumber>;
|
|
597
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
701
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
598
702
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
599
703
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
600
704
|
}, z.core.$strip>>;
|
|
601
|
-
|
|
705
|
+
h3: z.ZodOptional<z.ZodObject<{
|
|
602
706
|
size: z.ZodOptional<z.ZodNumber>;
|
|
603
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
707
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
604
708
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
605
709
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
606
710
|
}, z.core.$strip>>;
|
|
607
|
-
|
|
711
|
+
small: z.ZodOptional<z.ZodObject<{
|
|
608
712
|
size: z.ZodOptional<z.ZodNumber>;
|
|
609
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
713
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
610
714
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
611
715
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
612
716
|
}, z.core.$strip>>;
|
|
613
717
|
body: z.ZodOptional<z.ZodObject<{
|
|
614
718
|
size: z.ZodOptional<z.ZodNumber>;
|
|
615
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
719
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
616
720
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
617
721
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
618
722
|
}, z.core.$strip>>;
|
|
619
|
-
|
|
723
|
+
display: z.ZodOptional<z.ZodObject<{
|
|
620
724
|
size: z.ZodOptional<z.ZodNumber>;
|
|
621
|
-
weight: z.ZodOptional<z.ZodLiteral<400 |
|
|
725
|
+
weight: z.ZodOptional<z.ZodLiteral<400 | 600 | 500 | 300 | 700>>;
|
|
622
726
|
tracking: z.ZodOptional<z.ZodNumber>;
|
|
623
727
|
leading: z.ZodOptional<z.ZodNumber>;
|
|
624
728
|
}, z.core.$strip>>;
|
|
@@ -664,6 +768,7 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
664
768
|
headingFont?: z.ZodDefault<z.ZodString> | undefined;
|
|
665
769
|
bodyFont?: z.ZodDefault<z.ZodString> | undefined;
|
|
666
770
|
}, z.core.$strip>> | undefined;
|
|
771
|
+
format: z.ZodOptional<z.ZodNumber>;
|
|
667
772
|
url: z.ZodURL;
|
|
668
773
|
lang: z.ZodDefault<z.ZodString>;
|
|
669
774
|
business: z.ZodObject<{
|
|
@@ -744,6 +849,31 @@ export declare function defineSite<const B extends Record<string, z.ZodObject>>(
|
|
|
744
849
|
}, z.core.$strip>>>;
|
|
745
850
|
note: z.ZodOptional<z.ZodString>;
|
|
746
851
|
}, z.core.$strip>>;
|
|
852
|
+
ownHeader: z.ZodOptional<z.ZodObject<{
|
|
853
|
+
name: z.ZodOptional<z.ZodString>;
|
|
854
|
+
root: z.ZodType<Node, unknown, z.core.$ZodTypeInternals<Node, unknown>>;
|
|
855
|
+
}, z.core.$strip>>;
|
|
856
|
+
ownFooter: z.ZodOptional<z.ZodObject<{
|
|
857
|
+
name: z.ZodOptional<z.ZodString>;
|
|
858
|
+
root: z.ZodType<Node, unknown, z.core.$ZodTypeInternals<Node, unknown>>;
|
|
859
|
+
}, z.core.$strip>>;
|
|
860
|
+
consent: z.ZodOptional<z.ZodObject<{
|
|
861
|
+
on: z.ZodDefault<z.ZodBoolean>;
|
|
862
|
+
text: z.ZodDefault<z.ZodString>;
|
|
863
|
+
accept: z.ZodDefault<z.ZodString>;
|
|
864
|
+
decline: z.ZodDefault<z.ZodString>;
|
|
865
|
+
policy: z.ZodOptional<z.ZodObject<{
|
|
866
|
+
label: z.ZodString;
|
|
867
|
+
href: z.ZodString;
|
|
868
|
+
}, z.core.$strip>>;
|
|
869
|
+
place: z.ZodDefault<z.ZodEnum<{
|
|
870
|
+
top: "top";
|
|
871
|
+
bottom: "bottom";
|
|
872
|
+
"bottom-left": "bottom-left";
|
|
873
|
+
"bottom-right": "bottom-right";
|
|
874
|
+
}>>;
|
|
875
|
+
design: z.ZodOptional<z.ZodString>;
|
|
876
|
+
}, z.core.$strip>>;
|
|
747
877
|
redirects: z.ZodDefault<z.ZodArray<z.ZodObject<{
|
|
748
878
|
from: z.ZodString;
|
|
749
879
|
to: z.ZodString;
|
package/dist/content/index.js
CHANGED
|
@@ -11,11 +11,16 @@
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { checkStructure, describePath } from "../schema.js";
|
|
13
13
|
import { presets } from "../sections/presets.js";
|
|
14
|
+
import { built, component, treeProblems } from "../tree/index.js";
|
|
15
|
+
import { CONTENT_FORMAT } from "../content-migrate.js";
|
|
16
|
+
import { consent } from "../consent.js";
|
|
17
|
+
import { FIELD_KINDS, itemPath } from "./lists.js";
|
|
14
18
|
import { buttonStyleName, COLOUR_ROLES, colourOf, isDark, lookProblems, lookSchema, swatchSlug } from "./look.js";
|
|
15
19
|
export { COLOUR_ROLES, colourOf, contrast, HEADER_LAYOUTS, HEADER_STYLES, headerOf, isDark, KIT_FONTS, KIT_TYPE, lookCss, lookProblems, lookVars, swatchSlug, TYPE_ROLES, uploadedFontCss, buttonStyleClass, BUTTON_SIZES, MAX_BUTTON_STYLES, THEME_BUTTONS, } from "./look.js";
|
|
16
20
|
export { fontFaceCss, fontFiles, googleFamily, googleFont, googleFonts, isFontName, servedAt } from "../fonts-google.js";
|
|
17
21
|
export { blockLabel, checkStructure, describePath } from "../schema.js";
|
|
18
22
|
export { z };
|
|
23
|
+
export { allPages, FIELD_KINDS, fromList, itemOf, itemPages, itemPath, PAGE_LINK, THIS_ITEM, withListItems } from "./lists.js";
|
|
19
24
|
// Fields carry an "x-ui" hint in the JSON Schema, so CalOS draws the right control: a text area, a
|
|
20
25
|
// Markdown box, a picture picker.
|
|
21
26
|
export const text = z.string().trim().min(1);
|
|
@@ -213,6 +218,76 @@ export function footerOf(site) {
|
|
|
213
218
|
* A site's content shape from its blocks: each a name and the fields it has. The site's own block
|
|
214
219
|
* type is `z.output<typeof content.schema>["pages"][number]["blocks"][number]`.
|
|
215
220
|
*/
|
|
221
|
+
/** A list's key and a field's: what Shows and Repeats for name them by (`lists.products.items`, `this.price`). */
|
|
222
|
+
const listKey = z.string().regex(/^[a-z][a-zA-Z0-9]{0,39}$/, { error: "Letters and numbers, starting with a lowercase letter, like products or teamMembers" });
|
|
223
|
+
const fieldKey = z
|
|
224
|
+
.string()
|
|
225
|
+
.regex(/^[a-z][a-zA-Z0-9]{0,39}$/, { error: "Letters and numbers, starting with a lowercase letter, like name or price" })
|
|
226
|
+
.refine((k) => k !== "id" && k !== "slug", { error: "id and slug are an item's own" });
|
|
227
|
+
/** An item: its id, its address part, and its values (each checked against its field's kind: listProblems). */
|
|
228
|
+
const listItem = z
|
|
229
|
+
.object({
|
|
230
|
+
id: z.string().regex(/^[\w-]{1,64}$/),
|
|
231
|
+
slug: z.string().max(80).regex(/^[a-z0-9]+(-[a-z0-9]+)*$/, { error: "Lowercase letters, numbers and dashes, like walnut-desk" }),
|
|
232
|
+
})
|
|
233
|
+
.catchall(z.unknown());
|
|
234
|
+
/** Each kind of a list's field, as a value is checked. */
|
|
235
|
+
const VALUE = {
|
|
236
|
+
text: z.string().trim().max(300),
|
|
237
|
+
longText: z.string().max(5000),
|
|
238
|
+
image,
|
|
239
|
+
link: href,
|
|
240
|
+
number: z.number().finite(),
|
|
241
|
+
date: z.string().regex(/^\d{4}-\d{2}-\d{2}$/, { error: "A date like 2026-11-09" }),
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* What a list's shape can't say alone: fields named once, each item's values of their field's kind
|
|
245
|
+
* and no others, ids and addresses used once, a page titled and described by a field of words, and no
|
|
246
|
+
* item at the address of one of the site's pages.
|
|
247
|
+
*/
|
|
248
|
+
function listProblems(site) {
|
|
249
|
+
const out = [];
|
|
250
|
+
const lists = (site.lists ?? {});
|
|
251
|
+
const pagePaths = new Set(site.pages.map((p) => p.path));
|
|
252
|
+
for (const [key, list] of Object.entries(lists)) {
|
|
253
|
+
const at = ["lists", key];
|
|
254
|
+
const fields = new Map();
|
|
255
|
+
list.fields.forEach((f, i) => {
|
|
256
|
+
if (fields.has(f.key))
|
|
257
|
+
out.push({ path: [...at, "fields", i, "key"], message: `Two fields are called ${f.key}` });
|
|
258
|
+
fields.set(f.key, f.kind);
|
|
259
|
+
});
|
|
260
|
+
const ids = new Set();
|
|
261
|
+
const slugs = new Set();
|
|
262
|
+
list.items.forEach((item, i) => {
|
|
263
|
+
if (ids.has(item.id))
|
|
264
|
+
out.push({ path: [...at, "items", i, "id"], message: `Two items have the id ${item.id}` });
|
|
265
|
+
ids.add(item.id);
|
|
266
|
+
if (slugs.has(item.slug))
|
|
267
|
+
out.push({ path: [...at, "items", i, "slug"], message: `Two items have the address ${item.slug}` });
|
|
268
|
+
slugs.add(item.slug);
|
|
269
|
+
for (const [k, v] of Object.entries(item)) {
|
|
270
|
+
if (k === "id" || k === "slug" || v === undefined || v === null || v === "")
|
|
271
|
+
continue;
|
|
272
|
+
const kind = fields.get(k);
|
|
273
|
+
if (!kind)
|
|
274
|
+
out.push({ path: [...at, "items", i, k], message: `${k} isn't one of ${list.name}'s fields` });
|
|
275
|
+
else if (!VALUE[kind].safeParse(v).success)
|
|
276
|
+
out.push({ path: [...at, "items", i, k], message: `Not a ${kind === "longText" ? "text" : kind} value` });
|
|
277
|
+
}
|
|
278
|
+
if (list.page && pagePaths.has(itemPath(list.page, item.slug, site.trailingSlash !== false)))
|
|
279
|
+
out.push({ path: [...at, "items", i, "slug"], message: `There's a page at ${itemPath(list.page, item.slug, site.trailingSlash !== false)} already` });
|
|
280
|
+
});
|
|
281
|
+
if (list.page) {
|
|
282
|
+
const words = (k) => !k || fields.get(k) === "text" || fields.get(k) === "longText";
|
|
283
|
+
if (!fields.has(list.page.title) || fields.get(list.page.title) !== "text")
|
|
284
|
+
out.push({ path: [...at, "page", "title"], message: "The title is one of the list's fields of words" });
|
|
285
|
+
if (list.page.description && (!fields.has(list.page.description) || !words(list.page.description)))
|
|
286
|
+
out.push({ path: [...at, "page", "description"], message: "The description is one of the list's fields of words" });
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
return out;
|
|
290
|
+
}
|
|
216
291
|
export function defineSite(blocks, o = {}) {
|
|
217
292
|
const names = Object.keys(blocks);
|
|
218
293
|
if (!names.length)
|
|
@@ -229,6 +304,14 @@ export function defineSite(blocks, o = {}) {
|
|
|
229
304
|
const page = z.object({ ...pageBase(trailingSlash), ...o.pageExtend, blocks: z.array(union).min(1) });
|
|
230
305
|
const schema = z
|
|
231
306
|
.object({
|
|
307
|
+
/** Which format of the kit's the content is in (../content-migrate.ts): none for the first; set by the migrations, never edited. */
|
|
308
|
+
format: z
|
|
309
|
+
.number()
|
|
310
|
+
.int()
|
|
311
|
+
.min(0)
|
|
312
|
+
.max(CONTENT_FORMAT, { error: `A newer format than this kit's (${CONTENT_FORMAT}): the site needs a newer @caltho/site-kit` })
|
|
313
|
+
.optional()
|
|
314
|
+
.meta({ title: "Content format", readOnly: true, "x-ui": "hidden" }),
|
|
232
315
|
/** The address it's served at once live (its main domain). */
|
|
233
316
|
url: z.url({ protocol: /^https$/, error: "The site's address, starting https://" }).meta({ title: "Web address" }),
|
|
234
317
|
lang: z.string().default("en-US").meta({ title: "Language" }),
|
|
@@ -267,11 +350,48 @@ export function defineSite(blocks, o = {}) {
|
|
|
267
350
|
})
|
|
268
351
|
.optional()
|
|
269
352
|
.meta({ title: "Footer" }),
|
|
353
|
+
/**
|
|
354
|
+
* A header or footer of the business's own, built as a tree like a built section (../tree), in
|
|
355
|
+
* place of the kit's: its links, logo and button are elements, a phone menu an accordion. Left
|
|
356
|
+
* out, the kit's header and footer (from the menu, footer and Look above).
|
|
357
|
+
*/
|
|
358
|
+
ownHeader: built.optional().meta({ title: "Your own header", "x-ui": "hidden" }),
|
|
359
|
+
ownFooter: built.optional().meta({ title: "Your own footer", "x-ui": "hidden" }),
|
|
360
|
+
/** A cookie banner, and visits counted only once a visitor accepts: off unless turned on (../consent.ts). */
|
|
361
|
+
consent: consent.optional(),
|
|
270
362
|
/** Old addresses kept answering, when CalOS doesn't supply them at build. */
|
|
271
363
|
redirects: z.array(z.object({ from: z.string().startsWith("/"), to: href, status: z.union([z.literal(301), z.literal(302)]).default(301) })).default([]),
|
|
272
364
|
...(o.look ? { look: lookSchema(o.look) } : {}),
|
|
273
365
|
...o.extend,
|
|
274
366
|
pages: z.array(page).min(1),
|
|
367
|
+
/**
|
|
368
|
+
* The site's lists (./lists.ts): items of one kind kept once, repeated by built sections and,
|
|
369
|
+
* where a list has a page, each at its own address from one design.
|
|
370
|
+
*/
|
|
371
|
+
lists: z
|
|
372
|
+
.record(listKey, z.object({
|
|
373
|
+
name: text.meta({ title: "Name" }),
|
|
374
|
+
fields: z.array(z.object({ key: fieldKey, label: text, kind: z.enum(FIELD_KINDS) })).max(30),
|
|
375
|
+
items: z.array(listItem).max(2000).default([]),
|
|
376
|
+
page: z
|
|
377
|
+
.object({
|
|
378
|
+
path: pageBase(trailingSlash).path,
|
|
379
|
+
title: fieldKey.meta({ title: "The field each page is titled by" }),
|
|
380
|
+
description: fieldKey.optional().meta({ title: "The field each page is described by" }),
|
|
381
|
+
blocks: z.array(union).min(1),
|
|
382
|
+
})
|
|
383
|
+
.optional()
|
|
384
|
+
.meta({ title: "A page for each item" }),
|
|
385
|
+
/** Where its items come from, when CalOS fills it from one of the business's tables: kept by CalOS, never drawn. */
|
|
386
|
+
source: z
|
|
387
|
+
.object({ table: z.string().max(60), fields: z.record(z.string(), z.string().max(60)), publish: z.enum(["draft", "auto"]).default("draft") })
|
|
388
|
+
.optional()
|
|
389
|
+
.meta({ "x-ui": "hidden" }),
|
|
390
|
+
}))
|
|
391
|
+
.default({})
|
|
392
|
+
.meta({ title: "Lists", "x-ui": "hidden" }),
|
|
393
|
+
/** Trees kept once and used by name (`use` blocks), changed in one place for every use: on a site that takes built sections. */
|
|
394
|
+
...(names.includes("built") || names.includes("use") ? { components: z.array(component).max(50).default([]).meta({ title: "Components" }) } : {}),
|
|
275
395
|
/** Sections the business put together and named, to add again anywhere ("Package card"): CalOS offers them beside the site's own kinds. */
|
|
276
396
|
saved: z
|
|
277
397
|
.array(z.object({ name: text.meta({ title: "Name" }), block: union }))
|
|
@@ -289,6 +409,10 @@ export function defineSite(blocks, o = {}) {
|
|
|
289
409
|
if (placed)
|
|
290
410
|
for (const i of backgroundProblems(s, o.look))
|
|
291
411
|
ctx.addIssue({ code: "custom", path: i.path, message: i.message });
|
|
412
|
+
for (const i of builtProblems(s))
|
|
413
|
+
ctx.addIssue({ code: "custom", path: i.path, message: i.message });
|
|
414
|
+
for (const i of listProblems(s))
|
|
415
|
+
ctx.addIssue({ code: "custom", path: i.path, message: i.message });
|
|
292
416
|
o.refine?.(s, ctx);
|
|
293
417
|
});
|
|
294
418
|
return {
|
|
@@ -332,6 +456,37 @@ function backgroundProblems(site, look) {
|
|
|
332
456
|
saved.forEach((s, i) => s?.block && check(s.block, ["saved", i, "block"]));
|
|
333
457
|
return out;
|
|
334
458
|
}
|
|
459
|
+
/**
|
|
460
|
+
* What a built section's tree can't say alone (../tree: depth, size, an id used twice), for every
|
|
461
|
+
* tree the content keeps, and that each component a `use` block names is one the site has.
|
|
462
|
+
*/
|
|
463
|
+
function builtProblems(site) {
|
|
464
|
+
const out = [];
|
|
465
|
+
const components = Array.isArray(site.components) ? site.components : [];
|
|
466
|
+
const keys = new Set();
|
|
467
|
+
components.forEach((c, i) => {
|
|
468
|
+
if (c?.key && keys.has(c.key))
|
|
469
|
+
out.push({ path: ["components", i, "key"], message: `Two components are called ${c.key}` });
|
|
470
|
+
if (c?.key)
|
|
471
|
+
keys.add(c.key);
|
|
472
|
+
if (c?.root)
|
|
473
|
+
for (const m of treeProblems(c.root))
|
|
474
|
+
out.push({ path: ["components", i, "root"], message: m });
|
|
475
|
+
});
|
|
476
|
+
const design = site.consent?.design;
|
|
477
|
+
if (design && !keys.has(design))
|
|
478
|
+
out.push({ path: ["consent", "design"], message: `The site has no component called ${design}` });
|
|
479
|
+
const check = (b, at) => {
|
|
480
|
+
if (b.type === "built" && b.root && typeof b.root === "object")
|
|
481
|
+
for (const m of treeProblems(b.root))
|
|
482
|
+
out.push({ path: [...at, "root"], message: m });
|
|
483
|
+
if (b.type === "use" && typeof b.component === "string" && !keys.has(b.component))
|
|
484
|
+
out.push({ path: [...at, "component"], message: `The site has no component called ${b.component}` });
|
|
485
|
+
};
|
|
486
|
+
site.pages.forEach((p, i) => p.blocks.forEach((b, j) => check(b, ["pages", i, "blocks", j])));
|
|
487
|
+
(site.saved ?? []).forEach((s, i) => s?.block && check(s.block, ["saved", i, "block"]));
|
|
488
|
+
return out;
|
|
489
|
+
}
|
|
335
490
|
/** Search results cut a title at about 60 characters and a description at about 160: said, not refused, since the page still works. */
|
|
336
491
|
function lengthWarnings(site) {
|
|
337
492
|
return site.pages.flatMap((p, i) => [
|