create-rotor 0.2.2 → 0.3.0
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/index.js +51 -25
- package/package.json +1 -1
- package/template/CLAUDE.md +24 -0
- package/template/app/error.tsx +21 -0
- package/template/app/icon.svg +3 -0
- package/template/app/not-found.tsx +8 -0
- package/template/gitignore +6 -0
- package/template/lib/fetcher.ts +9 -0
- /package/template/{postcss.config.mjs → postcss.config.ts} +0 -0
package/dist/index.js
CHANGED
|
@@ -1171,7 +1171,7 @@ var MODULES = {
|
|
|
1171
1171
|
name: "swr",
|
|
1172
1172
|
label: "SWR",
|
|
1173
1173
|
hint: "Data fetching",
|
|
1174
|
-
files: [],
|
|
1174
|
+
files: ["lib/fetcher.ts"],
|
|
1175
1175
|
dependencies: {
|
|
1176
1176
|
swr: "2.4.1"
|
|
1177
1177
|
},
|
|
@@ -1210,7 +1210,7 @@ var MODULES = {
|
|
|
1210
1210
|
// src/helpers.ts
|
|
1211
1211
|
import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
1212
1212
|
import { join } from "node:path";
|
|
1213
|
-
function
|
|
1213
|
+
function trimPackageJson(pkgPath, selectedModules, options) {
|
|
1214
1214
|
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
1215
1215
|
const unselected = Object.keys(MODULES).filter((m) => !selectedModules.includes(m));
|
|
1216
1216
|
for (const moduleName of unselected) {
|
|
@@ -1222,11 +1222,6 @@ function trimDependencies(pkgPath, selectedModules) {
|
|
|
1222
1222
|
delete pkg.devDependencies?.[dep];
|
|
1223
1223
|
}
|
|
1224
1224
|
}
|
|
1225
|
-
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
1226
|
-
`);
|
|
1227
|
-
}
|
|
1228
|
-
function trimScripts(pkgPath, selectedModules) {
|
|
1229
|
-
const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
|
|
1230
1225
|
if (!selectedModules.includes("drizzle")) {
|
|
1231
1226
|
for (const key of Object.keys(pkg.scripts || {})) {
|
|
1232
1227
|
if (key.startsWith("db:")) {
|
|
@@ -1234,12 +1229,17 @@ function trimScripts(pkgPath, selectedModules) {
|
|
|
1234
1229
|
}
|
|
1235
1230
|
}
|
|
1236
1231
|
}
|
|
1232
|
+
if (options?.removeHusky) {
|
|
1233
|
+
delete pkg.devDependencies?.husky;
|
|
1234
|
+
delete pkg.devDependencies?.["lint-staged"];
|
|
1235
|
+
delete pkg.scripts?.prepare;
|
|
1236
|
+
}
|
|
1237
1237
|
writeFileSync(pkgPath, `${JSON.stringify(pkg, null, 2)}
|
|
1238
1238
|
`);
|
|
1239
1239
|
}
|
|
1240
1240
|
function trimEnvFile(envPath, selectedModules) {
|
|
1241
1241
|
if (!existsSync(envPath))
|
|
1242
|
-
return;
|
|
1242
|
+
return false;
|
|
1243
1243
|
const content = readFileSync(envPath, "utf-8");
|
|
1244
1244
|
const lines = content.split(`
|
|
1245
1245
|
`);
|
|
@@ -1271,21 +1271,28 @@ function trimEnvFile(envPath, selectedModules) {
|
|
|
1271
1271
|
`).trim();
|
|
1272
1272
|
writeFileSync(envPath, cleaned ? `${cleaned}
|
|
1273
1273
|
` : "");
|
|
1274
|
+
return cleaned.length > 0;
|
|
1275
|
+
}
|
|
1276
|
+
function removeHuskyFiles(projectDir) {
|
|
1277
|
+
rmSync(join(projectDir, ".husky"), { recursive: true, force: true });
|
|
1278
|
+
rmSync(join(projectDir, ".lintstagedrc"), { force: true });
|
|
1274
1279
|
}
|
|
1275
1280
|
function removeModuleFiles(projectDir, selectedModules) {
|
|
1276
1281
|
const unselected = Object.keys(MODULES).filter((m) => !selectedModules.includes(m));
|
|
1277
1282
|
for (const moduleName of unselected) {
|
|
1278
1283
|
const mod = MODULES[moduleName];
|
|
1279
1284
|
for (const file of mod.files) {
|
|
1280
|
-
|
|
1281
|
-
if (existsSync(filePath)) {
|
|
1282
|
-
rmSync(filePath, { recursive: true, force: true });
|
|
1283
|
-
}
|
|
1285
|
+
rmSync(join(projectDir, file), { recursive: true, force: true });
|
|
1284
1286
|
}
|
|
1285
1287
|
}
|
|
1286
1288
|
}
|
|
1287
1289
|
function replaceProjectName(projectDir, projectName) {
|
|
1288
|
-
const filesToReplace = [
|
|
1290
|
+
const filesToReplace = [
|
|
1291
|
+
"package.json",
|
|
1292
|
+
"app/layout.tsx",
|
|
1293
|
+
"README.md",
|
|
1294
|
+
"CLAUDE.md"
|
|
1295
|
+
];
|
|
1289
1296
|
for (const file of filesToReplace) {
|
|
1290
1297
|
const filePath = join(projectDir, file);
|
|
1291
1298
|
if (!existsSync(filePath))
|
|
@@ -1422,34 +1429,53 @@ async function main() {
|
|
|
1422
1429
|
renameSync(join2(targetDir, "gitignore"), join2(targetDir, ".gitignore"));
|
|
1423
1430
|
replaceProjectName(targetDir, projectName);
|
|
1424
1431
|
removeModuleFiles(targetDir, selectedModules);
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1432
|
+
trimPackageJson(join2(targetDir, "package.json"), selectedModules, {
|
|
1433
|
+
removeHusky: !initGit
|
|
1434
|
+
});
|
|
1435
|
+
const hasEnv = trimEnvFile(join2(targetDir, ".env.example"), selectedModules);
|
|
1428
1436
|
if (!selectedModules.includes("shadcn")) {
|
|
1429
1437
|
trimCssShadcn(join2(targetDir, "app", "globals.css"));
|
|
1430
1438
|
}
|
|
1439
|
+
if (!initGit) {
|
|
1440
|
+
removeHuskyFiles(targetDir);
|
|
1441
|
+
}
|
|
1431
1442
|
s.stop("Project created!");
|
|
1443
|
+
let installed = false;
|
|
1432
1444
|
if (installDeps) {
|
|
1433
1445
|
const installSpinner = be();
|
|
1434
1446
|
installSpinner.start("Installing dependencies...");
|
|
1447
|
+
let hasBun = false;
|
|
1435
1448
|
try {
|
|
1436
|
-
execSync("bun
|
|
1437
|
-
|
|
1449
|
+
execSync("bun --version", { stdio: "ignore" });
|
|
1450
|
+
hasBun = true;
|
|
1438
1451
|
} catch {
|
|
1439
|
-
installSpinner.stop('
|
|
1452
|
+
installSpinner.stop('Bun not found. Install it from https://bun.sh then run "bun install".');
|
|
1453
|
+
}
|
|
1454
|
+
if (hasBun) {
|
|
1455
|
+
try {
|
|
1456
|
+
execSync("bun install", { cwd: targetDir, stdio: "ignore" });
|
|
1457
|
+
installSpinner.stop("Dependencies installed!");
|
|
1458
|
+
installed = true;
|
|
1459
|
+
} catch {
|
|
1460
|
+
installSpinner.stop('Failed to install dependencies. Run "bun install" manually.');
|
|
1461
|
+
}
|
|
1440
1462
|
}
|
|
1441
1463
|
}
|
|
1442
1464
|
if (initGit) {
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1465
|
+
try {
|
|
1466
|
+
execSync("git init", { cwd: targetDir, stdio: "ignore" });
|
|
1467
|
+
execSync("git add -A", { cwd: targetDir, stdio: "ignore" });
|
|
1468
|
+
execSync('git commit -m "chore: init from create-rotor"', {
|
|
1469
|
+
cwd: targetDir,
|
|
1470
|
+
stdio: "ignore"
|
|
1471
|
+
});
|
|
1472
|
+
} catch {}
|
|
1446
1473
|
}
|
|
1447
1474
|
const steps = [`cd ${projectName}`];
|
|
1448
|
-
if (!
|
|
1475
|
+
if (!installed) {
|
|
1449
1476
|
steps.push("bun install");
|
|
1450
1477
|
}
|
|
1451
|
-
|
|
1452
|
-
if (readFileSync2(envPath, "utf-8").trim().length > 0) {
|
|
1478
|
+
if (hasEnv) {
|
|
1453
1479
|
steps.push("cp .env.example .env # configure environment variables");
|
|
1454
1480
|
}
|
|
1455
1481
|
steps.push("bun dev");
|
package/package.json
CHANGED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
## Commands
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun dev # Start dev server with Turbopack
|
|
7
|
+
bun build # Production build
|
|
8
|
+
bun start # Start production server
|
|
9
|
+
bun run check # Lint and format with Biome
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Architecture
|
|
13
|
+
|
|
14
|
+
Next.js App Router project.
|
|
15
|
+
|
|
16
|
+
- **Styling**: Tailwind CSS v4 — CSS-first config in `app/globals.css`, no `tailwind.config`
|
|
17
|
+
- **Code quality**: Biome (lint + format)
|
|
18
|
+
- **Path alias**: `@/*` maps to project root
|
|
19
|
+
|
|
20
|
+
## Key Directories
|
|
21
|
+
|
|
22
|
+
- `app/` — Routes, layouts, pages, API routes
|
|
23
|
+
- `lib/` — Utilities, database client, shared logic
|
|
24
|
+
- `components/` — React components
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
export default function ErrorPage({
|
|
4
|
+
reset,
|
|
5
|
+
}: {
|
|
6
|
+
error: Error & { digest?: string };
|
|
7
|
+
reset: () => void;
|
|
8
|
+
}) {
|
|
9
|
+
return (
|
|
10
|
+
<main className="flex min-h-screen flex-col items-center justify-center p-24">
|
|
11
|
+
<h1 className="font-bold text-4xl">Something went wrong</h1>
|
|
12
|
+
<button
|
|
13
|
+
className="mt-4 rounded-md bg-neutral-900 px-4 py-2 text-sm text-white hover:bg-neutral-800"
|
|
14
|
+
onClick={reset}
|
|
15
|
+
type="button"
|
|
16
|
+
>
|
|
17
|
+
Try again
|
|
18
|
+
</button>
|
|
19
|
+
</main>
|
|
20
|
+
);
|
|
21
|
+
}
|
package/template/gitignore
CHANGED
|
File without changes
|