@codebakers/mcp 5.4.1 → 5.4.3
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/INSTALL.md +221 -221
- package/LICENSE +21 -21
- package/README.md +412 -412
- package/dist/cli.js +27 -27
- package/dist/tools/analyze-mockups.js +37 -37
- package/dist/tools/autonomous-build.d.ts +18 -18
- package/dist/tools/autonomous-build.js +286 -286
- package/dist/tools/check-gate.js +6 -6
- package/dist/tools/check-scope.js +10 -10
- package/dist/tools/enforce-feature.js +15 -15
- package/dist/tools/fix-commit.js +18 -18
- package/dist/tools/fix-mockups.js +191 -191
- package/dist/tools/generate-api-route.js +155 -155
- package/dist/tools/generate-chatbot.js +306 -306
- package/dist/tools/generate-component.js +117 -117
- package/dist/tools/generate-docs.js +525 -525
- package/dist/tools/generate-e2e-tests.js +19 -19
- package/dist/tools/generate-migration.js +22 -22
- package/dist/tools/generate-schema.js +37 -37
- package/dist/tools/generate-spec.js +38 -38
- package/dist/tools/generate-store-contracts.js +42 -42
- package/dist/tools/generate-store.js +109 -109
- package/dist/tools/generate-unit-tests.js +57 -57
- package/dist/tools/map-dependencies.js +45 -45
- package/dist/tools/run-interview.js +142 -142
- package/dist/tools/setup-github.js +8 -8
- package/dist/tools/setup-supabase.js +8 -8
- package/dist/tools/setup-vercel.js +8 -8
- package/dist/tools/validate-mockups.js +19 -19
- package/package.json +50 -50
|
@@ -78,53 +78,53 @@ async function generateQuickStart(cwd) {
|
|
|
78
78
|
catch {
|
|
79
79
|
// project-profile.md doesn't exist
|
|
80
80
|
}
|
|
81
|
-
const content = `
|
|
82
|
-
<h1>Quick Start Guide</h1>
|
|
83
|
-
|
|
84
|
-
<h2>Get Started in 5 Minutes</h2>
|
|
85
|
-
|
|
86
|
-
<h3>1. Clone and Install</h3>
|
|
87
|
-
<pre><code class="language-bash">git clone [repository-url]
|
|
88
|
-
cd ${projectName.toLowerCase().replace(/\s+/g, '-')}
|
|
89
|
-
pnpm install</code></pre>
|
|
90
|
-
|
|
91
|
-
<h3>2. Setup Environment</h3>
|
|
92
|
-
<pre><code class="language-bash"># Copy environment template
|
|
93
|
-
cp .env.example .env
|
|
94
|
-
|
|
95
|
-
# Add your credentials (see Setup guide for details)
|
|
96
|
-
# Required: SUPABASE_URL, SUPABASE_ANON_KEY
|
|
97
|
-
</code></pre>
|
|
98
|
-
|
|
99
|
-
<h3>3. Run Development Server</h3>
|
|
100
|
-
<pre><code class="language-bash">pnpm dev</code></pre>
|
|
101
|
-
|
|
102
|
-
<p>Open <a href="http://localhost:3000">http://localhost:3000</a> in your browser.</p>
|
|
103
|
-
|
|
104
|
-
<h3>4. Run Tests</h3>
|
|
105
|
-
<pre><code class="language-bash"># Unit tests
|
|
106
|
-
pnpm test
|
|
107
|
-
|
|
108
|
-
# E2E tests
|
|
109
|
-
pnpm test:e2e</code></pre>
|
|
110
|
-
|
|
111
|
-
<h3>5. Build for Production</h3>
|
|
112
|
-
<pre><code class="language-bash">pnpm build
|
|
113
|
-
pnpm start</code></pre>
|
|
114
|
-
|
|
115
|
-
<h2>What's Next?</h2>
|
|
116
|
-
|
|
117
|
-
<ul>
|
|
118
|
-
<li><a href="setup.html">Complete Setup Guide</a> - Environment variables and credentials</li>
|
|
119
|
-
<li><a href="architecture.html">Architecture Overview</a> - How the app works</li>
|
|
120
|
-
<li><a href="api-reference.html">API Reference</a> - Backend endpoints</li>
|
|
121
|
-
<li><a href="components.html">Components</a> - UI component library</li>
|
|
122
|
-
</ul>
|
|
123
|
-
|
|
124
|
-
<div class="callout callout-success">
|
|
125
|
-
<h4>🎉 You're Ready!</h4>
|
|
126
|
-
<p>Your app is now running. Start exploring the codebase or jump into development.</p>
|
|
127
|
-
</div>
|
|
81
|
+
const content = `
|
|
82
|
+
<h1>Quick Start Guide</h1>
|
|
83
|
+
|
|
84
|
+
<h2>Get Started in 5 Minutes</h2>
|
|
85
|
+
|
|
86
|
+
<h3>1. Clone and Install</h3>
|
|
87
|
+
<pre><code class="language-bash">git clone [repository-url]
|
|
88
|
+
cd ${projectName.toLowerCase().replace(/\s+/g, '-')}
|
|
89
|
+
pnpm install</code></pre>
|
|
90
|
+
|
|
91
|
+
<h3>2. Setup Environment</h3>
|
|
92
|
+
<pre><code class="language-bash"># Copy environment template
|
|
93
|
+
cp .env.example .env
|
|
94
|
+
|
|
95
|
+
# Add your credentials (see Setup guide for details)
|
|
96
|
+
# Required: SUPABASE_URL, SUPABASE_ANON_KEY
|
|
97
|
+
</code></pre>
|
|
98
|
+
|
|
99
|
+
<h3>3. Run Development Server</h3>
|
|
100
|
+
<pre><code class="language-bash">pnpm dev</code></pre>
|
|
101
|
+
|
|
102
|
+
<p>Open <a href="http://localhost:3000">http://localhost:3000</a> in your browser.</p>
|
|
103
|
+
|
|
104
|
+
<h3>4. Run Tests</h3>
|
|
105
|
+
<pre><code class="language-bash"># Unit tests
|
|
106
|
+
pnpm test
|
|
107
|
+
|
|
108
|
+
# E2E tests
|
|
109
|
+
pnpm test:e2e</code></pre>
|
|
110
|
+
|
|
111
|
+
<h3>5. Build for Production</h3>
|
|
112
|
+
<pre><code class="language-bash">pnpm build
|
|
113
|
+
pnpm start</code></pre>
|
|
114
|
+
|
|
115
|
+
<h2>What's Next?</h2>
|
|
116
|
+
|
|
117
|
+
<ul>
|
|
118
|
+
<li><a href="setup.html">Complete Setup Guide</a> - Environment variables and credentials</li>
|
|
119
|
+
<li><a href="architecture.html">Architecture Overview</a> - How the app works</li>
|
|
120
|
+
<li><a href="api-reference.html">API Reference</a> - Backend endpoints</li>
|
|
121
|
+
<li><a href="components.html">Components</a> - UI component library</li>
|
|
122
|
+
</ul>
|
|
123
|
+
|
|
124
|
+
<div class="callout callout-success">
|
|
125
|
+
<h4>🎉 You're Ready!</h4>
|
|
126
|
+
<p>Your app is now running. Start exploring the codebase or jump into development.</p>
|
|
127
|
+
</div>
|
|
128
128
|
`;
|
|
129
129
|
return wrapInTemplate('Quick Start', content);
|
|
130
130
|
}
|
|
@@ -138,61 +138,61 @@ async function generateSetupGuide(cwd) {
|
|
|
138
138
|
catch {
|
|
139
139
|
// CREDENTIALS-NEEDED.md doesn't exist
|
|
140
140
|
}
|
|
141
|
-
const content = `
|
|
142
|
-
<h1>Setup Guide</h1>
|
|
143
|
-
|
|
144
|
-
<h2>Prerequisites</h2>
|
|
145
|
-
|
|
146
|
-
<ul>
|
|
147
|
-
<li>Node.js 18+ (<code>node --version</code>)</li>
|
|
148
|
-
<li>pnpm (<code>npm install -g pnpm</code>)</li>
|
|
149
|
-
<li>Git</li>
|
|
150
|
-
<li>Supabase account (free tier works)</li>
|
|
151
|
-
</ul>
|
|
152
|
-
|
|
153
|
-
<h2>Installation Steps</h2>
|
|
154
|
-
|
|
155
|
-
<h3>Step 1: Install Dependencies</h3>
|
|
156
|
-
<pre><code class="language-bash">pnpm install</code></pre>
|
|
157
|
-
|
|
158
|
-
<h3>Step 2: Setup Supabase</h3>
|
|
159
|
-
|
|
160
|
-
<ol>
|
|
161
|
-
<li>Create project at <a href="https://supabase.com/dashboard">supabase.com/dashboard</a></li>
|
|
162
|
-
<li>Copy <strong>Project URL</strong> and <strong>anon key</strong> from Settings → API</li>
|
|
163
|
-
<li>Run migrations: <code>pnpm supabase:migrate</code></li>
|
|
164
|
-
</ol>
|
|
165
|
-
|
|
166
|
-
<h3>Step 3: Environment Variables</h3>
|
|
167
|
-
|
|
168
|
-
<pre><code class="language-bash"># .env
|
|
169
|
-
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
170
|
-
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
171
|
-
</code></pre>
|
|
172
|
-
|
|
173
|
-
<h2>External Services</h2>
|
|
174
|
-
|
|
175
|
-
<div class="credentials-section">
|
|
176
|
-
${credentials.includes('No external') ? '<p>No external credentials required.</p>' : `<pre>${credentials}</pre>`}
|
|
177
|
-
</div>
|
|
178
|
-
|
|
179
|
-
<h2>Verification</h2>
|
|
180
|
-
|
|
181
|
-
<p>Verify everything works:</p>
|
|
182
|
-
|
|
183
|
-
<pre><code class="language-bash"># Type check
|
|
184
|
-
pnpm type-check
|
|
185
|
-
|
|
186
|
-
# Run tests
|
|
187
|
-
pnpm test
|
|
188
|
-
|
|
189
|
-
# Start dev server
|
|
190
|
-
pnpm dev</code></pre>
|
|
191
|
-
|
|
192
|
-
<div class="callout callout-info">
|
|
193
|
-
<h4>Need Help?</h4>
|
|
194
|
-
<p>Check <a href="https://github.com/your-repo/issues">GitHub Issues</a> or the main documentation.</p>
|
|
195
|
-
</div>
|
|
141
|
+
const content = `
|
|
142
|
+
<h1>Setup Guide</h1>
|
|
143
|
+
|
|
144
|
+
<h2>Prerequisites</h2>
|
|
145
|
+
|
|
146
|
+
<ul>
|
|
147
|
+
<li>Node.js 18+ (<code>node --version</code>)</li>
|
|
148
|
+
<li>pnpm (<code>npm install -g pnpm</code>)</li>
|
|
149
|
+
<li>Git</li>
|
|
150
|
+
<li>Supabase account (free tier works)</li>
|
|
151
|
+
</ul>
|
|
152
|
+
|
|
153
|
+
<h2>Installation Steps</h2>
|
|
154
|
+
|
|
155
|
+
<h3>Step 1: Install Dependencies</h3>
|
|
156
|
+
<pre><code class="language-bash">pnpm install</code></pre>
|
|
157
|
+
|
|
158
|
+
<h3>Step 2: Setup Supabase</h3>
|
|
159
|
+
|
|
160
|
+
<ol>
|
|
161
|
+
<li>Create project at <a href="https://supabase.com/dashboard">supabase.com/dashboard</a></li>
|
|
162
|
+
<li>Copy <strong>Project URL</strong> and <strong>anon key</strong> from Settings → API</li>
|
|
163
|
+
<li>Run migrations: <code>pnpm supabase:migrate</code></li>
|
|
164
|
+
</ol>
|
|
165
|
+
|
|
166
|
+
<h3>Step 3: Environment Variables</h3>
|
|
167
|
+
|
|
168
|
+
<pre><code class="language-bash"># .env
|
|
169
|
+
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
|
|
170
|
+
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
|
|
171
|
+
</code></pre>
|
|
172
|
+
|
|
173
|
+
<h2>External Services</h2>
|
|
174
|
+
|
|
175
|
+
<div class="credentials-section">
|
|
176
|
+
${credentials.includes('No external') ? '<p>No external credentials required.</p>' : `<pre>${credentials}</pre>`}
|
|
177
|
+
</div>
|
|
178
|
+
|
|
179
|
+
<h2>Verification</h2>
|
|
180
|
+
|
|
181
|
+
<p>Verify everything works:</p>
|
|
182
|
+
|
|
183
|
+
<pre><code class="language-bash"># Type check
|
|
184
|
+
pnpm type-check
|
|
185
|
+
|
|
186
|
+
# Run tests
|
|
187
|
+
pnpm test
|
|
188
|
+
|
|
189
|
+
# Start dev server
|
|
190
|
+
pnpm dev</code></pre>
|
|
191
|
+
|
|
192
|
+
<div class="callout callout-info">
|
|
193
|
+
<h4>Need Help?</h4>
|
|
194
|
+
<p>Check <a href="https://github.com/your-repo/issues">GitHub Issues</a> or the main documentation.</p>
|
|
195
|
+
</div>
|
|
196
196
|
`;
|
|
197
197
|
return wrapInTemplate('Setup Guide', content);
|
|
198
198
|
}
|
|
@@ -206,93 +206,93 @@ async function generateArchitecture(cwd) {
|
|
|
206
206
|
catch {
|
|
207
207
|
// BRAIN.md doesn't exist
|
|
208
208
|
}
|
|
209
|
-
const content = `
|
|
210
|
-
<h1>Architecture Overview</h1>
|
|
211
|
-
|
|
212
|
-
<h2>Tech Stack</h2>
|
|
213
|
-
|
|
214
|
-
<table>
|
|
215
|
-
<tr>
|
|
216
|
-
<th>Layer</th>
|
|
217
|
-
<th>Technology</th>
|
|
218
|
-
<th>Purpose</th>
|
|
219
|
-
</tr>
|
|
220
|
-
<tr>
|
|
221
|
-
<td>Frontend</td>
|
|
222
|
-
<td>Next.js 14 (App Router)</td>
|
|
223
|
-
<td>React framework with SSR/SSG</td>
|
|
224
|
-
</tr>
|
|
225
|
-
<tr>
|
|
226
|
-
<td>Backend</td>
|
|
227
|
-
<td>Next.js API Routes</td>
|
|
228
|
-
<td>Server-side endpoints</td>
|
|
229
|
-
</tr>
|
|
230
|
-
<tr>
|
|
231
|
-
<td>Database</td>
|
|
232
|
-
<td>Supabase (PostgreSQL)</td>
|
|
233
|
-
<td>Data persistence + Auth</td>
|
|
234
|
-
</tr>
|
|
235
|
-
<tr>
|
|
236
|
-
<td>State</td>
|
|
237
|
-
<td>Zustand</td>
|
|
238
|
-
<td>Client-side state management</td>
|
|
239
|
-
</tr>
|
|
240
|
-
<tr>
|
|
241
|
-
<td>Styling</td>
|
|
242
|
-
<td>Tailwind CSS</td>
|
|
243
|
-
<td>Utility-first CSS</td>
|
|
244
|
-
</tr>
|
|
245
|
-
<tr>
|
|
246
|
-
<td>Testing</td>
|
|
247
|
-
<td>Vitest + Playwright</td>
|
|
248
|
-
<td>Unit + E2E tests</td>
|
|
249
|
-
</tr>
|
|
250
|
-
</table>
|
|
251
|
-
|
|
252
|
-
<h2>Folder Structure</h2>
|
|
253
|
-
|
|
254
|
-
<pre><code>src/
|
|
255
|
-
├── app/ # Next.js App Router
|
|
256
|
-
│ ├── (routes)/ # Page routes
|
|
257
|
-
│ ├── api/ # API endpoints
|
|
258
|
-
│ └── layout.tsx # Root layout
|
|
259
|
-
├── components/ # React components
|
|
260
|
-
│ ├── ui/ # UI primitives
|
|
261
|
-
│ └── features/ # Feature components
|
|
262
|
-
├── stores/ # Zustand stores
|
|
263
|
-
├── lib/ # Utilities and helpers
|
|
264
|
-
└── types/ # TypeScript types
|
|
265
|
-
|
|
266
|
-
supabase/
|
|
267
|
-
└── migrations/ # Database migrations
|
|
268
|
-
|
|
269
|
-
tests/
|
|
270
|
-
├── unit/ # Vitest unit tests
|
|
271
|
-
└── e2e/ # Playwright E2E tests
|
|
272
|
-
</code></pre>
|
|
273
|
-
|
|
274
|
-
<h2>Data Flow</h2>
|
|
275
|
-
|
|
276
|
-
<ol>
|
|
277
|
-
<li><strong>User Action</strong> → Component event handler</li>
|
|
278
|
-
<li><strong>Store Method</strong> → Calls API route</li>
|
|
279
|
-
<li><strong>API Route</strong> → Validates auth, queries Supabase</li>
|
|
280
|
-
<li><strong>Database</strong> → Returns data</li>
|
|
281
|
-
<li><strong>Store Update</strong> → Updates state + dependent stores</li>
|
|
282
|
-
<li><strong>React Re-render</strong> → UI reflects new state</li>
|
|
283
|
-
</ol>
|
|
284
|
-
|
|
285
|
-
<h2>Key Principles</h2>
|
|
286
|
-
|
|
287
|
-
<ul>
|
|
288
|
-
<li><strong>Security First:</strong> All queries filter by <code>user_id</code></li>
|
|
289
|
-
<li><strong>Type Safety:</strong> TypeScript strict mode everywhere</li>
|
|
290
|
-
<li><strong>Dependency Awareness:</strong> Mutations update all affected stores</li>
|
|
291
|
-
<li><strong>Error Handling:</strong> All components have loading/error/empty/success states</li>
|
|
292
|
-
<li><strong>Testing:</strong> Every feature has unit + E2E tests</li>
|
|
293
|
-
</ul>
|
|
294
|
-
|
|
295
|
-
${brainContent ? `<h2>Project Context</h2><pre>${brainContent.slice(0, 1000)}</pre>` : ''}
|
|
209
|
+
const content = `
|
|
210
|
+
<h1>Architecture Overview</h1>
|
|
211
|
+
|
|
212
|
+
<h2>Tech Stack</h2>
|
|
213
|
+
|
|
214
|
+
<table>
|
|
215
|
+
<tr>
|
|
216
|
+
<th>Layer</th>
|
|
217
|
+
<th>Technology</th>
|
|
218
|
+
<th>Purpose</th>
|
|
219
|
+
</tr>
|
|
220
|
+
<tr>
|
|
221
|
+
<td>Frontend</td>
|
|
222
|
+
<td>Next.js 14 (App Router)</td>
|
|
223
|
+
<td>React framework with SSR/SSG</td>
|
|
224
|
+
</tr>
|
|
225
|
+
<tr>
|
|
226
|
+
<td>Backend</td>
|
|
227
|
+
<td>Next.js API Routes</td>
|
|
228
|
+
<td>Server-side endpoints</td>
|
|
229
|
+
</tr>
|
|
230
|
+
<tr>
|
|
231
|
+
<td>Database</td>
|
|
232
|
+
<td>Supabase (PostgreSQL)</td>
|
|
233
|
+
<td>Data persistence + Auth</td>
|
|
234
|
+
</tr>
|
|
235
|
+
<tr>
|
|
236
|
+
<td>State</td>
|
|
237
|
+
<td>Zustand</td>
|
|
238
|
+
<td>Client-side state management</td>
|
|
239
|
+
</tr>
|
|
240
|
+
<tr>
|
|
241
|
+
<td>Styling</td>
|
|
242
|
+
<td>Tailwind CSS</td>
|
|
243
|
+
<td>Utility-first CSS</td>
|
|
244
|
+
</tr>
|
|
245
|
+
<tr>
|
|
246
|
+
<td>Testing</td>
|
|
247
|
+
<td>Vitest + Playwright</td>
|
|
248
|
+
<td>Unit + E2E tests</td>
|
|
249
|
+
</tr>
|
|
250
|
+
</table>
|
|
251
|
+
|
|
252
|
+
<h2>Folder Structure</h2>
|
|
253
|
+
|
|
254
|
+
<pre><code>src/
|
|
255
|
+
├── app/ # Next.js App Router
|
|
256
|
+
│ ├── (routes)/ # Page routes
|
|
257
|
+
│ ├── api/ # API endpoints
|
|
258
|
+
│ └── layout.tsx # Root layout
|
|
259
|
+
├── components/ # React components
|
|
260
|
+
│ ├── ui/ # UI primitives
|
|
261
|
+
│ └── features/ # Feature components
|
|
262
|
+
├── stores/ # Zustand stores
|
|
263
|
+
├── lib/ # Utilities and helpers
|
|
264
|
+
└── types/ # TypeScript types
|
|
265
|
+
|
|
266
|
+
supabase/
|
|
267
|
+
└── migrations/ # Database migrations
|
|
268
|
+
|
|
269
|
+
tests/
|
|
270
|
+
├── unit/ # Vitest unit tests
|
|
271
|
+
└── e2e/ # Playwright E2E tests
|
|
272
|
+
</code></pre>
|
|
273
|
+
|
|
274
|
+
<h2>Data Flow</h2>
|
|
275
|
+
|
|
276
|
+
<ol>
|
|
277
|
+
<li><strong>User Action</strong> → Component event handler</li>
|
|
278
|
+
<li><strong>Store Method</strong> → Calls API route</li>
|
|
279
|
+
<li><strong>API Route</strong> → Validates auth, queries Supabase</li>
|
|
280
|
+
<li><strong>Database</strong> → Returns data</li>
|
|
281
|
+
<li><strong>Store Update</strong> → Updates state + dependent stores</li>
|
|
282
|
+
<li><strong>React Re-render</strong> → UI reflects new state</li>
|
|
283
|
+
</ol>
|
|
284
|
+
|
|
285
|
+
<h2>Key Principles</h2>
|
|
286
|
+
|
|
287
|
+
<ul>
|
|
288
|
+
<li><strong>Security First:</strong> All queries filter by <code>user_id</code></li>
|
|
289
|
+
<li><strong>Type Safety:</strong> TypeScript strict mode everywhere</li>
|
|
290
|
+
<li><strong>Dependency Awareness:</strong> Mutations update all affected stores</li>
|
|
291
|
+
<li><strong>Error Handling:</strong> All components have loading/error/empty/success states</li>
|
|
292
|
+
<li><strong>Testing:</strong> Every feature has unit + E2E tests</li>
|
|
293
|
+
</ul>
|
|
294
|
+
|
|
295
|
+
${brainContent ? `<h2>Project Context</h2><pre>${brainContent.slice(0, 1000)}</pre>` : ''}
|
|
296
296
|
`;
|
|
297
297
|
return wrapInTemplate('Architecture', content);
|
|
298
298
|
}
|
|
@@ -304,65 +304,65 @@ async function generateAPIReference(cwd) {
|
|
|
304
304
|
}
|
|
305
305
|
else {
|
|
306
306
|
for (const route of apiRoutes) {
|
|
307
|
-
routesList += `
|
|
308
|
-
<div class="api-route">
|
|
309
|
-
<h3>${route.method} ${route.path}</h3>
|
|
310
|
-
<p><strong>File:</strong> <code>${route.file}</code></p>
|
|
311
|
-
<p><strong>Description:</strong> ${route.description}</p>
|
|
312
|
-
</div>
|
|
307
|
+
routesList += `
|
|
308
|
+
<div class="api-route">
|
|
309
|
+
<h3>${route.method} ${route.path}</h3>
|
|
310
|
+
<p><strong>File:</strong> <code>${route.file}</code></p>
|
|
311
|
+
<p><strong>Description:</strong> ${route.description}</p>
|
|
312
|
+
</div>
|
|
313
313
|
`;
|
|
314
314
|
}
|
|
315
315
|
}
|
|
316
|
-
const content = `
|
|
317
|
-
<h1>API Reference</h1>
|
|
318
|
-
|
|
319
|
-
<h2>API Endpoints</h2>
|
|
320
|
-
|
|
321
|
-
${routesList}
|
|
322
|
-
|
|
323
|
-
<h2>Authentication</h2>
|
|
324
|
-
|
|
325
|
-
<p>All API routes require authentication via Supabase session:</p>
|
|
326
|
-
|
|
327
|
-
<pre><code class="language-typescript">const supabase = createServerClient();
|
|
328
|
-
const { data: { user }, error } = await supabase.auth.getUser();
|
|
329
|
-
|
|
330
|
-
if (!user) {
|
|
331
|
-
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
332
|
-
}</code></pre>
|
|
333
|
-
|
|
334
|
-
<h2>Error Responses</h2>
|
|
335
|
-
|
|
336
|
-
<table>
|
|
337
|
-
<tr>
|
|
338
|
-
<th>Status</th>
|
|
339
|
-
<th>Meaning</th>
|
|
340
|
-
</tr>
|
|
341
|
-
<tr>
|
|
342
|
-
<td>200</td>
|
|
343
|
-
<td>Success</td>
|
|
344
|
-
</tr>
|
|
345
|
-
<tr>
|
|
346
|
-
<td>400</td>
|
|
347
|
-
<td>Bad Request (validation error)</td>
|
|
348
|
-
</tr>
|
|
349
|
-
<tr>
|
|
350
|
-
<td>401</td>
|
|
351
|
-
<td>Unauthorized (not logged in)</td>
|
|
352
|
-
</tr>
|
|
353
|
-
<tr>
|
|
354
|
-
<td>403</td>
|
|
355
|
-
<td>Forbidden (no permission)</td>
|
|
356
|
-
</tr>
|
|
357
|
-
<tr>
|
|
358
|
-
<td>404</td>
|
|
359
|
-
<td>Not Found</td>
|
|
360
|
-
</tr>
|
|
361
|
-
<tr>
|
|
362
|
-
<td>500</td>
|
|
363
|
-
<td>Internal Server Error</td>
|
|
364
|
-
</tr>
|
|
365
|
-
</table>
|
|
316
|
+
const content = `
|
|
317
|
+
<h1>API Reference</h1>
|
|
318
|
+
|
|
319
|
+
<h2>API Endpoints</h2>
|
|
320
|
+
|
|
321
|
+
${routesList}
|
|
322
|
+
|
|
323
|
+
<h2>Authentication</h2>
|
|
324
|
+
|
|
325
|
+
<p>All API routes require authentication via Supabase session:</p>
|
|
326
|
+
|
|
327
|
+
<pre><code class="language-typescript">const supabase = createServerClient();
|
|
328
|
+
const { data: { user }, error } = await supabase.auth.getUser();
|
|
329
|
+
|
|
330
|
+
if (!user) {
|
|
331
|
+
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
|
|
332
|
+
}</code></pre>
|
|
333
|
+
|
|
334
|
+
<h2>Error Responses</h2>
|
|
335
|
+
|
|
336
|
+
<table>
|
|
337
|
+
<tr>
|
|
338
|
+
<th>Status</th>
|
|
339
|
+
<th>Meaning</th>
|
|
340
|
+
</tr>
|
|
341
|
+
<tr>
|
|
342
|
+
<td>200</td>
|
|
343
|
+
<td>Success</td>
|
|
344
|
+
</tr>
|
|
345
|
+
<tr>
|
|
346
|
+
<td>400</td>
|
|
347
|
+
<td>Bad Request (validation error)</td>
|
|
348
|
+
</tr>
|
|
349
|
+
<tr>
|
|
350
|
+
<td>401</td>
|
|
351
|
+
<td>Unauthorized (not logged in)</td>
|
|
352
|
+
</tr>
|
|
353
|
+
<tr>
|
|
354
|
+
<td>403</td>
|
|
355
|
+
<td>Forbidden (no permission)</td>
|
|
356
|
+
</tr>
|
|
357
|
+
<tr>
|
|
358
|
+
<td>404</td>
|
|
359
|
+
<td>Not Found</td>
|
|
360
|
+
</tr>
|
|
361
|
+
<tr>
|
|
362
|
+
<td>500</td>
|
|
363
|
+
<td>Internal Server Error</td>
|
|
364
|
+
</tr>
|
|
365
|
+
</table>
|
|
366
366
|
`;
|
|
367
367
|
return wrapInTemplate('API Reference', content);
|
|
368
368
|
}
|
|
@@ -425,32 +425,32 @@ async function generateComponentDocs(cwd) {
|
|
|
425
425
|
}
|
|
426
426
|
else {
|
|
427
427
|
for (const component of components) {
|
|
428
|
-
componentsList += `
|
|
429
|
-
<div class="component-doc">
|
|
430
|
-
<h3>${component.name}</h3>
|
|
431
|
-
<p><strong>File:</strong> <code>${component.file}</code></p>
|
|
432
|
-
<p><strong>Props:</strong> ${component.props.join(', ') || 'None'}</p>
|
|
433
|
-
</div>
|
|
428
|
+
componentsList += `
|
|
429
|
+
<div class="component-doc">
|
|
430
|
+
<h3>${component.name}</h3>
|
|
431
|
+
<p><strong>File:</strong> <code>${component.file}</code></p>
|
|
432
|
+
<p><strong>Props:</strong> ${component.props.join(', ') || 'None'}</p>
|
|
433
|
+
</div>
|
|
434
434
|
`;
|
|
435
435
|
}
|
|
436
436
|
}
|
|
437
|
-
const content = `
|
|
438
|
-
<h1>Component Documentation</h1>
|
|
439
|
-
|
|
440
|
-
<h2>UI Components</h2>
|
|
441
|
-
|
|
442
|
-
${componentsList}
|
|
443
|
-
|
|
444
|
-
<h2>Component Structure</h2>
|
|
445
|
-
|
|
446
|
-
<p>All components follow the same pattern:</p>
|
|
447
|
-
|
|
448
|
-
<pre><code class="language-typescript">// States
|
|
449
|
-
if (loading) return <SkeletonLoader />;
|
|
450
|
-
if (error) return <ErrorMessage error={error} />;
|
|
451
|
-
if (data.length === 0) return <EmptyState />;
|
|
452
|
-
return <SuccessView data={data} />;
|
|
453
|
-
</code></pre>
|
|
437
|
+
const content = `
|
|
438
|
+
<h1>Component Documentation</h1>
|
|
439
|
+
|
|
440
|
+
<h2>UI Components</h2>
|
|
441
|
+
|
|
442
|
+
${componentsList}
|
|
443
|
+
|
|
444
|
+
<h2>Component Structure</h2>
|
|
445
|
+
|
|
446
|
+
<p>All components follow the same pattern:</p>
|
|
447
|
+
|
|
448
|
+
<pre><code class="language-typescript">// States
|
|
449
|
+
if (loading) return <SkeletonLoader />;
|
|
450
|
+
if (error) return <ErrorMessage error={error} />;
|
|
451
|
+
if (data.length === 0) return <EmptyState />;
|
|
452
|
+
return <SuccessView data={data} />;
|
|
453
|
+
</code></pre>
|
|
454
454
|
`;
|
|
455
455
|
return wrapInTemplate('Components', content);
|
|
456
456
|
}
|
|
@@ -485,52 +485,52 @@ function generateIndexPage(sections) {
|
|
|
485
485
|
const filename = s.toLowerCase().replace(/\s+/g, '-') + '.html';
|
|
486
486
|
return `<li><a href="${filename}">${s}</a></li>`;
|
|
487
487
|
}).join('\n');
|
|
488
|
-
const content = `
|
|
489
|
-
<h1>📚 Documentation</h1>
|
|
490
|
-
|
|
491
|
-
<p>Welcome to the complete documentation for this application.</p>
|
|
492
|
-
|
|
493
|
-
<h2>Sections</h2>
|
|
494
|
-
|
|
495
|
-
<ul class="nav-list">
|
|
496
|
-
${sectionLinks}
|
|
497
|
-
</ul>
|
|
498
|
-
|
|
499
|
-
<div class="callout callout-success">
|
|
500
|
-
<h4>🚀 New to the project?</h4>
|
|
501
|
-
<p>Start with the <a href="quick-start.html">Quick Start Guide</a></p>
|
|
502
|
-
</div>
|
|
488
|
+
const content = `
|
|
489
|
+
<h1>📚 Documentation</h1>
|
|
490
|
+
|
|
491
|
+
<p>Welcome to the complete documentation for this application.</p>
|
|
492
|
+
|
|
493
|
+
<h2>Sections</h2>
|
|
494
|
+
|
|
495
|
+
<ul class="nav-list">
|
|
496
|
+
${sectionLinks}
|
|
497
|
+
</ul>
|
|
498
|
+
|
|
499
|
+
<div class="callout callout-success">
|
|
500
|
+
<h4>🚀 New to the project?</h4>
|
|
501
|
+
<p>Start with the <a href="quick-start.html">Quick Start Guide</a></p>
|
|
502
|
+
</div>
|
|
503
503
|
`;
|
|
504
504
|
return wrapInTemplate('Documentation', content);
|
|
505
505
|
}
|
|
506
506
|
function wrapInTemplate(title, content) {
|
|
507
|
-
return `<!DOCTYPE html>
|
|
508
|
-
<html lang="en">
|
|
509
|
-
<head>
|
|
510
|
-
<meta charset="UTF-8">
|
|
511
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
512
|
-
<title>${title} - Documentation</title>
|
|
513
|
-
<link rel="stylesheet" href="styles.css">
|
|
514
|
-
</head>
|
|
515
|
-
<body>
|
|
516
|
-
<nav class="sidebar">
|
|
517
|
-
<h2>📚 Docs</h2>
|
|
518
|
-
<ul>
|
|
519
|
-
<li><a href="index.html">Home</a></li>
|
|
520
|
-
<li><a href="quick-start.html">Quick Start</a></li>
|
|
521
|
-
<li><a href="setup.html">Setup</a></li>
|
|
522
|
-
<li><a href="architecture.html">Architecture</a></li>
|
|
523
|
-
<li><a href="api-reference.html">API Reference</a></li>
|
|
524
|
-
<li><a href="components.html">Components</a></li>
|
|
525
|
-
</ul>
|
|
526
|
-
</nav>
|
|
527
|
-
<main class="content">
|
|
528
|
-
${content}
|
|
529
|
-
<footer>
|
|
530
|
-
<p>Generated by CodeBakers v5.2.0 • ${new Date().toLocaleDateString()}</p>
|
|
531
|
-
</footer>
|
|
532
|
-
</main>
|
|
533
|
-
</body>
|
|
507
|
+
return `<!DOCTYPE html>
|
|
508
|
+
<html lang="en">
|
|
509
|
+
<head>
|
|
510
|
+
<meta charset="UTF-8">
|
|
511
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
512
|
+
<title>${title} - Documentation</title>
|
|
513
|
+
<link rel="stylesheet" href="styles.css">
|
|
514
|
+
</head>
|
|
515
|
+
<body>
|
|
516
|
+
<nav class="sidebar">
|
|
517
|
+
<h2>📚 Docs</h2>
|
|
518
|
+
<ul>
|
|
519
|
+
<li><a href="index.html">Home</a></li>
|
|
520
|
+
<li><a href="quick-start.html">Quick Start</a></li>
|
|
521
|
+
<li><a href="setup.html">Setup</a></li>
|
|
522
|
+
<li><a href="architecture.html">Architecture</a></li>
|
|
523
|
+
<li><a href="api-reference.html">API Reference</a></li>
|
|
524
|
+
<li><a href="components.html">Components</a></li>
|
|
525
|
+
</ul>
|
|
526
|
+
</nav>
|
|
527
|
+
<main class="content">
|
|
528
|
+
${content}
|
|
529
|
+
<footer>
|
|
530
|
+
<p>Generated by CodeBakers v5.2.0 • ${new Date().toLocaleDateString()}</p>
|
|
531
|
+
</footer>
|
|
532
|
+
</main>
|
|
533
|
+
</body>
|
|
534
534
|
</html>`;
|
|
535
535
|
}
|
|
536
536
|
async function writeDocFile(outputPath, filename, content) {
|
|
@@ -538,221 +538,221 @@ async function writeDocFile(outputPath, filename, content) {
|
|
|
538
538
|
await fs.writeFile(filePath, content, 'utf-8');
|
|
539
539
|
}
|
|
540
540
|
async function writeCSSFile(outputPath) {
|
|
541
|
-
const css = `
|
|
542
|
-
* {
|
|
543
|
-
margin: 0;
|
|
544
|
-
padding: 0;
|
|
545
|
-
box-sizing: border-box;
|
|
546
|
-
}
|
|
547
|
-
|
|
548
|
-
body {
|
|
549
|
-
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
550
|
-
line-height: 1.6;
|
|
551
|
-
color: #333;
|
|
552
|
-
display: flex;
|
|
553
|
-
min-height: 100vh;
|
|
554
|
-
}
|
|
555
|
-
|
|
556
|
-
.sidebar {
|
|
557
|
-
width: 250px;
|
|
558
|
-
background: #2c3e50;
|
|
559
|
-
color: white;
|
|
560
|
-
padding: 2rem 1.5rem;
|
|
561
|
-
position: fixed;
|
|
562
|
-
height: 100vh;
|
|
563
|
-
overflow-y: auto;
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
.sidebar h2 {
|
|
567
|
-
margin-bottom: 1.5rem;
|
|
568
|
-
font-size: 1.5rem;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
.sidebar ul {
|
|
572
|
-
list-style: none;
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
.sidebar li {
|
|
576
|
-
margin-bottom: 0.5rem;
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
.sidebar a {
|
|
580
|
-
color: #ecf0f1;
|
|
581
|
-
text-decoration: none;
|
|
582
|
-
display: block;
|
|
583
|
-
padding: 0.5rem;
|
|
584
|
-
border-radius: 4px;
|
|
585
|
-
transition: background 0.2s;
|
|
586
|
-
}
|
|
587
|
-
|
|
588
|
-
.sidebar a:hover {
|
|
589
|
-
background: #34495e;
|
|
590
|
-
}
|
|
591
|
-
|
|
592
|
-
.content {
|
|
593
|
-
margin-left: 250px;
|
|
594
|
-
padding: 3rem;
|
|
595
|
-
flex: 1;
|
|
596
|
-
max-width: 900px;
|
|
597
|
-
}
|
|
598
|
-
|
|
599
|
-
h1 {
|
|
600
|
-
font-size: 2.5rem;
|
|
601
|
-
margin-bottom: 1.5rem;
|
|
602
|
-
color: #2c3e50;
|
|
603
|
-
border-bottom: 3px solid #3498db;
|
|
604
|
-
padding-bottom: 0.5rem;
|
|
605
|
-
}
|
|
606
|
-
|
|
607
|
-
h2 {
|
|
608
|
-
font-size: 2rem;
|
|
609
|
-
margin: 2rem 0 1rem;
|
|
610
|
-
color: #34495e;
|
|
611
|
-
}
|
|
612
|
-
|
|
613
|
-
h3 {
|
|
614
|
-
font-size: 1.5rem;
|
|
615
|
-
margin: 1.5rem 0 1rem;
|
|
616
|
-
color: #555;
|
|
617
|
-
}
|
|
618
|
-
|
|
619
|
-
h4 {
|
|
620
|
-
font-size: 1.2rem;
|
|
621
|
-
margin: 1rem 0 0.5rem;
|
|
622
|
-
}
|
|
623
|
-
|
|
624
|
-
p {
|
|
625
|
-
margin-bottom: 1rem;
|
|
626
|
-
}
|
|
627
|
-
|
|
628
|
-
a {
|
|
629
|
-
color: #3498db;
|
|
630
|
-
text-decoration: none;
|
|
631
|
-
}
|
|
632
|
-
|
|
633
|
-
a:hover {
|
|
634
|
-
text-decoration: underline;
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
pre {
|
|
638
|
-
background: #f5f5f5;
|
|
639
|
-
border: 1px solid #ddd;
|
|
640
|
-
border-radius: 4px;
|
|
641
|
-
padding: 1rem;
|
|
642
|
-
overflow-x: auto;
|
|
643
|
-
margin: 1rem 0;
|
|
644
|
-
font-size: 0.9rem;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
code {
|
|
648
|
-
background: #f5f5f5;
|
|
649
|
-
padding: 0.2rem 0.4rem;
|
|
650
|
-
border-radius: 3px;
|
|
651
|
-
font-family: 'Courier New', monospace;
|
|
652
|
-
font-size: 0.9em;
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
pre code {
|
|
656
|
-
background: none;
|
|
657
|
-
padding: 0;
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
table {
|
|
661
|
-
width: 100%;
|
|
662
|
-
border-collapse: collapse;
|
|
663
|
-
margin: 1.5rem 0;
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
th, td {
|
|
667
|
-
padding: 0.75rem;
|
|
668
|
-
text-align: left;
|
|
669
|
-
border-bottom: 1px solid #ddd;
|
|
670
|
-
}
|
|
671
|
-
|
|
672
|
-
th {
|
|
673
|
-
background: #f5f5f5;
|
|
674
|
-
font-weight: 600;
|
|
675
|
-
}
|
|
676
|
-
|
|
677
|
-
ul, ol {
|
|
678
|
-
margin: 1rem 0 1rem 2rem;
|
|
679
|
-
}
|
|
680
|
-
|
|
681
|
-
li {
|
|
682
|
-
margin-bottom: 0.5rem;
|
|
683
|
-
}
|
|
684
|
-
|
|
685
|
-
.nav-list {
|
|
686
|
-
list-style: none;
|
|
687
|
-
margin: 1rem 0;
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
.nav-list li {
|
|
691
|
-
margin-bottom: 1rem;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
.nav-list a {
|
|
695
|
-
display: block;
|
|
696
|
-
padding: 1rem;
|
|
697
|
-
background: #f5f5f5;
|
|
698
|
-
border-left: 4px solid #3498db;
|
|
699
|
-
border-radius: 4px;
|
|
700
|
-
transition: all 0.2s;
|
|
701
|
-
}
|
|
702
|
-
|
|
703
|
-
.nav-list a:hover {
|
|
704
|
-
background: #e8f4f8;
|
|
705
|
-
transform: translateX(5px);
|
|
706
|
-
text-decoration: none;
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
.callout {
|
|
710
|
-
padding: 1rem 1.5rem;
|
|
711
|
-
border-radius: 4px;
|
|
712
|
-
margin: 1.5rem 0;
|
|
713
|
-
border-left: 4px solid;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
.callout-success {
|
|
717
|
-
background: #d4edda;
|
|
718
|
-
border-color: #28a745;
|
|
719
|
-
color: #155724;
|
|
720
|
-
}
|
|
721
|
-
|
|
722
|
-
.callout-info {
|
|
723
|
-
background: #d1ecf1;
|
|
724
|
-
border-color: #17a2b8;
|
|
725
|
-
color: #0c5460;
|
|
726
|
-
}
|
|
727
|
-
|
|
728
|
-
.api-route, .component-doc {
|
|
729
|
-
background: #f9f9f9;
|
|
730
|
-
padding: 1.5rem;
|
|
731
|
-
border-radius: 4px;
|
|
732
|
-
margin-bottom: 1.5rem;
|
|
733
|
-
border-left: 4px solid #3498db;
|
|
734
|
-
}
|
|
735
|
-
|
|
736
|
-
footer {
|
|
737
|
-
margin-top: 4rem;
|
|
738
|
-
padding-top: 2rem;
|
|
739
|
-
border-top: 1px solid #ddd;
|
|
740
|
-
color: #777;
|
|
741
|
-
font-size: 0.9rem;
|
|
742
|
-
}
|
|
743
|
-
|
|
744
|
-
@media (max-width: 768px) {
|
|
745
|
-
.sidebar {
|
|
746
|
-
width: 100%;
|
|
747
|
-
position: static;
|
|
748
|
-
height: auto;
|
|
749
|
-
}
|
|
750
|
-
|
|
751
|
-
.content {
|
|
752
|
-
margin-left: 0;
|
|
753
|
-
padding: 1.5rem;
|
|
754
|
-
}
|
|
755
|
-
}
|
|
541
|
+
const css = `
|
|
542
|
+
* {
|
|
543
|
+
margin: 0;
|
|
544
|
+
padding: 0;
|
|
545
|
+
box-sizing: border-box;
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
body {
|
|
549
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
550
|
+
line-height: 1.6;
|
|
551
|
+
color: #333;
|
|
552
|
+
display: flex;
|
|
553
|
+
min-height: 100vh;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
.sidebar {
|
|
557
|
+
width: 250px;
|
|
558
|
+
background: #2c3e50;
|
|
559
|
+
color: white;
|
|
560
|
+
padding: 2rem 1.5rem;
|
|
561
|
+
position: fixed;
|
|
562
|
+
height: 100vh;
|
|
563
|
+
overflow-y: auto;
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
.sidebar h2 {
|
|
567
|
+
margin-bottom: 1.5rem;
|
|
568
|
+
font-size: 1.5rem;
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
.sidebar ul {
|
|
572
|
+
list-style: none;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.sidebar li {
|
|
576
|
+
margin-bottom: 0.5rem;
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
.sidebar a {
|
|
580
|
+
color: #ecf0f1;
|
|
581
|
+
text-decoration: none;
|
|
582
|
+
display: block;
|
|
583
|
+
padding: 0.5rem;
|
|
584
|
+
border-radius: 4px;
|
|
585
|
+
transition: background 0.2s;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
.sidebar a:hover {
|
|
589
|
+
background: #34495e;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
.content {
|
|
593
|
+
margin-left: 250px;
|
|
594
|
+
padding: 3rem;
|
|
595
|
+
flex: 1;
|
|
596
|
+
max-width: 900px;
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
h1 {
|
|
600
|
+
font-size: 2.5rem;
|
|
601
|
+
margin-bottom: 1.5rem;
|
|
602
|
+
color: #2c3e50;
|
|
603
|
+
border-bottom: 3px solid #3498db;
|
|
604
|
+
padding-bottom: 0.5rem;
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
h2 {
|
|
608
|
+
font-size: 2rem;
|
|
609
|
+
margin: 2rem 0 1rem;
|
|
610
|
+
color: #34495e;
|
|
611
|
+
}
|
|
612
|
+
|
|
613
|
+
h3 {
|
|
614
|
+
font-size: 1.5rem;
|
|
615
|
+
margin: 1.5rem 0 1rem;
|
|
616
|
+
color: #555;
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
h4 {
|
|
620
|
+
font-size: 1.2rem;
|
|
621
|
+
margin: 1rem 0 0.5rem;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
p {
|
|
625
|
+
margin-bottom: 1rem;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
a {
|
|
629
|
+
color: #3498db;
|
|
630
|
+
text-decoration: none;
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
a:hover {
|
|
634
|
+
text-decoration: underline;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
pre {
|
|
638
|
+
background: #f5f5f5;
|
|
639
|
+
border: 1px solid #ddd;
|
|
640
|
+
border-radius: 4px;
|
|
641
|
+
padding: 1rem;
|
|
642
|
+
overflow-x: auto;
|
|
643
|
+
margin: 1rem 0;
|
|
644
|
+
font-size: 0.9rem;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
code {
|
|
648
|
+
background: #f5f5f5;
|
|
649
|
+
padding: 0.2rem 0.4rem;
|
|
650
|
+
border-radius: 3px;
|
|
651
|
+
font-family: 'Courier New', monospace;
|
|
652
|
+
font-size: 0.9em;
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
pre code {
|
|
656
|
+
background: none;
|
|
657
|
+
padding: 0;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
table {
|
|
661
|
+
width: 100%;
|
|
662
|
+
border-collapse: collapse;
|
|
663
|
+
margin: 1.5rem 0;
|
|
664
|
+
}
|
|
665
|
+
|
|
666
|
+
th, td {
|
|
667
|
+
padding: 0.75rem;
|
|
668
|
+
text-align: left;
|
|
669
|
+
border-bottom: 1px solid #ddd;
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
th {
|
|
673
|
+
background: #f5f5f5;
|
|
674
|
+
font-weight: 600;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
ul, ol {
|
|
678
|
+
margin: 1rem 0 1rem 2rem;
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
li {
|
|
682
|
+
margin-bottom: 0.5rem;
|
|
683
|
+
}
|
|
684
|
+
|
|
685
|
+
.nav-list {
|
|
686
|
+
list-style: none;
|
|
687
|
+
margin: 1rem 0;
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
.nav-list li {
|
|
691
|
+
margin-bottom: 1rem;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
.nav-list a {
|
|
695
|
+
display: block;
|
|
696
|
+
padding: 1rem;
|
|
697
|
+
background: #f5f5f5;
|
|
698
|
+
border-left: 4px solid #3498db;
|
|
699
|
+
border-radius: 4px;
|
|
700
|
+
transition: all 0.2s;
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
.nav-list a:hover {
|
|
704
|
+
background: #e8f4f8;
|
|
705
|
+
transform: translateX(5px);
|
|
706
|
+
text-decoration: none;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
.callout {
|
|
710
|
+
padding: 1rem 1.5rem;
|
|
711
|
+
border-radius: 4px;
|
|
712
|
+
margin: 1.5rem 0;
|
|
713
|
+
border-left: 4px solid;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
.callout-success {
|
|
717
|
+
background: #d4edda;
|
|
718
|
+
border-color: #28a745;
|
|
719
|
+
color: #155724;
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
.callout-info {
|
|
723
|
+
background: #d1ecf1;
|
|
724
|
+
border-color: #17a2b8;
|
|
725
|
+
color: #0c5460;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
.api-route, .component-doc {
|
|
729
|
+
background: #f9f9f9;
|
|
730
|
+
padding: 1.5rem;
|
|
731
|
+
border-radius: 4px;
|
|
732
|
+
margin-bottom: 1.5rem;
|
|
733
|
+
border-left: 4px solid #3498db;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
footer {
|
|
737
|
+
margin-top: 4rem;
|
|
738
|
+
padding-top: 2rem;
|
|
739
|
+
border-top: 1px solid #ddd;
|
|
740
|
+
color: #777;
|
|
741
|
+
font-size: 0.9rem;
|
|
742
|
+
}
|
|
743
|
+
|
|
744
|
+
@media (max-width: 768px) {
|
|
745
|
+
.sidebar {
|
|
746
|
+
width: 100%;
|
|
747
|
+
position: static;
|
|
748
|
+
height: auto;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
.content {
|
|
752
|
+
margin-left: 0;
|
|
753
|
+
padding: 1.5rem;
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
756
|
`;
|
|
757
757
|
await fs.writeFile(path.join(outputPath, 'styles.css'), css, 'utf-8');
|
|
758
758
|
}
|