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

Commit

Permalink
feat: separates all node.js code and makes backup manager browser fri…
Browse files Browse the repository at this point in the history
…endly
  • Loading branch information
Enngage committed May 19, 2020
1 parent dbb9e57 commit bfd046c
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 43 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "@kentico/kontent-backup-manager",
"version": "1.4.0",
"version": "1.5.0-next.0",
"description": "This utility enables backup & restore of Kentico Kontent projects",
"preferGlobal": true,
"bin": {
"kbm": "./_commonjs/src/cli/app.js"
"kbm": "./_commonjs/src/node-js/cli/app.js"
},
"repository": {
"type": "git",
Expand Down
33 changes: 23 additions & 10 deletions src/cli/app.ts → src/node-js/cli/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@
import * as fs from 'fs';
import yargs = require('yargs');

import { CleanService } from '../clean';
import { ICliFileConfig, fileHelper, getFilenameWithoutExtension, CliAction } from '../core';
import { ExportService } from '../export';
import { IImportSource, ImportService } from '../import';
import { ZipService } from '../zip';
import { CleanService } from '../../clean';
import { ICliFileConfig, fileHelper, getFilenameWithoutExtension, CliAction } from '../../core';
import { ExportService } from '../../export';
import { IImportSource, ImportService } from '../../import';
import { ZipService } from '../../zip';
import { ProjectContracts, SharedModels } from '@kentico/kontent-management';
import { FileService } from '..';

const argv = yargs.argv;

Expand All @@ -22,15 +23,21 @@ const backupAsync = async (config: ICliFileConfig) => {
}
});

