Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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) {
console.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);
}

console.info("🚀 ~ createTerms ~ nestedTerms:", 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) {
console.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> = {};
res?.data?.taxonomies?.forEach(async (taxonomy: any) => {
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) {
console.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