| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- import fs from 'fs';
- import path from 'path';
- import streamToPromise from 'stream-to-promise';
- import unzipStream, { type Entry } from 'unzip-stream';
- import loggerFactory from '~/utils/logger';
- import type { ZipFileStat } from '../interfaces/export';
- import { tapStreamDataByPromise } from './unzip-stream-utils';
- const logger = loggerFactory('growi:services:GrowiBridgeService'); // eslint-disable-line no-unused-vars
- /**
- * the service class for bridging GROWIs (export and import)
- * common properties and methods between export service and import service are defined in this service
- */
- class GrowiBridgeService {
- crowi: any;
- encoding: BufferEncoding = 'utf-8';
- metaFileName = 'meta.json';
- baseDir: string | undefined;
- constructor(crowi) {
- this.crowi = crowi;
- }
- /**
- * getter for encoding
- *
- * @memberOf GrowiBridgeService
- * @return {BufferEncoding} encoding
- */
- getEncoding(): BufferEncoding {
- return this.encoding;
- }
- /**
- * getter for metaFileName
- *
- * @memberOf GrowiBridgeService
- * @return {string} base name of meta file
- */
- getMetaFileName(): string {
- return this.metaFileName;
- }
- /**
- * get the absolute path to a file
- *
- * @memberOf GrowiBridgeService
- */
- getFile(fileName: string, baseDir: string): string {
- const jsonFile = path.join(baseDir, fileName);
- // throws err if the file does not exist
- fs.accessSync(jsonFile);
- return jsonFile;
- }
- /**
- * parse a zip file
- *
- * @memberOf GrowiBridgeService
- * @param {string} zipFile path to zip file
- * @return {object} meta{object} and files{Array.<object>}
- */
- async parseZipFile(zipFile: string): Promise<ZipFileStat | null> {
- const fileStat = fs.statSync(zipFile);
- const innerFileStats: Array<{ fileName: string, collectionName: string, size: number }> = [];
- let meta = {};
- const readStream = fs.createReadStream(zipFile);
- const unzipStreamPipe = readStream.pipe(unzipStream.Parse());
- let tapPromise;
- const unzipEntryStream = unzipStreamPipe.on('entry', (entry: Entry) => {
- const fileName = entry.path;
- const size = entry.size; // might be undefined in some archives
- if (fileName === this.getMetaFileName()) {
- tapPromise = tapStreamDataByPromise(entry).then((metaBuffer) => {
- meta = JSON.parse(metaBuffer.toString());
- });
- }
- else {
- innerFileStats.push({
- fileName,
- collectionName: path.basename(fileName, '.json'),
- size,
- });
- }
- entry.autodrain();
- });
- try {
- await streamToPromise(unzipEntryStream);
- await tapPromise;
- }
- // if zip is broken
- catch (err) {
- logger.error(err);
- return null;
- }
- return {
- meta,
- fileName: path.basename(zipFile),
- zipFilePath: zipFile,
- fileStat,
- innerFileStats,
- };
- }
- }
- export default GrowiBridgeService;
|