Skip to content

Commit

Permalink
feat(includers/unarchive): unarchive input
Browse files Browse the repository at this point in the history
introduce new includer that allows to unpack
tar archive before including content
  • Loading branch information
moki committed Dec 29, 2022
1 parent 65f0297 commit 4801dc5
Show file tree
Hide file tree
Showing 6 changed files with 170 additions and 7 deletions.
74 changes: 70 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: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
"shelljs": "0.8.5",
"simple-git": "2.48.0",
"slugify": "^1.6.5",
"tar-stream": "^2.2.0",
"threads": "1.7.0",
"threads-plugin": "1.4.0",
"walk-sync": "2.2.0",
Expand All @@ -77,6 +78,7 @@
"@types/react": "16.14.21",
"@types/react-dom": "16.9.14",
"@types/shelljs": "0.8.10",
"@types/tar-stream": "^2.2.2",
"@types/yargs": "15.0.14",
"@typescript-eslint/eslint-plugin": "2.34.0",
"@typescript-eslint/parser": "2.34.0",
Expand Down
2 changes: 1 addition & 1 deletion src/models.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export type YfmTocIncluders = YfmTocIncluder[];

export type YfmTocIncluder = YfmTocIncluderName | YfmTocIncluderObject;

export const includersNames = ['sourcedocs', 'openapi', 'generic'] as const;
export const includersNames = ['sourcedocs', 'openapi', 'generic', 'unarchive'] as const;

export type YfmTocIncluderName = typeof includersNames[number];

Expand Down
1 change: 1 addition & 0 deletions src/services/includers/batteries/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * as generic from './generic';
export * as sourcedocs from './sourcedocs';
export * as openapi from './openapi';
export * as unarchive from './unarchive';
94 changes: 94 additions & 0 deletions src/services/includers/batteries/unarchive.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import {mkdirSync, createReadStream, createWriteStream} from 'fs';
import {join, dirname} from 'path';
import {extract, Headers} from 'tar-stream';

import type {PassThrough} from 'stream';

import {IncluderFunctionParams} from '../../../models';

const name = 'unarchive';

class UnarchiveIncluderError extends Error {
path: string;

constructor(message: string, path: string) {
super(message);

this.name = 'UnarchiveIncluderError';
this.path = path;
}
}

function pipeline(readPath: string, writeBasePath: string): Promise<void> {
return new Promise((res, rej) => {
const reader = createReadStream(readPath);

reader.on('error', (err: Error) => {
rej(err);
});

const extractor = extract();

extractor.on('error', (err: Error) => {
rej(err);
});

mkdirSync(writeBasePath, {recursive: true});

extractor.on('entry', (header: Headers, stream: PassThrough, next: Function) => {
const {type, name} = header;

const writePath = join(writeBasePath, name);

const writeDirPath = type === 'directory' ? writePath : dirname(writePath);

mkdirSync(writeDirPath, {recursive: true});

if (type !== 'directory') {
const writer = createWriteStream(writePath, {flags: 'w'});

writer.on('error', (err) => {
rej(err);
});

stream.pipe(writer);
}

stream.on('end', () => {
next();
});

stream.resume();
});

reader.pipe(extractor).on('finish', () => {
res();
});
});
}

async function includerFunction(params: IncluderFunctionParams) {
const {readBasePath, writeBasePath, tocPath, passedParams: {input, output}, index} = params;

if (!input?.length || !output?.length) {
throw new UnarchiveIncluderError('provide includer with input parameter', tocPath);
}

const contentPath = index === 0
? join(writeBasePath, input)
: join(readBasePath, input);

const writePath = join(writeBasePath, output);

try {
await pipeline(contentPath, writePath);
} catch (err) {
throw new UnarchiveIncluderError(err.toString(), tocPath);
}

return {input: output};
}

export {name, includerFunction};

export default {name, includerFunction};
4 changes: 2 additions & 2 deletions src/services/includers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {isObject} from 'lodash';
import {ArgvService} from '../index';
import {IncludeMode} from '../../constants';
import {logger} from '../../utils/logger';
import {generic, sourcedocs, openapi} from './batteries';
import {generic, sourcedocs, openapi, unarchive} from './batteries';

import type {
Includer,
Expand Down Expand Up @@ -51,7 +51,7 @@ class IncludersError extends Error {
function init(custom: Includer[] = []) {
if (includersMap) { return; }

includersMap = {generic, sourcedocs, openapi};
includersMap = {generic, sourcedocs, openapi, unarchive};

for (const includer of custom) {
includersMap[includer.name] = includer;
Expand Down

0 comments on commit 4801dc5

Please sign in to comment.