
Security News
AI Agent Lands PRs in Major OSS Projects, Targets Maintainers via Cold Outreach
An AI agent is merging PRs into major OSS projects and cold-emailing maintainers to drum up more work.
Features:
s3://uploads/avatar.pngget, post, put, head and delete methods to handle files.In comparison to NodeJS sync-async contract: all functions with generic name are synchronous, and the
**Asyncare 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. GoAsync.
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 readAsyncRead 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
*.jsonfile 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 readRangeAsyncGet bytes or string for a range from the file
let content = file.readRange(position, length);
let content = await file.readRangeAsync(position, length)
write writeAsyncHooks will be per default executed. For example, when writing to
*.jsonfile 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 appendAsyncfile.append(content: string)
await file.appendAsync(string);
exists existsAsynclet b: boolean = file.exists()
let b: boolean = await file.existsAsync();
copyTo copyToAsyncinterface 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 renameAsyncfile.rename(filename: string)
file.renameAsync(filename: string): Promise<void>
replace replaceAsyncReads 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 removeAsyncfile.remove(): boolean
file.removeAsync(): Promise<boolean>
watchWatch file for changes
file.watch(cb: (path) => void)
file.unwatch(cb?: (path) => void): boolean
Each read will be cached. To control cache behavior use next methods:
File.clearCache(<?string> path);
When path is null, then all cache is dropped.
File.disableCache();
File.disableCache();
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);
})
;
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.
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
}
};
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.
Lately will be converted into plugins, @see Plugins
read
write
There additional read/write middlewares as atma plugins:
atma plugin install NAMEatma-loader-ts - Compiles [Typescript]atma-loader-less - Compiles Lessatma-loader-sass - Compiles SASSatma-io-middleware-yml - Parse YML and returns the Objectatma-io-transport-s3 - Read/Save s3:// files paths from/to S3 storageFor 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" ]
}
}
}
}
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' };
}
});
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.
dir.exists()//> boolean
dir.existsAsync()//> Deferred
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
let files: File[] = await dir.readFilesAsync(globPattern?);
Copy files to destination directory. Before copying dir.readFiles can be called to copy only specific files.
dir.copyTo(destination: string)
dir.copyToAsync(destination: string) //> Deferred
dir.rename(<string> folderName);
dir.renameAsync(<string> folderName) //> Deferred
Removes all content recursively and the folder itself
dir.remove() //> boolean
dir.removeAsync()
dir.ensure()
Creates directory structure, if not already exists.
dir.ensureAsync()
dir.watch(callback)
Watch directory for changes
dir.unwatch(callback)
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
FAQs
File / Directory Classes
We found that atma-io demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
An AI agent is merging PRs into major OSS projects and cold-emailing maintainers to drum up more work.

Research
/Security News
Chrome extension CL Suite by @CLMasters neutralizes 2FA for Facebook and Meta Business accounts while exfiltrating Business Manager contact and analytics data.

Security News
After Matplotlib rejected an AI-written PR, the agent fired back with a blog post, igniting debate over AI contributions and maintainer burden.