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

Commit

Permalink
feat: add directory method, support deep directories (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
sveisvei authored Nov 17, 2017
1 parent ab9ade3 commit 85ef43e
Show file tree
Hide file tree
Showing 10 changed files with 256 additions and 157 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ Async method for writing a file to storage

Async method for checking if a file exists in storage

### dir(directoryName: string): Promise<Array>

Async method for getting all files in a given directory


### writer(type)

Expand Down
76 changes: 58 additions & 18 deletions lib/sink.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ const JSONStream = require('JSONStream');
const common = require('asset-pipe-common');
const stream = require('readable-stream');
const assert = require('assert');
const path = require('path');
const { join, basename, dirname } = require('path');
const fs = require('fs');
const os = require('os');
const { promisify } = require('util');
const mkdirp = promisify(require('mkdirp'));
const readFile = promisify(fs.readFile);
const writeFile = promisify(fs.writeFile);
const access = promisify(fs.access);
const readdir = promisify(fs.readdir);
const stat = promisify(fs.stat);

class WriteStream extends stream.PassThrough {
constructor(options = {}, type) {
constructor(rootPath, type) {
super();

const temp = path.join(
os.tmpdir(),
common.createTemporaryFilename(type)
);
const temp = join(os.tmpdir(), common.createTemporaryFilename(type));
const hasher =
type === 'json' ? new common.IdHasher() : new common.FileHasher();
const parser =
Expand All @@ -30,7 +30,7 @@ class WriteStream extends stream.PassThrough {
fileStream.on('finish', () => {
const id = hasher.hash;
const file = `${id}.${type}`;
fs.rename(temp, path.join(options.path, file), error => {
fs.rename(temp, join(rootPath, file), error => {
if (error) {
return this.emit('file not saved', error);
}
Expand Down Expand Up @@ -58,7 +58,7 @@ class WriteStream extends stream.PassThrough {
class ReadStream extends fs.createReadStream {
constructor(...args) {
super(...args);
const file = path.parse(args[0]).base;
const file = basename(args[0]);
this.on('open', () => {
this.emit('file found', file);
});
Expand All @@ -71,15 +71,15 @@ class ReadStream extends fs.createReadStream {
}

module.exports = class SinkFs extends EventEmitter {
constructor(options = {}) {
constructor({ path } = {}) {
super();
assert(options.path, '"options.path" is missing');
assert(path, '"options.path" is missing');
this.name = 'asset-pipe-sink-fs';
this.options = Object.assign({}, options);
this.rootPath = path;
}

getFileName(fileName) {
return path.join(this.options.path, fileName);
joinPath(fileName) {
return join(this.rootPath, fileName);
}

assertFileName(fileName) {
Expand All @@ -92,7 +92,7 @@ module.exports = class SinkFs extends EventEmitter {
async get(fileName) {
this.assertFileName(fileName);
try {
const file = await readFile(this.getFileName(fileName), 'utf8');
const file = await readFile(this.joinPath(fileName), 'utf8');
if (file) {
return file;
}
Expand All @@ -103,28 +103,68 @@ module.exports = class SinkFs extends EventEmitter {
async set(fileName, fileContent) {
this.assertFileName(fileName);
assert(fileContent, '"fileContent" is missing');
await writeFile(this.getFileName(fileName), fileContent, 'utf8');
const target = this.joinPath(fileName);
await mkdirp(dirname(target));
await writeFile(target, fileContent, 'utf8');
}

async has(fileName) {
this.assertFileName(fileName);
try {
await access(
this.getFileName(fileName),
this.joinPath(fileName),
fs.constants.R_OK | fs.constants.W_OK
);
return true;
} catch (e) {}
return false;
}

async dir(directoryName = '/') {
const resolveTargetDirName = this.joinPath(directoryName);
try {
const dir = await readdir(resolveTargetDirName);
if (dir.length === 0) {
throw new Error();
}
let results = await Promise.all(
dir.map(relativePath =>
stat(join(resolveTargetDirName, relativePath)).then(
stats => {
if (stats.isDirectory()) {
// filter out
return;
}

return this.get(
join(directoryName, relativePath)
).then(content => ({
fileName: relativePath,
content,
}));
}
)
)
);
results = results.filter(Boolean);
if (results.length === 0) {
throw new Error();
}
return results;
} catch (e) {
throw new Error(
`Missing folder with name "${directoryName}" or empty result`
);
}
}

writer(type) {
assert(type, '"type" is missing');
return new WriteStream(this.options, type);
return new WriteStream(this.rootPath, type);
}

reader(fileName) {
this.assertFileName(fileName);
return new ReadStream(this.getFileName(fileName));
return new ReadStream(this.joinPath(fileName));
}
};
Loading

0 comments on commit 85ef43e

Please sign in to comment.