Major changes: - Replace Payload CMS with Tina CMS (self-hosted) - Add Astro DB for consent logging (PDPA compliant) - Update Tailwind v3 to v4 (@tailwindcss/vite plugin) - Add astro-tina-starter template - Rewrite consent template for Astro (ConsentBanner.astro, Astro DB, Nano Stores) - Add install-tina-backend.sh for self-hosted Tina per customer - Rename convert-astro.sh to migrate-tina.sh - Add AGENTS.md template for generated websites - Delete all Payload/Next.js files Technical updates: - Astro DB using defineDb with eq operators for queries - Tailwind v4 with @theme block - Tina CMS local development mode - Proper Astro API routes for consent Research-verified with official documentation (April 2026)
229 lines
5.6 KiB
Bash
Executable File
229 lines
5.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -e
|
|
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m'
|
|
|
|
PROJECT_NAME="${1:-}"
|
|
PROJECT_PATH="${2:-.}"
|
|
|
|
SKILL_DIR="$(dirname "$(dirname "$(readlink -f "$0")")")"
|
|
TEMPLATE_DIR="$SKILL_DIR/templates/astro-tina-starter"
|
|
|
|
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
|
|
log_success() { echo -e "${GREEN}[SUCCESS]${NC} $1"; }
|
|
log_warning() { echo -e "${YELLOW}[WARNING]${NC} $1"; }
|
|
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }
|
|
|
|
print_usage() {
|
|
cat << EOF
|
|
Usage: $(basename "$0") [project-name] [project-path]
|
|
|
|
Create new Astro + Tina CMS project from template
|
|
|
|
Arguments:
|
|
project-name Project name (optional)
|
|
project-path Project location (default: current directory)
|
|
|
|
Examples:
|
|
$(basename "$0") my-website
|
|
$(basename "$0") my-website /path/to/projects/
|
|
|
|
Creates:
|
|
- Astro 6.1.7 framework
|
|
- Tailwind CSS 4.x
|
|
- Tina CMS (self-hosted)
|
|
- Astro DB for consent logging
|
|
- PDPA-compliant consent system
|
|
|
|
EOF
|
|
}
|
|
|
|
check_requirements() {
|
|
log_info "Checking requirements..."
|
|
|
|
if ! command -v git &> /dev/null; then
|
|
log_error "git not found"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v node &> /dev/null; then
|
|
log_error "node.js not found"
|
|
exit 1
|
|
fi
|
|
|
|
NODE_VERSION=$(node -v | cut -d'v' -f2 | cut -d'.' -f1)
|
|
if [ "$NODE_VERSION" -lt 20 ]; then
|
|
log_error "node.js >= 20 required (current: $(node -v))"
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v npm &> /dev/null; then
|
|
log_error "npm not found"
|
|
exit 1
|
|
fi
|
|
|
|
if [ ! -d "$TEMPLATE_DIR" ]; then
|
|
log_error "Template not found: $TEMPLATE_DIR"
|
|
exit 1
|
|
fi
|
|
|
|
log_success "Requirements OK (git, node $(node -v), npm)"
|
|
}
|
|
|
|
setup_directory() {
|
|
local actual_project_path="$PROJECT_PATH"
|
|
|
|
if [ -n "$PROJECT_NAME" ]; then
|
|
actual_project_path="$PROJECT_PATH/$PROJECT_NAME"
|
|
fi
|
|
|
|
mkdir -p "$actual_project_path"
|
|
|
|
if [ "$(ls -A "$actual_project_path" | wc -l)" -gt 0 ]; then
|
|
log_warning "Directory not empty: $actual_project_path"
|
|
read -p "Continue? (y/n): " -n 1 -r
|
|
echo
|
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
|
exit 1
|
|
fi
|
|
fi
|
|
|
|
PROJECT_PATH="$actual_project_path"
|
|
log_info "Project path: $PROJECT_PATH"
|
|
}
|
|
|
|
copy_template() {
|
|
log_info "Copying Astro+Tina template..."
|
|
|
|
cp -r "$TEMPLATE_DIR/"* "$PROJECT_PATH/"
|
|
cp -r "$TEMPLATE_DIR"/.* "$PROJECT_PATH/" 2>/dev/null || true
|
|
|
|
log_success "Template copied"
|
|
}
|
|
|
|
copy_consent_system() {
|
|
log_info "Adding PDPA consent system..."
|
|
|
|
local consent_template="$SKILL_DIR/templates/consent"
|
|
|
|
if [ -d "$consent_template" ]; then
|
|
mkdir -p "$PROJECT_PATH/src/components/consent"
|
|
cp "$consent_template/ConsentBanner.astro" "$PROJECT_PATH/src/components/consent/" 2>/dev/null || true
|
|
cp "$consent_template/stores/"* "$PROJECT_PATH/src/stores/" 2>/dev/null || true
|
|
|
|
mkdir -p "$PROJECT_PATH/src/pages/api"
|
|
cp "$consent_template/api/consent.ts" "$PROJECT_PATH/src/pages/api/" 2>/dev/null || true
|
|
|
|
mkdir -p "$PROJECT_PATH/db"
|
|
cp "$consent_template/db/config.ts" "$PROJECT_PATH/db/" 2>/dev/null || true
|
|
fi
|
|
|
|
log_success "Consent system added"
|
|
}
|
|
|
|
copy_legal_templates() {
|
|
log_info "Copying PDPA legal templates..."
|
|
|
|
mkdir -p "$PROJECT_PATH/src/content/pages"
|
|
|
|
if [ -f "$SKILL_DIR/templates/privacy-policy.md" ]; then
|
|
cp "$SKILL_DIR/templates/privacy-policy.md" "$PROJECT_PATH/src/content/pages/"
|
|
fi
|
|
|
|
if [ -f "$SKILL_DIR/templates/terms-of-service.md" ]; then
|
|
cp "$SKILL_DIR/templates/terms-of-service.md" "$PROJECT_PATH/src/content/pages/"
|
|
fi
|
|
|
|
log_success "Legal templates copied"
|
|
}
|
|
|
|
install_dependencies() {
|
|
log_info "Installing dependencies..."
|
|
|
|
cd "$PROJECT_PATH"
|
|
npm install
|
|
|
|
log_success "Dependencies installed"
|
|
}
|
|
|
|
setup_environment() {
|
|
log_info "Setting up environment..."
|
|
|
|
cd "$PROJECT_PATH"
|
|
|
|
if [ ! -f ".env" ]; then
|
|
if [ -f ".env.example" ]; then
|
|
cp .env.example .env
|
|
log_success "Created .env from .env.example"
|
|
else
|
|
cat > .env << 'EOF'
|
|
PUBLIC_SITE_URL=http://localhost:4321
|
|
TINA_TOKEN=your-tina-token
|
|
EOF
|
|
log_success "Created default .env"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
init_git() {
|
|
log_info "Initializing git..."
|
|
|
|
cd "$PROJECT_PATH"
|
|
|
|
if [ ! -d ".git" ]; then
|
|
git init
|
|
git add .
|
|
git commit -m "Initial commit: Astro + Tina CMS starter"
|
|
log_success "Git initialized"
|
|
fi
|
|
}
|
|
|
|
show_structure() {
|
|
log_info "Project structure:"
|
|
cd "$PROJECT_PATH"
|
|
echo ""
|
|
find . -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.astro" -o -name "*.mjs" -o -name "*.css" -o -name "*.md" -o -name "package.json" \) 2>/dev/null | grep -v node_modules | sort | head -30
|
|
}
|
|
|
|
main() {
|
|
echo "=============================================="
|
|
echo " Astro + Tina CMS Project Creator"
|
|
echo "=============================================="
|
|
echo ""
|
|
|
|
if [ "$1" == "-h" ] || [ "$1" == "--help" ]; then
|
|
print_usage
|
|
exit 0
|
|
fi
|
|
|
|
check_requirements
|
|
setup_directory
|
|
copy_template
|
|
copy_consent_system
|
|
copy_legal_templates
|
|
install_dependencies
|
|
setup_environment
|
|
init_git
|
|
show_structure
|
|
|
|
echo ""
|
|
echo "=============================================="
|
|
log_success "Project created successfully!"
|
|
echo "=============================================="
|
|
echo ""
|
|
echo "Next steps:"
|
|
echo " 1. cd $PROJECT_PATH"
|
|
echo " 2. npm run dev"
|
|
echo " 3. Open http://localhost:4321"
|
|
echo ""
|
|
echo "For Tina CMS admin:"
|
|
echo " - npm run dev"
|
|
echo " - Visit http://localhost:4321/admin"
|
|
echo ""
|
|
}
|
|
|
|
main "$@" |