Skip to content

Commit

Permalink
added the case to update the extensions that depend on the content-ty…
Browse files Browse the repository at this point in the history
…pe creation first
  • Loading branch information
cs-raj committed Jan 22, 2024
1 parent 2e2550c commit a06c592
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 12 deletions.
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
79 changes: 79 additions & 0 deletions packages/contentstack-import/src/import/modules/content-types.ts
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);
});
});
}
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.

0 comments on commit a06c592

Please sign in to comment.