atma-io
Version:
File / Directory Classes
415 lines (356 loc) • 9.32 kB
Markdown
Atma Node.js FileSystem Module
----
[](https://travis-ci.org/atmajs/atma-io)
[](http://badge.fury.io/js/atma-io)
Features:
- File Class
- Directory Class
- File `read/write` Middleware
- Sync + Async
> In comparison to NodeJS sync-async contract: all functions with generic name are synchronous, and the `**Async` are asynchronous with the same interface and return deferred object. Sync versions never throw exceptions and are designed to be used in not performance critical applications, like bash scripts, etc.
> This library is included into Atma.Toolkit, so creating custom scripts, you can use this API.
- [File](#file)
- [API](#file-methods)
- [Cache](#cache)
- [Middleware](#file-middleware)
- [Virtual File](#virtual-files)
- [Directory](#directory)
- [API](#directory-methods)
### File
#### File methods
##### File constructor
```javascript
var file = new io.File('test.txt');
```
Path is always relative to the cwd (_except windows os, when drive letter is used_). To specify system absolute path, use `file://` protocol.
##### read
Read file's content. If `encoding` is set to null raw `Buffer` is returned.
For each `read` middleware pipeline is used, to skip it, set `skipHooks` to true.
```javascript
var content = file.read( <?Object> {
encoding: String | null, //> 'utf8'
skipHooks: Boolean //> false
});
```
##### readAsync
```javascript
file
.readAsync( <?Object> {
encoding: String | null, //> 'utf8'
skipHooks: Boolean //> false
})
.done(function(content, file))
.fail(function(error))
```
##### write
```javascript
file.write(String | Buffer, <?Object>{
skipHooks: Boolean
})
```
##### writeAsync
```javascript
file
.writeAsync(String | Buffer, <?Object>{
skipHooks: Boolean
})
.done(function())
.fail(function(error))
```
##### exists
```ts
file.exists(): boolean
```
##### copyTo
```ts
interface IFileCopyOpts {
silent?: boolean
baseSource?: string
}
/**
* @param path: Target file path or directory, when ends with slash
*/
file.copyTo(path: string, opts?: IFileCopyOpts): boolean
```
##### copyToAsync
```ts
file.copyToAsync(path: string, opts?: IFileCopyOpts): Promise<boolean>
```
##### rename
```ts
file.rename(filename: string)
```
##### renameAsync
```ts
file.renameAsync(filename: string): Promise<void>
```
##### replace
Reads the content as string, replaces the matches and writes the result.
Expected arguments are the same as for JavaScripts String `replace`.
Returns new content.
```ts
.replace(string | RegExp, string | Function): string
```
##### replaceAsync
```ts
.replaceAsync(string | RegExp, string | Function): Promise<string>
```
##### remove
```ts
file.remove()
```
##### removeAsync
```ts
file.removeAsync(): Promise<void>
```
##### watch
```javascript
file.watch(cb: (path) => void)
```
Watch file for changes
##### unwatch
```ts
file.unwatch(cb?: (path) => void): boolean
```
#### Cache
Each `read` will be cached. To control cache behaviour use next methods:
##### clearCache
```javascript
File.clearCache(<?String> path);
```
When `path` is `null`, then all cache is dropped.
##### disableCache
```javascript
File.disableCache();
```
##### enableCache
```javascript
File.disableCache();
```
#### short forms
There are some static methods, so that there is no need to initialize the File instance.
```javascript
File[method] //> Function(filepath, [..args])
// methods:
'exists'
'existsAsync'
'read'
'readAsync'
'write'
'writeAsync'
'remove'
'removeAsync',
'replace',
'replaceAsync',
'rename'
'renameAsync'
'copyTo'
'copyToAsync'
// sample
io
.File
.readAsync('/baz.txt')
.done(function(content){
console.log(content);
})
.fail(function(error){
console.error(error);
})
;
```
### File Middleware
Middleware pattern is used for all reads and writes. It can be used, for example, to compile coffee script to javascript on the fly. Or when reading `*.yml` file, the resulted content is not a YAML string, but already parsed object.
#### Extensions
To get the idea, look at the hook definition sample:
```javascript
io.File.registerExtensions({
'coffee':[
'conditions:read',
'coffee-compiler:read',
'uglify:write'
]
});
```
Each middleware has unique name and is registerd in this way:
```javascript
io.File.middleware['coffee'] = {
read: function(<io.File> file, <Object> config){
var coffee = require('coffee-script');
file.content = coffee.compile(file.content);
},
write: function(<io.File> file, <Object> config){
// ... do smth with `content` before disk write
}
};
```
#### Advanced middleware
```ts
io
.File
.getHookHandler()
.register({
regexp: <RegExp>,
method: <'read'|'write'>,
handler: <Function | Object> handler,
zIndex: Boolean
```
##### existsAsync
```javascript
dir.existsAsync()//> Deferred
```
##### readFiles
```javascript
dir.readFiles(<?String> pattern).files // Array<io.Files>
```
Get list of all files in the directory. `pattern` is a glob pattern.
```javascript
// all javascript files, also from sub-directories
pattern = '*.js';
// only from base directory
pattern = '/*.js'
// only from sub-directories
pattern = '**/*.js'
dir.readFiles(pattern).files
```
##### readFilesAsync
```javascript
dir
.readFilesAsync(<?String> pattern)
.done(function(files))
.fail(function(error))
```
##### copyTo
Copy `files` to destination directory. Before copying `dir.readFiles` can be called to copy only specific files.
```ts
dir.copyTo(destination: string)
```
##### copyToAsync
```javascript
dir.copyToAsync(destination: string) //> Deferred
```
##### rename
```javascript
dir.rename(<String> folderName);
```
##### renameAsync
```javascript
dir.renameAsync(<String> folderName) //> Deferred
```
##### remove
Removes all content recursively and the folder itself
```javascript
dir.remove() //> Boolean
```
##### removeAsync
```javascript
dir.removeAsync()
```
##### ensure
```javascript
dir.ensure()
```
Creates directory structure, if not already exists.
##### ensureAsync
```javascript
dir.ensureAsync()
```
##### watch
```javascript
dir.watch(callback)
```
Watch directory for changes
##### unwatch
```javascript
dir.unwatch(callback)
```
##### short forms
There are some static methods, so that there is no need to initialize the Directory instance.
```javascript
io.Directory[method] //> Function(dirpath, [..args])
// methods:
'exists'
'existsAsync'
'readFiles'
'readFilesAsync'
'ensure'
'ensureAsync'
'remove'
'removeAsync'
'copyTo'
'copyToAsync'
// sample
io
.Directory
.readFilesAsync('sub/', '**.js')
.done(function(files))
.fail(function(error))
```
----
(c) MIT - Atma.js Project