@acms-subir/core 0.3.16 → 0.3.18
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 +16 -0
- package/cli/common.mjs +2 -2
- package/cli/main.mjs +10 -3
- package/cli/migrations.generated.mjs +71 -1
- package/cli/remote.mjs +1 -1
- package/cli/sync.mjs +876 -0
- package/docs/environment-sync.md +302 -0
- package/integration.mjs +2 -0
- package/package.json +1 -1
- package/section-library/upcoming-events/UpcomingEvents.astro +26 -17
- package/section-library/upcoming-events/section.json +41 -0
- package/src/actions/index.ts +5 -1
- package/src/components/CalendarFallbackImage.tsx +18 -0
- package/src/components/DesignAccess.tsx +3 -0
- package/src/components/EventPage.astro +4 -2
- package/src/components/LinksManager.tsx +86 -55
- package/src/components/ThemeSectionsEditor.tsx +13 -1
- package/src/layouts/Site.astro +1 -0
- package/src/lib/calendar/cards.ts +4 -2
- package/src/lib/calendar/images.ts +17 -0
- package/src/lib/editor/schemas.ts +2 -2
- package/src/lib/editor/site-data.ts +5 -3
- package/src/lib/links-avatar.ts +10 -0
- package/src/lib/mobile/links.ts +4 -0
- package/src/lib/mobile/schemas.ts +2 -2
- package/src/lib/repo/migrations.ts +26 -0
- package/src/lib/repo/sql.ts +8 -3
- package/src/lib/repo/types.ts +3 -1
- package/src/lib/schema.ts +14 -0
- package/src/lib/sync/auth.ts +24 -0
- package/src/lib/sync/catalog.ts +250 -0
- package/src/lib/sync/migration.ts +51 -0
- package/src/lib/sync/protocol.mjs +125 -0
- package/src/lib/sync/service.ts +994 -0
- package/src/lib/sync/store.ts +349 -0
- package/src/pages/admin/calendar/settings.astro +21 -2
- package/src/pages/admin/integrations.astro +2 -0
- package/src/pages/admin/links.astro +1 -1
- package/src/pages/api/agent/docs.ts +2 -0
- package/src/pages/api/design/keys.ts +7 -3
- package/src/pages/api/sync/index.ts +114 -0
- package/src/pages/api/sync/media.ts +90 -0
- package/src/pages/links.astro +13 -2
- package/src/styles/admin.css +27 -36
- package/src/styles/page-transitions.css +27 -0
- package/src/styles/site.css +3 -1
- package/src/styles/theme-editor.css +47 -12
- package/src/theme-sdk/index.ts +1 -0
package/src/pages/links.astro
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
import LiveCard from '../components/LiveCard.astro';
|
|
3
|
+
import { linksAvatarStyles } from '../lib/links-avatar';
|
|
3
4
|
import Site from '../layouts/Site.astro';
|
|
4
5
|
import { getRepo } from '../lib/repo';
|
|
5
6
|
import { cleanEventName } from '../lib/analytics';
|
|
@@ -17,6 +18,7 @@ const socials = navItems
|
|
|
17
18
|
.map((n) => ({ ...n, path: socialIconPath(n.url) }));
|
|
18
19
|
|
|
19
20
|
// links page has its own identity; falls back to the site's until it's set
|
|
21
|
+
const avatarStyles = linksAvatarStyles(settings);
|
|
20
22
|
const profileName = settings.linksName || settings.siteTitle;
|
|
21
23
|
const profileBio = settings.linksBio || settings.tagline;
|
|
22
24
|
|
|
@@ -94,8 +96,17 @@ const visible = links.filter((l) => {
|
|
|
94
96
|
|
|
95
97
|
<Site title="Links" bare>
|
|
96
98
|
<div class="links-page">
|
|
97
|
-
{settings.linksAvatar &&
|
|
98
|
-
|
|
99
|
+
{settings.linksAvatar && (
|
|
100
|
+
<div class="links-avatar" style={avatarStyles.frame}>
|
|
101
|
+
<img src={settings.linksAvatar} alt={profileName} style={avatarStyles.image} />
|
|
102
|
+
</div>
|
|
103
|
+
)}
|
|
104
|
+
<h1>{profileName}{settings.linksVerified && (
|
|
105
|
+
<svg class="links-verified" viewBox="0 0 24 24" role="img" aria-label="Verified">
|
|
106
|
+
<path fill="currentColor" d="m12 1 3 2.2 3.7.1 1.2 3.5L22 10l-1 3.6.3 3.7-3.4 1.5-2.4 2.8L12 20.5l-3.5 1.1-2.4-2.8-3.4-1.5.3-3.7L2 10l2.1-3.2 1.2-3.5 3.7-.1Z" />
|
|
107
|
+
<path d="m7.5 11.8 3 3 6-6" fill="none" stroke="var(--bg)" stroke-width="2.2" stroke-linecap="round" stroke-linejoin="round" />
|
|
108
|
+
</svg>
|
|
109
|
+
)}</h1>
|
|
99
110
|
{profileBio && <p class="tagline">{profileBio}</p>}
|
|
100
111
|
{socials.length > 0 && (
|
|
101
112
|
<nav class="social-nav" aria-label="Social">
|
package/src/styles/admin.css
CHANGED
|
@@ -504,6 +504,7 @@ input.bare.mono { font-family: ui-monospace, 'SF Mono', monospace; font-size: 12
|
|
|
504
504
|
display: flex; align-items: center; gap: 8px; padding: 7px 8px 7px 16px;
|
|
505
505
|
background: var(--text); color: var(--bg); border-radius: var(--r-lg); box-shadow: var(--shadow-pop); white-space: nowrap;
|
|
506
506
|
}
|
|
507
|
+
@media (max-width: 420px) { .lm-savebar { width: calc(100% - 24px); flex-wrap: wrap; justify-content: flex-end; } .lm-savebar > span { flex: 1 0 100%; } }
|
|
507
508
|
.lm-savebar span { margin-right: 8px; font-weight: 600; font-size: 13px; }
|
|
508
509
|
.lm-savebar .btn:not(.primary) { background: transparent; color: var(--bg); border-color: color-mix(in srgb, var(--bg) 30%, transparent); box-shadow: none; }
|
|
509
510
|
.lm-url { flex: 1; min-width: 0; background: var(--panel); border: 1px solid var(--line-strong); border-radius: var(--r-sm); padding: 4px 10px; font-size: 12px; color: var(--text-2); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
@@ -518,44 +519,34 @@ input.bare.mono { font-family: ui-monospace, 'SF Mono', monospace; font-size: 12
|
|
|
518
519
|
color: var(--text-2); background: var(--sel); border-radius: 5px; padding: 2px 7px;
|
|
519
520
|
}
|
|
520
521
|
|
|
521
|
-
/* profile
|
|
522
|
-
.lm-profile {
|
|
523
|
-
.lm-
|
|
524
|
-
.lm-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
background: var(--sel);
|
|
528
|
-
user-select: none; cursor: pointer; position: relative; overflow: hidden; font-family: inherit;
|
|
529
|
-
}
|
|
522
|
+
/* Explicit profile controls stay visible on touch screens, too. */
|
|
523
|
+
.lm-profile-card { padding: 20px; margin-bottom: 20px; border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--panel); }
|
|
524
|
+
.lm-profile-card h2 { margin: 0 0 18px; font-size: 16px; }
|
|
525
|
+
.lm-profile { display: flex; gap: 20px; align-items: flex-start; }
|
|
526
|
+
.lm-avatarwrap { display: flex; flex-direction: column; align-items: center; gap: 8px; flex: 0 0 110px; }
|
|
527
|
+
.lm-avatar { width: 80px; height: 80px; border-radius: 50%; border: 1px solid var(--line); padding: 0; display: grid; place-items: center; color: var(--text-2); background: var(--sel); cursor: pointer; position: relative; overflow: hidden; }
|
|
530
528
|
.lm-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
531
|
-
.lm-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
}
|
|
536
|
-
.lm-
|
|
537
|
-
.lm-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
font-size: 9px; cursor: pointer; display: grid; place-items: center; padding: 0;
|
|
541
|
-
opacity: 0; transition: opacity 0.12s;
|
|
542
|
-
}
|
|
543
|
-
.lm-avatarwrap:hover .lm-avatar-remove { opacity: 1; }
|
|
544
|
-
.lm-avatar-remove:hover { color: var(--red); border-color: var(--red); }
|
|
529
|
+
.lm-photo-controls { min-width: 0; margin: 0 0 20px; padding: 0 0 16px; border: 0; border-bottom: 1px solid var(--line); }
|
|
530
|
+
.lm-photo-controls legend { margin-bottom: 10px; padding: 0; font-size: 12px; font-weight: 600; }
|
|
531
|
+
.lm-photo-options { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
|
|
532
|
+
.lm-photo-options label { flex: 1 1 130px; min-width: 0; }
|
|
533
|
+
.lm-photo-controls label { font-size: 12px; }
|
|
534
|
+
.lm-photo-controls select { display: block; width: 100%; margin-top: 5px; }
|
|
535
|
+
.lm-photo-controls output { margin-left: 6px; font-variant-numeric: tabular-nums; font-weight: 600; }
|
|
536
|
+
.lm-photo-controls input[type='range'] { display: block; width: 100%; padding: 0; margin: 8px 0; accent-color: var(--accent); }
|
|
537
|
+
.lm-photo-controls p { margin: 0 0 10px; color: var(--muted); font-size: 12px; line-height: 1.5; }
|
|
545
538
|
.lm-profile-fields { flex: 1; min-width: 0; }
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
}
|
|
551
|
-
.lm-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
}
|
|
556
|
-
.lm-profile-
|
|
557
|
-
input.lm-profile-name:hover, .lm-profile-bio:hover { border-color: var(--line); }
|
|
558
|
-
input.lm-profile-name:focus, .lm-profile-bio:focus { border-color: var(--accent); background: var(--panel); }
|
|
539
|
+
.lm-profile-fields > label { display: block; margin-bottom: 6px; font-size: 12px; font-weight: 600; }
|
|
540
|
+
input.lm-profile-name, .lm-profile-bio { display: block; width: 100%; margin: 0 0 14px; padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--r-md); background: var(--bg); color: var(--text); font: inherit; }
|
|
541
|
+
.lm-profile-bio { resize: vertical; min-height: 70px; }
|
|
542
|
+
.lm-profile-fields > .lm-verification { display: flex; align-items: center; gap: 10px; margin: 4px 0 0; cursor: pointer; }
|
|
543
|
+
.lm-verification input { appearance: none; width: 34px; height: 20px; padding: 2px; margin: 0; flex: 0 0 auto; border: 1px solid var(--line-strong); border-radius: 99px; background: var(--line-strong); cursor: pointer; }
|
|
544
|
+
.lm-verification input::before { content: ''; display: block; width: 14px; height: 14px; border-radius: 50%; background: var(--panel); transition: transform 0.15s; }
|
|
545
|
+
.lm-verification input:checked { background: var(--accent); border-color: var(--accent); }
|
|
546
|
+
.lm-verification input:checked::before { transform: translateX(14px); }
|
|
547
|
+
.lm-verification input:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
|
|
548
|
+
.lm-verification small { display: block; margin-top: 3px; color: var(--muted); font-weight: 400; }
|
|
549
|
+
@media (max-width: 540px) { .lm-profile { flex-direction: column; } .lm-avatarwrap { flex-basis: auto; } .lm-profile-fields { width: 100%; } }
|
|
559
550
|
|
|
560
551
|
/* add-block picker */
|
|
561
552
|
.lm-picker-head { display: flex; align-items: center; gap: 8px; }
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* Native same-origin document transitions. Both pages opt in through Site.astro;
|
|
2
|
+
the browser keeps normal navigation, history, forms and script lifecycles. */
|
|
3
|
+
@view-transition {
|
|
4
|
+
navigation: auto;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
/* Keep the browser's built-in crossfade; themes can adjust its pace. */
|
|
8
|
+
@layer base {
|
|
9
|
+
::view-transition-group(root),
|
|
10
|
+
::view-transition-old(root),
|
|
11
|
+
::view-transition-new(root) {
|
|
12
|
+
animation-duration: var(--page-transition-duration, 180ms);
|
|
13
|
+
animation-timing-function: var(--page-transition-easing, ease-out);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@media (prefers-reduced-motion: reduce) {
|
|
18
|
+
@view-transition {
|
|
19
|
+
navigation: none;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
::view-transition-group(*),
|
|
23
|
+
::view-transition-old(*),
|
|
24
|
+
::view-transition-new(*) {
|
|
25
|
+
animation: none !important;
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/styles/site.css
CHANGED
|
@@ -488,10 +488,12 @@ li::marker { color: var(--muted); }
|
|
|
488
488
|
/* ---- links page (/links) ------------------------------------------------------------ */
|
|
489
489
|
.links-page { max-width: 480px; margin: 0 auto; text-align: center; padding: 48px 0 24px; }
|
|
490
490
|
.links-page h1 { font-size: 26px; letter-spacing: -0.03em; margin: 0 0 6px; }
|
|
491
|
+
.links-verified { display: inline-block; width: 0.8em; height: 0.8em; margin-left: 0.25em; vertical-align: -0.02em; color: var(--muted); }
|
|
491
492
|
.links-avatar {
|
|
492
|
-
width: 96px; height: 96px; border-radius: 50%;
|
|
493
|
+
width: 96px; height: 96px; border-radius: 50%; overflow: hidden; background: var(--panel); margin: 0 auto 16px;
|
|
493
494
|
box-shadow: 0 0 0 4px var(--panel), var(--sh-2);
|
|
494
495
|
}
|
|
496
|
+
.links-avatar img { width: 100%; height: 100%; display: block; object-fit: cover; transform-origin: center; }
|
|
495
497
|
.links-page .tagline { color: var(--muted); margin: 0 0 18px; white-space: pre-wrap; font-size: 15.5px; }
|
|
496
498
|
.links-page .social-nav { justify-content: center; margin: 0 0 26px; }
|
|
497
499
|
.link-btn {
|
|
@@ -36,12 +36,25 @@
|
|
|
36
36
|
.te-mode .seg > [role='radio'] { min-height: 28px; }
|
|
37
37
|
.te-mode .seg > [role='radio']:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
|
|
38
38
|
|
|
39
|
-
/* section list
|
|
40
|
-
|
|
39
|
+
/* section list: each section is its own card, with a gap, alternating surface and
|
|
40
|
+
a stronger frame when open, so it is clear where one section ends */
|
|
41
|
+
.te-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 6px; }
|
|
41
42
|
.te-list.is-inactive { opacity: 0.72; }
|
|
42
|
-
.te-none { padding: 14px 16px; margin: 0; }
|
|
43
|
-
.te-sec
|
|
44
|
-
|
|
43
|
+
.te-none { padding: 14px 16px; margin: 0; border: 1px dashed var(--line-strong); border-radius: var(--r-lg); }
|
|
44
|
+
.te-sec {
|
|
45
|
+
border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--panel);
|
|
46
|
+
transition: border-color 150ms ease-out, box-shadow 150ms ease-out;
|
|
47
|
+
}
|
|
48
|
+
.te-sec:nth-child(even) { background: var(--panel-2); }
|
|
49
|
+
.te-sec:hover { border-color: var(--line-strong); }
|
|
50
|
+
.te-sec.is-hidden { border-style: dashed; }
|
|
51
|
+
.te-sec.is-open {
|
|
52
|
+
margin: 8px 0; background: var(--panel); border-color: var(--line-strong);
|
|
53
|
+
box-shadow: var(--shadow-card);
|
|
54
|
+
}
|
|
55
|
+
.te-sec.is-open:first-child { margin-top: 0; }
|
|
56
|
+
.te-sec.is-open:last-child { margin-bottom: 0; }
|
|
57
|
+
.te-sec-head { display: flex; align-items: center; gap: 4px; padding: 4px 6px 4px 0; border-radius: calc(var(--r-lg) - 1px); }
|
|
45
58
|
.te-sec-toggle {
|
|
46
59
|
flex: 1; min-width: 0; display: flex; align-items: center; gap: 8px; min-height: 40px;
|
|
47
60
|
padding: 6px 8px 6px 12px; border: 0; background: none; font: inherit; color: var(--text); text-align: left;
|
|
@@ -51,7 +64,9 @@
|
|
|
51
64
|
.te-sec-toggle:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
|
|
52
65
|
.te-sec-toggle svg { width: 14px; height: 14px; flex-shrink: 0; color: var(--muted); transition: transform 150ms ease-out; }
|
|
53
66
|
.te-sec.is-open .te-sec-toggle svg { transform: rotate(90deg); }
|
|
54
|
-
.te-sec.is-open .te-sec-head {
|
|
67
|
+
.te-sec.is-open .te-sec-head {
|
|
68
|
+
background: var(--sel); border-radius: calc(var(--r-lg) - 1px) calc(var(--r-lg) - 1px) 0 0;
|
|
69
|
+
}
|
|
55
70
|
.te-sec.is-open .te-sec-name { font-weight: 600; }
|
|
56
71
|
.te-sec-name { font-size: 13.5px; font-weight: 500; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
57
72
|
.te-sec-meta { font-size: 12px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
@@ -61,10 +76,28 @@
|
|
|
61
76
|
.te-sec-actions .icon-btn:disabled { opacity: 0.35; cursor: default; background: none; }
|
|
62
77
|
.te-sec-actions .icon-btn:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
|
|
63
78
|
.te svg { fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round; }
|
|
64
|
-
.te-sec-body { padding:
|
|
79
|
+
.te-sec-body { padding: 16px 16px 14px; border-top: 1px solid var(--line-strong); }
|
|
65
80
|
.te-sec-body textarea { resize: vertical; min-height: 84px; }
|
|
66
|
-
.te-sec-foot { display: flex; flex-wrap: wrap; gap: 6px; padding-top:
|
|
67
|
-
.te-sec-foot
|
|
81
|
+
.te-sec-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding-top: 14px; margin-top: 4px; border-top: 1px solid var(--line); }
|
|
82
|
+
.te-sec-foot:empty { display: none; }
|
|
83
|
+
.te-sec-foot .te-publish-one { margin-left: auto; }
|
|
84
|
+
.te-sec-foot .btn:focus-visible, .te-more > summary:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--accent-ring); }
|
|
85
|
+
/* destructive action lives in its own tinted strip, apart from everyday tools */
|
|
86
|
+
.te-sec-danger {
|
|
87
|
+
display: flex; align-items: center; gap: 12px; margin-top: 14px; padding: 10px 12px;
|
|
88
|
+
border: 1px solid color-mix(in srgb, var(--red) 28%, transparent); border-radius: var(--r-md);
|
|
89
|
+
background: var(--red-soft);
|
|
90
|
+
}
|
|
91
|
+
.te-sec-danger-text { flex: 1; min-width: 0; margin: 0; display: flex; flex-direction: column; gap: 1px; font-size: 12px; color: var(--text-2); }
|
|
92
|
+
.te-sec-danger-text b { font-size: 12.5px; font-weight: 600; color: var(--red); }
|
|
93
|
+
.te-sec-delete.btn {
|
|
94
|
+
flex-shrink: 0; color: var(--red); background: var(--panel);
|
|
95
|
+
border-color: color-mix(in srgb, var(--red) 45%, transparent);
|
|
96
|
+
}
|
|
97
|
+
.te-sec-delete.btn:hover { background: var(--red-soft); border-color: var(--red); color: var(--red); }
|
|
98
|
+
.te-sec-delete.btn:focus-visible { outline: none; box-shadow: 0 0 0 3px color-mix(in srgb, var(--red) 35%, transparent); }
|
|
99
|
+
.te-sec-delete svg { width: 14px; height: 14px; }
|
|
100
|
+
@media (prefers-reduced-motion: reduce) { .te-sec, .te-sec-toggle svg { transition: none; } }
|
|
68
101
|
|
|
69
102
|
/* image field */
|
|
70
103
|
.te-image { margin-bottom: 12px; }
|
|
@@ -152,8 +185,6 @@
|
|
|
152
185
|
.te-preset-more summary { cursor: pointer; color: var(--muted); }
|
|
153
186
|
.te-orphans, .te-sec-body .notice.warn { display: flex; align-items: flex-start; gap: 10px; justify-content: space-between; }
|
|
154
187
|
.te-orphans .btn, .te-sec-body .notice.warn .btn { flex-shrink: 0; }
|
|
155
|
-
.te-publish-one { order: -1; }
|
|
156
|
-
.te-sec-foot .te-publish-one + * { margin-left: 0; }
|
|
157
188
|
|
|
158
189
|
/* ---- field types ---- */
|
|
159
190
|
.te fieldset.field { border: 0; margin: 0 0 14px; padding: 0; min-width: 0; }
|
|
@@ -224,7 +255,11 @@
|
|
|
224
255
|
.te-pagepick { flex-basis: 100%; }
|
|
225
256
|
.te-mode { flex-wrap: wrap; }
|
|
226
257
|
.te-sec-actions .icon-btn { width: 36px; height: 36px; }
|
|
227
|
-
.te-sec-
|
|
258
|
+
.te-sec-body { padding: 14px 12px 12px; }
|
|
259
|
+
.te-sec-foot .te-publish-one { margin-left: 0; flex-basis: 100%; justify-content: center; }
|
|
260
|
+
.te-sec-danger { flex-direction: column; align-items: stretch; gap: 10px; }
|
|
261
|
+
.te-sec-delete.btn { justify-content: center; }
|
|
262
|
+
.te-sec-foot .btn, .te-sec-delete.btn, .te-savebar .btn, .te-add .btn, .da-keys .btn, .da-token-row .btn { min-height: 36px; }
|
|
228
263
|
.te-sec-body input, .te-sec-body select, .te-sec-body textarea,
|
|
229
264
|
.te-pagebar select, .te-add select, .da input[type='text'], .da-token-row input { font-size: 16px; }
|
|
230
265
|
.te-review li { grid-template-columns: minmax(0, 1fr) auto; }
|
package/src/theme-sdk/index.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export { ThemeTokens, ThemeManifest, PostOptions, SectionDefinition, SectionInstance, SectionLayout, SectionPages, PagePreset, BUILTIN_SECTIONS, sectionDefinitions, sectionIssues, THEME_API_VERSION } from './contract.mjs';
|
|
2
2
|
export { formatTime, formatDay } from './fields.mjs';
|
|
3
3
|
export { upcomingEvents, calendarConfig, eventUrl } from './calendar';
|
|
4
|
+
export { eventImage } from '../lib/calendar/images';
|
|
4
5
|
export type { UpcomingEventsOptions, UpcomingEvent, ThemeCalendarConfig } from './calendar';
|
|
5
6
|
export { CONTENT, postsIndexUrl, postUrl, tagUrl, collectionUrl } from '../lib/content';
|
|
6
7
|
export { formatDate } from '../lib/dates';
|