create-avalon 0.1.10 → 0.1.12
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/dist/cli.js +120 -75
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -1192,7 +1192,7 @@ async function collectProjectConfig(initialName) {
|
|
|
1192
1192
|
|
|
1193
1193
|
// src/scaffold.ts
|
|
1194
1194
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
1195
|
-
import { join } from "node:path";
|
|
1195
|
+
import { join, dirname } from "node:path";
|
|
1196
1196
|
|
|
1197
1197
|
// src/types.ts
|
|
1198
1198
|
var INTEGRATION_PACKAGES = {
|
|
@@ -1254,6 +1254,8 @@ function generatePackageJson(config) {
|
|
|
1254
1254
|
devDependencies["tailwindcss"] = "latest";
|
|
1255
1255
|
devDependencies["@tailwindcss/vite"] = "latest";
|
|
1256
1256
|
dependencies["@shadcn/ui"] = "latest";
|
|
1257
|
+
dependencies["tailwind-merge"] = "^3.5.0";
|
|
1258
|
+
dependencies["clsx"] = "^2.1.1";
|
|
1257
1259
|
break;
|
|
1258
1260
|
}
|
|
1259
1261
|
const pkg = {
|
|
@@ -1282,20 +1284,33 @@ function generateTsConfig() {
|
|
|
1282
1284
|
esModuleInterop: true,
|
|
1283
1285
|
skipLibCheck: true,
|
|
1284
1286
|
allowArbitraryExtensions: true,
|
|
1287
|
+
allowImportingTsExtensions: true,
|
|
1288
|
+
noEmit: true,
|
|
1285
1289
|
jsx: "react-jsx",
|
|
1286
1290
|
paths: {
|
|
1287
1291
|
"@shared/*": ["./app/shared/*"],
|
|
1288
1292
|
"@modules/*": ["./app/modules/*"]
|
|
1289
1293
|
}
|
|
1290
1294
|
},
|
|
1291
|
-
include: ["app/**/*.ts", "app/**/*.tsx", "server/**/*.ts", "routes/**/*.ts", "middleware/**/*.ts"]
|
|
1295
|
+
include: ["app/**/*.ts", "app/**/*.tsx", "app/**/*.d.ts", "server/**/*.ts", "routes/**/*.ts", "middleware/**/*.ts"]
|
|
1292
1296
|
};
|
|
1293
1297
|
return JSON.stringify(tsconfig, null, 2);
|
|
1294
1298
|
}
|
|
1299
|
+
function generateEnvDts() {
|
|
1300
|
+
return `/// <reference types="@useavalon/avalon/types" />
|
|
1301
|
+
|
|
1302
|
+
// Virtual module declarations
|
|
1303
|
+
declare module 'virtual:avalon/config' {
|
|
1304
|
+
const config: Record<string, unknown>;
|
|
1305
|
+
export default config;
|
|
1306
|
+
}
|
|
1307
|
+
`;
|
|
1308
|
+
}
|
|
1295
1309
|
|
|
1296
1310
|
// src/templates/vite-config.ts
|
|
1297
1311
|
function generateViteConfig(config) {
|
|
1298
1312
|
const imports = [
|
|
1313
|
+
`import { resolve } from 'node:path';`,
|
|
1299
1314
|
`import { defineConfig, type UserConfig } from 'vite';`,
|
|
1300
1315
|
`import { avalon } from '@useavalon/avalon';`
|
|
1301
1316
|
];
|
|
@@ -1348,6 +1363,14 @@ function generateViteConfig(config) {
|
|
|
1348
1363
|
`),
|
|
1349
1364
|
` ],`,
|
|
1350
1365
|
``,
|
|
1366
|
+
` resolve: {`,
|
|
1367
|
+
` alias: {`,
|
|
1368
|
+
` '@shared': resolve(__dirname, 'app/shared'),`,
|
|
1369
|
+
` '@modules': resolve(__dirname, 'app/modules'),`,
|
|
1370
|
+
` '@': resolve(__dirname, 'app'),`,
|
|
1371
|
+
` },`,
|
|
1372
|
+
` },`,
|
|
1373
|
+
``,
|
|
1351
1374
|
` server: {`,
|
|
1352
1375
|
` port: 3000,`,
|
|
1353
1376
|
` },`,
|
|
@@ -1453,91 +1476,32 @@ export default async function HomePage() {
|
|
|
1453
1476
|
}
|
|
1454
1477
|
|
|
1455
1478
|
// src/templates/middleware.ts
|
|
1456
|
-
function generateSampleMiddleware(
|
|
1457
|
-
|
|
1458
|
-
case "h3":
|
|
1459
|
-
return generateH3Middleware();
|
|
1460
|
-
case "hono":
|
|
1461
|
-
return generateHonoMiddleware();
|
|
1462
|
-
case "elysia":
|
|
1463
|
-
return generateElysiaMiddleware();
|
|
1464
|
-
}
|
|
1465
|
-
}
|
|
1466
|
-
function generateH3Middleware() {
|
|
1467
|
-
return `import { defineHandler } from 'nitro/h3';
|
|
1479
|
+
function generateSampleMiddleware(_config) {
|
|
1480
|
+
return `import { defineHandler } from 'nitro';
|
|
1468
1481
|
|
|
1469
1482
|
export default defineHandler((event) => {
|
|
1470
|
-
console.log(\`[\${new Date().toISOString()}] \${event.method} \${event.
|
|
1471
|
-
});
|
|
1472
|
-
`;
|
|
1473
|
-
}
|
|
1474
|
-
function generateHonoMiddleware() {
|
|
1475
|
-
return `import { Hono } from 'hono';
|
|
1476
|
-
|
|
1477
|
-
const app = new Hono();
|
|
1478
|
-
|
|
1479
|
-
app.use('*', async (c, next) => {
|
|
1480
|
-
console.log(\`[\${new Date().toISOString()}] \${c.req.method} \${c.req.path}\`);
|
|
1481
|
-
await next();
|
|
1483
|
+
console.log(\`[\${new Date().toISOString()}] \${event.req.method} \${event.url.pathname}\`);
|
|
1482
1484
|
});
|
|
1483
|
-
|
|
1484
|
-
export default app;
|
|
1485
|
-
`;
|
|
1486
|
-
}
|
|
1487
|
-
function generateElysiaMiddleware() {
|
|
1488
|
-
return `import { Elysia } from 'elysia';
|
|
1489
|
-
|
|
1490
|
-
export default new Elysia()
|
|
1491
|
-
.onBeforeHandle(({ request }) => {
|
|
1492
|
-
console.log(\`[\${new Date().toISOString()}] \${request.method} \${new URL(request.url).pathname}\`);
|
|
1493
|
-
});
|
|
1494
1485
|
`;
|
|
1495
1486
|
}
|
|
1496
1487
|
|
|
1497
1488
|
// src/templates/api-routes.ts
|
|
1498
|
-
function generateHelloRoute(
|
|
1499
|
-
|
|
1500
|
-
case "h3":
|
|
1501
|
-
return generateH3Route();
|
|
1502
|
-
case "hono":
|
|
1503
|
-
return generateHonoRoute();
|
|
1504
|
-
case "elysia":
|
|
1505
|
-
return generateElysiaRoute();
|
|
1506
|
-
}
|
|
1507
|
-
}
|
|
1508
|
-
function generateH3Route() {
|
|
1509
|
-
return `import { defineHandler } from 'nitro/h3';
|
|
1489
|
+
function generateHelloRoute(_config) {
|
|
1490
|
+
return `import { defineHandler } from 'nitro';
|
|
1510
1491
|
|
|
1511
1492
|
export default defineHandler(() => {
|
|
1512
|
-
return { message: 'Hello from Avalon!' };
|
|
1493
|
+
return Response.json({ message: 'Hello from Avalon!' });
|
|
1513
1494
|
});
|
|
1514
1495
|
`;
|
|
1515
1496
|
}
|
|
1516
|
-
function generateHonoRoute() {
|
|
1517
|
-
return `import { Hono } from 'hono';
|
|
1518
|
-
|
|
1519
|
-
const app = new Hono();
|
|
1520
|
-
|
|
1521
|
-
app.get('/', (c) => {
|
|
1522
|
-
return c.json({ message: 'Hello from Avalon!' });
|
|
1523
|
-
});
|
|
1524
|
-
|
|
1525
|
-
export default app;
|
|
1526
|
-
`;
|
|
1527
|
-
}
|
|
1528
|
-
function generateElysiaRoute() {
|
|
1529
|
-
return `import { Elysia } from 'elysia';
|
|
1530
|
-
|
|
1531
|
-
export default new Elysia()
|
|
1532
|
-
.get('/', () => ({ message: 'Hello from Avalon!' }));
|
|
1533
|
-
`;
|
|
1534
|
-
}
|
|
1535
1497
|
|
|
1536
1498
|
// src/templates/styling.ts
|
|
1537
1499
|
function generateStylingFiles(config) {
|
|
1538
1500
|
const files = new Map;
|
|
1539
1501
|
files.set("app/shared/styles/main.css", generateMainCss(config));
|
|
1540
|
-
|
|
1502
|
+
if (config.styling === "css-modules") {
|
|
1503
|
+
files.set("app/shared/styles/reset.css", generateResetCss());
|
|
1504
|
+
}
|
|
1541
1505
|
switch (config.styling) {
|
|
1542
1506
|
case "css-modules":
|
|
1543
1507
|
files.set("app/shared/styles/tokens.css", generateTokensCss());
|
|
@@ -1547,19 +1511,21 @@ function generateStylingFiles(config) {
|
|
|
1547
1511
|
break;
|
|
1548
1512
|
case "tailwind":
|
|
1549
1513
|
files.set("tailwind.config.js", generateTailwindConfig());
|
|
1550
|
-
files.set("app/shared/styles/global.css", generateTailwindGlobalCss());
|
|
1514
|
+
files.set("app/shared/styles/global.css", generateTailwindGlobalCss(config));
|
|
1551
1515
|
break;
|
|
1552
1516
|
case "shadcn":
|
|
1553
1517
|
files.set("tailwind.config.js", generateTailwindConfig());
|
|
1554
|
-
files.set("app/shared/styles/global.css", generateTailwindGlobalCss());
|
|
1518
|
+
files.set("app/shared/styles/global.css", generateTailwindGlobalCss(config));
|
|
1555
1519
|
files.set("components.json", generateShadcnComponentsJson(config));
|
|
1520
|
+
files.set("app/shared/utils/cn.ts", generateCnUtil());
|
|
1556
1521
|
break;
|
|
1557
1522
|
}
|
|
1558
1523
|
return files;
|
|
1559
1524
|
}
|
|
1560
1525
|
function generateMainCss(config) {
|
|
1561
|
-
const imports = [
|
|
1526
|
+
const imports = [];
|
|
1562
1527
|
if (config.styling === "css-modules") {
|
|
1528
|
+
imports.push(`@import './reset.css';`);
|
|
1563
1529
|
imports.push(`@import './tokens.css';`);
|
|
1564
1530
|
} else {
|
|
1565
1531
|
imports.push(`@import './global.css';`);
|
|
@@ -1667,8 +1633,47 @@ export default {
|
|
|
1667
1633
|
};
|
|
1668
1634
|
`;
|
|
1669
1635
|
}
|
|
1670
|
-
function generateTailwindGlobalCss() {
|
|
1671
|
-
|
|
1636
|
+
function generateTailwindGlobalCss(config) {
|
|
1637
|
+
const lines = [`@import "tailwindcss";`];
|
|
1638
|
+
if (config.styling === "shadcn") {
|
|
1639
|
+
lines.push("");
|
|
1640
|
+
lines.push(`@theme inline {
|
|
1641
|
+
--color-background: oklch(1 0 0);
|
|
1642
|
+
--color-foreground: oklch(0.145 0 0);
|
|
1643
|
+
--color-card: oklch(1 0 0);
|
|
1644
|
+
--color-card-foreground: oklch(0.145 0 0);
|
|
1645
|
+
--color-popover: oklch(1 0 0);
|
|
1646
|
+
--color-popover-foreground: oklch(0.145 0 0);
|
|
1647
|
+
--color-primary: oklch(0.205 0 0);
|
|
1648
|
+
--color-primary-foreground: oklch(0.985 0 0);
|
|
1649
|
+
--color-secondary: oklch(0.97 0 0);
|
|
1650
|
+
--color-secondary-foreground: oklch(0.205 0 0);
|
|
1651
|
+
--color-muted: oklch(0.97 0 0);
|
|
1652
|
+
--color-muted-foreground: oklch(0.556 0 0);
|
|
1653
|
+
--color-accent: oklch(0.97 0 0);
|
|
1654
|
+
--color-accent-foreground: oklch(0.205 0 0);
|
|
1655
|
+
--color-destructive: oklch(0.577 0.245 27.325);
|
|
1656
|
+
--color-destructive-foreground: oklch(0.577 0.245 27.325);
|
|
1657
|
+
--color-border: oklch(0.922 0 0);
|
|
1658
|
+
--color-input: oklch(0.922 0 0);
|
|
1659
|
+
--color-ring: oklch(0.708 0 0);
|
|
1660
|
+
--radius-sm: 0.25rem;
|
|
1661
|
+
--radius-md: 0.375rem;
|
|
1662
|
+
--radius-lg: 0.5rem;
|
|
1663
|
+
--radius-xl: 0.75rem;
|
|
1664
|
+
}`);
|
|
1665
|
+
}
|
|
1666
|
+
return lines.join(`
|
|
1667
|
+
`) + `
|
|
1668
|
+
`;
|
|
1669
|
+
}
|
|
1670
|
+
function generateCnUtil() {
|
|
1671
|
+
return `import { clsx, type ClassValue } from 'clsx';
|
|
1672
|
+
import { twMerge } from 'tailwind-merge';
|
|
1673
|
+
|
|
1674
|
+
export function cn(...inputs: ClassValue[]) {
|
|
1675
|
+
return twMerge(clsx(inputs));
|
|
1676
|
+
}
|
|
1672
1677
|
`;
|
|
1673
1678
|
}
|
|
1674
1679
|
function generateShadcnComponentsJson(config) {
|
|
@@ -1695,6 +1700,39 @@ function getFaviconBuffer() {
|
|
|
1695
1700
|
}
|
|
1696
1701
|
|
|
1697
1702
|
// src/scaffold.ts
|
|
1703
|
+
function generateHonoServerEntry() {
|
|
1704
|
+
return `import { Hono } from 'hono';
|
|
1705
|
+
|
|
1706
|
+
const app = new Hono();
|
|
1707
|
+
|
|
1708
|
+
// Add your Hono middleware and routes here.
|
|
1709
|
+
// This file is the Nitro server entry using the web fetch interface.
|
|
1710
|
+
// Route files in routes/ still use defineHandler from 'nitro'.
|
|
1711
|
+
|
|
1712
|
+
app.use('*', async (c, next) => {
|
|
1713
|
+
console.log(\`[\${new Date().toISOString()}] \${c.req.method} \${c.req.path}\`);
|
|
1714
|
+
await next();
|
|
1715
|
+
});
|
|
1716
|
+
|
|
1717
|
+
export default app;
|
|
1718
|
+
`;
|
|
1719
|
+
}
|
|
1720
|
+
function generateElysiaServerEntry() {
|
|
1721
|
+
return `import { Elysia } from 'elysia';
|
|
1722
|
+
|
|
1723
|
+
const app = new Elysia();
|
|
1724
|
+
|
|
1725
|
+
// Add your Elysia middleware and routes here.
|
|
1726
|
+
// This file is the Nitro server entry using the web fetch interface.
|
|
1727
|
+
// Route files in routes/ still use defineHandler from 'nitro'.
|
|
1728
|
+
|
|
1729
|
+
app.onBeforeHandle(({ request }) => {
|
|
1730
|
+
console.log(\`[\${new Date().toISOString()}] \${request.method} \${new URL(request.url).pathname}\`);
|
|
1731
|
+
});
|
|
1732
|
+
|
|
1733
|
+
export default app;
|
|
1734
|
+
`;
|
|
1735
|
+
}
|
|
1698
1736
|
async function scaffoldProject(config, targetDir) {
|
|
1699
1737
|
await mkdir(targetDir, { recursive: true });
|
|
1700
1738
|
for (const dir of BASE_DIRS) {
|
|
@@ -1708,13 +1746,20 @@ async function scaffoldProject(config, targetDir) {
|
|
|
1708
1746
|
await writeFile(join(targetDir, "app/modules/home/pages/index.tsx"), generateHomePage(config));
|
|
1709
1747
|
await writeFile(join(targetDir, "middleware/01.logger.ts"), generateSampleMiddleware(config));
|
|
1710
1748
|
await writeFile(join(targetDir, "routes/api/hello.ts"), generateHelloRoute(config));
|
|
1749
|
+
if (config.middleware === "hono") {
|
|
1750
|
+
await writeFile(join(targetDir, "server.ts"), generateHonoServerEntry());
|
|
1751
|
+
} else if (config.middleware === "elysia") {
|
|
1752
|
+
await writeFile(join(targetDir, "server.ts"), generateElysiaServerEntry());
|
|
1753
|
+
}
|
|
1711
1754
|
const stylingFiles = generateStylingFiles(config);
|
|
1712
1755
|
for (const [filePath, content] of stylingFiles) {
|
|
1756
|
+
await mkdir(join(targetDir, dirname(filePath)), { recursive: true });
|
|
1713
1757
|
await writeFile(join(targetDir, filePath), content);
|
|
1714
1758
|
}
|
|
1715
1759
|
await writeFile(join(targetDir, "public/favicon.ico"), getFaviconBuffer());
|
|
1716
1760
|
await writeFile(join(targetDir, "server/env.d.ts"), `/// <reference types="nitro" />
|
|
1717
1761
|
`);
|
|
1762
|
+
await writeFile(join(targetDir, "app/env.d.ts"), generateEnvDts());
|
|
1718
1763
|
await writeFile(join(targetDir, "server/renderer.ts"), [
|
|
1719
1764
|
`import { createNitroRenderer } from '@useavalon/avalon/nitro/renderer';`,
|
|
1720
1765
|
`import avalonConfig from 'virtual:avalon/config';`,
|