fs-blob-storage
Advanced tools
Comparing version 0.6.1 to 1.0.0
# Changelog | ||
## v1.0.0 2018-09-07 | ||
* Rewritten in Typescript. | ||
* New syntax of import in plain Javascript. | ||
## v0.6.1 2018-07-16 | ||
@@ -4,0 +9,0 @@ |
/// <reference types="node" /> | ||
import fs from 'fs' | ||
import fs from 'fs'; | ||
export interface FsBlobStorageOptions { | ||
defaultExt?: string | ||
defaultPart?: string | ||
exclusive?: boolean | ||
path?: string | ||
fs?: typeof fs | ||
defaultExt?: string; | ||
defaultPart?: string; | ||
exclusive?: boolean; | ||
path?: string; | ||
fs?: typeof fs; | ||
} | ||
export interface FsBlobStorageWriteStreamOptions { | ||
ext?: string | ||
part?: string | ||
encoding?: string | ||
ext?: string; | ||
part?: string; | ||
encoding?: string; | ||
} | ||
export interface FsBlobStorageReadStreamOptions { | ||
ext?: string | ||
encoding?: string | ||
ext?: string; | ||
encoding?: string; | ||
} | ||
export interface FsBlobStorageCommitOptions { | ||
ext?: string | ||
part?: string | ||
ext?: string; | ||
part?: string; | ||
} | ||
export interface FsBlobStorageRemoveOptions { | ||
ext?: string | ||
ext?: string; | ||
} | ||
export class FsBlobStorage { | ||
constructor (options?: FsBlobStorageOptions) | ||
createWriteStream (key: string, options?: FsBlobStorageWriteStreamOptions): Promise<fs.WriteStream> | ||
createReadStream (key: string, options?: FsBlobStorageReadStreamOptions): Promise<fs.ReadStream> | ||
commit (key: string, options?: FsBlobStorageCommitOptions): Promise<void> | ||
remove (key: string, options?: FsBlobStorageRemoveOptions): Promise<void> | ||
interface FsPromises { | ||
close: typeof fs.close.__promisify__; | ||
open: typeof fs.open.__promisify__; | ||
rename: typeof fs.rename.__promisify__; | ||
stat: typeof fs.stat.__promisify__; | ||
unlink: typeof fs.unlink.__promisify__; | ||
} | ||
export default FsBlobStorage | ||
export declare class FsBlobStorage { | ||
protected defaultExt: string; | ||
protected defaultPart: string; | ||
protected writeFlags: string; | ||
protected fs: typeof fs; | ||
protected path: string; | ||
protected fsPromises: FsPromises; | ||
constructor(options?: FsBlobStorageOptions); | ||
createWriteStream(key: string, options?: FsBlobStorageWriteStreamOptions): Promise<fs.WriteStream>; | ||
createReadStream(key: string, options?: FsBlobStorageReadStreamOptions): Promise<fs.ReadStream>; | ||
commit(key: string, options?: FsBlobStorageCommitOptions): Promise<void>; | ||
remove(key: string, options?: FsBlobStorageRemoveOptions): Promise<void>; | ||
} | ||
export default FsBlobStorage; |
@@ -1,133 +0,74 @@ | ||
const fs = require('fs') | ||
const makeDir = require('make-dir') | ||
const path = require('path') | ||
const promisify = require('util.promisify') | ||
const DEFAULT_EXT = '' | ||
const DEFAULT_PART = '.part' | ||
/** | ||
* @class | ||
* @param {Object} [options] | ||
* @param {string} [options.defaultExt] | ||
* @param {string} [options.defaultPart] | ||
* @param {boolean} [options.exclusive] | ||
* @param {Object} [options.fs] | ||
* @param {string} [options.path] | ||
*/ | ||
"use strict"; | ||
/// <reference types="node" /> | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const tslib_1 = require("tslib"); | ||
const fs_1 = tslib_1.__importDefault(require("fs")); | ||
const make_dir_1 = tslib_1.__importDefault(require("make-dir")); | ||
const path_1 = tslib_1.__importDefault(require("path")); | ||
// tslint:disable-next-line:no-var-requires | ||
const promisify = require('util.promisify'); | ||
const DEFAULT_EXT = ''; | ||
const DEFAULT_PART = '.part'; | ||
class FsBlobStorage { | ||
constructor (options = {}) { | ||
this.defaultExt = options.defaultExt !== undefined ? options.defaultExt : DEFAULT_EXT | ||
this.defaultPart = options.defaultPart !== undefined ? options.defaultPart : DEFAULT_PART | ||
this.writeFlags = options.exclusive ? 'wx' : 'w' | ||
this.fs = options.fs || fs | ||
this.path = options.path || '.' | ||
this.fsPromises = {} | ||
for (const method of ['close', 'open', 'rename', 'stat', 'unlink']) { | ||
this.fsPromises[method] = promisify(this.fs[method]) | ||
constructor(options = {}) { | ||
this.defaultExt = options.defaultExt !== undefined ? options.defaultExt : DEFAULT_EXT; | ||
this.defaultPart = options.defaultPart !== undefined ? options.defaultPart : DEFAULT_PART; | ||
this.writeFlags = options.exclusive ? 'wx' : 'w'; | ||
this.fs = options.fs || fs_1.default; | ||
this.path = options.path || '.'; | ||
this.fsPromises = {}; | ||
for (const method of ['close', 'open', 'rename', 'stat', 'unlink']) { | ||
this.fsPromises[method] = promisify(this.fs[method]); | ||
} | ||
} | ||
} | ||
/** | ||
* @async | ||
* @param {string} key | ||
* @param {Object} [options] | ||
* @param {string} [options.ext] | ||
* @param {string} [options.part] | ||
* @param {string} [options.encoding] | ||
* @returns {Promise<Writable>} | ||
*/ | ||
createWriteStream (key, options = {}) { | ||
const { ext = this.defaultExt, part = this.defaultPart, encoding = null } = options | ||
const filepath = path.join(this.path, key + ext) | ||
const dirpath = path.dirname(filepath) | ||
if (part) { | ||
let fd | ||
return makeDir(dirpath, { fs: this.fs }).then(() => { | ||
// for exclusive mode it will reject if file already exist | ||
return this.fsPromises.open(filepath, this.writeFlags) | ||
}).then((value) => { | ||
fd = value | ||
// do `open` instead of `stat` to prevent race condition | ||
return this.fsPromises.open(filepath + part, this.writeFlags) | ||
}).then((fdPart) => { | ||
// `close` before `rename` just for Windows | ||
return this.fsPromises.close(fdPart) | ||
}).then(() => { | ||
// `rename` overwrites quietly the file | ||
return this.fsPromises.rename(filepath, filepath + part) | ||
}).then(() => { | ||
// first argument is ignored | ||
return this.fs.createWriteStream(filepath + part, { fd, encoding }) | ||
}) | ||
createWriteStream(key, options = {}) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const { ext = this.defaultExt, part = this.defaultPart, encoding } = options; | ||
const filepath = path_1.default.join(this.path, key + ext); | ||
const dirpath = path_1.default.dirname(filepath); | ||
yield make_dir_1.default(dirpath, { fs: this.fs }); | ||
// for exclusive mode it will reject if file already exist | ||
const fd = yield this.fsPromises.open(filepath, this.writeFlags); | ||
if (part) { | ||
// do `open` instead of `stat` to prevent race condition | ||
const fdPart = yield this.fsPromises.open(filepath + part, this.writeFlags); | ||
// `close` before `rename` just for Windows | ||
yield this.fsPromises.close(fdPart); | ||
// `rename` overwrites quietly the file | ||
yield this.fsPromises.rename(filepath, filepath + part); | ||
} | ||
// first argument is ignored | ||
return this.fs.createWriteStream(filepath + part, { fd, encoding }); | ||
}); | ||
} | ||
return makeDir(dirpath, { fs: this.fs }).then(() => { | ||
return this.fsPromises.open(filepath, this.writeFlags) | ||
}).then((fd) => { | ||
return this.fs.createWriteStream(filepath, { fd, encoding }) | ||
}) | ||
} | ||
/** | ||
* @async | ||
* @param {string} key | ||
* @param {Object} [options] | ||
* @param {string} [options.ext] | ||
* @param {string} [options.encoding] | ||
* @returns {Promise<Readable>} | ||
*/ | ||
createReadStream (key, options = {}) { | ||
const { ext = this.defaultExt, encoding = null } = options | ||
const filepath = path.join(this.path, key + ext) | ||
let fd | ||
return this.fsPromises.open(filepath, 'r').then((value) => { | ||
fd = value | ||
return this.fsPromises.stat(filepath) | ||
}).then((stats) => { | ||
if (!stats.size) { | ||
return Promise.reject(Object.assign(new Error(`ENOENT: empty file, open '${filepath}'`), { code: 'ENOENT', path: filepath })) | ||
} | ||
return this.fs.createReadStream(filepath, { fd, encoding }) | ||
}) | ||
} | ||
/** | ||
* @async | ||
* @param {string} key | ||
* @param {Object} [options] | ||
* @param {string} [options.ext] | ||
* @param {string} [options.part] | ||
* @returns {Promise<undefined>} | ||
*/ | ||
commit (key, options = {}) { | ||
const { ext = this.defaultExt, part = this.defaultPart } = options | ||
if (part) { | ||
const filepath = path.join(this.path, key + ext) | ||
return this.fsPromises.rename(filepath + part, filepath) | ||
createReadStream(key, options = {}) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const { ext = this.defaultExt, encoding } = options; | ||
const filepath = path_1.default.join(this.path, key + ext); | ||
const fd = yield this.fsPromises.open(filepath, 'r'); | ||
const stats = yield this.fsPromises.stat(filepath); | ||
if (!stats.size) { | ||
throw Object.assign(new Error(`ENOENT: empty file, open '${filepath}'`), { code: 'ENOENT', path: filepath }); | ||
} | ||
return this.fs.createReadStream(filepath, { fd, encoding }); | ||
}); | ||
} | ||
} | ||
/** | ||
* @async | ||
* @param {string} key | ||
* @param {Object} [options] | ||
* @param {string} [options.ext] | ||
* @returns {Promise<undefined>} | ||
*/ | ||
remove (key, options = {}) { | ||
const { ext = this.defaultExt } = options | ||
const filepath = path.join(this.path, key + ext) | ||
return this.fsPromises.unlink(filepath) | ||
} | ||
commit(key, options = {}) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const { ext = this.defaultExt, part = this.defaultPart } = options; | ||
if (part) { | ||
const filepath = path_1.default.join(this.path, key + ext); | ||
return this.fsPromises.rename(filepath + part, filepath); | ||
} | ||
}); | ||
} | ||
remove(key, options = {}) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const { ext = this.defaultExt } = options; | ||
const filepath = path_1.default.join(this.path, key + ext); | ||
return this.fsPromises.unlink(filepath); | ||
}); | ||
} | ||
} | ||
FsBlobStorage.FsBlobStorage = FsBlobStorage | ||
module.exports = FsBlobStorage | ||
exports.FsBlobStorage = FsBlobStorage; | ||
exports.default = FsBlobStorage; |
{ | ||
"name": "fs-blob-storage", | ||
"version": "0.6.1", | ||
"version": "1.0.0", | ||
"description": "Blob storage on filesystem, with streams and promises API", | ||
@@ -28,47 +28,51 @@ "main": "lib/fs-blob-storage.js", | ||
"make-dir": "^1.3.0", | ||
"tslib": "^1.9.3", | ||
"util.promisify": "^1.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/chai": "^4.1.4", | ||
"@types/chai-as-promised": "^7.1.0", | ||
"@types/make-dir": "^1.0.3", | ||
"@types/node": "^10.5.2", | ||
"@types/mocha": "^5.2.5", | ||
"@types/node": "^10.9.4", | ||
"chai": "^4.1.2", | ||
"chai-as-promised": "^7.1.1", | ||
"eslint": "^5.1.0", | ||
"eslint-config-standard": "^12.0.0-alpha.0", | ||
"eslint-plugin-import": "^2.13.0", | ||
"eslint-plugin-node": "^6.0.1", | ||
"eslint-plugin-promise": "^3.8.0", | ||
"eslint-plugin-standard": "^3.1.0", | ||
"markdownlint-cli": "^0.11.0", | ||
"eslint": "^5.5.0", | ||
"eslint-config-standard": "^12.0.0", | ||
"eslint-plugin-import": "^2.14.0", | ||
"eslint-plugin-node": "^7.0.1", | ||
"eslint-plugin-promise": "^4.0.1", | ||
"eslint-plugin-standard": "^4.0.0", | ||
"markdownlint-cli": "^0.13.0", | ||
"mocha": "^5.2.0", | ||
"nyc": "^13.0.1", | ||
"promise-readable": "^3.1.5", | ||
"promise-writable": "^3.1.2", | ||
"standard": "^11.0.1", | ||
"rimraf": "^2.6.2", | ||
"stream.pipeline-shim": "^1.0.4", | ||
"tap": "^12.0.1", | ||
"tap-given": "^0.6.0", | ||
"tslint": "^5.10.0", | ||
"tslint-config-standard": "^7.1.0", | ||
"typescript": "^2.9.2" | ||
"ts-node": "^7.0.1", | ||
"tslint": "^5.11.0", | ||
"tslint-config-standard": "^8.0.1", | ||
"tslint-eslint-rules": "^5.4.0", | ||
"typescript": "^3.0.3" | ||
}, | ||
"scripts": { | ||
"pretest": "eslint . && tsc --noEmit --pretty && tslint -t stylish -p . && echo markdownlint *.md", | ||
"test": "npm run test:api", | ||
"test:api": "tap test/*.js", | ||
"test:coverage": "npm test -- --coverage" | ||
"build": "tsc --pretty", | ||
"clean": "rimraf lib", | ||
"postpublish": "git tag v$npm_package_version -a -m \"Release $npm_package_version\" && git push --tags", | ||
"prepublishOnly": "npm run build", | ||
"pretest": "npm run build && eslint . && tslint -t stylish -p . && markdownlint \"*.md\"", | ||
"test": "npm run test:spec", | ||
"test:spec": "npm run ts-mocha -- \"test/*.ts\"", | ||
"test:coverage": "nyc --reporter json npm run test:spec && nyc report", | ||
"ts-mocha": "mocha --use_strict --throw-deprecation --require source-map-support/register --require ts-node/register --timeout 90000" | ||
}, | ||
"standard": { | ||
"globals": [ | ||
"And", | ||
"After", | ||
"Before", | ||
"Feature", | ||
"Given", | ||
"Scenario", | ||
"Then", | ||
"When" | ||
"nyc": { | ||
"extension": [ | ||
".ts" | ||
], | ||
"exclude": [ | ||
"**/*.d.ts" | ||
] | ||
}, | ||
"nyc": { | ||
"exclude": [] | ||
} | ||
} |
@@ -37,3 +37,3 @@ # fs-blob-storage | ||
```js | ||
const FsBlobStorage = require('fs-blob-storage') | ||
const { FsBlobStorage } = require('fs-blob-storage') | ||
``` | ||
@@ -47,2 +47,14 @@ | ||
Transpiling this module with own settings in `tsconfig.json`: | ||
```json | ||
{ | ||
"compilerOptions": { | ||
"paths": { | ||
"fs-blob-storage": ["node_modules/fs-blob-storage/src/fs-blob-storage"] | ||
} | ||
} | ||
} | ||
``` | ||
### constructor | ||
@@ -49,0 +61,0 @@ |
{ | ||
"compilerOptions": { | ||
"declaration": true, | ||
"esModuleInterop": true, | ||
"importHelpers": true, | ||
"lib": [ | ||
"es6" | ||
], | ||
"module": "commonjs", | ||
"noImplicitAny": true, | ||
"noImplicitReturns": true, | ||
"noUnusedLocals": true, | ||
"noUnusedParameters": true, | ||
"outDir": "./lib", | ||
"target": "es6", | ||
"strict": true, | ||
"target": "ES2017" | ||
} | ||
"typeRoots": [ | ||
"node_modules/@types" | ||
] | ||
}, | ||
"exclude": [ | ||
"./examples/**/*", | ||
"./lib/**/*", | ||
"./test/**/*" | ||
] | ||
} |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
17845
9
246
0
159
3
25
+ Addedtslib@^1.9.3
+ Addedtslib@1.14.1(transitive)