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
2 changes: 1 addition & 1 deletion api/src/config/prod.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ export const prodConfig = {
GCP_NA: "https://gcp-na-app.contentstack.com/#!",
},
LOG_FILE_PATH:
process.platform === "win32" ? ".\\combine.log" : "./combine.log", // Replace with the actual path to your log file
process.platform === "win32" ? ".\\sample.log" : "./sample.log", // Replace with the actual path to your log file
};
3 changes: 2 additions & 1 deletion api/src/models/FieldMapper.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { JSONFile } from "lowdb/node";
import LowWithLodash from "../utils/lowdb-lodash.utils.js";
import path from "path";

/**
* Represents the advanced configuration options for a field mapper.
Expand Down Expand Up @@ -44,7 +45,7 @@ const defaultData: FieldMapper = { field_mapper: [] };
* Represents the database instance for the FieldMapper model.
*/
const db = new LowWithLodash(
new JSONFile<FieldMapper>("database/field-mapper.json"),
new JSONFile<FieldMapper>(path.join(process.cwd(), "database", "field-mapper.json")),
defaultData
);

Expand Down
3 changes: 2 additions & 1 deletion api/src/models/contentTypesMapper-lowdb.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { JSONFile } from "lowdb/node";
import path from 'path';
import LowWithLodash from "../utils/lowdb-lodash.utils.js";

/**
Expand Down Expand Up @@ -80,7 +81,7 @@ const defaultData: ContentTypeMapperDocument = { ContentTypesMappers: [] };
* Represents the database instance for the content types mapper.
*/
const db = new LowWithLodash(
new JSONFile<ContentTypeMapperDocument>("database/contentTypesMapper.json"),
new JSONFile<ContentTypeMapperDocument>(path.join(process.cwd(), "database", 'contentTypesMapper.json')),
defaultData
);

