prev-cli 0.13.1 → 0.14.1

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 CHANGED
@@ -3,7 +3,8 @@
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
+ import { existsSync as existsSync5, mkdirSync as mkdirSync2, writeFileSync as writeFileSync3, rmSync as rmSync2, readFileSync as readFileSync4 } from "fs";
7
+ import { fileURLToPath as fileURLToPath3 } from "url";
7
8
 
8
9
  // src/vite/start.ts
9
10
  import { createServer as createServer2, build as build2, preview } from "vite";
@@ -960,6 +961,21 @@ async function previewSite(rootDir, options = {}) {
960
961
  }
961
962
 
962
963
  // src/cli.ts
964
+ function getVersion() {
965
+ try {
966
+ let dir = path7.dirname(fileURLToPath3(import.meta.url));
967
+ for (let i = 0;i < 5; i++) {
968
+ const pkgPath = path7.join(dir, "package.json");
969
+ if (existsSync5(pkgPath)) {
970
+ const pkg = JSON.parse(readFileSync4(pkgPath, "utf-8"));
971
+ if (pkg.name === "prev-cli")
972
+ return pkg.version;
973
+ }
974
+ dir = path7.dirname(dir);
975
+ }
976
+ } catch {}
977
+ return "unknown";
978
+ }
963
979
  var { values, positionals } = parseArgs({
964
980
  args: process.argv.slice(2),
965
981
  options: {
@@ -967,7 +983,8 @@ var { values, positionals } = parseArgs({
967
983
  days: { type: "string", short: "d" },
968
984
  cwd: { type: "string", short: "c" },
969
985
  include: { type: "string", short: "i", multiple: true },
970
- help: { type: "boolean", short: "h" }
986
+ help: { type: "boolean", short: "h" },
987
+ version: { type: "boolean", short: "v" }
971
988
  },
972
989
  allowPositionals: true
973
990
  });
@@ -982,7 +999,8 @@ Usage:
982
999
  prev build [options] Build for production
983
1000
  prev preview [options] Preview production build
984
1001
  prev create [name] Create preview in previews/<name>/ (default: "example")
985
- prev clean [options] Remove old cache directories
1002
+ prev clearcache Clear Vite cache (.vite directory)
1003
+ prev clean [options] Remove old prev-cli caches
986
1004
 
987
1005
  Options:
988
1006
  -c, --cwd <path> Set working directory
@@ -990,6 +1008,7 @@ Options:
990
1008
  -i, --include <dir> Include dot-prefixed directory (can use multiple times)
991
1009
  -d, --days <days> Cache age threshold for clean (default: 30)
992
1010
  -h, --help Show this help message
1011
+ -v, --version Show version number
993
1012
 
994
1013
  Previews:
995
1014
  Previews must be in the previews/ directory at your project root.
@@ -1021,6 +1040,8 @@ Previews:
1021
1040
  Previews are bundled via esbuild-wasm in dev, and pre-compiled
1022
1041
  to standalone HTML files in production builds.
1023
1042
 
1043
+ Browse all previews at /previews (Storybook-like catalog).
1044
+
1024
1045
  Examples:
1025
1046
  prev Start dev server on random port
1026
1047
  prev -p 3000 Start dev server on port 3000
@@ -1031,6 +1052,27 @@ Examples:
1031
1052
  prev clean -d 7 Remove caches older than 7 days
1032
1053
  `);
1033
1054
  }
1055
+ function clearViteCache(rootDir2) {
1056
+ const viteCacheDir = path7.join(rootDir2, ".vite");
1057
+ const nodeModulesVite = path7.join(rootDir2, "node_modules", ".vite");
1058
+ let cleared = 0;
1059
+ if (existsSync5(viteCacheDir)) {
1060
+ rmSync2(viteCacheDir, { recursive: true });
1061
+ cleared++;
1062
+ console.log(` ✓ Removed .vite/`);
1063
+ }
1064
+ if (existsSync5(nodeModulesVite)) {
1065
+ rmSync2(nodeModulesVite, { recursive: true });
1066
+ cleared++;
1067
+ console.log(` ✓ Removed node_modules/.vite/`);
1068
+ }
1069
+ if (cleared === 0) {
1070
+ console.log(" No Vite cache found");
1071
+ } else {
1072
+ console.log(`
1073
+ Cleared ${cleared} cache director${cleared === 1 ? "y" : "ies"}`);
1074
+ }
1075
+ }
1034
1076
  function createPreview(rootDir2, name) {
1035
1077
  const previewDir = path7.join(rootDir2, "previews", name);
1036
1078
  if (existsSync5(previewDir)) {
@@ -1176,6 +1218,10 @@ export default function App() {
1176
1218
  `);
1177
1219
  }
