initial commit after project creation
This commit is contained in:
190
scripts/README.md
Normal file
190
scripts/README.md
Normal file
@@ -0,0 +1,190 @@
|
||||
# TinaDocs Utility Scripts
|
||||
|
||||
This directory contains utility scripts to help you manage your TinaDocs project.
|
||||
|
||||
## Documentation Reset
|
||||
|
||||
The `cleanup` script provides a complete documentation reset, removing all content directories while preserving only the main index page.
|
||||
|
||||
### What it does
|
||||
|
||||
- ✅ **Deletes all directories** within `content/docs/` (preserves only `index.mdx`)
|
||||
- ✅ **Deletes all API schema files** in `content/apiSchema/` (spec files, swagger files, etc.)
|
||||
- ✅ **Deletes** image asset directories (`docs-assets/` and `landing-assets/`)
|
||||
- ✅ **Clears Next.js cache** (`.next` folder) to prevent stale page references
|
||||
- ✅ **Completely removes** the API tab from navigation
|
||||
- ✅ **Provides** a completely clean documentation slate
|
||||
- ✅ **Validates** that you're in a TinaDocs project before running
|
||||
- ✅ **Requires interactive confirmation** - asks for explicit "yes" to proceed
|
||||
|
||||
### Usage
|
||||
|
||||
```bash
|
||||
pnpm run cleanup
|
||||
```
|
||||
|
||||
> **🚨 CRITICAL WARNING - READ BEFORE RUNNING:**
|
||||
>
|
||||
> **This script PERMANENTLY DELETES all documentation content and cannot be undone.**
|
||||
>
|
||||
> ❌ **DO NOT RUN if you've already made changes** - it will DELETE your work
|
||||
> ✅ **DO RUN FIRST** if you want a clean slate, then make your changes
|
||||
> ✅ **COMMIT TO GIT** before running if you want to preserve existing changes
|
||||
>
|
||||
> **This action is irreversible unless you have version control backups.**
|
||||
|
||||
### When to use this script
|
||||
|
||||
Use this script when you:
|
||||
- Want to completely reset your documentation structure **BEFORE making any changes**
|
||||
- Need to remove all existing content and start fresh **from the beginning**
|
||||
- Are setting up a new project from the TinaDocs template **as your first step**
|
||||
- Want to clear out example/demo content **before adding your own**
|
||||
- Need a clean slate for new documentation **at project start**
|
||||
|
||||
### When NOT to use this script
|
||||
|
||||
❌ **DO NOT USE** if you have:
|
||||
- Already written your own documentation content
|
||||
- Made customizations to the example files
|
||||
- Added your own pages or sections
|
||||
- Started working on your documentation project
|
||||
|
||||
⚠️ **Use with extreme caution** if you have made ANY changes to the documentation.
|
||||
|
||||
### What gets preserved
|
||||
|
||||
The script preserves:
|
||||
- `content/docs/index.mdx` (main landing page)
|
||||
- All other files outside the docs directory
|
||||
|
||||
### What gets removed
|
||||
|
||||
The script removes:
|
||||
- ALL directories within `content/docs/` including:
|
||||
- `api-documentation/`
|
||||
- `examples/`
|
||||
- `tinadocs-features/`
|
||||
- `using-tinacms/`
|
||||
- `introduction/`
|
||||
- `going-live/`
|
||||
- ALL files in `content/apiSchema/` directory:
|
||||
- `spec.json`
|
||||
- `Swagger-Petstore.json`
|
||||
- Any other API schema files
|
||||
- The `public/img/docs-assets/` directory and all its images
|
||||
- The `public/img/landing-assets/` directory and all its images
|
||||
- The `.next` cache directory (prevents stale page references)
|
||||
- The complete API tab from navigation
|
||||
|
||||
### Safety features
|
||||
|
||||
- ✅ Validates TinaDocs project structure before running
|
||||
- ✅ Shows what will be deleted and preserves important files
|
||||
- ✅ Preserves `content/docs/index.mdx` (main landing page)
|
||||
- ✅ Handles missing directories gracefully (skips if not found)
|
||||
- ✅ Updates navigation safely without breaking other tabs
|
||||
- ✅ Clears Next.js cache to prevent stale page references
|
||||
- ✅ Provides detailed success/error messages with file counts
|
||||
|
||||
### Example output
|
||||
|
||||
```
|
||||
🧹 TinaDocs API Documentation Cleanup
|
||||
|
||||
🚨 WARNING: This will PERMANENTLY DELETE all documentation content!
|
||||
- All directories in content/docs/ (except index.mdx)
|
||||
- All API schema files
|
||||
- All image assets
|
||||
- Navigation links
|
||||
- Next.js cache
|
||||
|
||||
❌ If you've made changes, they will be DELETED!
|
||||
✅ Only run this if you want a completely clean slate.
|
||||
|
||||
✅ TinaDocs project detected
|
||||
|
||||
🔍 Do you want to proceed with the cleanup?
|
||||
Type 'yes' or 'y' to continue
|
||||
Type 'no' or 'n' to cancel
|
||||
|
||||
👉 Your choice (yes/no): yes
|
||||
|
||||
✅ Proceeding with cleanup...
|
||||
|
||||
🗑️ Cleaning up docs directories (preserving index.mdx)...
|
||||
🗑️ Deleting directory: content/docs/api-documentation
|
||||
📄 Deleting file: overview.mdx
|
||||
📄 Deleting file: pet/get-pet-findbystatus.mdx
|
||||
(... more files)
|
||||
✅ Directory deleted: api-documentation (9 files)
|
||||
|
||||
📄 Cleaning API schema files...
|
||||
🗑️ Deleted: Swagger-Petstore.json
|
||||
🗑️ Deleted: spec.json
|
||||
✅ Cleaned up 2 API schema file(s)
|
||||
|
||||
🗑️ Deleting docs-assets directory: public/img/docs-assets
|
||||
📄 Deleting file: api-spec-upload.png
|
||||
(... more files)
|
||||
✅ docs-assets directory deleted (27 files)
|
||||
|
||||
🗂️ Cleaning Next.js cache...
|
||||
✅ Deleted .next cache directory (1346 files)
|
||||
|
||||
📝 Updating navigation...
|
||||
🔍 Found Docs tab with 4 menu groups
|
||||
🗑️ Cleaned up Docs navigation (removed 3 groups)
|
||||
✅ Navigation now only shows index.mdx
|
||||
🗑️ Completely removed API tab from navigation
|
||||
✅ Navigation updated successfully
|
||||
|
||||
🎉 Cleanup completed!
|
||||
|
||||
📊 Summary:
|
||||
• Deleted docs directories: api-documentation, examples, going-live, introduction, tinadocs-features, using-tinacms (31 files)
|
||||
• Deleted API schema files: 2 files
|
||||
• Deleted image directories: docs-assets, landing-assets (31 files)
|
||||
• Navigation updated successfully
|
||||
• Next.js cache cleared successfully
|
||||
|
||||
💡 Next steps:
|
||||
• Review the changes in your editor
|
||||
• Restart your dev server: pnpm dev
|
||||
• Test your documentation site
|
||||
• Commit the changes to version control
|
||||
```
|
||||
|
||||
### Troubleshooting
|
||||
|
||||
If you encounter issues:
|
||||
|
||||
1. **"This doesn't appear to be a TinaDocs project"**
|
||||
- Make sure you're running the script from your project root
|
||||
- Verify you have `content/docs/` and `tina/` directories
|
||||
|
||||
2. **"Navigation update failed"**
|
||||
- Check that `content/navigation-bar/docs-navigation-bar.json` exists
|
||||
- Ensure the file is valid JSON
|
||||
|
||||
3. **Permission errors**
|
||||
- Make sure you have write permissions to the project directory
|
||||
- Check permissions for `content/`, `public/`, and `.next` directories
|
||||
|
||||
4. **"API schema directory not found"**
|
||||
- This is normal if your project doesn't have API schema files
|
||||
- The script will skip this step safely
|
||||
|
||||
### After running the script
|
||||
|
||||
1. Review the changes in your editor
|
||||
2. **Restart your dev server**: `pnpm dev` (required to clear Next.js cache)
|
||||
3. Test your documentation site
|
||||
4. Commit the changes to version control
|
||||
5. Update any links or references to the deleted documentation
|
||||
|
||||
> **Important:** You must restart your development server after running cleanup to ensure Next.js rebuilds the site without cached references to deleted pages.
|
||||
|
||||
---
|
||||
|
||||
For more TinaDocs utilities and documentation, visit [TinaDocs GitHub](https://github.com/tinacms/tina-docs).
|
||||
23
scripts/check-pagefind.js
Normal file
23
scripts/check-pagefind.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
|
||||
const entryPath = path.join(__dirname, "..", "public", "pagefind", "pagefind-entry.json");
|
||||
|
||||
if (!fs.existsSync(entryPath)) {
|
||||
console.warn(
|
||||
"\x1b[33m⚠ Pagefind index not found. Search will not work in dev.\n" +
|
||||
" Run: pnpm build-local-pagefind\x1b[0m\n"
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
const stats = fs.statSync(entryPath);
|
||||
const ageMs = Date.now() - stats.mtimeMs;
|
||||
const ageDays = Math.floor(ageMs / (1000 * 60 * 60 * 24));
|
||||
|
||||
if (ageDays >= 7) {
|
||||
console.warn(
|
||||
`\x1b[33m⚠ Pagefind index is ${ageDays} day${ageDays === 1 ? "" : "s"} old. Search results may be stale.\n` +
|
||||
" Run: pnpm build-local-pagefind\x1b[0m\n"
|
||||
);
|
||||
}
|
||||
658
scripts/cleanup.js
Normal file
658
scripts/cleanup.js
Normal file
@@ -0,0 +1,658 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* TinaDocs API Documentation Cleanup Script
|
||||
*
|
||||
* This script helps TinaDocs users clean up auto-generated API documentation
|
||||
* while preserving manually created overview documents.
|
||||
*
|
||||
* Usage:
|
||||
* pnpm run cleanup
|
||||
*
|
||||
* What it does:
|
||||
* 1. Deletes all directories within content/docs/ (preserves only index.mdx)
|
||||
* 2. Deletes all files in content/apiSchema/ (API spec files)
|
||||
* 3. Deletes docs-assets and landing-assets image folders
|
||||
* 4. Clears Next.js cache (.next folder) to prevent stale page references
|
||||
* 5. Cleans up navigation to only show the main index page
|
||||
* 6. Rewrites index.mdx with clean slate instructions and admin link
|
||||
* 7. Provides a completely clean documentation slate
|
||||
*/
|
||||
|
||||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const readline = require("readline");
|
||||
|
||||
console.log("🧹 TinaDocs API Documentation Cleanup\n");
|
||||
console.log(
|
||||
"🚨 WARNING: This will PERMANENTLY DELETE all documentation content!"
|
||||
);
|
||||
console.log(" - All directories in content/docs/ (except index.mdx)");
|
||||
console.log(" - All API schema files");
|
||||
console.log(" - All image assets");
|
||||
console.log(" - Navigation links");
|
||||
console.log(" - Next.js cache");
|
||||
console.log("\n❌ If you've made changes, they will be DELETED!");
|
||||
console.log("✅ Only run this if you want a completely clean slate.\n");
|
||||
|
||||
/**
|
||||
* Prompt user for confirmation before proceeding with cleanup
|
||||
*/
|
||||
function askForConfirmation() {
|
||||
return new Promise((resolve) => {
|
||||
const rl = readline.createInterface({
|
||||
input: process.stdin,
|
||||
output: process.stdout,
|
||||
});
|
||||
|
||||
console.log("🔍 Do you want to proceed with the cleanup?");
|
||||
console.log(" Type 'yes' or 'y' to continue");
|
||||
console.log(" Type 'no' or 'n' to cancel");
|
||||
|
||||
rl.question("\n👉 Your choice (yes/no): ", (answer) => {
|
||||
rl.close();
|
||||
|
||||
const normalizedAnswer = answer.toLowerCase().trim();
|
||||
if (normalizedAnswer === "yes" || normalizedAnswer === "y") {
|
||||
console.log("\n✅ Proceeding with cleanup...\n");
|
||||
resolve(true);
|
||||
} else if (normalizedAnswer === "no" || normalizedAnswer === "n") {
|
||||
console.log("\n❌ Cleanup cancelled. No changes were made.");
|
||||
resolve(false);
|
||||
} else {
|
||||
console.log(
|
||||
"\n⚠️ Invalid input. Please type 'yes', 'y', 'no', or 'n'."
|
||||
);
|
||||
// Recursively ask again for invalid input
|
||||
askForConfirmation().then(resolve);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Paths (relative to project root)
|
||||
const docsPath = path.join(process.cwd(), "content/docs");
|
||||
const apiSchemaPath = path.join(process.cwd(), "content/apiSchema");
|
||||
const docsAssetsPath = path.join(process.cwd(), "public/img/docs-assets");
|
||||
const landingAssetsPath = path.join(process.cwd(), "public/img/landing-assets");
|
||||
const nextCachePath = path.join(process.cwd(), ".next");
|
||||
const navigationPath = path.join(
|
||||
process.cwd(),
|
||||
"content/navigation-bar/docs-navigation-bar.json"
|
||||
);
|
||||
|
||||
/**
|
||||
* Validate that we're in a TinaDocs project
|
||||
*/
|
||||
function validateTinaDocsProject() {
|
||||
const requiredPaths = [
|
||||
"content/docs",
|
||||
"content/navigation-bar",
|
||||
"tina/config.ts",
|
||||
];
|
||||
|
||||
for (const requiredPath of requiredPaths) {
|
||||
if (!fs.existsSync(path.join(process.cwd(), requiredPath))) {
|
||||
console.error(`❌ Error: This doesn't appear to be a TinaDocs project.`);
|
||||
console.error(` Missing required path: ${requiredPath}`);
|
||||
console.error(
|
||||
` Please run this script from your TinaDocs project root.`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
console.log("✅ TinaDocs project detected\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively delete a directory and all its contents
|
||||
*/
|
||||
function deleteDirectory(dirPath) {
|
||||
if (!fs.existsSync(dirPath)) {
|
||||
console.log(
|
||||
`⚠️ Directory not found: ${path.relative(process.cwd(), dirPath)}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
console.log(
|
||||
`🗑️ Deleting directory: ${path.relative(process.cwd(), dirPath)}`
|
||||
);
|
||||
|
||||
try {
|
||||
const files = fs.readdirSync(dirPath);
|
||||
let fileCount = 0;
|
||||
|
||||
// Delete each file/directory
|
||||
files.forEach((file) => {
|
||||
const filePath = path.join(dirPath, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
deleteDirectory(filePath); // Recursive delete
|
||||
} else {
|
||||
console.log(` 📄 Deleting file: ${file}`);
|
||||
fs.unlinkSync(filePath);
|
||||
fileCount++;
|
||||
}
|
||||
});
|
||||
|
||||
// Remove the now-empty directory
|
||||
fs.rmdirSync(dirPath);
|
||||
console.log(
|
||||
`✅ Directory deleted: ${path.basename(dirPath)} (${fileCount} files)\n`
|
||||
);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`❌ Error deleting directory ${path.basename(dirPath)}:`,
|
||||
error.message
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update navigation to clean up all references to deleted directories
|
||||
*/
|
||||
function updateNavigation() {
|
||||
console.log("📝 Updating navigation...");
|
||||
|
||||
if (!fs.existsSync(navigationPath)) {
|
||||
console.log("⚠️ Navigation file not found - skipping navigation update");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Read the navigation file
|
||||
const navigationData = JSON.parse(fs.readFileSync(navigationPath, "utf8"));
|
||||
|
||||
let updatesCount = 0;
|
||||
|
||||
// Remove API tab completely
|
||||
const originalTabCount = navigationData.tabs?.length || 0;
|
||||
if (navigationData.tabs) {
|
||||
navigationData.tabs = navigationData.tabs.filter(
|
||||
(tab) => tab.title !== "API"
|
||||
);
|
||||
}
|
||||
const apiTabsRemoved =
|
||||
originalTabCount - (navigationData.tabs?.length || 0);
|
||||
updatesCount += apiTabsRemoved;
|
||||
|
||||
// Clean up Docs tab - remove all groups except Introduction with only index.mdx
|
||||
const docsTab = navigationData.tabs?.find((tab) => tab.title === "Docs");
|
||||
if (docsTab && docsTab.supermenuGroup) {
|
||||
console.log(
|
||||
` 🔍 Found Docs tab with ${docsTab.supermenuGroup.length} menu groups`
|
||||
);
|
||||
|
||||
// Keep only Introduction group with only index.mdx
|
||||
const originalGroupCount = docsTab.supermenuGroup.length;
|
||||
docsTab.supermenuGroup = [
|
||||
{
|
||||
title: "Introduction",
|
||||
items: [
|
||||
{
|
||||
slug: "content/docs/index.mdx",
|
||||
_template: "item",
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const removedGroups = originalGroupCount - docsTab.supermenuGroup.length;
|
||||
updatesCount += removedGroups;
|
||||
|
||||
console.log(
|
||||
` 🗑️ Cleaned up Docs navigation (removed ${removedGroups} groups)`
|
||||
);
|
||||
console.log(` ✅ Navigation now only shows index.mdx`);
|
||||
}
|
||||
|
||||
if (updatesCount > 0) {
|
||||
if (apiTabsRemoved > 0) {
|
||||
console.log(` 🗑️ Completely removed API tab from navigation`);
|
||||
}
|
||||
|
||||
// Write back to file
|
||||
fs.writeFileSync(navigationPath, JSON.stringify(navigationData, null, 2));
|
||||
console.log("✅ Navigation updated successfully\n");
|
||||
} else {
|
||||
console.log(" ℹ️ No navigation updates needed\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error("❌ Error updating navigation:", error.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up all directories within content/docs/ while preserving index.mdx
|
||||
*/
|
||||
function cleanupDocsDirectories() {
|
||||
if (!fs.existsSync(docsPath)) {
|
||||
console.log("⚠️ Docs directory not found - nothing to clean up");
|
||||
return { deletedDirectories: [], totalFiles: 0 };
|
||||
}
|
||||
|
||||
console.log("🗑️ Cleaning up docs directories (preserving index.mdx)...\n");
|
||||
|
||||
const results = { deletedDirectories: [], totalFiles: 0 };
|
||||
|
||||
try {
|
||||
const items = fs.readdirSync(docsPath);
|
||||
|
||||
items.forEach((item) => {
|
||||
const itemPath = path.join(docsPath, item);
|
||||
const stat = fs.statSync(itemPath);
|
||||
|
||||
if (stat.isDirectory()) {
|
||||
console.log(
|
||||
`🗑️ Deleting directory: ${path.relative(process.cwd(), itemPath)}`
|
||||
);
|
||||
|
||||
// Count files in this directory recursively
|
||||
let fileCount = 0;
|
||||
function countFiles(dirPath) {
|
||||
try {
|
||||
const dirItems = fs.readdirSync(dirPath);
|
||||
dirItems.forEach((dirItem) => {
|
||||
const dirItemPath = path.join(dirPath, dirItem);
|
||||
const dirItemStat = fs.statSync(dirItemPath);
|
||||
if (dirItemStat.isFile()) {
|
||||
fileCount++;
|
||||
console.log(
|
||||
` 📄 Deleting file: ${path.relative(itemPath, dirItemPath)}`
|
||||
);
|
||||
} else if (dirItemStat.isDirectory()) {
|
||||
countFiles(dirItemPath);
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
console.error(
|
||||
` ⚠️ Error reading directory ${dirPath}:`,
|
||||
error.message
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
countFiles(itemPath);
|
||||
|
||||
// Delete the directory
|
||||
if (deleteDirectory(itemPath)) {
|
||||
console.log(`✅ Directory deleted: ${item} (${fileCount} files)\n`);
|
||||
results.deletedDirectories.push(item);
|
||||
results.totalFiles += fileCount;
|
||||
}
|
||||
} else if (stat.isFile() && item !== "index.mdx") {
|
||||
// Delete any other files in docs root (but preserve index.mdx)
|
||||
console.log(`🗑️ Deleting file: ${item}`);
|
||||
fs.unlinkSync(itemPath);
|
||||
console.log(`✅ File deleted: ${item}\n`);
|
||||
results.totalFiles += 1;
|
||||
} else if (item === "index.mdx") {
|
||||
console.log(`✅ Preserving: ${item}`);
|
||||
}
|
||||
});
|
||||
|
||||
return results;
|
||||
} catch (error) {
|
||||
console.error(`❌ Error cleaning up docs directories:`, error.message);
|
||||
return { deletedDirectories: [], totalFiles: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up image asset directories
|
||||
*/
|
||||
function cleanupImageAssets() {
|
||||
const results = { deletedDirectories: [], totalFiles: 0 };
|
||||
|
||||
// Clean up docs-assets directory
|
||||
if (fs.existsSync(docsAssetsPath)) {
|
||||
console.log(
|
||||
`🗑️ Deleting docs-assets directory: ${path.relative(
|
||||
process.cwd(),
|
||||
docsAssetsPath
|
||||
)}`
|
||||
);
|
||||
|
||||
try {
|
||||
const files = fs.readdirSync(docsAssetsPath);
|
||||
let fileCount = 0;
|
||||
|
||||
files.forEach((file) => {
|
||||
const filePath = path.join(docsAssetsPath, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isFile()) {
|
||||
console.log(` 📄 Deleting file: ${file}`);
|
||||
fs.unlinkSync(filePath);
|
||||
fileCount++;
|
||||
}
|
||||
});
|
||||
|
||||
fs.rmdirSync(docsAssetsPath);
|
||||
console.log(`✅ docs-assets directory deleted (${fileCount} files)\n`);
|
||||
results.deletedDirectories.push("docs-assets");
|
||||
results.totalFiles += fileCount;
|
||||
} catch (error) {
|
||||
console.error(`❌ Error deleting docs-assets directory:`, error.message);
|
||||
}
|
||||
} else {
|
||||
console.log("⚠️ docs-assets directory not found - skipping");
|
||||
}
|
||||
|
||||
// Clean up landing-assets directory
|
||||
if (fs.existsSync(landingAssetsPath)) {
|
||||
console.log(
|
||||
`🗑️ Deleting landing-assets directory: ${path.relative(
|
||||
process.cwd(),
|
||||
landingAssetsPath
|
||||
)}`
|
||||
);
|
||||
|
||||
try {
|
||||
const files = fs.readdirSync(landingAssetsPath);
|
||||
let fileCount = 0;
|
||||
|
||||
files.forEach((file) => {
|
||||
const filePath = path.join(landingAssetsPath, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
if (stat.isFile()) {
|
||||
console.log(` 📄 Deleting file: ${file}`);
|
||||
fs.unlinkSync(filePath);
|
||||
fileCount++;
|
||||
}
|
||||
});
|
||||
|
||||
fs.rmdirSync(landingAssetsPath);
|
||||
console.log(`✅ landing-assets directory deleted (${fileCount} files)\n`);
|
||||
results.deletedDirectories.push("landing-assets");
|
||||
results.totalFiles += fileCount;
|
||||
} catch (error) {
|
||||
console.error(
|
||||
`❌ Error deleting landing-assets directory:`,
|
||||
error.message
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.log("⚠️ landing-assets directory not found - skipping");
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up API schema files
|
||||
*/
|
||||
function cleanupApiSchema() {
|
||||
console.log("📄 Cleaning API schema files...");
|
||||
|
||||
if (!fs.existsSync(apiSchemaPath)) {
|
||||
console.log(" ⚠️ API schema directory not found - skipping\n");
|
||||
return { deletedFiles: 0 };
|
||||
}
|
||||
|
||||
try {
|
||||
const files = fs.readdirSync(apiSchemaPath);
|
||||
let deletedFiles = 0;
|
||||
|
||||
for (const file of files) {
|
||||
const filePath = path.join(apiSchemaPath, file);
|
||||
const stat = fs.statSync(filePath);
|
||||
|
||||
if (stat.isFile()) {
|
||||
fs.unlinkSync(filePath);
|
||||
deletedFiles++;
|
||||
console.log(` 🗑️ Deleted: ${file}`);
|
||||
}
|
||||
}
|
||||
|
||||
if (deletedFiles > 0) {
|
||||
console.log(` ✅ Cleaned up ${deletedFiles} API schema file(s)\n`);
|
||||
} else {
|
||||
console.log(" ℹ️ No files found to delete\n");
|
||||
}
|
||||
|
||||
return { deletedFiles };
|
||||
} catch (error) {
|
||||
console.error(` ❌ Error cleaning API schema: ${error.message}\n`);
|
||||
return { deletedFiles: 0 };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean up Next.js cache directory
|
||||
*/
|
||||
function cleanupNextCache() {
|
||||
console.log("🗂️ Cleaning Next.js cache...");
|
||||
|
||||
if (!fs.existsSync(nextCachePath)) {
|
||||
console.log(" ℹ️ No .next folder found (cache already clean)\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Count files in .next before deletion
|
||||
let fileCount = 0;
|
||||
function countFiles(dir) {
|
||||
const entries = fs.readdirSync(dir, { withFileTypes: true });
|
||||
for (const entry of entries) {
|
||||
if (entry.isDirectory()) {
|
||||
countFiles(path.join(dir, entry.name));
|
||||
} else {
|
||||
fileCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
countFiles(nextCachePath);
|
||||
|
||||
// Delete the .next directory
|
||||
fs.rmSync(nextCachePath, { recursive: true, force: true });
|
||||
console.log(` ✅ Deleted .next cache directory (${fileCount} files)\n`);
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(` ❌ Error deleting .next cache: ${error.message}\n`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite index.mdx after successful cleanup
|
||||
*/
|
||||
function rewriteIndexMdx() {
|
||||
console.log("📝 Updating index.mdx for clean slate...");
|
||||
|
||||
const indexPath = path.join(process.cwd(), "content/docs/index.mdx");
|
||||
|
||||
if (!fs.existsSync(indexPath)) {
|
||||
console.log(" ⚠️ index.mdx not found - skipping rewrite\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
// Read current content
|
||||
const currentContent = fs.readFileSync(indexPath, "utf8");
|
||||
|
||||
// Extract front matter and intro content (lines 1-15)
|
||||
const lines = currentContent.split("\n");
|
||||
const frontMatterEnd = lines.findIndex(
|
||||
(line, index) => index > 0 && line.trim() === "---"
|
||||
);
|
||||
|
||||
if (frontMatterEnd === -1) {
|
||||
console.log(" ❌ Could not find front matter - skipping rewrite\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find the end of the intro content (line that contains "GitHub repository")
|
||||
const introEndIndex = lines.findIndex((line) =>
|
||||
line.includes(
|
||||
"GitHub repository—versioned, portable, and fully under your control."
|
||||
)
|
||||
);
|
||||
|
||||
if (introEndIndex === -1) {
|
||||
console.log(
|
||||
" ❌ Could not find intro content end - skipping rewrite\n"
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
// Preserve front matter and intro content
|
||||
const preservedLines = lines.slice(0, introEndIndex + 1);
|
||||
const preservedContent = preservedLines.join("\n");
|
||||
|
||||
// New content for post-cleanup (TinaCMS-compatible)
|
||||
const newContent =
|
||||
"\n\n## Clean Slate Ready!\n\nCongratulations! You've successfully reset your TinaDocs project and now have a clean slate to work with.\n\n### What's Next?\n\n**Start creating your documentation:**\n\n1. **Open the TinaCMS Admin Interface** at: http://localhost:3000/admin\n\n2. **Begin editing your content** using TinaCMS's visual editor\n\n3. **Add new pages** and organize your documentation structure\n\n4. **Customize your site** to match your project's needs\n\n### Quick Tips\n\n- **Create new pages** through the TinaCMS admin interface\n- **Organize content** using TinaCMS's folder structure\n- **Preview changes** instantly as you edit\n- **Commit changes** to your repository when ready\n\n> **Need help getting started?** Check out the [TinaCMS documentation](https://tina.io/docs/) for detailed guides and tutorials.\n\n**Happy documenting!**\n";
|
||||
|
||||
// Combine preserved content with new content
|
||||
const finalContent = preservedContent + newContent;
|
||||
|
||||
// Write the updated content
|
||||
fs.writeFileSync(indexPath, finalContent);
|
||||
|
||||
console.log(" ✅ Updated index.mdx with clean slate instructions\n");
|
||||
return true;
|
||||
} catch (error) {
|
||||
console.error(` ❌ Error rewriting index.mdx: ${error.message}\n`);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Main cleanup function
|
||||
*/
|
||||
async function cleanup() {
|
||||
try {
|
||||
// Validate we're in a TinaDocs project
|
||||
validateTinaDocsProject();
|
||||
|
||||
// Ask for user confirmation before proceeding
|
||||
const shouldProceed = await askForConfirmation();
|
||||
if (!shouldProceed) {
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Clean up all docs directories (preserve only index.mdx)
|
||||
const { deletedDirectories: deletedDocs, totalFiles: docsFileCount } =
|
||||
cleanupDocsDirectories();
|
||||
|
||||
// Clean up API schema files
|
||||
const { deletedFiles: apiSchemaFileCount } = cleanupApiSchema();
|
||||
|
||||
// Clean up image asset directories
|
||||
const { deletedDirectories: deletedImageDirs, totalFiles: imageFileCount } =
|
||||
cleanupImageAssets();
|
||||
|
||||
// Clean up Next.js cache
|
||||
const nextCacheDeleted = cleanupNextCache();
|
||||
|
||||
// Update navigation
|
||||
const navigationUpdated = updateNavigation();
|
||||
|
||||
// Rewrite index.mdx for clean slate
|
||||
const indexUpdated = rewriteIndexMdx();
|
||||
|
||||
// Summary
|
||||
console.log("🎉 Cleanup completed!\n");
|
||||
console.log("📊 Summary:");
|
||||
|
||||
if (deletedDocs.length > 0) {
|
||||
console.log(
|
||||
`• Deleted docs directories: ${deletedDocs.join(
|
||||
", "
|
||||
)} (${docsFileCount} files)`
|
||||
);
|
||||
} else {
|
||||
console.log("• No docs directories were deleted (none found)");
|
||||
}
|
||||
|
||||
if (apiSchemaFileCount > 0) {
|
||||
console.log(`• Deleted API schema files: ${apiSchemaFileCount} files`);
|
||||
} else {
|
||||
console.log("• No API schema files were deleted (none found)");
|
||||
}
|
||||
|
||||
if (deletedImageDirs.length > 0) {
|
||||
console.log(
|
||||
`• Deleted image directories: ${deletedImageDirs.join(
|
||||
", "
|
||||
)} (${imageFileCount} files)`
|
||||
);
|
||||
} else {
|
||||
console.log("• No image directories were deleted (none found)");
|
||||
}
|
||||
|
||||
if (navigationUpdated) {
|
||||
console.log("• Navigation updated successfully");
|
||||
} else {
|
||||
console.log("• Navigation update skipped or failed");
|
||||
}
|
||||
|
||||
if (nextCacheDeleted) {
|
||||
console.log("• Next.js cache cleared successfully");
|
||||
} else {
|
||||
console.log("• Next.js cache clearing skipped (no cache found)");
|
||||
}
|
||||
|
||||
if (indexUpdated) {
|
||||
console.log("• Index page updated with clean slate instructions");
|
||||
} else {
|
||||
console.log("• Index page update skipped or failed");
|
||||
}
|
||||
|
||||
console.log("\n💡 Next steps:");
|
||||
console.log(" • Review the changes in your editor");
|
||||
if (nextCacheDeleted) {
|
||||
console.log(" • Restart your dev server: pnpm dev");
|
||||
} else {
|
||||
console.log(" • Start/restart your dev server: pnpm dev");
|
||||
}
|
||||
if (indexUpdated) {
|
||||
console.log(
|
||||
" • Visit http://localhost:3000/admin to start editing content"
|
||||
);
|
||||
}
|
||||
console.log(" • Test your documentation site");
|
||||
console.log(" • Commit the changes to version control");
|
||||
} catch (error) {
|
||||
console.error("\n❌ Cleanup failed:", error.message);
|
||||
console.error("\n🔧 Troubleshooting:");
|
||||
console.error(" • Make sure you're in your TinaDocs project root");
|
||||
console.error(" • Check that you have write permissions");
|
||||
console.error(" • Ensure the content/ directory structure exists");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Show help if requested
|
||||
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
||||
console.log("TinaDocs API Documentation Cleanup Script\n");
|
||||
console.log("Usage:");
|
||||
console.log(" pnpm run cleanup");
|
||||
console.log("\nOptions:");
|
||||
console.log(" --help, -h Show this help message");
|
||||
console.log("\nDescription:");
|
||||
console.log(
|
||||
" Removes all documentation directories while preserving index.mdx"
|
||||
);
|
||||
console.log(" Deletes all folders in content/docs/ and API schema files.");
|
||||
console.log(" Deletes image asset directories.");
|
||||
console.log(" Clears Next.js cache to prevent stale page references.");
|
||||
console.log(" Cleans up navigation to only show the main index page.");
|
||||
console.log(
|
||||
" Rewrites index.mdx with clean slate instructions and admin link."
|
||||
);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
// Run the cleanup
|
||||
(async () => {
|
||||
await cleanup();
|
||||
})();
|
||||
Reference in New Issue
Block a user