Skip to content

Commit

Permalink
feat: entries module supports taxonomy
Browse files Browse the repository at this point in the history
  • Loading branch information
aman19K committed Oct 4, 2023
1 parent e79f6f8 commit f0f880a
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 25 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default class ContentTypesImport extends BaseClass {
writeConcurrency?: number;
};
private taxonomiesPath: string;
public taxonomies: Record<string, unknown>[] = [];
public taxonomies: Record<string, unknown>;

constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
super({ importConfig, stackAPIClient });
Expand Down Expand Up @@ -97,7 +97,7 @@ export default class ContentTypesImport extends BaseClass {
this.installedExtensions = (
((await fsUtil.readFile(this.marketplaceAppMapperPath)) as any) || { extension_uid: {} }
).extension_uid;
this.taxonomies = fsUtil.readFile(this.taxonomiesPath) as Record<string, unknown>[];
this.taxonomies = fsUtil.readFile(this.taxonomiesPath) as Record<string, unknown>;

await this.seedCTs();
log(this.importConfig, 'Created content types', 'success');
Expand Down
8 changes: 8 additions & 0 deletions packages/contentstack-import/src/import/modules/entries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
lookupEntries,
lookupAssets,
fileHelper,
lookUpTerms,
} from '../../utils';
import { ModuleClassParams } from '../../types';
import BaseClass, { ApiOptions } from './base-class';
Expand Down Expand Up @@ -53,6 +54,8 @@ export default class EntriesImport extends BaseClass {
private entriesUidMapper: Record<string, any>;
private envs: Record<string, any>;
private autoCreatedEntries: Record<string, any>[];
private taxonomiesPath: string;
public taxonomies: Record<string, unknown>;

constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
super({ importConfig, stackAPIClient });
Expand All @@ -64,6 +67,7 @@ export default class EntriesImport extends BaseClass {
this.uniqueUidMapperPath = path.join(this.entriesMapperPath, 'unique-mapping.json');
this.modifiedCTsPath = path.join(this.entriesMapperPath, 'modified-schemas.json');
this.marketplaceAppMapperPath = path.join(this.importConfig.data, 'mapper', 'marketplace_apps', 'uid-mapping.json');
this.taxonomiesPath = path.join(this.importConfig.data, 'mapper', 'taxonomies', 'terms', 'success.json');
this.entriesConfig = importConfig.modules.entries;
this.entriesPath = path.resolve(importConfig.data, this.entriesConfig.dirName);
this.cTsPath = path.resolve(importConfig.data, importConfig.modules['content-types'].dirName);
Expand Down Expand Up @@ -96,6 +100,8 @@ export default class EntriesImport extends BaseClass {

this.assetUidMapper = (fsUtil.readFile(this.assetUidMapperPath) as Record<string, any>) || {};
this.assetUrlMapper = (fsUtil.readFile(this.assetUrlMapperPath) as Record<string, any>) || {};

this.taxonomies = (fsUtil.readFile(this.taxonomiesPath) as Record<string, any>);

fsUtil.makeDirectory(this.entriesMapperPath);
await this.disableMandatoryCTReferences();
Expand Down Expand Up @@ -360,6 +366,8 @@ export default class EntriesImport extends BaseClass {
if (this.jsonRteCTsWithRef.indexOf(cTUid) > -1) {
entry = removeEntryRefsFromJSONRTE(entry, contentType.schema);
}
//will remove term if term doesn't exists in taxonomy
lookUpTerms(contentType?.schema, entry, this.taxonomies);
// will replace all old asset uid/urls with new ones
entry = lookupAssets(
{
Expand Down
5 changes: 3 additions & 2 deletions packages/contentstack-import/src/import/modules/taxonomies.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import keys from 'lodash/keys';
import pick from 'lodash/pick';
import { join } from 'node:path';
import values from 'lodash/values';
import isEmpty from 'lodash/isEmpty';
Expand Down Expand Up @@ -128,7 +129,7 @@ export default class ImportTaxonomies extends BaseClass {
//NOTE - Temp code to handle error thru API. Will remove this once sdk is ready
if ([200, 201, 202].includes(status)) {
const { taxonomy } = data;
this.taxonomiesSuccess[taxonomy.uid] = taxonomy;
this.taxonomiesSuccess[taxonomy.uid] = pick(taxonomy, ['name', 'description']);
log(this.importConfig, `Taxonomy '${name}' imported successfully`, 'success');
} else {
let errorMsg:any;
Expand Down Expand Up @@ -223,7 +224,7 @@ export default class ImportTaxonomies extends BaseClass {
if ([200, 201, 202].includes(status)) {
if (!this.termsSuccess[taxonomy_uid]) this.termsSuccess[taxonomy_uid] = {};
const { term } = data;
this.termsSuccess[taxonomy_uid][term.uid] = term;
this.termsSuccess[taxonomy_uid][term.uid] = pick(term, ['name']);
log(this.importConfig, `Term '${name}' imported successfully`, 'success');
} else {
if (!this.termsFailed[taxonomy_uid]) this.termsFailed[taxonomy_uid] = {};
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-import/src/utils/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,4 @@ export {
restoreJsonRteEntryRefs,
} from './entries-helper';
export * from './common-helper';
export { lookUpTaxonomy } from './taxonomies-helper';
export { lookUpTaxonomy, lookUpTerms } from './taxonomies-helper';
120 changes: 100 additions & 20 deletions packages/contentstack-import/src/utils/taxonomies-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,32 +3,112 @@
*/
import { cliux } from '@contentstack/cli-utilities';

export const lookUpTaxonomy = function (schema: any, taxonomies: Record<string, unknown>[]) {
/**
* check and remove if referenced taxonomy doesn't exists in stack
* @param {any} schema content type schema
* @param {Record<string, unknown>} taxonomies created taxonomies
*/
export const lookUpTaxonomy = function (schema: any, taxonomies: Record<string, unknown>) {
for (let i in schema) {
if (schema[i].data_type === 'taxonomy') {
const taxonomyFieldData = schema[i].taxonomies as Record<string, any>[];
if (!taxonomyFieldData.length) break;
for (let index = 0; index < taxonomyFieldData.length; index++) {
const taxonomyData = taxonomyFieldData[index];
if (taxonomies === undefined || !taxonomies[taxonomyData?.taxonomy_uid]) {
// remove taxonomy from taxonomies field data with warning
cliux.print(
`Taxonomy '${taxonomyData?.taxonomy_uid}' does not exist. Removing the data from taxonomy field`,
{ color: 'yellow' },
);
taxonomyFieldData.splice(index, 1);
--index;
}
}
//Case 1:- if no taxonomy exist and trying to create taxonomies field API error -> The 'taxonomies' property must have atleast one taxonomy object.
if (!taxonomyFieldData?.length) {
cliux.print(`Content type related Taxonomy does not exist in stack. Removing the field from schema`, {
color: 'yellow',
});
const { updatedTaxonomyData, isTaxonomyFieldRemoved } = verifyAndRemoveTaxonomy(taxonomyFieldData, taxonomies);

//Handle API error -> The 'taxonomies' property must have atleast one taxonomy object. Remove taxonomy field from schema.
if (isTaxonomyFieldRemoved) {
schema.splice(i, 1);
} else {
schema[i].taxonomies = taxonomyFieldData;
schema[i].taxonomies = updatedTaxonomyData;
}
}
}
};

/**
* verify and remove referenced taxonomy with warning from respective content type
* @param {Record<string, any>[]} taxonomyFieldData
* @param {Record<string, unknown>} taxonomies created taxonomies
* @returns
*/
const verifyAndRemoveTaxonomy = function (
taxonomyFieldData: Record<string, any>[],
taxonomies: Record<string, unknown>,
): {
updatedTaxonomyData: Record<string, any>[];
isTaxonomyFieldRemoved: boolean;
} {
let isTaxonomyFieldRemoved: boolean = false;

for (let index = 0; index < taxonomyFieldData?.length; index++) {
const taxonomyData = taxonomyFieldData[index];

if (taxonomies === undefined || !taxonomies.hasOwnProperty(taxonomyData?.taxonomy_uid)) {
// remove taxonomy from taxonomies field data with warning if respective taxonomy doesn't exists
cliux.print(`Taxonomy '${taxonomyData?.taxonomy_uid}' does not exist. Removing the data from taxonomies field`, {
color: 'yellow',
});
taxonomyFieldData.splice(index, 1);
--index;
}
}

if (!taxonomyFieldData?.length) {
cliux.print('Taxonomy does not exist. Removing the field from content type', { color: 'yellow' });
isTaxonomyFieldRemoved = true;
}

return {
updatedTaxonomyData: taxonomyFieldData,
isTaxonomyFieldRemoved,
};
};

/**
* check and remove if referenced terms doesn't exists in taxonomy
* @param {Record<string, any>[]} ctSchema content type schema
* @param {any} entry
* @param {Record<string, any>} taxonomiesAndTermData created taxonomies and terms
*/
export const lookUpTerms = function (
ctSchema: Record<string, any>[],
entry: any,
taxonomiesAndTermData: Record<string, any>,
) {
for (let index = 0; index < ctSchema?.length; index++) {
if (ctSchema[index].data_type === 'taxonomy') {
const taxonomyFieldData = entry[ctSchema[index].uid];
const updatedTaxonomyData = verifyAndRemoveTerms(taxonomyFieldData, taxonomiesAndTermData);
entry[ctSchema[index].uid] = updatedTaxonomyData;
}
}
};

/**
* verify and remove referenced term with warning from respective entry
* @param {Record<string, any>[]} taxonomyFieldData entry taxonomies data
* @param {Record<string, any>} taxonomiesAndTermData created taxonomies and terms
* @returns { Record<string, any>[]}
*/
const verifyAndRemoveTerms = function (
taxonomyFieldData: Record<string, any>[],
taxonomiesAndTermData: Record<string, any>,
): Record<string, any>[] {
for (let index = 0; index < taxonomyFieldData?.length; index++) {
const taxonomyData = taxonomyFieldData[index];
const taxUID = taxonomyData?.taxonomy_uid;
const termUID = taxonomyData?.term_uid;

if (
taxonomiesAndTermData === undefined ||
!taxonomiesAndTermData.hasOwnProperty(taxUID) ||
(taxonomiesAndTermData.hasOwnProperty(taxUID) && !taxonomiesAndTermData[taxUID].hasOwnProperty(termUID))
) {
// remove term from taxonomies field data with warning if respective term doesn't exists
cliux.print(`Term '${termUID}' does not exist. Removing it from taxonomy - '${taxUID}'`, { color: 'yellow' });
taxonomyFieldData.splice(index, 1);
--index;
}
}

return taxonomyFieldData;
};

0 comments on commit f0f880a

Please sign in to comment.