1178
1220
  async function main() {
1221
+ if (values.version) {
1222
+ console.log(`prev-cli v${getVersion()}`);
1223
+ process.exit(0);
1224
+ }
1179
1225
  if (values.help) {
1180
1226
  printHelp();
1181
1227
  process.exit(0);
@@ -1202,6 +1248,9 @@ async function main() {
1202
1248
  const previewName = positionals[1] || "example";
1203
1249
  createPreview(rootDir, previewName);
1204
1250
  break;
1251
+ case "clearcache":
1252
+ clearViteCache(rootDir);
1253
+ break;
1205
1254
  default:
1206
1255
  console.error(`Unknown command: ${command}`);
1207
1256
  printHelp();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "prev-cli",
3
- "version": "0.13.1",
3
+ "version": "0.14.1",
4
4
  "description": "Transform MDX directories into beautiful documentation websites",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -9,6 +9,8 @@ import {
9
9
  } from '@tanstack/react-router'
10
10
  import { MDXProvider } from '@mdx-js/react'
11
11
  import { pages, sidebar } from 'virtual:prev-pages'
12
+ import { previews } from 'virtual:prev-previews'
13
+ import { Preview } from './Preview'
12
14
  import { useDiagrams } from './diagrams'
13
15
  import { Layout } from './Layout'
14
16
  import { MetadataBlock } from './MetadataBlock'
@@ -83,6 +85,92 @@ function PageWrapper({ Component, meta }: { Component: React.ComponentType; meta
83
85
  )
84
86
  }
85
87
 
88
+ // Previews catalog - Storybook-like gallery
89
+ function PreviewsCatalog() {
90
+ if (!previews || previews.length === 0) {
91
+ return (
92
+ <div style={{ padding: '40px 20px', textAlign: 'center' }}>
93
+ <h1 style={{ fontSize: '24px', fontWeight: 'bold', marginBottom: '16px' }}>
94
+ No Previews Found
95
+ </h1>
96
+ <p style={{ color: '#666', marginBottom: '24px' }}>
97
+ Create your first preview with:
98
+ </p>
99
+ <code style={{
100
+ display: 'inline-block',
101
+ padding: '12px 20px',
102
+ backgroundColor: '#f4f4f5',
103
+ borderRadius: '8px',
104
+ fontFamily: 'monospace',
105
+ }}>
106
+ prev create my-demo
107
+ </code>
108
+ </div>
109
+ )
110
+ }
111
+
112
+ return (
113
+ <div style={{ padding: '20px' }}>
114
+ <div style={{ marginBottom: '32px' }}>
115
+ <h1 style={{ fontSize: '28px', fontWeight: 'bold', marginBottom: '8px' }}>
116
+ Previews
117
+ </h1>
118
+ <p style={{ color: '#666' }}>
119
+ {previews.length} component preview{previews.length !== 1 ? 's' : ''} available
120
+ </p>
121
+ </div>
122
+
123
+ <div style={{
124
+ display: 'grid',
125
+ gridTemplateColumns: 'repeat(auto-fill, minmax(400px, 1fr))',
126
+ gap: '24px',
127
+ }}>
128
+ {previews.map((preview: { name: string; route: string }) => (
129
+ <div key={preview.name} style={{
130
+ border: '1px solid #e4e4e7',
131
+ borderRadius: '12px',
132
+ overflow: 'hidden',
133
+ backgroundColor: '#fff',
134
+ }}>
135
+ <div style={{
136
+ padding: '12px 16px',
137
+ borderBottom: '1px solid #e4e4e7',
138
+ backgroundColor: '#fafafa',
139
+ }}>
140
+ <h2 style={{ fontSize: '16px', fontWeight: 600, margin: 0 }}>
141
+ {preview.name}
142
+ </h2>
143
+ <code style={{
144
+ fontSize: '12px',
145
+ color: '#666',
146
+ fontFamily: 'monospace',
147
+ }}>
148
+ previews/{preview.name}/
149
+ </code>
150
+ </div>
151
+ <Preview src={preview.name} height={300} />
152
+ </div>
153
+ ))}
154
+ </div>
155
+
156
+ <div style={{
157
+ marginTop: '40px',
158
+ padding: '16px',
159
+ backgroundColor: '#f0f9ff',
160
+ border: '1px solid #bae6fd',
161
+ borderRadius: '8px',
162
+ }}>
163
+ <p style={{ margin: 0, fontSize: '14px', color: '#0369a1' }}>
164
+ <strong>Tip:</strong> Embed any preview in your MDX docs with{' '}
165
+ <code style={{ backgroundColor: '#e0f2fe', padding: '2px 6px', borderRadius: '4px' }}>
166
+ {'<Preview src="name" />'}
167
+ </code>
168
+ </p>
169
+ </div>
170
+ </div>
171
+ )
172
+ }
173
+
86
174
  // Root layout with custom lightweight Layout
87
175
  function RootLayout() {
88
176
  const pageTree = convertToPageTree(sidebar)
@@ -101,6 +189,13 @@ const rootRoute = createRootRoute({
101
189
  component: RootLayout,
102
190
  })
103
191
 
192
+ // Previews catalog route
193
+ const previewsRoute = createRoute({
194
+ getParentRoute: () => rootRoute,
195
+ path: '/previews',
196
+ component: PreviewsCatalog,
197
+ })
198
+
104
199
  // Create routes from pages
105
200
  const pageRoutes = pages.map((page: { route: string; file: string; title?: string; description?: string; frontmatter?: Record<string, unknown> }) => {
106
201
  const Component = getPageComponent(page.file)
@@ -117,7 +212,7 @@ const pageRoutes = pages.map((page: { route: string; file: string; title?: strin
117
212
  })
118
213
 
119
214
  // Create router
120
- const routeTree = rootRoute.addChildren(pageRoutes)
215
+ const routeTree = rootRoute.addChildren([previewsRoute, ...pageRoutes])
121
216
  const router = createRouter({ routeTree })
122
217
 
123
218
  // Mount app - RouterProvider must be outermost so TanStack Router context is available