Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CS-43546: Update in import command #1253

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/contentstack-clone/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
"dependencies": {
"@contentstack/cli-cm-export": "~1.10.2",
"@contentstack/cli-cm-import": "~1.13.0",
"@contentstack/cli-cm-import": "~1.13.1",
"@contentstack/cli-command": "~1.2.16",
"@contentstack/cli-utilities": "~1.5.10",
"@colors/colors": "^1.5.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-import/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-cm-import",
"description": "Contentstack CLI plugin to import content into stack",
"version": "1.13.0",
"version": "1.13.1",
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { fsUtil, log, formatError, schemaTemplate, lookupExtension, lookUpTaxono
import { ImportConfig, ModuleClassParams } from '../../types';
import BaseClass, { ApiOptions } from './base-class';
import { updateFieldRules } from '../../utils/content-type-helper';
import { getAllContentTypesFromStack } from './../../utils/common-helper'

export default class ContentTypesImport extends BaseClass {
private cTsMapperPath: string;
Expand Down Expand Up @@ -51,6 +52,9 @@ export default class ContentTypesImport extends BaseClass {
};
private taxonomiesPath: string;
public taxonomies: Record<string, unknown>;
private extScopePath: string;
private extUidMapperPath: string;
private extSuccessPath: string;

constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
super({ importConfig, stackAPIClient });
Expand Down Expand Up @@ -78,6 +82,10 @@ export default class ContentTypesImport extends BaseClass {
this.createdGFs = [];
this.pendingGFs = [];
this.taxonomiesPath = path.join(importConfig.data, 'mapper/taxonomies', 'success.json');
this.stackAPIClient = stackAPIClient;
this.extScopePath = path.join(this.importConfig.backupDir,importConfig.modules.extensions.dirName,'scope.json')
this.extUidMapperPath = path.join(this.importConfig.backupDir, 'mapper', 'extensions','uid-mapping.json');
this.extSuccessPath = path.join(this.importConfig.backupDir, 'mapper', 'extensions','success.json')
}

async start(): Promise<any> {
Expand Down Expand Up @@ -111,6 +119,8 @@ export default class ContentTypesImport extends BaseClass {
});
log(this.importConfig, 'Updated pending global fields with content type with references', 'success');
log(this.importConfig, 'Content types have been imported successfully!', 'success');
const contentTypeTitle = await getAllContentTypesFromStack(this.stackAPIClient);
await this.lookupExtensionScope(contentTypeTitle)
}

async seedCTs(): Promise<any> {
Expand Down Expand Up @@ -250,4 +260,73 @@ export default class ContentTypesImport extends BaseClass {
apiOptions.apiData = globalFieldPayload;
return apiOptions;
}

async lookupExtensionScope(contentTypeTitles:any,) {
const extension = await fsUtil.readFile(this.extScopePath);
const extensionToBeCreated: any = []
if(Array.isArray(extension)){
extension.forEach((ext:any)=>{
let isAllCtPresent:boolean = true;
ext?.scope?.content_types.forEach((ct:string)=>{
if(!contentTypeTitles.includes(ct)){
isAllCtPresent = false;
log(this.importConfig,`For Extension '${ext.title}' content type '${ct}' is not present. Skipping this extension creation`,'error');
}
})
if(isAllCtPresent) {
extensionToBeCreated.push(ext);
}
})
}
if(extensionToBeCreated.length===0){
log(this.importConfig,`No extension found to be dependent on Content types`,'info');
} else {
const apiContent = extensionToBeCreated
const extSuccess:any = fsUtil.readFile(this.extSuccessPath);
const extUidMapper:any = fsUtil.readFile(this.extUidMapperPath);
const existingExtensions = [];
const extFailed = [];

const onSuccess = ({ response, apiData: { uid, title } = { uid: null, title: '' } }: any) => {
extSuccess.push(response);
extUidMapper[uid] = response.uid;
log(this.importConfig, `Extension '${title}' imported successfully`, 'success');
fsUtil.writeFile(this.extUidMapperPath, extUidMapper);
};

const onReject = ({ error, apiData }: any) => {
const { title } = apiData;
if (error?.errors?.title) {
if (this.importConfig.replaceExisting) {
existingExtensions.push(apiData);
}
if (!this.importConfig.skipExisting) {
log(this.importConfig, `Extension '${title}' already exists`, 'info');
}
} else {
extFailed.push(apiData);
log(this.importConfig, `Extension '${title}' failed to be import ${formatError(error)}`, 'error');
log(this.importConfig, error, 'error');
}
};

await this.makeConcurrentCall(
{
apiContent,
processName: 'import extensions',
apiParams: {
reject: onReject.bind(this),
resolve: onSuccess.bind(this),
entity: 'create-extensions',
includeParamOnCompletion: true,
},
concurrencyLimit: this.importConfig.concurrency || this.importConfig.fetchConcurrency || 1,
},
undefined,
false,
);
fsUtil.writeFile(this.extSuccessPath, extSuccess);
}

}
}
24 changes: 23 additions & 1 deletion packages/contentstack-import/src/import/modules/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default class ImportExtensions extends BaseClass {
private extSuccess: Record<string, unknown>[];
private extFailed: Record<string, unknown>[];
private existingExtensions: Record<string, unknown>[];
private extScopePath: string;

constructor({ importConfig, stackAPIClient }: ModuleClassParams) {
super({ importConfig, stackAPIClient });
Expand All @@ -28,6 +29,7 @@ export default class ImportExtensions extends BaseClass {
this.extUidMapperPath = join(this.mapperDirPath, 'uid-mapping.json');
this.extSuccessPath = join(this.mapperDirPath, 'success.json');
this.extFailsPath = join(this.mapperDirPath, 'fails.json');
this.extScopePath = join(this.extensionsFolderPath,'scope.json')
this.extFailed = [];
this.extSuccess = [];
this.existingExtensions = [];
Expand Down Expand Up @@ -56,7 +58,7 @@ export default class ImportExtensions extends BaseClass {
this.extUidMapper = fileHelper.fileExistsSync(this.extUidMapperPath)
? (fsUtil.readFile(join(this.extUidMapperPath), true) as Record<string, unknown>)
: {};

await this.getContentTypesInScope();
await this.importExtensions();

// Note: if any extensions present, then update it
Expand Down Expand Up @@ -209,4 +211,24 @@ export default class ImportExtensions extends BaseClass {
}
});
}

async getContentTypesInScope(){
const extension = values(this.extensions);
const extensionObject:{string:Record<string,unknown>}[] = []
type extType = {
uid: string,
scope: Record<string,unknown>
}
extension.forEach((ext:any)=>{
let ct:any = ext?.scope?.content_types || [];
if(ct.length===1 && (ct[0]!=='$all')){
extensionObject.push(ext)
delete this.extensions[ext.uid]
} else if(ct?.length>1) {
extensionObject.push(ext)
delete this.extensions[ext.uid]
}
})
fsUtil.writeFile(this.extScopePath, extensionObject);
}
}
46 changes: 46 additions & 0 deletions packages/contentstack-import/src/utils/common-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,49 @@ export const formatDate = (date: Date = new Date()) => {

return formattedDate;
};

// Get all the content types to validate whether all the content types are present in scope for the given extension
export const getAllContentTypesFromStack:any = async (stackAPIClient:any) => {
try{
let contentTypes:any[] = []
const contentTypeCount:number = await getContentTypeCount(stackAPIClient);
for (let index = 0; index <= contentTypeCount / 100; index++) {
const contentTypesMap = await getContentTypes(stackAPIClient, index);
contentTypes = contentTypes.concat((Object.keys(contentTypesMap))); // prompt for content Type
}
return contentTypes
} catch (err) {
return err;
}
}

function getContentTypeCount(stackAPIClient:any):number|any {
return new Promise((resolve, reject) => {
stackAPIClient
.contentType()
.query()
.count()
.then((contentTypes:any) => resolve(contentTypes.content_types))
.catch((error:any) => reject(error));
});
}


function getContentTypes(stackAPIClient:any, skip:any) {
return new Promise((resolve, reject) => {
let result:any = {};
stackAPIClient
.contentType()
.query({ skip: skip * 100, include_branch: true })
.find()
.then((contentTypes:any) => {
contentTypes.items.forEach((contentType:any) => {
result[contentType.title] = contentType.uid;
});
resolve(result);
})
.catch((error:any) => {
reject(error);
});
});
}
10 changes: 10 additions & 0 deletions packages/contentstack-import/src/utils/content-type-helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,16 @@ export const removeReferenceFields = async function (
flag.supressed = true;
schema[i].reference_to = ['sys_assets'];
}
else if (
// handling entry references in rte
schema[i].data_type === 'text' &&
schema[i].field_metadata.rich_text_type &&
schema[i].field_metadata.embed_entry &&
schema[i].reference_to.length >= 1
) {
flag.supressed = true;
schema[i].reference_to = ['sys_assets'];
}
}
};

Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-seed/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"dependencies": {
"@contentstack/cli-cm-import": "~1.13.0",
"@contentstack/cli-cm-import": "~1.13.1",
"@contentstack/cli-command": "~1.2.16",
"@contentstack/cli-utilities": "~1.5.10",
"inquirer": "8.2.4",
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
"@contentstack/cli-cm-clone": "~1.9.0",
"@contentstack/cli-cm-export": "~1.10.2",
"@contentstack/cli-cm-export-to-csv": "~1.6.2",
"@contentstack/cli-cm-import": "~1.13.0",
"@contentstack/cli-cm-import": "~1.13.1",
"@contentstack/cli-cm-migrate-rte": "~1.4.15",
"@contentstack/cli-cm-seed": "~1.7.1",
"@contentstack/cli-command": "~1.2.17",
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.