Skip to content

Commit

Permalink
Merge pull request #1287 from contentstack/feat/CS-43753
Browse files Browse the repository at this point in the history
Export | Taxonomy | Replace taxonomy all terms api with export api
  • Loading branch information
aman19K authored Feb 7, 2024
2 parents c8850fe + 8bb704d commit ae9faa7
Show file tree
Hide file tree
Showing 12 changed files with 1,023 additions and 235 deletions.
594 changes: 532 additions & 62 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/contentstack-export/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-cm-export/1.10.5 darwin-arm64 node-v20.8.0
@contentstack/cli-cm-export/1.11.0 darwin-arm64 node-v18.19.0
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-export/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-cm-export",
"description": "Contentstack CLI plugin to export content from stack",
"version": "1.10.5",
"version": "1.11.0",
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"dependencies": {
Expand Down
9 changes: 2 additions & 7 deletions packages/contentstack-export/src/config/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -165,13 +165,8 @@ const config: DefaultConfig = {
taxonomies: {
dirName: 'taxonomies',
fileName: 'taxonomies.json',
invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath'],
},
terms: {
dirName: 'terms',
fileName: 'terms.json',
invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath'],
},
invalidKeys: ['updated_at', 'created_by', 'updated_by', 'stackHeaders', 'urlPath', 'created_at'],
}
},
languagesCode: [
'af-za',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ export type ApiModuleType =
| 'content-types'
| 'stacks'
| 'versioned-entries'
| 'download-asset';
| 'download-asset'
| 'export-taxonomy';

export default abstract class BaseClass {
readonly client: any;
Expand Down Expand Up @@ -176,6 +177,12 @@ export default abstract class BaseClass {
.download({ url, responseType: 'stream' })
.then((response: any) => resolve({ response, isLastRequest, additionalInfo }))
.catch((error: any) => reject({ error, isLastRequest, additionalInfo }));
case 'export-taxonomy':
return this.stack
.taxonomy(uid)
.export()
.then((response: any) => resolve({ response, uid }))
.catch((error: any) => reject({ error, uid }));
default:
return Promise.resolve();
}
Expand Down
104 changes: 30 additions & 74 deletions packages/contentstack-export/src/export/modules/taxonomies.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,54 @@ import { resolve as pResolve } from 'node:path';

import BaseClass from './base-class';
import { log, fsUtil } from '../../utils';
import { TaxonomiesConfig, TermsConfig, ModuleClassParams } from '../../types';
import { TaxonomiesConfig, ModuleClassParams } from '../../types';

export default class ExportTaxonomies extends BaseClass {
private taxonomies: Record<string, Record<string, string>>;
private terms: Record<string, unknown>[];
private taxonomiesConfig: TaxonomiesConfig;
private termsConfig: TermsConfig;
private qs: {
include_count: boolean;
skip: number;
asc: string;
depth?: number;
};
public taxonomiesFolderPath: string;
public termsFolderPath: string;

constructor({ exportConfig, stackAPIClient }: ModuleClassParams) {
super({ exportConfig, stackAPIClient });
this.taxonomies = {};
this.terms = [];
this.taxonomiesConfig = exportConfig.modules.taxonomies;
this.termsConfig = exportConfig.modules.terms;
this.qs = { include_count: true, skip: 0, asc: 'created_at' };
}

async start(): Promise<void> {
log(this.exportConfig, 'Starting taxonomies export', 'info');

//create taxonomies and terms folder in data directory path
//create taxonomies folder
this.taxonomiesFolderPath = pResolve(
this.exportConfig.data,
this.exportConfig.branchName || '',
this.taxonomiesConfig.dirName,
);
await fsUtil.makeDirectory(this.taxonomiesFolderPath);
this.termsFolderPath = pResolve(this.taxonomiesFolderPath, this.termsConfig.dirName);
await fsUtil.makeDirectory(this.termsFolderPath);

//fetch all taxonomies and write into taxonomies folder
await this.getAllTaxonomies();
if (this.taxonomies === undefined || isEmpty(this.taxonomies)) {
log(this.exportConfig, 'No taxonomies found!', 'info');
return;
} else {
fsUtil.writeFile(pResolve(this.taxonomiesFolderPath, this.taxonomiesConfig.fileName), this.taxonomies);
log(this.exportConfig, 'All taxonomies exported successfully!', 'success');
fsUtil.writeFile(pResolve(this.taxonomiesFolderPath, 'taxonomies.json'), this.taxonomies);
await this.exportTaxonomies();
}

//fetch all terms of respective and write into taxonomies/terms folder
await this.getAllTerms();
log(this.exportConfig, `Taxonomies exported!`, 'success');
}

/**
* fetch all taxonomies in the provided stack
* @param {number} skip
* @returns {Promise<any>}
*/
async getAllTaxonomies(skip = 0): Promise<any> {
async getAllTaxonomies(skip: number = 0): Promise<any> {
if (skip) {
this.qs.skip = skip;
}
Expand Down Expand Up @@ -97,75 +87,41 @@ export default class ExportTaxonomies extends BaseClass {
for (let index = 0; index < taxonomies?.length; index++) {
const taxonomyUID = taxonomies[index].uid;
this.taxonomies[taxonomyUID] = omit(taxonomies[index], this.taxonomiesConfig.invalidKeys);
log(this.exportConfig, `'${taxonomyUID}' taxonomy exported successfully!`, 'success');
}
}

/**
* fetch all terms of respective taxonomy and write it into <taxonomy-uid>-terms file
* Export all taxonomies details using metadata(this.taxonomies) and write it into respective <taxonomy-uid>.json file
* @returns {Promise<void>}
*/
async getAllTerms() {
async exportTaxonomies(): Promise<void> {
const taxonomiesUID = keys(this.taxonomies) || [];
this.qs.depth = 0;

for (let index = 0; index < taxonomiesUID?.length; index++) {
const taxonomyUID = taxonomiesUID[index];
this.terms = [];
await this.fetchTermsOfTaxonomy(taxonomyUID);
if (!this.terms?.length) {
log(this.exportConfig, `No terms found for taxonomy - '${taxonomyUID}'!`, 'info');
const onSuccess = ({ response, uid }: any) => {
const filePath = pResolve(this.taxonomiesFolderPath, `${uid}.json`);
fsUtil.writeFile(filePath, response);
log(this.exportConfig, `'${uid}' taxonomy exported successfully!`, 'success');
};

const onReject = ({ error, uid }: any) => {
if (error?.errorMessage) {
log(this.exportConfig, `Failed to export taxonomy - '${uid}'! ${error.errorMessage}`, 'error');
} else if (error?.message) {
const errorMsg = error?.errors?.taxonomy || error?.errors?.term || error?.message;
log(this.exportConfig, `Failed to export taxonomy - '${uid}'! ${errorMsg}`, 'error');
} else {
fsUtil.writeFile(pResolve(this.termsFolderPath, `${taxonomyUID}-${this.termsConfig.fileName}`), this.terms);
log(this.exportConfig, `Terms from taxonomy '${taxonomyUID}' exported successfully!`, 'success');
log(this.exportConfig, `Failed to export taxonomy - '${uid}'! ${error}`, 'error');
}
}
log(this.exportConfig, `All the terms exported successfully!`, 'success');
}

/**
* fetch all terms of the provided taxonomy uid
* @async
* @param {string} taxonomyUID
* @param {number} skip
* @returns {Promise<any>}
*/
async fetchTermsOfTaxonomy(taxonomyUID: string, skip = 0): Promise<any> {
if (skip) {
this.qs.skip = skip;
}
await this.stack
.taxonomy(taxonomyUID)
.terms()
.query(this.qs)
.find()
.then(async (data: any) => {
const { items, count } = data;
const termsCount = count !== undefined ? count : items?.length;
};

if (items?.length) {
this.sanitizeTermsAttribs(items);
skip += this.taxonomiesConfig.limit || 100;
if (skip >= termsCount) {
return;
}
return await this.fetchTermsOfTaxonomy(taxonomyUID, skip);
}
})
.catch((error: any) => {
this.handleErrorMsg(error);
for (let index = 0; index < taxonomiesUID?.length; index++) {
const taxonomyUID = taxonomiesUID[index];
await this.makeAPICall({
reject: onReject,
resolve: onSuccess,
uid: taxonomyUID,
module: 'export-taxonomy',
});
}

/**
* remove invalid keys and write data into taxonomies
* @function sanitizeTaxonomiesAttribs
* @param terms
*/
sanitizeTermsAttribs(terms: Record<string, string>[]) {
for (let index = 0; index < terms?.length; index++) {
const term = omit(terms[index], this.termsConfig.invalidKeys);
this.terms.push(term)
}
}

Expand All @@ -175,7 +131,7 @@ export default class ExportTaxonomies extends BaseClass {
} else if (err?.message) {
const errorMsg = err?.errors?.taxonomy || err?.errors?.term || err?.message;
log(this.exportConfig, `Failed to export! ${errorMsg}`, 'error');
}else{
} else {
log(this.exportConfig, `Failed to export! ${err}`, 'error');
}
}
Expand Down
6 changes: 0 additions & 6 deletions packages/contentstack-export/src/types/default-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,6 @@ export default interface DefaultConfig {
invalidKeys: string[];
dependencies?: Modules[];
};
terms: {
dirName: string;
fileName: string;
invalidKeys: string[];
dependencies?: Modules[];
};
};
languagesCode: string[];
apis: {
Expand Down
18 changes: 5 additions & 13 deletions packages/contentstack-export/src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,37 +100,29 @@ export interface WebhookConfig {
limit?: number;
}

export interface WorkflowConfig{
export interface WorkflowConfig {
dirName: string;
fileName: string;
invalidKeys: string[];
dependencies?: Modules[];
limit?: number;
}

export interface CustomRoleConfig{
export interface CustomRoleConfig {
dirName: string;
fileName: string;
customRolesLocalesFileName: string;
dependencies?: Modules[];
}

export interface StackConfig{
dirName: string;
fileName: string;
dependencies?: Modules[];
limit?: number;
}

export interface TaxonomiesConfig{
export interface StackConfig {
dirName: string;
fileName: string;
invalidKeys: string[];
dependencies?: Modules[];
limit?: number;
}

export interface TermsConfig{
export interface TaxonomiesConfig {
dirName: string;
fileName: string;
invalidKeys: string[];
Expand All @@ -140,4 +132,4 @@ export interface TermsConfig{

export { default as DefaultConfig } from './default-config';
export { default as ExportConfig } from './export-config';
export * from './marketplace-app'
export * from './marketplace-app';
2 changes: 1 addition & 1 deletion packages/contentstack-import/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
"@contentstack/cli-audit": "^1.3.5",
"@contentstack/cli-command": "~1.2.16",
"@contentstack/cli-utilities": "~1.5.11",
"@contentstack/management": "~1.13.0",
"@contentstack/management": "^1.15.1",
"@oclif/core": "^2.9.3",
"big-json": "^3.2.0",
"bluebird": "^3.7.2",
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-utilities/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"author": "contentstack",
"license": "MIT",
"dependencies": {
"@contentstack/management": "~1.13.0",
"@contentstack/management": "^1.15.1",
"@contentstack/marketplace-sdk": "^1.0.1",
"@oclif/core": "^2.9.3",
"axios": "^1.6.4",
Expand Down
4 changes: 2 additions & 2 deletions packages/contentstack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
"@contentstack/cli-cm-bootstrap": "~1.7.1",
"@contentstack/cli-cm-branches": "~1.0.22",
"@contentstack/cli-cm-bulk-publish": "~1.4.0",
"@contentstack/cli-cm-export": "~1.10.5",
"@contentstack/cli-cm-export": "~1.11.0",
"@contentstack/cli-cm-clone": "~1.10.0",
"@contentstack/cli-cm-export-to-csv": "~1.6.2",
"@contentstack/cli-cm-import": "~1.13.3",
Expand All @@ -38,7 +38,7 @@
"@contentstack/cli-launch": "~1.0.16",
"@contentstack/cli-migration": "~1.4.2",
"@contentstack/cli-utilities": "~1.5.11",
"@contentstack/management": "~1.13.0",
"@contentstack/management": "~1.15.1",
"@oclif/core": "^2.9.3",
"@oclif/plugin-help": "^5",
"@oclif/plugin-not-found": "^2.4.0",
Expand Down
Loading

0 comments on commit ae9faa7

Please sign in to comment.