♻️ refactor(core): Restructure project for better module separation

This commit is contained in:
web@ppanel
2024-12-26 02:53:28 +07:00
parent 17ce96a423
commit 9d0cb8b869
368 changed files with 152606 additions and 47239 deletions
+12
View File
@@ -0,0 +1,12 @@
#!/bin/bash
echo "Cleaning all node_modules, bun.lock, and bun.lockb files..."
# Remove all node_modules directories
find . -name "node_modules" -type d -prune -exec rm -rf '{}' +
# Remove all bun.lock files
find . -name "bun.lock" -type f -delete
# Remove all bun.lockb files
find . -name "bun.lockb" -type f -delete
-27
View File
@@ -1,27 +0,0 @@
#!/bin/bash
# Skip entire script in CI environment
if [ "$CI" = "true" ]; then
echo "CI environment detected, skipping script execution."
exit 0
fi
# Check and install @lobehub/i18n-cli if not installed
if ! npm list -g --depth=0 @lobehub/i18n-cli > /dev/null 2>&1; then
echo "Installing @lobehub/i18n-cli globally..."
npm install -g @lobehub/i18n-cli
else
echo "@lobehub/i18n-cli is already installed."
fi
# Check and install @lobehub/commit-cli if not installed
if ! npm list -g --depth=0 @lobehub/commit-cli > /dev/null 2>&1; then
echo "Installing @lobehub/commit-cli globally..."
npm install -g @lobehub/commit-cli
else
echo "@lobehub/commit-cli is already installed."
fi
# Run lobe-commit -i
echo "Running lobe-commit -i..."
lobe-commit -i
+51 -27
View File
@@ -6,38 +6,62 @@ if [ "$CI" = "true" ]; then
exit 0
fi
# Run Husky installation if not already installed
echo "Setting up Husky..."
# Exit if not a Git repository
if [ ! -d ".git" ]; then
echo "Not a Git repository. Exiting."
exit 1
fi
# Function to set up a Husky hook
setup_husky_hook() {
local hook_name=$1
local hook_content=$2
if [ ! -f ".husky/$hook_name" ]; then
echo "Setting up $hook_name hook..."
echo "$hook_content" > ".husky/$hook_name" || echo "Failed to set up $hook_name hook. Skipping."
chmod +x ".husky/$hook_name" || echo "Failed to make $hook_name hook executable. Skipping."
else
echo "$hook_name hook is already set up."
fi
}
# Ensure Husky is installed and initialized
if [ ! -d ".husky" ]; then
husky
echo "Setting up Husky..."
npx husky || echo "Failed to set up Husky. Skipping."
else
echo "Husky is already set up."
fi
# Set up pre-commit hook if it doesn't exist
if [ ! -f ".husky/pre-commit" ]; then
echo "Setting up pre-commit hook..."
cat > .husky/pre-commit << EOL
#!/bin/sh
. "\$(dirname "\$0")/_/husky.sh"
# Set up pre-commit hook
setup_husky_hook "pre-commit" "#!/bin/sh
. \"\$(dirname \"\$0\")/_/husky.sh\"
npx --no-install lint-staged
EOL
chmod +x .husky/pre-commit
else
echo "pre-commit hook is already set up."
fi
npx --no-install lint-staged"
# Set up commit-msg hook if it doesn't exist
if [ ! -f ".husky/commit-msg" ]; then
echo "Setting up commit-msg hook..."
cat > .husky/commit-msg << EOL
#!/bin/sh
. "\$(dirname "\$0")/_/husky.sh"
# Set up commit-msg hook
setup_husky_hook "commit-msg" "#!/bin/sh
. \"\$(dirname \"\$0\")/_/husky.sh\"
npx --no -- commitlint --edit "\$1"
EOL
chmod +x .husky/commit-msg
else
echo "commit-msg hook is already set up."
fi
npx --no-install commitlint --edit \"\$1\""
# Function to globally install an npm package if not installed
install_global_package() {
local package_name=$1
if ! npm list -g --depth=0 "$package_name" > /dev/null 2>&1; then
echo "Installing $package_name globally..."
npm install -g "$package_name" || echo "Failed to install $package_name globally. Skipping."
else
echo "$package_name is already installed."
fi
}
# Check and install required global npm packages
install_global_package "@lobehub/i18n-cli"
install_global_package "@lobehub/commit-cli"
# Run lobe-commit interactively
echo "Running lobe-commit -i..."
lobe-commit -i || echo "lobe-commit failed. Skipping."
+94
View File
@@ -0,0 +1,94 @@
#!/bin/bash
# Set up directories
OUT_DIR="out"
# Clean up any existing build artifacts
rm -rf $OUT_DIR
mkdir -p $OUT_DIR
# Declare an array of projects to build
PROJECTS=(
"ppanel-admin-web:apps/admin:3001"
"ppanel-user-web:apps/user:3002"
)
# Step 1: Install dependencies
bun install || {
echo "Dependency installation failed"
exit 1
}
# Function to extract variables from .env.template
extract_env_variables() {
local TEMPLATE_PATH=$1
local DEFAULT_PORT=$2
local ENV_VARS=" NODE_ENV: 'production'," # Start with NODE_ENV
ENV_VARS="$ENV_VARS\n PORT: $DEFAULT_PORT," # Add default port
if [[ -f $TEMPLATE_PATH ]]; then
while IFS= read -r line; do
# Ignore empty lines and comments
if [[ ! -z "$line" && ! $line =~ ^# ]]; then
VAR_NAME=$(echo $line | cut -d'=' -f1)
VAR_VALUE=$(echo $line | cut -d'=' -f2-)
ENV_VARS="$ENV_VARS\n $VAR_NAME: '$VAR_VALUE'," # Add new line for each variable
fi
done < "$TEMPLATE_PATH"
fi
# Remove the trailing comma
ENV_VARS=${ENV_VARS%,}
echo -e "$ENV_VARS"
}
# Step 2: Build each project using Turbo
for ITEM in "${PROJECTS[@]}"; do
IFS=":" read -r PROJECT PROJECT_PATH DEFAULT_PORT <<< "$ITEM"
echo "Building project: $PROJECT (Path: $PROJECT_PATH)"
bun run build --filter=$PROJECT || {
echo "Build failed for $PROJECT"
exit 1
}
# Extract environment variables
ENV_TEMPLATE_PATH="$PROJECT_PATH/.env.template"
ENV_VARS=$(extract_env_variables "$ENV_TEMPLATE_PATH" "$DEFAULT_PORT")
# Copy build output and static resources to the build directory
PROJECT_BUILD_DIR=$OUT_DIR/$PROJECT
mkdir -p $PROJECT_BUILD_DIR
cp -r $PROJECT_PATH/.next/standalone/. $PROJECT_BUILD_DIR/
mkdir -p $PROJECT_BUILD_DIR/$PROJECT_PATH/.next/static
cp -r $PROJECT_PATH/.next/static/ $PROJECT_BUILD_DIR/$PROJECT_PATH/.next/static
mkdir -p $PROJECT_BUILD_DIR/$PROJECT_PATH/public
cp -r $PROJECT_PATH/public/ $PROJECT_BUILD_DIR/$PROJECT_PATH/public
# Generate ecosystem.config.js for the project
ECOSYSTEM_CONFIG="$PROJECT_BUILD_DIR/ecosystem.config.js"
cat > $ECOSYSTEM_CONFIG << EOL
module.exports = {
apps: [
{
name: "$PROJECT",
script: "$PROJECT_PATH/server.js",
env: {
$ENV_VARS
}
}
]
};
EOL
echo "PM2 configuration created: $ECOSYSTEM_CONFIG"
# Create a tar.gz archive for each project
ARCHIVE_NAME="$OUT_DIR/$PROJECT.tar.gz"
tar -czvf $ARCHIVE_NAME -C $PROJECT_BUILD_DIR . || {
echo "Archiving failed for $PROJECT"
exit 1
}
echo "Archive created: $ARCHIVE_NAME"
done
# Final output
echo "All projects have been built, archived, and individual PM2 configuration files generated in their respective directories."
-167
View File
@@ -1,167 +0,0 @@
import { spawn } from 'child_process';
import { readdir, readFile, rm, writeFile } from 'fs/promises';
import { dirname, join, resolve } from 'path';
import { fileURLToPath } from 'url';
// Get the directory of the current script
const scriptDir = dirname(fileURLToPath(import.meta.url));
// Set the target directory to `../packages/shadcn` relative to the script directory
const targetDir = resolve(scriptDir, '../packages/shadcn');
// Define replacements based on the directory type
const replacementsByDirectory = {
components: [
{ from: '@/lib/utils', to: '../../lib/utils' },
{ from: '@/components/ui', to: '.' },
{ from: '@/hooks', to: '../../hooks' },
{ from: '@/data', to: '../../data' },
],
hooks: [{ from: '@/components', to: '../components' }],
};
// Recursively fetch all files in a directory
async function getAllFiles(dir) {
let files = [];
const entries = await readdir(dir, { withFileTypes: true });
for (const entry of entries) {
const fullPath = join(dir, entry.name);
if (entry.isDirectory()) {
// If directory, recursively get files inside it
files = [...files, ...(await getAllFiles(fullPath))];
} else {
// If file, add to the files array
files.push(fullPath);
}
}
return files;
}
// Perform replacements in a single file
async function replaceInFile(filePath) {
let content = await readFile(filePath, 'utf8');
let modified = false;
// Add ts-ignore at the top of the file
if (!content.startsWith('// @ts-nocheck')) {
content = `// @ts-nocheck\n${content}`;
}
// Determine the appropriate replacement set based on the directory
let replacements;
if (filePath.includes(`${join('src', 'components')}`)) {
replacements = replacementsByDirectory.components;
} else if (filePath.includes(`${join('src', 'hooks')}`)) {
replacements = replacementsByDirectory.hooks;
} else {
replacements = replacementsByDirectory.default;
}
replacements?.forEach(({ from, to }) => {
if (content.includes(from)) {
// Replace all occurrences of `from` with `to`
content = content.replace(new RegExp(from, 'g'), to);
modified = true;
}
});
if (modified) {
await writeFile(filePath, content, 'utf8');
console.log(`Updated: ${filePath}`);
}
}
// Run replacements in all files within a directory
async function replaceInFiles(dir) {
try {
const files = await getAllFiles(dir);
for (const file of files) {
await replaceInFile(file);
}
console.log('All files updated successfully.');
} catch (error) {
console.error('Error updating files:', error.message);
}
}
function runCommand(command, args, options) {
return new Promise((resolve, reject) => {
const process = spawn(command, args, options);
process.stdout.on('data', (data) => {
const message = data.toString();
console.log(`stdout: ${message}`);
});
process.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
process.on('close', (code) => {
if (code === 0) {
console.log(`Process completed successfully with code: ${code}`);
resolve();
} else {
reject(new Error(`Process exited with code: ${code}`));
}
});
process.on('error', (error) => {
reject(error);
});
process.stdin.end();
});
}
async function installComponents() {
try {
console.log('Installing all default Shadcn components in directory:', targetDir);
const registry = await fetch('https://ui.aceternity.com/registry');
const registryJson = await registry.json();
const components = registryJson
.filter(
(item) =>
!['card-spotlight', 'canvas-reveal-effect', 'sparkles', 'cover'].includes(item.name),
)
.map((item) => `https://ui.aceternity.com/registry/${item.name}.json`);
// Install AceternityUI a Shadcn components
await runCommand('npx', ['shadcn@latest', 'add', ...components], {
cwd: targetDir,
shell: true,
});
// Install all default Shadcn components
await runCommand('npx', ['shadcn@latest', 'add', '-y', '-o', '-a'], {
cwd: targetDir,
shell: true,
});
console.log('All components successfully installed');
// Replace paths in installed files
const targetSrcDir = join(targetDir, 'src');
console.log('Replacing paths in target directory:', targetSrcDir);
await replaceInFiles(targetSrcDir);
// Step 3: Remove `example` and `blocks` directories from `components`
const componentsDir = join(targetSrcDir, 'components');
const exampleDir = join(componentsDir, 'example');
const blocksDir = join(componentsDir, 'blocks');
console.log('Removing example and blocks directories...');
await Promise.all([
rm(exampleDir, { recursive: true, force: true }),
rm(blocksDir, { recursive: true, force: true }),
]);
console.log('Example and blocks directories removed successfully.');
} catch (error) {
console.error('An error occurred during the installation process:', error.message);
console.error(error.stack);
}
}
// Run the installation function
installComponents();
+14
View File
@@ -0,0 +1,14 @@
##!/bin/bash
# Update dependencies in root directory
echo "Updating dependencies in root directory..."
bun update --latest
# Update dependencies in packages and apps directories
for dir in ./packages/* ./apps/*; do
if [ -d "$dir" ]; then
echo "Updating dependencies in $dir..."
(cd "$dir" && bun update --latest)
fi
done
+8
View File
@@ -0,0 +1,8 @@
#!/bin/bash
cd apps/user
bunx --bun shadcn@canary add -a -o
bunx --bun shadcn@canary add https://ui.aceternity.com/registry/timeline.json -o
bunx --bun shadcn@canary add https://ui.aceternity.com/registry/text-generate-effect.json -o
bunx --bun shadcn@canary add https://ui.aceternity.com/registry/hover-border-gradient.json -o