Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions api/src/config/dev.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@ export const devConfig = {
EU: "https://stag-eu-api.csnonprod.com/v3",
AZURE_NA: "https://stag-azure-na-api.csnonprod.com/v3",
GCP_NA: "https://stag-gcp-na-api.csnonprod.com/v3",
AU:"https://stag-au-api.csnonprod.com/v3",
GCP_EU: "https://stag-gcp-eu-api.csnonprod.com/v3",
},
CS_URL: {
NA: "https://app.contentstack.com/#!",
EU: "https://eu-app.contentstack.com/#!",
AZURE_NA: "https://azure-na-app.contentstack.com/#!",
AZURE_EU: "https://azure-eu-app.contentstack.com/#!",
GCP_NA: "https://gcp-na-app.contentstack.com/#!",
AU: "https://au-app.contentstack.com/#!",
GCP_EU: "https://gcp-eu-app.contentstack.com/#!",
},
LOG_FILE_PATH:
process.platform === "win32" ? ".\\combine.log" : "./combine.log", // Replace with the actual path to your log file
Expand Down
4 changes: 4 additions & 0 deletions api/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,17 @@ export type ConfigType = {
AZURE_NA: string;
AZURE_EU?: string;
GCP_NA?: string;
AU?: string;
GCP_EU?: string;
};
CS_URL: {
NA: string;
EU: string;
AZURE_NA: string;
AZURE_EU?: string;
GCP_NA?: string;
AU?: string;
GCP_EU?: string;
};
LOG_FILE_PATH: string;
};
Expand Down
4 changes: 4 additions & 0 deletions api/src/config/prod.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,17 @@ export const prodConfig = {
AZURE_NA: "https://azure-na-api.contentstack.com/v3",
AZURE_EU: "https://azure-eu-api.contentstack.com/v3",
GCP_NA: "https://gcp-na-api.contentstack.com/v3",
AU: "https://au-api.contentstack.com/v3",
GCP_EU: "https://gcp-eu-api.contentstack.com/v3",
},
CS_URL: {
NA: "https://app.contentstack.com/#!",
EU: "https://eu-app.contentstack.com/#!",
AZURE_NA: "https://azure-na-app.contentstack.com/#!",
AZURE_EU: "https://azure-eu-app.contentstack.com/#!",
GCP_NA: "https://gcp-na-app.contentstack.com/#!",
AU: "https://au-app.contentstack.com/#!",
GCP_EU: "https://gcp-eu-app.contentstack.com/#!",
},
LOG_FILE_PATH:
process.platform === "win32" ? ".\\sample.log" : "./sample.log", // Replace with the actual path to your log file
Expand Down
4 changes: 3 additions & 1 deletion api/src/constants/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
export const CS_REGIONS = ["NA", "EU", "AZURE_NA", "AZURE_EU", "GCP_NA"];
export const CS_REGIONS = ["NA", "EU", "AZURE_NA", "AZURE_EU", "GCP_NA", "AU", "GCP_EU"];
export const DEVURLS: any = {
NA: "developerhub-api.contentstack.com",
EU: "eu-developerhub-api.contentstack.com",
AZURE_NA: "azure-na-developerhub-api.contentstack.com",
AZURE_EU: "azure-eu-developerhub-api.contentstack.com",
GCP_NA: "gcp-na-developerhub-api.contentstack.com",
AU: "au-developerhub-api.contentstack.com",
GCP_EU: "gcp-eu-developerhub-api.contentstack.com",
};
export const CMS = {
CONTENTFUL: "contentful",
Expand Down
15 changes: 15 additions & 0 deletions api/src/services/aem.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,21 @@ function processFieldsRecursive(
obj[uid] = jsonData;
break;
}
case 'html': {
const aemFieldName = field?.otherCmsField ? getLastKey(field?.otherCmsField, ' > ') : field?.uid;
const value = getFieldValue(items, aemFieldName);
const uid = getLastKey(field?.contentstackFieldUid);

let htmlContent = '';

if (typeof value === 'string') {
htmlContent = value;
} else if (value && typeof value === 'object') {
htmlContent = value?.text || value?.content || '';
}
obj[uid] = htmlContent;
break;
}
case 'link': {
const value = {
title: getFieldValue(items, 'title') ?? '',
Expand Down
44 changes: 39 additions & 5 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
version: "3.8"

services:
api:
container_name: migration-api
build:
context: ./api
ports:
- "5001:5001"
restart: always
restart: unless-stopped
volumes:
- ${CMS_DATA_PATH}:${CONTAINER_PATH}
- ${DOCKER_MOUNT_PATH:-${CMS_DATA_PATH}}:${CONTAINER_PATH}:ro
- shared_data:/app/extracted_files
environment:
- NODE_ENV=${NODE_ENV:-production}
- CMS_TYPE=${CMS_TYPE}
- CONTAINER_PATH=${CONTAINER_PATH}
- CMS_DATA_PATH=${CMS_DATA_PATH}
- AEM_TEMPLATES_DIR=${AEM_TEMPLATES_DIR:-templates}
networks:
- migration-network
security_opt:
- no-new-privileges:true

Expand All @@ -19,22 +28,47 @@ services:
context: ./upload-api
ports:
- "4002:4002"
restart: always
restart: unless-stopped
volumes:
- ${CMS_DATA_PATH}:${CONTAINER_PATH}
- ${DOCKER_MOUNT_PATH:-${CMS_DATA_PATH}}:${CONTAINER_PATH}:ro
- shared_data:/app/extracted_files
environment:
- NODE_ENV=${NODE_ENV:-production}
- CMS_TYPE=${CMS_TYPE}
- CONTAINER_PATH=${CONTAINER_PATH}
- CMS_DATA_PATH=${CMS_DATA_PATH}
- NODE_BACKEND_API=${NODE_BACKEND_API:-http://migration-api:5001}
- AEM_TEMPLATES_DIR=${AEM_TEMPLATES_DIR:-templates}
networks:
- migration-network
security_opt:
- no-new-privileges:true
depends_on:
- api

ui:
container_name: migration-ui
build:
context: ./ui
ports:
- "3000:3000"
restart: always
restart: unless-stopped
environment:
- NODE_ENV=${NODE_ENV:-production}
- REACT_APP_API_URL=${REACT_APP_API_URL:-http://localhost:5001}
- REACT_APP_UPLOAD_API_URL=${REACT_APP_UPLOAD_API_URL:-http://localhost:4002}
networks:
- migration-network
security_opt:
- no-new-privileges:true
depends_on:
- api
- upload-api

networks:
migration-network:
driver: bridge

volumes:
shared_data:
driver: local
117 changes: 98 additions & 19 deletions setup-docker.sh
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/bin/bash

echo "Choose the CMS (numbers):"
select CMS_TYPE in "sitecore" "contentful" "wordpress"; do
select CMS_TYPE in "sitecore" "contentful" "wordpress" "aem"; do
case $CMS_TYPE in
sitecore)
EXAMPLE_FILE="sitecore.zip"
Expand All @@ -15,20 +15,26 @@ select CMS_TYPE in "sitecore" "contentful" "wordpress"; do
EXAMPLE_FILE="wordpress.xml"
break
;;
aem)
EXAMPLE_FILE="aem_data_structure"
break
;;
*)
echo "Invalid option. Please select 1, 2, or 3."
echo "Invalid option. Please select 1, 2, 3, or 4."
;;
esac
done

read -p "Enter the full path to your $CMS_TYPE data file (e.g., $EXAMPLE_FILE): " CMS_DATA_PATH

# Remove surrounding quotes if they exist
CMS_DATA_PATH="${CMS_DATA_PATH%\"}"
CMS_DATA_PATH="${CMS_DATA_PATH#\"}"
# Prompt for the CMS data path
echo "Enter the path to your $CMS_TYPE data:"
if [[ "$CMS_TYPE" == "aem" ]]; then
echo "(Path should contain a 'templates' folder with JSON files, or provide direct path to templates folder)"
fi
read -r CMS_DATA_PATH

# Store original Windows path for Docker volume mounting
# Store original path for Docker (Windows paths work with Docker Desktop)
ORIGINAL_PATH="$CMS_DATA_PATH"
DOCKER_MOUNT_PATH="$CMS_DATA_PATH" # Path to mount in Docker

# Convert Windows path to Unix format for Git Bash file operations ONLY
UNIX_PATH="$CMS_DATA_PATH"
Expand All @@ -39,15 +45,60 @@ if [[ "$CMS_DATA_PATH" =~ ^[A-Za-z]:\\ ]]; then
UNIX_PATH=$(echo "$UNIX_PATH" | sed 's/^\([A-Za-z]\):/\/\L\1/')
fi

# Check if file exists using the converted path
if [ ! -f "$UNIX_PATH" ]; then
echo "❌ File does not exist: $UNIX_PATH"
exit 1
# Check if file/directory exists using the converted path
if [[ "$CMS_TYPE" == "aem" ]]; then
# For AEM, check if it's a directory
if [ ! -d "$UNIX_PATH" ]; then
echo "❌ Directory does not exist: $UNIX_PATH"
echo "Please provide the path to your AEM data structure folder"
exit 1
fi

# Check if the provided path IS the templates folder
if [[ "$(basename "$UNIX_PATH")" == "templates" ]]; then
# User provided the templates folder directly
TEMPLATES_PATH="$UNIX_PATH"
# Get parent directory for Docker mounting
UNIX_MOUNT_PATH="$(dirname "$UNIX_PATH")"
DOCKER_MOUNT_PATH="$(dirname "$ORIGINAL_PATH")"
echo "ℹ️ Detected direct templates path, using parent folder for Docker mounting"
else
# User provided the parent folder
TEMPLATES_PATH="$UNIX_PATH/templates"
UNIX_MOUNT_PATH="$UNIX_PATH"

# Verify templates folder exists
if [ ! -d "$TEMPLATES_PATH" ]; then
echo "❌ 'templates' folder not found in: $UNIX_PATH"
echo "Expected structure: your-folder/templates/*.json"
echo "Or provide the direct path to the templates folder"
exit 1
fi
fi

# Check if templates folder contains JSON files
JSON_COUNT=$(find "$TEMPLATES_PATH" -maxdepth 1 -name "*.json" -type f 2>/dev/null | wc -l)
if [ "$JSON_COUNT" -eq 0 ]; then
echo "❌ No JSON files found in templates folder: $TEMPLATES_PATH"
echo "Please ensure your templates folder contains template JSON files"
exit 1
fi

echo "✅ Found $JSON_COUNT JSON template file(s) in templates folder"

FILENAME=$(basename "$UNIX_MOUNT_PATH")
CONTAINER_PATH="/data/$FILENAME"
else
# For other CMS types, check if it's a file
if [ ! -f "$UNIX_PATH" ]; then
echo "❌ File does not exist: $UNIX_PATH"
exit 1
fi

FILENAME=$(basename "$UNIX_PATH")
CONTAINER_PATH="/data/$FILENAME"
fi

FILENAME=$(basename "$UNIX_PATH")
CONTAINER_PATH="/data/$FILENAME"

export CMS_TYPE
export CMS_DATA_PATH="$ORIGINAL_PATH"
export CONTAINER_PATH
Expand All @@ -73,11 +124,19 @@ set_env_var() {
}

set_env_var "CMS_TYPE" "$CMS_TYPE"
# Use original Windows path for Docker volume mounting
# Save the full path to templates (what user provided)
set_env_var "CMS_DATA_PATH" "$ORIGINAL_PATH"
# Save the Docker mount path (may be parent directory for AEM)
set_env_var "DOCKER_MOUNT_PATH" "$DOCKER_MOUNT_PATH"
set_env_var "CONTAINER_PATH" "$CONTAINER_PATH"
set_env_var "NODE_BACKEND_API" "http://migration-api:5001"

# Set AEM-specific environment variables
if [[ "$CMS_TYPE" == "aem" ]]; then
set_env_var "AEM_TEMPLATES_DIR" "templates"
echo "ℹ️ Set AEM_TEMPLATES_DIR to: templates"
fi

# Check if docker-compose.yml exists before running
if [ ! -f "docker-compose.yml" ]; then
echo "❌ docker-compose.yml not found in current directory"
Expand All @@ -87,10 +146,30 @@ if [ ! -f "docker-compose.yml" ]; then
exit 1
fi

# Check if Docker is running
if ! docker info > /dev/null 2>&1; then
echo ""
echo "❌ Docker is not running!"
echo "Please start Docker Desktop and try again."
exit 1
fi

echo ""
echo "✅ Starting Docker Compose with the following configuration:"
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo "CMS_TYPE: $CMS_TYPE"
echo "CMS_DATA_PATH (for Docker): $ORIGINAL_PATH"
echo "CMS_DATA_PATH (for file check): $UNIX_PATH"
echo "CONTAINER_PATH: $CONTAINER_PATH"
echo "CMS_DATA_PATH: $ORIGINAL_PATH"
if [[ "$CMS_TYPE" == "aem" ]]; then
echo "DOCKER_MOUNT_PATH: $DOCKER_MOUNT_PATH"
echo "CONTAINER_PATH: $CONTAINER_PATH"
echo "Templates accessible at: $CONTAINER_PATH/templates"
else
echo "CONTAINER_PATH: $CONTAINER_PATH"
fi
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
echo ""

# Export for docker-compose
export DOCKER_MOUNT_PATH

MSYS_NO_PATHCONV=1 docker compose up --build
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,13 @@ export class BreadcrumbComponent extends ContentstackComponent {
uid: key,
displayName: key,
description: "",
defaultValue: schemaProp.value
defaultValue: ""
}).toContentstack(),
boolean: (key, schemaProp) => new BooleanField({
uid: key,
displayName: key,
description: "",
defaultValue: schemaProp.value
defaultValue: false
}).toContentstack(),
object: (key, schemaProp) => {
// For breadcrumb, handle the link object
Expand All @@ -44,7 +44,7 @@ export class BreadcrumbComponent extends ContentstackComponent {
uid: key,
displayName: key,
description: "",
defaultValue: schemaProp?.properties?.url?.value
defaultValue: ""
}).toContentstack();
}
return null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,14 @@ export class ButtonComponent extends ContentstackComponent {
uid: key,
displayName: key,
description: "",
defaultValue: schemaProp.value
defaultValue: false
}).toContentstack(),
integer: (key, schemaProp) => new TextField({
uid: key,
displayName: key,
description: "",
isNumber: true,
defaultValue: schemaProp.value
defaultValue: ""
}).toContentstack(),
object: (key, schemaProp) => {
const urlValue = schemaProp?.properties?.url?.value;
Expand All @@ -67,7 +67,7 @@ export class ButtonComponent extends ContentstackComponent {
uid: key,
displayName: key,
description: "",
defaultValue: urlValue
defaultValue: ""
}).toContentstack();
}
return null;
Expand Down
Loading