npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

atma-io

v1.3.5

Published

File / Directory Classes

Downloads

7,150

Readme

FileSystem Module



Build Status NPM version

Features:

  • File Class.
  • Directory Class.
  • File IO Middlewares to preprocess reads and writes actions.
  • File Transport middleware for custom file protocols, e.g. s3://uploads/avatar.png
  • Sync and Async
  • Safe Files to ensure thread-safe and process-safe file writes.
  • File-locks to make custom process-safe actions easy to implement.
  • File watcher: cross-platform file watchers.
  • AES-256 Encryption
  • HTTP Transport: get, post, put, head and delete methods to handle files.

📚 API Documentation

In comparison to NodeJS sync-async contract: all functions with generic name are synchronous, and the **Async are asynchronous with the same interface. Sync versions never throw exceptions and are designed to be used in not performance critical applications, like bash scripts, etc. Go Async.

File

File methods

File constructor
import { File } from 'atma-io'

const file = new File('./test.txt');

Path is relative to the cwd (except windows os, when drive letter is used). To specify system absolute path, use file:// protocol.

read readAsync

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.

Hooks will be per default executed. For example, when reading from *.json file the string will be deserialized to json object

let content = file.read<TOut = string>( options?: {
    encoding?: 'buffer' | 'utf8' //> default 'utf8'
    skipHooks?: boolean //> false
    aes256?: { secret: string }
});

let content = await file.readAsync <TOut = string> (options?: {
    encoding?: 'buffer' | 'utf8', //> 'utf8'
    skipHooks?: boolean //> false
    aes256?: { secret: string }
});
readRange readRangeAsync

Get bytes or string for a range from the file

let content = file.readRange(position, length);

let content = await file.readRangeAsync(position, length)
write writeAsync

Hooks will be per default executed. For example, when writing to *.json file and providing an object, this object will be serialized to json string

file.write(string | Buffer | any, options?: {
    skipHooks?: boolean
    aes256?: { secret: string }
})

file
    .writeAsync(content: string | Buffer | any, options?: {
        skipHooks?: boolean
        aes256?: { secret: string }
    })
    .then(() => {}, (err) => {})
append appendAsync
file.append(content: string)

await file.appendAsync(string);
exists existsAsync
let b: boolean = file.exists()

let b: boolean = await file.existsAsync();
copyTo copyToAsync
interface IFileCopyOpts {
    silent?: boolean
    baseSource?: string
}
/**
 * @param path: Target file path or directory, when ends with slash
 */
file.copyTo(path: string, opts?: IFileCopyOpts): boolean

file.copyToAsync(path: string, opts?: IFileCopyOpts): Promise<boolean>
rename renameAsync
file.rename(filename: string)

file.renameAsync(filename: string): Promise<void>
replace replaceAsync

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.

file.replace(search: string | RegExp, replacer: string | Function): string

file.replaceAsync(search: string | RegExp, replacer: string | Function): Promise<string>
remove removeAsync
file.remove(): boolean

file.removeAsync(): Promise<boolean>
watch

Watch file for changes

file.watch(cb: (path) => void)
unwatch
file.unwatch(cb?: (path) => void): boolean

Cache

Each read will be cached. To control cache behavior use next methods:

clearCache
File.clearCache(<?string> path);

When path is null, then all cache is dropped.

disableCache
File.disableCache();
enableCache
File.disableCache();

short forms

There are some static methods, so that there is no need to initialize the File instance.

File[method] //> Function(filepath, [..args])
// methods:
        'exists'
        'existsAsync'
        'read'
        'readAsync'
        'readRange'
        'readRangeAsync'
        'write'
        'writeAsync'
        'append'
        'appendAsync'
        'remove'
        'removeAsync'
        'replace'
        'replaceAsync'
        'rename'
        'renameAsync'
        'copyTo'
        'copyToAsync'

// sample
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:

import { File } from 'atma-io'
File.registerExtensions({
    'coffee':[
        'conditions:read',
        'coffee-compiler:read',
        'uglify:write'
    ]
});

Each middleware has unique name and is registered in this way:

import { File } from 'atma-io'
File.middleware['coffee'] = {
    read: function(<io.File> file, <Object> config){
        let 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

import { File } from 'atma-io'
File
    .getHookHandler()
    .register({
        regexp: <RegExp>,
        method: <'read'|'write'>,
        handler: <Function | Object> handler,
        zIndex: <?Number> // default: 0
    });

Path is matched by the regexp. The greater zIndex is, the later it is called in the pipeline, otherwise the handlers are called in the order they were registered.

Embedded middlewares

Lately will be converted into plugins, @see Plugins

  • read

    • coffee ( -> javascript )
    • markdown ( -> html )
    • jshint ( -> run jshint )
    • json ( -> JSON.parse is used )
    • yml ( -> YAML parser is used )
  • write

    • uglify ( -> Minify source before write)
    • cssmin ( -> Minify source before write)
    • yml ( -> stringify object to yml string )
    • json ( -> stringify object to json )

Middleware Plugins

There additional read/write middlewares as atma plugins:

atma plugin install NAME
Combined middlewares

For example, you want to use Traceur middelware and jshint for reading js files: via javascript

File.registerExtensions({
    js: ['hint:read', 'atma-loader-ts:read' /* ... */],
})

via package.json

...
"atma": {
    "settings" : {
        "io": {
            "extensions": {
                "js": [ "hint:read", "atma-loader-ts:read" ]
            }
        }
    }
}

Virtual Files

Define with RegExp a File Handler to completely override the read/write/exists/remove behavior.

import { File } from 'atma-io'
File
    .getFactory()
    .registerHandler(/defaults\.json$/i, class {
        exists (){
            return true;
        },
        read (){
            return { foo: 'bar' };
        }
    });

Directory

Directory methods

Constructor
import { Directory } from 'atma-io'
let dir = new Directory('src/');

Path is always relative to the cwd (except windows os, when drive letter is used). To specify system absolute path, use file:// protocol.

exists
dir.exists()//> boolean
existsAsync
dir.existsAsync()//> Deferred
readFiles
dir.readFiles(<?string> pattern).files // Array<io.Files>

Get list of all files in the directory. pattern is a glob pattern.

// 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
let files: File[] = await dir.readFilesAsync(globPattern?);
copyTo

Copy files to destination directory. Before copying dir.readFiles can be called to copy only specific files.

dir.copyTo(destination: string)
copyToAsync
dir.copyToAsync(destination: string) //> Deferred
rename
dir.rename(<string> folderName);
renameAsync
dir.renameAsync(<string> folderName) //> Deferred
remove

Removes all content recursively and the folder itself

dir.remove() //> boolean
removeAsync
dir.removeAsync()
ensure
dir.ensure()

Creates directory structure, if not already exists.

ensureAsync
dir.ensureAsync()
watch
dir.watch(callback)

Watch directory for changes

unwatch
dir.unwatch(callback)
short forms

There are some static methods, so that there is no need to initialize the Directory instance.

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