Skip to content

Commit 4332d57

Browse files
committed
Refactor migration and Drupal services for improved clarity and functionality
- Removed redundant audit log index calculations in migration.service.ts. - Cleaned up import statements in entries.service.ts by removing unused constants. - Enhanced uidCorrector function to support a default prefix for UID generation. - Streamlined error handling and logging in various Drupal services for better maintainability.
1 parent 100668a commit 4332d57

File tree

9 files changed

+160
-206
lines changed

9 files changed

+160
-206
lines changed

api/src/services/drupal/entries.service.ts

Lines changed: 27 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,7 @@ import {
99
jsonToHtml,
1010
jsonToMarkdown,
1111
} from '@contentstack/json-rte-serializer';
12-
import {
13-
CHUNK_SIZE,
14-
LOCALE_MAPPER,
15-
MIGRATION_DATA_CONFIG,
16-
} from '../../constants/index.js';
12+
import { CHUNK_SIZE, MIGRATION_DATA_CONFIG } from '../../constants/index.js';
1713
import { getLogMessage } from '../../utils/index.js';
1814
import customLogger from '../../utils/custom-logger.utils.js';
1915
import { getDbConnection } from '../../helper/index.js';
@@ -27,26 +23,33 @@ import {
2723
type AssetFieldMapping,
2824
} from './field-analysis.service.js';
2925
import FieldFetcherService from './field-fetcher.service.js';
30-
import {
31-
entriesFieldCreator,
32-
unflatten,
33-
} from '../../utils/entries-field-creator.utils.js';
3426
import { mapDrupalLocales } from './locales.service.js';
3527
// Dynamic import for phpUnserialize will be used in the function
3628

3729
// Local utility functions (extracted from entries-field-creator.utils.ts patterns)
38-
const append = 'a';
30+
// Default prefix fallback if none provided
31+
const DEFAULT_PREFIX = 'cs';
3932

4033
function startsWithNumber(str: string) {
4134
return /^\d/.test(str);
4235
}
4336