Expand Down
2 changes: 1 addition & 1 deletion api/src/models/project-lowdb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ interface Project {
test_stacks: [];
current_test_stack_id: string;
legacy_cms: LegacyCMS;
content_mapper: [];
content_mapper: any[];
execution_log: [ExecutionLog];
created_at: string;
updated_at: string;
Expand Down
68 changes: 40 additions & 28 deletions api/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,30 +19,48 @@ import migrationRoutes from "./routes/migration.routes.js";
import chokidar from "chokidar";
import { Server } from "socket.io";
import fs from "fs";
import path from "path";

// Initialize file watcher for the log file
const watcher = chokidar.watch(config.LOG_FILE_PATH, {
usePolling: true, // Enables polling to detect changes in all environments
interval: 100, // Poll every 100ms (you can adjust this if needed)
interval: 1, // Poll every 100ms (you can adjust this if needed)
awaitWriteFinish: { // Wait for file to finish being written before triggering
stabilityThreshold: 500, // Time to wait before considering the file stable
pollInterval: 100, // Interval at which to poll for file stability
stabilityThreshold: 1, // Time to wait before considering the file stable
pollInterval: 1, // Interval at which to poll for file stability
},
persistent: true, // Keeps watching the file even after initial change
}); // Initialize with initial log path

let io: Server; // Socket.IO server instance

// Dynamically change the log file path and update the watcher
export async function setLogFilePath(path: string) {
console.info(`Setting new log file path: ${path}`);

// Stop watching the old log file
watcher.unwatch(config.LOG_FILE_PATH);

// Update the config and start watching the new log file
config.LOG_FILE_PATH = path;
watcher.add(path);
export async function setLogFilePath(newPath: string) {
try {
// Ensure the new log file path is absolute and valid
const absolutePath = path.resolve(newPath);
console.info(`Attempting to set new log file path: ${absolutePath}`);
// Check if the new log file exists
// Stop watching the old log file
if (config.LOG_FILE_PATH) {
console.info(`Stopping watcher for previous log file: ${config.LOG_FILE_PATH}`);
watcher.unwatch(config.LOG_FILE_PATH);
}
// Update the config to use the new log file path
config.LOG_FILE_PATH = absolutePath;

// Start watching the new log file
console.info(`Starting watcher for new log file: ${absolutePath}`);
watcher.add(absolutePath);

} catch (error: any) {
console.error(`Failed to set new log file path: ${error.message}`);
// Optional: fallback to default or previous log file if the new path is invalid
if (config.LOG_FILE_PATH) {
console.info(`Reverting to previous log file path: ${config.LOG_FILE_PATH}`);
watcher.add(config.LOG_FILE_PATH); // Re-watch previous log file
}
}
}

try {
Expand Down Expand Up @@ -99,26 +117,20 @@ try {
});

// Emit initial log file content to connected clients

// File watcher for log file changes
watcher.on("change", (path) => {
// File watcher for log file changes
watcher.on("change", async (path) => {
console.info(`File changed: ${path}`);
// Read the updated file content
fs.readFile(path, "utf8", (err, data) => {
if (err) {
logger.error(`Error reading log file: ${err}`);
return;
}
try {
// Emit the updated log content to connected clients
io.emit("logUpdate", data);
} catch (error) {
logger.error(`Error emitting log data: ${error}`);
}
});
try {
const data = await fs.promises.readFile(path, "utf8")
// Emit the updated log content to connected clients
io.emit("logUpdate", data);
} catch (error) {
logger.error(`Error emitting log data: ${error}`);
}
});

})();

} catch (e) {
logger.error("Error while starting the server!");
logger.error(e);
Expand Down
18 changes: 10 additions & 8 deletions api/src/services/contentMapper.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ const putTestData = async (req: Request) => {
const projectId = req.params.projectId;
const contentTypes = req.body.contentTypes;


await FieldMapperModel.read();

/*
Expand Down Expand Up @@ -61,7 +62,7 @@ const putTestData = async (req: Request) => {
});

await ContentTypesMapperModelLowdb.read();
const contentIds: string[] = [];
const contentIds: any[] = [];

/*
this code snippet is iterating over an array called contentTypes and
Expand All @@ -70,7 +71,7 @@ const putTestData = async (req: Request) => {
and the generated id values are pushed into the contentIds array.
*/
const contentType = contentTypes.map((item: any) => {
const id = item?.id.replace(/[{}]/g, "")?.toLowerCase() || uuidv4();
const id = item?.id?.replace(/[{}]/g, "")?.toLowerCase() || uuidv4();
item.id = id;
contentIds.push(id);
return { ...item, id, projectId };
Expand All @@ -88,11 +89,12 @@ const putTestData = async (req: Request) => {
.get("projects")
.findIndex({ id: projectId })
.value();
if (index > -1) {
ProjectModelLowdb.update((data: any) => {
data.projects[index].content_mapper = contentIds;
data.projects[index].extract_path = req?.body?.extractPath;
});
if (index > -1 && contentIds?.length) {
ProjectModelLowdb.data.projects[index].content_mapper = contentIds;
ProjectModelLowdb.data.projects[index].extract_path = req?.body?.extractPath;
ProjectModelLowdb.write();
} else {
throw new BadRequestError(HTTP_TEXTS.CONTENT_TYPE_NOT_FOUND);
}

const pData = ProjectModelLowdb.chain
Expand Down Expand Up @@ -900,7 +902,7 @@ const getSingleGlobalField = async (req: Request) => {
},
})
);

if (err)
return {
data: err.response.data,
Expand Down
24 changes: 18 additions & 6 deletions api/src/services/migration.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Request } from "express";
import path from "path";
import ProjectModelLowdb from "../models/project-lowdb.js";
import { config } from "../config/index.js";
import { safePromise, getLogMessage } from "../utils/index.js";
Expand All @@ -12,6 +13,9 @@ import { fieldAttacher } from "../utils/field-attacher.utils.js";
import { siteCoreService } from "./sitecore.service.js";
import { testFolderCreator } from "../utils/test-folder-creator.utils.js";
import { utilsCli } from './runCli.service.js';
import customLogger from "../utils/custom-logger.utils.js";
import { setLogFilePath } from "../server.js";




Expand Down Expand Up @@ -208,12 +212,16 @@ const startTestMigration = async (req: Request): Promise<any> => {
const project = ProjectModelLowdb.chain.get("projects").find({ id: projectId }).value();
const packagePath = project?.extract_path;
if (packagePath && project?.current_test_stack_id) {
const loggerPath = path.join(process.cwd(), 'logs', projectId, `${project?.current_test_stack_id}.log`);
const message = getLogMessage('startTestMigration', 'Starting Test Migration...', {});
await customLogger(projectId, project?.current_test_stack_id, 'info', message);
await setLogFilePath(loggerPath);
const contentTypes = await fieldAttacher({ orgId, projectId, destinationStackId: project?.current_test_stack_id });
await siteCoreService?.createEntry({ packagePath, contentTypes, destinationStackId: project?.current_test_stack_id });
await siteCoreService?.createLocale(req, project?.current_test_stack_id);
await siteCoreService?.createEntry({ packagePath, contentTypes, destinationStackId: project?.current_test_stack_id, projectId });
await siteCoreService?.createLocale(req, project?.current_test_stack_id, projectId);
await siteCoreService?.createVersionFile(project?.current_test_stack_id);
await testFolderCreator?.({ destinationStackId: project?.current_test_stack_id });
await utilsCli?.runCli(region, user_id, project?.current_test_stack_id, projectId, true);
await utilsCli?.runCli(region, user_id, project?.current_test_stack_id, projectId, true, loggerPath);
}
}

Expand All @@ -230,11 +238,15 @@ const startMigration = async (req: Request): Promise<any> => {
const project = ProjectModelLowdb.chain.get("projects").find({ id: projectId }).value();
const packagePath = project?.extract_path;
if (packagePath && project?.destination_stack_id) {
const loggerPath = path.join(process.cwd(), 'logs', projectId, `${project?.destination_stack_id}.log`);
const message = getLogMessage('startTestMigration', 'Starting Migration...', {});
await customLogger(projectId, project?.destination_stack_id, 'info', message);
await setLogFilePath(loggerPath);
const contentTypes = await fieldAttacher({ orgId, projectId, destinationStackId: project?.destination_stack_id });
await siteCoreService?.createEntry({ packagePath, contentTypes, destinationStackId: project?.destination_stack_id });
await siteCoreService?.createLocale(req, project?.destination_stack_id);
await siteCoreService?.createEntry({ packagePath, contentTypes, destinationStackId: project?.destination_stack_id, projectId });
await siteCoreService?.createLocale(req, project?.destination_stack_id, projectId);
await siteCoreService?.createVersionFile(project?.destination_stack_id);
await utilsCli?.runCli(region, user_id, project?.destination_stack_id, projectId);
await utilsCli?.runCli(region, user_id, project?.destination_stack_id, projectId, false, loggerPath);
}
}

Expand Down
10 changes: 5 additions & 5 deletions api/src/services/runCli.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@ import path from "path";
import fs from 'fs';
import shell from 'shelljs'
import { v4 } from "uuid";
import { setLogFilePath } from "../server.js";
import { copyDirectory, createDirectoryAndFile } from '../utils/index.js'
import { CS_REGIONS } from "../constants/index.js";
import ProjectModelLowdb from "../models/project-lowdb.js";
import AuthenticationModel from "../models/authentication.js";
import watchLogs from "../utils/watch.utils.js";
import { setLogFilePath } from "../server.js";

const addCustomMessageInCliLogs = async (loggerPath: string, level: string = 'info', message: string) => {
try {
Expand All @@ -22,8 +23,7 @@ const addCustomMessageInCliLogs = async (loggerPath: string, level: string = 'in
}
}


export const runCli = async (rg: string, user_id: string, stack_uid: any, projectId: string, isTest = false) => {
export const runCli = async (rg: string, user_id: string, stack_uid: any, projectId: string, isTest = false, transformePath: string) => {
try {
const regionPresent = CS_REGIONS?.find((item: string) => item === rg) ?? 'NA';
await AuthenticationModel.read();
Expand All @@ -36,10 +36,10 @@ export const runCli = async (rg: string, user_id: string, stack_uid: any, projec
const backupPath = path.join(process.cwd(), 'migration-data', `${stack_uid}_${v4().slice(0, 4)}`);
await copyDirectory(sourcePath, backupPath);
const loggerPath = path.join(backupPath, 'logs', 'import', 'success.log');
createDirectoryAndFile(loggerPath);
await createDirectoryAndFile(loggerPath, transformePath);
await setLogFilePath(loggerPath);
await watchLogs(loggerPath, transformePath);
shell.cd(path.join(process.cwd(), '..', 'cli', 'packages', 'contentstack'));
shell.exec('pwd');
shell.exec(`node bin/run config:set:region ${regionPresent}`);
shell.exec(`node bin/run login -a ${userData?.authtoken} -e ${userData?.email}`);
const importData = shell.exec(`node bin/run cm:stacks:import -k ${stack_uid} -d ${sourcePath} --backup-dir=${backupPath} --yes`, { async: true });
Expand Down
Loading