create-avalon 0.1.15 → 0.1.16
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 +59 -59
- package/dist/cli.js +89 -1
- package/package.json +39 -39
package/README.md
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
# create-avalon
|
|
2
|
-
|
|
3
|
-
Scaffold a new [Avalon](https://useavalon.dev) project in seconds.
|
|
4
|
-
|
|
5
|
-
## Usage
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm create avalon@latest
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
Or with other package managers:
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
pnpm create avalon@latest
|
|
15
|
-
yarn create avalon
|
|
16
|
-
bun create avalon
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
The CLI walks you through:
|
|
20
|
-
|
|
21
|
-
- Project name and directory
|
|
22
|
-
- Framework selection (React, Preact, Vue, Svelte, Solid, Lit, Qwik — or multiple)
|
|
23
|
-
- Styling approach (CSS Modules, Tailwind, vanilla CSS)
|
|
24
|
-
- Optional features (API routes, middleware, layouts, MDX)
|
|
25
|
-
- Package manager preference
|
|
26
|
-
|
|
27
|
-
## What you get
|
|
28
|
-
|
|
29
|
-
A ready-to-run Avalon project with file-system routing, islands architecture, and zero JavaScript by default.
|
|
30
|
-
|
|
31
|
-
```
|
|
32
|
-
my-project/
|
|
33
|
-
├── app/
|
|
34
|
-
│ ├── modules/
|
|
35
|
-
│ │ └── home/
|
|
36
|
-
│ │ ├── pages/ # File-system routes
|
|
37
|
-
│ │ ├── components/ # Interactive components
|
|
38
|
-
│ │ └── layouts/ # Module layouts
|
|
39
|
-
│ └── shared/
|
|
40
|
-
│ ├── layouts/ # Root layout
|
|
41
|
-
│ ├── components/ # Shared components
|
|
42
|
-
│ └── styles/ # Global styles & tokens
|
|
43
|
-
├── middleware/ # Server middleware
|
|
44
|
-
├── routes/
|
|
45
|
-
│ └── api/ # API routes
|
|
46
|
-
├── server/ # Server config & env
|
|
47
|
-
├── public/ # Static assets
|
|
48
|
-
├── vite.config.ts
|
|
49
|
-
└── package.json
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Links
|
|
53
|
-
|
|
54
|
-
- [Documentation](https://useavalon.dev/docs/introduction)
|
|
55
|
-
- [GitHub](https://github.com/useAvalon/Avalon)
|
|
56
|
-
|
|
57
|
-
## License
|
|
58
|
-
|
|
59
|
-
MIT
|
|
1
|
+
# create-avalon
|
|
2
|
+
|
|
3
|
+
Scaffold a new [Avalon](https://useavalon.dev) project in seconds.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm create avalon@latest
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or with other package managers:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
pnpm create avalon@latest
|
|
15
|
+
yarn create avalon
|
|
16
|
+
bun create avalon
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The CLI walks you through:
|
|
20
|
+
|
|
21
|
+
- Project name and directory
|
|
22
|
+
- Framework selection (React, Preact, Vue, Svelte, Solid, Lit, Qwik — or multiple)
|
|
23
|
+
- Styling approach (CSS Modules, Tailwind, vanilla CSS)
|
|
24
|
+
- Optional features (API routes, middleware, layouts, MDX)
|
|
25
|
+
- Package manager preference
|
|
26
|
+
|
|
27
|
+
## What you get
|
|
28
|
+
|
|
29
|
+
A ready-to-run Avalon project with file-system routing, islands architecture, and zero JavaScript by default.
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
my-project/
|
|
33
|
+
├── app/
|
|
34
|
+
│ ├── modules/
|
|
35
|
+
│ │ └── home/
|
|
36
|
+
│ │ ├── pages/ # File-system routes
|
|
37
|
+
│ │ ├── components/ # Interactive components
|
|
38
|
+
│ │ └── layouts/ # Module layouts
|
|
39
|
+
│ └── shared/
|
|
40
|
+
│ ├── layouts/ # Root layout
|
|
41
|
+
│ ├── components/ # Shared components
|
|
42
|
+
│ └── styles/ # Global styles & tokens
|
|
43
|
+
├── middleware/ # Server middleware
|
|
44
|
+
├── routes/
|
|
45
|
+
│ └── api/ # API routes
|
|
46
|
+
├── server/ # Server config & env
|
|
47
|
+
├── public/ # Static assets
|
|
48
|
+
├── vite.config.ts
|
|
49
|
+
└── package.json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Links
|
|
53
|
+
|
|
54
|
+
- [Documentation](https://useavalon.dev/docs/introduction)
|
|
55
|
+
- [GitHub](https://github.com/useAvalon/Avalon)
|
|
56
|
+
|
|
57
|
+
## License
|
|
58
|
+
|
|
59
|
+
MIT
|
package/dist/cli.js
CHANGED
|
@@ -1371,6 +1371,11 @@ function generateViteConfig(config) {
|
|
|
1371
1371
|
` nitro: {`,
|
|
1372
1372
|
` preset: process.env.NITRO_PRESET || 'node_server',`,
|
|
1373
1373
|
` streaming: true,`,
|
|
1374
|
+
` prerender: {`,
|
|
1375
|
+
` routes: ['/'],`,
|
|
1376
|
+
` crawlLinks: true,`,
|
|
1377
|
+
` ignore: [],`,
|
|
1378
|
+
` },`,
|
|
1374
1379
|
` },`,
|
|
1375
1380
|
` });`,
|
|
1376
1381
|
"",
|
|
@@ -1784,7 +1789,7 @@ function finish() {
|
|
|
1784
1789
|
setTimeout(() => {
|
|
1785
1790
|
console.log('[build] Running post-build...');
|
|
1786
1791
|
try {
|
|
1787
|
-
execSync('node post-build.mjs', { cwd: CWD, stdio: 'inherit', timeout:
|
|
1792
|
+
execSync('node post-build.mjs', { cwd: CWD, stdio: 'inherit', timeout: 120_000 });
|
|
1788
1793
|
} catch (err) {
|
|
1789
1794
|
console.error('[build] post-build warning:', err.message);
|
|
1790
1795
|
}
|
|
@@ -1944,11 +1949,94 @@ function generatePostBuildMjs() {
|
|
|
1944
1949
|
`}`,
|
|
1945
1950
|
``,
|
|
1946
1951
|
`// ── Run ──────────────────────────────────────────────────────────`,
|
|
1952
|
+
`(async () => {`,
|
|
1953
|
+
``,
|
|
1947
1954
|
`generateIslandRedirects();`,
|
|
1948
1955
|
`copyAdapters();`,
|
|
1949
1956
|
`copyToNetlifyPaths();`,
|
|
1950
1957
|
`ensureNetlifyRedirects();`,
|
|
1958
|
+
``,
|
|
1959
|
+
`// ── Prerender (SSG) ──────────────────────────────────────────────`,
|
|
1960
|
+
`// Spawn the built server and fetch routes to generate static HTML.`,
|
|
1961
|
+
`const serverEntries = [`,
|
|
1962
|
+
` join(CWD, '.output', 'server', 'index.mjs'),`,
|
|
1963
|
+
` join(CWD, '.netlify', 'functions-internal', 'server', 'server.mjs'),`,
|
|
1964
|
+
` join(CWD, '.netlify', 'v1', 'functions', 'server', 'server.mjs'),`,
|
|
1965
|
+
`];`,
|
|
1966
|
+
`const serverEntry = serverEntries.find(p => existsSync(p));`,
|
|
1967
|
+
`const outputDir = [join(CWD, '.output', 'public'), DIST_DIR].find(d => existsSync(d));`,
|
|
1968
|
+
``,
|
|
1969
|
+
`if (serverEntry && outputDir) {`,
|
|
1970
|
+
` const { spawn: spawnProcess } = await import('node:child_process');`,
|
|
1971
|
+
` const PORT = 13172;`,
|
|
1972
|
+
` const baseUrl = 'http://localhost:' + PORT;`,
|
|
1973
|
+
` console.log('[prerender] Spawning server on port ' + PORT + '...');`,
|
|
1974
|
+
` const srv = spawnProcess('node', [serverEntry], {`,
|
|
1975
|
+
` env: { ...process.env, PORT: String(PORT), NITRO_PORT: String(PORT), HOST: '127.0.0.1', NITRO_HOST: '127.0.0.1', NODE_ENV: 'production' },`,
|
|
1976
|
+
` stdio: ['ignore', 'pipe', 'pipe'],`,
|
|
1977
|
+
` });`,
|
|
1978
|
+
` srv.stdout?.on('data', d => { const m = d.toString().trim(); if (m) console.log('[prerender:server] ' + m); });`,
|
|
1979
|
+
` srv.stderr?.on('data', d => { const m = d.toString().trim(); if (m) console.error('[prerender:server:err] ' + m); });`,
|
|
1980
|
+
` let ready = false;`,
|
|
1981
|
+
` const t0 = Date.now();`,
|
|
1982
|
+
` while (Date.now() - t0 < 15000) {`,
|
|
1983
|
+
` try { const r = await fetch(baseUrl + '/'); if (r.ok || r.status < 500) { ready = true; break; } } catch {}`,
|
|
1984
|
+
` await new Promise(r => setTimeout(r, 200));`,
|
|
1985
|
+
` }`,
|
|
1986
|
+
` if (ready) {`,
|
|
1987
|
+
` console.log('[prerender] Server ready');`,
|
|
1988
|
+
` const visited = new Set();`,
|
|
1989
|
+
` const queue = ['/'];`,
|
|
1990
|
+
` const prerendered = [];`,
|
|
1991
|
+
` while (queue.length > 0) {`,
|
|
1992
|
+
` const batch = queue.splice(0, 4);`,
|
|
1993
|
+
` await Promise.all(batch.map(async (route) => {`,
|
|
1994
|
+
` const norm = route.endsWith('/') && route !== '/' ? route.slice(0, -1) : route;`,
|
|
1995
|
+
` if (visited.has(norm)) return;`,
|
|
1996
|
+
` visited.add(norm);`,
|
|
1997
|
+
` try {`,
|
|
1998
|
+
` const res = await fetch(baseUrl + norm);`,
|
|
1999
|
+
` if (!res.ok) { console.error('[prerender] ' + norm + ' returned ' + res.status); return; }`,
|
|
2000
|
+
` const html = await res.text();`,
|
|
2001
|
+
` const fileName = join(norm, 'index.html');`,
|
|
2002
|
+
` const out = join(outputDir, fileName);`,
|
|
2003
|
+
` mkdirSync(dirname(out), { recursive: true });`,
|
|
2004
|
+
` writeFileSync(out, html);`,
|
|
2005
|
+
` prerendered.push(norm);`,
|
|
2006
|
+
` console.log('[prerender] ' + norm);`,
|
|
2007
|
+
` // Crawl links`,
|
|
2008
|
+
` const re = /<a\\s[^>]*href=["']([^"'#?]+)/gi;`,
|
|
2009
|
+
` let m;`,
|
|
2010
|
+
` while ((m = re.exec(html)) !== null) {`,
|
|
2011
|
+
` const href = m[1];`,
|
|
2012
|
+
` if (href.startsWith('/') && !href.startsWith('//') && !href.startsWith('/assets/') && !href.startsWith('/islands/') && !href.match(/\\.\\w{2,5}$/)) {`,
|
|
2013
|
+
` const n = href.endsWith('/') && href !== '/' ? href.slice(0, -1) : href;`,
|
|
2014
|
+
` if (!visited.has(n)) queue.push(n);`,
|
|
2015
|
+
` }`,
|
|
2016
|
+
` }`,
|
|
2017
|
+
` } catch (err) { console.error('[prerender] Error fetching ' + norm + ':', err.message); }`,
|
|
2018
|
+
` }));`,
|
|
2019
|
+
` }`,
|
|
2020
|
+
` srv.kill('SIGKILL');`,
|
|
2021
|
+
` console.log('[prerender] Done: ' + prerendered.length + ' page(s)');`,
|
|
2022
|
+
` // Copy to alt output dirs`,
|
|
2023
|
+
` for (const alt of [DIST_DIR, join(CWD, '.netlify', 'v1', 'functions', 'server', 'public')].filter(d => d !== outputDir && existsSync(dirname(d)))) {`,
|
|
2024
|
+
` for (const route of prerendered) {`,
|
|
2025
|
+
` const f = join(route, 'index.html');`,
|
|
2026
|
+
` const src = join(outputDir, f);`,
|
|
2027
|
+
` const dest = join(alt, f);`,
|
|
2028
|
+
` if (existsSync(src)) { mkdirSync(dirname(dest), { recursive: true }); copyFileSync(src, dest); }`,
|
|
2029
|
+
` }`,
|
|
2030
|
+
` }`,
|
|
2031
|
+
` } else {`,
|
|
2032
|
+
` srv.kill('SIGKILL');`,
|
|
2033
|
+
` console.error('[prerender] Server did not start, skipping prerender');`,
|
|
2034
|
+
` }`,
|
|
2035
|
+
`}`,
|
|
2036
|
+
``,
|
|
1951
2037
|
`console.log('[post-build] Complete');`,
|
|
2038
|
+
``,
|
|
2039
|
+
`})().catch(err => { console.error('[post-build] Fatal:', err); process.exit(1); });`,
|
|
1952
2040
|
``
|
|
1953
2041
|
];
|
|
1954
2042
|
return lines.join(`
|
package/package.json
CHANGED
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "create-avalon",
|
|
3
|
-
"version": "0.1.
|
|
4
|
-
"description": "Scaffold a new Avalon project with multi-framework islands architecture",
|
|
5
|
-
"license": "MIT",
|
|
6
|
-
"type": "module",
|
|
7
|
-
"repository": {
|
|
8
|
-
"type": "git",
|
|
9
|
-
"url": "https://github.com/useAvalon/Avalon.git",
|
|
10
|
-
"directory": "packages/create-avalon"
|
|
11
|
-
},
|
|
12
|
-
"homepage": "https://useavalon.dev",
|
|
13
|
-
"keywords": [
|
|
14
|
-
"avalon",
|
|
15
|
-
"create",
|
|
16
|
-
"scaffold",
|
|
17
|
-
"cli",
|
|
18
|
-
"islands",
|
|
19
|
-
"vite"
|
|
20
|
-
],
|
|
21
|
-
"bin": {
|
|
22
|
-
"create-avalon": "dist/cli.js"
|
|
23
|
-
},
|
|
24
|
-
"files": [
|
|
25
|
-
"dist",
|
|
26
|
-
"README.md"
|
|
27
|
-
],
|
|
28
|
-
"scripts": {
|
|
29
|
-
"build": "bun build src/cli.ts --outdir dist --target node --format esm",
|
|
30
|
-
"prepublishOnly": "bun run build"
|
|
31
|
-
},
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"@clack/prompts": "^1.1.0"
|
|
34
|
-
},
|
|
35
|
-
"devDependencies": {
|
|
36
|
-
"fast-check": "^4.6.0",
|
|
37
|
-
"vitest": "^4.1.0"
|
|
38
|
-
}
|
|
39
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "create-avalon",
|
|
3
|
+
"version": "0.1.16",
|
|
4
|
+
"description": "Scaffold a new Avalon project with multi-framework islands architecture",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/useAvalon/Avalon.git",
|
|
10
|
+
"directory": "packages/create-avalon"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://useavalon.dev",
|
|
13
|
+
"keywords": [
|
|
14
|
+
"avalon",
|
|
15
|
+
"create",
|
|
16
|
+
"scaffold",
|
|
17
|
+
"cli",
|
|
18
|
+
"islands",
|
|
19
|
+
"vite"
|
|
20
|
+
],
|
|
21
|
+
"bin": {
|
|
22
|
+
"create-avalon": "dist/cli.js"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"README.md"
|
|
27
|
+
],
|
|
28
|
+
"scripts": {
|
|
29
|
+
"build": "bun build src/cli.ts --outdir dist --target node --format esm",
|
|
30
|
+
"prepublishOnly": "bun run build"
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {
|
|
33
|
+
"@clack/prompts": "^1.1.0"
|
|
34
|
+
},
|
|
35
|
+
"devDependencies": {
|
|
36
|
+
"fast-check": "^4.6.0",
|
|
37
|
+
"vitest": "^4.1.0"
|
|
38
|
+
}
|
|
39
|
+
}
|