@acms-subir/core 0.0.1
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/cli.mjs +75 -0
- package/integration.mjs +286 -0
- package/package.json +89 -0
- package/src/actions/index.ts +502 -0
- package/src/components/DesignManager.tsx +542 -0
- package/src/components/LinksManager.tsx +694 -0
- package/src/components/Modal.astro +65 -0
- package/src/components/NavManager.tsx +168 -0
- package/src/components/WidgetRenderer.astro +84 -0
- package/src/components/builder/PageBuilder.tsx +575 -0
- package/src/components/editor/ImagePicker.tsx +215 -0
- package/src/components/editor/PostEditor.tsx +1011 -0
- package/src/components/editor/PreviewOverlay.tsx +77 -0
- package/src/components/editor/extensions/calendar.tsx +230 -0
- package/src/components/editor/extensions/cards.tsx +488 -0
- package/src/components/editor/extensions/codeBlock.tsx +70 -0
- package/src/components/editor/extensions/infoCards.tsx +270 -0
- package/src/components/editor/extensions/mediaCards.tsx +376 -0
- package/src/components/editor/extensions/postList.tsx +130 -0
- package/src/components/editor/extensions/slash.tsx +250 -0
- package/src/components/editor/extensions/tableTyping.ts +63 -0
- package/src/components/editor/imaging.ts +146 -0
- package/src/components/media/CropModal.tsx +229 -0
- package/src/components/media/MediaLibrary.tsx +295 -0
- package/src/layouts/Admin.astro +119 -0
- package/src/layouts/Site.astro +218 -0
- package/src/lib/auth.ts +94 -0
- package/src/lib/backup/unzip.ts +38 -0
- package/src/lib/backup/zip.ts +105 -0
- package/src/lib/blocksToHtml.ts +68 -0
- package/src/lib/brand.ts +26 -0
- package/src/lib/calendar/ics.ts +402 -0
- package/src/lib/calendar/render.ts +275 -0
- package/src/lib/calendar/src.ts +68 -0
- package/src/lib/content.ts +53 -0
- package/src/lib/dates.ts +34 -0
- package/src/lib/dynamicBlocks.ts +115 -0
- package/src/lib/env.ts +6 -0
- package/src/lib/highlightCode.ts +44 -0
- package/src/lib/i18n.ts +40 -0
- package/src/lib/markdown.ts +7 -0
- package/src/lib/media/store.ts +95 -0
- package/src/lib/net.ts +51 -0
- package/src/lib/preview.ts +28 -0
- package/src/lib/repo/d1.ts +44 -0
- package/src/lib/repo/index.ts +23 -0
- package/src/lib/repo/migrations.ts +231 -0
- package/src/lib/repo/search.ts +14 -0
- package/src/lib/repo/sql.ts +721 -0
- package/src/lib/repo/sqlite.ts +43 -0
- package/src/lib/repo/types.ts +132 -0
- package/src/lib/schema.ts +286 -0
- package/src/lib/seo.ts +37 -0
- package/src/lib/theme.ts +206 -0
- package/src/lib/widgets.ts +108 -0
- package/src/middleware.ts +109 -0
- package/src/pages/[...slug].astro +43 -0
- package/src/pages/admin/c/[collection]/[id].astro +56 -0
- package/src/pages/admin/c/[collection]/index.astro +163 -0
- package/src/pages/admin/design.astro +42 -0
- package/src/pages/admin/index.astro +145 -0
- package/src/pages/admin/links.astro +21 -0
- package/src/pages/admin/login.astro +83 -0
- package/src/pages/admin/logout.ts +7 -0
- package/src/pages/admin/media.astro +13 -0
- package/src/pages/admin/navigation.astro +17 -0
- package/src/pages/admin/pages/[id].astro +49 -0
- package/src/pages/admin/pages/index.astro +100 -0
- package/src/pages/admin/posts/[id].astro +6 -0
- package/src/pages/admin/posts/index.astro +7 -0
- package/src/pages/admin/settings.astro +512 -0
- package/src/pages/admin/tags.astro +101 -0
- package/src/pages/admin/users.astro +149 -0
- package/src/pages/api/backup.ts +63 -0
- package/src/pages/api/drafts.ts +106 -0
- package/src/pages/api/media/upload.ts +89 -0
- package/src/pages/api/restore.ts +102 -0
- package/src/pages/author/[slug].astro +66 -0
- package/src/pages/blog/[slug].astro +240 -0
- package/src/pages/blog/index.astro +51 -0
- package/src/pages/blog/tag/[slug].astro +83 -0
- package/src/pages/embed/[pageId]/[blockId].ts +45 -0
- package/src/pages/go/[id].ts +10 -0
- package/src/pages/index.astro +52 -0
- package/src/pages/links.astro +110 -0
- package/src/pages/llms.txt.ts +47 -0
- package/src/pages/media/[...key].ts +18 -0
- package/src/pages/preview/[type]/[id].astro +52 -0
- package/src/pages/robots.txt.ts +28 -0
- package/src/pages/rss.xml.ts +58 -0
- package/src/pages/search.astro +83 -0
- package/src/pages/sitemap.xml.ts +55 -0
- package/src/styles/admin.css +652 -0
- package/src/styles/builder.css +121 -0
- package/src/styles/cards.css +176 -0
- package/src/styles/editor.css +596 -0
- package/src/styles/site.css +427 -0
- package/src/themes/editorial/templates/home.astro +127 -0
- package/src/themes/editorial/templates/post-minimal.astro +50 -0
- package/src/themes/editorial/theme.css +108 -0
- package/src/themes/editorial/theme.json +20 -0
- package/src/themes/field/theme.json +17 -0
- package/src/themes/ink/theme.json +17 -0
- package/src/themes/night/theme.css +7 -0
- package/src/themes/night/theme.json +17 -0
- package/src/virtual.d.ts +25 -0
- package/src/worker.ts +28 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
/* Editorial — serif magazine styling on top of the shared tokens. */
|
|
2
|
+
|
|
3
|
+
body { font-size: 16.5px; }
|
|
4
|
+
h1, h2, h3 { font-weight: 550; letter-spacing: -0.015em; }
|
|
5
|
+
article h1 { font-size: 42px; line-height: 1.12; }
|
|
6
|
+
|
|
7
|
+
.site-header { padding-top: 34px; }
|
|
8
|
+
.site-header .brand { font-family: var(--font-heading); font-size: 20px; font-weight: 550; }
|
|
9
|
+
.site-nav a { text-transform: uppercase; font-size: 12px; letter-spacing: 0.1em; }
|
|
10
|
+
.site-nav a[aria-current='page'] { border-bottom: 1.5px solid var(--ink); padding-bottom: 3px; }
|
|
11
|
+
|
|
12
|
+
.post-list a { font-family: var(--font-heading); font-weight: 550; }
|
|
13
|
+
.post-meta { text-transform: uppercase; font-size: 11.5px; letter-spacing: 0.08em; }
|
|
14
|
+
.post-cover { border-radius: 4px; }
|
|
15
|
+
.tag { border-radius: 3px; text-transform: uppercase; font-size: 11px; letter-spacing: 0.06em; }
|
|
16
|
+
|
|
17
|
+
.site-footer { text-align: center; text-transform: uppercase; font-size: 12px; letter-spacing: 0.08em; }
|
|
18
|
+
|
|
19
|
+
/* ---- coded homepage (templates/home.astro) ---- */
|
|
20
|
+
.ed-home { padding-top: 26px; }
|
|
21
|
+
|
|
22
|
+
.ed-hero { padding: 40px 0 8px; }
|
|
23
|
+
.ed-hero > :first-child { margin-top: 0; }
|
|
24
|
+
.ed-hero h1 { font-size: clamp(38px, 7vw, 58px); line-height: 1.08; margin: 10px 0 22px; font-weight: 500; }
|
|
25
|
+
.ed-hero p { color: var(--muted); font-size: 17px; max-width: 58ch; }
|
|
26
|
+
.ed-hero > p:first-child,
|
|
27
|
+
.ed-hero .ed-kicker { text-transform: uppercase; letter-spacing: 0.16em; font-size: 12px; color: var(--muted); }
|
|
28
|
+
|
|
29
|
+
.ed-section { margin-top: 56px; padding-top: 26px; border-top: 1px solid var(--line); }
|
|
30
|
+
.ed-sechead { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 18px; }
|
|
31
|
+
.ed-sechead h2 { font-family: var(--font-heading); font-style: italic; font-weight: 500; font-size: 30px; margin: 0; }
|
|
32
|
+
.ed-sechead a { text-transform: uppercase; font-size: 11.5px; letter-spacing: 0.1em; color: var(--muted); text-decoration: none; }
|
|
33
|
+
.ed-sechead a:hover { color: var(--ink); }
|
|
34
|
+
|
|
35
|
+
.ed-meta { text-transform: uppercase; font-size: 11px; letter-spacing: 0.08em; color: var(--muted); }
|
|
36
|
+
.ed-meta .dot { margin: 0 4px; }
|
|
37
|
+
|
|
38
|
+
.ed-feature a.ed-imglink { display: block; }
|
|
39
|
+
.ed-feature img { width: 100%; aspect-ratio: 1.9 / 1; object-fit: cover; border-radius: 4px; background: var(--soft); }
|
|
40
|
+
.ed-feature h3 { font-size: 32px; margin: 12px 0 6px; font-weight: 550; }
|
|
41
|
+
.ed-feature h3 a, .ed-card h3 a, .ed-item h3 a { color: var(--ink); text-decoration: none; }
|
|
42
|
+
.ed-feature h3 a:hover, .ed-card h3 a:hover, .ed-item h3 a:hover { color: var(--accent); }
|
|
43
|
+
.ed-feature p.ed-excerpt, .ed-card p.ed-excerpt { color: var(--muted); font-size: 15px; margin: 4px 0 0; }
|
|
44
|
+
|
|
45
|
+
.ed-cols { display: grid; grid-template-columns: 1fr 1fr; gap: 36px; }
|
|
46
|
+
@media (max-width: 640px) { .ed-cols { grid-template-columns: 1fr; } }
|
|
47
|
+
.ed-cols .ed-section { margin-top: 56px; }
|
|
48
|
+
|
|
49
|
+
.ed-cards { display: grid; gap: 26px; }
|
|
50
|
+
.ed-card img { width: 100%; aspect-ratio: 1.9 / 1; object-fit: cover; border-radius: 4px; background: var(--soft); }
|
|
51
|
+
.ed-card h3 { font-size: 24px; margin: 10px 0 4px; font-weight: 550; }
|
|
52
|
+
|
|
53
|
+
.ed-list { list-style: none; margin: 0; padding: 0; }
|
|
54
|
+
.ed-item { padding: 16px 0; border-bottom: 1px solid var(--line); }
|
|
55
|
+
.ed-item:last-child { border-bottom: none; }
|
|
56
|
+
.ed-item h3 { font-size: 22px; margin: 4px 0 4px; font-weight: 550; }
|
|
57
|
+
.ed-item p { color: var(--muted); font-size: 14.5px; margin: 2px 0 0; }
|
|
58
|
+
|
|
59
|
+
.ed-empty { border: 1.5px dashed var(--line); border-radius: 6px; padding: 26px; text-align: center; color: var(--muted); font-size: 14px; }
|
|
60
|
+
|
|
61
|
+
.ed-feature-text { margin-top: 14px; }
|
|
62
|
+
.ed-feature img { margin-bottom: 0; }
|
|
63
|
+
.ed-feature .ed-excerpt { max-width: 58ch; }
|
|
64
|
+
|
|
65
|
+
/* ---- post page: Ghost-style editorial treatment ---- */
|
|
66
|
+
.post-header { text-align: center; padding-top: 18px; }
|
|
67
|
+
.post-kicker { margin-bottom: 10px; }
|
|
68
|
+
.post-header .post-kicker .tag { background: none; padding: 0 6px; color: var(--muted); }
|
|
69
|
+
.post-header .post-kicker a.tag:hover { background: none; color: var(--accent); }
|
|
70
|
+
article > .post-header h1 { font-size: clamp(34px, 6vw, 52px); font-weight: 500; margin: 6px 0 12px; }
|
|
71
|
+
.post-header .post-meta { justify-content: center; }
|
|
72
|
+
.post-header .byline a { color: var(--muted); text-decoration: none; }
|
|
73
|
+
.post-header .byline a:hover { color: var(--accent); }
|
|
74
|
+
|
|
75
|
+
/* cover spacing — full-bleed itself is data-driven (.is-full, set by the
|
|
76
|
+
theme's post.cover default or the Design screen override) */
|
|
77
|
+
.post-cover { margin-top: 26px; margin-bottom: 40px; }
|
|
78
|
+
|
|
79
|
+
/* share as a floating rail beside the text on desktop */
|
|
80
|
+
@media (min-width: 1000px) {
|
|
81
|
+
.post-layout { display: grid; grid-template-columns: minmax(0, 1fr) 44px; gap: 40px; align-items: start; }
|
|
82
|
+
.post-share { flex-direction: column; align-items: center; gap: 12px; margin: 4px 0 0; position: sticky; top: 40px; }
|
|
83
|
+
.post-share-label { margin: 0 0 2px; }
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/* author card: serif italic name, centered block like the reference */
|
|
87
|
+
.author-card { gap: 22px; margin-top: 44px; padding-top: 32px; }
|
|
88
|
+
.author-card .author-avatar { width: 76px; height: 76px; }
|
|
89
|
+
.author-card-name { font-family: var(--font-heading); font-style: italic; font-weight: 500; font-size: 30px; margin: 2px 0 6px; }
|
|
90
|
+
.author-card-bio { font-size: 15.5px; line-height: 1.6; }
|
|
91
|
+
.author-card-more { color: var(--muted); border-bottom: 1px solid var(--line); padding-bottom: 2px; }
|
|
92
|
+
.author-card-more:hover { color: var(--ink); }
|
|
93
|
+
|
|
94
|
+
/* related reading */
|
|
95
|
+
.related { margin-top: 48px; }
|
|
96
|
+
.related-title { font-style: italic; font-weight: 500; font-size: 30px; }
|
|
97
|
+
.related-card h3 { font-family: var(--font-heading); font-weight: 550; font-size: 20px; }
|
|
98
|
+
.related-thumb img { border-radius: 4px; }
|
|
99
|
+
|
|
100
|
+
/* author page hero */
|
|
101
|
+
.author-hero { flex-direction: column; text-align: center; gap: 14px; padding-top: 24px; }
|
|
102
|
+
.author-hero .author-avatar { width: 96px; height: 96px; }
|
|
103
|
+
.author-hero h1 { font-size: 40px; font-weight: 500; }
|
|
104
|
+
.author-hero .tag-desc { max-width: 52ch; margin: 0 auto; }
|
|
105
|
+
|
|
106
|
+
/* overlay hero: keep the serif display sizing on the image variant too */
|
|
107
|
+
.post-hero-content h1 { font-size: clamp(34px, 6vw, 52px); font-weight: 500; }
|
|
108
|
+
.post-hero-content .post-kicker .tag { background: none; padding: 0 6px; }
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Editorial",
|
|
3
|
+
"description": "Serif editorial magazine — Fraunces display headings, warm paper, crimson accents. Ships a coded homepage with Featured / Latest / tag sections.",
|
|
4
|
+
"tokens": {
|
|
5
|
+
"bg": "#f7f5f0",
|
|
6
|
+
"ink": "#181712",
|
|
7
|
+
"muted": "#6d685e",
|
|
8
|
+
"line": "#e4e0d5",
|
|
9
|
+
"accent": "#b33a2e",
|
|
10
|
+
"panel": "#fdfcf9",
|
|
11
|
+
"soft": "#edeae1",
|
|
12
|
+
"headingFont": "'Fraunces', Georgia, serif",
|
|
13
|
+
"bodyFont": "'Inter', system-ui, sans-serif",
|
|
14
|
+
"googleFonts": "family=Fraunces:ital,opsz,wght@0,9..144,400;0,9..144,550;1,9..144,400;1,9..144,550&family=Inter:wght@400;500;600",
|
|
15
|
+
"width": 720
|
|
16
|
+
},
|
|
17
|
+
"post": {
|
|
18
|
+
"cover": "full"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Field Notes",
|
|
3
|
+
"description": "Warm green-tinted paper with Lora serif headings — calm, notebook-like.",
|
|
4
|
+
"tokens": {
|
|
5
|
+
"bg": "#f4f6f2",
|
|
6
|
+
"ink": "#232a22",
|
|
7
|
+
"muted": "#68715f",
|
|
8
|
+
"line": "#dde3d6",
|
|
9
|
+
"accent": "#3d6b45",
|
|
10
|
+
"panel": "#fdfefc",
|
|
11
|
+
"soft": "#e6ebdf",
|
|
12
|
+
"headingFont": "'Lora', Georgia, serif",
|
|
13
|
+
"bodyFont": "'Inter', system-ui, sans-serif",
|
|
14
|
+
"googleFonts": "family=Lora:ital,wght@0,500;0,600;1,500&family=Inter:wght@400;500;600",
|
|
15
|
+
"width": 720
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Ink",
|
|
3
|
+
"description": "The original Acms look — quiet Inter sans on warm paper with an indigo accent.",
|
|
4
|
+
"tokens": {
|
|
5
|
+
"bg": "#faf9f7",
|
|
6
|
+
"ink": "#1e1f24",
|
|
7
|
+
"muted": "#6b6e78",
|
|
8
|
+
"line": "#e5e3de",
|
|
9
|
+
"accent": "#4f46e5",
|
|
10
|
+
"panel": "#ffffff",
|
|
11
|
+
"soft": "#eceae5",
|
|
12
|
+
"headingFont": "'Inter', system-ui, sans-serif",
|
|
13
|
+
"bodyFont": "'Inter', system-ui, sans-serif",
|
|
14
|
+
"googleFonts": "family=Inter:wght@400;600;700",
|
|
15
|
+
"width": 760
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/* Night Studio — dark-mode fixups beyond what tokens cover. */
|
|
2
|
+
pre { background: #0d0e12; }
|
|
3
|
+
.link-btn:hover { box-shadow: 0 6px 18px rgb(0 0 0 / 45%); }
|
|
4
|
+
.links-avatar { box-shadow: 0 4px 16px rgb(0 0 0 / 50%); }
|
|
5
|
+
.post-cover { background: var(--soft); }
|
|
6
|
+
a.tag:hover { color: #14151a; }
|
|
7
|
+
.w-btn.primary { color: #14151a; }
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "Night Studio",
|
|
3
|
+
"description": "Dark charcoal studio with Space Grotesk headings and a warm amber accent.",
|
|
4
|
+
"tokens": {
|
|
5
|
+
"bg": "#14151a",
|
|
6
|
+
"ink": "#e8e7e2",
|
|
7
|
+
"muted": "#9a9aa3",
|
|
8
|
+
"line": "#2b2c33",
|
|
9
|
+
"accent": "#e8a849",
|
|
10
|
+
"panel": "#1d1e25",
|
|
11
|
+
"soft": "#25262e",
|
|
12
|
+
"headingFont": "'Space Grotesk', system-ui, sans-serif",
|
|
13
|
+
"bodyFont": "'Inter', system-ui, sans-serif",
|
|
14
|
+
"googleFonts": "family=Space+Grotesk:wght@500;700&family=Inter:wght@400;500;600",
|
|
15
|
+
"width": 760
|
|
16
|
+
}
|
|
17
|
+
}
|
package/src/virtual.d.ts
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Ambient types for the virtual modules provided by integration.mjs.
|
|
2
|
+
|
|
3
|
+
declare module 'virtual:acms-config' {
|
|
4
|
+
export const userConfig: {
|
|
5
|
+
coreVersion: string;
|
|
6
|
+
brand: { name?: string; version?: string; stack?: string };
|
|
7
|
+
seed: { siteTitle?: string; tagline?: string; heroHeading?: string; heroSub?: string };
|
|
8
|
+
// resolved (defaults applied + validated) by integration.mjs; `posts`
|
|
9
|
+
// always exists in collections, insertion order = display order
|
|
10
|
+
content: {
|
|
11
|
+
collections: Record<string, { singular: string; plural: string; base: string; redirectFrom: string[] }>;
|
|
12
|
+
tags: { base: string };
|
|
13
|
+
};
|
|
14
|
+
// resolved by integration.mjs; empty locales = i18n not configured
|
|
15
|
+
i18n: { locales: string[]; defaultLocale: string };
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
declare module 'virtual:acms-user-themes' {
|
|
20
|
+
export const jsons: Record<string, unknown>;
|
|
21
|
+
export const csses: Record<string, string>;
|
|
22
|
+
export const homes: Record<string, { default: unknown }>;
|
|
23
|
+
export const postTpls: Record<string, { default: unknown }>;
|
|
24
|
+
export const pageTpls: Record<string, { default: unknown }>;
|
|
25
|
+
}
|
package/src/worker.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SSRManifest } from 'astro';
|
|
2
|
+
import { App } from 'astro/app';
|
|
3
|
+
import { handle } from '@astrojs/cloudflare/handler';
|
|
4
|
+
import { D1Repository, type D1Database } from './lib/repo/d1';
|
|
5
|
+
|
|
6
|
+
// Custom Workers entrypoint (wired via the adapter's workerEntryPoint
|
|
7
|
+
// option): identical fetch behavior to the stock entry, plus a cron-driven
|
|
8
|
+
// scheduled handler so posts publish on time even with zero traffic. The
|
|
9
|
+
// middleware's on-request sweep remains as the fallback for the Node target
|
|
10
|
+
// and local dev, where cron triggers don't exist.
|
|
11
|
+
|
|
12
|
+
type HandleRequest = Parameters<typeof handle>[2];
|
|
13
|
+
type HandleEnv = Parameters<typeof handle>[3];
|
|
14
|
+
type HandleContext = Parameters<typeof handle>[4];
|
|
15
|
+
|
|
16
|
+
export function createExports(manifest: SSRManifest) {
|
|
17
|
+
const app = new App(manifest);
|
|
18
|
+
return {
|
|
19
|
+
default: {
|
|
20
|
+
async fetch(request: HandleRequest, env: HandleEnv, context: HandleContext) {
|
|
21
|
+
return handle(manifest, app, request, env, context);
|
|
22
|
+
},
|
|
23
|
+
async scheduled(_controller: unknown, env: HandleEnv, context: HandleContext) {
|
|
24
|
+
context.waitUntil(new D1Repository(env.DB as D1Database).publishDuePosts(Date.now()));
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|