create-avalon 0.2.0 → 0.2.2
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 +6 -5
- package/dist/cli.js +74 -21
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ The CLI walks you through:
|
|
|
21
21
|
- Project name and directory
|
|
22
22
|
- Rendering engine (Preact or React) and island integrations
|
|
23
23
|
- Styling approach (CSS Modules, Tailwind, shadcn)
|
|
24
|
-
- Plugins (SEO, agent optimization
|
|
24
|
+
- Plugins (SEO, agent optimization). MDX syntax highlighting is always on.
|
|
25
25
|
- Middleware (h3, Hono, Elysia)
|
|
26
26
|
- Deploy target (**Cloudflare Pages**, Netlify, or none)
|
|
27
27
|
- Scheduled jobs (cron)
|
|
@@ -44,10 +44,11 @@ A ready-to-run Avalon project with file-system routing, islands architecture, an
|
|
|
44
44
|
my-project/
|
|
45
45
|
├── app/
|
|
46
46
|
│ ├── modules/
|
|
47
|
-
│ │
|
|
48
|
-
│ │
|
|
49
|
-
│ │
|
|
50
|
-
│ │
|
|
47
|
+
│ │ ├── main/ # Site root (/)
|
|
48
|
+
│ │ │ ├── pages/ # File-system routes for this module
|
|
49
|
+
│ │ │ ├── components/
|
|
50
|
+
│ │ │ └── layouts/
|
|
51
|
+
│ │ └── about/ # /about — a module name is a URL prefix
|
|
51
52
|
│ └── shared/
|
|
52
53
|
│ ├── layouts/ # Root layout
|
|
53
54
|
│ ├── components/ # Shared components
|
package/dist/cli.js
CHANGED
|
@@ -115,11 +115,7 @@ var STYLING_OPTIONS = [
|
|
|
115
115
|
"tailwind",
|
|
116
116
|
"shadcn"
|
|
117
117
|
];
|
|
118
|
-
var PLUGINS = [
|
|
119
|
-
"seo",
|
|
120
|
-
"agent-optimization",
|
|
121
|
-
"syntax-highlighting"
|
|
122
|
-
];
|
|
118
|
+
var PLUGINS = ["seo", "agent-optimization"];
|
|
123
119
|
var MIDDLEWARE_OPTIONS = [
|
|
124
120
|
"h3",
|
|
125
121
|
"hono",
|
|
@@ -143,6 +139,9 @@ var BASE_DIRS = [
|
|
|
143
139
|
"app/modules/main/pages",
|
|
144
140
|
"app/modules/main/components",
|
|
145
141
|
"app/modules/main/layouts",
|
|
142
|
+
"app/modules/about/pages",
|
|
143
|
+
"app/modules/about/components",
|
|
144
|
+
"app/modules/about/layouts",
|
|
146
145
|
"app/shared/layouts",
|
|
147
146
|
"app/shared/components",
|
|
148
147
|
"app/shared/styles",
|
|
@@ -1246,11 +1245,6 @@ async function collectProjectConfig(initialName) {
|
|
|
1246
1245
|
value: "agent-optimization",
|
|
1247
1246
|
label: "agent-optimization",
|
|
1248
1247
|
hint: "LLM/AI optimization (llms.txt, markdown, sitemap)"
|
|
1249
|
-
},
|
|
1250
|
-
{
|
|
1251
|
-
value: "syntax-highlighting",
|
|
1252
|
-
label: "syntax-highlighting",
|
|
1253
|
-
hint: "Code block highlighting for MDX (rehype-highlight)"
|
|
1254
1248
|
}
|
|
1255
1249
|
],
|
|
1256
1250
|
initialValues: ["seo"],
|
|
@@ -1731,8 +1725,8 @@ function generateRootLayout(config) {
|
|
|
1731
1725
|
`)}
|
|
1732
1726
|
|
|
1733
1727
|
export default async function RootLayout({ children, frontmatter }: Readonly<LayoutProps>) {
|
|
1734
|
-
const title = frontmatter?.title
|
|
1735
|
-
const description = frontmatter?.description
|
|
1728
|
+
const title = typeof frontmatter?.title === 'string' ? frontmatter.title : '${safeName}';
|
|
1729
|
+
const description = typeof frontmatter?.description === 'string' ? frontmatter.description : '';
|
|
1736
1730
|
|
|
1737
1731
|
return (
|
|
1738
1732
|
<html lang="en">
|
|
@@ -1740,8 +1734,9 @@ export default async function RootLayout({ children, frontmatter }: Readonly<Lay
|
|
|
1740
1734
|
<meta charset="UTF-8" />
|
|
1741
1735
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
1742
1736
|
<title>{title}</title>
|
|
1743
|
-
{description
|
|
1737
|
+
{description ? <meta name="description" content={description} /> : null}
|
|
1744
1738
|
<link rel="icon" href="/favicon.ico" />
|
|
1739
|
+
<link rel="stylesheet" href="/syntax-highlighting.css" />
|
|
1745
1740
|
</head>
|
|
1746
1741
|
<body style={{ margin: 0 }}>
|
|
1747
1742
|
{children}
|
|
@@ -1759,6 +1754,14 @@ export default async function MainLayout({ children }: Readonly<LayoutProps>) {
|
|
|
1759
1754
|
}
|
|
1760
1755
|
`;
|
|
1761
1756
|
}
|
|
1757
|
+
function generateAboutLayout(_config) {
|
|
1758
|
+
return `import type { LayoutProps } from '@useavalon/avalon';
|
|
1759
|
+
|
|
1760
|
+
export default async function AboutLayout({ children }: Readonly<LayoutProps>) {
|
|
1761
|
+
return <>{children}</>;
|
|
1762
|
+
}
|
|
1763
|
+
`;
|
|
1764
|
+
}
|
|
1762
1765
|
|
|
1763
1766
|
// src/templates/middleware.ts
|
|
1764
1767
|
function generateSampleMiddleware(_config) {
|
|
@@ -1891,6 +1894,10 @@ export default async function HomePage() {
|
|
|
1891
1894
|
<code style={{ display: 'block', padding: '0.6rem 1.2rem', borderRadius: '6px', background: 'rgba(255,255,255,0.04)', border: '1px solid rgba(255,255,255,0.08)', color: '#a5b4fc', fontSize: '0.85rem', fontFamily: 'ui-monospace, monospace' }}>
|
|
1892
1895
|
Edit app/modules/main/pages/index.tsx
|
|
1893
1896
|
</code>
|
|
1897
|
+
<p style={{ fontSize: '0.85rem', color: '#94a3b8', margin: '0.5rem 0 0' }}>
|
|
1898
|
+
<a href="/about" style={{ color: '#818cf8', textDecoration: 'none' }}>About</a>
|
|
1899
|
+
{' '}is the about module — app/modules/about/pages/index.tsx → /about
|
|
1900
|
+
</p>
|
|
1894
1901
|
</div>
|
|
1895
1902
|
|
|
1896
1903
|
<footer style={{ position: 'relative', zIndex: 1, marginTop: '4rem', paddingTop: '2rem', borderTop: '1px solid rgba(255,255,255,0.06)', width: '100%', maxWidth: '640px' }}>
|
|
@@ -1904,6 +1911,28 @@ export default async function HomePage() {
|
|
|
1904
1911
|
}
|
|
1905
1912
|
`;
|
|
1906
1913
|
}
|
|
1914
|
+
function generateAboutPage() {
|
|
1915
|
+
return `export const metadata = {
|
|
1916
|
+
title: 'About',
|
|
1917
|
+
description: 'The about module maps to the /about route.',
|
|
1918
|
+
};
|
|
1919
|
+
|
|
1920
|
+
export default function AboutPage() {
|
|
1921
|
+
return (
|
|
1922
|
+
<div style={{ minHeight: '100vh', display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', background: 'linear-gradient(145deg, #0a0a12 0%, #0d1117 40%, #111827 100%)', color: '#e2e8f0', fontFamily: 'system-ui, -apple-system, sans-serif', padding: '2rem', textAlign: 'center' }}>
|
|
1923
|
+
<p style={{ fontSize: '0.8rem', letterSpacing: '0.15em', textTransform: 'uppercase', color: '#818cf8', marginBottom: '1.5rem', fontWeight: 500 }}>Module route</p>
|
|
1924
|
+
<h1 style={{ fontSize: 'clamp(2rem, 5vw, 3rem)', fontWeight: 700, lineHeight: 1.1, margin: '0 0 1.5rem' }}>About</h1>
|
|
1925
|
+
<p style={{ fontSize: '1.05rem', lineHeight: 1.7, color: '#94a3b8', marginBottom: '2rem', maxWidth: '480px' }}>
|
|
1926
|
+
This page is <code style={{ color: '#a5b4fc' }}>app/modules/about/pages/index.tsx</code>.
|
|
1927
|
+
A module name is a URL prefix, so the about module is <code style={{ color: '#a5b4fc' }}>/about</code>.
|
|
1928
|
+
The main module is the site root.
|
|
1929
|
+
</p>
|
|
1930
|
+
<a href="/" style={{ color: '#818cf8', textDecoration: 'none', fontWeight: 500 }}>Home</a>
|
|
1931
|
+
</div>
|
|
1932
|
+
);
|
|
1933
|
+
}
|
|
1934
|
+
`;
|
|
1935
|
+
}
|
|
1907
1936
|
function generate404Page() {
|
|
1908
1937
|
return `export const metadata = {
|
|
1909
1938
|
title: '404 - Page Not Found',
|
|
@@ -1951,6 +1980,7 @@ function generatePostBuildMjs() {
|
|
|
1951
1980
|
function generateStylingFiles(config) {
|
|
1952
1981
|
const files = new Map;
|
|
1953
1982
|
files.set("app/shared/styles/main.css", generateMainCss(config));
|
|
1983
|
+
files.set("public/syntax-highlighting.css", generateSyntaxHighlightingCss());
|
|
1954
1984
|
if (config.styling === "css-modules") {
|
|
1955
1985
|
files.set("app/shared/styles/reset.css", generateResetCss());
|
|
1956
1986
|
}
|
|
@@ -2144,6 +2174,30 @@ function generateShadcnComponentsJson(config) {
|
|
|
2144
2174
|
return JSON.stringify(componentsConfig, null, 2) + `
|
|
2145
2175
|
`;
|
|
2146
2176
|
}
|
|
2177
|
+
function generateSyntaxHighlightingCss() {
|
|
2178
|
+
return `code.hljs { padding: 3px 5px; }
|
|
2179
|
+
pre code.hljs { display: block; overflow-x: auto; padding: 1em; }
|
|
2180
|
+
.hljs { color: #c9d1d9; background: transparent; }
|
|
2181
|
+
.hljs-doctag, .hljs-keyword, .hljs-meta .hljs-keyword, .hljs-template-tag,
|
|
2182
|
+
.hljs-template-variable, .hljs-type, .hljs-variable.language_ { color: #ff7b72; }
|
|
2183
|
+
.hljs-title, .hljs-title.class_, .hljs-title.class_.inherited__,
|
|
2184
|
+
.hljs-title.function_ { color: #d2a8ff; }
|
|
2185
|
+
.hljs-attr, .hljs-attribute, .hljs-literal, .hljs-meta, .hljs-number,
|
|
2186
|
+
.hljs-operator, .hljs-variable, .hljs-selector-attr, .hljs-selector-class,
|
|
2187
|
+
.hljs-selector-id { color: #79c0ff; }
|
|
2188
|
+
.hljs-regexp, .hljs-string, .hljs-meta .hljs-string { color: #a5d6ff; }
|
|
2189
|
+
.hljs-built_in, .hljs-symbol { color: #ffa657; }
|
|
2190
|
+
.hljs-comment, .hljs-code, .hljs-formula { color: #8b949e; }
|
|
2191
|
+
.hljs-name, .hljs-quote, .hljs-selector-tag, .hljs-selector-pseudo { color: #7ee787; }
|
|
2192
|
+
.hljs-subst { color: #c9d1d9; }
|
|
2193
|
+
.hljs-section { color: #1f6feb; font-weight: bold; }
|
|
2194
|
+
.hljs-bullet { color: #f2cc60; }
|
|
2195
|
+
.hljs-emphasis { color: #c9d1d9; font-style: italic; }
|
|
2196
|
+
.hljs-strong { color: #c9d1d9; font-weight: bold; }
|
|
2197
|
+
.hljs-addition { color: #aff5b4; background-color: #033a16; }
|
|
2198
|
+
.hljs-deletion { color: #ffdcd7; background-color: #67060c; }
|
|
2199
|
+
`;
|
|
2200
|
+
}
|
|
2147
2201
|
|
|
2148
2202
|
// src/templates/tsconfig.ts
|
|
2149
2203
|
function generateTsConfig(core = "preact") {
|
|
@@ -2286,7 +2340,7 @@ function generateViteConfig(config) {
|
|
|
2286
2340
|
` clientEntry: 'app/entry-client',`,
|
|
2287
2341
|
` globalCSS: ['app/shared/styles/main.css'],`,
|
|
2288
2342
|
` prerender: {`,
|
|
2289
|
-
` routes: ['/'],`,
|
|
2343
|
+
` routes: ['/', '/about'],`,
|
|
2290
2344
|
` crawlLinks: true,`,
|
|
2291
2345
|
` ignore: [],`,
|
|
2292
2346
|
` },`,
|
|
@@ -2387,6 +2441,8 @@ async function scaffoldProject(config, targetDir) {
|
|
|
2387
2441
|
await writeFile(join(targetDir, "app/modules/main/layouts/_layout.tsx"), generateMainLayout(config));
|
|
2388
2442
|
await writeFile(join(targetDir, "app/modules/main/pages/index.tsx"), generateMainPage(config));
|
|
2389
2443
|
await writeFile(join(targetDir, "app/modules/main/pages/404.tsx"), generate404Page());
|
|
2444
|
+
await writeFile(join(targetDir, "app/modules/about/layouts/_layout.tsx"), generateAboutLayout(config));
|
|
2445
|
+
await writeFile(join(targetDir, "app/modules/about/pages/index.tsx"), generateAboutPage());
|
|
2390
2446
|
await writeFile(join(targetDir, "middleware/01.logger.ts"), generateSampleMiddleware(config));
|
|
2391
2447
|
await writeFile(join(targetDir, "routes/api/hello.ts"), generateHelloRoute(config));
|
|
2392
2448
|
if (config.cron) {
|
|
@@ -2413,13 +2469,10 @@ async function scaffoldProject(config, targetDir) {
|
|
|
2413
2469
|
`);
|
|
2414
2470
|
await writeFile(join(targetDir, "server/renderer.ts"), [
|
|
2415
2471
|
`/**`,
|
|
2416
|
-
` * SSR
|
|
2417
|
-
` *`,
|
|
2418
|
-
` * Avalon auto-discovers layouts, injects client assets, and handles`,
|
|
2419
|
-
` * layout wrapping. Import from the virtual modules directly to customize:`,
|
|
2472
|
+
` * Nitro SSR catch-all. Keep this re-export for the default renderer.`,
|
|
2420
2473
|
` *`,
|
|
2421
|
-
` *
|
|
2422
|
-
` *
|
|
2474
|
+
` * Customize only when you need a custom hydration directive or to wrap`,
|
|
2475
|
+
` * the handler. See https://useavalon.dev/docs/ssr-renderer`,
|
|
2423
2476
|
` */`,
|
|
2424
2477
|
`export { default } from 'virtual:avalon/renderer';`,
|
|
2425
2478
|
``
|
|
@@ -2516,7 +2569,7 @@ async function main() {
|
|
|
2516
2569
|
" --core Rendering engine: preact (default) | react",
|
|
2517
2570
|
" --integrations Comma list: preact,react,vue,svelte,solid,lit,qwik",
|
|
2518
2571
|
" --styling css-modules (default) | tailwind | shadcn",
|
|
2519
|
-
" --plugins Comma list: seo (default),agent-optimization
|
|
2572
|
+
" --plugins Comma list: seo (default),agent-optimization",
|
|
2520
2573
|
" --middleware h3 (default) | hono | elysia",
|
|
2521
2574
|
" --deploy cloudflare | netlify | none (default)",
|
|
2522
2575
|
" --cron Scaffold an example cron task + config",
|