const zipService = new ZipService({
filename: config.zipFilename,
const fileService = new FileService({
enableLog: config.enableLog
});

const zipService = new ZipService({
enableLog: config.enableLog,
context: 'node.js'
});

const report = await exportService.exportProjectValidationAsync();

const response = await exportService.exportAllAsync();
await zipService.createZipAsync(response);
const zipFileData = await zipService.createZipAsync(response);

await fileService.writeFileAsync(config.zipFilename, zipFileData);

if (exportContainsInconsistencies(report)) {
const logFilename: string = getLogFilename(config.zipFilename);
Expand Down Expand Up @@ -66,7 +73,11 @@ const cleanAsync = async (config: ICliFileConfig) => {

const restoreAsync = async (config: ICliFileConfig) => {
const zipService = new ZipService({
filename: config.zipFilename,
enableLog: config.enableLog,
context: 'node.js'
});

const fileService = new FileService({
enableLog: config.enableLog
});

Expand All @@ -88,7 +99,9 @@ const restoreAsync = async (config: ICliFileConfig) => {
}
});

const data = await zipService.extractZipAsync();
const file = await fileService.loadFileAsync(config.zipFilename);

const data = await zipService.extractZipAsync(file);

if (canImport(data, config)) {
await importService.importFromSourceAsync(data);
Expand Down
File renamed without changes.
3 changes: 3 additions & 0 deletions src/node-js/file/file.models.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface IFileServiceConfig {
enableLog: boolean;
}
39 changes: 39 additions & 0 deletions src/node-js/file/file.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import * as fs from 'fs';
import { IFileServiceConfig } from './file.models';

export class FileService {

constructor(private config: IFileServiceConfig) {
}

private readonly zipExtension: string = '.zip';


async loadFileAsync(fileNameWithoutExtension: string): Promise<Buffer> {
const filePath = this.getFilePath(fileNameWithoutExtension);

if (this.config.enableLog) {
console.log(`Reading file '${filePath}'`);
}
const file = await fs.promises.readFile(filePath);
if (this.config.enableLog) {
console.log(`Reading file completed`);
}

return file;
}

async writeFileAsync(fileNameWithoutExtension: string, content: any): Promise<void> {
const filePath = this.getFilePath(fileNameWithoutExtension);

console.log(`Writing file '${filePath}'`);
await fs.promises.writeFile(filePath, content);
console.log(`File saved`);
}

private getFilePath(fileNameWithoutExtension: string) {
const filenameWithExtension = fileNameWithoutExtension + this.zipExtension;
return`./${filenameWithExtension}`;
}

}
2 changes: 2 additions & 0 deletions src/node-js/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './file/file.service';
export * from './file/file.models';
20 changes: 15 additions & 5 deletions src/samples/export-sample.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,18 @@
import { ZipService } from 'src/zip';

import { ExportService } from '../export';
import { FileService } from '../node-js';

const run = async () => {
const fileService = new FileService({
enableLog: true
});

const zipService = new ZipService({
enableLog: true,
context: 'node.js'
});

const exportService = new ExportService({
apiKey: 'sourceProjectApiKey',
projectId: 'sourceProjectId',
Expand All @@ -15,11 +25,11 @@ const run = async () => {
// data contains entire project content
const data = await exportService.exportAllAsync();

// you can also save backup in file with ZipService
const zipService = new ZipService({
filename: 'file',
enableLog: true
});
// prepare zip file
const zipFile = await zipService.createZipAsync(data);

// save zip to file system (node.js only)
await fileService.writeFileAsync('filename', zipFile);

await zipService.createZipAsync(data);
};
Expand Down
16 changes: 12 additions & 4 deletions src/samples/restore-sample.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { ImportService } from 'src';
import { ZipService } from 'src/zip';
import { ZipService } from '../zip';
import { FileService } from '../node-js';

const run = async () => {
const zipService = new ZipService({
filename: 'xxx',
enableLog: true,
context: 'node.js'
});

const fileService = new FileService({
enableLog: true
});

Expand All @@ -19,8 +24,11 @@ const run = async () => {
workflowIdForImportedItems: '00000000-0000-0000-0000-000000000000' // id that items are assigned
});

// read export data from zip
const data = await zipService.extractZipAsync();
// read file
const file = fileService.loadFileAsync('fileName');

// extract file
const data = await zipService.extractZipAsync(file);

// restore into target project
await importService.importFromSourceAsync(data);
Expand Down
4 changes: 3 additions & 1 deletion src/zip/zip.models.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
export type ZipContext = 'node.js' | 'browser';

export interface IZipServiceConfig {
filename: string;
enableLog: boolean;
context: ZipContext
}
45 changes: 24 additions & 21 deletions src/zip/zip.service.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { AssetContracts } from '@kentico/kontent-management';
import * as fs from 'fs';
import JSZip = require('jszip');
import axios, {} from 'axios';

Expand All @@ -8,7 +7,6 @@ import { IBinaryFile, IImportSource } from '../import';
import { IZipServiceConfig } from './zip.models';

export class ZipService {
private readonly zipExtension: string = '.zip';

private readonly contentTypesName: string = 'contentTypes.json';
private readonly contentItemsName: string = 'contentItems.json';
Expand All @@ -22,23 +20,15 @@ export class ZipService {
private readonly assetFoldersName: string = 'assetFolders.json';
private readonly validationName: string = 'validation.json';

private readonly filenameWithExtension: string;

constructor(private config: IZipServiceConfig) {
this.filenameWithExtension = config.filename + this.zipExtension;
}

public async extractZipAsync(): Promise<IImportSource> {
const filePath = `./${this.filenameWithExtension}`;
if (this.config.enableLog) {
console.log(`Reading file '${filePath}'`);
}
const file = await fs.promises.readFile(filePath);

public async extractZipAsync(zipFile: any): Promise<IImportSource> {
if (this.config.enableLog) {
console.log(`Unzipping file`);
}
const unzippedFile = await JSZip.loadAsync(file);

const unzippedFile = await JSZip.loadAsync(zipFile);

if (this.config.enableLog) {
console.log(`Parsing zip contents`);
Expand Down Expand Up @@ -67,7 +57,7 @@ export class ZipService {
return result;
}

public async createZipAsync(exportData: IExportAllResult): Promise<void> {
public async createZipAsync(exportData: IExportAllResult): Promise<any> {
const zip = new JSZip();

if (this.config.enableLog) {
Expand Down Expand Up @@ -100,16 +90,17 @@ export class ZipService {
});
}

const filePath = './' + this.filenameWithExtension;
if (this.config.enableLog) {
console.log(`Creating zip file`);
}

const content = await zip.generateAsync({ type: this.getZipOutputType() });

if (this.config.enableLog) {
console.log(`Generating zip file '${filePath}'`);
console.log(`Zip file prepared`);
}
const content = await zip.generateAsync({ type: 'nodebuffer' });

console.log(`Writing file '${filePath}'`);
await fs.promises.writeFile(filePath, content);
console.log(`File saved`);
return content;
}

private async extractBinaryFilesAsync(
Expand All @@ -123,7 +114,7 @@ export class ZipService {
for (const asset of assets) {
const assetFile = files[this.getFullAssetPath(asset.id, asset.file_name)];

const binaryData = await assetFile.async('nodebuffer');
const binaryData = await assetFile.async(this.getZipOutputType());
binaryFiles.push({
asset,
binaryData
Expand All @@ -133,6 +124,18 @@ export class ZipService {
return binaryFiles;
}

private getZipOutputType(): 'nodebuffer' | 'blob' {
if (this.config.context === 'browser') {
return 'blob';
}

if (this.config.context === 'node.js') {
return 'nodebuffer';
}

throw Error(`Unsupported context '${this.config.context}'`);
}

/**
* Gets path to asset within zip folder. Uses tree format using asset ids such as:
* "files/3b4/3b42f36c-2e67-4605-a8d3-fee2498e5224/image.jpg"
Expand Down

0 comments on commit bfd046c

Please sign in to comment.