Skip to content

Commit ae322d5

Browse files
committed
Merge branch 'dev' of https://github.com/contentstack/migration-v2-node-server into feature/content-mapper
2 parents 791c806 + d2eed4f commit ae322d5

File tree

11 files changed

+152
-103
lines changed

11 files changed

+152
-103
lines changed

api/src/models/FieldMapper.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ interface FieldMapper {
2828
field_mapper: {
2929
id: string;
3030
projectId: string;
31+
contentTypeId: string;
3132
uid: string;
3233
otherCmsField: string;
3334
otherCmsType: string;

api/src/services/contentMapper.service.ts

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,21 @@ const putTestData = async (req: Request) => {
3636
const contentTypes = req.body.contentTypes;
3737

3838
try {
39-
await FieldMapperModel.read();
39+
40+
/*
41+
this code snippet is iterating over an array called contentTypes and
42+
transforming each element by adding a unique identifier (id) if it doesn't already exist.
43+
The transformed elements are then stored in the contentType variable,
44+
and the generated id values are pushed into the contentIds array.
45+
*/
46+
await ContentTypesMapperModelLowdb.read();
47+
const contentIds: any[] = [];
48+
const contentType = contentTypes.map((item: any) => {
49+
const id = item?.id?.replace(/[{}]/g, "")?.toLowerCase() || uuidv4();
50+
item.id = id;
51+
contentIds.push(id);
52+
return { ...item, id, projectId };
53+
});
4054

4155
/*
4256
this code snippet iterates over an array of contentTypes and performs
@@ -47,36 +61,24 @@ const putTestData = async (req: Request) => {
4761
It then updates the field_mapper property of a data object using the FieldMapperModel.update() function.
4862
Finally, it updates the fieldMapping property of each type in the contentTypes array with the fieldIds array.
4963
*/
64+
await FieldMapperModel.read();
65+
5066
contentTypes.map((type: any, index: any) => {
5167
const fieldIds: string[] = [];
5268
const fields = type?.fieldMapping?.filter((field: any) => field)?.map?.((field: any) => {
5369
const id = field?.id ? field?.id?.replace(/[{}]/g, "")?.toLowerCase() : uuidv4();
5470
field.id = id;
5571
fieldIds.push(id);
56-
return { id, projectId, isDeleted: false, ...field };
72+
return { id, projectId, contentTypeId: type?.id, isDeleted: false, ...field };
5773
});
5874

5975
FieldMapperModel.update((data: any) => {
6076
data.field_mapper = [...(data?.field_mapper ?? []), ...(fields ?? [])];
6177
});
62-
contentTypes[index].fieldMapping = fieldIds;
78+
contentType[index].fieldMapping = fieldIds;
6379
});
6480

65-
await ContentTypesMapperModelLowdb.read();
66-
const contentIds: any[] = [];
6781

68-
/*
69-
this code snippet is iterating over an array called contentTypes and
70-
transforming each element by adding a unique identifier (id) if it doesn't already exist.
71-
The transformed elements are then stored in the contentType variable,
72-
and the generated id values are pushed into the contentIds array.
73-
*/
74-
const contentType = contentTypes.map((item: any) => {
75-
const id = item?.id?.replace(/[{}]/g, "")?.toLowerCase() || uuidv4();
76-
item.id = id;
77-
contentIds.push(id);
78-
return { ...item, id, projectId };
79-
});
8082

8183
await ContentTypesMapperModelLowdb.update((data: any) => {
8284
data.ContentTypesMappers = [
@@ -248,7 +250,7 @@ const getFieldMapping = async (req: Request) => {
248250
const fieldData = contentType?.fieldMapping?.map?.((fields: any) => {
249251
const fieldMapper = FieldMapperModel.chain
250252
.get("field_mapper")
251-
.find({ id: fields, projectId: projectId })
253+
.find({ id: fields, projectId: projectId, contentTypeId: contentTypeId })
252254
.value();
253255

254256
return fieldMapper;
@@ -616,7 +618,7 @@ const updateContentType = async (req: Request) => {
616618
await FieldMapperModel.read();
617619
fieldMapping.forEach((field: any) => {
618620
const fieldIndex = FieldMapperModel.data.field_mapper.findIndex(
619-
(f: any) => f?.id === field?.id
621+
(f: any) => f?.id === field?.id && f?.contentTypeId === field?.contentTypeId
620622
);
621623
if (fieldIndex > -1 && field?.contentstackFieldType !== "") {
622624
FieldMapperModel.update((data: any) => {

api/src/services/contentful.service.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -939,16 +939,16 @@ const createLocale = async (packagePath: string, destination_stack_id: string, p
939939
}
940940
const fallbackMapLocales: any = { ...project?.master_locale ?? {}, ...project?.locales ?? {} }
941941
await Promise?.all(locales?.map?.(async (localeData: any) => {
942-
const currentMapLocale = getKeyByValue?.(fallbackMapLocales, localeData?.code) ?? `${localeData.code.toLowerCase()}`;
942+
const currentMapLocale = getKeyByValue?.(fallbackMapLocales, localeData?.code) ?? `${localeData?.code?.toLowerCase?.()}`;
943943
const title = localeData?.sys?.id;
944944
const newLocale: Locale = {
945945
code: currentMapLocale,
946946
name: localeCodes?.[currentMapLocale] || "English - United States",
947947
fallback_locale: getKeyByValue(fallbackMapLocales, localeData?.fallbackCode) ?? '',
948948
uid: `${title}`,
949949
};
950-
951-
if (localeData.default === true) {
950+
const masterLocaleCode = getKeyByValue(project?.master_locale, localeData?.code);
951+
if (masterLocaleCode !== undefined) {
952952
msLocale[title] = newLocale;
953953
const message = getLogMessage(
954954
srcFunc,
@@ -957,16 +957,26 @@ const createLocale = async (packagePath: string, destination_stack_id: string, p
957957
)
958958
await customLogger(projectId, destination_stack_id, 'info', message);
959959
} else {
960-
allLocales[title] = newLocale;
961-
const message = getLogMessage(
962-
srcFunc,
963-
`Locale ${newLocale?.code} has been successfully transformed.`,
964-
{}
965-
)
966-
await customLogger(projectId, destination_stack_id, 'info', message);
960+
if (project?.locales?.[localeData?.code]) {
961+
allLocales[title] = newLocale;
962+
const message = getLogMessage(
963+
srcFunc,
964+
`Locale ${newLocale?.code} has been successfully transformed.`,
965+
{}
966+
)
967+
await customLogger(projectId, destination_stack_id, 'info', message);
968+
}
967969
}
968970
localeList[title] = newLocale;
969971
}));
972+
const masterLocaleData = Object?.values(msLocale)?.[0];
973+
if (masterLocaleData) {
974+
for (const [key, value] of Object.entries(allLocales) ?? {}) {
975+
if (value?.code === masterLocaleData?.fallback_locale) {
976+
allLocales[key].fallback_locale = masterLocaleData?.code
977+
}
978+
}
979+
}
970980
await writeFile(localeSave, LOCALE_FILE_NAME, allLocales)
971981
await writeFile(localeSave, LOCALE_MASTER_LOCALE, msLocale)
972982
await writeFile(localeSave, LOCALE_CF_LANGUAGE, localeList)

api/src/services/wordpress.service.ts

Lines changed: 56 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import axios from "axios";
55
//import _ from "lodash";
66
import { MIGRATION_DATA_CONFIG } from "../constants/index.js";
77
import jsdom from "jsdom";
8-
import { htmlToJson } from "@contentstack/json-rte-serializer";
8+
import { htmlToJson, jsonToHtml } from "@contentstack/json-rte-serializer";
99
import customLogger from "../utils/custom-logger.utils.js";
1010
import { getLogMessage } from "../utils/index.js";
1111
import { Advanced } from "../models/FieldMapper.js";
@@ -108,20 +108,28 @@ let assetData: Record<string, any> | any = {};
108108
let blog_base_url = "";
109109

110110
//helper function to convert entries with content type
111-
function mapContentTypeToEntry(contentType: any, data: any) {
112-
return contentType?.fieldMapping?.reduce((acc: { [key: string]: any }, field: FieldMapping) => {
111+
async function mapContentTypeToEntry(contentType: any, data: any) {
112+
const result: { [key: string]: any } = {};
113+
114+
for (const field of contentType?.fieldMapping || []) {
113115
const fieldValue = data?.[field?.uid];
114116
let formattedValue;
115117

116118
switch (field?.contentstackFieldType) {
117119
case "single_line_text":
118120
case "text":
119-
case 'html':
120121
formattedValue = fieldValue;
121122
break;
122-
case "json":
123-
formattedValue = convertHtmlToJson(fieldValue);
123+
case "html":
124+
formattedValue =
125+
fieldValue && typeof fieldValue === "object"
126+
? await convertJsonToHtml(fieldValue)
127+
: fieldValue;
124128
break;
129+
case "json":
130+
131+
formattedValue = await convertHtmlToJson(fieldValue);
132+
break;
125133
case "reference":
126134
formattedValue = getParent(data,data[field.uid]);
127135
break;
@@ -132,10 +140,12 @@ function mapContentTypeToEntry(contentType: any, data: any) {
132140
formattedValue = Array.isArray(formattedValue) ? formattedValue : [formattedValue];
133141
}
134142

135-
acc[field.contentstackFieldUid] = formattedValue;
136-
return acc;
137-
}, {});
143+
result[field?.contentstackFieldUid] = formattedValue;
144+
}
145+
146+
return result;
138147
}
148+
139149
// helper functions
140150
async function writeFileAsync(filePath: string, data: any, tabSpaces: number) {
141151
filePath = path.resolve(filePath);
@@ -596,7 +606,7 @@ async function getAllreference(affix: string, packagePath: string, destinationSt
596606
...processReferenceData(referenceTerms, "terms", "wp:term_slug", terms)
597607
);
598608
referenceArray.push(
599-
...processReferenceData(referenceTags, "tags", "wp:tag_slug", tag)
609+
...processReferenceData(referenceTags, "tag", "wp:tag_slug", tag)
600610
);
601611

602612
if (referenceArray.length > 0) {
@@ -776,7 +786,7 @@ async function saveAuthors(authorDetails: any[], destinationStackId: string, pro
776786
authordata[customId] = {
777787
...authordata[customId],
778788
uid: customId,
779-
...mapContentTypeToEntry(contentType, authordataEntry),
789+
...( await mapContentTypeToEntry(contentType, authordataEntry)),
780790
};
781791
authordata[customId].publish_details = [];
782792

@@ -1473,7 +1483,7 @@ async function saveTerms(termsDetails: any[], destinationStackId: string, projec
14731483
`${master_locale}.json`
14741484
);
14751485
const termsdata = termsDetails.reduce(
1476-
(acc: { [key: string]: any }, data) => {
1486+
async (acc: { [key: string]: any }, data) => {
14771487

14781488
const { id } = data;
14791489
const uid = `terms_${id}`;
@@ -1485,7 +1495,7 @@ async function saveTerms(termsDetails: any[], destinationStackId: string, projec
14851495
acc[customId] = {
14861496
...acc[customId],
14871497
uid: customId,
1488-
...mapContentTypeToEntry(contentType, data), // Pass individual term object
1498+
...(await mapContentTypeToEntry(contentType, data)), // Pass individual term object
14891499
};
14901500
acc[customId].publish_details = [];
14911501
return acc;
@@ -1598,7 +1608,7 @@ async function saveTags(tagDetails: any[], destinationStackId: string, projectId
15981608
tagsFolderPath,
15991609
`${master_locale}.json`
16001610
);
1601-
const tagdata = tagDetails.reduce((acc: { [key: string]: any }, data) => {
1611+
const tagdata = tagDetails.reduce(async (acc: { [key: string]: any }, data) => {
16021612
const { id } = data;
16031613
const uid = `tags_${id}`;
16041614
//const title = `Tags - ${id}`;
@@ -1609,7 +1619,7 @@ async function saveTags(tagDetails: any[], destinationStackId: string, projectId
16091619
acc[customId]={
16101620
...acc[customId],
16111621
uid:customId,
1612-
...mapContentTypeToEntry(contenttype,data),
1622+
...( await mapContentTypeToEntry(contenttype,data)),
16131623
};
16141624
acc[customId].publish_details = [];
16151625

@@ -1715,11 +1725,22 @@ async function startingDirCategories(affix: string, ct: string, master_locale:st
17151725
}
17161726

17171727
const convertHtmlToJson = (htmlString: any) => {
1718-
const dom = new JSDOM(htmlString?.replace(/&amp;/g, "&"));
1719-
const htmlDoc = dom.window.document.querySelector("body");
1720-
return htmlToJson(htmlDoc);
1728+
if(typeof htmlString === 'string'){
1729+
const dom = new JSDOM(htmlString?.replace(/&amp;/g, "&"));
1730+
const htmlDoc = dom.window.document.querySelector("body");
1731+
const jsonValue = htmlToJson(htmlDoc)
1732+
return jsonValue;
1733+
1734+
}
1735+
else return htmlString;
17211736
};
17221737

1738+
const convertJsonToHtml = async (json: any) => {
1739+
const htmlValue = await jsonToHtml(json);
1740+
return htmlValue;
1741+
1742+
}
1743+
17231744
function getParent(data: any,id: string) {
17241745
const parentId: any = fs.readFileSync(
17251746
path.join(referencesFolder, MIGRATION_DATA_CONFIG.REFERENCES_FILE_NAME),
@@ -1745,7 +1766,7 @@ async function saveCategories(categoryDetails: any[], destinationStackId:string,
17451766
const srcFunc = 'saveCategories';
17461767
try {
17471768
const categorydata = categoryDetails.reduce(
1748-
(acc: { [key: string]: any }, data) => {
1769+
async (acc: { [key: string]: any }, data) => {
17491770
const uid = `category_${data["id"]}`;
17501771

17511772
const customId = uid
@@ -1754,7 +1775,7 @@ async function saveCategories(categoryDetails: any[], destinationStackId:string,
17541775
acc[customId]={
17551776
...acc[customId],
17561777
uid:customId,
1757-
...mapContentTypeToEntry(contenttype,data),
1778+
...(await mapContentTypeToEntry(contenttype,data)),
17581779
}
17591780
acc[customId].publish_details = [];
17601781

@@ -2057,23 +2078,18 @@ async function processChunkData(
20572078
data,
20582079
postdata
20592080
);
2060-
const formattedPosts = Object?.entries(formatted_posts)?.reduce(
2061-
(acc: { [key: string]: any }, data:any) => {
2062-
2063-
const customId = idCorrector(data["uid"])
2064-
2065-
// Accumulate category data
2066-
acc[customId]={
2067-
...acc[customId],
2068-
uid: customId,
2069-
...mapContentTypeToEntry(contenttype,data),
2070-
};
2071-
acc[customId].publish_details = [];
2072-
2073-
return acc;
2074-
},
2075-
{}
2076-
);
2081+
const formattedPosts: any = {};
2082+
2083+
for (const [key, value] of Object.entries(formatted_posts as {[key: string]: any})) {
2084+
const customId = idCorrector(value?.uid);
2085+
2086+
formattedPosts[customId] = {
2087+
...formattedPosts[customId],
2088+
uid: customId,
2089+
...(await mapContentTypeToEntry(contenttype, value)),
2090+
};
2091+
formattedPosts[customId].publish_details = [];
2092+
}
20772093
Object.assign(postdata,formattedPosts);
20782094

20792095
// await writeFileAsync(
@@ -2095,6 +2111,7 @@ async function processChunkData(
20952111
if (isLastChunk && allSuccess) {
20962112
console.info("last data");
20972113
}
2114+
console.info("postData ---> ", postdata)
20982115
return postdata
20992116
} catch (error) {
21002117
console.error(error);
@@ -2105,8 +2122,8 @@ async function processChunkData(
21052122

21062123
async function extractPosts( packagePath: string, destinationStackId: string, projectId: string,contentTypes:any, keyMapper:any, master_locale: string) {
21072124
const srcFunc = "extractPosts";
2108-
const ct:any = keyMapper?.["categories"];
2109-
const contenttype = contentTypes?.find((item:any)=> item?.otherCmsUid === 'categories');
2125+
const ct:any = keyMapper?.["posts"];
2126+
const contenttype = contentTypes?.find((item:any)=> item?.otherCmsUid === 'posts');
21102127

21112128
try {
21122129
await startingDirPosts(ct, master_locale);

ui/src/components/AdvancePropertise/index.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ const AdvancePropertise = (props: SchemaProps) => {
576576
isMulti={true}
577577
onChange={(selectedOptions: ContentTypeOption[]) => {
578578
setCTValue(selectedOptions);
579-
const embedObject = selectedOptions.map((item: optionsType) => item.label); // Update the state with the selected options
579+
const embedObject = selectedOptions.map((item: optionsType) => item?.value); // Update the state with the selected options
580580
props?.updateFieldSettings(
581581
props?.rowId,
582582
{

ui/src/components/ContentMapper/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -671,6 +671,7 @@ const ContentMapper = forwardRef(({handleStepChange}: contentMapperProps, ref: R
671671
const validTableData = data?.fieldMapping?.filter((field: FieldMapType) => field?.otherCmsType !== undefined);
672672

673673
setTableData(validTableData || []);
674+
setSelectedEntries(validTableData);
674675
setTotalCounts(validTableData?.length);
675676
setInitialRowSelectedData(validTableData?.filter((item: FieldMapType) => !item?.isDeleted))
676677
setIsLoading(false);

0 commit comments

Comments
 (0)