Skip to content
Merged

Dev #305

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
f4f8cb5
removed csdx utilities code
RohitKini Sep 12, 2024
817163a
Merge branch 'dev' of https://github.com/contentstack/migration-v2-no…
RohitKini Sep 16, 2024
f14ecdd
added updated code
umeshmore45 Sep 16, 2024
049724c
Merge branch 'feature/merge_two' of https://github.com/contentstack/m…
RohitKini Sep 16, 2024
1c49aa6
added uid
umeshmore45 Sep 17, 2024
61d9485
logger functionality
RohitKini Sep 18, 2024
c8206fd
Merge branch 'feature/merge_two' of https://github.com/contentstack/m…
RohitKini Sep 18, 2024
4ff1b0a
logger functionality
RohitKini Sep 18, 2024
3bf2249
logger functionality
RohitKini Sep 18, 2024
461362d
added updated code
umeshmore45 Sep 19, 2024
5c605e6
added cli code
umeshmore45 Sep 19, 2024
74d321d
added bin
umeshmore45 Sep 19, 2024
a26cd52
Merge branch 'dev' of https://github.com/contentstack/migration-v2-no…
RohitKini Sep 24, 2024
c456e3e
stacks limit check
RohitKini Sep 26, 2024
175eab7
Merge pull request #296 from contentstack/feature/rohit-updates
RohitKini Sep 26, 2024
1e11f79
Merge pull request #297 from contentstack/feature/merge_two
umeshmore45 Sep 30, 2024
e30acee
added create test route
RohitKini Sep 30, 2024
57ca484
Merge pull request #299 from contentstack/feature/rohit-updates
RohitKini Sep 30, 2024
10819d2
[CMG-311], [CMG-326]
sayalijoshi27 Oct 1, 2024
a0ae36f
Done changes in Contentmapper removed existing ct and global field st…
sayalijoshi27 Oct 1, 2024
ff43e2e
added test
umeshmore45 Oct 2, 2024
ff2deea
[CMG-82] - Create Project modal validation behaviour separated for na…
sayalijoshi27 Oct 3, 2024
ba89476
code added
umeshmore45 Oct 3, 2024
47bedd7
Merge pull request #300 from contentstack/feature/test-mig2
umeshmore45 Oct 3, 2024
418bb4d
Test Migration API integrated
sayalijoshi27 Oct 3, 2024
cd0581c
Merge pull request #301 from contentstack/bugfix/content-mapper
RohitKini Oct 4, 2024
cf19a63
Merge branch 'dev' of https://github.com/contentstack/migration-v2-no…
sayalijoshi27 Oct 4, 2024
e5bd5e9
Test Migration API integrated
sayalijoshi27 Oct 3, 2024
bdcb680
rebased
umeshmore45 Oct 4, 2024
0e59657
Merge pull request #302 from contentstack/rebase
sayalijoshi27 Oct 4, 2024
8d34f28
Test migration button disabld and loader aaded
sayalijoshi27 Oct 4, 2024
1fc3d70
Merge pull request #303 from contentstack/feature/test-migration
RohitKini Oct 4, 2024
b5cf124
addded test ture boolean code
umeshmore45 Oct 4, 2024
561e04f
Merge pull request #304 from contentstack/feature/lowdb-fix
umeshmore45 Oct 4, 2024
2899517
Test Migration button disable changes
sayalijoshi27 Oct 4, 2024
8956f37
Merge pull request #306 from contentstack/feature/test-migration
sayalijoshi27 Oct 4, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ PublishScripts/
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# **/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
Expand Down Expand Up @@ -349,10 +349,10 @@ MigrationBackup/
# Ionide (cross platform F# VS Code tools) working folder
.ionide/


upload-api/node_modules
upload-api/build
package-lock.json
ui/.env
upload-api/sitecoreMigrationData
upload-api/extracted_files
locale-cli
3 changes: 2 additions & 1 deletion api/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -361,4 +361,5 @@ package-lock.json
!example.env