44-
const uidCorrector = ({ uid, id }: any) => {
37+
const uidCorrector = ({
38+
uid,
39+
id,
40+
prefix,
41+
}: {
42+
uid?: string;
43+
id?: string;
44+
prefix?: string;
45+
}) => {
4546
const value = uid || id;
4647
if (!value) return '';
4748

49+
const effectivePrefix = prefix || DEFAULT_PREFIX;
50+
4851
if (startsWithNumber(value)) {
49-
return `${append}_${_.replace(
52+
return `${effectivePrefix}_${_.replace(
5053
value,
5154
new RegExp('[ -]', 'g'),
5255
'_'
@@ -69,9 +72,7 @@ interface TaxonomyFieldOutput {
6972
const {
7073
DATA,
7174
ENTRIES_DIR_NAME,
72-
ENTRIES_MASTER_FILE,
7375
ASSETS_DIR_NAME,
74-
ASSETS_SCHEMA_FILE,
7576
REFERENCES_DIR_NAME,
7677
REFERENCES_FILE_NAME,
7778
TAXONOMIES_DIR_NAME,
@@ -190,34 +191,6 @@ async function readFile(filePath: string, fileName: string) {
190191
}
191192
}
192193

193-
/**
194-
* Splits the given entry data into chunks that are under the specified size in bytes.
195-
*/
196-
function makeChunks(entryData: any) {
197-
let currentChunkSize = 0;
198-
const chunkSize = CHUNK_SIZE; // 1 MB in bytes
199-
let currentChunkId = uuidv4();
200-
const chunks: { [key: string]: any } = {};
201-
202-
for (const [key, value] of Object.entries(entryData)) {
203-
const tempObj = { [(value as { uid: string }).uid]: value };
204-
chunks[currentChunkId] = { ...chunks[currentChunkId], ...tempObj };
205-
206-
currentChunkSize = Buffer.byteLength(
207-
JSON.stringify(chunks[currentChunkId]),
208-
'utf8'
209-
);
210-
211-
if (currentChunkSize > chunkSize) {
212-
currentChunkId = uuidv4();
213-
currentChunkSize = 0;
214-
chunks[currentChunkId] = {};
215-
}
216-
}
217-
218-
return chunks;
219-
}
220-
221194
/**
222195
* Fetches field configurations from Drupal database
223196
*/
@@ -663,7 +636,8 @@ const processFieldData = async (
663636
referenceFieldMapping: ReferenceFieldMapping,
664637
assetFieldMapping: any,
665638
taxonomyReferenceLookup: Record<number, TaxonomyFieldOutput>,
666-
contentType: string
639+
contentType: string,
640+
prefix: string = DEFAULT_PREFIX
667641
): Promise<any> => {
668642
const fieldNames = Object.keys(entryData);
669643
const isoDate = new Date();
@@ -872,7 +846,10 @@ const processFieldData = async (
872846
} else if (fieldName.endsWith('_tid')) {
873847
ctValue[fieldName] = [value];
874848
} else if (fieldName === 'nid') {
875-
ctValue.uid = uidCorrector({ id: `content_type_entries_title_${value}` });
849+
ctValue.uid = uidCorrector({
850+
id: `content_type_entries_title_${value}`,
851+
prefix,
852+
});
876853
} else if (fieldName === 'langcode') {
877854
// Use the actual langcode from the entry for proper multilingual support
878855
ctValue.locale = value || 'en-us'; // fallback to en-us if langcode is empty
@@ -1149,7 +1126,6 @@ const processEntries = async (
11491126
// This replaces the old hardcoded transformation rules with dynamic user mapping
11501127
const transformedEntriesByLocale: { [locale: string]: any[] } = {};
11511128
const allLocales = Object.keys(entriesByLocale);
1152-
const hasUnd = allLocales.includes('und');
11531129
const hasEn = allLocales.includes('en');
11541130
const hasEnUs = allLocales.includes('en-us');
11551131

@@ -1252,6 +1228,9 @@ const processEntries = async (
12521228
const existingLocaleContent =
12531229
(await readFile(localeFolderPath, localeFileName)) || {};
12541230

1231+
// Extract prefix from project for UID correction
1232+
const prefix = project?.legacy_cms?.affix || DEFAULT_PREFIX;
1233+
12551234
// Process each entry in this locale
12561235
for (const entry of localeEntries) {
12571236
let processedEntry = await processFieldData(
@@ -1264,7 +1243,8 @@ const processEntries = async (
12641243
referenceFieldMapping,
12651244
assetFieldMapping,
12661245
taxonomyReferenceLookup,
1267-
contentType
1246+
contentType,
1247+
prefix
12681248
);
12691249

12701250
// 🏷️ TAXONOMY CONSOLIDATION: Merge all taxonomy fields into single 'taxonomies' field
@@ -1412,6 +1392,7 @@ const processEntries = async (
14121392
if (typeof entry.nid === 'number') {
14131393
const entryUid = uidCorrector({
14141394
id: `content_type_entries_title_${entry.nid}`,
1395+
prefix,
14151396
});
14161397
existingLocaleContent[entryUid] = processedEntry;
14171398
allProcessedContent[entryUid] = processedEntry;
@@ -1525,7 +1506,6 @@ const processContentType = async (
15251506

15261507
// 🧪 Process entries in batches (test migration: single entry, main migration: all entries)
15271508
const effectiveLimit = isTest ? 1 : LIMIT;
1528-
const maxIterations = isTest ? 1 : Math.ceil(totalCount / LIMIT); // Test: single iteration, Main: full pagination
15291509

15301510
for (
15311511
let i = 0;
@@ -1624,11 +1604,6 @@ export const createEntry = async (
16241604
destination_stack_id,
16251605
REFERENCES_DIR_NAME
16261606
);
1627-
const taxonomiesSave = path.join(
1628-
DATA,
1629-
destination_stack_id,
1630-
TAXONOMIES_DIR_NAME
1631-
);
16321607

16331608
// Initialize directories
16341609
await fs.promises.mkdir(entriesSave, { recursive: true });

api/src/services/drupal/locales.service.ts

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,16 +29,6 @@ async function writeFile(dirPath: string, filename: string, data: any) {
2929
}
3030
}
3131

32-
/**
33-
* Helper function to get key by value from an object
34-
*/
35-
function getKeyByValue(
36-
obj: Record<string, string>,
37-
targetValue: string
38-
): string | undefined {
39-
return Object.entries(obj).find(([_, value]) => value === targetValue)?.[0];
40-
}
41-
4232
/**
4333
* Maps source locale to destination locale based on user-selected mapping from UI.
4434
* Similar to WordPress/Contentful/Sitecore mapLocales function.
@@ -115,21 +105,6 @@ export function mapDrupalLocales({
115105
return locale?.toLowerCase?.() || locale;
116106
}
117107

118-
/**
119-
* Fetches locale names from Contentstack API
120-
*/
121-
async function fetchContentstackLocales(): Promise<Record<string, string>> {
122-
try {
123-
const response = await axios.get(
124-
'https://app.contentstack.com/api/v3/locales?include_all=true'
125-
);
126-
return response.data?.locales || {};
127-
} catch (error) {
128-
console.error('Error fetching Contentstack locales:', error);
129-
return {};
130-
}
131-
}
132-
133108
/**
134109
* Applies special locale code transformations based on business rules
135110
* - "und" alone → "en-us"
@@ -299,7 +274,7 @@ export const createLocale = async (
299274
const localesFromProject = project?.locales || {};
300275

301276
// 4. Fetch locale names from Contentstack API
302-
const [err, localesApiResponse] = await getAllLocales();
277+
const [localesApiResponse] = await getAllLocales();
303278
const contentstackLocales = localesApiResponse || {}; // ✅ FIX: getAllLocales already returns the locales object
304279

305280
// 5. Map source locales to destination locales using user selection

api/src/services/drupal/query.service.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,7 @@ import path from 'path';
33
import mysql from 'mysql2';
44
import { getDbConnection } from '../../helper/index.js';
55
import customLogger from '../../utils/custom-logger.utils.js';
6-
import { getLogMessage } from '../../utils/index.js';
76
import { MIGRATION_DATA_CONFIG } from '../../constants/index.js';
8-
import OptimizedQueryBuilder from '../../utils/optimized-query-builder.utils.js';
97

108
const { DATA } = MIGRATION_DATA_CONFIG;
119

@@ -132,8 +130,6 @@ const generateQueriesForFields = async (
132130
projectId: string,
133131
destination_stack_id: string
134132
): Promise<QueryConfig> => {
135-
const srcFunc = 'generateQueriesForFields';
136-
137133
try {
138134
const select: { [contentType: string]: string } = {};
139135
const countQuery: { [contentType: string]: string } = {};
@@ -330,7 +326,6 @@ export const createQuery = async (
330326
destination_stack_id: string,
331327
projectId: string
332328
): Promise<void> => {
333-
const srcFunc = 'createQuery';
334329
let connection: mysql.Connection | null = null;
335330

336331
try {
@@ -346,26 +341,31 @@ export const createQuery = async (
346341
user: dbConfig?.user,
347342
database: dbConfig?.database,
348343
port: dbConfig?.port,
349-
hasPassword: !!dbConfig?.password
344+
hasPassword: !!dbConfig?.password,
350345
});
351346

352347
const message = `Generating dynamic queries from Drupal database...`;
353348
await customLogger(projectId, destination_stack_id, 'info', message);
354349

355350
// Create database connection
356-
console.info(`🔍 query.service.ts - About to call getDbConnection with config:`, {
357-
host: dbConfig?.host,
358-
user: dbConfig?.user,
359-
database: dbConfig?.database
360-
});
361-
351+
console.info(
352+
`🔍 query.service.ts - About to call getDbConnection with config:`,
353+
{
354+
host: dbConfig?.host,
355+
user: dbConfig?.user,
356+
database: dbConfig?.database,
357+
}
358+
);
359+
362360
connection = await getDbConnection(
363361
dbConfig,
364362
projectId,
365363
destination_stack_id
366364
);
367-
368-
console.info(`🔍 query.service.ts - Database connection established successfully`);
365+
366+
console.info(
367+
`🔍 query.service.ts - Database connection established successfully`
368+
);
369369

370370
// SQL query to extract field configuration from Drupal
371371
const configQuery =

0 commit comments

Comments
 (0)