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 .talismanrc
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ fileignoreconfig:

- filename: upload-api/src/config/index.ts
checksum: bd1465785804b3e3942d79f4424498bec838e5aba431c715eb419f3d39cf8d30
- filename: ui/src/components/ContentMapper/index.tsx
checksum: 376fc21e84880c760fab7af4b1bb653f526548f962126c1db7551d036eab765d
- filename: api/src/services/taxonomy.service.ts
checksum: bd2344e7277b41c7eb29c50504c88debf9a86d198c2508dea90d9a98f53d89e9



Expand Down
2 changes: 2 additions & 0 deletions api/src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,8 @@ export const MIGRATION_DATA_CONFIG = {
EXTENSION_APPS_FILE_NAME: "extensions.json",
REFERENCES_DIR_NAME: "reference",
REFERENCES_FILE_NAME: "reference.json",
TAXONOMIES_DIR_NAME: "taxonomies",
TAXONOMIES_FILE_NAME: "taxonomies.json",

RTE_REFERENCES_DIR_NAME: "rteReference",
RTE_REFERENCES_FILE_NAME: "rteReference.json",
Expand Down
9 changes: 9 additions & 0 deletions api/src/services/migration.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { marketPlaceAppService } from './marketplace.service.js';
import { extensionService } from './extension.service.js';
import fsPromises from 'fs/promises';
import { matchesSearchText } from '../utils/search.util.js';
import { taxonomyService } from './taxonomy.service.js';
// import { getSafePath } from "../utils/sanitize-path.utils.js";

/**
Expand Down Expand Up @@ -324,6 +325,14 @@ const startTestMigration = async (req: Request): Promise<any> => {
await extensionService?.createExtension({
destinationStackId: project?.current_test_stack_id,
});
await taxonomyService?.createTaxonomy({
orgId,
projectId,
stackId:project?.destination_stack_id,
current_test_stack_id: project?.current_test_stack_id,
region,
userId: user_id,})

switch (cms) {
case CMS.SITECORE_V8:
case CMS.SITECORE_V9:
Expand Down
210 changes: 210 additions & 0 deletions api/src/services/taxonomy.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
import { getLogMessage, safePromise } from "../utils/index.js";
import getAuthtoken from "../utils/auth.utils.js";
import { config } from "../config/index.js";
import https from "../utils/https.utils.js";
import fs from 'fs';
import { HTTP_TEXTS, MIGRATION_DATA_CONFIG } from "../constants/index.js";
import path from "path";
import logger from "../utils/logger.js";

const {
TAXONOMIES_DIR_NAME,
TAXONOMIES_FILE_NAME
} = MIGRATION_DATA_CONFIG;

const getDescendantsTerm = async ( {authtoken,taxonomyUid, termUid, region, stackId}:
{authtoken: string,taxonomyUid : string, termUid: string, region : string, stackId : string}) => {
const srcFun = "getDescendantsTerm";

try {
const [err, res] = await safePromise(
https({
method: "GET",
url: `${config.CS_API[
region as keyof typeof config.CS_API
]!}/taxonomies/${taxonomyUid}/terms/${termUid}/descendants?include_children_count=true&include_count=true&include_order=true`,
headers: {
api_key : stackId,
authtoken,
},
}));
if (err) {
logger.error(
getLogMessage(srcFun, HTTP_TEXTS.CS_ERROR, {}, err?.response?.data)
);

return {
data: err?.response?.data,
status: err?.response?.status,
};
}
const terms = res?.data?.terms || [];
const allTerms: { uid: string; name: string; parent_uid: string }[] = [];
for (const term of terms) {
// Push current term
allTerms.push({
uid: term?.uid,
name: term?.name,
parent_uid: term?.parent_uid,
});

// Recursively fetch deeper descendants
if (term?.children_count > 0) {
const nestedTerms = await getDescendantsTerm({
authtoken,
taxonomyUid,
termUid: term?.uid,
region,
stackId,
});

if (Array.isArray(nestedTerms)) {
allTerms.push(...nestedTerms);
}
}
}
return allTerms;
} catch (error) {
logger.error("🚀 ~ getDescendantsTerm ~ error:", error);
throw error;

}
}

const createTerms = async(
{authtoken,taxonomyUid, region, stackId}:
{authtoken: string,taxonomyUid : string, region : string, stackId : string}) => {
const srcFun = "createTerms";
try {
const [err, res] = await safePromise(
https({
method: "GET",
url: `${config.CS_API[
region as keyof typeof config.CS_API
]!}/taxonomies/${taxonomyUid}/terms?include_terms_count=true&include_count=true&include_children_count=true&include_referenced_entries_count=true`,
headers: {
api_key : stackId,
authtoken,
},
}));
const termsData = res?.data?.terms;
const allTerms: any[] = [];
for (const term of termsData || []) {
if (term?.uid) {
allTerms.push({
uid: term?.uid,
name: term?.name,
parent_uid: term?.parent_uid,
});

if (term?.children_count > 0) {
const nestedTerms = await getDescendantsTerm({
authtoken,
taxonomyUid,
termUid: term?.uid,
region,
stackId,
});

if (Array.isArray(nestedTerms)) {
allTerms.push(...nestedTerms);
}
}
}
}




if (err) {
logger.error(
getLogMessage(srcFun, HTTP_TEXTS.CS_ERROR, {}, err?.response?.data)
);

return {
data: err?.response?.data,
status: err?.response?.status,
};
}
return allTerms;

} catch (error) {
logger.error("🚀 ~ createTaxonomy ~ error:", error);
throw error;

}



}
const createTaxonomy = async ({stackId,region,userId,current_test_stack_id} :
{orgId: string, stackId: string, projectId:string,region: string,userId: string,current_test_stack_id:string}) => {
const srcFun = "createTaxonomy";
const taxonomiesPath = path.join(MIGRATION_DATA_CONFIG.DATA, current_test_stack_id, TAXONOMIES_DIR_NAME);
await fs.promises.mkdir(taxonomiesPath, { recursive: true });
try {
const authtoken = await getAuthtoken(
region,
userId
);
const [err, res] = await safePromise(
https({
method: "GET",
url: `${config.CS_API[
region as keyof typeof config.CS_API
]!}/taxonomies?include_terms_count=true&include_count=true`,
headers: {
api_key : stackId,
authtoken,
},
})
);
if (err) {
logger.error(
getLogMessage(srcFun, HTTP_TEXTS.CS_ERROR, {}, err?.response?.data)
);

return {
data: err?.response?.data,
status: err?.response?.status,
};
}

const taxonomiesDataObject: Record<string, any> = {};
if (res?.data?.taxonomies) {
for (const taxonomy of res.data.taxonomies) {
if (taxonomy?.uid) {
taxonomiesDataObject[taxonomy.uid] = {
uid: taxonomy?.uid,
name: taxonomy?.name,
description: taxonomy?.description,
};
const singleTaxonomy: any = {};
singleTaxonomy['taxonomy'] = {
uid: taxonomy?.uid,
name: taxonomy?.name,
description: taxonomy?.description,
};
singleTaxonomy['terms'] = await createTerms({ authtoken, taxonomyUid: taxonomy?.uid, region, stackId });
await fs.promises.writeFile(path.join(taxonomiesPath, `${taxonomy?.uid}.json`), JSON.stringify(singleTaxonomy, null, 2));
}
}
}

const filePath = path.join(taxonomiesPath, TAXONOMIES_FILE_NAME);
await fs.promises.writeFile(filePath, JSON.stringify(taxonomiesDataObject, null, 2));



} catch (error) {
logger.error("🚀 ~ createTaxonomy ~ error:", error);
throw error;
}

}


export const taxonomyService = {
createTaxonomy
}

60 changes: 43 additions & 17 deletions api/src/utils/content-type-creator.utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,19 @@ const arrangGroups = ({ schema, newStack }: any) => {
schema?.forEach((item: any) => {
if (item?.contentstackFieldType === 'group') {
const groupSchema: any = { ...item, schema: [] }
if (item?.contentstackFieldUid?.includes('.')) {
const parts = item?.contentstackFieldUid?.split('.');
groupSchema.contentstackFieldUid = parts?.[parts?.length - 1];
}
schema?.forEach((et: any) => {
if (et?.contentstackFieldUid?.includes(`${item?.contentstackFieldUid}.`) ||
(newStack === false && et?.uid?.includes(`${item?.uid}.`))) {
const target = groupSchema?.contentstackFieldUid;
const index = et?.contentstackFieldUid?.indexOf(target);

if (index > 0) {
et.contentstackFieldUid = et?.contentstackFieldUid?.substring?.(index);
}
groupSchema?.schema?.push(et);
}
})
Expand Down Expand Up @@ -665,35 +675,51 @@ const mergeArrays = async (a: any[], b: any[]) => {
}
}
return a;
}
};

// Recursive search to find a group by uid anywhere in the schema
const findGroupByUid = (schema: any[], uid: string): any | null => {
for (const field of schema) {
if (field?.data_type === 'group') {
if (field?.uid === uid) return field;
const nested = findGroupByUid(field?.schema ?? [], uid);
if (nested) return nested;
}
}
return null;
};

const mergeTwoCts = async (ct: any, mergeCts: any) => {
const ctData: any = {
...ct,
title: mergeCts?.title,
uid: mergeCts?.uid,
options: {
"singleton": false,
singleton: false,
}
}
for await (const field of ctData?.schema ?? []) {
if (field?.data_type === 'group') {
const currentGroup = mergeCts?.schema?.find((grp: any) => grp?.uid === field?.uid &&
grp?.data_type === 'group');
const group = [];
for await (const fieldGp of currentGroup?.schema ?? []) {
const fieldNst = field?.schema?.find((fld: any) => fld?.uid === fieldGp?.uid &&
fld?.data_type === fieldGp?.data_type);
if (fieldNst === undefined) {
group?.push(fieldGp);
};

const mergeGroupSchema = async (targetSchema: any[], sourceSchema: any[]) => {
for await (const targetField of targetSchema) {
if (targetField?.data_type === 'group') {
const matchingSourceGroup = findGroupByUid(sourceSchema, targetField?.uid);
if (matchingSourceGroup) {
if (!Array.isArray(targetField?.schema)) targetField.schema = [];
if (!Array.isArray(matchingSourceGroup?.schema)) matchingSourceGroup.schema = [];

await mergeGroupSchema(targetField?.schema, matchingSourceGroup?.schema);
targetField.schema = await mergeArrays(targetField?.schema, matchingSourceGroup?.schema);
}
}
field.schema = [...field?.schema ?? [], ...group];
}
}
ctData.schema = await mergeArrays(ctData?.schema, mergeCts?.schema) ?? [];
};

await mergeGroupSchema(ctData?.schema ?? [], mergeCts?.schema ?? []);
ctData.schema = await mergeArrays(ctData?.schema, mergeCts?.schema ?? []);

return ctData;
}
};


export const contenTypeMaker = async ({ contentType, destinationStackId, projectId, newStack, keyMapper, region, user_id }: any) => {
const marketPlacePath = path.join(process.cwd(), MIGRATION_DATA_CONFIG.DATA, destinationStackId);
Expand Down
Loading