database/
/sitecoreMigrationData
/sitecoreMigrationData
/migration-data
4 changes: 4 additions & 0 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,15 @@
"express": "^4.18.2",
"express-validator": "^7.0.1",
"express-winston": "^4.2.0",
"fs-extra": "^11.2.0",
"fs-readdir-recursive": "^1.1.0",
"helmet": "^7.1.0",
"html-to-json-parser": "^2.0.1",
"http": "^0.0.1-security",
"jsdom": "^24.1.0",
"jsonwebtoken": "^9.0.2",
"lowdb": "^7.0.1",
"mkdirp": "^3.0.1",
"shelljs": "^0.8.5",
"socket.io": "^4.7.5",
"uuid": "^9.0.1",
Expand All @@ -50,10 +52,12 @@
"devDependencies": {
"@types/cors": "^2.8.17",
"@types/express": "^4.17.21",
"@types/fs-extra": "^11.0.4",
"@types/fs-readdir-recursive": "^1.1.3",
"@types/jsdom": "^21.1.7",
"@types/jsonwebtoken": "^9.0.5",
"@types/lodash": "^4.17.0",
"@types/mkdirp": "^2.0.0",
"@types/node": "^20.10.4",
"@types/shelljs": "^0.8.15",
"@types/uuid": "^9.0.8",
Expand Down
2 changes: 2 additions & 0 deletions api/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ dotenv.config({
path: path.resolve(process.cwd(), `${process.env.NODE_ENV}.env`),
});


/**
* Configuration type for the application.
*/
Expand All @@ -34,6 +35,7 @@ export type ConfigType = {
AZURE_EU?: string;
GCP_NA?: string;
};
LOG_FILE_PATH: string;
};

/**
Expand Down
2 changes: 1 addition & 1 deletion api/src/controllers/migration.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const createTestStack = async (req: Request, res: Response): Promise<void> => {
* @returns {Promise<void>} - A Promise that resolves when the stack is deleted.
*/
const fieldMapping = async (req: Request, res: Response): Promise<void> => {
const resp = await migrationService.fieldMapping(req);
const resp = migrationService.fieldMapping(req);
res.status(200).json(resp);
};

Expand Down
15 changes: 14 additions & 1 deletion api/src/controllers/org.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,11 +62,24 @@ const getStackLocale = async (req: Request, res: Response) => {
res.status(resp.status).json(resp.data);
};

/* Retrieves the org details.
*
* @param req - The request object.
* @param res - The response object.
* @returns A Promise that resolves to the org details response.
*/
const getOrgDetails = async (req: Request, res: Response) => {
const resp = await orgService.getOrgDetails(req);
res.status(resp.status).json(resp.data);
};



export const orgController = {
getAllStacks,
createStack,
getLocales,
getStackStatus,
getStackLocale
getStackLocale,
getOrgDetails,
};
15 changes: 14 additions & 1 deletion api/src/controllers/projects.contentMapper.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,18 @@ const getSingleContentTypes = async (
res.status(201).json(resp);
};

/**
* Retrieves single global field.
*
* @param req - The request object.
* @param res - The response object.
* @returns A Promise that resolves to void.
*/
const getSingleGlobalField = async(req: Request, res: Response): Promise<void> => {
const resp = await contentMapperService.getSingleGlobalField(req);
res.status(201).json(resp);
}

/**
* update content mapping details a project.
*
Expand All @@ -148,5 +160,6 @@ export const contentMapperController = {
getSingleContentTypes,
removeContentMapper,
updateContentMapper,
getExistingGlobalFields
getExistingGlobalFields,
getSingleGlobalField
};
7 changes: 4 additions & 3 deletions api/src/models/project-lowdb.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import path from 'path';
import { JSONFile } from "lowdb/node";
import LowWithLodash from "../utils/lowdb-lodash.utils.js";

Expand Down Expand Up @@ -27,11 +28,11 @@ interface LegacyCMS {
is_localPath: boolean;
}

interface StackDetails{
interface StackDetails {
uid: string;
label: string;
master_locale: string;
created_at: string;
created_at: string;
isNewStack: boolean;
}

Expand Down Expand Up @@ -84,7 +85,7 @@ const defaultData: ProjectDocument = { projects: [] };
* Represents the database instance for the project.
*/
const db = new LowWithLodash(
new JSONFile<ProjectDocument>("database/project.json"),
new JSONFile<ProjectDocument>(path.join(process.cwd(), "database/project.json")),
defaultData
);

Expand Down
15 changes: 13 additions & 2 deletions api/src/routes/contentMapper.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ router.get(
* @route GET /:projectId
*/
router.get(
"/globalFields/:projectId",
"/:projectId/globalFields",
asyncRouter(contentMapperController.getExistingGlobalFields)
);

Expand Down Expand Up @@ -85,7 +85,18 @@ router.get(
asyncRouter(contentMapperController.removeContentMapper)
);

//update content mapper details
/**
* Update content mapper
* @route GET /:orgId/:projectId
*/
router.patch("/:orgId/:projectId/mapper_keys", asyncRouter(contentMapperController.updateContentMapper));

/**
* Get Single Global Field data
* @route GET /:projectId/:globalFieldUid
*/
router.get("/:projectId/globalFields/:globalFieldUid",
asyncRouter(contentMapperController.getSingleGlobalField)
);

export default router;
13 changes: 13 additions & 0 deletions api/src/routes/migration.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,17 @@ router.post(
asyncRouter(migrationController.deleteTestStack)
);

/**
* Route for creating a test stack.
* @route POST /test-stack/:projectId
* @group Migration
* @param {string} projectId - The ID of the project.
* @returns {Promise<void>} - A promise that resolves when the test stack is deleted.
*/
router.post(
"/create-test-stack/:orgId/:projectId",
asyncRouter(migrationController.createTestStack)
);


export default router;
9 changes: 9 additions & 0 deletions api/src/routes/org.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,13 @@ router.post(
router.get("/get_stack_locales", asyncRouter(orgController.getStackLocale));


/**
* GET all contentstack org details route.
* @param req - Express request object.
* @param res - Express response object.
*/
router.get("/get_org_details", asyncRouter(orgController.getOrgDetails));



export default router;
98 changes: 59 additions & 39 deletions api/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,89 +18,109 @@ import contentMapperRoutes from "./routes/contentMapper.routes.js";
import migrationRoutes from "./routes/migration.routes.js";
import chokidar from "chokidar";
import { Server } from "socket.io";
import http from "http";
import fs from "fs";

// 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)
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
},
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);
}

