Skip to content
This repository has been archived by the owner on Feb 27, 2024. It is now read-only.

Commit

Permalink
feat: adds support for preserving publish & fixes custom workflow ste…
Browse files Browse the repository at this point in the history
…p assignment
  • Loading branch information
Enngage committed Feb 24, 2021
1 parent 5414de5 commit ac1e8a0
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 9 deletions.
5 changes: 4 additions & 1 deletion src/core/core.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export interface ICliFileConfig {
action: CliAction;
zipFilename: string;
enableLog: boolean;
enablePublish: boolean;
force: boolean;
baseUrl?: string;
exportFilter?: ItemType[]
Expand All @@ -41,6 +42,8 @@ export type ItemType =
| 'workflowStep'
| 'binaryFile';

export type ActionType = ItemType | 'publish' | 'changeWorkflowStep';

export type ValidImportModel =
| ContentTypeModels.ContentType
| TaxonomyModels.Taxonomy
Expand All @@ -64,7 +67,7 @@ export type ValidImportContract =

export interface IProcessedItem {
title: string;
type: ItemType;
type: ActionType;
data: any;
}

Expand Down
3 changes: 3 additions & 0 deletions src/import/import.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import {
LanguageVariantContracts,
TaxonomyContracts,
ProjectContracts,
WorkflowContracts,
} from '@kentico/kontent-management';

import { IProcessedItem, ItemType, IPackageMetadata } from '../core';

export interface IImportConfig {
workflowIdForImportedItems?: string;
enablePublish: boolean
baseUrl?: string;
projectId: string;
apiKey: string;
Expand Down Expand Up @@ -63,6 +65,7 @@ export interface IImportSource {
languageVariants: LanguageVariantContracts.ILanguageVariantModelContract[];
languages: LanguageContracts.ILanguageModelContract[];
assets: AssetContracts.IAssetModelContract[];
workflowSteps: WorkflowContracts.IWorkflowStepContract[];
};
metadata: IPackageMetadata;
validation: ProjectContracts.IProjectReportResponseContract;
Expand Down
94 changes: 87 additions & 7 deletions src/import/import.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ import {
ManagementClient,
SharedModels,
TaxonomyContracts,
TaxonomyModels
TaxonomyModels,
WorkflowContracts
} from '@kentico/kontent-management';

import {
idTranslateHelper,
IImportItemResult,
ItemType,
ActionType,
translationHelper,
ValidImportContract,
ValidImportModel
Expand All @@ -34,6 +35,7 @@ export class ImportService {
private readonly defaultLanguageId: string = '00000000-0000-0000-0000-000000000000';
private readonly defaultWorkflowId: string = '00000000-0000-0000-0000-000000000000';
private readonly client: IManagementClient;
private readonly publishedWorkflowStepName: string = 'Published';

/**
* Maximum allowed size of asset in Bytes.
Expand Down Expand Up @@ -172,6 +174,14 @@ export class ImportService {
importedItems
);
importedItems.push(...importedLanguageVariants);

if (this.config.enablePublish) {
await this.publishLanguageVariantsAsync(sourceData.importData.languageVariants, sourceData.importData.workflowSteps);
}

if (this.config.workflowIdForImportedItems) {
await this.moveLanguageVariantsToCustomWorkflowStepAsync(this.config.workflowIdForImportedItems, sourceData.importData.languageVariants);
}
} else {
if (this.config.enableLog) {
console.log(`Skipping language variants`);
Expand All @@ -196,6 +206,7 @@ export class ImportService {
translationHelper.replaceIdReferencesWithCodenames(source.importData.assets, source.importData, {});
translationHelper.replaceIdReferencesWithCodenames(source.importData.contentItems, source.importData, {});
translationHelper.replaceIdReferencesWithCodenames(source.importData.languageVariants, source.importData, {});
translationHelper.replaceIdReferencesWithCodenames(source.importData.workflowSteps, source.importData, {});
}

private removeSkippedItemsFromImport(source: IImportSource): void {
Expand Down Expand Up @@ -607,6 +618,75 @@ export class ImportService {
return importedItems;
}

private async publishLanguageVariantsAsync(
languageVariants: LanguageVariantContracts.ILanguageVariantModelContract[],
workflowSteps: WorkflowContracts.IWorkflowStepContract[]
): Promise<void> {
const publishedWorkflowStep = this.getPublishedWorkflowStep(workflowSteps);

if (!publishedWorkflowStep) {
// published workflow step was not found
return;
}

const itemsToPublish = languageVariants.filter(m => m.workflow_step.id === publishedWorkflowStep.id);

if (!itemsToPublish.length) {
// no items to publish
return;
}

for (const itemToPublish of itemsToPublish) {
const itemCodename: string | undefined = itemToPublish.item.codename;
const languageCodename: string | undefined = itemToPublish.language.codename;

if (!itemCodename) {
throw Error(`Missing item codename for item`);
}
if (!languageCodename) {
throw Error(`Missing language codename for item`);
}

await this.client
.publishLanguageVariant()
.byItemCodename(itemCodename)
.byLanguageCodename(languageCodename)
.withoutData()
.toPromise()
.then((response) => {
this.processItem(`${itemCodename} (${languageCodename})`, 'publish', response.data);
})
.catch((error) => this.handleImportError(error));
}
}

private async moveLanguageVariantsToCustomWorkflowStepAsync(workflowStepId: string,
languageVariants: LanguageVariantContracts.ILanguageVariantModelContract[]
): Promise<void> {
for (const item of languageVariants) {
const itemCodename: string | undefined = item.item.codename;
const languageCodename: string | undefined = item.language.codename;

if (!itemCodename) {
throw Error(`Missing item codename for item`);
}
if (!languageCodename) {
throw Error(`Missing language codename for item`);
}

await this.client
.changeWorkflowStepOfLanguageVariant()
.byItemCodename(itemCodename)
.byLanguageCodename(languageCodename)
.byWorkflowStepId(workflowStepId)
.toPromise()
.then((response) => {
this.processItem(`${itemCodename} (${languageCodename})`, 'changeWorkflowStep', response.data);
})
.catch((error) => this.handleImportError(error));
}
}

private async importLanguageVariantsAsync(
languageVariants: LanguageVariantContracts.ILanguageVariantModelContract[],
currentItems: IImportItemResult<ValidImportContract, ValidImportModel>[]
Expand Down Expand Up @@ -635,10 +715,6 @@ export class ImportService {
// replace ids in assets with new ones
idTranslateHelper.replaceIdReferencesWithNewId(languageVariant, currentItems);

// set workflow id (there is no API to create workflows programatically)
const newWorkflowId: string = this.config.workflowIdForImportedItems ?? this.defaultWorkflowId;
languageVariant.workflow_step.id = newWorkflowId;

await this.client
.upsertLanguageVariant()
.byItemCodename(itemCodename)
Expand Down Expand Up @@ -724,7 +800,7 @@ export class ImportService {
throw error;
}

private processItem(title: string, type: ItemType, data: any): void {
private processItem(title: string, type: ActionType, data: any): void {
if (!this.config.onImport) {
return;
}
Expand Down Expand Up @@ -817,4 +893,8 @@ export class ImportService {
folders: folder.folders?.map((m) => this.mapAssetFolder(m)) ?? []
};
}

private getPublishedWorkflowStep(workflowSteps: WorkflowContracts.IWorkflowStepContract[]): WorkflowContracts.IWorkflowStepContract | undefined {
return workflowSteps.find(m => m.name === this.publishedWorkflowStepName);
}
}
3 changes: 3 additions & 0 deletions src/node-js/cli/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const restoreAsync = async (config: ICliFileConfig) => {
console.log(`Imported: ${item.title} | ${item.type}`);
}
},
enablePublish: config.enablePublish,
baseUrl: config.baseUrl,
fixLanguages: true,
projectId: config.projectId,
Expand Down Expand Up @@ -195,6 +196,7 @@ const getConfig = async () => {
const apiKey: string | undefined = argv.apiKey as string | undefined;
const enableLog: boolean | undefined = (argv.enableLog as boolean | undefined) ?? true;
const force: boolean | undefined = (argv.force as boolean | undefined) ?? true;
const enablePublish: boolean | undefined = (argv.enablePublish as boolean | undefined) ?? true;
const projectId: string | undefined = argv.projectId as string | undefined;
const baseUrl: string | undefined = argv.baseUrl as string | undefined;
const zipFilename: string | undefined = (argv.zipFilename as string | undefined) ?? getDefaultBackupFilename();
Expand All @@ -218,6 +220,7 @@ const getConfig = async () => {

// get config from command line
const config: ICliFileConfig = {
enablePublish,
action,
apiKey,
enableLog,
Expand Down
1 change: 1 addition & 0 deletions src/samples/restore-sample.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const run = async () => {
// called when any content is imported
console.log(`Imported: ${item.title} | ${item.type}`);
},
enablePublish: true,
projectId: 'targetProjectId',
apiKey: 'targetProjectId',
enableLog: true,
Expand Down
3 changes: 2 additions & 1 deletion src/zip/zip.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export class ZipService {
console.log(`Parsing zip contents`);
}
const assets = await this.readAndParseJsonFile(unzippedFile, this.assetsName);
const result = {
const result: IImportSource = {
importData: {
assets,
contentTypes: await this.readAndParseJsonFile(unzippedFile, this.contentTypesName),
Expand All @@ -47,6 +47,7 @@ export class ZipService {
contentItems: await this.readAndParseJsonFile(unzippedFile, this.contentItemsName),
contentTypeSnippets: await this.readAndParseJsonFile(unzippedFile, this.contentTypeSnippetsName),
taxonomies: await this.readAndParseJsonFile(unzippedFile, this.taxonomiesName),
workflowSteps: await this.readAndParseJsonFile(unzippedFile, this.workflowStepsName),
},
assetFolders: await this.readAndParseJsonFile(unzippedFile, this.assetFoldersName),
binaryFiles: await this.extractBinaryFilesAsync(unzippedFile, assets),
Expand Down

0 comments on commit ac1e8a0

Please sign in to comment.