Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c1e4598
sitecore nested zip issue resolved
sauravraw Sep 22, 2025
b767523
remove hardcode value from config
sauravraw Sep 22, 2025
2537325
Merge branch 'feature/new-logo-update' of https://github.com/contents…
sauravraw Sep 25, 2025
e6f12b1
fixed sitecore issues
sauravraw Sep 25, 2025
5a4de41
Update contenttypes.js
sauravraw Sep 26, 2025
54c45d8
added prefix support
sauravraw Sep 26, 2025
fa5bd36
[CMG-726]
sayalijoshi27 Oct 10, 2025
1dab9fa
Merge branch 'dev' of https://github.com/contentstack/migration-v2-no…
sayalijoshi27 Oct 10, 2025
0f4eb92
Merge branch 'dev' of https://github.com/contentstack/migration-v2-no…
sayalijoshi27 Oct 10, 2025
585e624
Merge branch 'dev' of https://github.com/contentstack/migration-v2-no…
sayalijoshi27 Oct 15, 2025
2799cba
Disabled mandatory toggle for Modular blocks
sayalijoshi27 Oct 15, 2025
a91eb7b
Refactor project service and UI components for improved readability a…
sauravraw Oct 29, 2025
ac72604
Merge branch 'dev' of https://github.com/contentstack/migration-v2 in…
sauravraw Oct 31, 2025
1bfde71
chore: update package-lock.json to mark several dependencies as dev d…
sauravraw Oct 31, 2025
cdcedf4
refactor: enhance error handling and validation in project service me…
sauravraw Nov 3, 2025
5f1eeff
fix: correct comment typo in contentTypeMapper for dropdown advanced …
sauravraw Nov 3, 2025
3eb1eb0
chore: update @contentstack/cli and related dependencies in package.j…
sauravraw Nov 3, 2025
8e01696
refactor: simplify nested zip file validation logic in sitecoreValida…
sauravraw Nov 3, 2025
aa8e183
bugfix: added initial key to enable advance field reset
yashin4112 Nov 3, 2025
860ee72
Merge pull request #821 from contentstack/bugfix/sitecore-zip-issue
sayalijoshi27 Nov 3, 2025
f8ac7db
Merge pull request #822 from contentstack/bugfix/aem-752
sayalijoshi27 Nov 3, 2025
b3fa09a
refactor: add isNumber field to SearchComponent and TeaserComponent f…
shobhitupadhyayy Nov 4, 2025
087d330
[CMG-736] - Multiple clicks on buttons or links that return results s…
sayalijoshi27 Nov 4, 2025
a6d356e
[CMG-736] - Multiple clicks on buttons or links that return results s…
sayalijoshi27 Nov 4, 2025
d6c63ee
conflict resolved
sayalijoshi27 Nov 4, 2025
b46532a
Replaced Master word with default
sayalijoshi27 Nov 4, 2025
595e9f4
refactor: improve state management and formatting in AdvancePropertis…
shobhitupadhyayy Nov 4, 2025
fd4d592
Merge pull request #823 from contentstack/feat/custom-app
umeshmore45 Nov 4, 2025
c46761f
conflict resolved
sayalijoshi27 Nov 4, 2025
d12b956
copilot suggestions added
sayalijoshi27 Nov 4, 2025
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
7 changes: 5 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -356,8 +356,11 @@ upload-api/build
ui/.env
upload-api/sitecoreMigrationData
upload-api/cmsMigrationData
upload-api/extracted_files
upload-api/extracted_files*
*copy*
.qodo
.vscode
app.json
*extracted_files*
*MigrationData*
*.zip
app.json
1 change: 0 additions & 1 deletion api/.eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaVersion": 2022,
"project": ["./tsconfig.json"],
"sourceType": "module"
},
"plugins": ["@typescript-eslint"],
Expand Down
3,515 changes: 1,314 additions & 2,201 deletions api/package-lock.json

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,14 @@
},
"homepage": "https://github.com/contentstack/migration-v2.git#readme",
"dependencies": {
"@contentstack/cli": "1.41.0",
"@contentstack/cli-utilities": "^1.12.0",
"@contentstack/json-rte-serializer": "^2.0.7",
"@contentstack/marketplace-sdk": "^1.2.4",
"@contentstack/cli": "^1.51.1",
"@contentstack/cli-utilities": "^1.14.2",
"@contentstack/json-rte-serializer": "^3.0.4",
"@contentstack/marketplace-sdk": "^1.4.0",
"axios": "^1.12.0",
"chokidar": "^3.6.0",
"cors": "^2.8.5",
"dayjs": "^1.11.18",
"dotenv": "^16.3.1",
"express": "^4.21.0",
"express-validator": "^7.3.0",
Expand Down
93 changes: 60 additions & 33 deletions api/src/services/marketplace.service.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,16 @@
import path from 'path';
import fs from 'fs';
import getAuthtoken from "../utils/auth.utils.js";
import getAuthtoken from '../utils/auth.utils.js';
import { MIGRATION_DATA_CONFIG, KEYTOREMOVE } from '../constants/index.js';
import { getAppManifestAndAppConfig } from '../utils/market-app.utils.js';
import { v4 as uuidv4 } from "uuid";

import { v4 as uuidv4 } from 'uuid';

const {
EXTENSIONS_MAPPER_DIR_NAME,
MARKETPLACE_APPS_DIR_NAME,
MARKETPLACE_APPS_FILE_NAME
MARKETPLACE_APPS_FILE_NAME,
} = MIGRATION_DATA_CONFIG;


const groupByAppUid = (data: any) => {
return data?.reduce?.((acc: any, item: any) => {
if (!acc[item.appUid]) {
Expand All @@ -21,85 +19,114 @@ const groupByAppUid = (data: any) => {
acc[item.appUid].push(item.extensionUid);
return acc;
}, {});
}
};
const removeKeys = (obj: any, keysToRemove: any) => {
return Object.fromEntries(
Object.entries(obj).filter(([key]) => !keysToRemove.includes(key))
);
}
};

const writeManifestFile = async ({ destinationStackId, appManifest }: any) => {
const dirPath = path.join(process.cwd(), MIGRATION_DATA_CONFIG.DATA, destinationStackId, MARKETPLACE_APPS_DIR_NAME);
const dirPath = path.join(
process.cwd(),
MIGRATION_DATA_CONFIG.DATA,
destinationStackId,
MARKETPLACE_APPS_DIR_NAME
);
try {
await fs.promises.access(dirPath);
} catch (err) {
try {
await fs.promises.mkdir(dirPath, { recursive: true });
} catch (mkdirErr) {
console.error("🚀 ~ fs.mkdir ~ err:", mkdirErr);
console.error('🚀 ~ fs.mkdir ~ err:', mkdirErr);
return;
}
}
try {
const filePath = path.join(dirPath, MARKETPLACE_APPS_FILE_NAME);
await fs.promises.writeFile(filePath, JSON.stringify(appManifest, null, 2));
} catch (writeErr) {
console.error("🚀 ~ fs.writeFile ~ err:", writeErr);
console.error('🚀 ~ fs.writeFile ~ err:', writeErr);
}
}
};



