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

Commit

Permalink
feat: implements reading from zip files & prepares base id translatio…
Browse files Browse the repository at this point in the history
…n helper and supports importing assets with binary files
  • Loading branch information
Enngage committed Jan 13, 2020
1 parent df0aff6 commit e781d8b
Show file tree
Hide file tree
Showing 10 changed files with 226 additions and 60 deletions.
Binary file added output/processed.zip
Binary file not shown.
Binary file modified output/test.zip
Binary file not shown.
52 changes: 25 additions & 27 deletions src/cli/app.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
#!/usr/bin/env node
import * as fs from 'fs';
import JSZip = require('jszip');
import yargs = require('yargs');

import { CleanService } from '../clean';
import { CliAction } from '../core';
import { ExportService } from '../export';
import { CliAction, codenameTranslateHelper } from '../core';
import { ImportService } from '../import';
import { CleanService } from '../clean';
import { ZipService } from '../zip';

const argv = yargs.argv;

Expand Down Expand Up @@ -42,58 +41,57 @@ const exportService = new ExportService({
});

const importService = new ImportService({
processItem: (item) => {
processItem: item => {
console.log('imported item: ' + item.title);
},
projectId: targetProjectId,
apiKey: targetApiKey,
workflowIdForImportedItems: '00000000-0000-0000-0000-000000000000',
skip: {
languages: true
}
});

const cleanService = new CleanService({
processItem: (item) => {
processItem: item => {
console.log('deleted item: ' + item.title);
},
projectId: targetProjectId,
apiKey: targetApiKey
});

const backup = async () => {
const filename = 'test.zip';
const zipService = new ZipService({
filename: 'test'
});

const backup = async () => {
const response = await exportService.exportAllAsync();
const data = JSON.stringify(response);

codenameTranslateHelper.replaceIdReferencesWithCodenames(response, response);
const data2 = JSON.stringify(response);
await zipService.createZipAsync(response.data, response.metadata);

/*
codenameTranslateHelper.replaceIdReferencesWithCodenames(response.data, response.data);
const zip = new JSZip();
const dataFolder = zip.folder('data');

dataFolder.file('test1.json', data);
dataFolder.file('test2.json', data2);

zip.generateAsync({ type: 'nodebuffer' }).then(content => {
fs.writeFile('./' + filename, content, wError => {
if (wError) {
throw Error(`Could not create zip file`);
}
console.log(`Zip file generated`, mappedAction);
});
});

zip.file('test.json', JSON.stringify(response.data));
const content = await zip.generateAsync({ type: 'nodebuffer' });
await fs.promises.writeFile(
'./processed.zip',
content
);
*/
};

const clean = async () => {
await cleanService.cleanAllAsync();
};

const restore = async () => {
const response = await exportService.exportAllAsync();
await importService.importFromExportDataAsync(response.data);
// const response = await exportService.exportAllAsync();

const data = await zipService.extractZipAsync();

await importService.importFromSourceAsync(data);
};

if (mappedAction === 'backup') {
Expand Down
8 changes: 8 additions & 0 deletions src/core/core.models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,11 @@ export interface IProcessedItem {
type: ItemType;
data: any;
}

export interface IImportItemResult<TRaw, TModel> {
original: TRaw;
imported: TModel;

originalId?: string;
importId?: string;
}
45 changes: 45 additions & 0 deletions src/core/id-translate-helper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@

import { ValidImportContract, ValidImportModel, IImportItemResult } from './core.models';

export class IdTranslateHelper {
public replaceIdReferencesWithNewId(
data: any,
items: IImportItemResult<ValidImportContract, ValidImportModel>[]
): void {
if (data) {
if (Array.isArray(data)) {
for (const arrayItem of data) {
this.replaceIdReferencesWithNewId(arrayItem, items);
}
} else {
for (const key of Object.keys(data)) {
const val = (data as any)[key];
if (key.toLowerCase() === 'id') {
const id = (data as any).id;

const newId = this.tryFindNewId(id, items);

// replace old id with new
if (newId) {
data.id = newId;
}
}

if (key !== '0') {
this.replaceIdReferencesWithNewId(val, items);
}
}
}
}
}

private tryFindNewId(
id: string,
items: IImportItemResult<ValidImportContract, ValidImportModel>[]
): string | undefined {
const item = items.find(m => m.originalId === id);
return item?.importId;
}
}

export const idTranslateHelper = new IdTranslateHelper();
1 change: 1 addition & 0 deletions src/core/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './core.models';
export * from './codename-translate-helper';
export * from './id-translate-helper';
11 changes: 6 additions & 5 deletions src/import/import.helper.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,18 @@
import { codenameTranslateHelper } from '../core';
import { IExportData } from '../export';
import { IImportData, IPreparedImportItem } from './import.models';
import { IImportData, IPreparedImportItem, IImportSource } from './import.models';

export class ImportHelper {
public prepareImportData(exportData: IExportData): IImportData {
public prepareImportData(sourceData: IImportSource): IImportData {
// translate internal ids to codenames
codenameTranslateHelper.replaceIdReferencesWithCodenames(exportData, exportData);
codenameTranslateHelper.replaceIdReferencesWithCodenames(sourceData.importData, sourceData.importData);

// flatten data
const items = this.flattenExportData(exportData);
const items = this.flattenExportData(sourceData.importData);

return {
orderedImportItems: items
orderedImportItems: items,
binaryFiles: sourceData.binaryFiles
};
}

Expand Down
37 changes: 31 additions & 6 deletions src/import/import.models.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,22 @@
import {
AssetContracts,
ContentItemContracts,
ContentTypeContracts,
ContentTypeSnippetContracts,
LanguageContracts,
LanguageVariantContracts,
TaxonomyContracts,
} from '@kentico/kontent-management';

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

export interface IImportConfig {
workflowIdForImportedItems: string;
projectId: string;
apiKey: string;
processItem?: (item: IProcessedItem) => void;
skip?: {
languages?: boolean
languages?: boolean;
};
}

Expand All @@ -23,11 +34,25 @@ export interface IPreparedImportItem {
deps: string[];
}

export interface IImportData {
orderedImportItems: IPreparedImportItem[];
export interface IBinaryFile {
binaryData: any;
asset: AssetContracts.IAssetModelContract;
}

export interface IImportSource {
importData: {
taxonomies: TaxonomyContracts.ITaxonomyContract[];
contentTypeSnippets: ContentTypeSnippetContracts.IContentTypeSnippetContract[];
contentTypes: ContentTypeContracts.IContentTypeContract[];
contentItems: ContentItemContracts.IContentItemModelContract[];
languageVariants: LanguageVariantContracts.ILanguageVariantModelContract[];
languages: LanguageContracts.ILanguageModelContract[];
assets: AssetContracts.IAssetModelContract[];
};
binaryFiles: IBinaryFile[];
}

export interface IImportItemResult<TRaw, TModel> {
original: TRaw;
imported: TModel;
export interface IImportData {
orderedImportItems: IPreparedImportItem[];
binaryFiles: IBinaryFile[];
}
Loading

0 comments on commit e781d8b

Please sign in to comment.