├── .gitignore ├── .haxerc ├── .travis.yml ├── .vscode ├── settings.json └── tasks.json ├── README.md ├── haxe_libraries ├── asynctools.hxml ├── asys.hxml ├── buddy.hxml ├── hxnodejs.hxml ├── promhx.hxml ├── tink_chunk.hxml ├── tink_cli.hxml ├── tink_core.hxml ├── tink_io.hxml ├── tink_macro.hxml ├── tink_streams.hxml ├── tink_stringly.hxml └── travix.hxml ├── haxelib.json ├── package.json ├── src └── asys │ ├── FileStat.hx │ ├── FileSystem.hx │ ├── io │ ├── File.hx │ ├── FileInput.hx │ ├── FileOutput.hx │ ├── FileSeek.hx │ └── Process.hx │ ├── net │ ├── Host.hx │ └── Socket.hx │ └── ssl │ └── Socket.hx ├── tests.hxml ├── tests ├── Prepare.hx └── RunTests.hx └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | bin 2 | dump 3 | *.hxproj 4 | *.txt 5 | node_modules -------------------------------------------------------------------------------- /.haxerc: -------------------------------------------------------------------------------- 1 | { 2 | "version": "4.0.5", 3 | "resolveLibs": "scoped" 4 | } -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: required 2 | dist: xenial 3 | 4 | language: node_js 5 | node_js: 12 6 | 7 | install: 8 | - yarn 9 | 10 | script: 11 | - yarn travix neko 12 | - yarn travix node 13 | - yarn travix python 14 | # - yarn travix java 15 | - yarn travix php 16 | - yarn travix cpp 17 | # - yarn travix cs 18 | # - yarn travix lua 19 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "haxe.configurations": [ 3 | ["tests.hxml","-lib","travix","-lib","hxnodejs","-lib","asys","-js","bin/node/tests.js"], 4 | ["tests.hxml","-lib","travix","-lib","asys","-php","bin/php"] 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "2.0.0", 3 | "command": "haxe", 4 | "args": ["tests.hxml"], 5 | "problemMatcher": "$haxe" 6 | } 7 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # asys 2 | 3 | [![Build Status](https://travis-ci.org/benmerckx/asys.svg?branch=master)](https://travis-ci.org/benmerckx/asys) 4 | [![Gitter](https://img.shields.io/gitter/room/nwjs/nw.js.svg?maxAge=2592000)](https://gitter.im/haxetink/public) 5 | 6 | Asynchronous sys module for all sys targets and node.js. 7 | The structure mimics the haxe std sys classes. Each method has an asynchronous 8 | counterpart in asys. Asynchronous methods return a [`Future`](https://haxetink.github.io/tink_core/#/types/future) or a [`Promise`](https://haxetink.github.io/tink_core/#/types/promise). 9 | 10 | For example where you would previously write 11 | ```haxe 12 | trace(FileSystem.exists(path)); 13 | ``` 14 | That would become 15 | ```haxe 16 | FileSystem.exists(path).handle(function(exists) 17 | trace(exists) 18 | ); 19 | ``` 20 | 21 | Using [tink_await](https://github.com/haxetink/tink_await) this can be written as: 22 | ```haxe 23 | trace(@await FileSystem.exists(path)); 24 | ``` 25 | 26 | There other shortcuts for working with futures and promises which you can find in the [tink_core documentation](https://github.com/haxetink/tink_core). 27 | 28 | 29 | #### Currently implemented 30 | 31 | All methods are handled asynchronously on node.js. 32 | On other targets all methods are implemented using `Future.sync`. 33 | If used in combination with [tink_runloop](https://github.com/haxetink/tink_runloop), file io will be done asynchronously. 34 | 35 | ``` 36 | asys 37 | io 38 | File 39 | FileInput 40 | FileOutput 41 | FileSeek 42 | Process 43 | net 44 | Host 45 | Socket 46 | ssl 47 | Socket 48 | FileStat 49 | FileSystem 50 | ``` 51 | 52 | License: MIT 53 | -------------------------------------------------------------------------------- /haxe_libraries/asynctools.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:/asynctools#0.1.0" into asynctools/0.1.0/haxelib 2 | -cp ${HAXE_LIBCACHE}/asynctools/0.1.0/haxelib/ 3 | -D asynctools=0.1.0 4 | -------------------------------------------------------------------------------- /haxe_libraries/asys.hxml: -------------------------------------------------------------------------------- 1 | -cp src 2 | -D asys 3 | 4 | -lib tink_io -------------------------------------------------------------------------------- /haxe_libraries/buddy.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:/buddy#2.10.4" into buddy/2.10.4/haxelib 2 | -lib asynctools 3 | -lib promhx 4 | -cp ${HAXE_LIBCACHE}/buddy/2.10.4/haxelib/ 5 | -D buddy=2.10.4 6 | -------------------------------------------------------------------------------- /haxe_libraries/hxnodejs.hxml: -------------------------------------------------------------------------------- 1 | -D hxnodejs=12.0.0 2 | # @install: lix --silent download "haxelib:/hxnodejs#12.0.0" into hxnodejs/12.0.0/haxelib 3 | -cp ${HAXE_LIBCACHE}/hxnodejs/12.0.0/haxelib/src 4 | --macro allowPackage('sys') 5 | # should behave like other target defines and not be defined in macro context 6 | --macro define('nodejs') 7 | -------------------------------------------------------------------------------- /haxe_libraries/promhx.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:/promhx#1.1.0" into promhx/1.1.0/haxelib 2 | -cp ${HAXE_LIBCACHE}/promhx/1.1.0/haxelib/src/main 3 | -D promhx=1.1.0 4 | -------------------------------------------------------------------------------- /haxe_libraries/tink_chunk.hxml: -------------------------------------------------------------------------------- 1 | -D tink_chunk=0.3.1 2 | # @install: lix --silent download "haxelib:/tink_chunk#0.3.1" into tink_chunk/0.3.1/haxelib 3 | -cp ${HAXE_LIBCACHE}/tink_chunk/0.3.1/haxelib/src 4 | -------------------------------------------------------------------------------- /haxe_libraries/tink_cli.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:/tink_cli#0.5.0" into tink_cli/0.5.0/haxelib 2 | -lib tink_io 3 | -lib tink_macro 4 | -lib tink_stringly 5 | -cp ${HAXE_LIBCACHE}/tink_cli/0.5.0/haxelib/src 6 | -D tink_cli=0.5.0 7 | # Make sure docs are generated 8 | -D use-rtti-doc -------------------------------------------------------------------------------- /haxe_libraries/tink_core.hxml: -------------------------------------------------------------------------------- 1 | -D tink_core=1.25.0 2 | # @install: lix --silent download "haxelib:/tink_core#1.25.0" into tink_core/1.25.0/haxelib 3 | -cp ${HAXE_LIBCACHE}/tink_core/1.25.0/haxelib/src 4 | -------------------------------------------------------------------------------- /haxe_libraries/tink_io.hxml: -------------------------------------------------------------------------------- 1 | -D tink_io=0.7.1 2 | # @install: lix --silent download "haxelib:/tink_io#0.7.1" into tink_io/0.7.1/haxelib 3 | -lib tink_chunk 4 | -lib tink_streams 5 | -cp ${HAXE_LIBCACHE}/tink_io/0.7.1/haxelib/src 6 | -------------------------------------------------------------------------------- /haxe_libraries/tink_macro.hxml: -------------------------------------------------------------------------------- 1 | -D tink_macro=0.19.0 2 | # @install: lix --silent download "haxelib:/tink_macro#0.19.0" into tink_macro/0.19.0/haxelib 3 | -lib tink_core 4 | -cp ${HAXE_LIBCACHE}/tink_macro/0.19.0/haxelib/src 5 | -------------------------------------------------------------------------------- /haxe_libraries/tink_streams.hxml: -------------------------------------------------------------------------------- 1 | -D tink_streams=0.3.2 2 | # @install: lix --silent download "haxelib:/tink_streams#0.3.2" into tink_streams/0.3.2/haxelib 3 | -lib tink_core 4 | -cp ${HAXE_LIBCACHE}/tink_streams/0.3.2/haxelib/src 5 | # temp for development, delete this file when pure branch merged 6 | -D pure -------------------------------------------------------------------------------- /haxe_libraries/tink_stringly.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:/tink_stringly#0.4.0" into tink_stringly/0.4.0/haxelib 2 | -lib tink_core 3 | -cp ${HAXE_LIBCACHE}/tink_stringly/0.4.0/haxelib/src 4 | -D tink_stringly=0.4.0 5 | -------------------------------------------------------------------------------- /haxe_libraries/travix.hxml: -------------------------------------------------------------------------------- 1 | # @install: lix --silent download "haxelib:/travix#0.13.1" into travix/0.13.1/haxelib 2 | # @post-install: cd ${HAXE_LIBCACHE}/travix/0.13.1/haxelib && haxe -cp src --run travix.PostDownload 3 | # @run: haxelib run-dir travix ${HAXE_LIBCACHE}/travix/0.13.1/haxelib 4 | -lib tink_cli 5 | -cp ${HAXE_LIBCACHE}/travix/0.13.1/haxelib/src 6 | -D travix=0.13.1 7 | -------------------------------------------------------------------------------- /haxelib.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "asys", 3 | "url" : "https://github.com/benmerckx/asys", 4 | "license": "MIT", 5 | "tags": ["cross", "utility", "js"], 6 | "description": "Asynchronous sys std module", 7 | "version": "0.4.0", 8 | "releasenote": "", 9 | "contributors": ["benmerckx"], 10 | "classPath": "src", 11 | "dependencies": { 12 | "tink_core": "", 13 | "tink_io": "", 14 | "tink_streams": "" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "scripts": { 3 | "postinstall": "lix download", 4 | "travix": "lix run travix", 5 | "submit": "bestzip submit.zip src/* haxelib.json readme.md && haxelib submit submit.zip && rm submit.zip" 6 | }, 7 | "devDependencies": { 8 | "lix": "^15.8.9" 9 | }, 10 | "dependencies": { 11 | "bestzip": "^2.1.5" 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/asys/FileStat.hx: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C)2005-2016 Haxe Foundation 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | */ 22 | package asys; 23 | 24 | #if !nodejs 25 | 26 | typedef FileStat = sys.FileStat; 27 | 28 | #else 29 | 30 | /** 31 | File informations, as given by [asys.FileSystem.stat] 32 | **/ 33 | typedef FileStat = { 34 | /** the user group id for the file **/ 35 | var gid : Int; 36 | /** the user id for the file **/ 37 | var uid : Int; 38 | /** the last access time for the file (when enabled by the file system) **/ 39 | var atime : Date; 40 | /** the last modification time for the file **/ 41 | var mtime : Date; 42 | /** the creation time for the file (not all filesystems support this) **/ 43 | var ctime : Date; 44 | /** the size of the file **/ 45 | var size : Int; 46 | var dev : Int; 47 | var ino : Int; 48 | var nlink : Int; 49 | var rdev : Int; 50 | var mode : Int; 51 | } 52 | 53 | #end 54 | -------------------------------------------------------------------------------- /src/asys/FileSystem.hx: -------------------------------------------------------------------------------- 1 | package asys; 2 | 3 | #if nodejs 4 | import js.node.Fs; 5 | import js.node.Path; 6 | import js.node.fs.Stats; 7 | import #if haxe4 js.lib.Error #else js.Error #end as JsError; 8 | #end 9 | import asys.FileStat; 10 | 11 | using tink.CoreApi; 12 | 13 | class FileSystem { 14 | 15 | #if nodejs 16 | 17 | public static function exists(path: String): Future { 18 | var trigger = Future.trigger(); 19 | Fs.stat(path, function(err, stats) 20 | trigger.trigger(err == null) 21 | ); 22 | return trigger.asFuture(); 23 | } 24 | 25 | public static function rename(path: String, newPath: String): Promise { 26 | var trigger = Future.trigger(); 27 | Fs.rename(path, newPath, function(err) 28 | trigger.trigger(switch err { 29 | case null: Success(Noise); 30 | default: Failure(Error.withData(err.message, err)); 31 | }) 32 | ); 33 | return trigger.asFuture(); 34 | } 35 | 36 | public static function stat(path: String): Promise { 37 | var trigger = Future.trigger(); 38 | Fs.stat(path, function(err, stat: Stats) 39 | trigger.trigger(switch err { 40 | case null: Success({ 41 | gid: stat.gid, 42 | uid: stat.uid, 43 | atime: (cast stat.atime:Date), // FIXME: https://github.com/HaxeFoundation/haxe/issues/7549 44 | mtime: (cast stat.mtime:Date), // FIXME: https://github.com/HaxeFoundation/haxe/issues/7549 45 | ctime: (cast stat.ctime:Date), // FIXME: https://github.com/HaxeFoundation/haxe/issues/7549 46 | size: Std.int(stat.size), 47 | dev : stat.dev, 48 | ino: Std.int(stat.ino), 49 | nlink: stat.nlink, 50 | rdev: stat.rdev, 51 | mode: stat.mode 52 | }); 53 | default: Failure(Error.withData(err.message, err)); 54 | }) 55 | ); 56 | return trigger.asFuture(); 57 | } 58 | 59 | public static function fullPath(relPath: String): Promise { 60 | var trigger = Future.trigger(); 61 | Fs.realpath(relPath, function(err: JsError, path) 62 | trigger.trigger(switch err { 63 | case null: Success(path); 64 | default: Failure(Error.withData(err.message, err)); 65 | }) 66 | ); 67 | return trigger.asFuture(); 68 | } 69 | 70 | public static function absolutePath(relPath: String): String { 71 | if (haxe.io.Path.isAbsolute(relPath)) return relPath; 72 | return haxe.io.Path.join([Sys.getCwd(), relPath]); 73 | } 74 | 75 | public static function isDirectory(path: String): Future { 76 | var trigger = Future.trigger(); 77 | Fs.stat(path, function(err: JsError, stat: Stats) 78 | trigger.trigger(switch err { 79 | case null: stat.isDirectory(); 80 | default: false; 81 | }) 82 | ); 83 | return trigger.asFuture(); 84 | } 85 | 86 | static function mkdir(path) { 87 | return Future.async(function(_cb) { 88 | Fs.mkdir(path, function(err:JsError) _cb( 89 | if(err == null || untyped err.code == 'EEXIST') 90 | Success(Noise) 91 | else 92 | Failure(Error.ofJsError(err)) 93 | )); 94 | }); 95 | } 96 | 97 | public static function createDirectory(path: String): Promise { 98 | return Future.async(function(cb) { 99 | isDirectory(path).handle(function(isDir) { 100 | if(isDir) 101 | cb(Success(Noise)); 102 | else { 103 | mkdir(path).handle(function(o) switch o { 104 | case Failure(e) if((cast e.data).code == 'ENOENT'): createDirectory(Path.dirname(path)).next(function(_) return mkdir(path)).handle(cb); 105 | case _: cb(o); 106 | }); 107 | } 108 | }); 109 | }).eager(); 110 | } 111 | 112 | public static function deleteFile(path: String): Promise { 113 | var trigger = Future.trigger(); 114 | Fs.unlink(path, function(err: JsError) 115 | trigger.trigger(switch err { 116 | case null: Success(Noise); 117 | default: Failure(Error.withData(err.message, err)); 118 | }) 119 | ); 120 | return trigger.asFuture(); 121 | } 122 | 123 | public static function deleteDirectory(path: String): Promise { 124 | return Future.async(function(cb) { 125 | readDirectory(path) 126 | .next(function(files) { 127 | return Promise.inParallel([for(file in files) { 128 | var cur = '$path/$file'; 129 | isDirectory(cur).next(function(isDir) return isDir ? deleteDirectory(cur) : deleteFile(cur)); 130 | }]); 131 | }) 132 | .next(function(_) return Future.async(function(cb1) { 133 | Fs.rmdir(path, function(err) cb(err == null ? Success(Noise) : Failure(Error.ofJsError(err)))); 134 | })) 135 | .handle(cb); 136 | }).eager(); 137 | } 138 | 139 | public static function readDirectory(path: String): Promise> { 140 | var trigger = Future.trigger(); 141 | Fs.readdir(path, function(err: JsError, files) 142 | trigger.trigger(switch err { 143 | case null: Success(files); 144 | default: Failure(Error.withData(err.message, err)); 145 | }) 146 | ); 147 | return trigger.asFuture(); 148 | } 149 | 150 | #elseif (tink_runloop && concurrent) 151 | 152 | public static function exists(path: String): Future 153 | return Future.async(function(done) 154 | tink.RunLoop.current.work(function () 155 | done(sys.FileSystem.exists(path)) 156 | ) 157 | ); 158 | 159 | public static function rename(path: String, newPath: String): Promise 160 | return Future.async(function(done) 161 | tink.RunLoop.current.work(function () done( 162 | try { 163 | sys.FileSystem.rename(path, newPath); 164 | Success(Noise); 165 | } 166 | catch (e: Dynamic) Failure(new Error('$e')) 167 | )) 168 | ); 169 | 170 | public static function stat(path: String): Promise 171 | return Future.async(function(done) 172 | tink.RunLoop.current.work(function () done( 173 | try Success(sys.FileSystem.stat(path)) 174 | catch (e: Dynamic) Failure(new Error('$e')) 175 | )) 176 | ); 177 | 178 | public static function fullPath(relPath: String): Promise 179 | return Future.async(function(done) 180 | tink.RunLoop.current.work(function () done( 181 | try Success(sys.FileSystem.fullPath(relPath)) 182 | catch (e: Dynamic) Failure(new Error('$e')) 183 | )) 184 | ); 185 | 186 | public static function absolutePath(relPath: String): String 187 | return sys.FileSystem.absolutePath(relPath); 188 | 189 | public static function isDirectory(path: String): Future 190 | return Future.async(function(done) 191 | tink.RunLoop.current.work(function () done( 192 | try sys.FileSystem.isDirectory(path) 193 | catch (e: Dynamic) false 194 | )) 195 | ); 196 | 197 | public static function createDirectory(path: String): Promise 198 | return Future.async(function(done) 199 | tink.RunLoop.current.work(function () done( 200 | try { 201 | sys.FileSystem.createDirectory(path); 202 | Success(Noise); 203 | } 204 | catch (e: Dynamic) Failure(new Error('$e')) 205 | )) 206 | ); 207 | 208 | public static function deleteFile(path: String): Promise 209 | return Future.async(function(done) 210 | tink.RunLoop.current.work(function () done( 211 | try { 212 | sys.FileSystem.deleteFile(path); 213 | Success(Noise); 214 | } 215 | catch (e: Dynamic) Failure(new Error('$e')) 216 | )) 217 | ); 218 | 219 | public static function deleteDirectory(path: String): Promise 220 | return Future.async(function(done) 221 | tink.RunLoop.current.work(function () done( 222 | try { 223 | sys.FileSystem.deleteDirectory(path); 224 | Success(Noise); 225 | } 226 | catch (e: Dynamic) Failure(new Error('$e')) 227 | )) 228 | ); 229 | 230 | public static function readDirectory(path: String): Promise> 231 | return Future.async(function(done) 232 | tink.RunLoop.current.work(function () done( 233 | try Success(sys.FileSystem.readDirectory(path)) 234 | catch (e: Dynamic) Failure(new Error('$e')) 235 | )) 236 | ); 237 | 238 | #else 239 | 240 | public static function exists(path: String): Future 241 | return Future.sync(sys.FileSystem.exists(path)); 242 | 243 | public static function rename(path: String, newPath: String): Promise 244 | return Future.sync( 245 | try { 246 | sys.FileSystem.rename(path, newPath); 247 | Success(Noise); 248 | } 249 | catch(e: Dynamic) Failure(new Error('$e')) 250 | ); 251 | 252 | public static function stat(path: String): Promise 253 | return Future.sync( 254 | try Success(sys.FileSystem.stat(path)) 255 | catch(e: Dynamic) Failure(new Error('$e')) 256 | ); 257 | 258 | public static function fullPath(relPath: String): Promise 259 | return Future.sync( 260 | try Success(sys.FileSystem.fullPath(relPath)) 261 | catch(e: Dynamic) Failure(new Error('$e')) 262 | ); 263 | 264 | public static function absolutePath(relPath: String): String 265 | return sys.FileSystem.absolutePath(relPath); 266 | 267 | public static function isDirectory(path: String): Future 268 | return Future.sync( 269 | try sys.FileSystem.isDirectory(path) 270 | catch(e: Dynamic) false 271 | ); 272 | 273 | public static function createDirectory(path: String): Promise 274 | return Future.sync( 275 | try { 276 | sys.FileSystem.createDirectory(path); 277 | Success(Noise); 278 | } 279 | catch(e: Dynamic) Failure(new Error('$e')) 280 | ); 281 | 282 | public static function deleteFile(path: String): Promise 283 | return Future.sync( 284 | try { 285 | sys.FileSystem.deleteFile(path); 286 | Success(Noise); 287 | } 288 | catch(e: Dynamic) Failure(new Error('$e')) 289 | ); 290 | 291 | public static function deleteDirectory(path: String): Promise 292 | return Future.sync( 293 | try { 294 | sys.FileSystem.deleteDirectory(path); 295 | Success(Noise); 296 | } 297 | catch(e: Dynamic) Failure(new Error('$e')) 298 | ); 299 | 300 | public static function readDirectory(path: String): Promise> 301 | return Future.sync( 302 | try Success(sys.FileSystem.readDirectory(path)) 303 | catch(e: Dynamic) Failure(new Error('$e')) 304 | ); 305 | 306 | #end 307 | 308 | } 309 | -------------------------------------------------------------------------------- /src/asys/io/File.hx: -------------------------------------------------------------------------------- 1 | package asys.io; 2 | 3 | #if nodejs 4 | import js.node.Fs; 5 | import js.node.fs.Stats; 6 | import #if haxe4 js.lib.Error #else js.Error #end as JsError; 7 | #end 8 | import asys.io.FileInput; 9 | import asys.io.FileOutput; 10 | import tink.io.Sink; 11 | 12 | using tink.io.Source; 13 | using tink.CoreApi; 14 | 15 | @:access(sys.io.FileInput) 16 | @:access(sys.io.FileOutput) 17 | class File { 18 | 19 | public static function readStream(path: String, binary = true): RealSource { 20 | #if nodejs 21 | return Source.ofNodeStream('asys read stream', Fs.createReadStream(path)); 22 | #else 23 | return Source.ofInput('asys read stream', sys.io.File.read(path)); 24 | #end 25 | } 26 | 27 | public static function writeStream(path : String, binary: Bool = true): RealSink { 28 | #if nodejs 29 | return Sink.ofNodeStream('asys write stream', Fs.createWriteStream(path)); 30 | #else 31 | return Sink.ofOutput('asys write stream', sys.io.File.write(path)); 32 | #end 33 | } 34 | 35 | #if nodejs 36 | 37 | public static function getContent(path: String): Promise { 38 | var trigger = Future.trigger(); 39 | Fs.readFile(path, 'utf8', function(err: JsError, data: String) 40 | trigger.trigger(switch err { 41 | case null: Success(data); 42 | default: Failure(Error.withData(err.message, err)); 43 | }) 44 | ); 45 | return trigger.asFuture(); 46 | } 47 | 48 | public static function saveContent(path: String, content: String): Promise { 49 | var trigger = Future.trigger(); 50 | Fs.writeFile(path, untyped content, 'utf8', function(err: JsError) 51 | trigger.trigger(switch err { 52 | case null: Success(Noise); 53 | default: Failure(Error.withData(err.message, err)); 54 | }) 55 | ); 56 | return trigger.asFuture(); 57 | } 58 | 59 | public static function getBytes(path: String): Promise { 60 | var trigger = Future.trigger(); 61 | Fs.readFile(path, function(err: JsError, buffer: js.node.Buffer) 62 | trigger.trigger(switch err { 63 | case null: Success(buffer.hxToBytes()); 64 | default: Failure(Error.withData(err.message, err)); 65 | }) 66 | ); 67 | return trigger.asFuture(); 68 | } 69 | 70 | public static function saveBytes(path: String, bytes: haxe.io.Bytes): Promise { 71 | var trigger = Future.trigger(); 72 | Fs.writeFile(path, js.node.Buffer.hxFromBytes(bytes), function(err: JsError) 73 | trigger.trigger(switch err { 74 | case null: Success(Noise); 75 | default: Failure(Error.withData(err.message, err)); 76 | }) 77 | ); 78 | return trigger.asFuture(); 79 | } 80 | 81 | public static function read(path: String, binary = true): Promise { 82 | var trigger = Future.trigger(); 83 | Fs.open(path, 'r', function(err: JsError, fd: Int) 84 | trigger.trigger(switch err { 85 | case null: Success(new FileInput(fd)); 86 | default: Failure(Error.withData(err.message, err)); 87 | }) 88 | ); 89 | return trigger.asFuture(); 90 | } 91 | 92 | public static function write(path : String, binary: Bool = true): Promise { 93 | var trigger = Future.trigger(); 94 | Fs.open(path, 'w', function(err: JsError, fd: Int) 95 | trigger.trigger(switch err { 96 | case null: Success(new FileOutput(fd)); 97 | default: Failure(Error.withData(err.message, err)); 98 | }) 99 | ); 100 | return trigger.asFuture(); 101 | } 102 | 103 | public static function append(path : String, binary : Bool = true): Promise { 104 | var trigger = Future.trigger(); 105 | Fs.open(path, 'a', function(err: JsError, fd: Int) 106 | trigger.trigger(switch err { 107 | case null: Success(new FileOutput(fd)); 108 | default: Failure(Error.withData(err.message, err)); 109 | }) 110 | ); 111 | return trigger.asFuture(); 112 | } 113 | 114 | public static function copy(srcPath: String, dstPath: String): Promise { 115 | var trigger = Future.trigger(); 116 | var called = false; 117 | function done(?err: JsError) { 118 | if (called) return; 119 | trigger.trigger(switch err { 120 | case null: Success(Noise); 121 | default: Failure(Error.withData(err.message, err)); 122 | }); 123 | called = true; 124 | } 125 | var rd = Fs.createReadStream(srcPath); 126 | rd.on('error', done); 127 | var wr = Fs.createWriteStream(dstPath); 128 | wr.on('error', done); 129 | wr.on('close', function(ex) { 130 | done(); 131 | }); 132 | rd.pipe(wr); 133 | 134 | return trigger.asFuture(); 135 | } 136 | 137 | #elseif (tink_runloop && concurrent) 138 | 139 | public static function getContent(path: String): Promise 140 | return Future.async(function(done) 141 | tink.RunLoop.current.work(function () done( 142 | try Success(sys.io.File.getContent(path)) 143 | catch (e: Dynamic) Failure(new Error('$e')) 144 | )) 145 | ); 146 | 147 | public static function saveContent(path: String, content: String): Promise 148 | return Future.async(function(done) 149 | tink.RunLoop.current.work(function () done( 150 | try { 151 | sys.io.File.saveContent(path, content); 152 | Success(Noise); 153 | } 154 | catch (e: Dynamic) Failure(new Error('$e')) 155 | )) 156 | ); 157 | 158 | public static function getBytes(path: String): Promise 159 | return Future.async(function(done) 160 | tink.RunLoop.current.work(function () done( 161 | try Success(sys.io.File.getBytes(path)) 162 | catch(e: Dynamic) Failure(new Error('$e')) 163 | )) 164 | ); 165 | 166 | public static function saveBytes(path: String, bytes: haxe.io.Bytes): Promise 167 | return Future.async(function(done) 168 | tink.RunLoop.current.work(function () done( 169 | try { 170 | sys.io.File.saveBytes(path, bytes); 171 | Success(Noise); 172 | } 173 | catch (e: Dynamic) Failure(new Error('$e')) 174 | )) 175 | ); 176 | 177 | public static function read(path: String, binary = true): Promise 178 | return Future.async(function(done) 179 | tink.RunLoop.current.work(function () done( 180 | try Success(sys.io.File.read(path, binary)) 181 | catch (e: Dynamic) Failure(new Error('$e')) 182 | )) 183 | ); 184 | 185 | public static function write(path : String, binary: Bool = true): Promise 186 | return Future.async(function(done) 187 | tink.RunLoop.current.work(function () done( 188 | try Success(sys.io.File.write(path, binary)) 189 | catch (e: Dynamic) Failure(new Error('$e')) 190 | )) 191 | ); 192 | 193 | public static function append(path : String, binary : Bool = true): Promise 194 | return Future.async(function(done) 195 | tink.RunLoop.current.work(function () done( 196 | try Success(sys.io.File.append(path, binary)) 197 | catch (e: Dynamic) Failure(new Error('$e')) 198 | )) 199 | ); 200 | 201 | public static function copy(srcPath: String, dstPath: String): Promise 202 | return Future.async(function(done) 203 | tink.RunLoop.current.work(function () done( 204 | try { 205 | sys.io.File.copy(srcPath, dstPath); 206 | Success(Noise); 207 | } 208 | catch (e: Dynamic) Failure(new Error('$e')) 209 | )) 210 | ); 211 | 212 | #else 213 | 214 | public static function getContent(path: String): Promise 215 | return Future.sync( 216 | try Success(sys.io.File.getContent(path)) 217 | catch(e: Dynamic) Failure(new Error('$e')) 218 | ); 219 | 220 | public static function saveContent(path: String, content: String): Promise 221 | return Future.sync( 222 | try { 223 | sys.io.File.saveContent(path, content); 224 | Success(Noise); 225 | } 226 | catch(e: Dynamic) Failure(new Error('$e')) 227 | ); 228 | 229 | public static function getBytes(path: String): Promise 230 | return Future.sync( 231 | try Success(sys.io.File.getBytes(path)) 232 | catch(e: Dynamic) Failure(new Error('$e')) 233 | ); 234 | 235 | public static function saveBytes(path: String, bytes: haxe.io.Bytes): Promise 236 | return Future.sync( 237 | try { 238 | sys.io.File.saveBytes(path, bytes); 239 | Success(Noise); 240 | } 241 | catch(e: Dynamic) Failure(new Error('$e')) 242 | ); 243 | 244 | public static function read(path: String, binary = true): Promise 245 | return Future.sync( 246 | try Success(sys.io.File.read(path, binary)) 247 | catch(e: Dynamic) Failure(new Error('$e')) 248 | ); 249 | 250 | public static function write(path : String, binary: Bool = true): Promise 251 | return Future.sync( 252 | try Success(sys.io.File.write(path, binary)) 253 | catch(e: Dynamic) Failure(new Error('$e')) 254 | ); 255 | 256 | public static function append(path : String, binary : Bool = true): Promise 257 | return Future.sync( 258 | try Success(sys.io.File.append(path, binary)) 259 | catch(e: Dynamic) Failure(new Error('$e')) 260 | ); 261 | 262 | public static function copy(srcPath: String, dstPath: String): Promise 263 | return Future.sync( 264 | try { 265 | sys.io.File.copy(srcPath, dstPath); 266 | Success(Noise); 267 | } 268 | catch(e: Dynamic) Failure(new Error('$e')) 269 | ); 270 | 271 | #end 272 | } -------------------------------------------------------------------------------- /src/asys/io/FileInput.hx: -------------------------------------------------------------------------------- 1 | package asys.io; 2 | 3 | typedef FileInput = sys.io.FileInput; -------------------------------------------------------------------------------- /src/asys/io/FileOutput.hx: -------------------------------------------------------------------------------- 1 | package asys.io; 2 | 3 | typedef FileOutput = sys.io.FileOutput; -------------------------------------------------------------------------------- /src/asys/io/FileSeek.hx: -------------------------------------------------------------------------------- 1 | package asys.io; 2 | 3 | typedef FileSeek = sys.io.FileSeek; -------------------------------------------------------------------------------- /src/asys/io/Process.hx: -------------------------------------------------------------------------------- 1 | package asys.io; 2 | 3 | #if nodejs 4 | import js.Node; 5 | import js.node.ChildProcess; 6 | #end 7 | import tink.io.Sink; 8 | 9 | using tink.io.Source; 10 | using tink.CoreApi; 11 | 12 | class Process { 13 | 14 | public var stdout(default,null): RealSource; 15 | public var stderr(default,null): RealSource; 16 | public var stdin(default,null): RealSink; 17 | var process: #if nodejs js.node.child_process.ChildProcess #else sys.io.Process #end; 18 | var exitTrigger = Future.trigger(); 19 | 20 | public function new(cmd: String, ?args: Array ) { 21 | #if nodejs 22 | process = ChildProcess.spawn(cmd, args); 23 | stdin = RealSink.ofNodeStream('stdin', process.stdin); 24 | stderr = RealSource.ofNodeStream('stderr', process.stderr); 25 | stdout = RealSource.ofNodeStream('stdout', process.stdout); 26 | process.on('exit', function(code, signal) { 27 | exitTrigger.trigger(code); 28 | }); 29 | #else 30 | process = new sys.io.Process(cmd, args); 31 | stdin = RealSink.ofOutput('stdin', process.stdin); 32 | stderr = RealSource.ofInput('stderr', process.stderr); 33 | stdout = RealSource.ofInput('stdout', process.stdout); 34 | exitTrigger.trigger(process.exitCode()); 35 | #end 36 | } 37 | 38 | public function getPid() 39 | return #if nodejs process.pid #else process.getPid() #end; 40 | 41 | public function exitCode(): Future { 42 | return exitTrigger.asFuture(); 43 | } 44 | 45 | public function close() { 46 | #if !nodejs 47 | process.close(); 48 | #end 49 | } 50 | 51 | public function kill() 52 | process.kill(); 53 | 54 | } 55 | -------------------------------------------------------------------------------- /src/asys/net/Host.hx: -------------------------------------------------------------------------------- 1 | package asys.net; 2 | 3 | using tink.CoreApi; 4 | 5 | class Host { 6 | 7 | public var host(default,null): String; 8 | public var ip(default,null): Future; 9 | var address: String; 10 | var ipTrigger = Future.trigger(); 11 | #if !nodejs 12 | @:allow(asys.net.Socket) 13 | var instance: sys.net.Host; 14 | #end 15 | 16 | public function new( name : String ) : Void { 17 | host = name; 18 | #if nodejs 19 | if(~/^(\d{1,3}\.){3}\d{1,3}$/.match(name)) { 20 | address = name; 21 | processIp(null, address); 22 | } else { 23 | js.node.Dns.lookup(name, 4, processIp); 24 | } 25 | ip = ipTrigger.asFuture(); 26 | #else 27 | instance = new sys.net.Host(name); 28 | address = Std.string(instance); 29 | ipTrigger.trigger(instance.ip); 30 | #end 31 | } 32 | 33 | function processIp(err, address, ?_) { 34 | if(host == address || err != null) { 35 | ipTrigger.trigger(0); 36 | return; 37 | } 38 | 39 | this.address = address; 40 | var parts = address.split("."); 41 | var res = 0; 42 | 43 | res += Std.parseInt(parts[0]) << 24; 44 | res += Std.parseInt(parts[1]) << 16; 45 | res += Std.parseInt(parts[2]) << 8; 46 | res += Std.parseInt(parts[3]); 47 | 48 | ipTrigger.trigger(res); 49 | } 50 | 51 | public function toString(): String { 52 | return address; 53 | } 54 | 55 | public function reverse(): Promise { 56 | #if !nodejs 57 | return Future.sync(Error.catchExceptions(instance.reverse)); 58 | #else 59 | var trigger = Future.trigger(); 60 | js.node.Dns.reverse(address, function(err: js.lib.Error, res) 61 | trigger.trigger(switch err { 62 | case null: Success(res.pop()); 63 | default: Failure(Error.withData(err.message, err)); 64 | }) 65 | ); 66 | return trigger.asFuture(); 67 | #end 68 | } 69 | 70 | public static function localhost() : String { 71 | #if nodejs 72 | return js.node.Os.hostname(); 73 | #elseif php 74 | return #if (haxe_ver >= 4) php.Syntax.code #else untyped __php__ #end ("isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'"); 75 | #else 76 | return sys.net.Host.localhost(); 77 | #end 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/asys/net/Socket.hx: -------------------------------------------------------------------------------- 1 | package asys.net; 2 | 3 | import asys.net.Host; 4 | import tink.io.Sink; 5 | import tink.io.Source; 6 | 7 | using tink.CoreApi; 8 | 9 | typedef NativeSocket = 10 | #if nodejs js.node.net.Socket 11 | #elseif php php.net.Socket 12 | #else sys.net.Socket 13 | #end; 14 | 15 | class Socket { 16 | public var input(default,null): RealSource; 17 | public var output(default,null): RealSink; 18 | var socket: NativeSocket; 19 | var host: Host; 20 | var port: Int; 21 | 22 | public function new() { 23 | createSocket(); 24 | } 25 | 26 | function createSocket() { 27 | socket = new NativeSocket(); 28 | } 29 | 30 | function setStreams() { 31 | #if !nodejs 32 | output = Sink.ofOutput('socket output', socket.output); 33 | input = Source.ofInput('socket input', socket.input); 34 | #else 35 | input = Source.ofNodeStream('socket input', socket); 36 | output = Sink.ofNodeStream('socket output', socket); 37 | #end 38 | } 39 | 40 | public function connect(host: Host, port: Int): Promise { 41 | this.host = host; 42 | this.port = port; 43 | #if !nodejs 44 | return Future.sync( 45 | try { 46 | socket.connect(host.instance, port); 47 | setStreams(); 48 | Success(Noise); 49 | } catch (e: Dynamic) { 50 | Failure(new Error(Std.string(e))); 51 | } 52 | ); 53 | #else 54 | var trigger = Future.trigger(); 55 | setStreams(); 56 | socket.on('error', function(err: js.lib.Error) 57 | trigger.trigger(Failure(Error.withData(err.message, err))) 58 | ); 59 | socket.on('connect', function() 60 | trigger.trigger(Success(Noise)) 61 | ); 62 | socket.connect({host: host.host, port: port}); 63 | return trigger.asFuture(); 64 | #end 65 | } 66 | 67 | public function close() { 68 | #if nodejs 69 | socket.destroy(); 70 | #else 71 | socket.close(); 72 | #end 73 | } 74 | 75 | public function setTimeout(timeout: Float) { 76 | #if nodejs 77 | socket.setTimeout(Std.int(timeout*1000), function() { 78 | socket.emit('error', 'Socket timeout'); 79 | close(); 80 | }); 81 | #else 82 | socket.setTimeout(timeout); 83 | #end 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/asys/ssl/Socket.hx: -------------------------------------------------------------------------------- 1 | package asys.ssl; 2 | 3 | import asys.net.Host; 4 | import asys.net.Socket as PlainSocket; 5 | import tink.io.Sink; 6 | import tink.io.Source; 7 | 8 | using tink.CoreApi; 9 | 10 | 11 | @:access(asys.net.Socket) 12 | class Socket extends PlainSocket { 13 | 14 | override function createSocket() { 15 | socket = cast 16 | #if nodejs 17 | null 18 | #elseif php 19 | new php.net.SslSocket() 20 | #elseif java 21 | new java.net.SslSocket() 22 | #elseif (haxe_ver > 3.210) 23 | #if (cpp || neko) 24 | new sys.ssl.Socket() 25 | #else 26 | null; throw 'Not supported on this platform' 27 | #end 28 | #else 29 | null; throw 'Not supported on this platform' 30 | #end 31 | ; 32 | } 33 | 34 | @:access(sys.ssl.Socket) 35 | @:access(sys.net.Socket) 36 | public static function upgrade(socket: PlainSocket): Socket { 37 | #if nodejs 38 | socket.socket = js.node.Tls.connect({socket: socket.socket}); 39 | socket.setStreams(); 40 | return cast socket; 41 | #elseif php 42 | var resource = socket.socket.__s; 43 | php.Global.stream_set_blocking(resource, true); 44 | php.Syntax.code('stream_socket_enable_crypto({0}, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)', resource); 45 | socket.setStreams(); 46 | return cast socket; 47 | #elseif java 48 | socket.input = null; 49 | socket.output = null; 50 | var s = new Socket(); 51 | s.socket = socket.socket; 52 | socket.socket.sock = 53 | (untyped java.javax.net.ssl.SSLSocketFactory.getDefault()).createSocket( 54 | socket.socket.sock, 55 | socket.socket.sock.getInetAddress().getHostAddress(), 56 | socket.socket.sock.getPort(), 57 | true 58 | ); 59 | (untyped socket.socket.sock).startHandshake(); 60 | s.input = new tink.io.java.JavaSource(java.nio.channels.Channels.newChannel(socket.socket.sock.getInputStream()), 'socket input'); 61 | s.output = new tink.io.java.JavaSink(java.nio.channels.Channels.newChannel(socket.socket.sock.getOutputStream()), 'socket out'); 62 | return s; 63 | #elseif (haxe_ver > 3.210) 64 | #if neko 65 | var s = new Socket(); 66 | s.socket.__s = socket.socket.__s; 67 | var sslSocket = (cast s.socket: sys.ssl.Socket); 68 | sslSocket.ctx = sslSocket.buildSSLContext(false); 69 | var ssl = sslSocket.ssl = sys.ssl.Socket.ssl_new(sslSocket.ctx); 70 | sys.ssl.Socket.ssl_set_socket(ssl, s.socket.__s); 71 | if (socket.host.host != null) 72 | sys.ssl.Socket.ssl_set_hostname(ssl, untyped socket.host.host.__s); 73 | sslSocket.handshake(); 74 | s.setStreams(); 75 | return cast s; 76 | #elseif cpp 77 | var s = new Socket(); 78 | s.socket.__s = socket.socket.__s; 79 | var sslSocket = (cast s.socket: sys.ssl.Socket); 80 | sslSocket.conf = sslSocket.buildSSLConfig(false); 81 | var ssl = sslSocket.ssl = cpp.NativeSsl.ssl_new(sslSocket.conf); 82 | cpp.NativeSsl.ssl_set_socket(ssl, s.socket.__s); 83 | if (socket.host.host != null) 84 | cpp.NativeSsl.ssl_set_hostname(ssl, socket.host.host); 85 | sslSocket.handshake(); 86 | s.setStreams(); 87 | return cast s; 88 | #else 89 | throw 'Not supported on this platform'; 90 | #end 91 | #else 92 | throw 'Not supported on this platform'; 93 | #end 94 | } 95 | 96 | #if nodejs 97 | override public function connect(host: Host, port: Int): Promise { 98 | var trigger = Future.trigger(); 99 | socket = js.node.Tls.connect(port, host.host); 100 | setStreams(); 101 | socket.on('error', function(err: js.lib.Error) 102 | trigger.trigger(Failure(Error.withData(err.message, err))) 103 | ); 104 | socket.on('connect', function() 105 | trigger.trigger(Success(Noise)) 106 | ); 107 | return trigger.asFuture(); 108 | } 109 | #end 110 | } 111 | -------------------------------------------------------------------------------- /tests.hxml: -------------------------------------------------------------------------------- 1 | --macro Prepare.init() 2 | -lib buddy 3 | -cp tests 4 | -main RunTests 5 | 6 | # -D no-deprecation-warnings -------------------------------------------------------------------------------- /tests/Prepare.hx: -------------------------------------------------------------------------------- 1 | import sys.io.File; 2 | 3 | class Prepare { 4 | 5 | public static function init() { 6 | File.saveContent('test.txt', 'ok'); 7 | } 8 | 9 | } -------------------------------------------------------------------------------- /tests/RunTests.hx: -------------------------------------------------------------------------------- 1 | #if tink_runloop #error #end 2 | 3 | import buddy.SingleSuite; 4 | import haxe.io.Bytes; 5 | 6 | import asys.FileSystem; 7 | import asys.io.File; 8 | import asys.net.Socket; 9 | import asys.net.Host; 10 | 11 | using tink.io.Source; 12 | using buddy.Should; 13 | using tink.CoreApi; 14 | 15 | @colorize 16 | class RunTests extends SingleSuite { 17 | 18 | public function new() { 19 | describe('asys', { 20 | 21 | #if !python 22 | describe('socket', { 23 | it('upgrades', done -> { 24 | var socket = new Socket(); 25 | socket.connect(new Host('ssl0.ovh.net'), 465).handle( 26 | res -> switch res { 27 | case Success(_): 28 | asys.ssl.Socket.upgrade(socket); 29 | done(); 30 | case Failure(e): 31 | throw e; 32 | done(); 33 | } 34 | ); 35 | }); 36 | }); 37 | #end 38 | 39 | describe('FileSystem', { 40 | it('exists', function(done) { 41 | FileSystem.exists('haxelib.json').handle(function(response) { 42 | response.should.be(true); 43 | FileSystem.exists('none').handle(function(response) { 44 | response.should.be(false); 45 | done(); 46 | }); 47 | }); 48 | }); 49 | 50 | it('rename', function(done) { 51 | FileSystem.rename('test.txt', 'test2.txt').handle(function(response) { 52 | response.should.equal(Success(Noise)); 53 | done(); 54 | }); 55 | }); 56 | 57 | it('stat', function(done) { 58 | FileSystem.stat('test2.txt').handle(function(response) switch response { 59 | case Success(res): 60 | res.size.should.be(2); 61 | done(); 62 | default: fail(); 63 | }); 64 | }); 65 | 66 | it('fullPath', function(done) { 67 | FileSystem.fullPath('haxelib.json').handle(function(response) switch response { 68 | case Success(res): 69 | (res.length > 'haxelib.json'.length).should.be(true); 70 | done(); 71 | default: fail(); 72 | }); 73 | }); 74 | 75 | it('isDirectory', function(done) { 76 | FileSystem.isDirectory('tests').handle(function(response) { 77 | response.should.be(true); 78 | FileSystem.isDirectory('none').handle(function(response) { 79 | response.should.be(false); 80 | done(); 81 | }); 82 | }); 83 | }); 84 | 85 | it('createDirectory', function(done) { 86 | FileSystem.createDirectory('tests-dir').handle(function(response) { 87 | response.should.equal(Success(Noise)); 88 | done(); 89 | }); 90 | }); 91 | 92 | it('createDirectory recursive', function(done) { 93 | FileSystem.createDirectory('tests-dir2/sub-dir').handle(function(response) { 94 | response.should.equal(Success(Noise)); 95 | done(); 96 | }); 97 | }); 98 | 99 | it('deleteFile', function(done) { 100 | FileSystem.deleteFile('test2.txt').handle(function(response) { 101 | response.should.equal(Success(Noise)); 102 | FileSystem.deleteFile('none').handle(function(response) switch response { 103 | case Failure(_): done(); 104 | default: fail(); 105 | }); 106 | }); 107 | }); 108 | 109 | it('deleteDirectory', function(done) { 110 | FileSystem.deleteDirectory('tests-dir').handle(function(response) { 111 | response.should.equal(Success(Noise)); 112 | FileSystem.deleteDirectory('tests-dir').handle(function(response) switch response { 113 | case Failure(_): done(); 114 | default: fail(); 115 | }); 116 | }); 117 | }); 118 | 119 | #if nodejs // FIXME: see https://github.com/HaxeFoundation/haxe/issues/5585 120 | it('deleteDirectory recursive', function(done) { 121 | File.saveContent('tests-dir2/sub-dir/foo.txt', 'foo') 122 | .next(function(_) return FileSystem.deleteDirectory('tests-dir2')) 123 | .handle(function(response) { 124 | response.should.equal(Success(Noise)); 125 | done(); 126 | }); 127 | }); 128 | #end 129 | 130 | it('readDirectory', function(done) { 131 | FileSystem.readDirectory('tests').handle(function(response) switch response { 132 | case Success(list): 133 | done(); 134 | default: fail(); 135 | }); 136 | }); 137 | }); 138 | 139 | describe('File', { 140 | it('saveContent', function(done) { 141 | File.saveContent('test.txt', 'done').handle(function(response) { 142 | response.should.equal(Success(Noise)); 143 | done(); 144 | }); 145 | }); 146 | 147 | it('getContent', function(done) { 148 | File.getContent('test.txt').handle(function(response) switch response { 149 | case Success(res): 150 | res.should.be('done'); 151 | done(); 152 | default: fail(); 153 | }); 154 | }); 155 | 156 | it('saveBytes', function(done) { 157 | File.saveBytes('test.txt', Bytes.ofString('bytes')).handle(function(response) { 158 | response.should.equal(Success(Noise)); 159 | done(); 160 | }); 161 | }); 162 | 163 | it('getBytes', function(done) { 164 | File.getBytes('test.txt').handle(function(response) switch response { 165 | case Success(res): 166 | res.toString().should.be('bytes'); 167 | done(); 168 | default: fail(); 169 | }); 170 | }); 171 | 172 | it('write', function(done) { 173 | File.write('test.txt').handle(function(response) switch response { 174 | case Success(res): 175 | res.writeBytes(Bytes.ofString('as'), 0, 2); 176 | done(); 177 | default: fail(); 178 | }); 179 | }); 180 | 181 | it('append', function(done) { 182 | File.append('test.txt').handle(function(response) switch response { 183 | case Success(res): 184 | res.writeBytes(Bytes.ofString('ys'), 0, 2); 185 | done(); 186 | default: fail(); 187 | }); 188 | }); 189 | 190 | it('copy', function(done) { 191 | File.copy('test.txt', 'test2.txt').handle(function(response) { 192 | response.should.equal(Success(Noise)); 193 | done(); 194 | }); 195 | }); 196 | 197 | #if nodejs 198 | it('read', function(done) { 199 | File.readStream('test.txt').all().handle(function(o) switch o { 200 | case Success(chunk): 201 | chunk.length.should.beGreaterThan(0); 202 | done(); 203 | case Failure(e): fail(); 204 | }); 205 | }); 206 | #end 207 | 208 | afterAll({ 209 | FileSystem.deleteFile('test2.txt').handle(function(_) null); 210 | FileSystem.deleteFile('test.txt').handle(function(_) null); 211 | }); 212 | }); 213 | }); 214 | } 215 | 216 | } -------------------------------------------------------------------------------- /yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | ansi-regex@^4.1.0: 6 | version "4.1.0" 7 | resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" 8 | integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== 9 | 10 | ansi-styles@^3.2.0: 11 | version "3.2.1" 12 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" 13 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== 14 | dependencies: 15 | color-convert "^1.9.0" 16 | 17 | archiver-utils@^2.1.0: 18 | version "2.1.0" 19 | resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" 20 | integrity sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw== 21 | dependencies: 22 | glob "^7.1.4" 23 | graceful-fs "^4.2.0" 24 | lazystream "^1.0.0" 25 | lodash.defaults "^4.2.0" 26 | lodash.difference "^4.5.0" 27 | lodash.flatten "^4.4.0" 28 | lodash.isplainobject "^4.0.6" 29 | lodash.union "^4.6.0" 30 | normalize-path "^3.0.0" 31 | readable-stream "^2.0.0" 32 | 33 | archiver@^3.0.0: 34 | version "3.1.1" 35 | resolved "https://registry.yarnpkg.com/archiver/-/archiver-3.1.1.tgz#9db7819d4daf60aec10fe86b16cb9258ced66ea0" 36 | integrity sha512-5Hxxcig7gw5Jod/8Gq0OneVgLYET+oNHcxgWItq4TbhOzRLKNAFUb9edAftiMKXvXfCB0vbGrJdZDNq0dWMsxg== 37 | dependencies: 38 | archiver-utils "^2.1.0" 39 | async "^2.6.3" 40 | buffer-crc32 "^0.2.1" 41 | glob "^7.1.4" 42 | readable-stream "^3.4.0" 43 | tar-stream "^2.1.0" 44 | zip-stream "^2.1.2" 45 | 46 | async@^2.6.1, async@^2.6.3: 47 | version "2.6.3" 48 | resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" 49 | integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== 50 | dependencies: 51 | lodash "^4.17.14" 52 | 53 | balanced-match@^1.0.0: 54 | version "1.0.0" 55 | resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" 56 | integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c= 57 | 58 | base64-js@^1.0.2: 59 | version "1.3.1" 60 | resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" 61 | integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== 62 | 63 | bestzip@^2.1.5: 64 | version "2.1.5" 65 | resolved "https://registry.yarnpkg.com/bestzip/-/bestzip-2.1.5.tgz#815980248bbbd907fa724d5c5e5cb9fd295619d3" 66 | integrity sha512-ieNnkUNC4iF3eC8L+00Gd/niBqyjqZ28UnKYOSozWDBluqht3NMlQXLJVi47mehwgSsvGq+GqvEmVWZHQy2nrQ== 67 | dependencies: 68 | archiver "^3.0.0" 69 | async "^2.6.1" 70 | glob "^7.1.3" 71 | which "^1.3.1" 72 | yargs "^13.2.4" 73 | 74 | bl@^4.0.1: 75 | version "4.0.2" 76 | resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.2.tgz#52b71e9088515d0606d9dd9cc7aa48dc1f98e73a" 77 | integrity sha512-j4OH8f6Qg2bGuWfRiltT2HYGx0e1QcBTrK9KAHNMwMZdQnDZFk0ZSYIpADjYCB3U12nicC5tVJwSIhwOWjb4RQ== 78 | dependencies: 79 | buffer "^5.5.0" 80 | inherits "^2.0.4" 81 | readable-stream "^3.4.0" 82 | 83 | brace-expansion@^1.1.7: 84 | version "1.1.11" 85 | resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" 86 | integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== 87 | dependencies: 88 | balanced-match "^1.0.0" 89 | concat-map "0.0.1" 90 | 91 | buffer-crc32@^0.2.1, buffer-crc32@^0.2.13: 92 | version "0.2.13" 93 | resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" 94 | integrity sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI= 95 | 96 | buffer@^5.1.0, buffer@^5.5.0: 97 | version "5.5.0" 98 | resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.5.0.tgz#9c3caa3d623c33dd1c7ef584b89b88bf9c9bc1ce" 99 | integrity sha512-9FTEDjLjwoAkEwyMGDjYJQN2gfRgOKBKRfiglhvibGbpeeU/pQn1bJxQqm32OD/AIeEuHxU9roxXxg34Byp/Ww== 100 | dependencies: 101 | base64-js "^1.0.2" 102 | ieee754 "^1.1.4" 103 | 104 | camelcase@^5.0.0: 105 | version "5.3.1" 106 | resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 107 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 108 | 109 | cliui@^5.0.0: 110 | version "5.0.0" 111 | resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" 112 | integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== 113 | dependencies: 114 | string-width "^3.1.0" 115 | strip-ansi "^5.2.0" 116 | wrap-ansi "^5.1.0" 117 | 118 | color-convert@^1.9.0: 119 | version "1.9.3" 120 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" 121 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== 122 | dependencies: 123 | color-name "1.1.3" 124 | 125 | color-name@1.1.3: 126 | version "1.1.3" 127 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" 128 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= 129 | 130 | compress-commons@^2.1.1: 131 | version "2.1.1" 132 | resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-2.1.1.tgz#9410d9a534cf8435e3fbbb7c6ce48de2dc2f0610" 133 | integrity sha512-eVw6n7CnEMFzc3duyFVrQEuY1BlHR3rYsSztyG32ibGMW722i3C6IizEGMFmfMU+A+fALvBIwxN3czffTcdA+Q== 134 | dependencies: 135 | buffer-crc32 "^0.2.13" 136 | crc32-stream "^3.0.1" 137 | normalize-path "^3.0.0" 138 | readable-stream "^2.3.6" 139 | 140 | concat-map@0.0.1: 141 | version "0.0.1" 142 | resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" 143 | integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= 144 | 145 | core-util-is@~1.0.0: 146 | version "1.0.2" 147 | resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" 148 | integrity sha1-tf1UIgqivFq1eqtxQMlAdUUDwac= 149 | 150 | crc32-stream@^3.0.1: 151 | version "3.0.1" 152 | resolved "https://registry.yarnpkg.com/crc32-stream/-/crc32-stream-3.0.1.tgz#cae6eeed003b0e44d739d279de5ae63b171b4e85" 153 | integrity sha512-mctvpXlbzsvK+6z8kJwSJ5crm7yBwrQMTybJzMw1O4lLGJqjlDCXY2Zw7KheiA6XBEcBmfLx1D88mjRGVJtY9w== 154 | dependencies: 155 | crc "^3.4.4" 156 | readable-stream "^3.4.0" 157 | 158 | crc@^3.4.4: 159 | version "3.8.0" 160 | resolved "https://registry.yarnpkg.com/crc/-/crc-3.8.0.tgz#ad60269c2c856f8c299e2c4cc0de4556914056c6" 161 | integrity sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ== 162 | dependencies: 163 | buffer "^5.1.0" 164 | 165 | decamelize@^1.2.0: 166 | version "1.2.0" 167 | resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" 168 | integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= 169 | 170 | emoji-regex@^7.0.1: 171 | version "7.0.3" 172 | resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" 173 | integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== 174 | 175 | end-of-stream@^1.4.1: 176 | version "1.4.4" 177 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" 178 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== 179 | dependencies: 180 | once "^1.4.0" 181 | 182 | find-up@^3.0.0: 183 | version "3.0.0" 184 | resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" 185 | integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== 186 | dependencies: 187 | locate-path "^3.0.0" 188 | 189 | fs-constants@^1.0.0: 190 | version "1.0.0" 191 | resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" 192 | integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== 193 | 194 | fs.realpath@^1.0.0: 195 | version "1.0.0" 196 | resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" 197 | integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= 198 | 199 | get-caller-file@^2.0.1: 200 | version "2.0.5" 201 | resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" 202 | integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== 203 | 204 | glob@^7.1.3, glob@^7.1.4: 205 | version "7.1.6" 206 | resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" 207 | integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== 208 | dependencies: 209 | fs.realpath "^1.0.0" 210 | inflight "^1.0.4" 211 | inherits "2" 212 | minimatch "^3.0.4" 213 | once "^1.3.0" 214 | path-is-absolute "^1.0.0" 215 | 216 | graceful-fs@^4.2.0: 217 | version "4.2.3" 218 | resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423" 219 | integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ== 220 | 221 | ieee754@^1.1.4: 222 | version "1.1.13" 223 | resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84" 224 | integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg== 225 | 226 | inflight@^1.0.4: 227 | version "1.0.6" 228 | resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" 229 | integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk= 230 | dependencies: 231 | once "^1.3.0" 232 | wrappy "1" 233 | 234 | inherits@2, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: 235 | version "2.0.4" 236 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" 237 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== 238 | 239 | is-fullwidth-code-point@^2.0.0: 240 | version "2.0.0" 241 | resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" 242 | integrity sha1-o7MKXE8ZkYMWeqq5O+764937ZU8= 243 | 244 | isarray@~1.0.0: 245 | version "1.0.0" 246 | resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" 247 | integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= 248 | 249 | isexe@^2.0.0: 250 | version "2.0.0" 251 | resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" 252 | integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= 253 | 254 | lazystream@^1.0.0: 255 | version "1.0.0" 256 | resolved "https://registry.yarnpkg.com/lazystream/-/lazystream-1.0.0.tgz#f6995fe0f820392f61396be89462407bb77168e4" 257 | integrity sha1-9plf4PggOS9hOWvolGJAe7dxaOQ= 258 | dependencies: 259 | readable-stream "^2.0.5" 260 | 261 | lix@^15.8.9: 262 | version "15.8.9" 263 | resolved "https://registry.yarnpkg.com/lix/-/lix-15.8.9.tgz#684e355cd015130a6cfc52157c09b18296b623a9" 264 | integrity sha512-PeyaVHuq6I5q7Gf6YL74zhK9ASPGncF+L405my+waKcFFhtIF8LzrcNWGhcVuJwOHW1VD32+UiTRKoWbHwvvjg== 265 | 266 | locate-path@^3.0.0: 267 | version "3.0.0" 268 | resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" 269 | integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== 270 | dependencies: 271 | p-locate "^3.0.0" 272 | path-exists "^3.0.0" 273 | 274 | lodash.defaults@^4.2.0: 275 | version "4.2.0" 276 | resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" 277 | integrity sha1-0JF4cW/+pN3p5ft7N/bwgCJ0WAw= 278 | 279 | lodash.difference@^4.5.0: 280 | version "4.5.0" 281 | resolved "https://registry.yarnpkg.com/lodash.difference/-/lodash.difference-4.5.0.tgz#9ccb4e505d486b91651345772885a2df27fd017c" 282 | integrity sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw= 283 | 284 | lodash.flatten@^4.4.0: 285 | version "4.4.0" 286 | resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f" 287 | integrity sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8= 288 | 289 | lodash.isplainobject@^4.0.6: 290 | version "4.0.6" 291 | resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb" 292 | integrity sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs= 293 | 294 | lodash.union@^4.6.0: 295 | version "4.6.0" 296 | resolved "https://registry.yarnpkg.com/lodash.union/-/lodash.union-4.6.0.tgz#48bb5088409f16f1821666641c44dd1aaae3cd88" 297 | integrity sha1-SLtQiECfFvGCFmZkHETdGqrjzYg= 298 | 299 | lodash@^4.17.14: 300 | version "4.17.15" 301 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" 302 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== 303 | 304 | minimatch@^3.0.4: 305 | version "3.0.4" 306 | resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" 307 | integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== 308 | dependencies: 309 | brace-expansion "^1.1.7" 310 | 311 | normalize-path@^3.0.0: 312 | version "3.0.0" 313 | resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" 314 | integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== 315 | 316 | once@^1.3.0, once@^1.4.0: 317 | version "1.4.0" 318 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" 319 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E= 320 | dependencies: 321 | wrappy "1" 322 | 323 | p-limit@^2.0.0: 324 | version "2.2.2" 325 | resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e" 326 | integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ== 327 | dependencies: 328 | p-try "^2.0.0" 329 | 330 | p-locate@^3.0.0: 331 | version "3.0.0" 332 | resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" 333 | integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== 334 | dependencies: 335 | p-limit "^2.0.0" 336 | 337 | p-try@^2.0.0: 338 | version "2.2.0" 339 | resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" 340 | integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== 341 | 342 | path-exists@^3.0.0: 343 | version "3.0.0" 344 | resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" 345 | integrity sha1-zg6+ql94yxiSXqfYENe1mwEP1RU= 346 | 347 | path-is-absolute@^1.0.0: 348 | version "1.0.1" 349 | resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" 350 | integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= 351 | 352 | process-nextick-args@~2.0.0: 353 | version "2.0.1" 354 | resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" 355 | integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== 356 | 357 | readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.3.6: 358 | version "2.3.7" 359 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" 360 | integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== 361 | dependencies: 362 | core-util-is "~1.0.0" 363 | inherits "~2.0.3" 364 | isarray "~1.0.0" 365 | process-nextick-args "~2.0.0" 366 | safe-buffer "~5.1.1" 367 | string_decoder "~1.1.1" 368 | util-deprecate "~1.0.1" 369 | 370 | readable-stream@^3.1.1, readable-stream@^3.4.0: 371 | version "3.6.0" 372 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" 373 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== 374 | dependencies: 375 | inherits "^2.0.3" 376 | string_decoder "^1.1.1" 377 | util-deprecate "^1.0.1" 378 | 379 | require-directory@^2.1.1: 380 | version "2.1.1" 381 | resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" 382 | integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= 383 | 384 | require-main-filename@^2.0.0: 385 | version "2.0.0" 386 | resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" 387 | integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== 388 | 389 | safe-buffer@~5.1.0, safe-buffer@~5.1.1: 390 | version "5.1.2" 391 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" 392 | integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== 393 | 394 | safe-buffer@~5.2.0: 395 | version "5.2.0" 396 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519" 397 | integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg== 398 | 399 | set-blocking@^2.0.0: 400 | version "2.0.0" 401 | resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" 402 | integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= 403 | 404 | string-width@^3.0.0, string-width@^3.1.0: 405 | version "3.1.0" 406 | resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" 407 | integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== 408 | dependencies: 409 | emoji-regex "^7.0.1" 410 | is-fullwidth-code-point "^2.0.0" 411 | strip-ansi "^5.1.0" 412 | 413 | string_decoder@^1.1.1: 414 | version "1.3.0" 415 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" 416 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== 417 | dependencies: 418 | safe-buffer "~5.2.0" 419 | 420 | string_decoder@~1.1.1: 421 | version "1.1.1" 422 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" 423 | integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== 424 | dependencies: 425 | safe-buffer "~5.1.0" 426 | 427 | strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: 428 | version "5.2.0" 429 | resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" 430 | integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== 431 | dependencies: 432 | ansi-regex "^4.1.0" 433 | 434 | tar-stream@^2.1.0: 435 | version "2.1.2" 436 | resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.2.tgz#6d5ef1a7e5783a95ff70b69b97455a5968dc1325" 437 | integrity sha512-UaF6FoJ32WqALZGOIAApXx+OdxhekNMChu6axLJR85zMMjXKWFGjbIRe+J6P4UnRGg9rAwWvbTT0oI7hD/Un7Q== 438 | dependencies: 439 | bl "^4.0.1" 440 | end-of-stream "^1.4.1" 441 | fs-constants "^1.0.0" 442 | inherits "^2.0.3" 443 | readable-stream "^3.1.1" 444 | 445 | util-deprecate@^1.0.1, util-deprecate@~1.0.1: 446 | version "1.0.2" 447 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" 448 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= 449 | 450 | which-module@^2.0.0: 451 | version "2.0.0" 452 | resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" 453 | integrity sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho= 454 | 455 | which@^1.3.1: 456 | version "1.3.1" 457 | resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" 458 | integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== 459 | dependencies: 460 | isexe "^2.0.0" 461 | 462 | wrap-ansi@^5.1.0: 463 | version "5.1.0" 464 | resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" 465 | integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== 466 | dependencies: 467 | ansi-styles "^3.2.0" 468 | string-width "^3.0.0" 469 | strip-ansi "^5.0.0" 470 | 471 | wrappy@1: 472 | version "1.0.2" 473 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" 474 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= 475 | 476 | y18n@^4.0.0: 477 | version "4.0.0" 478 | resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" 479 | integrity sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w== 480 | 481 | yargs-parser@^13.1.2: 482 | version "13.1.2" 483 | resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" 484 | integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== 485 | dependencies: 486 | camelcase "^5.0.0" 487 | decamelize "^1.2.0" 488 | 489 | yargs@^13.2.4: 490 | version "13.3.2" 491 | resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" 492 | integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== 493 | dependencies: 494 | cliui "^5.0.0" 495 | find-up "^3.0.0" 496 | get-caller-file "^2.0.1" 497 | require-directory "^2.1.1" 498 | require-main-filename "^2.0.0" 499 | set-blocking "^2.0.0" 500 | string-width "^3.0.0" 501 | which-module "^2.0.0" 502 | y18n "^4.0.0" 503 | yargs-parser "^13.1.2" 504 | 505 | zip-stream@^2.1.2: 506 | version "2.1.3" 507 | resolved "https://registry.yarnpkg.com/zip-stream/-/zip-stream-2.1.3.tgz#26cc4bdb93641a8590dd07112e1f77af1758865b" 508 | integrity sha512-EkXc2JGcKhO5N5aZ7TmuNo45budRaFGHOmz24wtJR7znbNqDPmdZtUauKX6et8KAVseAMBOyWJqEpXcHTBsh7Q== 509 | dependencies: 510 | archiver-utils "^2.1.0" 511 | compress-commons "^2.1.1" 512 | readable-stream "^3.4.0" 513 | --------------------------------------------------------------------------------