Comparing version 0.0.2 to 1.0.0-beta.1
{ | ||
"name": "phylo", | ||
"version": "0.0.2", | ||
"version": "1.0.0-beta.1", | ||
"description": "File operations class", | ||
@@ -26,4 +26,6 @@ "main": "File.js", | ||
"json5": "^0.5.0", | ||
"mkdirp": "^0.5.1" | ||
"mkdirp": "^0.5.1", | ||
"rimraf": "^2.5.4", | ||
"tmp": "0.0.30" | ||
} | ||
} |
148
play.js
'use strict'; | ||
const File = require('./File'); | ||
const Globber = File.Globber; | ||
File.COMPANY = 'Foobar'; | ||
var f; | ||
var gg = Globber.get('i'); | ||
console.log(gg); | ||
var re = gg.compile('**/*.txt'); | ||
console.log(re); | ||
console.log('match:', re.exec('C:\\Program Files/foo.txt')); | ||
var f = File.temp(); | ||
console.log(`home: ${File.home()}`); | ||
console.log(`profile: ${File.profile('Acme')}`); | ||
console.log(`profile: ${File.profile()}`); | ||
//console.log(`profile.stat: `, File.profile().stat()); | ||
//console.log(`profile.access: `, File.profile().access()); | ||
f = File.cwd().upTo('package.json').load(); | ||
console.log(`package ${f.name}`); | ||
File.asyncTemp().then(t => { | ||
console.log(`asyncTemp: ${t}`); | ||
}); | ||
f = new File('~/.sencha'); | ||
console.log(`temp: ${f}`); | ||
console.log(`File.temp: ${File.temp()}`); | ||
console.log(`tempFile: ${f.temp().absolutePath()}`); | ||
console.log(`f: ${f}`); | ||
console.log(`f.abssolute: ${f.absolutePath()}`); | ||
console.log(`f.canonical: ${f.canonicalPath()}`); | ||
console.log(`f.native: ${f.nativePath()}`); | ||
console.log(`f.normalized: ${f.normalizedPath()}`); | ||
console.log(`f.slashified: ${f.slashifiedPath()}`); | ||
console.log(`f.join: ${f.join('foo')}`); | ||
console.log(`f.parent: ${f.parent}`); | ||
console.log(`f.parent.join: ${f.parent.join('foo')}`); | ||
console.log(`f.parent.parent: ${f.parent.parent}`); | ||
File.asyncTemp().then(t => { | ||
console.log(`asyncTemp: ${t}`); | ||
}); | ||
f.list('A').forEach(ff => { | ||
let pkg = File.cwd().upTo('package.json').load(); | ||
console.log(`package ${pkg.name}`); | ||
f.asyncTemp().then(ff => { | ||
console.log(`ff: ${ff}`); | ||
}); | ||
try { | ||
File.from('C:\\Windows\\foobar.txt').save(pkg); | ||
} | ||
catch (e) { | ||
console.log(`error: ${e.code} - ${e.message}`); | ||
} | ||
// f.join('foo.json').save(pkg, { | ||
// indent: '\t' | ||
// }); | ||
// | ||
// f.list().forEach(ff => { | ||
// console.log(`ff: ${ff.path}`); | ||
// }); | ||
// f = new File('~/.sencha'); | ||
// | ||
// console.log(`f: ${f}`); | ||
// console.log(`f.absolute: ${f.absolutePath()}`); | ||
// console.log(`f.canonical: ${f.canonicalPath()}`); | ||
// console.log(`f.native: ${f.nativePath()}`); | ||
// console.log(`f.normalized: ${f.normalizedPath()}`); | ||
// console.log(`f.slashified: ${f.slashifiedPath()}`); | ||
// console.log(`f.join: ${f.join('foo')}`); | ||
// console.log(`f.parent: ${f.parent}`); | ||
// console.log(`f.parent.join: ${f.parent.join('foo')}`); | ||
// console.log(`f.parent.parent: ${f.parent.parent}`); | ||
// f = File.cwd(); | ||
// f.list('A', '*.js').forEach(ff => { | ||
// console.log(`ff: ${ff} ==> ${ff.name}`); | ||
// }); | ||
var fd = File.cwd().join('foo'); | ||
fd.mkdir(); | ||
File.cwd().list('A', ff => { | ||
console.log(`ff: ${ff}`); | ||
}); | ||
// console.log(`rm ${fd}`); | ||
// fd.remove(); | ||
// File.cwd().list('A', ff => { | ||
// console.log(`ff: ${ff}`); | ||
// }); | ||
f = fd.join('foo.json'); | ||
f.save(pkg, 'json5'); | ||
f.parent.list('A', '*.json').forEach(ff => { | ||
console.log(`ff: ${ff} ==> ${ff.name}`); | ||
}); | ||
f = new File('~~/.sencha'); | ||
console.log(`f: ${f}`); | ||
console.log(`f.abssolute: ${f.absolutePath()}`); | ||
//console.log(`f.canonical: ${f.canonicalPath()}`); | ||
console.log(`f.native: ${f.nativePath()}`); | ||
console.log(`f.normalized: ${f.normalizedPath()}`); | ||
console.log(`f.slashified: ${f.slashifiedPath()}`); | ||
console.log(`f.join: ${f.join('foo')}`); | ||
console.log(`f.parent: ${f.parent}`); | ||
console.log(`f.parent.join: ${f.parent.join('foo')}`); | ||
console.log(`f.parent.parent: ${f.parent.parent}`); | ||
console.log(`rm ${f.name}`); | ||
f.remove(); | ||
f.parent.list('A', '*.json').forEach(ff => { | ||
console.log(`ff: ${ff} ==> ${ff.name}`); | ||
}); | ||
//f.save(pkg, 'json5'); | ||
fd.asyncRemove().then(ff => { | ||
console.log(`ff: ${ff}`); | ||
File.cwd().list('A', cc => { | ||
console.log(`cc: ${cc}`); | ||
}); | ||
}, | ||
e => { | ||
console.log('rm err:', e.message); | ||
}); | ||
// f.list('A', (name, f2) => { console.log('f2',f2); return name.endsWith('.js'); }).forEach(ff => { | ||
// console.log(`ff: ${ff} ==> ${ff.name}`); | ||
// }); | ||
// f.walk('A', '**/*.{js,json}', ff => { | ||
// console.log(`walk: ${ff}`) | ||
// }); | ||
// f = new File('~~/.sencha'); | ||
// console.log(`f: ${f}`); | ||
// console.log(`f.absolute: ${f.absolutePath()}`); | ||
// //console.log(`f.canonical: ${f.canonicalPath()}`); | ||
// console.log(`f.native: ${f.nativePath()}`); | ||
// console.log(`f.normalized: ${f.normalizedPath()}`); | ||
// console.log(`f.slashified: ${f.slashifiedPath()}`); | ||
// console.log(`f.join: ${f.join('foo')}`); | ||
// console.log(`f.parent: ${f.parent}`); | ||
// console.log(`f.parent.join: ${f.parent.join('foo')}`); | ||
// console.log(`f.parent.parent: ${f.parent.parent}`); | ||
//console.log(`load: ${f.join('don.license').load()}`); | ||
@@ -63,4 +151,8 @@ | ||
// f.asyncWalk('Ad', (item, state) => { | ||
// console.log(`${' '.repeat(state.stack.length * 4)}${item.name} - ${item._stat ? item._stat.attribs : ''}`); | ||
// f = File.cwd(); | ||
// f.asyncWalk('', (item, state) => { | ||
// //let c = item.isDirectory() ? '>' : ' '; | ||
// //console.log(`${c} ${' '.repeat(state.stack.length * 4)}${item.name} - ${item._stat ? item._stat.attribs : ''}`); | ||
// }, (item, state) => { | ||
// console.log(`< ${' '.repeat(state.stack.length * 4)}${item.name} - ${item.stat().attrib.text}`); | ||
// }).then(() => { | ||
@@ -67,0 +159,0 @@ // console.log('done'); |
338
README.md
@@ -53,2 +53,9 @@ # phylo | ||
- Callbacks passed to async methods can return immediate results or Promises. | ||
- As much as possible, exceptions and `null` return values are avoided. For | ||
example, `stat()` returns an object in all cases but that object may have an | ||
`error` property. | ||
- Where reasonable, objects are cached to avoid GC pressure. For example, things | ||
like access masks, file attributes, status errors, directory list modes, etc. are | ||
lazily cached as immutable (`Object.freeze()` enforced) instances and reused as | ||
needed. | ||
@@ -117,4 +124,5 @@ ## Path Manipulation | ||
- `equals(o)` - Returns `true` if `this` is equal to `o` (`compare(o) === 0`) | ||
- `prefixes(o)` - Returns `true` if `this` is a path prefix of `o`. Best to | ||
use `absolutify()` on both instances first to avoid issues with `..` segments. | ||
- `prefixes(o)` - Returns `true` if `this` is a path prefix of `o`. It is | ||
recommended to use `absolutify()` on both instances first to avoid confusion with | ||
`..` segments. | ||
@@ -140,3 +148,4 @@ File name comparisons are case-insensitive on Windows and Mac OS X, so we have | ||
- `access()` - Returns a `FileAccess` object or `null` if the file doesn't exist. | ||
- `access()` - Returns a `File.Access` object. If the file does not exist (or some | ||
other error is encountered), this object will have an `error` property. | ||
- `can(mode)` - Returns `true` if this exists with the desired access (`mode` is "r", | ||
@@ -148,9 +157,19 @@ "rw", "rwx", "w", "wx" or "x"). | ||
- `hasFile(rel)` - Returns `true` if a file exists at the `rel` path from this file. | ||
- `isHidden()` - Returns `true` if this file does not exist or is hidden. | ||
- `stat()` / `restat()` - Returns `fs.statSync(this.path)` (an `fs.Stats`). | ||
- `statLink()` / `restatLink()` - Returns `fs.lstatSync(this.path)` (an `fs.Stats`). | ||
- `isHidden()` - Returns `true` if this file does not exist or is hidden. Note that on | ||
Windows, hidden state is not based on a file name convention (".hidden") but is a bit | ||
stored in the file-system (see below). | ||
- `stat()` / `restat()` - Returns `fs.statSync(this.path)` (an `fs.Stats`). If the | ||
file does not exist (or some other error is encountered), this object will have an | ||
`error` property. | ||
- `statLink()` / `restatLink()` - Returns `fs.lstatSync(this.path)` (an `fs.Stats`). If | ||
the file does not exist (or some other error is encountered), this object will have an | ||
`error` property. | ||
The `error` property will be a value like `"ENOENT"` (for file/folder not found), and | ||
`"EACCES"` or `"EPERM"` for permission denied. These codes come directly from the | ||
underlying API. | ||
In asynchronous form: | ||
- `asyncAccess()` - Promises a `FileAccess` | ||
- `asyncAccess()` - Promises a `File.Access` | ||
- `asyncCan(mode)` - Promises `true` or `false`. | ||
@@ -165,22 +184,31 @@ - `asyncExists()` - Promises `true` or `false`. | ||
### FileAccess | ||
### File Status | ||
`FileAccess` objects are succinct descriptions of read, write and execute permission | ||
masks. These replace the use of fs.constants.R_OK, fs.constants.W_OK and | ||
fs.constants.X_OK. For example: | ||
let mode = fs.statSync(file).mode; | ||
if (mode & fs.constants.R_OK && mode & fs.constants.W_OK) { | ||
// path is R and W | ||
} | ||
The [`fs.Stat`](https://nodejs.org/api/fs.html#fs_class_fs_stats) structure is augmented | ||
with an `attrib` property. This is an instance of `File.Attribute` and will have these | ||
boolean properties: | ||
Or using `File` and `FileAccess`: | ||
- `A` - Archive | ||
- `C` - Compressed | ||
- `E` - Encrypted | ||
- `H` - Hidden | ||
- `O` - Offline | ||
- `R` - Readonly | ||
- `S` - System | ||
if (file.access().rw) { | ||
// path is R and W | ||
} | ||
The [`fswin`](https://www.npmjs.com/package/fswin) module is used to retrieve this | ||
information on Windows. On other platforms, this object contains `false` values for all | ||
of the above properties. | ||
To handle the case where the file may not exist, compare: | ||
An `fs.Stat` object is cached on the `File` instance by the `stat()` family of methods | ||
and a separate instance is cached on by the `statLink()` family. These are lazily | ||
retrieved and then stored for future use. To get fresh copies, use the `restat()` family | ||
of methods. | ||
### File.Access | ||
`File.Access` objects are succinct descriptions of read, write and execute permission | ||
masks. These replace the use of `fs.constants.R_OK`, `fs.constants.W_OK` and | ||
`fs.constants.X_OK`. For example: | ||
try { | ||
@@ -197,4 +225,10 @@ let mode = fs.statSync(file).mode; | ||
But using `File` this can be: | ||
Or using `File` and `File.Access`: | ||
if (file.access().rw) { | ||
// file exists and is R & W | ||
} | ||
Alternatively, there is the `can()` method: | ||
if (file.can('rw')) { | ||
@@ -204,6 +238,25 @@ // file exists and is R & W | ||
There are a fixed set of `FileAccess` objects, one for each combination of R, W and X | ||
permissions: `r`, `rw`, `rx`, `rwx`, `w`, `wx`, `x`. Each instance also has these | ||
same properties as boolean values. The full set of properties is a bit larger: | ||
When the file does not exist, or an error is encountered, the object returned by the | ||
`access()` method will have an `error` property. Since the access bits are all `false` | ||
in this case, this distinction if often unimportant (as above). | ||
To check for errors: | ||
var acc = file.accecss(); | ||
if (acc.rw) { | ||
// file exists and has R/W access | ||
} | ||
else if (acc.error === 'ENOENT') { | ||
// file does not exist... | ||
} | ||
else if (acc.error === 'EACCES' || acc.error === 'EPERM') { | ||
// access or permission error... | ||
} | ||
... | ||
There are a fixed set of immutable `File.Access` objects, one for each combination of | ||
R, W and X permissions: `r`, `rw`, `rx`, `rwx`, `w`, `wx`, `x`. Each instance also has | ||
these same properties as boolean values. The full set of properties is a bit larger: | ||
- `r` - True if `R_OK` is set. | ||
@@ -222,34 +275,37 @@ - `rw` - True if `R_OK` and `W_OK` are both set. | ||
It is often important to know if a file is a directory or other type of entity. This | ||
information is fundamentally a result of the `stat()` family but for convenience is | ||
information is fundamentally the business of the `stat()` family but for convenience is | ||
also provided on the `File` instance: | ||
- `isDirectory` | ||
- `isFile` | ||
- `isBlockDevice` | ||
- `isCharacterDevice` | ||
- `isFIFO` | ||
- `isSocket` | ||
- `isSymbolicLink` | ||
- `isDirectory(mode)` | ||
- `isFile(mode)` | ||
- `isBlockDevice(mode)` | ||
- `isCharacterDevice(mode)` | ||
- `isFIFO(mode)` | ||
- `isSocket(mode)` | ||
- `isSymbolicLink(mode)` | ||
In addition, the following shorthand methods are also available: | ||
- `isDir` (alias for `isDirectory()`) | ||
- `isSymLink` (alias for `isSymbolicLink()`) | ||
- `isDir(mode)` (alias for `isDirectory()`) | ||
- `isSymLink(mode)` (alias for `isSymbolicLink()`) | ||
These are also available as async methods: | ||
- `asyncIsDir` | ||
- `asyncIsDirectory` | ||
- `asyncIsFile` | ||
- `asyncIsBlockDevice` | ||
- `asyncIsCharacterDevice` | ||
- `asyncIsFIFO` | ||
- `asyncIsSocket` | ||
- `asyncIsSymLink` | ||
- `asyncIsSymbolicLink` | ||
- `asyncIsDir(mode)` | ||
- `asyncIsDirectory(mode)` | ||
- `asyncIsFile(mode)` | ||
- `asyncIsBlockDevice(mode)` | ||
- `asyncIsCharacterDevice(mode)` | ||
- `asyncIsFIFO(mode)` | ||
- `asyncIsSocket(mode)` | ||
- `asyncIsSymLink(mode)` | ||
- `asyncIsSymbolicLink(mode)` | ||
Since the nature of a file seldom changes on a whim, the results of these tests are | ||
stored on the `File` instance. If this is undesired, it is better to stick with the | ||
`stat()` family since it provides a way to refresh this information (`restat()`). | ||
The optional `mode` parameter can be `'l'` (lowercase-L) to use the `statLink()` (or | ||
`asyncStatLink()`) method to determine the result. | ||
Since the nature of a file seldom changes on a whim, these methods use the `stat()` | ||
methods and their cached information. If this is undesired, these results can be | ||
refreshed using the `restat()` family of methods. | ||
## Directory Listing | ||
@@ -312,4 +368,4 @@ | ||
`join(rel)` from that location. | ||
- `upDir(rel)` - Same as `upTo()` but using `hasDir(rel)` as the `test`. | ||
- `upFile(rel)` - Same as `upTo()` but using `hasFile(rel)` as the `test`. | ||
- `upToDir(rel)` - Same as `upTo()` but using `hasDir(rel)` as the `test`. | ||
- `upToFile(rel)` - Same as `upTo()` but using `hasFile(rel)` as the `test`. | ||
@@ -334,4 +390,4 @@ The different between these forms can be seen best by example: | ||
- `asyncUpTo(rel)` - TODO | ||
- `asyncUpDir(rel)` - TODO | ||
- `asyncUpFile(rel)` - TODO | ||
- `asyncUpToDir(rel)` - TODO | ||
- `asyncUpToFile(rel)` - TODO | ||
@@ -342,11 +398,13 @@ ### Descent | ||
Once a match is found, no descent into that folder is made (hence, the "tips" of | ||
the sub-tree). | ||
- `walk(mode, handler)` - Calls `handler` for all items that `list(mode)` generates | ||
recursively. | ||
the sub-tree). Uses `walk(mode)` to descend the file-system. | ||
- `walk(mode, before, after)` - Calls `before` for all items that | ||
`list(mode)` generates recursively, then processes those items and | ||
lastly calls `after`. Both `before` and `after` are optional but one | ||
should be provided. | ||
The `walk` method's `handler` looks like this: | ||
The `walk` method's `before` and `after` handlers looks like this: | ||
function handler (file, state) { | ||
function beforeOrAfter (file, state) { | ||
if (file.isDir() && ...) { | ||
return false; // do not recurse into this dir | ||
return false; // do not recurse into file (before only) | ||
} | ||
@@ -363,2 +421,3 @@ | ||
- `previous` - The `File` previously passed to the handler. | ||
- `root` - The `File` used to start the descent. | ||
- `stack` - A `File[]` of instances starting with the `File` used to start things. | ||
@@ -377,3 +436,3 @@ - `stop` - A boolean property that can be set to `true` to abort the `walk`. | ||
The `state` parameter is the same as for the `handler` on the `walk` method. | ||
The `state` parameter is the same as for the `walk` method. | ||
@@ -383,15 +442,24 @@ Asynchronous forms: | ||
- `asyncTips(mode, test)` | ||
- `asyncWalk(mode, handler)` | ||
- `asyncWalk(mode, before, after)` | ||
The `test` and `handler` methods of the asynchronous methods accept the same | ||
parameters and can return the same results as with the synchronous forms. They | ||
can alternatively return a Promise if their determination is also async. | ||
The `test`, `before` and `after` handlers of the asynchronous methods | ||
accept the same parameters and return the same results as with the | ||
synchronous forms. They can, alternatively, return a Promise if their | ||
determination is also async. | ||
## Reading / Loading Files | ||
## Reading and Writing Files | ||
Basic file reading and decoding/parsing are provided by these methods: | ||
- `load(options)` - Reads, decodes and parses the file according to `options`. | ||
- `asyncLoad(options)` - Same as `load()` except a Promise is returned | ||
- `asyncLoad(options)` - Same as `load()` except a Promise is returned. | ||
- `load(options)` - Reads, decodes and parses the file according to | ||
the provided `options`. | ||
And serializing, encoding and writing is provided by: | ||
- `asyncSave(data, options)` - Same as `save()` except a Promise is | ||
returned. | ||
- `save(data, options)` - Serializes and encodes the data and writes | ||
it to this file using the specified `options`. | ||
The act of loading a file consists initially of reading the data (obviously). To | ||
@@ -403,13 +471,11 @@ get this part right, you need an `encoding` option which is tedious to setup in | ||
var pkg = path.join(dir, 'package.json'); // a string | ||
var pkg = path.join(dir, 'package.json'); | ||
var data = JSON.parse(fs.readfileSync(pkg, { | ||
encoding: 'utf8' | ||
})); | ||
var data = JSON.parse(fs.readfileSync(pkg, 'utf8')); | ||
To loading using `File`: | ||
var pkg = dir.join('package.json'); // a File | ||
var pkg = dir.join('package.json'); | ||
var data = pkg.load(); // a parsed Object | ||
var data = pkg.load(); | ||
@@ -428,5 +494,44 @@ The basic advantage of the `File` approach is the error messages you get when | ||
### Loader Options | ||
When it is time to save the data, the process looks very symmetric: | ||
The default loader is based on the file's type, but we can override this: | ||
pkg.save(data); | ||
Instead of the manual alternative: | ||
fs.writeFileSync(pkg, JSON.stringify(data, null, ' '), 'utf8'); | ||
**NOTE:** Unlike most of the `File` API, these methods throw exceptions (or reject | ||
Promises) on failure. | ||
### Predefined Readers | ||
Readers are objects that manage options for reading and parsing files. The following | ||
readers come predefined: | ||
- `bin` - An alias for `binary`. | ||
- `binary` - Reads a file as a buffer. | ||
- `json` - Extends the `text` reader and provides a `parse` method to | ||
deserialize JSON data. This uses the [`json5`](https://www.npmjs.com/package/json5) | ||
module to tolerate human friendly JSON. | ||
- `json:strict` - Extends `text` reader and uses strict `JSON.parse()`. | ||
- `text` - Reads a file as `utf8` encoding. | ||
- `txt` - An alias for `text`. | ||
### Predefined Writers | ||
Writers are objects that manage options for serializing and writing files. The | ||
following writers come predefined: | ||
- `bin` - An alias for `binary`. | ||
- `binary` - Writes a file from a buffer. | ||
- `json` - Extends the `text` writer and provides a `serialize` method to | ||
write JSON data. | ||
- `json5` - Extends `json` writer and uses `json5.stringify()`. | ||
- `text` - Writes a file as `utf8` encoding. Accepts a `join` string option to | ||
join the data if the data is an array (of lines perhaps). | ||
- `txt` - An alias for `text`. | ||
### Reader Options | ||
The default reader is selected based on the file's type, but we can override this: | ||
@@ -442,16 +547,11 @@ var data = pkg.load('text'); // load as a simple text (not parsed) | ||
This simplicity is accomplished using a `File.Loader` instance or simply a `loader`. | ||
Loaders are identified by name such as `text`, `binary` or `json`. By default, | ||
the file's extension (`extent` property) is used to select the `loader`. This will | ||
default to `text` for files with unrecognized extensions. | ||
Readers support the following configuration properties: | ||
Loaders support the following configuration properties: | ||
- `parse` - A function called to parse the file content. The method accepts two | ||
arguments: `data` and `loader`. The `data` parameter is the file's content and | ||
the `loader` is the fully configured `loader` instance. | ||
arguments: `data` and `reader`. The `data` parameter is the file's content and | ||
the `reader` is the fully configured `reader` instance. | ||
- `split` - An optional `RegExp` or `String` for a call to `String.split()`. This | ||
is used by the default `parse` method. | ||
In addition to `loader` configuration, the `fs.readFile()` options can be supplied: | ||
In addition to `reader` configuration, the `fs.readFile()` options can be supplied: | ||
@@ -465,3 +565,3 @@ var content = file.load({ | ||
The `encoding` can be specified in the `options` or directly to the `loader`: | ||
The `encoding` can be specified in the `options` or directly to the `reader`: | ||
@@ -480,2 +580,51 @@ var content = file.load({ | ||
### Writer Options | ||
The default writer is selected based on the file's type, but we can override this: | ||
pkg.save(data, 'text'); | ||
Other options can be specified (e.g. to join lines in an array with new-lines): | ||
pkg.save(data, { | ||
type: 'text', | ||
join: '\n' | ||
}); | ||
Writers support the following configuration properties: | ||
- `serialize` - A function called to convert the data and return what will be written | ||
to disk. The method accepts two arguments: `data` and `writer`. The `data` parameter | ||
is the raw file data and the `writer` is the fully configured `writer` instance. | ||
- `join` - An optional `String` for a call to `Array.join()` when file data is | ||
an array. This is used by the default `serialize` method. | ||
The `json` writer also supports these properties: | ||
- `indent` maps to the `space` parameter for `JSON.stringify`. | ||
- `replacer` map to the `replacer` parameter for `JSON.stringify`. | ||
In addition to `writer` configuration, the `fs.writeFile()` options can be supplied: | ||
file.save(data, { | ||
// The options object is passed directly to fs.writeFile() | ||
options: { | ||
... | ||
} | ||
}); | ||
The `encoding` can be specified in the `options` or directly to the `writer`: | ||
file.save(data, { | ||
encoding: 'utf16' | ||
}); | ||
// Or on the fs options: | ||
file.save(data, { | ||
options: { | ||
encoding: 'utf16' | ||
} | ||
}); | ||
## Static Methods | ||
@@ -499,2 +648,11 @@ | ||
There is also `fspath()` that resolves `"~"` path elements: | ||
var s = File.fspath(file); | ||
If the argument is already a `String` it is simply returned (just like the `path()` | ||
method). If the string may contain `"~"` elements, the safe conversion would be: | ||
var s = File.from(file).fspath; | ||
### Utility Methods | ||
@@ -511,2 +669,3 @@ | ||
- `split(fs)`- Returns a `String[]` from the `File` or `String`. | ||
- `stat(fs)` - Returns the `stat()` for the `File` or `String`. | ||
- `sorter(fs1, fs2)` - Calls `File.from(fs1).compare(fs2)` (useful for sorting | ||
@@ -535,3 +694,14 @@ `File[]` and `String[]`). | ||
- `profile()` - Returns the platform-favored storage folder for app data. | ||
- `temp()` - Temporary folder for this application. | ||
### Temp | ||
The `temp()` and `asyncTemp()` static methods use the [`tmp`](https://www.npmjs.com/package/tmp) | ||
module to generate a temporary folder in the appropriate location for the platform. | ||
When these methods are called with no `options` argument, they lazily | ||
create (and cache for future requests) a single temporary folder. | ||
### Profile | ||
The `profile()` method handles the various OS preferences for storing application | ||
@@ -538,0 +708,0 @@ data. |
Sorry, the diff of this file is too big to display
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
166906
13
3985
751
1
5
+ Addedrimraf@^2.5.4
+ Addedtmp@0.0.30
+ Addedbalanced-match@1.0.2(transitive)
+ Addedbrace-expansion@1.1.11(transitive)
+ Addedconcat-map@0.0.1(transitive)
+ Addedfs.realpath@1.0.0(transitive)
+ Addedglob@7.2.3(transitive)
+ Addedinflight@1.0.6(transitive)
+ Addedinherits@2.0.4(transitive)
+ Addedminimatch@3.1.2(transitive)
+ Addedonce@1.4.0(transitive)
+ Addedos-tmpdir@1.0.2(transitive)
+ Addedpath-is-absolute@1.0.1(transitive)
+ Addedrimraf@2.7.1(transitive)
+ Addedtmp@0.0.30(transitive)
+ Addedwrappy@1.0.2(transitive)