prev-cli 0.12.4 → 0.13.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/cli.js +151 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
// src/cli.ts
|
|
4
4
|
import { parseArgs } from "util";
|
|
5
5
|
import path7 from "path";
|
|
6
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3 } from "fs";
|
|
6
7
|
|
|
7
8
|
// src/vite/start.ts
|
|
8
9
|
import { createServer as createServer2, build as build2, preview } from "vite";
|
|
@@ -980,6 +981,7 @@ Usage:
|
|
|
980
981
|
prev [options] Start development server
|
|
981
982
|
prev build [options] Build for production
|
|
982
983
|
prev preview [options] Preview production build
|
|
984
|
+
prev create [name] Create example preview (default: "example")
|
|
983
985
|
prev clean [options] Remove old cache directories
|
|
984
986
|
|
|
985
987
|
Options:
|
|
@@ -1023,10 +1025,155 @@ Examples:
|
|
|
1023
1025
|
prev Start dev server on random port
|
|
1024
1026
|
prev -p 3000 Start dev server on port 3000
|
|
1025
1027
|
prev build Build static site to ./dist
|
|
1028
|
+
prev create Create example preview in previews/example/
|
|
1029
|
+
prev create my-demo Create preview in previews/my-demo/
|
|
1026
1030
|
prev -i .c3 Include .c3 directory in docs
|
|
1027
1031
|
prev clean -d 7 Remove caches older than 7 days
|
|
1028
1032
|
`);
|
|
1029
1033
|
}
|
|
1034
|
+
function createPreview(rootDir2, name) {
|
|
1035
|
+
const previewDir = path7.join(rootDir2, "previews", name);
|
|
1036
|
+
if (existsSync5(previewDir)) {
|
|
1037
|
+
console.error(`Preview "${name}" already exists at: ${previewDir}`);
|
|
1038
|
+
process.exit(1);
|
|
1039
|
+
}
|
|
1040
|
+
mkdirSync2(previewDir, { recursive: true });
|
|
1041
|
+
const appTsx = `import { useState } from 'react'
|
|
1042
|
+
import './styles.css'
|
|
1043
|
+
|
|
1044
|
+
export default function App() {
|
|
1045
|
+
const [count, setCount] = useState(0)
|
|
1046
|
+
const [items, setItems] = useState<string[]>([])
|
|
1047
|
+
|
|
1048
|
+
const addItem = () => {
|
|
1049
|
+
setItems([...items, \`Item \${items.length + 1}\`])
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
return (
|
|
1053
|
+
<div className="min-h-screen bg-gradient-to-br from-indigo-50 to-purple-100 p-8">
|
|
1054
|
+
<div className="max-w-md mx-auto space-y-6">
|
|
1055
|
+
{/* Header */}
|
|
1056
|
+
<div className="text-center animate-fade-in">
|
|
1057
|
+
<h1 className="text-3xl font-bold text-gray-800">
|
|
1058
|
+
Preview Demo
|
|
1059
|
+
</h1>
|
|
1060
|
+
<p className="text-gray-600 mt-2">
|
|
1061
|
+
React + TypeScript + Tailwind
|
|
1062
|
+
</p>
|
|
1063
|
+
</div>
|
|
1064
|
+
|
|
1065
|
+
{/* Counter Card */}
|
|
1066
|
+
<div className="bg-white rounded-xl shadow-lg p-6 animate-fade-in">
|
|
1067
|
+
<h2 className="text-lg font-semibold text-gray-700 mb-4">Counter</h2>
|
|
1068
|
+
<div className="flex items-center justify-center gap-4">
|
|
1069
|
+
<button
|
|
1070
|
+
onClick={() => setCount(c => c - 1)}
|
|
1071
|
+
className="w-12 h-12 rounded-full bg-red-500 hover:bg-red-600 text-white text-xl font-bold transition-colors"
|
|
1072
|
+
>
|
|
1073
|
+
-
|
|
1074
|
+
</button>
|
|
1075
|
+
<span className="text-4xl font-mono font-bold text-gray-800 w-16 text-center">
|
|
1076
|
+
{count}
|
|
1077
|
+
</span>
|
|
1078
|
+
<button
|
|
1079
|
+
onClick={() => setCount(c => c + 1)}
|
|
1080
|
+
className="w-12 h-12 rounded-full bg-green-500 hover:bg-green-600 text-white text-xl font-bold transition-colors"
|
|
1081
|
+
>
|
|
1082
|
+
+
|
|
1083
|
+
</button>
|
|
1084
|
+
</div>
|
|
1085
|
+
</div>
|
|
1086
|
+
|
|
1087
|
+
{/* Dynamic List Card */}
|
|
1088
|
+
<div className="bg-white rounded-xl shadow-lg p-6 animate-fade-in">
|
|
1089
|
+
<div className="flex items-center justify-between mb-4">
|
|
1090
|
+
<h2 className="text-lg font-semibold text-gray-700">Dynamic List</h2>
|
|
1091
|
+
<button
|
|
1092
|
+
onClick={addItem}
|
|
1093
|
+
className="px-3 py-1 bg-indigo-500 hover:bg-indigo-600 text-white text-sm rounded-lg transition-colors"
|
|
1094
|
+
>
|
|
1095
|
+
Add Item
|
|
1096
|
+
</button>
|
|
1097
|
+
</div>
|
|
1098
|
+
{items.length === 0 ? (
|
|
1099
|
+
<p className="text-gray-400 text-center py-4">No items yet</p>
|
|
1100
|
+
) : (
|
|
1101
|
+
<ul className="space-y-2">
|
|
1102
|
+
{items.map((item, i) => (
|
|
1103
|
+
<li
|
|
1104
|
+
key={i}
|
|
1105
|
+
className="px-3 py-2 bg-gray-50 rounded-lg text-gray-700 animate-slide-in"
|
|
1106
|
+
>
|
|
1107
|
+
{item}
|
|
1108
|
+
</li>
|
|
1109
|
+
))}
|
|
1110
|
+
</ul>
|
|
1111
|
+
)}
|
|
1112
|
+
</div>
|
|
1113
|
+
|
|
1114
|
+
{/* Info Box */}
|
|
1115
|
+
<div className="bg-indigo-50 border border-indigo-200 rounded-lg p-4 text-sm text-indigo-700">
|
|
1116
|
+
<strong>Tip:</strong> Use the DevTools pill (bottom-right) to test
|
|
1117
|
+
responsive layouts and dark mode.
|
|
1118
|
+
</div>
|
|
1119
|
+
</div>
|
|
1120
|
+
</div>
|
|
1121
|
+
)
|
|
1122
|
+
}
|
|
1123
|
+
`;
|
|
1124
|
+
const stylesCss = `/* Custom animations for the preview */
|
|
1125
|
+
@keyframes fade-in {
|
|
1126
|
+
from {
|
|
1127
|
+
opacity: 0;
|
|
1128
|
+
transform: translateY(-10px);
|
|
1129
|
+
}
|
|
1130
|
+
to {
|
|
1131
|
+
opacity: 1;
|
|
1132
|
+
transform: translateY(0);
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
|
|
1136
|
+
@keyframes slide-in {
|
|
1137
|
+
from {
|
|
1138
|
+
opacity: 0;
|
|
1139
|
+
transform: translateX(-10px);
|
|
1140
|
+
}
|
|
1141
|
+
to {
|
|
1142
|
+
opacity: 1;
|
|
1143
|
+
transform: translateX(0);
|
|
1144
|
+
}
|
|
1145
|
+
}
|
|
1146
|
+
|
|
1147
|
+
.animate-fade-in {
|
|
1148
|
+
animation: fade-in 0.3s ease-out;
|
|
1149
|
+
}
|
|
1150
|
+
|
|
1151
|
+
.animate-slide-in {
|
|
1152
|
+
animation: slide-in 0.2s ease-out;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
/* Dark mode support */
|
|
1156
|
+
@media (prefers-color-scheme: dark) {
|
|
1157
|
+
.dark\\:bg-gray-900 { background-color: #111827; }
|
|
1158
|
+
.dark\\:text-white { color: #fff; }
|
|
1159
|
+
}
|
|
1160
|
+
`;
|
|
1161
|
+
writeFileSync3(path7.join(previewDir, "App.tsx"), appTsx);
|
|
1162
|
+
writeFileSync3(path7.join(previewDir, "styles.css"), stylesCss);
|
|
1163
|
+
console.log(`
|
|
1164
|
+
✨ Created preview: ${name}
|
|
1165
|
+
|
|
1166
|
+
Files:
|
|
1167
|
+
previews/${name}/App.tsx React component
|
|
1168
|
+
previews/${name}/styles.css Custom styles
|
|
1169
|
+
|
|
1170
|
+
Usage in MDX:
|
|
1171
|
+
import { Preview } from '@prev/theme'
|
|
1172
|
+
<Preview src="${name}" />
|
|
1173
|
+
|
|
1174
|
+
Run 'prev' to start the dev server and see it in action.
|
|
1175
|
+
`);
|
|
1176
|
+
}
|
|
1030
1177
|
async function main() {
|
|
1031
1178
|
if (values.help) {
|
|
1032
1179
|
printHelp();
|
|
@@ -1050,6 +1197,10 @@ async function main() {
|
|
|
1050
1197
|
const removed = await cleanCache({ maxAgeDays: days });
|
|
1051
1198
|
console.log(`Removed ${removed} cache(s) older than ${days} days`);
|
|
1052
1199
|
break;
|
|
1200
|
+
case "create":
|
|
1201
|
+
const previewName = positionals[1] || "example";
|
|
1202
|
+
createPreview(rootDir, previewName);
|
|
1203
|
+
break;
|
|
1053
1204
|
default:
|
|
1054
1205
|
console.error(`Unknown command: ${command}`);
|
|
1055
1206
|
printHelp();
|