try {
const app = express();

// Set security-related HTTP headers
app.use(
helmet({
crossOriginOpenerPolicy: false,
crossOriginOpenerPolicy: false, // Disable to allow cross-origin resource sharing
})
);

// Enable CORS for all origins
app.use(cors({ origin: "*" }));

// Parsing request bodies
app.use(express.urlencoded({ extended: false, limit: "10mb" }));
app.use(express.json({ limit: "10mb" }));

// Custom middleware for logging and request headers
app.use(loggerMiddleware);
app.use(requestHeadersMiddleware);

// Routes
// Define routes
app.use("/v2/auth", authRoutes);
app.use("/v2/user", authenticateUser, userRoutes);
app.use("/v2/org/:orgId", authenticateUser, orgRoutes);
app.use("/v2/org/:orgId/project", authenticateUser, projectRoutes);
app.use("/v2/mapper", authenticateUser, contentMapperRoutes);
app.use("/v2/migration", authenticateUser, migrationRoutes);

//For unmatched route patterns
// Handle unmatched routes
app.use(unmatchedRoutesMiddleware);

// Error Middleware
// Handle errors
app.use(errorMiddleware);

// starting the server & DB connection.
// Start the server and establish DB connection
(async () => {
await connectToDatabase();
await connectToDatabase(); // Establish DB connection

const server = app.listen(config.PORT, () =>
logger.info(`Server listening at port ${config.PORT}`)
);
// Chokidar - Watch for log file changes
const logFilePath = config.LOG_FILE_PATH;
const watcher = chokidar.watch(logFilePath);
// Socket.IO - Send logs to client
/**
* The Socket.IO server instance.
*
* @remarks
* This server instance is responsible for handling real-time communication between the client and the server using the Socket.IO library.
*
* @type {Server}
*/
const io = new Server(
server,
(http,
{
cors: {
origin: "*", // This allows all origins. For production, specify exact origins for security.
methods: ["GET", "POST"], // Specify which HTTP methods are allowed.
allowedHeaders: ["my-custom-header"], // Specify which headers are allowed.
credentials: true, // If your client needs to send cookies or credentials with the requests.
},
})
);

// Initialize Socket.IO for real-time log updates
io = new Server(server, {
cors: {
origin: "*", // Allow all origins; adjust for production
methods: ["GET", "POST"],
allowedHeaders: ["my-custom-header"],
credentials: true,
},
});

// Emit initial log file content to connected clients

// File watcher for log file changes
watcher.on("change", (path) => {
// Read the updated log file
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;
}
// Get just the updated data
// const updatedData = data.slice(data.lastIndexOf("\n") + 1);
console.info("updates", data);
// Emit the updated data to all connected clients
try {
const parsedData = data;
io.emit("logUpdate", parsedData);
// Emit the updated log content to connected clients
io.emit("logUpdate", data);
} catch (error) {
logger.error(`Error parsing data: ${error}`);
logger.error(`Error emitting log data: ${error}`);
}
});
});

})();
} catch (e) {
logger.error("Error while starting the server!");
logger.error(e);
}

5 changes: 0 additions & 5 deletions api/src/services/auth.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import logger from "../utils/logger.js";
*/
const login = async (req: Request): Promise<LoginServiceType> => {
const srcFun = "Login";
const cliUtilities: any = await import('@contentstack/cli-utilities');
/*
handles user authentication by making a request to an API,
performing various checks and validations,
Expand Down Expand Up @@ -110,10 +109,6 @@ const login = async (req: Request): Promise<LoginServiceType> => {
data.users[userIndex].authtoken = res?.data.user?.authtoken;
data.users[userIndex].updated_at = new Date().toISOString();
}

cliUtilities?.configHandler?.set('region', userData?.region);
cliUtilities?.configHandler?.set('authtoken', res?.data.user?.authtoken);

});

// JWT token generation
Expand Down
Loading