Comparing version 1.0.0 to 2.0.0
{ | ||
"name": "fsify", | ||
"version": "1.0.0", | ||
"version": "2.0.0", | ||
"authors": [ | ||
"Tobias Reich <tobias@electerious.com>" | ||
], | ||
"description": "Convert an object into a persistent or temporary directory structure.", | ||
"description": "Convert an array of objects into a persistent or temporary directory structure", | ||
"main": "src/index.js", | ||
@@ -44,5 +44,8 @@ "keywords": [ | ||
"dependencies": { | ||
"del": "^2.2.2", | ||
"is-path-inside": "^1.0.0", | ||
"is-plain-obj": "^1.1.0", | ||
"once": "^1.4.0", | ||
"pify": "^2.3.0" | ||
} | ||
} |
263
README.md
@@ -1,5 +0,264 @@ | ||
# fsify (WIP) | ||
# fsify | ||
[![Travis Build Status](https://travis-ci.org/electerious/fsify.svg?branch=master)](https://travis-ci.org/electerious/fsify) [![Coverage Status](https://coveralls.io/repos/github/electerious/fsify/badge.svg?branch=master)](https://coveralls.io/github/electerious/fsify?branch=master) [![Dependencies](https://david-dm.org/electerious/fsify.svg)](https://david-dm.org/electerious/fsify#info=dependencies) | ||
Convert an object into a persistent or temporary directory structure. | ||
Convert an array of objects into a persistent or temporary directory structure. | ||
## Contents | ||
- [Description](#description) | ||
- [Install](#install) | ||
- [Usage](#usage) | ||
- [Structure with content](#structure-with-content) | ||
- [Deeply nested structure](#deeply-nested-structure) | ||
- [Temporary file in existing directory](#temporary-file-in-existing-directory) | ||
- [Structure from `tree -J`](#structure-from-tree--j) | ||
- [API](#api) | ||
- [Instance API](#instance-api) | ||
- [Structure](#structure) | ||
- [Directory](#directory) | ||
- [File](#file) | ||
## Description | ||
`fsify` creates a persistent or temporary directory structure from an array of objects. It's like the opposite of the Linux and Unix `tree` command. | ||
## Install | ||
``` | ||
npm install fsify | ||
``` | ||
## Usage | ||
### Structure with content | ||
``` | ||
. | ||
├── dirname | ||
│ └── filename | ||
└── filename | ||
``` | ||
```js | ||
const fsify = require('fsify')() | ||
const structure = [ | ||
{ | ||
type: fsify.DIRECTORY, | ||
name: 'dirname', | ||
contents: [ | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename', | ||
contents: 'data' | ||
} | ||
] | ||
}, | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename', | ||
contents: 'data' | ||
} | ||
] | ||
fsify(structure) | ||
.then((structure) => console.log(structure)) | ||
.catch((err) => console.error(err)) | ||
``` | ||
### Deeply nested structure | ||
``` | ||
. | ||
└── dirname | ||
└── dirname | ||
└── filename | ||
``` | ||
```js | ||
const fsify = require('fsify')() | ||
const structure = [ | ||
{ | ||
type: fsify.DIRECTORY, | ||
name: 'dirname', | ||
contents: [ | ||
{ | ||
type: fsify.DIRECTORY, | ||
name: 'dirname', | ||
contents: [ | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename' | ||
} | ||
] | ||
} | ||
] | ||
} | ||
] | ||
fsify(structure) | ||
.then((structure) => console.log(structure)) | ||
.catch((err) => console.error(err)) | ||
``` | ||
### Temporary file in existing directory | ||
``` | ||
dirname/ | ||
└── filename | ||
``` | ||
```js | ||
const fsify = require('fsify')({ | ||
cwd: 'dirname/', | ||
persistent: false | ||
}) | ||
const structure = [ | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename' | ||
} | ||
] | ||
fsify(structure) | ||
.then((structure) => console.log(structure)) | ||
.catch((err) => console.error(err)) | ||
``` | ||
### Structure from `tree -J` | ||
`tree` is a Linux and Unix command that lists the contents of directories in a tree-like format. It's a helpful CLI to view the structure of your file system. The flag `-J` prints out an JSON representation of the tree. The output can be used in `fsify`. | ||
``` | ||
tree -J > tree.json | ||
``` | ||
```js | ||
const fs = require('fs') | ||
const fsify = require('fsify')() | ||
const structure = fs.readFileSync('tree.json', 'utf8') | ||
fsify(structure) | ||
.then((structure) => console.log(structure)) | ||
.catch((err) => console.error(err)) | ||
``` | ||
## API | ||
### Usage | ||
```js | ||
const fsify = require('fsify')() | ||
``` | ||
```js | ||
const fsify = require('fsify')({ | ||
cwd: process.cwd(), | ||
persistent: true, | ||
force: false | ||
}) | ||
``` | ||
### Parameters | ||
- `opts` `{?Object}` Options. | ||
- `cwd` `{?String}` - Custom relative or absolute path. Defaults to `process.cwd()`. | ||
- `persistent` `{?Boolean}` - Keep directories and files even when the process exists. Defaults to `true`. | ||
- `force` `{?Boolean}` - Allow deleting the current working directory and outside. | ||
### Returns | ||
- `instance` `{Function}({?Array})` [fsify instance](#instance-api). | ||
## Instance API | ||
### Usage | ||
```js | ||
const structure = [ | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename' | ||
} | ||
] | ||
fsify(structure) | ||
.then((structure) => console.log(structure)) | ||
.catch((err) => console.error(err)) | ||
``` | ||
### Parameters | ||
- `structure` `{?Array}` Array of objects containing information about a directory or file. | ||
### Returns | ||
- `{Promise}({Array})` A promise that resolves a structure. Equal to the input structure, but parsed and with a absolute path as the name. | ||
## Structure | ||
A structure is an array of objects that represents a directory structure. Each object must contain information about a directory or file. | ||
The structure … | ||
``` | ||
. | ||
├── dirname | ||
│ └── filename | ||
└── filename | ||
``` | ||
… is equal to … | ||
```js | ||
[ | ||
{ | ||
type: fsify.DIRECTORY, | ||
name: 'dirname', | ||
contents: [ | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename', | ||
contents: 'data' | ||
} | ||
] | ||
}, | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename', | ||
contents: 'data' | ||
} | ||
] | ||
``` | ||
### Directory | ||
A directory must have the `type` of a directory and a `name`. It can also contain another nested structure in its `contents` and a `mode`. | ||
```js | ||
{ | ||
type: fsify.DIRECTORY, | ||
name: 'dirname', | ||
mode: 0o777, | ||
contents: [] | ||
} | ||
``` | ||
### File | ||
A file must have the `type` of a file and a `name`. It can also contain `contents` (data of the file). `encoding`, `mode` and `flag` will be passed directly to `fs.writeFile`. | ||
```js | ||
{ | ||
type: fsify.FILE, | ||
name: 'filename', | ||
contents: 'data', | ||
encoding: 'utf8', | ||
mode: 0o666, | ||
flag: 'w' | ||
} | ||
``` |
'use strict' | ||
const path = require('path') | ||
const once = require('once') | ||
const isPlainObj = require('is-plain-obj') | ||
const parseStructure = require('./parseStructure') | ||
const writeStructure = require('./writeStructure') | ||
const binStructure = require('./binStructure') | ||
const cleanup = require('./cleanup') | ||
/** | ||
* Converts an object into a persistent or temporary directory structure. | ||
* Creates a new instance of fsify. Each instance has its own bin to make testing easier. | ||
* @public | ||
* @param {?Array} structure - Array of objects containing information about a directory or file. | ||
* @param {?Object} opts - Optional options. | ||
* @returns {Promise} Returns the following properties if resolved: {Object}. | ||
* @param {?Object} opts - Options. | ||
* @returns {Function} | ||
*/ | ||
module.exports = function(structure = [], opts = {}) { | ||
module.exports = function(opts = {}) { | ||
return new Promise((resolve, reject) => { | ||
const bin = require('./bin')() | ||
if (Array.isArray(structure)===false) { | ||
throw new Error(`'structure' must be an array`) | ||
} | ||
/** | ||
* Converts an object into a persistent or temporary directory structure. | ||
* @param {?Array} structure - Array of objects containing information about a directory or file. | ||
* @returns {Promise} Returns the following properties if resolved: {Array}. | ||
*/ | ||
const main = function(structure = []) { | ||
if (isPlainObj(opts)===false && opts!=null) { | ||
throw new Error(`'opts' must be an object, null or undefined`) | ||
} | ||
return new Promise((resolve, reject) => { | ||
opts = Object.assign({ | ||
cwd: process.cwd() | ||
}, opts) | ||
if (Array.isArray(structure)===false) { | ||
throw new Error(`'structure' must be an array`) | ||
} | ||
// Support relative and absolute paths | ||
opts.cwd = path.resolve(process.cwd(), opts.cwd) | ||
parseStructure(structure, opts.cwd) | ||
.then((parsedStructure) => writeStructure(parsedStructure)) | ||
.then((parsedStructure) => binStructure(parsedStructure, bin, opts.persistent)) | ||
.then(resolve, reject) | ||
parseStructure(structure, opts.cwd) | ||
.then((parsedStructure) => writeStructure(parsedStructure)) | ||
.then(resolve, reject) | ||
}) | ||
}) | ||
} | ||
/** | ||
* Triggers a cleanup. | ||
* @returns {Array} deletedEntries - Deleted directories and files. | ||
*/ | ||
main.cleanup = function() { | ||
const entriesToDelete = bin() | ||
return cleanup(entriesToDelete, opts.force) | ||
} | ||
/** | ||
* Constants for the structure. | ||
* We don't use symbols for the constants as it should still be possible | ||
* to copy, paste and use the JSON output of `tree`. | ||
*/ | ||
main.DIRECTORY = module.exports.DIRECTORY | ||
main.FILE = module.exports.FILE | ||
if (isPlainObj(opts)===false) { | ||
throw new Error(`'opts' must be an object`) | ||
} | ||
opts = Object.assign({ | ||
cwd : process.cwd(), | ||
persistent : true, | ||
force : false | ||
}, opts) | ||
// Support relative and absolute paths | ||
opts.cwd = path.resolve(process.cwd(), opts.cwd) | ||
// Add cleanup listener when files shouldn't be persistent | ||
if (opts.persistent===false) process.addListener('exit', main.cleanup) | ||
return main | ||
} | ||
@@ -41,0 +82,0 @@ |
'use strict' | ||
const path = require('path') | ||
const get = require('./get') | ||
const path = require('path') | ||
const isPathInside = require('is-path-inside') | ||
const get = require('./get') | ||
@@ -20,10 +21,15 @@ /** | ||
const { type, name, contents, isDirectory, isFile } = get(entry) | ||
const { name, contents, isDirectory, isFile } = get(entry) | ||
const absolutePath = entry.name = path.join(cwd, name) | ||
// Resolve join to get rid of a leading slash that might occur. | ||
const absolutePath = entry.name = path.resolve(path.join(cwd, name)) | ||
if (absolutePath===cwd) { | ||
throw new Error(`Directory name points to the same directory as the surrounding directory`) | ||
throw new Error(`Entry name points to the same path as the surrounding structure`) | ||
} | ||
if (isPathInside(absolutePath, cwd)===false) { | ||
throw new Error(`Entry name points to a path outside the cwd`) | ||
} | ||
if (isDirectory===true) { | ||
@@ -30,0 +36,0 @@ |
@@ -10,3 +10,3 @@ 'use strict' | ||
* @param {String} cwd - Directory to start from. | ||
* @returns {Promise} Returns the following properties if resolved: {Object}. | ||
* @returns {Promise} Returns the following properties if resolved: {Array}. | ||
*/ | ||
@@ -13,0 +13,0 @@ module.exports = function(structure = [], cwd) { |
@@ -18,3 +18,3 @@ 'use strict' | ||
const { type, name, contents, encoding, mode, flag, isDirectory, isFile } = get(entry) | ||
const { name, contents, encoding, mode, flag, isDirectory, isFile } = get(entry) | ||
@@ -21,0 +21,0 @@ if (isDirectory===true) { |
@@ -9,3 +9,3 @@ 'use strict' | ||
* @param {?Array} structure - Array of objects containing information about a directory or file. | ||
* @returns {Promise} Returns the following properties if resolved: {Object}. | ||
* @returns {Promise} Returns the following properties if resolved: {Array}. | ||
*/ | ||
@@ -12,0 +12,0 @@ module.exports = function(structure = []) { |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
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
17859
17
316
264
0
5
+ Addeddel@^2.2.2
+ Addedis-path-inside@^1.0.0
+ Addedonce@^1.4.0
+ Addedarray-union@1.0.2(transitive)
+ Addedarray-uniq@1.0.3(transitive)
+ Addedarrify@1.0.1(transitive)
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addeddel@2.2.2(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedglobby@5.0.0(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedis-path-cwd@1.0.0(transitive)
+ Addedis-path-in-cwd@1.0.1(transitive)
+ Addedis-path-inside@1.0.1(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedobject-assign@4.1.1(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedpath-is-inside@1.0.2(transitive)
+ Addedpinkie@2.0.4(transitive)
+ Addedpinkie-promise@2.0.1(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedwrappy@1.0.2(transitive)