const createAppManifest = async ({ destinationStackId, region, userId, orgId }: any) => {
const createAppManifest = async ({
destinationStackId,
region,
userId,
orgId,
}: any) => {
const authtoken = await getAuthtoken(region, userId);
const marketPlacePath = path.join(MIGRATION_DATA_CONFIG.DATA, destinationStackId, EXTENSIONS_MAPPER_DIR_NAME);
const AppMapper: any = await fs.promises.readFile(marketPlacePath, "utf-8").catch(async () => { });
const marketPlacePath = path.join(
MIGRATION_DATA_CONFIG.DATA,
destinationStackId,
EXTENSIONS_MAPPER_DIR_NAME
);
const AppMapper: any = await fs.promises
.readFile(marketPlacePath, 'utf-8')
.catch(async () => {});
if (AppMapper !== undefined) {
const appManifest: any = [];
const groupUids: any = groupByAppUid(JSON.parse(AppMapper));
for await (const [key, value] of Object?.entries?.(groupUids) || {}) {
const data: any = await getAppManifestAndAppConfig({ organizationUid: orgId, authtoken, region, manifestUid: key });
const data: any = await getAppManifestAndAppConfig({
organizationUid: orgId,
authtoken,
region,
manifestUid: key,
});
data.manifest = removeKeys(data, KEYTOREMOVE);
const extensionUids: any = new Set(value) ?? [];
const extensionUids: any = new Set(Array.isArray(value) ? value : []);
const locations: any = [];
for (const ext of extensionUids ?? []) {
for (const ext of extensionUids) {
const seprateUid = ext?.split?.('-');
const type: string = seprateUid?.[1];
const extUid: string = seprateUid?.[0];
for (const loc of data?.ui_location?.locations ?? []) {
if (loc?.type === type) {
const isPresent = locations?.meta?.findIndex((item: any) => item?.extension_uid === extUid);
const isPresent = locations?.meta?.findIndex(
(item: any) => item?.extension_uid === extUid
);
if (isPresent === undefined) {
locations?.push({
type,
meta: [{ ...(loc?.meta?.[0] || {}), extension_uid: extUid }]
})
meta: [{ ...(loc?.meta?.[0] || {}), extension_uid: extUid }],
});
}
}
}
}
const configData = data?.ui_location?.locations?.find((ele: any) => ele?.type === 'cs.cm.stack.config');
const configData = data?.ui_location?.locations?.find(
(ele: any) => ele?.type === 'cs.cm.stack.config'
);
if (configData) {
locations?.push({
type: configData?.type,
meta: [{ ...(configData?.meta?.[0] || {}), name: 'Config', extension_uid: uuidv4() }]
})
meta: [
{
...(configData?.meta?.[0] || {}),
name: 'Config',
extension_uid: uuidv4(),
},
],
});
}
data.ui_location.locations = locations;
data.status = "installed";
data.status = 'installed';
data.target = {
"type": "stack",
"uid": destinationStackId
type: 'stack',
uid: destinationStackId,
};
data.installation_uid = data?.uid;
data.configuration = "";
data.server_configuration = "";
data.configuration = '';
data.server_configuration = '';
appManifest?.push(removeKeys(data, KEYTOREMOVE));
}
await writeManifestFile({ destinationStackId, appManifest });
}
}
};

export const marketPlaceAppService = {
createAppManifest
}
createAppManifest,
};
Loading