{"_id":"file-box","_rev":"127-e4cb1f597dbc6816bb4c1f215520be4b","name":"file-box","dist-tags":{"latest":"1.4.15","next":"1.5.5"},"versions":{"0.0.1":{"name":"file-box","version":"0.0.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local, remote url, or cloud storage)","main":"index.js","directories":{"doc":"docs"},"scripts":{"test":"echo test"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","gitHead":"761f00bc2427f101ab0a515665ae5c90f8f9e94c","_id":"file-box@0.0.1","_npmVersion":"5.6.0","_nodeVersion":"9.11.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-YIEY31yr88oFRIk7PL6A78KY41pVVPJTCzE82tp8/7c8EdouRFLxP1aizeZHfxMlJVOCoPlmNdSeziecEi1dKQ==","shasum":"0cfb96157888efa6be0e86eecab2ba2112bb3953","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.0.1.tgz","fileCount":4,"unpackedSize":48488,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa96fWCRA9TVsSAnZWagAAvRwQAI71UoWADDSlyYuB2Fuv\nMPuJCu1BKRBbarPpvOmER/iB4J1lwZr5zYNAou9qFhk/eVQHfU4vQF+uRhru\nK5RoHYaTW7YxboFm7ricJp2MzPDGmmzPAAjQb4ST/ihhorpiA+GV5nGLq9Hp\nFFdotAmtZs0FyAdtMMThGcUdbQQ+XwUVZLZ1wSYtrZA+cgT8/hgxDQWALY7Y\n2KOiX/22N0GL8UbihQjQlUR47ILEImV9oqnGbwfhKzLWQmL+fEV2kSmn/0r+\nqBEHnmOzhX1K9TJpCBzB1DGpdd1/nNQYcrkCn6gR/Uileff9DD80bq2bd5eF\nSiTiTS6VM9ma0Mx0cDC/GrbfAfv/L5qfYx19WH1U7z5gwgzI2a97zlejONuq\n+dj5jDuLUhkDZExSv407k0odXdlTAEM7tjkUMqBEGLZjaxX0nDX3ScahSg/v\n8nUeaVGmQykFglLYjKty0ANPpn6+GL2qOiDq/oidOcawYroGC28YbG+SdpoN\n4Zi9ZFxmjmArMyyKoYiymfXj0S2kFHOnlb5vBFvGazll9AgLQoEFp6pJzrZU\n4SbVZajHueaJBED0cC/F/hHwDAje3/Pl56TrJUDmhz8y3/SXxIKHs63xeE48\nm7HStKOvofoxor4Me0F2/PLkcg7FkvTcbKa7TYWs+10HeVytMV2CK+EVlb/I\nbYeY\r\n=IK8M\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDIKc6LgNAQJdq5uxUlPp/TAEThH0zPmX8xFLe4wSN1pwIgezzy4UkRAFwGCVzb/+9GPt2XNARAkRqNrPzVoQvjtO0="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.0.1_1526179796949_0.49565492567685787"},"_hasShrinkwrap":false},"0.1.2":{"name":"file-box","version":"0.1.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"next"},"gitHead":"e2293f79775dd88988f90201d9afec13966a6b83","readme":"# FILEBOX\n\nPack a file in a Box for easy transport between servers with the least payload, no mater than where it is.(local path, remote url, or cloud storage)\n\n![File Box](https://zixia.github.io/node-file-box/images/file-box-logo.jpg)\n\n## WIP\n\nWORKING IN PROGRESS ...\n\nPLEASE COME BACK AFTER 4 WEEKS ...\n\n## FEATURES\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## SEE ALSO\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n\n## THANKS\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## AUTHOR\n\n[Huan LI](http://linkedin.com/in/zixia) \\<zixia@zixia.net\\>\n\n<a href=\"https://stackexchange.com/users/265499\">\n  <img src=\"https://stackexchange.com/users/flair/265499.png\" width=\"208\" height=\"58\" alt=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\" title=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\">\n</a>\n\n## COPYRIGHT & LICENSE\n\n* Code & Docs © 2016-2018 Huan LI \\<zixia@zixia.net\\>\n* Code released under the Apache-2.0 License\n* Docs released under Creative Commons\n","readmeFilename":"README.md","_id":"file-box@0.1.2","_npmVersion":"5.6.0","_nodeVersion":"10.1.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-k7W/78OWVk53uKd3gLfcy/WMfNUfEsofibh7XJ7Vh/8OCIhzZsKjbdfJ2+iYj4y4rlL2AU2iWSM/37AzrqBdZA==","shasum":"b222ecc118be70ce45013176726c0c7157b850fe","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.1.2.tgz","fileCount":40,"unpackedSize":97082,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+nS8CRA9TVsSAnZWagAAzlEP/1gfMWLo3aEcQZasXioT\nIg1Vl7AuVfi0SGW9vF6pKzfq75J9kONdEL75Eq4hDjw+FmtuybvXY2KpqFo0\nF3bJUrhdH0FhICrNX4r67ixLmxEik13I8PRk9sYn1Ly1e+kV2XVzuO7STap1\n/xHxWpMaeANdWVrfkYXtKZVq5w8fYOxHS9HkPC7bB2g/npzNb71cX9nVReZH\notPrqczgFy7/w7EA3oL2UiHsWTGoFktm6Jph2LJ/PpuXKHMX11JPOy7fTtOI\nvFAPqfKdJkv4B6yAyTvt2den34AJc8IbThIVzv6WZrLPpmsEsizkI5nes0ep\nwWo40ACGhQ9zTZnoLT1CFWVMYZJh2Sf5JNIWUlEEWpu9yo5a3m8Lpx0sF58N\nOudWyP3GumeF0m+KmDuELFvdHLZZToZLyzM/gLCebwRysPwQkjShfRiZ0kPz\nE90PvWqJPrwhDBITiNgiuk+CYP9EncVZJf6kuKjfWXa3W/tbCTE85IkXZ9Si\nB4FAjPcTasZihaSNvRnu0GRaTo67tjLayyooag6PIpX3QUCZSOMHsat9wtgS\nG6CXZE5rJuAyBkyGmRYOucE6jwIq8ciqeZnR/DuXqDxesOr+jIc24MWlUAi0\n9HbcTtht1mb2hNoNQA4nTvLRBhvjLyIgGtPgUeIM0d8oSSSX/GhGtrpKOpZj\nhyb9\r\n=AiLV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDM6z8vtEUZkAAAPIjC6ypRmMeQIGvtvY5EI8FGlNlLEAIgKQvyy/ba/dEXvcxBqtt4TXPsw/FK1B5tx30Kbtx7LbI="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.1.2_1526363324002_0.9874792920976534"},"_hasShrinkwrap":false},"0.2.1":{"name":"file-box","version":"0.2.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"35a64e286889367d69dfbb96cab59b3084d74a39","_id":"file-box@0.2.1","_npmVersion":"5.6.0","_nodeVersion":"10.1.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-XhvrZs3hzlYNZz2GRuwh1SXHWmc4ZxzQM7bw9H2DtwGYGuXyh2kdD77M2KTDQTbyVK4IygnijJPswzarKib3zA==","shasum":"c3cfeacca246d74b420006f0b1eca900e2af53a0","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.2.1.tgz","fileCount":40,"unpackedSize":97085,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+nZHCRA9TVsSAnZWagAAr4YP/0Uz728WaJBrAFwVpwH1\nxWs8PHITEHlHQHgXe6B+eMxwBnxFDbNbCfwhXIZQz7gUMQqYkLE5gtdibbtD\nPJFltvqU2KsMW2q+STyXg7gYV+vKdFJxU2muYUDMjHz/doGkY8TF7bcsC4Cy\nFo2EYBY9jiNJcRvM14nrDErbxQgz/LBaHl4rMH8CHfArcfKBgloPAXcuyWp3\nrCxbt/IAzV2mmEtdDmBJf9yv4aBnAdKZRoRWy8NJG5QlwxBo4H6SMk3CAr9T\ny8TFTj/F9U99p3Bv0eoo0ZtYSFISFsKiCtwnP2ZsOqVor7Du/E3O7bX41eda\nHdUn1S2idJDsjwITgGP0mNJ6nM1a8wDYv8W7iKMbrU7Gn+Jkfcb6XX2CCcxF\ngAQAKQQumElyH1JOhKGPW9VGRR9Cg7ALEn5/ybQHpOSdufxIOEaDOT3QyCel\nxEX6TYwf4pnryRHiqMX6ZimFx2m4qpO5zPRAyME1UIlBIHFMMS38+R/Y8/UC\nEDALXhpzL003LmFkyKhLyNMqnxGRK+HL7kqqPBz2Dnnik/N+fzoqpc5UQELe\ncS6AqMY9oRT6mz8+Y5VE3xZizwTF/wcw4xMwfOtGMuMj2qcCvb08gXvKVlIs\njfYgLZU61IksBuKypAEdDuIbc2ZbZg7aiBJ0/nasMy04IgzVNBuexNNInADM\nHbKz\r\n=xLqV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEF9d5yUfJGNfBIhLG3w+5sD83e1HSPrdPrOacGOOiRNAiEA3DeUZOHav9/cIL5+1zq26UaXaHdcaFEHzQ00OZgIyYM="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.2.1_1526363717742_0.10135780557519114"},"_hasShrinkwrap":false},"0.2.2":{"name":"file-box","version":"0.2.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"efac55fd8d59ceb7f84d1b08d1ed0ab9d1425a6f","_id":"file-box@0.2.2","_npmVersion":"5.6.0","_nodeVersion":"10.1.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-GeTHG4x/USAo5r0sr2LJxvYUu+HE3G9Mq4AZAmqUZsMz675MMjwSZSQybtgtpQRVFurcZy4/a9QrxqF7lvV2tQ==","shasum":"eb1d41ca6dd03e10b4b8a7e3949152effe863896","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.2.2.tgz","fileCount":41,"unpackedSize":97664,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa+6yyCRA9TVsSAnZWagAAQvwP/0NPyPWBgQ1u+skEbDO7\nbzSXDlVXoPjMVIFLYEf/HNd1SqqaHWd05lg3v1MGYSBAs1Y7xL/PEJolZRf+\nxhBBr7hEPcgJ2q12t3oTG2FxvSrsoo/yeqIPuJFPVnloX1fTTq3VcJmYx61h\n0EuPmH6HDbd/LEBCe+PyMIgDnUUBTaUUkwqymvZ8IzKNtiMOcORfe9Nh634B\nh/TenTkBUskis2i3MXJVhKeiwBKt/EtsS+rvg1ruZRt9uDwKaTh3/sCR10dW\nkC4Cn8YEDniLwj5ySbNHj8kk0sxKIzEJDn7nURKh9/V1KIqged6DGbjDrIXh\nj10dXbHb0pM02I7WETjsxef51bQjRfSn8ED/qRJB8o7KjRTq3z7xkYE4m70G\nQ6ReZMGZcya5on3ZHkd9XudUOp7EJPVqxv8AWN7hDce2cIiA8IgqvXreWNRD\nQypOzvexO7ZP6g8DMjvjJp/FobMz/GBCtb+WyazDON7GPw5qBwmpS8kdJ9+e\nKB28yZROAaqLig9prltLjR0f/58teGJQCzlfCsEYmAjEXCCzSA7E7BuOTLD5\n7Lmape+KCBIr6Ndc1V5mpfQauB71P2ydLssLwz2RzDKH6PzqJhpSEL8HRSIz\nmgtK2uu6TmKZUCtUk4t5UuGRCugkoJ0SILht1kAMA55pALNEVcgdiST1sNb1\nEWeg\r\n=FQVG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCGQkAMwSchzye0C1tCuN35kwjW1J/8JsEyILJtBJNtEQIhAPQQBCkpspgn7vBiVpvE9nveJSdLpi4NSekGexh3lnZU"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.2.2_1526443185618_0.6033819794935689"},"_hasShrinkwrap":false},"0.2.3":{"name":"file-box","version":"0.2.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"681570ed11481b2ef5314026f819291a5546e7b3","_id":"file-box@0.2.3","_npmVersion":"5.6.0","_nodeVersion":"10.1.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-fMi+4b8XZo1r28AdTEwDFQmP2Ngp1+JWV13nPaKXBjXH92/P6K6WgYooK7LoX9bvOQmsBLk74/uB+z11oTCF6A==","shasum":"5f06e0a5ecadb8845c52ffccbeaf4b73b77eee08","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.2.3.tgz","fileCount":41,"unpackedSize":102852,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJa/SSNCRA9TVsSAnZWagAA/aIP/0rpAa/zei5RFv5+r/sP\nl2rgIb8k0Aj8WWK6Czg6/ftHsZn8uc7tCJYaLRkKj+RwGFqc6W7yTKRnXtLE\nRaNpikR2z8i3lX5tjRDcmfIEVigRHXheL2R0f08IUdxytBbrLxTv63yzkdvD\n6/uieqo4uQpdTM5ULCwM+SjWu/ctpa1Erkk7eoFTxrMeiJsXTHu4sjISUcPJ\nFO3rYwx08KTjFGLbThXTV+WstcGYW5m53WBOmkgj/pwbBohOw9Us7ksBtwUK\nC0V2WJ7crmWuDphMv8Re0yyAcm5bIxa0DnCptJo7xw9JDQGtXlkd6c2olKxi\nHeIREcyqzxyn/3CbADmChTxaVZGBrEtWwpVlJTraNxD0K2fWxJ+r5EqGUvLh\nQkaXHtSf55i7OkWpSM7dY1VwbkZ5NMyvZJQT+cqpWI8NDdewh2EBGLwIAWPg\nzMYr916IJU4VOcQtaCFUQAqN9VNezKeRLdIEwBcHEkUf2ShTHg462eugKEn1\nKjrMRNkgnoD1nW624q4MTKPn69Fw1A3q3naQ9jpyR+yPspmKn3triqFS821Q\nLyXHnRkBfa5YD7kMY6ubhKcYwbOGIEozuA6XwnkDw14CQxwClhfMULILzG5R\nUKKX3zWq1sXnBmhjI39iMZzQklL0WIQIK2SQ+3Mk4caoVGDMdl+nAZMLTidW\n3VUt\r\n=N59e\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIARV9mHBnTzPsvOTS+EjnVRkBJUDtWUSa8ADAWHWjk42AiEA21V1dUSTS2Fp8SVndXhTbkhb4vHix9cI2slp0CpP6qE="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.2.3_1526539404478_0.930327056901586"},"_hasShrinkwrap":false},"0.3.1":{"name":"file-box","version":"0.3.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"next"},"gitHead":"4c4a17fc8c1175dc66006b86e78c25dfcdcaa8b4","readme":"# FILEBOX\n\nPack a file in a Box for easy transport between servers with the least payload, no mater than where it is.(local path, remote url, or cloud storage)\n\n![File Box](https://zixia.github.io/node-file-box/images/file-box-logo.jpg)\n\n## API Reference\n\n1. `fromLocal(filePath: string): FileBox`\n\n1. `fromRemote(url: string, headers: { [idx: string]: string }): FileBox`\n\n1. `fromStream(stream: Readable): FileBox`\n\n1. `fromBuffer(buffer: Buffer): FileBox`\n\n1. `pipe(destination: Writable): Promise<void>`\n\n## FEATURES\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## CHANGE LOG\n\n### v0.4 (master)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## SEE ALSO\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n\n## THANKS\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## AUTHOR\n\n[Huan LI](http://linkedin.com/in/zixia) \\<zixia@zixia.net\\>\n\n<a href=\"https://stackexchange.com/users/265499\">\n  <img src=\"https://stackexchange.com/users/flair/265499.png\" width=\"208\" height=\"58\" alt=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\" title=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\">\n</a>\n\n## COPYRIGHT & LICENSE\n\n* Code & Docs © 2016-2018 Huan LI \\<zixia@zixia.net\\>\n* Code released under the Apache-2.0 License\n* Docs released under Creative Commons\n","readmeFilename":"README.md","_id":"file-box@0.3.1","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-3PongInN2yTLgJRe2aMOrKEsW+kQrhZE5VdruZqojdmjWLI+XfFOeijMH790jOa9raCa/tW3z/+l6bsIGHF9qQ==","shasum":"dedde3ab7f09b9a064dba4f52ec55236fae58a2c","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.3.1.tgz","fileCount":41,"unpackedSize":105981,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCMt4CRA9TVsSAnZWagAAFp4P/18+q4OuJf3jXyG1wjN9\n1nIVnf8Lix3qvtpEWDt6QKwNhs+h15jkPbsH/VwMDxmUxY5iMEeglIEFE4wW\nBhHXC8gHxXws5dHF/oLaFLMvzQf5CNDuDsctqUDc8Rg0jyF548e96YkVrRIy\nDit8obt+fL5AZ2EEHiyGM0rY3pKUMt85VJU6OCpMB7ud+trzqpKGq9re+Hpl\nEPSabOqTIXCRFJ4TfpOBNBniEyuBh3k8BuYBPAb0oxP9/vj+ksZZXiK8oMjT\nc6YCCQcrrSpvgAivPW5nrZ8KgmJRIXrrH6GWI7ClacHUi3Y1s8jZxM22fPsP\nx5TlstFf0EM46xdL1mFMx6XT7Y+y+9YEQFXMIdyf8M7O50FPfh91lncBwmBo\n9RYcX+Hfmbw4nnKGBsydCG9EIGQPKxX7pR24I2icO9khgcVmiwZWd1IolGP8\ngDLT0jWE+XIvhijwQ4aWNIcWFKWaa6tDq/YewV0gEVPZrLZ/DXvYFvaisnR4\nEbTASAH8sQKftWd3FP1TCqTpx8yVDzX4WLp5b6fdbWdrfJJy3meA45U6AXcz\neRf9FqxLuPGq+NyzlZB0hJL5DwJPZ9fEYcpL7KYaP4cpuRtdP6W7jmWKY+8b\nmUj/KtcaZpV6SXnBz1nn/UBVc8t6JJBj+Py3ZA2Xg4UReq1WCSP3/u2Jx5f5\nlTVH\r\n=AHEQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHsoeeWN2exdGrXoZ5JsPeJBMIHE0DBSSAtGLvDPy7WlAiAq2tQoUHoQz/Yldyx5Pgi4GOCW4Qd2pn4PM8TXCjPmqA=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.3.1_1527303031573_0.32528958017401366"},"_hasShrinkwrap":false},"0.3.2":{"name":"file-box","version":"0.3.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"next"},"gitHead":"bd3426d206921ccc0b9487a70b2d77aa43eba4ae","readme":"# FILEBOX\n\nPack a file in a Box for easy transport between servers with the least payload, no mater than where it is.(local path, remote url, or cloud storage)\n\n![File Box](https://zixia.github.io/node-file-box/images/file-box-logo.jpg)\n\n## API Reference\n\n1. `name`: the file name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n1. `version()`: version of the FileBox\n\n1. `toJSON()`: to be implemented\n\n1. `syncRemoteName()`: try to get the filename from the HTTP Response Header\n\nHTTP Header Example: `Content-Disposition: attachment; filename=\"filename.ext\"`\n\n### Load File to Box\n\n1. `fromLocal(filePath: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n1. `fromRemote(url: string, name?: string, headers?: { [idx: string]: string }): FileBox`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n  {},\n)\n```\n\n1. `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n1. `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n### Pipe File to Strem\n\n1. `pipe(destination: Writable): Promise<void>`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n### Save to File System\n\n1. `save(path: string): Promise<void>`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nawait fileBox.save('/tmp/logo.jpg')\n```\n\n## FEATURES\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## CHANGE LOG\n\n### v0.4 (master)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## SEE ALSO\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n\n## THANKS\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## AUTHOR\n\n[Huan LI](http://linkedin.com/in/zixia) \\<zixia@zixia.net\\>\n\n<a href=\"https://stackexchange.com/users/265499\">\n  <img src=\"https://stackexchange.com/users/flair/265499.png\" width=\"208\" height=\"58\" alt=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\" title=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\">\n</a>\n\n## COPYRIGHT & LICENSE\n\n* Code & Docs © 2016-2018 Huan LI \\<zixia@zixia.net\\>\n* Code released under the Apache-2.0 License\n* Docs released under Creative Commons\n","readmeFilename":"README.md","_id":"file-box@0.3.2","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-TQLX2gd/R7GcFueB5ivz659v+qRzfkoBU1Bs3js9iQU6nsl/X/5zVOnqClbqz3lVnIrOGto0mw14Yhu5ImJpzw==","shasum":"c6bd572c7368839561e920b2fff1f909e5bf67ec","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.3.2.tgz","fileCount":41,"unpackedSize":107318,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCNxICRA9TVsSAnZWagAAPVMP/2KV+nggkGBN284ANTfk\n0v7xGeHL+LKHC9VoxClq5QJnNmHaTqD47+VFvTyZg154GRvV5o1a4ZtUDfrX\nkMQ6KIMaIlPBnv0hKmIiNNYSPkafBVviRzMaqDDDLs87ISS6w4t5REyPpdSr\nSeQFmzPG/A1beSznX4ETUt3AZwIY/i9SsiNZ/4T3L1ZTEt8uL53SjipeNIGq\ncBVhOqvrych2nDDoP0/cBPiF+2aSU3cBlEDIqNzjOxaJVPX20COBfjXHyvLt\n8HveAbEdqNoVH5/js+JySdlxgz7gftpOic0qTutuWk9RmLLSjDwbkY6WZIkV\nwnVZtyyhG0x/cHpai8SDMJqX1ACD6G+ghSX4ahrpyINulRPCANLyPE7mpCR8\nyifsNcjapzOnE9lTKuzFZLEGY1zzb0tjxZhJ2oI+JPPb2BeloMMFPIivgM9j\n+mDK6imzYPRNkSOhlq6s8VU360wvRLF6Ql/iFDlT8T1l6HXHwa48aeMJzQnL\nG0GS7OtP4Yn3xRE7gyXQKdBtA15qOAQdw+vhU5E6VnQAs3X8StPqomN8V4o1\n9fnL2dT5ytjAD1bCvtXOp2RuxxIa+GEDxJ1Nhu2hJBWZnxI42VAWeIyPwvvC\nYvLhrumAloI1aFIp8PHO6qaxh3m1mZJtExPYtDMkj1ez9JoM910gE+OcSwzL\nXIqB\r\n=5qTf\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDs6ahx7gRCEAjanwlFyFuthM6djEMk3kyV0LGNmdjyngIhAKFEAgECwC5oucKIAqIruUj8WkMYhXV2SrlOe1pQ/DAF"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.3.2_1527307335692_0.02459678314366287"},"_hasShrinkwrap":false},"0.3.3":{"name":"file-box","version":"0.3.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"next"},"gitHead":"f23f59a4ed4b78e061bf2f39d15d1c3fa9225765","readme":"# FILEBOX\n\nPack a file in a Box for easy transport between servers with the least payload, no mater than where it is.(local path, remote url, or cloud storage)\n\n![File Box](https://zixia.github.io/node-file-box/images/file-box-logo.jpg)\n\n## API Reference\n\n### 1. Load File in Box\n\n#### 1.1 `fromLocal(filePath: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromRemote(url: string, name?: string, headers?: { [idx: string]: string }): FileBox`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n  {},\n)\n```\n\n#### 1.3 `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n### 2. Get File from Box\n\n### 2.1 Save to File System\n\n1. `save(path: string): Promise<void>`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nawait fileBox.save('/tmp/logo.jpg')\n```\n\n#### 2.2 Pipe to Stream\n\n1. `pipe(destination: Writable): Promise<void>`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n### 3. Misc\n\n#### 3.1 `name`: the file name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `version()`: version of the FileBox\n\n#### 3.3 `toJSON()`: to be implemented\n\n#### 3.4 `syncRemoteName()`: try to get the filename from the HTTP Response Header\n\nHTTP Header Example: `Content-Disposition: attachment; filename=\"filename.ext\"`\n\n## FEATURES\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## CHANGE LOG\n\n### v0.4 (master)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## SEE ALSO\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n\n## THANKS\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## AUTHOR\n\n[Huan LI](http://linkedin.com/in/zixia) \\<zixia@zixia.net\\>\n\n<a href=\"https://stackexchange.com/users/265499\">\n  <img src=\"https://stackexchange.com/users/flair/265499.png\" width=\"208\" height=\"58\" alt=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\" title=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\">\n</a>\n\n## COPYRIGHT & LICENSE\n\n* Code & Docs © 2016-2018 Huan LI \\<zixia@zixia.net\\>\n* Code released under the Apache-2.0 License\n* Docs released under Creative Commons\n","readmeFilename":"README.md","_id":"file-box@0.3.3","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-zeVQIj3+LcrlzwUkxFrlJ3H2gB1miUUnqxx138WfhEbOrki3UZWQFvbvdYFPUcMBr4D55qTk5oKV0hZC2zGpIQ==","shasum":"a571581274b45e559ad4f99aad346c58be695b76","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.3.3.tgz","fileCount":41,"unpackedSize":107413,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCNzzCRA9TVsSAnZWagAAmPYP/2ow3U2xwI4BeUVAnVn+\n4TJc79iCIIMecUUoZR5zJzpQGG3rkQ/81goYjsAsEYuHWVR03AXOzkqB4eN2\nIAoYRIUuZvEOjP6DmefPyvFwQ3UpqjKQstVDe1RE1BonbRf340dGY/VQL+81\n4qZ1ptEAqrgvrQD5cwofcicGuvIuVTgS+ALf7onXIsV+gMEkL9xPqOcSsOAZ\npfeiGZe7l64sEsxDw36K2f5t1H3ijlfb7wY7cZXmIeoin1PCz+PlHwTKblHq\nr5I7E8cvghivZN3N6zKkMmKldAOWCvss2vYT+gPbDJ8y7Kan+TEDIJpLo+xn\nBd4b71caTsIlC0qCU0JaFbkDYu14VStyV4CJ/9Ywjmxsk3xgsaNP0z2ISixa\n4yiZ+PP9Qut1vu+hD9Q+WcXbsiYz+W4J15hCfgkLCLqZbGg6ZgctRRleu06j\nd6TTsG4y2fHyZSwmNWqvSSkLgkst+J+VvotLx+dThrF6IDrqEN9UgEO+YMED\nlD39uO3fPVDdNsORXcJHgu0O61Eflz1BZbOCSY2ue2q5fwjCNp19KtY9ZIB/\nZTBWqr6nrAWUARxI1X9Kyc9iXhOvAMF6To+couJkHUHfIF/o4Tmv/x71ZGyO\nWUsETUy2amAoD3IkR0JtYFXQdyqlXPgUUkDjGhcFj19GkOpufKoPqO+3J4Hi\np7G6\r\n=gzT0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCwMoqrFUulQqEAsvdLwmNiBi3QeOWLjmCNKuZDYPXldAIhAMxFJkx+CapqwD0BdSiP/0WyG+ktowttWS7PVMqqnM7R"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.3.3_1527307506655_0.7298157159180225"},"_hasShrinkwrap":false},"0.3.4":{"name":"file-box","version":"0.3.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"next"},"gitHead":"ff11b3eb26a9371fb9e4d91df00518ff2283aff5","readme":"# FILEBOX\n\nPack a file in a Box for easy transport between servers with the least payload, no mater than where it is.(local path, remote url, or cloud storage)\n\n![File Box](https://zixia.github.io/node-file-box/images/file-box-logo.jpg)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromLocal(filePath: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromRemote(url: string, name?: string, headers?: { [idx: string]: string }): FileBox`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n  {},\n)\n```\n\n#### 1.3 `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n### 2. Get File out from Box\n\n### 2.1 Save to File System\n\n1. `save(path: string): Promise<void>`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nawait fileBox.save('/tmp/logo.jpg')\n```\n\n#### 2.2 Pipe to Stream\n\n1. `pipe(destination: Writable): Promise<void>`\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/node-file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `version()`\n\nVersion of the FileBox\n\n#### 3.3 `toJSON()`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.4 `syncRemoteName()`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n## FEATURES\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## CHANGE LOG\n\n### v0.4 (master)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## SEE ALSO\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n\n## THANKS\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## AUTHOR\n\n[Huan LI](http://linkedin.com/in/zixia) \\<zixia@zixia.net\\>\n\n<a href=\"https://stackexchange.com/users/265499\">\n  <img src=\"https://stackexchange.com/users/flair/265499.png\" width=\"208\" height=\"58\" alt=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\" title=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\">\n</a>\n\n## COPYRIGHT & LICENSE\n\n* Code & Docs © 2016-2018 Huan LI \\<zixia@zixia.net\\>\n* Code released under the Apache-2.0 License\n* Docs released under Creative Commons\n","readmeFilename":"README.md","_id":"file-box@0.3.4","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-VwQujSAG6BoQderTlStb6RsQKp/QwmO7ai2u6YKNGi7/eEdZdYp+me2zeTKuuc0g3FRl+kGL/NUIUCKlH1LRXQ==","shasum":"6dd0553e8a58ae39a141dafcd1a5fabbb454d150","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.3.4.tgz","fileCount":41,"unpackedSize":107452,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCN2YCRA9TVsSAnZWagAAE/8P/i/CEWIxiTsuiZOPF0K6\nuQ4Kvx3D2imJ+Pwv/CSi/9YU6ZgQlmwgshShMqJlN5H7i6zuvhpSgFRzJmZj\nSH0ZTrQ97WYEaoc5PLn3cuWv2pdMxopa8tl/IfkP435i9iGI3x476owzbfCQ\n61WmFqJRV5etBWhVQGtX0cmeB0oaHbzQlnVFpVbD9ZJxxmfRIEaPdq4qfX1K\nGhsbDSQJ+1Tu+H22oJOe8PxKFhzu9cg1wMVVhVVqyoEgO2+3+N5KOLq8fzfj\nA61pfHL5CYdFcNpkUGZ/StiX+cCDmkTiF2v2OCrJirpzBtpFkjjfBQA3814B\nQxVXZBH+Bf0QwJ+PiFUloYtWOnNIZ0szDz0aXYCU8yLEQn9jeXFBvdt7uq/1\nrU8BRDHDCupZ1A8IlGZLJBt47pq1T66jp7QaAkftDLqD400hc8N0FuOCaDp7\nQFIT1XtLG5/XPN+GVTYkqKsCuDosmOEqn7VoNmLo+47YmknPn7Ny3V/mY/U8\nAeGSC6l15N1Kr5j9ztHSNyZbMS7h1NEe8JljmvXyK/MDm3Ua32HC49gxdQf9\nW6bAdalsxPQ2ygrB6l6unVukAbBzJh7zKPjXcYngrWEE965fjEHk8rlY19a7\nTfnTHxCr0Cy0NivHWT0F30PvFBRnPOE01F+q+yXHS4RInAKEiMc8iI56D9e/\nwUL+\r\n=sTsI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCpkZTI//IFDoV8xSiaxpuOgv73XJCS/VkOJ7rIAnb84QIgLtuOBTGD9fvzoixUanIdMQAt1w6tgA7DNr+hCqRe8Ew="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.3.4_1527307671528_0.5484709936679699"},"_hasShrinkwrap":false},"0.4.1":{"name":"file-box","version":"0.4.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"df09f8140fd3bf3ace126df588927ff91a2fde3a","_id":"file-box@0.4.1","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-3z0UtQBASroX6dHiZ23Px6bKQgL2Lkt+oZMAyS+EHSLkeWrMOIxM4wb1ysXNUkrNCBmb+h/6gO1J7dbQda0kBA==","shasum":"90779b50fb7f81416cbd09a551d0d8370f27038d","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.4.1.tgz","fileCount":41,"unpackedSize":107455,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCOSnCRA9TVsSAnZWagAAqu0P/RdMRmxGPt7gATGQHZgn\najRbLASZjn62WnT7woF2rx0ddS7H3nCPjSh/e+PKV+32wFppwNH5r5BthFsS\nC4IdhFPjx7SqyLE8Y7gOuQVtQVxPiYq1vgrqNIL4UJcSRWWHUEeF80nsadLb\nRecJvwCR7V8A2h9S2K9bd1c5v15Yec9BUshTVX1eXET522MLhKiMj3W1avKH\n/+WYOdT0etkOqsMupEXOjSj9txfpbBlUgybqurweG03iCvrJsg8dBut+uYPo\n8Lb7m0xI8Ix0utcnJpE1tEWK0lGvwZFje1XowY/kxkPDB9xgd417c/LpuvrO\neFu5j8G4eercbn9gzS7GgP9zTPtZEBcyAj4tQCOP7zVUxjIjEaemE6CKn9qx\n3ey8flxlBoxtNuaa2s4S7PDOFGoCMZD8I5DOQOA/0DFZH6E3q5s2ifmIDarX\niT2AZlqbRWecptA9pN0Ush4qW3NWqw63ns57UcUp2zmjW27JCQFT3tS5N8eU\n6Tu1R5ZfnpANnCMdP00GpEb+EeSYqOdw5P8NYWDRNLGUYzB/jQ9dQxtUNBPx\nxyTPyeuV1RlezFHoq02PUQps8uzDXxA6Oa3V4IeTf0xReSrkhsNxkSeZfkT2\nCNydavQ6G7u3o+nG10bPDNCJBag/K3+Dbtysl9wr+7U1r9v2RyHacPUFMpeS\ny3jd\r\n=AStW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCKltwRB6qznpAnpvZqVBCf3Urf2/QH9ws3d6dLed37oQIhAMDAVJJZ6Phw1qnpU/oK1PIHTjhtA05ylErDm5OrefRX"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.4.1_1527309478703_0.485886566065832"},"_hasShrinkwrap":false},"0.6.2":{"name":"file-box","version":"0.6.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"2570d859afaf2f54d843fe6ad06c43f66f2470d0","_id":"file-box@0.6.2","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-kQbLF8NkX+XHdO9edZsb7bsko5JU+RCDT5wgkbBWNC9iTAMS027WX8E2zQfjZOAaq/KRG7NtCTRvEmT16gY1Aw==","shasum":"92a69654ed9f65cf6d68e9726ef43e93aa7a4782","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.2.tgz","fileCount":41,"unpackedSize":105975,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCYmFCRA9TVsSAnZWagAADJMP/jm012ro5kuigW31E6uF\n4PwsYFS3zsdKg75ogGbfUJNdV7YfUfkaptMuSeJyOLebdUClr1ldXfaakC2+\n3u+mwsNatpeneKw+KO3AjPaqSfLuxiRkzNA7MHKW1Q8Upg+mhrflKoFGaBOq\nwTqKm887tnwtEkoa7STQ1Qt5DABHKrYYTzN5pble60R8r+ti2rAPARis+lzK\nKa6T7yVylwYh/UXYDGROIlZl405bH0SLwpdp/1GDvCJA/fOUSq0kG6YZc3AP\np8RoHBIGqFb59zyREpN/BCfBr1sVH6SejDx2lJ+TeqdhAJR4m2TuCpyeyjMy\ne2RxwSuWflQ19d/CyEDq9shQQLoZy1erVE1cuh244/vpoaRnXaKlkJOrdEtU\npet4m0E4t6uFZeMacgjtzUeVz+8NKnO5FA5ODAw5iiXdTYQRqOcKcNta8ej8\niyxqIlK0VB67Rok4P/j0Nh98FyL6FXZYMBPTxXJ26uGckqZirVCI8mvdP0NT\nKWvBRHNFmNgqPykOZsQDzX49sRZX2veBXjw7lvEiRpvTyJzHXZpBhnpxqStQ\nSmXGWsYC6LC5ahg/pNsCvPzeiakJ9z7IAXYO/yL0ke8cXF9Z1GFQcSWcurlM\nU97rxvG0eDhuHtFwXyEB9WI3Clq2rUPVRt82sNeou3v7EUWn5rZy531rsjY0\n5zKh\r\n=Abdo\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCNxyI7oT8aubaXOmLFnFBafZOvI7kfeHu0O+joAmyg+AIhAPyCCTNxDFQBgXn/gsHVU/DLalqUbbCVjUsrYZG2rehR"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.2_1527351685178_0.17850341793448887"},"_hasShrinkwrap":false},"0.6.3":{"name":"file-box","version":"0.6.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"1302c592f042001822bd1a5c82aee6ad5e280cba","_id":"file-box@0.6.3","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-mb4Ef5yYmHAbt7AZaJ5erh9me0XQKOmNpkCw9cqQFKYB1QQgNnT2obKbWF/EbipB2RLfV10RCdqUK00BpCSddg==","shasum":"653506c364657faceb707a0faa1914d6e2272815","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.3.tgz","fileCount":41,"unpackedSize":106099,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbCqTCCRA9TVsSAnZWagAAZFkQAJy2tm64DUkUyKKzQh9Z\n9T617NCefL/spiM2oFCW4JpnNRSdeKT6OGa0jXjsEuexVWeg6VwhMitL/5YD\nykNUe4CyT24j9HZPH07z7w9J5jYi+JSyV9RoUMi0i2LqAUJpVpOPOFjuxbuO\nYT8D/iH0oOh8ygunW98Eo0BNZbUeSp/vDeBu1uzDAudenXs/gzgHtpeMF4v+\n3n/MN+H/BgNMJLRbF9va+PN06lVl0rJNFsUUpveFicghZiCYjk0hFsiq7Yj3\nWpbF80VbvfOj9BcqK/6lD38siDIpAhvyRU9gSB+BmYcXvCGz9gCGuTbjI0kK\nroEKFtL+xB3KDr/JQxuz3XgIyzjr4/AUd2+02JIYoLrQRcViUcSKnGliOjzV\nBfoitZhQLwNtqWNMuNFyfI4Oy2QEIHCab/BoUgiXByUWsqyh9GoGCsoUjDxD\n8yN4x2BhiRIAyNz1qvcZysY9u8GeU0pcIxQTBotQwqNq6s/NIE8UHdJnf+z4\nkRNOzUlJHQLepTW01MM19KMiE3lsRYYLXW6tGgaGL6mKVXSDj97od9fMhFFu\nuQYByxETLcSFhpwpk3pUV747FFGButmOU4hOz7a8eYftAzv+nLBiWJEHjQWM\ncyUDkqIcztUyhTtLgatOwmb4WjgXs229NO95uYpue9FY95EuaVmmUgk3xoW6\nkEcG\r\n=icir\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCY81Tat8AkvQ4KQPHP38/jmnjYrB6ABisrRf8oA1wQbwIgFeCyXrRLRFDd388AuP9uOTyzwjIt3bQ8LDKHdXhIH10="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.3_1527424193023_0.13727434664966132"},"_hasShrinkwrap":false},"0.6.4":{"name":"file-box","version":"0.6.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"fcb22af1b1b5275ae30298b63cca641826f881aa","_id":"file-box@0.6.4","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-dOE4yTDdvbfr122nu1Qqry8DoNfsP3gWLkyWe9+fz5XyheicFqdttDiLQOSLPHJv1QKUvduJI5Y1NQNVIX03MQ==","shasum":"744840bb20b552d889b55842c112a922f8fbab33","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.4.tgz","fileCount":41,"unpackedSize":106070,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDF+fCRA9TVsSAnZWagAAgt4P/i+7dN4AS+C9fd0T7N6x\n4OGxl5akU0bw9xn97n+TWYGlwq9VAJZA8qd+NPXScEu/eUC+SeyD0Pxng8s7\nEtViAydYii4JESi6Etjxx5qHKfUh3cMfbVm/ffFWKINAYKdrqwjo8QM6en1S\nQ1CG9m7SUZ8FWoy70Ixn3ZHn9idWCB80ShruMMBBie2jwq6uHeGJZC8TJfYd\nVch3CEdN6/wEB0EeHMkZKHeXNLpa34jiKf/fTOSp0FFhOpGtP/9wNQPlUsQC\n+JQR3/tkJAel25orNOsNYskpZ6G6L7x5QTYzBtrAtdulqaOgK8gljiyrVtVi\nZfP583f7LGnq+BVUENEt5+tJDIOITrWGyNXaNPq2eLyaY09Q2f/bVNw9/gji\nQs0djhbfw/TktHPF43JhT1Ey9B+4mdKOZMBU27ocwON5RLQBGp4sbKFckiyU\naMM2CACXXKYH8qIBOi28ztyjeO9LLwvmQJJQh78MrTYrTxE8ypQIV75QvdQt\n0XuDL+ZMJKU6eR+QOtrfa4fQwm5jdhsLN2lEAi/1wBTBZd8gI8n9DjkwSaUB\n7G+MWh9+e3sLUIJv9OWTWyvDXZr7fCYuwbfGQMpjSdtckumNGyN9obONbzMq\ne8Yi43PCAO+fLl35Z182BYX46EAtdh4U+qslcf0s+NImZSmDm+4sN4qIz4Wo\nTBT7\r\n=67rT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBsNSKu/IIKXmZD0xRl/Ftp33SlsqQsXW5auojVk1i+PAiAFTYJgGXAE9WUp5vXTZcEEwhcYtqbI6+rVAETKdpnyfw=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.4_1527537565193_0.8572036046286757"},"_hasShrinkwrap":false},"0.6.5":{"name":"file-box","version":"0.6.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"0e0f50b3f210870b4c9ccfb3e467e9216616fe03","_id":"file-box@0.6.5","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-N4XvYpBVsXFLb8aRqwv/lZcr+SCmWIo3Ov1UceSHnPd24vO1EmMmZqYhwITDo+HG1+FSBjYgXBNtYnKSGJTBcg==","shasum":"365f484d616d27bdf3360a416d689ab6e625715f","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.5.tgz","fileCount":49,"unpackedSize":111260,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDQ4eCRA9TVsSAnZWagAA864P/3R7beoLH+OkD/Wp9hgo\n2ouJe1QqQKCVxhrtGsTioN+ggi6Fim2fQIS4jsydAt6Hy/VA0imlXsU5cWum\n5EVO3GfYcbERQhVp+Eeh+zb953iMZLy1WJ26mWHZ/iJdbrW2LFmUXxHW6/61\n+M3prtk9gxjdJ7b/moDqjXZquBT3QBBtSry3qdUEEe36LkcTcx8LQ59ysW4R\nBP2NudcoR0CAwcV2bKGwvv1t0iyutgPZfPboGekoCdFnaVUVSNpdGNB4O8YU\nobO7G4wqc0OTYRf8DmeCW/YQf9IkHo/DoYXS8S0Mk9roqRM7Uplzo8dyK4oZ\n6M/I334R/D2SvGPp0j+MX5Min70lxKxbsA/yciNSzLT612u8D3oNiLVtBEKR\nfI1Asn2Kcx/Volp1SSxOAqKZJxm0KCXXxohjXxSdc0/9lau+n9SqWbUlPCmz\nocISg6NdzLjWx7R9M7BIJPfuv1cWdWu2s+DUfkQP20HXl2m6nm6QYyTpB1J4\ncse5Xvct7VsKX5ZOnhUEU2SgLNsuY3PkX7/kg17Cgo0gkGJaxgb+yDil3On4\nMchlvTW67u7oDqImdUZXLErvTcpZZG1hRuCoMXVQJBh8X/oJ351/bR7zumW4\nczVk5VeP5VqLAoqkhUzgFxh0f5AMBtf8WNfRDG4ZphwXe+bdra9jvT2ERP+H\njXf0\r\n=e7hb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD/TJBczB0tDGyuvN+Ath4EG3fZPRUPpxjQTd5mxuFvOwIgYj2pO0ORf2cbY6MVMQ+70m50SORELnOT+X+79gfesbo="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.5_1527582237544_0.8680557579317365"},"_hasShrinkwrap":false},"0.6.6":{"name":"file-box","version":"0.6.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"252ca51de32ae29f789cbee88eaae36a64e9a5bb","_id":"file-box@0.6.6","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-QV/7oemkk5A0lPThPvxT7dQ9snD991b02HOJJWj0Lt2EOpD7iq0/XMWrhkbCzOCSpx79XLDT4PKWm224r3RTEw==","shasum":"e43f442d138230636b725d5012013e92dabba3b4","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.6.tgz","fileCount":49,"unpackedSize":110625,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDQ9XCRA9TVsSAnZWagAAUngP/193ZsaDt/UHi9WhHlkK\noTTMFjY1n9/KM0jLxTRgc3Rmm9cuZI9OICGKh97iaTsNLmN63vOg10FQ0aON\nuO3n5NRQebqZyTnKRzoRff8ICZasjERoK8xabNvGb9EZ3uj/qSJNExIPWN2A\nGQxIv38fuBhQqOxulK3EzdPqeaNYr+h5QMaQriuQBJuKn1VbPBtT4n5KaUPf\nCcr/Mcx7V1Tzk8AfyPdmj0eArS294Ls5xiENmhxRght579uxd0oz9SIrzFaI\nYZJE3yz59hgMeRddJUZOqYQq9FO94al02IQ0D606J0euAG+m1E3Ndw8W0bGJ\noCQHdR+o8Rx6WQo+2b2lVKuoG8+wQRSUTmj52KWXqQfqXN9tCuTIeCxx5dI3\nKbxwQivHQTCzF8wozR4i3B+72Gx2onj8JeXJYzs2l+gRar40e1bY7reOunxi\nBAA+Gtpe9dP3LJiE7NaZmnhoPGmBCy8goktxr6nT8vID3HPfb4sEgbyRFORS\nEPtjIWqs9numKS+hme2mZ75w6+z+Ny+38QU7QX3nF51xArEvxUw67GXXLy1C\nnym3veMj3+VqFuNu9wBFhkHj5yN0AGllXTs1cE/5cDM+MwlBq3vvFXUC173N\np6KTzAMxkNHHWAxzRo1OHmd8X5XsFAnJWyh8RSqTpEN4DOltLrOz4ev5iAD1\nScn6\r\n=EtCj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB2OjcdpSH+Ns2dmA6/R5NovPzvH8wz/ZKMWY9WZpkerAiEA9/gd5Cz003Um437/cPUBtOtWAIYc54S1mNln9RepNY8="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.6_1527582551124_0.20271157712820131"},"_hasShrinkwrap":false},"0.6.7":{"name":"file-box","version":"0.6.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"isomorphic-fetch":"^2.2.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"9eca8dbcf4f99c1ccb01012bc4e5f4c1a7a77fb9","_id":"file-box@0.6.7","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-csEprJbYhSsFZgGoZSLhQtK73YMk0ahRSsPtGkEVKaA3bh/gIj/8T1zOmnKjIw8fzedodhxACNGnMSEg7YJGvw==","shasum":"524fcccdaf0f268f8f3c12201e6c274aa2380a66","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.7.tgz","fileCount":49,"unpackedSize":122515,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDT3nCRA9TVsSAnZWagAA7WIP/3g9xrZkxD2llC8G9NRb\nEKaLmjNBV93DWl7R/HVL0cE/WurciB259sQGvGsSD5WGClS/yvwpX051NXRz\n2Ospy+ittShiXYFNTFjwWD/s+gAqqhDCaaSB9gZU9xAtpcbbVXfq52TLdx0l\nJaDAdzlRzvm7AllR4wNXNAmRbRP0+FJ2NUiQrSCQRHB20FNjbQiFqK2OmU72\nlLvSOGr9ipVipdZlmwMxd9vfK0uU2DJeuchDUZ269sqxy72HzMeny+RAelHe\nXVg8TxZJHFB6K9QXuPzsij98pbp8owjDBN3k2lM8TSxFwd6SNS9k4CqnlVnX\nRaTrQvet/e7FSh7H00uJaGLVOBQWc4wU0T8uJsa56ESURFiZxnsD8/hlsqnA\nFNjpy5D4aG1biOA3Uv4LQ1CCpYEZiaiIjWXw2T9kyws5l+WJkrfr+zIB6l1e\nhH5i/2BQ+n0bsipP05f7mQcafDtWahZS1gH3y7FgyzuPQBafzFA2W7EZx6ei\np3swY9vHnVg3A3NtaJ+2l4cwzZmRnTDnT4/D9UM3g55JO8y7Ac6MZdpvxpVk\nJtlTTNeL9XwrN65y8Sg75QmMCxm5jrl8NI7lNZs2+tb8g1bJo4EvG2Wlk5o5\nizr7wU1Y5yimwXzX9sZtit5kV5iukaQZGGssPp9EN6dw583vWoRSRT03ulH7\nifKm\r\n=sfCH\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFQaUnf7lbASR+F+GxtmkOpT8LAgEsmKuaa7k+qc/qQQAiEA3bLyutrju/MOPArfHFysQ5KWav+vFsfWjWrvcTYNGi8="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.7_1527594470588_0.03859956610676596"},"_hasShrinkwrap":false},"0.6.8":{"name":"file-box","version":"0.6.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"7488c9491069414396bbfe5da5f38d5701efcbd2","_id":"file-box@0.6.8","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-YbfttNM3xhYdU4Uk8ahManWvfAG9fRdVNuWdSTnmAbAgZz0IbHlayljrKaotHd4xOFii8ZNf1ajlVTTaVcOIwQ==","shasum":"0df65126f08c71ec30de7e986b76c791c9ea846b","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.8.tgz","fileCount":49,"unpackedSize":122479,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDT4FCRA9TVsSAnZWagAAFQ4P/RmFDmH3DGS0Ozz8PIqn\nG1e6ynRCVUwZ7xD/5AZoYNwn1ln8dvfRn9LW0ITUqP+Y9zWLBDZbbwyWyQTY\nWQDq/6L7a5BridK7ZFfMSzm5GGB1GeM/xIX45rl+XAr6K9fgxFWxytaEl0Z/\nC/k6GNK1OA3kHE0KcS8S+e/Jr1v1l3gQ5xFJxFXlgGXwUVG49XMc4DU38L6M\nJ+vOapQ+8Mu9nF2bao/EfOpEJxZ4lcY0SBCoAu+vp7l+wl/0g4P3sg4ZPtWa\naDsoy5OmJx9VnlsXh/o4ZEB6VfOBb3HVeiKQMMUQZmUbwgyOd83sAsJGmd3H\nRUAMXdqanG4zQKIEQ/kV/uRhhShHzbkQ6+q7tcgVWLpHAcq52WSATboGKG0G\nRSRbjfEtLUn6EcJ4kQ56vSnL8AHkdl6smU7Vmt/oYa1ST6qrkY2CFCJbfnPV\nOZc3djcRMShqBoFibD2bG4DOsqqSYa6zuSE/pdqpfhs+BWkbGMJUHKyLKo9U\nS7gUPFseV0fW4KaxoCJZyQDVhbsK7oholR6IUROcD/SzQrJPD5CSdunM4OEF\nIazujbMvO2qPPmZOin6RGX0S6ZdcqQEmcePHrz3ifWDrZ2F8F8hkAv1IswEC\nCSa+rsDFSPcSEUJZMUrDtDoVRDMToRX4RaJhhn/Wt8JFHwxvhv8GibnRACpY\nup/k\r\n=L6Sc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIExjY/VdkBQDyU/JIn0cwnL8D2JUkRJGtIdqpoLFmotbAiEAuzw3QGvshyydmalB4IUfcAy1lzlIyZpcmpIzCSkelC4="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.8_1527594501384_0.6976410596132132"},"_hasShrinkwrap":false},"0.6.9":{"name":"file-box","version":"0.6.9","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"eaf35ec7b6a4a67cf09d31a7971ec0eb995ea231","_id":"file-box@0.6.9","_npmVersion":"5.6.0","_nodeVersion":"10.2.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-pfPk/A9Yef7tyXxxqw+PzQ0ISI0x/1TnFiDyWWcR54RBmVmK1BjOeMTDFzCPBay/4jHYPio+aLdHT/YCk5Bx7w==","shasum":"8044360920f31706079209d4eb9ac0993156ddee","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.9.tgz","fileCount":49,"unpackedSize":122347,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDT5xCRA9TVsSAnZWagAAYSIP/A3Z/WL0c4ASNVbNdKsL\nngqNMyxxble6h5HWnT3pbV1y/UzRJqrYe6K2LQFi9AYpG7acLsbgPcAgwTz1\n+7hzYZLUBSt1VjyN/VCICidROs3mmcBgjDGZ5v8WgMLQx/s/XazZMYlkQrd9\nERr4kfRZhXfONnBKCjEn+j04YgQ7mD5/llYxc8FRokp8BB7C0LhlgzfPD3qE\ny4JJLskEvmnUJqRfL3YvcKf/TmwEl+Zzio1DoF7GxIV6763NiS2rybQ/Pbj/\nNuHFgWCm3uw8a5d+7K8MkeQvNlpQpaNptjDHWkf8iUUsa9SlEiL9T0CCpMtK\ndjk1NWCgIDHlEA2tB6mzbenTahOuFPT9h5N4ba5EdvM1B63Lmcmpl4nNPfdp\nvgkyH360yCrjOKq+USLtCs22vksFMx1m5hfAV0daAJcFH2hiMZlgfptMqF1v\nQN6FSCMZF4s20lg7SVGSv7DJkFp16Qx/b4SJA2NAHDKIqXr5BdXKq3uf2IVg\nW+Xt+BFfetSz7YWjffB1uhSiAMGCkx2StJg/his8BcJoBaMFDdIE3ovUWJj+\nh6uWtRNGEuIFuYrvmKvkUAV8T9kPKHp2em45CXrS1LMBidmPk58o8JIipAQ+\n+WLtalB32vVDvssw6RLDYzTfH5VRSAjwYGnrL77aehQa2X9a5S6QDKZ5s7UI\nrQfe\r\n=5Mk/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICLaLIf2Q694P+fAdvqMBbmCyJquuAaRQ5T5GP7PNOxJAiEA9+rKrmJMMGk2kqneSucpd/6fTlY5UodOQMxvTX/0tC0="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.9_1527594608989_0.811197201842788"},"_hasShrinkwrap":false},"0.6.10":{"name":"file-box","version":"0.6.10","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"b2cb7979a4d6d35564dff6d5a1496a51dd5c7a28","_id":"file-box@0.6.10","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-gmBTy6qq/F6qPSyXAhjhsT5lT5Pdp1IrY3p2JMDWQxhQfZ9teLlNvv27z8qIxP5hy3EwHql6sieHCccbK7TBmA==","shasum":"0e4c7bebc319f5000b552a5ef2b7a39ea3a3e7e3","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.10.tgz","fileCount":49,"unpackedSize":125736,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDZNACRA9TVsSAnZWagAA0K8P/AqYPFXLweNOLUHrWk/0\nLyagtIBGLi+Fzv2lDjDf2PUr5EMZMi4ClNIH6fNoFnmEj9WpOyueM/27Te5H\nzjVW3LF8id3iqEplM3tOaiuMezysb1tKF2V0QES8C/YDr9GnDTZmoRgbwcHx\nLJtE9ejbOSw3adcoZEpWIuS8xbrzIG0AOJXqkSBgjcqVNiGTYSD9z/D+uoMz\noYQEypXpOVSvhLEb4bmMlhhHBJ9xFaI+vL9cmzm0YIxrgm1xfZzOJ2dyw/5g\nGA3jkmyGAHSbi7OkFizKMlB/5DF1+PuvNj7T9ux3/LKSZezWYbQXjJl3z3UA\nCvveSzVXECLZyZZl3362p7e5JVxkIQuzNGbALDpmzEwcvQC7eSV0daa9av8y\n4TVZUQ3y1K8ombksnkvmsSYmr5orGWaxYJub0MI5pz2CJ/ixlNisKlO61oXN\nUmKtMkQntJTyTzU5ygjmSOej09TJmrOtKaClKXChSK14zv5ZSv0tsrEUcvgm\nFfHmKzwwzTP5HYgq2fW4xgbONlND6tnEbMH9SDrtJNGCDjryMP79grsJHexW\nobGxOYyfpKtUTGxgZjfRNfkGhzh8QuykYwKlzb/2JO6j9+5riVD/fuEqPV+k\na2w6e9NiIX14HJEits0nn5lumfJoW2UMG3mRKjTA8nrJDXTqys6bRGy35Nuw\n6OKg\r\n=utBi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIE26PH9j90pGZkQY1C9tcNUZHDYf1Gb9OAeDpWzCA+GgAiEAqz2mNbjVFm+XrLu9jvJ6xKNChFfxlxXEkDJHxDcoKLY="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.10_1527616319570_0.780948333471494"},"_hasShrinkwrap":false},"0.6.11":{"name":"file-box","version":"0.6.11","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"935d0e182dc31f80af5272230980e003895219ec","_id":"file-box@0.6.11","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-SN7Po4kQTT+YOszyERefZ5qtJ1m+3UzxQZ3BkfcyYc/VGZD/6OVyRyTSFY643Cr2qHN9JazDogFxVnl3HoVGVg==","shasum":"b58dcb4b8fe7f9b3052ed1edf37021ba425b051e","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.11.tgz","fileCount":49,"unpackedSize":125883,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDZwjCRA9TVsSAnZWagAAYJkP/1n/biViZmSoMsOEog6l\nWzz1mMtwFyK0S4THRZTrmXtx4iR2jDdheYRsO3+sa790GVJwR0xAHf3WFiTV\nOZ0C6LxYnnk5y1KBMmwXj0yXHUEkhGDhDrSJBrMwD4F95xPkbqh/FWF1fuvT\nMgpLTVSlF5AazJk3My643mVkZeNMET0W3Gof9IYA6zly1F32TmGLWC3dgtQd\nCENzGaEUrR1tEtqrQd5mIM1s1YbraWuMYszmoXHy4RdAN21xAZ7Xhsw9Y3dh\nhjZtn/VTXrp53bk91c41vQa6EWnfu/el6kju7U+CVBYP0lJmjKuaiBHfhuDD\nDXLSOtpcWlPC20X4sFwRxOW3LhTwvF9stVHlsa7jGT1+riw8n6eZr0DWNZSo\n7zLlP38vOeNFSgTIKazbyaDXhFE5gvf2S5ZQvMhmejBetAkqwTOBU6WtxRSF\nbCT9+OVhqCXRHhs0v4MdOMzRuCfzGQE6mNiN/ejcINiTOpPk7yCXgaz14sui\n2bSY0Koqi7metRDqLv+UEaq26ivaAxFA5ZjjHBB6Waa8v1BIbXlQUHagsdp/\nWVEHWOxpaL0QYq7Ky3G274Rbz1aRRfqdWVB/N7HoNjaD+/3e35T8JH8EN6KA\nlnDy4a6LG53NhbLwKy4S9Ye4M0OBRawyHm+2CygL9Smh1aFLLOVoeUXf/Nco\nmYcD\r\n=S694\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDSUQgBwZPMvxzzsmxE/HIQoRZPJPSQ2bM+eW5KKLCLVgIgFPczK1khj4DIvLotBex+Obt+nAexBlK4jlLUkx7MILM="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.11_1527618595048_0.07834989979661433"},"_hasShrinkwrap":false},"0.6.12":{"name":"file-box","version":"0.6.12","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"2c8d2cf30f77aacb6e7982c901b89ecc27bd9d8c","_id":"file-box@0.6.12","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-IKfMgR+Ez9Fg8o99JJS6r3YpmUOK0g5s1inh5X5oKdqNc72tSsoiVdugEIxaK1d7nA7OyPCLMFIbLPeZilV+tQ==","shasum":"9f85f03f84d59bc6424920bfbc3c8a5c66c546a5","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.12.tgz","fileCount":49,"unpackedSize":125875,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDZxsCRA9TVsSAnZWagAAe+AQAJ60076QTZmKWlw15jq2\nA37KMB+slZi+ABsg+UxVNP623f1qHESdbzPEbY5zivGvdgn6sdIES4V0LHk5\nr87aA0KdE8Wq5exT92an5Ci9s7vyZA7/xKJIcYbB07vNRhJtsNUBw6GwWqrH\nr/lPc4atnwDoPRcQ3oNxiSsW+HbQwqNunPBB/SdnIgHi05bTMg4o/NYP0Nbp\nIedLyBaYN4307We9Q/K9RMgNMigFeS1mc7GLftLy/f4s7Tl8+ovxQNQCGR70\njjsNIec0z/h4uVS/tmi0jz3BLKVMoLpCEBtpNNoj/hk09Y2ejx4Mfik6gVj+\nWXlyHKnggQ1EXRP4VCsgtN0RtHXedliKRFO9EVT5yBjuy79Xv09+IpTiCruV\nKGA+o6StSlg6o0vEPex0X3la6ol2zv6blc7UwVUemCWzO2xN/F4iA+roZ+ZG\nEYkoex6p2DP4UpvTTTGISxuPpWUYCwCWSMvg7KL0kKYednsYvld2OfLzJp8v\nBInQnYOzWWNnUeJnR7c2VSyI7pn/VKj6pQJwiJVRL16q8B2l7jJ6YNC3fTFX\nko0ueJXZfk3/4As5x+yowq3tpxd+vIV9eylR/dG8j+2AVWn5Zl6eK6MKn4iy\ng8nM//7eMXvlzeEXZU5ZBS7mhIJqy5dPk9WySevwhDyre0wddzkjvtzgL11M\nnxhp\r\n=m+tk\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDW2dInQg+igpQfaFyo+owjH4ylKbpYDWFJ3eypcvMFFAiEAqzx1dbe39nRsnY57HZ5W48qOR5QucJvV65txhQlICzQ="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.12_1527618667730_0.7138528785288589"},"_hasShrinkwrap":false},"0.6.13":{"name":"file-box","version":"0.6.13","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"505d489a38baa5143fe3c4852e2db2da974394ed","_id":"file-box@0.6.13","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-EwE/OIIsnuCYWDhTym7KxYLq/ZaUmEOgGAJ1KoyhgeFNCOpgat+38dFR6Bf6OzOzgStgM6cu7ClbaGSsKpipAw==","shasum":"c447d168a4f8362ede835c567112397cb43fe072","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.6.13.tgz","fileCount":49,"unpackedSize":125870,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDZyaCRA9TVsSAnZWagAAnYIP/A32i7P4HcpED0pMRpQu\nImGr0DUr9vnWnWkilhzdGRlPmmDWPq3gZyNMDBCXx7AWNoJpiblNBu8rFeuV\nBs1Fcne3QiKj9Wxj4ejPYezDQmdaSfPe2tsyeJsHb904X1/NdvGC7g6T3ksN\nIDyhS6Z7RD2/QryNyxSTsFMeLc51dwLJhHvpS1PilAMhILGj3sgtmi275QjP\nRj6vDlIo70Dx2okIRUixokyTX2CnMELBFwc7D1o7dbTCMaeCVTopmUpy9GzK\n8CSKPaXTvoOtIfoWCMsNGxO3DFr0gxt+/5AQMB8XFrlQ3qqQUFyDot04zqMP\n7DxPXydJgEnEbZGbMhOuGPBtNKUTQiO1IBB/IvFDn7BHQAHW9kbKAqvkCT+O\nqH4A7T4d7N24c7DQUQR8fIMs3otHRywj8W3GLqTe4gT2Ik/zznaqqa/H/qcU\njERJEWbQpwFX8svkdf33xKBc9vkAuN9dyOHlRYVB2pitILDi2BZLNyHO/yiJ\neeCam1MRGsnFFdyv/ILok+U8ggMNmA5up44WdTknbsPZ+6zb8CbF14IVSlFG\npUmpJQiYkz1eNRdJu7HoMKwFAgBkxPWtJAei7wV8JQ5Kv9bkpRHzwAm8hJvv\noyiz6omm5MH62ear/FAJnIUmnLAf63i6ZMzOtvmMV9mtOLnlc0YkSfeOS/5g\nkwMe\r\n=Blnm\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBrbiJ6S2CMVBnWfg2ji+EAE8kxkoM21QqgtCOd2a+IwIgHPBJIQAsa/k0xSOyMz/Dn9Cd9PRIFN+w6mI9rmWJWN8="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.6.13_1527618712934_0.961803466907091"},"_hasShrinkwrap":false},"0.8.1":{"name":"file-box","version":"0.8.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"446bd510fbdf75791fc9cf1a8516556b978fa9f2","_id":"file-box@0.8.1","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-Zgq3mqTTOisXKxP4oPsRQDJFI4KUFjlXEq1aFEEF1f63+upDCXBisGSyCV8FJAQDnAEe2kVdX6IAMfYWgQ1AkA==","shasum":"848b5ffcd8249b50bff379d2069d8aacda10676a","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.1.tgz","fileCount":50,"unpackedSize":134492,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDjl5CRA9TVsSAnZWagAA2Q8P+wU2i3uzn3Gt3sxMT9ru\nOMyZCscYikIQv9lmCiZzlOuGEPddWnTMVeAuAOHe2PDkWVSLFFk5kW5hsfr6\nHN97F3Cl+4d1YOBnWy4aaxzmYefGXbg54wYWY9KgK19zlFrHlqvIJ3iHR1yl\ncnaonjI/sotMWQsTqS69rVRH+QgFupsb68EjxVVw3eAGE83ElA7r9TCKFAr1\nAGb9xq0bE+zcErc2eEbkWKEyp3E3Vtn+kKx2pdDU59u2sYWrqCzG9IG238eO\nXkG14cNSmVjkzHRMX3RylhhSc3snEdr0WxpjNz7pGxjEmDOGSmCM9zuwgfNg\nqXXJ/fRh7If4//tFJqt3qir7eWPeki3VCU5S+sgU/F2Se/vyifhQ60HIYJ+S\nqzdGtfTFXua80DmjtfeM4bI42N9F2fXwrYf2Xoxbr5N6wAf6ROp9NiOTLi/m\nnT0Gjn8fGnkpZE914vWuVwYtXiL5+Ms0xe4+Iz4UgZkwzQk19Ed7+2InVK8h\nthBYE5bpyVhee87MF3SKdtgqSiNz8kwn5wOSA2yylKm1dGjnKCefsF0ZZrVT\nsQVtYM47yhNd7N3LU3lyctkQ2QtIoEs0TFnBN5li5wcYYlw/yXeYh/+h6zyD\nCBcTzIWmilNT43b2ITB/s/7m/fuAxqTSACphnnAm46NIZg8y5oYTgmhpVpnt\nKmxB\r\n=cd/X\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEJKJDFqEy5HyRvLz3BJ676IVqx9MeiULFhnb7U1lMeqAiB6pe0knpOu/s26w7HuijCEaxXkUO/ExTggjIBZxZmThw=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.1_1527658871780_0.02304320836610918"},"_hasShrinkwrap":false},"0.8.3":{"name":"file-box","version":"0.8.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"44c50967ba6412d6d1921d4bf418fc70b9bd066b","_id":"file-box@0.8.3","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-gmgrpqu9W43YYavcO2shxp86oWywuGuEeAbgL+HiVwh3atqNvGOvszY6M65jBCxk1oi4dK8FuZR4bOONaYN8NQ==","shasum":"38994d999fd25eef4bb3a3efe35dcb7ed0b1aa90","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.3.tgz","fileCount":50,"unpackedSize":135194,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD4WvCRA9TVsSAnZWagAA7EcQAJN+vsV08c2HvIJLL0U2\nB+PjoPZmpUbLsA9ZbwWjDIDbhcKs/C9JCx6gdHiuEALi5P50wERDxp7aDy2c\n63psapPXnJeD7cJB4MfgKmqBoMquu0eAPja48jfGmGkvoZL7VHJJLfTYLD1N\n4y1oCRJzo6SyfvpAcykvQ/kopR9ZEvX4qBvPWLgnyF61MlVqg5gktAR5Kgk9\n5cJytOJgTdcEOTWbWtPSon3fGKGPpcw8D9P+CIdUWRjdHAt9IbhcENmNJkLX\nwkz3iF9ytaJoVuqeXUVCeiuBkJd639X3kCSZ3t1mJMapSdSGKajFXUwiTnEE\nW9utaydilt+6Bjij6jq4zCPlFqwKqsYduA0YDa+RBg4XsA2rnmCMFWdDntwv\nrxIIHlj93eAoW621vpeilini6rKROmGKNPKNjwDUtorPVOewRtOEx2ADqsHc\nkZGjqHxBTfFDJDZGu3Unb2e9gVe9A/X8YdvslYCqqDMzOcAZgNo7c2oPo36T\nO8gDTbvoQOgOBCgRu6CZC2lB5gutSMxKOLkNi+2/UCAERl+38IOXHyOsItYd\n58PG6xTmN9jfMB8Ms8md86FhMpxUqGplzFJhgixDATkuqqWqApTcQiwnXqgn\nfMwSQ1obOx1NEys5P6s4a79D96Luwlhjd9ZWWitj3CE2jZm1i+nIA6h+KGnX\nePTp\r\n=aitL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDBD6klC9wu1WjCdz62GdtoKsmmkdI02AOiDNMw6sZx8gIhAJo3PHwJSo+Cc6hmJX9kIY1G8LT85G49tam5r0q8fPAT"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.3_1527743918524_0.2677980403417224"},"_hasShrinkwrap":false},"0.8.4":{"name":"file-box","version":"0.8.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"2746ef94ff0c53daceff88aeacd90ef22c855c4a","_id":"file-box@0.8.4","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-V44fHKnWVBOKuZBIpNIP4QMQLt3nikBUNGLYCr1s2HFLj31yDC2oT/eXHth7agnC5TQ2usxaqztwlLSK0hvTRA==","shasum":"b200793c82f478f9947ace7dace6ffbc5e171f19","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.4.tgz","fileCount":50,"unpackedSize":135693,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD4dECRA9TVsSAnZWagAAw40P/2UxZLCISBV4T6B1FHjA\nop9efvlobwN73Aq3wNYuDhieclifPVsaCzPDRrs5AQ+q0/Mxmle6YP39Vuy+\n/MCR2239p6vrEXRPmhEvxTOdOtcqhVNq3MDGDFmT33yfLQDyrqP8XtgSgF/m\nHKEDbP0FcQ5My108ZFBO3loyAG8tssNLnlQwQzLh2U+oEnIaJIHo8d41W2mF\nyx97lBUqnGCkIwLczIpLoQzmJbmn1+3S8UNqBZHUYUNXfTHWJN4jqlU/iAi9\n9WMLYPkqJZEZze/2M6iB14rdEEqrc+0WX4yK/sPH48XbvV06YRinKnHHJj9w\ncXvVIGPgfI9NFJ4+Du3aZC0dVBFpYuwAMlY1HsVoVGSfmFbVsx6hloCT0PwJ\n04aY/cDM0nE/LTyZqygbairYtgykcd6S3ArlW3kWLePX5RrKnDjscLVJkrGF\nBJphUDO/9tU/JKWe2gP2+pijDoY+jnJ0hbqxEPzqzFejYIhIHNa4EMuiCoB6\n2nsStmeIcHOcT+mRXnRC6RnmemIBaNQqmxznAUTRKGXnoeQloBQCmGFu4Bcr\nDey1XBC6DjF9+HDJq9BuiPOlBEpD4TrCVN9AjraZdT6bzkfe/r90zrm8eRJu\nifh5kYNwbCYcKrqkIdZKGqWRjG7zHomR6LMj2VI2UhW+QsKVrp60TOVXEjop\nwFtS\r\n=NvWF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCBZB+T+oXSaw2wFar8pT/CSxisFbP9hfomq3KFCPJXbwIgLHIak1JCSLzEfz59Yxstph6bm743uMtJ0WFtvF9yj50="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.4_1527744323647_0.33377351513617826"},"_hasShrinkwrap":false},"0.8.5":{"name":"file-box","version":"0.8.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"f2dda9d5beb61998d65600cb081cb60b296fcc90","_id":"file-box@0.8.5","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-f20kFzOLxLluKtmXzSHfsw4BExLGx+ifzWiIQy5xESzPJdFtG7rVvHDs0uX9oRQIIpuIom0Yi/5kZEzc8M4azw==","shasum":"b609387c161ea88a548e32059e0067e6b28a6f31","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.5.tgz","fileCount":50,"unpackedSize":136670,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD45QCRA9TVsSAnZWagAAxqoQAJhGsWcriBaG2XBheZla\nhpEH+aPbye0T3jKRB7pGR2Z9sLOfSm9cDNqdb8mMyVwk0fpeTyPC+4KYmfLJ\nQyDlhs/Qd7Iux4ulh9Rc/EhMtLMXiEcQdX4fmdhfYcJcSRBZlPCj/1JO1CfZ\nsYGC7jpCnU+dMi/7UeWY3pfC/0getuWqhcVewfzg4TIxgDpEywmGnoMiHgT1\nKYPUIXRuZ9I1O3o7/afjdqPl/VUW0o9dI1K5e+UJ20VJoMbhA5LrBg2U0hJv\nAyg43IYOWZ/a7CbIsA+1vEWhvBNIDSZJePKenyeuCO1GX3kzzl3UfiZ4he9S\nAB+28MxslIRCC1yacoZYj1zJ9i6durLZ/VJaZ6wAN6NqeJwKvJ7+vstLT76d\nuiP3aeUgoFU9JG/Vu1WUHLqYJPYgkklbzWDu8j1xbK996J+aYPu0q9bpKFnB\ngmzGMrk/ZVf9Z3F/zOshF2uhwDFlK1jVLzRqkGo8EG2f3BSDDfPd9jM2HAOL\niWixg6waQdYKcTBtTg4zTVfrdxkq8y9rDprqJIk7TV3AXvSjHHuJYvH1fhhx\nM2tJnxjWFauF8EJqfRd0rqX6Va1STa4DkTuMqw3MyPbFkC6WsnEWb4/iN46d\nQY654KnZqkZGZtMmTTzO+OcDFTsXAgax92ztVGL7pPF/1cWpm3CuRkLRxG5r\nzIzo\r\n=3nQp\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDYBMM3VODw+9Dw9vLUT53N1hx1MH0XhlQ32jcV5VQs5gIgHOWwSkgUKm67K476lcPSI+TgVcbUH9dR2eMZGZ7ZI8k="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.5_1527746126973_0.6735794911952553"},"_hasShrinkwrap":false},"0.8.6":{"name":"file-box","version":"0.8.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"e6eda9a2ae2e9ac31d93fef4fb880c2ec9c9f1f2","_id":"file-box@0.8.6","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-D+rDaMkPKKNlDDUJw7AKY9JRu7qdiUmyAzIwlrzrQll25OFj868GdugxJkL3RaMg5Xp3FgbOTrQjZ6RoMTPe3g==","shasum":"906635d950804723aee359679290e7bec5334ed0","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.6.tgz","fileCount":50,"unpackedSize":136807,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD47WCRA9TVsSAnZWagAAhOwP/iQKqH4NlmVo5MV0M0IO\nzTC9BpslANOxctedELH+I1keoo2b0Pf1KtX1yguqvRABXbtowtF9BdDHwvgT\nWKXg4QCdfly3dEVlV6kI3hASf9Qx69j66LA7cvAU8nAjc2euOKoOYydFhXY2\njKq2WMWAFf7QXqhsqreq8hqfbGFBafWXoZxWKs7mg09ZNGj1Z8rfCypI2Foz\nBBDqowRVh2HGNC9r4eAzNAoiqtggYiB6aj06IjsvGqwC7pk6K//JzEQUu6z5\nH+bjwUuhQ0+aurR/okpyTmhsL1Utu9ZJfL7r4IUTWHCsgtgjUsPOESimtW8Z\n97JiY+bfIIw8Ff+NtYmc/mw3gcOP8hR/Prbeo/5MWLLYyuiVKKJ3IR943GQW\nhDlH0yJVlspSeXda6IxvW7jLEpdNqPT9I39gjmWJEZbV4AF2E22sP1+QahC2\nLmq4d3t9EMIeUgpSjiIc0YihxzakaeYrk8EVfj5vmJoFJ8N9koHn9IjPaBPp\nwn8F7MXW+wEmkFUOuZ7md+v3nqKTR7vMcCBewrwG3RT/8Y9OzNrlhSNqfReU\nZA6/uBU0UYzGCyNMFo3/m017WPhFLJzGamHEdDZ59M6per5aQ91DlqcIelbc\nmHOlDO2fQ/xfmb+ZIOK7eGXZZfAmKam+vPEFHXDiYl5TH/6aBW9MjEOlrE+C\nO4Ah\r\n=awJW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFkGHkFb9wAiZqHwwrA8bHGIsXxpA4HksfsAj/6eZOyKAiBB8bOBZVkGdA2ivYHSyiWhm4M9qkKSgRhFzJY/CQwN6A=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.6_1527746260921_0.4641049297844291"},"_hasShrinkwrap":false},"0.8.7":{"name":"file-box","version":"0.8.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"3d3a632d2710485d923226c4da7efafcba8544dd","_id":"file-box@0.8.7","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-llqc0/gZ+Vq0/r9qx112dPOXUGR++o2Vbi3aB5JGUfUzhQtrnAmoFoD1lRCyMYamikcOEDyMHKyxIEbLHIDyFQ==","shasum":"eb2eb1437e39249299eb9d86947a96bb24d1c5eb","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.7.tgz","fileCount":50,"unpackedSize":137602,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD5M+CRA9TVsSAnZWagAAmuoP/1XX3A2T5io1A4sj+i97\nCuA2dMGc9z3PU0YqdITbgpwiumFTpp1zOAiYpkbWvSB1bmdLy2ijAg4tERIy\nMLr/0LGf9u2Qmm6ZnmNO7j0TmAVaEDID3SMCwxWkdywTlR7tYWRBinWdNAu7\nV7cMpCMpJWrDun93G4grtj9GfMga7zJK0iXByv7LilwkWfIb+psQRLC+awNU\n8d6DpiqWiuawZqsxe2ezKyD/Bk8ZxuT2da+FR82hJnbUqkWX+bMkoUkc48cy\nN5dPlcBW22PairltIq45W8C/TsoqCP8EV6U1bkh2HOPy1dYHL5Ba31VomC6T\nOQBBLGgRDIZgPnLlqAuuc9AKBm70CmUy1VMk6DqHyR6z5AwOk4CjMpLbMbRh\nfHwyxrZ4CuuHH2pyT1XNIdOIjxQxG8II3jL2zDbPxMllFF1RWEopQGa4mesO\nSeB67Z2G74HQwcLjBNX/AXV6N3oY+wJFTEqpptjb4hw53fOF0tGsJVEeoeQ0\nXO/FT8mQKga8ibwKv+uoR5BQ7CoT9a4mLwalC4gYpCobTozfh4AYmxlS5N2o\nuxy3h/E4Ul2W6oqk8KYW/xTUPhqJ2fH1ofiyuvo52qclxRhfnozi91xYiS1A\nneACFzB3nXi3TCClw1ut4c5b6SwIon8Y10mYFTGbaZdL+p3UYF4pr2bd7T12\n/jya\r\n=uJ/q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAZftXjd4nPM8Wt13Q1aKB5FOBB1U6qJxEyxX5ZAR/ExAiAIjuf2pPNgzqUKOAWl3DNlN/HLY+wr4IVcWcFSsfw07w=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.7_1527747389318_0.14642449785985834"},"_hasShrinkwrap":false},"0.8.8":{"name":"file-box","version":"0.8.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"eaf138dbe1c6e84edf59f70441a40bf9231e7bba","_id":"file-box@0.8.8","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-Y+kReXjKHGIWW20E7eWdidZkQ7BlQ2B/tCme5nys834RW3aae2fdxiQWBRTm+7YKP7SqChI4KvJU07IlIQu9AA==","shasum":"60b06797e8bdd04e65345b7cd0be28f534ebd8e2","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.8.tgz","fileCount":50,"unpackedSize":137602,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD5OHCRA9TVsSAnZWagAA6N0P/RgyPAwjlQ95EQQBLuXy\nHg3OphjH87/JUoBSa4D/2+h+uSmfGxSHZGtVRt+zPAT2yGL5oWe7JaodudKp\n46tfbdob5a5/QNUW3wVblU1sb5VpAg1dVYdbCkN99As6lPYBWYgbr90MEgd3\n8JkYpHyI7Vt9aVYbvWogU3yePy6nb4EaQNfLHoBvO0GPX0GrzgNpyLJMNWwF\nNHeP4wMt74zU29yriwJl8CYwLPO5R8qLSnc6+TDG8RVhqi87As7dNjcK4a3Q\ndlsAG4C2jS55WnNPoUX0KwWOHBBzYg+CXaZpM5XrVMcfP1SMNW10SWvTo7Zd\nPikuV7ka9r+iK+6BYXavXHzLEUkiO4IakWtXg9+cMG4ZZuTM3TGTIjbIcr1i\nyeLrhc48SE7FHMWrJk44x//EhGHikTRyAD91TZpjbZtewl34V9IX2Sbr2W6d\nf2zuwsFvZxw1QujcxHmrsx5KnB7Gi2aGw5drrIK+vYjaUi408LVca8Hhzvkg\n7/bIwk8tBMJmkHFirnhD48dHKdGr8+LmUbAcnjjz1SOYGifwMKA2RnKshowH\nwpMoMKgA1Pyhe0+N0pOjZO4tcyNhJLCaZ5bdIZyKpQ3NEBzgr/6LYr0l2ZIL\nzd4uFQgDaLQwb/WqTkaaCuUDwmCIx9OrfwCqZ/KL/PvW7X3EoLK1GJZqnyel\nT61R\r\n=wFkj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC8hXMmcdateRCxhyjPF21cffvuIrK2r8uDMuvJincL5gIgbQjayYILmg/dBT1yCmp7IcQg/+XDLjbn4jTaxnv9V/c="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.8_1527747462621_0.9919378887815395"},"_hasShrinkwrap":false},"0.8.9":{"name":"file-box","version":"0.8.9","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"d04ee54d42152913c8de75e9da80bde44bfdf2a2","_id":"file-box@0.8.9","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-A44ClfGkazbnI1KdiO4LxMH6fEb5wa8PNiHFZrokfbxHOXlxbkP7+jx7qPjjdmynxzeC7f2AuNsluuR5thfKCQ==","shasum":"ee33e1d222ada88235fdb784283195d44cb4338c","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.9.tgz","fileCount":50,"unpackedSize":137589,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD5P7CRA9TVsSAnZWagAAC18P/33YDaJE61AixFaphyAX\nZpCDMWI4t/VCeAf+WO89EgPnNjVJyuxQfpS0Vch/Fpg+fsSIjQhkUQs7L0Wh\nv8hY5JEtDYQbVaEQ1ewREG74xcK/Jt5WTBI2Aq2MqlWQICA9SYqtGDpC/gBw\nmaqYKI51uJg7aU9/2q2xv0+3r/6AXMpWwVK2VgWROpU427sM/b8hfxK3hzCr\nzMIeWkjPwQBVJGsw11p8JFrCX0aX+7pSLgHwgHO1D2muFRUNGTEH/6L7UBfv\ndI7wPQ5RLQA6DsPjtTMw/lpK6ANA6kGnmUH2z84GfbktleJbvtVYwkY5Og0N\nHDEb2g6OigiEzozG1gPnBQgpdnM2mftymlAnBUjcUG8+LVpFdZprCmqR8toE\nxU91bW9sBWMD0oGrE6mBM0LNTVSujw5pHBi/kOdx2QMhxpLSNTIrP9trRQIU\nHfjYHx9YJA50ZqqOtkcq0xV3ctL2lQD18PxBP8+8uqaiCpxtPvK5RmyhtlUm\nyXF6WxnwqLhx+E1zlOg9ZGk932T2+RsEL6WjvgAq6otyrG5ugivg2QnDyVjp\ny4WUUki+KbXy5Z/B7bnLCjkEiMxKx00kcqqc96z6naliDgrlguYMHtETmYz9\n7/gAXp9Hla1jmlFwpd8M4ewBytsuLkWCFwch+BwBT0gIamoGwpbMZj4MZ09s\nG7fa\r\n=RBxx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAL93o/WU7akkQoQjQC1dMqKgDUb3V2qhXA7H0LzrIVBAiEAlmcTg/u6mo4S9bxLwZ6Vb1ZRmG1A/lcdkXvUIg8aCvU="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.9_1527747578721_0.5916645801735254"},"_hasShrinkwrap":false},"0.8.10":{"name":"file-box","version":"0.8.10","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"aee78ec4af1f67529d6b9ede0fdc4829cb345a63","_id":"file-box@0.8.10","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-2gttNLzjkqgr9/ZYOmBpcIlZ9Itba0Q+COt3LvPcC0mCuzoVvcdniuSyHRUhVdb1hof9MN8TI1B1Ks/3dWOpHQ==","shasum":"7a3c1c444e3f60706397f96f6a267aaea3992aac","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.10.tgz","fileCount":50,"unpackedSize":137689,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD5TXCRA9TVsSAnZWagAAlTIP/0qBCLO4fzntFbzp/4T8\nck7tHTpZfah7anbarpkiWt2POOPd+wBRiB/AWOTipZs995DPzAWBRP24bf8L\nQU6CU92Ao/6OITDtDJHqDc1fhNak6o71cH7/McSZViSj1gh3hAHtTge4wwyu\n8/5mEqEdLWb8OcFtnlioWRI/gEql6O9kd2bBfrwa0nxHD14GJGm1g9/tRuxf\nWm43KxdURuefGduihj0fP+3nW+TZHXoO4znieeoguaFsuGX4/OLbWHspIpD/\nRUHpb9jeLpufyf5u2KlmR8P1HJxBpJC8d06ba2RLBEm+TlEUdtqlryeNg4Ke\nOYnXsIi9rFSmb2Gj0zD8m+k2ckHxqXYhiOFtRq3cGj7F0F8OMLM52LDxW1q8\n3QCaeSny5183/dRcnIHazjbxMTkrdi0j6hywCm419/ttR2Shb+68r5ayGb0L\nfmnkNa9y7+WHHRcdkuepgNMHvX9q4tHibgy9nYm6m+aPMuczn47RgudT9lHZ\n4mUYL99VK8YYxdvq90xcbXIOZsscsfYocYc9kmbiMD+s/6kLcCJkiWTnRx9s\navH1WZrr1s30XvZJAniYGpi0uzspN8RhqtWXVVr39pWuV8CvlL/aviHQ7e8W\nDdrLnkfwXNzA37mKVUqdMMuh0+MaBgwgXtMg4YjRFtXsyKJOlwww7dj4MANa\neWfA\r\n=PGPy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDLCd1vXbJXN13rSwBwlAHufYy9Q3dW6VpxqJgY3V1b0wIhAOmPd+7jlHDAnIXDyAPmEOiU+hOEt+s0XDGwvRmNedXa"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.10_1527747799080_0.8035897968632837"},"_hasShrinkwrap":false},"0.8.11":{"name":"file-box","version":"0.8.11","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"bd914ec617b4d28ae368c2714bf59576c3a83627","_id":"file-box@0.8.11","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-BrGeWjvJy17UkIno/vQp7RPvjfk7mMn8H6O5ZvlqKSKyTgOLUgnBsliFLc5uqqDU08j16RB+OPHSm5j36DJOlA==","shasum":"cf7c6f53f9bac6633fc1b48488bc6ad202261bef","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.11.tgz","fileCount":50,"unpackedSize":137698,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD5wsCRA9TVsSAnZWagAAt7gQAJLvJKIwRRDZ9ht1Ysfq\ni992NU9/Lpj/GfzyO/ZWNV2VkKhZiwv9fFVfDuoY9MUBefmQOBN4vaepqfd0\njScmtT1unpgy7rgs7Sx7rHqP4CXi1GQLTKT6y51IAud9LKzhF4d2BU7D3r/x\nm85aaSfeuow23TGZ2j3nHz7TQqmyjgzW5Fza1nzPJv0/PslKyqIZkBxKgJGH\nStbjmQh2azEonxlmcuOkm7yPZ6bO6Hr0Eb5WB8f5WOdx6VLz6EIBLEESxbgT\no9XzjYpVhFdoLIrs53YaUFZTwDtX8oWopDMZgXNO9M6jCUpHkbezFEfhHa6h\njLALgYy3OyJrsThG/GamjBejn9QKmrYsAZDS8ZC5DBzFWWfrVqexL7Bi6EY9\nOZ1SNatF8et2YORw1LivAHCwYSiRldZPRPLz1Hl8tviWp91rb+q9G/aQyOMJ\nMwdsPdkbsypUSBA6DhsfsFVq+Y4L0H8QPEZLgg8ExNnAMA+QrfqNgGSoMhw2\n1vcTB64Gx3BaKcyL9DEJ/gterbPOXejqyIsfqzxEcQlykIavT6V1FUeZmsm/\nEjiFBhpkyl5vP9oWFQMKspoVIw6F62R7o2YaR+3Z3MS20BP1xFK2QcsInYR0\njJlQJShYYMAYhCTJTos1c/oZvFyekEQVzB8TdMXgCsZqg+6N/edkL25Sxz8n\nUixh\r\n=5CnP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFkgLtcxOYMBN0ODFoS1dd1UAx2gTOX5FoXEkIL55SYbAiBSh+3Y6RFFqpA3LJ8wgtRmELZsPUaSGXNyOJdXYZjuOg=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.11_1527749675552_0.463481792735007"},"_hasShrinkwrap":false},"0.8.12":{"name":"file-box","version":"0.8.12","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/node-file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/node-file-box/issues"},"homepage":"https://github.com/zixia/node-file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"0f92d77ca41c2064d1d970454737b0ab1ff5cb5c","_id":"file-box@0.8.12","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-t2D7pJZVL5ABJbHlY7kIhkiwJEKhFdNgjoKgpzNEwQQT/ugj/z22BbCk19M7RDJAGOPft0/UsDWpsm6JvTpuEw==","shasum":"387b57643cdcea8b78b34e1e05192a30ec68ecd8","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.12.tgz","fileCount":50,"unpackedSize":137712,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD5ykCRA9TVsSAnZWagAAlrwQAJMoqCh3k9rf0K1O5la6\nC1Wpr1jQuL+TdKUIZSv8UQSGt7iobO/jigw8J7VAlwglurszIsIgLtNnPe2H\nNBaHPRTc5i/cK+v8whPnz9geLgqgLgMkvbQ3PS0v2ZuSyAs8h1Q68qbpCRNz\nqP7CBDF7fmGHnqoDlk1+/6ui4CUiRbr2DEdhcNNMThqvWCZjq7Nn2YxdSbPs\nfMWTnOocCDFW8MAygGfRKtoSGs76q8dGYn5pUVM0/XUqJKQebTHN//XGS2EX\npbo9fGBo4JvogF2Qjf7/cCH5svowNLkqHwQzP7TUTeMwWptWRrlOmjNnUZ7W\ntU7BAhydCBuSt9sEzmVpQbSIHpvHVAm9hbyCwoqPjIx4lgIsThEdRxEb7PqY\n+wx/J5x8sZxBNPCPbz2KFFcIsVjrG4fw5AhzuXnX14s1bD6XxvzyrvCm7Ly+\nKPHTpPEf52f74hICEMCJ2LMD/GVuZL56X7b4lsMNdrJfF38o2CC72bj7u+1X\nomH2W6xa99KmvWx+BUuoWvZU94yiemY3tCRyF4jW8pqJrmDWpidjJXD5uoxg\njEB2E3fPponEb0QHWwt4ezDio9DH9tXF6R5iqAK5nh68MihGdQgntYxOpEy4\nFECUvlXNnxvQB26bow2e8LxwogHSH9LyAPNCJxWKpc4N6wPt1Qojj/Z56V3k\nnGV2\r\n=tOAc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD0Djf4W38IoOEQqizYs4Q31Mw6FJ38lY9ffZctL8Hl2gIhAOE/zTvhDpiwmUaOSdu4+3vvBqEmcU+HavwnJJLVvyUP"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.12_1527749795628_0.5233041906851761"},"_hasShrinkwrap":false},"0.8.13":{"name":"file-box","version":"0.8.13","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"2d55b83bd00e5101e523f3f64286c183c4bc817d","_id":"file-box@0.8.13","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-fNpmRi70itD685K6iCXsXqTMqjp4ZyXvGvjguBt1ivlEG8hLKSsuknOG8nVVGdNdSQnrZFdSji4e74+cEy5LAA==","shasum":"5558a10a8744f7402a5e3123decad73cf958ee65","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.13.tgz","fileCount":50,"unpackedSize":137677,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbD6/mCRA9TVsSAnZWagAALAgP/A46Ag5cHibodySy+lEI\nDPaHtUXjx8sxG+pyvUlMVusOON5jB01MthpU6+pO2Da6qZtiZKi2AwN/ePxC\nwMvEj4AVwWRCJ0C0tqwBXk07oXPLDT6/Bca9qtYSwjqOO7ejAFGfsOMPciav\nRfuCRsb1nZlCDGx712qxqT04BIO+ZX2poQiMXfwam/q1Vpx0Q7Br5GShLBs+\nrEICpyOydFjFP7UkZlAoKh8uBeX9u4oKejj6cT0wxly/x/YjLqDBbs/HSQ1S\nlLF4RXge4FeYc8ueD8U7ia69BD0HqT10sKO+Cdh4PUOlLgPxjdRsU+0cM/YB\nw9tMrdNARUY9dRmZaDgcQyOdQg39dnx5IcfERzkL1cfmuEIA8sAvfeSAGQi6\nblDfKlwKtARwJyOuw4+IqqZ8jz5f75VaVccGyDvu/2pkY/p8PvJ53B86WxIx\nW76GPOgbxSlXYk6kx6Jkhj2tOtqSu2VnqtGAsJhExIpi8L7eqhmkGDG2oZAL\ng/q0aISoGaEmMkqmrt6GqJ/DnLGudrbaJnoSHpWmKFRwzUyAiJhph3Fxkris\nC3MhghHaPODU6Qe6Ckl90qOG5+RuEMPURKQpeUCgMSSgm6IoXgKefD9bww15\nRvXgq4UeaU33DRyW1e2tHhz+W1zvQ0N6d1kiGy5p2hxHT6TSsrMRP8oU36Nu\n8MCq\r\n=k89C\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG3OuNtSH25iF99l/7usDE2TBb3LJqiNqOM7626G0fbIAiEA+0K63YO6M/MBHW0cDIAo0kHSH5exXNRqfi29FJI6tCI="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.13_1527754725333_0.05384899491169515"},"_hasShrinkwrap":false},"0.8.14":{"name":"file-box","version":"0.8.14","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"6a09a66f8b87914d57ebae5a877ca191b75fdb1f","_id":"file-box@0.8.14","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-HkkgIMooNlKey7a8bNi+4cEi9zw7RtKvuRHP4o79qCxcch4r06zTA2vTL/nulmf+Q46zZvolYLeTBOGZwjAiuQ==","shasum":"73b934efd61ecd1a9e6acf71900a792a2f306686","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.14.tgz","fileCount":50,"unpackedSize":139144,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbEQaTCRA9TVsSAnZWagAAc2YP/A4LkxatcJ3e6Qg/4nOC\n9fc4Pie+qtRWBooWw9glMq7Yobt4R45SnA0uDZ3LVm9cyQ0HW9mLAqTWTIFH\nUmgnXyCnbumuyMAD4Sy0AdPJewyfH9YGLqykuUH7hyxiVMVKPgPigYRmsFXE\nJ9yKqqrSSKPNzONYuQN46d7/ZpBJwJ2U1n/f/rNLh1svEx8lwT2jxzC/sqWQ\neWaUlNmkzT4GA5BBD5Gb4D+jTYhB198ACCn3nAtyWlHuxic1cUuZL/YguMwY\nGETTFJc1UyJJiiikITjzgz6mcs+Bh+VKx/FaFUtT08c+zZK7ILqkZVBwqGD3\nO7LmVpWzFIkrBL73zogKD6tn+n5viK1oOIsbSlgHXceMaLw49zI5l3o2XxHK\nNHWFRSV6Yhyip/5cfGyJlS8Nkaq0wJLzRFfA0/z7hJSGIsd7PoH8IXLSva7C\n2S1ILHt1NqycjFdU6BUZZY2vUY8wgoGiCSoLO9nx61dVwWJ+a10bjx+sRksO\nn4JWQdFy6daktIwB/d2zK/QO3M3m86d2wtPxLzx4p0ATHbfF0YdrtisAVoR8\n3kqGS64NI0ZdRuNpMTWVW6zmSXzL9kzLUGYYvlb6zmJ6A5ncUvkSDYLjmJEn\nGMvvKiqT7gaV4X6u9ws5uSC9eHhefxsCZo/L1Qa0MO2VZza+xhPLL8PqToBz\n+cI1\r\n=Zt2C\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIANsNWEoREzDNC3puMYpfGtP9LLDaztqFseP/QLsfXAEAiEAsA0xFZIufbek4I/xt2rybtQkg1d6stMm3Us3cQ0l27g="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.14_1527842450538_0.3732836248681599"},"_hasShrinkwrap":false},"0.8.19":{"name":"file-box","version":"0.8.19","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"11a1ab18eac0a68382be484501a7e41b38b51497","_id":"file-box@0.8.19","_npmVersion":"6.1.0","_nodeVersion":"10.3.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-NDM3TGdrfPBnOnzkarO8715Bzj/tc9a436G+JLmHSvWR9L8XQJrlAxmzVjdXOBpu1aFQcJEDbbFpzrvzuZVLPQ==","shasum":"14a93aaa98f6907fc5c633358829823edbe0ecd9","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.19.tgz","fileCount":50,"unpackedSize":139578,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbFLbtCRA9TVsSAnZWagAA+oAP/2qAqmpq/OjDxs6f5uNO\nxRUPs5jOpKUPd0Pduksacttet6lnjZlLSYKGoFO+ECuqQMolcVX2FuUgs7mo\n/+YRd41HI3u/y6dqsj5Kvefhb1UA3PRFMeh2IV1j2xqc95xkjbSAAME0aBXV\nqV3/3ha4NS1ZR0zNBSWmn9w/OB4jj24P2gdzA5avfW1gnjPDSqWxh6Huez8e\n2xJoTF0xoavB0bt9SVYR8zLPlJ5v0E2AuUM7p/IkvKTv4/f35h8pR2Mho/nV\nEH9Lx5hoC5KC9XOjqQtiSfQ/7FcKFYAc+WuJPRp2Q6BjqfzR0V99GDMjqE9V\nlAN0U860pk7CVEMv9U3vnBkqKOjsxw12P+Nf1iYDYcECSRXUfdTfW53y+B5d\niOjAp/Unb85Q7ZTXdX0sWHEh3li5asEW2RbozLwICHVRLCZ01wEJxJpYg7c+\nDDH5JYiwhXRwz+Ci4DaXYm9W+mi81ZM86KWVAXTJo6735TuuDrtgYMVrRWIb\nI0viBlcAbnCBkBzTwl7lgx+g+BDV22jB3Yfh3nbzXwVDZg4HrZ5o1sXtmSK5\nfEK4ivs2QRT07E4jxb4uRjjS6jtG/TQuk7eISYnOmgXbxBLpEnIviQPzZabA\nXQLF3/derWkg4xYxggUAGm0Yrxvu/i9GuqAH5dMMYp2PPAhbLWjWODCWKUPQ\nd9tI\r\n=efMr\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFYfLmjEog6d3J10P/fqrZxin9NrdzGMG/EeMZYmEc79AiEAssd/KxJ0qvHuP95boyEWfduvmyKCU5L8LSAJRBeC8bw="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.19_1528084203361_0.7883786741662993"},"_hasShrinkwrap":false},"0.8.20":{"name":"file-box","version":"0.8.20","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"0fb2bec3e1ed83a1b8d22756a3f31f2e7ce9035b","_id":"file-box@0.8.20","_npmVersion":"6.1.0","_nodeVersion":"10.4.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-MClQkuIIL1szEggh1lsX0T3dlhCRt3agj/vw9iPg/reuwfe7MkSiDYC5SritKFGoKxkZJzDSiTCP89ltwzvbTA==","shasum":"c7de8efa18edfccaf8afb714c91cf9e713185a40","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.20.tgz","fileCount":50,"unpackedSize":139748,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbIYAXCRA9TVsSAnZWagAAxv8P/REwxz4BZVIuC/u2UhKH\nC0Sw49ONwK2O7uwHzW2VDy7YRMM8PozjtqrEj37qyh/NAyE/mdiU+Zb7iMlR\np31cmMZLhzd7HHH9U4lOP/FcJ2On/yTUS2U5ByLfc9qqqNEwrfPtHH/ORFPR\nZfEHWvjBNuyBTFiV1IAlcMVxxWttoM8NGZBSr3s0H9UWWzsbNqOyDBK11hSp\nZSS6+cwcHUHXMi3URjCU348y7Pw1cqPBlAEu1h8in/3RSvJCKNQaT8bL0Z9T\n1h8Y+8Wl/Yvg8KRlx9zQJQhnDIJh0cRzPtoGvRsePp3Z2bTcu/KgiFdMPuGa\npmFc8OSoBhcm3P5MQ86l6HLYN6V0tieVUto8nf2tcC+TCPxx2V9kC4pWm61W\nva2xmyXhE8ELIY9BV3O6OZUmekfSS+xqpprqwhQrIwanPx5LRobAVOuTtPWS\nxkhinymGFmuGxBdGZV43lQl08huhym8RE2kw2ufr/GBfr+LaG9WeFjcAh96R\nv4x9sEziAEDWqsKGGz41mUmum21KoPJEZCHJtPq0uE4RvEx2+K0cq9kd9AmY\nI++JybrkaAXvhYijc220n3loaaA3t7M+y2Z+Yf8Feo+KynuhdhooLO/cGHBg\nr7PESXRNcz3RRRy/4IOJzClKo9qZcqN5zfhnxYaJ0chrtHcQLv5p+9qTAaDA\nLDkc\r\n=TLha\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCEG38+3/8xuiQOGdYM1wr/Uw2+m3++rs5Hrzp8fM376AIgDhwCE7SMkeb9d9HcBMH05US0w9i6zL2Nz8JSbEKIcA4="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.20_1528922133470_0.09647431082346047"},"_hasShrinkwrap":false},"0.8.21":{"name":"file-box","version":"0.8.21","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"d28333ef87396c47e170ef4f031e8ea61f01467c","_id":"file-box@0.8.21","_npmVersion":"6.1.0","_nodeVersion":"10.4.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-15uXVMO/PItNkW6jygwS7IgDpi5VnkXl1NR0L0MPdwl3CE6biTalJxC0Ns2+BdrYv5tQmzUPLWU1QYlJVBG1cg==","shasum":"65273968e275854476477847d900a1f69926b154","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.21.tgz","fileCount":50,"unpackedSize":139722,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbIoE4CRA9TVsSAnZWagAAcmkP/iAdz454qpJ8elv9BzTu\nmKWCmXZWPHkZi043xPAb+cipeuNPCYTuZjSmjLg1C36dUdW+CaFB3shOZLU1\nOi9CWWj6QmL/mv3pTLtDQ5OqNgA9H8gyGdU93fZhufMtJ2lsPJQ/PkvrwkoK\nYUtSJb9oNCb/mUx+9Crauv7h4kirtevUFTSFnkuBJbYPfBY40KW9Ia5IHVxl\nQO/cFzmYx0gLczcW5UnaG1FxM4wlBUGBIkHkSxbhBl0gykmqIBSw2AW0NccO\nguxTjvOSknn9E2yqGckaZokcmKl5yVFZCxKkJYaRKO9G+6d17DNWwbVTFSra\n5rjAbDo6FJpTHuY8WCjFktatqt54EjiitZsk/hloWKgsuXd0dQz/zS3/ljaD\nklyk8+c9mCRMEGW6Az4ybr55UJZg1iT0aq//uAauoxhWhVX4nlanYAIV0ZPq\ndvpAm6/G4JgvMUT1bNCVl08iT9g5WJwcehQTy+S9Ee+kVwt7C19lRszC6oum\nFZ/eM+8FzJj0Z/7yZ/MOkJg3HcOCjtYVBHgUMxh6hyLCAmeBfnGpyU7O2JPJ\npnoOpXEeeaBCFYC70GKOVhv6qNfGI31oN8hrOZPVEwzgzhhr3wWonELH2BqX\n7Xih5HUvsRivvSq6z27voL4rZSCyXAq3pXKz6qepMFofDpyHhGXBFvpthxpf\npWbU\r\n=UcYM\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDVjy3suL3sNtQnzWfRhVlMEbDxJ9ugjzS4CpEmWU3Y6AIhAM4IMFW6QlZnT+VT2afo21oW1lKFbg4o0XzUf4pAaNFC"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.21_1528987959747_0.42563674674976193"},"_hasShrinkwrap":false},"0.8.22":{"name":"file-box","version":"0.8.22","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"79f4c50c2c0344c4e97fed39df860ccdde471d05","_id":"file-box@0.8.22","_npmVersion":"6.1.0","_nodeVersion":"10.4.1","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-PeGJP2e0vdssO2TQqAk34P8dPrF7WpbiTCiKkb+++e8ysyJ+EBnX8wNouq0yPQG/p/5dpQxDwoQ37C2f++MiuA==","shasum":"3888357d2e638f11146b6e946522732d65f03d6b","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.22.tgz","fileCount":50,"unpackedSize":139752,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbJpmNCRA9TVsSAnZWagAAFjsP/jW/zBuvYenYDazVFd64\nGshbg/a9hWnDDnYEH4omhFzT3paCkQ3Ps3SMJ1oVDVFwCONiTw3UvzsFam2/\n3r8WNNj66dBma+eBygNwWkdj8tb8JJCvjnKFzfDyaEADsfCfEDJcbYhvOfUD\nYt2bZ5CpqxPzebkHCMx080YMK2U+475O7TZFI7HJWQDNXLf8G/lbogjIwqd7\nqxpFIEvG9oUZawkD9TbLNzwtjheoxzufd7tqZ1Vb/K8yXONpotoey+ixsS0f\nzTaEFdfuZYnexJEe6vhObp+fDZO117oIb+fAule+FaR4L7y2DDTphHEMvWUj\n3KEC5TQn2HTFaUZPEd3clEEKe6GF8eCkJDg99ecbZc5JprU1dtass6zINFOz\ntGM3017eOMrKkvGW1CHkXV+Mm68m2G07T45QJzQKUYY9zE6fYUwmQC1K7+re\ngB1u345I5ZVdimMczfW+VWvKaW9L8aQI7BM4lz+FUssrgvc48YYWecoSb9Bu\nXGFLMfqA30hQg4/FR3Sx27DCIUu2OkxV5E0zEwXLfg1YPwwWG54rpgkiJtUg\nzkqUUmputpOMHrYpWbYGzIkhWDztw3blNjjzi72owFtRdxN7JzSpNAcrmGYe\nci5YBejeyYJ3qW1D9jBUin/Kgnqb77bibjNx+UMV90Q7tr9OO47wIXnzX39u\n56jW\r\n=lKye\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC6TDi+VdwKClOV7AeNrYb8Dbw4D3sWttAh1elo9yVrHwIgftjxbhrDArUFzeGc2jknLeMMfnWXUYX6XcaPHW43DD0="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.22_1529256331870_0.48399974003206303"},"_hasShrinkwrap":false},"0.8.23":{"name":"file-box","version":"0.8.23","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"dba2c7bf7fd80fe1810c6f78180b95e31eab5f36","_id":"file-box@0.8.23","_npmVersion":"6.1.0","_nodeVersion":"10.7.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-pqqo2cgZHzXFHViuBnxUJibfofH/LUj1P/qX8NML6awKxuJXU+6F6AYx/5JqC9BBXorHMvez4l3B/yJKgYAIZw==","shasum":"de5ebc3c62093be63b936e1fb11870c80fa90dfb","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.23.tgz","fileCount":50,"unpackedSize":141532,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbXztZCRA9TVsSAnZWagAAOoQP/RYGWBiDOo6eVqTxz9LQ\nU4BQPgHD2tJFh3s348RXqBiYrfeyjUswBITBzT9TQujscUPHdSaaxHSFsfFf\np0OXdwmdweIR+Wx+FAYrIm+4nzAp/AVn/s6W5icVpUNhD/HOpAHKgtC+BpZK\ni+0qNLXGadqbPNPg6V3/qFnwmFp3dG8uwk+b4rpn56w+fQGVF5sse9HwYH7Q\nklOyRrmL1E1SbduqTIuDoA4lmai7DNhoR+47ukYWZmC0wgF/sjwO/NdinwTX\n1J0hO1hBTqo00iC80PBkOkU65yDiCSzkqb8DFUf6rqxS7JJ3X1Z+6sR4CfIG\ntwu92wZaqf5Mu3ic7w7wNL27oTtQhmbR8xWbvgar1E2k60iNRqqHE9p/btBZ\nEv25TLHm10Lhxto67tH2U6OIzJUMc4uU2orO7hPDJkywsEUzJgxqjxytlZG2\n3X9LKMYG4zLuSDW+l7B6L/bMoZg0HqAEUGmRPCEARAWE6zxm61uWISR4dHD1\nhDvhom0tQxL+CI9Zqoxx+1pPIDdNalT4JjHhrjnmqclXTeEbP43Np0LMfgn4\nVYET4K6gFqtOqFmAMOFkQv0ga63pSzobkLj6i7t895AdhcLCDCdczsH7dRP9\nrBwDJZnIb+lZCo9+kGV3Y7mTmtXYwoR7zx9PKXENjtyg71hvHtyrU7iHdQnR\n8yoR\r\n=vgla\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGAnU0F+hJ/2O2yHYXnGBh19KhKG7jGasmSvjap+D76yAiBhfyCSrs+zaX1w2qClu05dlxIWRIR4q7rgnTrdWNhFjA=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.23_1532967769436_0.6523181585122875"},"_hasShrinkwrap":false},"0.8.24":{"name":"file-box","version":"0.8.24","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/zixia/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/zixia/file-box/issues"},"homepage":"https://github.com/zixia/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.2.2","ts-node":"^6.0.3","tslint":"^5.10.0","typescript":"^2.8.3"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"a1f0a547b645cddd9d3eb2abd14a95d3987d868d","_id":"file-box@0.8.24","_npmVersion":"6.1.0","_nodeVersion":"10.7.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-qQuXDM9uE2hjbpqIqv/OkHfb9ILcXCM5zRZom85AqDPYmKlJnBfzrf+rDbMok0ZnQW4fMK/8OdEN3jp2t9KFYQ==","shasum":"b14457dd34cdebac74ae3a674e97e09aaf780ee4","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.24.tgz","fileCount":50,"unpackedSize":143477,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbX8uWCRA9TVsSAnZWagAAtM0P/REEQCfgD3zYWKg51b6Q\n4nVEdzhL3e29AzvNXmsBn8PtkJshtgudxfZK046StR8k6KBFyTA+DFU7gnKg\nYf0H09o5yJZ5B6e/gNxNtEBH4KsE1v8F+ZvRBEXO0uXslEC3/lvD+zZm+EoH\nOYOyMQj180Su+Qfu+W270FQYh0koCR1w1TLg8vNpbAiB0DJ9MI5/b7QR0bml\nX3C62ZnpU3SJoO5063YHtTThjLggh1fDMmgOeZsu60YgUqZ4ExzR2FDtiBYk\nT2cDoG+GryvbTqUVDpB2yu+cyuB3yRtalIvkgx265Cgh/Ral3qngH8VKp0g5\n3/+fyo/5VpzfeGyKXQnmnRC0gSxlZ5sbyp1ILfOrYYH51l83CNCLR27zI0RA\nuGCnj3TEPCavG2EWvqwgqETyNUvSb8ScXKoLTN1nrXZ3H5Wc/vduYQa2vu03\n+IdQIFNWwPpAmjkg9tTeEblnA1i+ZQGZWh5wuLb5XBOVOtgpX22sfVnfZ7DA\nIG8q/uwQitzOHJnW0ZWqWshAbCIYWXhpPHciJF0hm8/AzQm3TyOd0CmaymHn\nFYqIIYKm8mqiKAAfsTWzcnP3BuLQz9eJcxZk6XHx5GlFJFlFrbxdgb/mxwVF\na4rhq8eZPGYdm3484q21knJgia6JbtLYTClqtXNrSacYVhff1JZbYWJKIhY7\nK/Gf\r\n=ofi+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDbqR57Vtw/ARcfRkk/FwgfmevpS0Iydsg8K66IuXvj8wIgZ38wsEUtgSXE5qY8XWvApGw2TGzI4CxvvMIlld+jHW4="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.24_1533004693922_0.915437150785821"},"_hasShrinkwrap":false},"0.8.26":{"name":"file-box","version":"0.8.26","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.3.2","ts-node":"^7.0.1","tslint":"^5.10.0","typescript":"^3.0.1"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"23eba3c295cb90c85d2e430e2c3dc9a81f491b67","_id":"file-box@0.8.26","_npmVersion":"6.4.1","_nodeVersion":"10.13.0","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-ROhS8Bgc7bLOuJuHJHx+dHkYxp17odhJgno+0W1LUzusJHcJfA9uMRIGpGRTRT6IZqfg2Skul+v8OUmW7lV7pw==","shasum":"72c1bd419b01c0926fedb7e429217217fe12a172","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.26.tgz","fileCount":50,"unpackedSize":144273,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJb/WWQCRA9TVsSAnZWagAAkcwP/3wHXHjQtaPeiNK8U7Vu\noZ2Ctw7sVwccHruvGq8qjeh3JCDvzYh2s6tplQunrF7x/g8C6Q9mnEgsYeO+\n2BlCzLu+Cp05AXVvyM86861A3TOXCxt4yVaNdAyx4R7MuByJbKkPHB8+2Qmi\nLZRgHnOSeIk+WLTNm7EU4Ia7BDk2KiXKluezQ0rxvyaDG3Eq21CvMCA9jznb\npJGW1T0xBct6i2mFkgAlXz+j4q6oF7HrDNxM9gLQBUJ0PBVbtkqgUus7vuR8\ngJAzQ4R7vEuiRN5BSPhUflt49Jh1Z8TjvsVahr1xK6oLXoBUOjELDcwSIbuB\nCrdxiYvVxvNePZsFq5Ec2NaXr96m/rPNAjzoTXx/GDnB86L5Vq8fHSh+Lqlb\nLPydVVRGFHoP2KQqZJHhl9G63nm9SbbehJ8Ym5taJEnYQfCle1hs4hAztiWg\nk+orGnUOPVIqseNgJszJi+yFtwL56c4kPmeKuy7kSgqPRHyxPnL9Zif0Z1jy\nIQHe1EpqOMOeA+DCTE92C1NFe2hyRpUqHAxN7D7UEnY9UHGQB6r3ZidaOJnu\nBF/oCtT3yl1R9y9nw/kqyh9QwoQtFHL41O+jBYPrkHUFpC/OaWN6kyHokE9U\nRoAls+YR1kgWSjp2k+y7TcXzkU+OMbkHtHTD60RYTPtiKwsJe0+knIac+fZF\nlJRe\r\n=M2ml\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIClTPVlS65D4pacZRJj7pjAgaiJtC1DoP5IVXu3ociGaAiEA78zdbGlctZgwxS8WcvduubuyVjIeW4S5vNn+PbOaitE="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.26_1543333263559_0.6957406420943459"},"_hasShrinkwrap":false},"0.8.27":{"name":"file-box","version":"0.8.27","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^10.0.8","@types/semver":"^5.5.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.3.2","ts-node":"^7.0.1","tslint":"^5.10.0","typescript":"^3.0.1"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"latest"},"gitHead":"c327fbb33551c36d46efc3bd9dc00a8d8028b3d0","_id":"file-box@0.8.27","_npmVersion":"6.4.1","_nodeVersion":"10.14.2","_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"dist":{"integrity":"sha512-ZgjZHnhwr3mRhfx2DSVFbxK2Q4OarxqjD7/g+LdOn79OrtL44uSJ8lM4RSCU3TeGw2nTXcwI2UKkvGNGIlA9tA==","shasum":"f209ed07709819a1cccde2c7c7e7391bce117a14","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.8.27.tgz","fileCount":50,"unpackedSize":143890,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJcGnDqCRA9TVsSAnZWagAAksgP/3yL17g3yDMVCS8p/VSE\n8SNIr9wdV70eP8nocPp0wskiscYGDEeTN2x+iFv9Jtuxk+nQnNbAXn/JC5ne\n2cxUAzRRPh+hMZFe1YnqCS3MNYmQdOe/mULf4enqdfmHGfo25uGPozRjiu71\nMuaE5zrfQxnp9AsN7aGqKh9U7UoBuWB7TDCvXLnj+pImaDXZooUbXwh9Y2nF\nswBeip0volQA+l6v3/CMVou1WEb1NfLJeBPgYumrNjlbeFPNv4XrbapkhSPK\nEtVU1s/z4DweZ4lZB2u8WJJ4F6iAphpkkn6X/zSAGtIyWJJGMr3tgBHwf5Ol\nkieq6cOKXTfRs3lebXvvashNuerIzZjfKw1JXp8qfP41oQYoQu1P+b5mlYQt\neOipCVZaXPCWMZ1bjEaMPIqfpI0h0vmRqMNKkRt7zeIeN58RK7roG7e3uR0Z\ngYv8Mb2Hs5o4re+Pn3NaYIHvfQodRmhyiGj9790EyewLMWOkF2V53SKkH3jg\n3aB8PHIApWd+bPknn5qBJ+NoU3Q4zpLdLeYRBjGQIsfgrO57ez3d5S4nogR5\nRSR8UFCEIHfiesjMJCGTsYoJp/jVngulFE0a1YErxNED4Ly+2bizjcLL6F1f\nrImsGpqr1xfL1cUmx2jPDaZrisn9CU/6mDmrWGU+XXJY4+A9Fyg9Z2cLVB4D\nKi14\r\n=hzep\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHkJ4CEs7PCZizkqpW+jqCfRzv7pCb2yQ8vg9B/ak+NtAiAPvoXxCEPXVRLcK+lCp2fLcB4r+/5yCsFnhQzyzd5Iew=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.8.27_1545236713740_0.9917641976268228"},"_hasShrinkwrap":false},"0.9.3":{"name":"file-box","version":"0.9.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:ts","lint:ts":"tslint --project tsconfig.json && tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh"},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/tsconfig":"^0.4.3","@types/blue-tape":"^0.1.31","@types/isomorphic-fetch":"0.0.34","@types/mime":"^2.0.0","@types/node":"^11.9.0","@types/semver":"^5.5.0","@wwwouter/tslint-contrib":"^1.0.0","blue-tape":"^1.0.0","git-scripts":"^0.2.1","read-pkg-up":"^6.0.0","reflect-metadata":"^0.1.12","semver":"^5.5.0","shx":"^0.3.2","ts-node":"^7.0.1","tslint":"^5.17.0","tslint-config-standard":"^8.0.1","typescript":"^3.5.1"},"dependencies":{"mime":"^2.3.1"},"git":{"scripts":{"pre-push":"bash scripts/pre-push.sh"}},"publishConfig":{"access":"public","tag":"next"},"readme":"ERROR: No README data found!","_id":"file-box@0.9.3","gitHead":"fc17e5920f77c27073c040b6cc5b6d07768de318","_nodeVersion":"10.16.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-fxXQQuBaw9c7mmwmiaP0WipwVY/6MdArNjgIBf7y21VdNWnAek1zwun+Z/JARG3aB6XXW0NnkAKa9xTCuVYPRQ==","shasum":"e7ad4612a5ae9912d6fee3684e4359ba79edd8e0","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.9.3.tgz","fileCount":75,"unpackedSize":155415,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJc9bTwCRA9TVsSAnZWagAAVEcP/ArJ5tpabLtYsZxWRO9t\nnrha5/YS8rhppz9ym42DHB7PrrSFEhvD48TYGnrrE+8X4oRSpysPjLxlAIRJ\nzVBRhEUnM4+Wb6qPvb1Syj+gsKE7t9iNezt7HhiIjgUv6oTVVjP1pO0METRa\nHlHnaQIZM6uyCJmojXul6NQYNJr69vzEL78Z/QP+hh+xilYDfCcsxBj/dNtM\nGPMCyg8QyG3G0+QrFZOVNhocyp8jn3PJji4H2V8Wd9VBPDKY/mcHcwE6sqiI\nEWlvNuXc9ZQBGHlTx1YoTaNXq73X0hynPlLDjBwMA2jHn8dBnTUm88EUZibu\nIQIJGrAvzEmLYjXnxMcZLqOta/Y4/vAjqtPmIAFz5Zza3H1247+EzxNSGvmi\nui8LOoRecKZnLK5gHLN+DMRXB+8JyDg1NqLBzGAZyzCA3r3ltffgKQ4bMOC8\nowIUnBaQ9f4rFJY6s7e2wNl/YKMetU9XhfozD0xPEePBFy8wFVaQwXQdt+RP\nW5JtstqAVZAMAoXThY9L8n5s1jYZ/UvZ+hFPbm0SgLvmN3sKLUnN5sQ/8Scd\na2NSI9VfDDkHw5ki4clV1CsyGwtViOT1GlHy43KKkcsiSvS76DCUcK4JuqvW\n/QJ7zlG4SLq3FqHzj+nNp4gI91tU5I/0SiqENvs46XZsyOGvmczoNXTDlEDP\nGTPD\r\n=Czmb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCYTqXa7bSqIvK8ZUKmm+lBWIp8Yz453T/I5tYtscA3xwIhAOdhMK8a+itajn9nZ/yA1D7xdTVzAxWJorEDAKBHIFNr"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.9.3_1559606511882_0.8957388188924262"},"_hasShrinkwrap":false},"0.9.5":{"name":"file-box","version":"0.9.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ 'src/**/*.ts' 'tests/**/*.ts'"},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.6.18","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.6.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","read-pkg-up":"^6.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"mime":"^2.3.1","pkg-jq":"^0.2.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"3788e591fad15a2ec00868a3150d1e136e3898dc","readme":"# FILEBOX\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![Build Status](https://api.travis-ci.com/huan/file-box.svg?branch=master)](https://travis-ci.com/huan/file-box)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![Greenkeeper badge](https://badges.greenkeeper.io/huan/file-box.svg)](https://greenkeeper.io/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| JSON | `fromJSON()`(TBW) | `toJSON()`(TBW) | Serialize/Deserialize FileBox |\n\n## EXAMPLES\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API REFERENCE\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlais: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\nWIP: **Not Implement Yet**\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any } `\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'zixia',\n  githubRepo  : 'https://github.com/zixia/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'zixia', githubRepo: 'https://github.com/zixia/file-box' }\nfileBox.metadata.author = 'Thanos'  // Will throw exception \n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n## FEATURES\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## CHANGE LOG\n\n### v0.9 (master) (Jun 2019)\n\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional informations. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## SEE ALSO\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## THANKS\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## AUTHOR\n\n[Huan LI](http://linkedin.com/in/zixia) \\<zixia@zixia.net\\>\n\n<a href=\"https://stackexchange.com/users/265499\">\n  <img src=\"https://stackexchange.com/users/flair/265499.png\" width=\"208\" height=\"58\" alt=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\" title=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\">\n</a>\n\n## COPYRIGHT & LICENSE\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","_id":"file-box@0.9.5","_nodeVersion":"12.4.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-rlKNkpSD0ctPbOUpuVEpIhPtBmeKjTDTwcUPfem2Pf+/OVxTMFX0T86dzREeib/kzMUyXepfQUcXrp0pKA2HTw==","shasum":"c67a7f20cbbed88aa2d483a26410c043e40d7698","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.9.5.tgz","fileCount":65,"unpackedSize":149418,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdDil0CRA9TVsSAnZWagAA4+UQAJzNZHYYWRjiSG5F+Nn0\nUbG4hsPr8OPU6mfnTcXb75aaQBVKxaIVZ08ofl7WeJx4HMzQ8QvnrXopHRO3\n62ELKiZpLp7Gn1WM8PrdaDfx8s57gi0pu+mvT1Op65uT+9xZqbQbzEl0KF1j\nHefUPevNiSfAF9yLMpPe8DCOdSEiwXE/rrIsoEt2Q2U2C+4ZLpV1IYSq+bLY\nVTWydxxATQY81sipARdcMLiHG4B9ByaDLZbytRvfyaswkLGhpdH0ikdUaYE0\n+oHPyvHq9Bd0moI8khiFmL082f5RzKu5YB1hiiE2fOI3w05E6B3P2TBJdGRC\n8llnngpN88wxdvN80lF5KReXb7SFUXocvJYRBJSBaMNmLxZP1Q+D7m/0aaaO\nerbvPM4jaY/yhjsTezmivi/NFvWhTWbH7wUXWM1Zc7yiQlO9hkkCS1aUkmco\nIu3YNG+XNrdxnsAZHZ4DRnKk1N1rvzbNJxOVqpnGtot+1O3z+4P+tNGeStCx\nCTTuXcAjNRGpbrso5P71cFUtow/81Woajc0iiOZvORzDN/S6BQBXQFYkul0k\neA2aWPVc+vuHy9do2LEWa6MK9Lp0JoQGpBuug8EOMzdr6IExEYWyJ8ccC+Xv\nPGRW7i1PTyhQEDRY1dzho55Qp93s4m2Ows48ifC6if+X1nr+5H9CJOtaCHYv\n/CK0\r\n=Wi9M\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGrivHzDpKVkUYDOHFPjvSDtcrBmVT6nbiqdbqI6fYtGAiEAizMFtLx0n0KjhkSeSz7vQnHVqzavEuEZ5FRx3alFzVs="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.9.5_1561209204038_0.3740635947996238"},"_hasShrinkwrap":false},"0.9.7":{"name":"file-box","version":"0.9.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ 'src/**/*.ts' 'tests/**/*.ts'"},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.6.18","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.6.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","read-pkg-up":"^6.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"mime":"^2.3.1","pkg-jq":"^0.2.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"91e94e860dee7c63b855760343151aad0895c55b","readme":"# FILEBOX\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![Build Status](https://api.travis-ci.com/huan/file-box.svg?branch=master)](https://travis-ci.com/huan/file-box)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![Greenkeeper badge](https://badges.greenkeeper.io/huan/file-box.svg)](https://greenkeeper.io/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| JSON | `fromJSON()`(TBW) | `toJSON()`(TBW) | Serialize/Deserialize FileBox |\n\n## EXAMPLES\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API REFERENCE\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlais: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\nWIP: **Not Implement Yet**\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any } `\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'zixia',\n  githubRepo  : 'https://github.com/zixia/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'zixia', githubRepo: 'https://github.com/zixia/file-box' }\nfileBox.metadata.author = 'Thanos'  // Will throw exception \n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n## FEATURES\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## CHANGE LOG\n\n### v0.9 (master) (Jun 2019)\n\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional informations. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## SEE ALSO\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## THANKS\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## AUTHOR\n\n[Huan LI](http://linkedin.com/in/zixia) \\<zixia@zixia.net\\>\n\n<a href=\"https://stackexchange.com/users/265499\">\n  <img src=\"https://stackexchange.com/users/flair/265499.png\" width=\"208\" height=\"58\" alt=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\" title=\"profile for zixia on Stack Exchange, a network of free, community-driven Q&amp;A sites\">\n</a>\n\n## COPYRIGHT & LICENSE\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","_id":"file-box@0.9.7","_nodeVersion":"12.4.0","_npmVersion":"6.9.0","dist":{"integrity":"sha512-ByWAWlvqCSiiUzmwtuHPXp093mWa872zJx4nIlOLv6crBD4I7goo6U81FboyeJUWNbev+Aj7mDy4WMGF9PIqGw==","shasum":"8ddb0df452272a075cc4d8f454e4cf2ed264d4f9","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.9.7.tgz","fileCount":65,"unpackedSize":149446,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJdDiyYCRA9TVsSAnZWagAAoaYQAJYfQId6E1OQnI0qVDPy\nnTthd7fSSstuCTvwKwUpNKEFGbb6anGmlMhrH1oLipvqVJPej+kk35bLjHsI\n4ZDJzrlaSz6T/f3Lq/MrH0IF94G1dDuNhSa1HyGQVtWLp+fNBwh4gFgnCqLo\nO9j7Ci2VXl6CPtuW3m3O6Xf8AiBip7HDSClIn/HG4Qu9zQrCmYO/RB5VNKQ6\nibUdVn0w7tpyOPthltvmCL85WmWCcY8jqE9M6hb9ee8rnwKtXez+rOGoHK2A\nGRKNtGd3LaAWQqdKJ8rmGPXQTX9pRGHll3ftkkb9eH19F11Y1W7qRns7tmFy\nmA9sl4DNX+HHVKaIpBfXAi4iuCEmpwLtgyjH3kPvS2sn8r0RejUTzWcvKc5D\ndTgFHQDupakxo38RjnGWJweeJid0x60/5AXp6uwzNWZVXGYVeYH4VRFsR8/D\nct61IkgjK+0mHsGIIfI0Wo9GS6/LYGG4JahcBGCHGf+4o9JbjfajXEyM6+gj\nD5PiNUFTHeDukPJUPLuTjx9XyLVXa/+nVMh5rNr0UzDlMNsI/1+dvcmg8PXT\nIececLFMm5+C2tj/oo4rj+PhjRnnJ5qxCtTIpT3nAvcVGBULg8lBdpzgOVx2\nM7pBBn2T0hsgONOT5l/+jPVSh8XS7LiZsCwRW4z9BetaNSbwQELrxAoW9nxw\ncrwQ\r\n=4QV/\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGnV6Gxd2YGhILeIQjGwuW5rACvBiRZcJG0qu8SNxBB4AiEAhqgeTgmRqjftYd4lQMZRXZ98mfj+tNAgcxXs7JRjGrw="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.9.7_1561210008150_0.5785348289031644"},"_hasShrinkwrap":false},"0.10.6":{"name":"file-box","version":"0.10.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.6.18","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.6.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.9.3","jsqr":"^1.2.0","mime":"^2.3.1","pkg-jq":"^0.2.4","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"e420f547dd3aa5f8035e2110ea3f6372b17b6afd","_id":"file-box@0.10.6","_nodeVersion":"13.7.0","_npmVersion":"6.13.6","dist":{"integrity":"sha512-GDczGx25ModLhb86OOBZIpfOUp/caCfGt5CcntVDptXiysS71pmb2r/e7Vj41aH5YuTiJ4H7PdNe9GjQXfMfJQ==","shasum":"4b069874959d2561cfe86910e2eb58c3d41b9b42","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.10.6.tgz","fileCount":75,"unpackedSize":174878,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeOm8XCRA9TVsSAnZWagAAtMEP/14gc+ziUCHNDNoDTue4\nL7JcW2mf7tlMiPAcrc21xf9WpqprdR/df0MhoNTtjkDBlWKH5q+LDiqoBN8v\nM2A8auJlnawCV0EvJeNnG87TXbfvVL7y+Lpz6LIA/Pisv9olziPQEGOIjVqg\nECDIa4O0D67srelIPKo4CZYTD9NFTAO93duY9kt/9Tqcsm4AKVQi1c4ThgRb\nZtO1XWvW8zhUZmXTovb+SJLmgjyts63TvRHu5I1muMfG4MrYwxz56vvqS3bU\nXUhgxvOqP3u/G/YNS7qgu7MKtcxo2MonF+w2igDi6hHRnhiy2SKYP50UT5pM\nkoR4PwVRFifSyXxfQ/QmAyt1wiPjgGKKjERzQ70ngXysABI3SkkIbYud2Xj/\nbl6HtYNRYQ31dxq/TIU2YScUufirvpb+Ul5R6mJv+MPHjWEdl0FzUjM4BfJt\nJTWCTIE0VE54OWStLuP9RgMyU9e4yDP/h5pS5Ud2j6soBj9CyAmKxhQDlx6R\nzRoLILskWyVRO6f6xIBqI13nV9Ps9+3/UB04gmE81soUM7LAy1LBKmrOPpXA\nGRmUykUTy8EL7OcnvLBT6vPyEOXP5Rtc4SJSoa2m1C/Z1vTv5IN010K4Dvo6\nPb28OSwy4/nzN+/pAHAhRS5m/UJgHFnl3EpSts3jkxN7LLmGZIfOLekEQlgR\nPth2\r\n=Bi1d\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHqz7euolr06Wdl9zm3DXTmlJko1xYhAc7vgQcN411ZhAiEAqJ+uj8hdgzPJGXelMJJxPwxnvJpFu3JTFG/ntnqoh60="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.10.6_1580887830542_0.987669377538906"},"_hasShrinkwrap":false},"0.11.7":{"name":"file-box","version":"0.11.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.6.18","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.6.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.9.3","jsqr":"^1.2.0","mime":"^2.3.1","pkg-jq":"^0.2.4","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"9a520e18cdde96d819afa5d45bfcc9f627482dcd","readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![Build Status](https://api.travis-ci.com/huan/file-box.svg?branch=master)](https://travis-ci.com/huan/file-box)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![Greenkeeper badge](https://badges.greenkeeper.io/huan/file-box.svg)](https://greenkeeper.io/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlais: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.Flie`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FleBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable becasue it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any } `\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://zixia.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'zixia',\n  githubRepo  : 'https://github.com/zixia/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'zixia', githubRepo: 'https://github.com/zixia/file-box' }\nfileBox.metadata.author = 'Thanos'  // Will throw exception \n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()`:\n\n1. `FileBox.fromJSON()` - Deserialization\n1. `fileBox.toJSON()` - Serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional informations. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)) zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","_id":"file-box@0.11.7","_nodeVersion":"13.8.0","_npmVersion":"6.13.6","dist":{"integrity":"sha512-Zg8ZoQ1Jew+oG5IKGqKD64Qvf2lGT/WWtdjG0LI3p9JXYGKvI9Xs9Up2bbOsfawRpuqUC8llDQbLj2594+lqeg==","shasum":"948591d44e4806d0c103612c1d5477e15589aa1d","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.11.7.tgz","fileCount":75,"unpackedSize":192678,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeQ1rQCRA9TVsSAnZWagAAKBoP/jyjypIikkFvyQjVszXN\npUwUm28X10B9GkAmefEMBjzmhuWkObxj8Twx2fCl2PNN19L1QsK/LZaCkT/I\njn0Krt5BEY8Z/Bo+pc8/w0y3GK/EJ311DMXGlRZJnwhCAfsR9e9DgD5n5S/l\ngcDLzxs8cVzaL13zJO9sutezf+BoDDQhaBX5UMrl9TD7Ct/Rnxk+WBarc0zi\n4qiosyzY1HuYeqy+HvbCRByDJ/Kok+ABJPlQGZjcwhtyb2Cw/jrEnfzBhZ0L\nWg1Q3UYOacNHrYRl8HFPv94AOG2vLMw8pCtyRPx9LsNLTl45bsf1E2uvCOJ3\nZl3xIiB9U89ZrDkj6jcE3w62XmnZPiarvOrrD9PADvM/ZJfv8y+6emTU9q/A\nrMOmUGbPTSlr+OWIKF65LRnxyfdqSk34DrZVFpiHDccX4CL3wG03fqvlXEu2\nj8HnAGJMq6afhX0oShFug7gZjrKrC1Q5nbflq4j4NKdv+9k6D+MbIxVBWnU5\nM+N0moWrR9U3CFQTpXL+smtUMk+I0LtMksO0bOvMX+lqZILSC2NFZ3c7Kgoa\n31zMGTpDqYldIJO7KU9oPJUJDnd0fn4biT93M1428NNxQH4kzquHwotMWv66\nwUUUHYnmIFpHU9ognUa0f5JYidjHhlhxqw+aFu+kpUC/D9DZmnS+T+CuXzvy\n8JvI\r\n=/Wx3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDov+oZjTe5B5HBtCIdO2CBWAIBgnjIe7/0O56DktNYtQIhAOQLXMQO3nPd+K3Qvivkdp142IKUuTA9vEh8O1mvEIip"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.11.7_1581472464474_0.5153958215184276"},"_hasShrinkwrap":false},"0.12.1":{"name":"file-box","version":"0.12.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.6.18","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.6.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.9.3","jsqr":"^1.2.0","mime":"^2.3.1","pkg-jq":"^0.2.4","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"a79d96dd6ced22a72633e4575be0607d4b3e61d1","_id":"file-box@0.12.1","_nodeVersion":"13.8.0","_npmVersion":"6.13.6","dist":{"integrity":"sha512-rEs3gSGAzSLC4vGXmyIaX3j3EQYA+/WT5xMdt9kxQWSWEQIndDlB8XNIT9E6nxK7fMvqXr2LJCCLlXlVR7lF1g==","shasum":"9e6b005d36f344b2f345db1223b11da0fa84bfb5","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.12.1.tgz","fileCount":75,"unpackedSize":192770,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeQ1/yCRA9TVsSAnZWagAAJ9QP/3ieCWOP71a2HP6J33LW\nBcE+jJSeIp1nsHy3hzHJRCgWRr3MU9XwgSrqPRTWUObqfbGlFVTfKV8A8R8a\ncvfPWoiRDoBGyuohF8ArwhEl3TpC8fN53JKXCnIOmoerS/1WynEgKRfYq2tb\nggtmw5KGe5a7ACMvj08dAxz2ZpFZ9qMHWb4gb+LiZrPY+R4ziF1CVtGReHcP\nIlL0ZKnNL2dol3TKoTSc7w49Grf9LPR2oiw2+GpMbglxjCh1G5gJpwOYbubX\n48tqfvXjn8dDdsBAROYQNaoYseus+bOMXsoMJucLzF1cf8qcNSOtn5DAWSpz\n9pVLKWap9gCQj/Btiw3euwuB8vRo5oEYvvkCOCEThI17XLltU9x/il/0WpxE\napwwCmVolMBLQTJlXJf4gJpqAAwdZe/jXT5epCHLyvmdy37ZSg7HjvPXJpPL\nAQ58WEZo5btxMv13GmC1rwMX7DyHTjo9r6WQRFphlP6wpyrYE/MzwC3w6xU2\nmK4Zonpn5BxBeBBvFqTZPXV84KgXH3jKgksleuGCPcm8P9IVkNP636Hf3iuS\nUGd2b+IzG530lwdPwPM7dUozZfcFtrbCQ1iLJzrMSnEL6I0Z1u23K2Et2Aef\n2yQZDKA60/uQN/GF9eC3JUCvsspkDoosbjEIJmR2WyYN1q2u+WZCCyob0pvR\nOEsJ\r\n=bR3E\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpgK4IeyJEvvS+MbAee1lRsOSCxEPfO8/wtQmYQlCq9AIgL+LNSjhSsF6FTv/5cYlwZosZ7iCAtGSvlJjiehvpSDY="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.12.1_1581473778406_0.8208740000783279"},"_hasShrinkwrap":false},"0.12.2":{"name":"file-box","version":"0.12.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.6.18","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.6.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.9.3","jsqr":"^1.2.0","mime":"^2.3.1","pkg-jq":"^0.2.4","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"757f4036e013d0fa9dda77e2238831fda49aae3b","_id":"file-box@0.12.2","_nodeVersion":"13.9.0","_npmVersion":"6.13.7","dist":{"integrity":"sha512-0Y4zpJsgHO2n4m+Kcc6WN+uz1jH/g1vAiLsr5MapbJmeBHSv58vjImHc42SryO1P7pd+jCsoRvntPGYep2e8+Q==","shasum":"cbfc25f687a7bf039dc49b5b136f441e44dd6550","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.12.2.tgz","fileCount":75,"unpackedSize":192576,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeT/7SCRA9TVsSAnZWagAAnwgQAIouDYR9wDEEyvgDuftr\nLpVBKYLhfytHsmtUjrmLo8WsrgXqTdLiQ9R6H3mwO4ujQZmdXrQyYtGh7FlN\nrOQ02CEzI6YR5AaNHvnQOIEt9Xi/FrIq+lwsv1DcAFD41GKDXySHkK9vAJm5\nQ37yAfLy+vH/rvRqm6dePhm3WWtvmB3aCKLXkQ8RXo8Gz9n9mRXalGVVME0J\ntdNIHI3DT9z/NLe8Nk2Z6DUmdIJRDHuVmuhCryWt+nr1wAHIWAtSGzuzrJhQ\nCHXjPly+g6ha7e0RVc1vuWOfbILB3Fe9WQHMV707QqFzz9xr1HRMJut4OiRv\nlBdTbL6JFd8dN+CHro8EObqCZfeP0kRt0AOgMhW6cuxyFBWv2mFcydgH1AL9\nQcZRsrIY9pzACdjiFwQ/szd1uy7u89UYOJkX5o1TZPm7nOc/CzzGnmiQc44S\nn8eteYcBmb6Whfhb9rSx+/THaAGOvPMo3PF3MczuqUJDF9EnNwspBZv20yjf\nZ8sT717CwsQjg0x/oaenM3KLK3EtZTVFVdXg2pG4rZeeeGL41fwKi28PM3OS\ndGTa5fEiRwHe2Fslp80+VVWYJa3VouU58Lav+GF/9GSBCJWpSaKAowdNmfop\nGYcNCi8eFNtPrkaoRjqipA5JoO25OrQaUWxPeVP1hy6fV2Gy4+mA0NYB1wdx\nqeDi\r\n=zNxS\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD6N4uwVta9EMnuugOeCAP5FjBNt1XtbSSzV0/z5XhmoQIgF+Un2rcMRXCZx+44lKXlfM924L7OIg+bsPPHwDdvCsM="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.12.2_1582300881713_0.5788806966738769"},"_hasShrinkwrap":false},"0.12.3":{"name":"file-box","version":"0.12.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.8.0","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.9.3","jsqr":"^1.2.0","mime":"^2.3.1","pkg-jq":"^0.2.4","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"9dbca4d41841dca87f37e58fb2347b31396a3033","_id":"file-box@0.12.3","_nodeVersion":"13.9.0","_npmVersion":"6.13.7","dist":{"integrity":"sha512-y7g1EpiYSkdx5x0DN6nAUm4D4EEH+cDJkqrMZ6xpbxldMjPY1GsU3yArJmjVkmBqYNu04opDOVQgoK8eeHQR6w==","shasum":"07c0ac66f26f3932669dd276e0ec7444a3cd47cb","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.12.3.tgz","fileCount":75,"unpackedSize":192501,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeUAQYCRA9TVsSAnZWagAABSEP/j7sfXPQPpJp6tPW5VTF\nyqKfHrVoHUj9gqz0IblYpVo+J+nvsFRj5hgyT09JN7rc7l4fGVFaLMZLXUEy\niTywcVdrOVh8rDQYUugnF1gufUsh3bXJpi1rcS8zFCtZsaj4EfXCSF950W6/\nans96MtkGCQB2UQqRY2G1rfsrd/5nOmHW0nHCiH/EsT7zeFJahBeyap8fTAS\ncO0nw9GhObq7IjpxrPu5b5zUOXVKnQ23zP097t8X9aSgwXSllJngZzzKxjBB\n0r5LZ84Ry/dBsp+Yfif/+8B19PuqcBGwh7DWxzmxR4LvAazdXl2TP71qyH3c\nPTJjbTsfDntfF70o7HZQqzwQiz0yPyA936Q1OfyK38Su3/PBzfy0+Uonc4oQ\nqR1nsp8H/mQ9cR/Hy9wCJWKgMHVxAUf6OnDSBlBm33MJ5x1bDD8n35EyZAOM\nGRxIhGloXlcy+DsmPJSw2UE7yDflLsJXYWhiJ5Sah686NXcauFMjJqHmltTj\n6jlmpQYiDmBN+vh5Vr5l2m4Kuhl3mcAhxaSY+JkdEjJAmmXjnCyYTC7AZYVI\n1e2N8NLd/8y8Bo8eqG0FogEs8XFS8DmzVzEx5TyCa/3Op0yEu/R1lkd4NZao\nqhgEoAaVAfhyoW4bw0KL/ilPtDw0xgRlAyF1lkZ56XWLF4Jb7ebG4pJyOG1P\nUkKx\r\n=4uZL\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCPvxDMsJb+vQCEuRlIgf54d+mDTysnCt4bRhJ9/c/vkQIgMk4LKV+oMr9FbibQB9CbX+J6xLROuLLQWr9RLnWMb/Y="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.12.3_1582302232141_0.5547910601910899"},"_hasShrinkwrap":false},"0.12.4":{"name":"file-box","version":"0.12.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.8.0","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.9.3","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"424aa5bd1f45dffe49635eb10ec41b4b3b5c04f9","_id":"file-box@0.12.4","_nodeVersion":"13.9.0","_npmVersion":"6.13.7","dist":{"integrity":"sha512-9U51QdPl5whzsNkjvDL1qNvFL3U2jUkxLMUjP6dPURUZQ6MLmro68mE1EcXuOKDx19hzTDJQFMB9dqtFl/fp+Q==","shasum":"2fcafe74a49fa04b046356c780369d50b88f915e","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.12.4.tgz","fileCount":75,"unpackedSize":192501,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeUoVACRA9TVsSAnZWagAALXcQAJKy4rWOWBh3jHqXBIZi\nnNARrhSpwtPrRf3OUSEiJCwvXialsdWe4IZYf6kG9t3C4zKqAx7vb7IwOxYp\nKzVDI9YH1YIlZO4IXegoBiSToXKNw+AyNKrp8WgGSKxz5hG4y/agrcmeyTpL\nEy09VtaF9KtdqDip0sS5M0yznCv6K+UMIqVMZzCu0wQ7mf7EqIIOEJRA8ep2\nQfmK+b0yneENxXJBAYUZVYTKA3lGgqCaf+xisE6Rbf1XStYswufp6S/A1CsS\nyKSTwnxMewUL7GeXoX8Mr3Ce/REGnPSZoUUSEJBaslJlFJfCABdIazv5aGCZ\np2AJKw9MEQjxx8jeL8yiFAAhAjxx+i02cLCXw+QeWW+S8Yg4TgUBInnbMgqn\nR59KNz1gN9aiqcqSckAe6y7ijNMBmcOuvZ+TATv4CVDYOYpP6JMIHD++8M2A\npSDqWoDh2S0IKVPfgDTKYet63jqZUTs92rP6Gixq+oPGo61x/mIiNgJCEzVf\n9OJsoHmjsR2+Z4Vcwh54PL51mvm9LKWDjzP7HG1iIjy5nNg8nXvr5qYEUfXJ\nihO/4Tvxht+4aAZyRUUjjTSD25NMA10SjKQe3VxcyybEUiVWmt6e4hYDmvK3\nD90vkM4GXYtolRH2TAVooSnGfEAvDhe9cBwFzCI6joo+NuZXxEVqUx1gkIHC\n/k6e\r\n=rskz\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD8vLEaXDAschmAMfNWYTSJa7NMOcOMhsOdT1DmFNvSpgIhAPwt12IqUGXww7y0/1cnRLS1tcQDPn8oCSEAYku3YvtJ"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.12.4_1582466368163_0.4313896390089491"},"_hasShrinkwrap":false},"0.12.7":{"name":"file-box","version":"0.12.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.8.0","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.9.3","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"2d8211a39d1a2d777ec76b76ab1755153d01e6b9","_id":"file-box@0.12.7","_nodeVersion":"13.10.1","_npmVersion":"6.13.7","dist":{"integrity":"sha512-sL3Cee6o7u8Gpe7xkjU2lstqfWo+woE8Smv2wxTp6cLHzkwPtniiO4dllb5HYrZNxlmTdURbxTi70jILRnA0EQ==","shasum":"0b124a649551af46d7a10fbb731f06fb97ea26e3","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.12.7.tgz","fileCount":75,"unpackedSize":193532,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJeZ+qzCRA9TVsSAnZWagAAKSEQAJrx/UBFtKjZSsCmmSBQ\ngnjlTBGK6dw5CUyhdMquYJSEAGmG9W4OW76aZuzlRq7yoT3WHPIg08nnDZa1\npw7g5M8Sw1+y0QofS2zLEMF5PJwAD1Y740x9jX7v+b2iXWFRBDPV5xFNKIwn\nHYoXd6HRrJs8Xhww6MmIPjyMModzVrlxuQPvecS5W9GcNmjdX+m0kYDNPSha\nsoShsQhnvs2TWy0z1cr8CijjqabwoNyaMMVqJrUgLpQHnAwz3eLKiIy1IdXC\nCVo4RxRuz2g+Zn3YrZ0PDqQwCAMAImDUN4b0PhJ2HLbpiF8Ud7uQ89VWvYfa\n4oxNnrILIjx9yoHoa3VDq4HRD7EeMTZd7cizaBgSVn0A2j1HBo00YFq/tkRR\nfJai+0Y7UK6KzfSnxtYHy/F/MhAkYqsPq5IPaE3gbqDy5KJmsgOBripz93/2\njUjw6m8XzO2rYhEj8zGvMwQs+7j+Lz3mOX447t9Gg4zwzbp5jYxOPeJH/T43\nnZuqJO5kfCdvV1cJkp0zKARkn5T1tQLSEKfkKnLa4N55MvcQa4jzgh+xvh1u\nqQOQJ4gw3iz0T2WJQIGvkntk9UI+8mk4Ob8mTrTFkWg+rFSqjJm4tFo+65x7\nom/TtYkOJEVg0Rt7Z3NCLwcudcWn5c9T7b+sGhwr6R65xhVbJMpyrj/4khS2\nfY36\r\n=psyc\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDiQIIw4X23HqtY5R2+n+NgDZ76t7xDu79jLbud/+aWtAiB+jFKvaBtsiDovDFYoh0yRW8eDUihKLMm2GlSGBD0Vcg=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.12.7_1583868595198_0.9084366206791163"},"_hasShrinkwrap":false},"0.12.8":{"name":"file-box","version":"0.12.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.2.5","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.8.0","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.10.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"d490907956edb53bb2eea78d565b2e98d26c45fc","_id":"file-box@0.12.8","_nodeVersion":"13.14.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-SimgMgyB52Ikrb6szckAbCh3h3MtEF4EnOCRbf7ScxcsqnVn0s0BV5DBhYiyasiiAi27zoaIUYNEDFRUy0uWSA==","shasum":"ec5d94c9c0ca990b5914c23c7b216172460311f5","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.12.8.tgz","fileCount":75,"unpackedSize":193529,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJerbV4CRA9TVsSAnZWagAADOsP/2gi8iB3yiR6mMSU+Lza\npTNfzHxzjquhWBMVR3YggSeuWW1W3oWgMm0k66mGFcnTCdFEfcJw7ZDkK4s4\nZL7DPGCdZF9NkvGmf464nZlnS1mM7DiQBGy6io5/CAz4q+xS9hUAvc/4/Jz9\nOsTMm3wJ0te67RNSRqhJPogndBo87q/bJXxcK8NxR+w7i+UsBIV9BbT1gxPZ\neCADvp730yjLjHuDWFTi/h7NXerQbOTJjp4pWM/nYX/KOJJWKcYbLtvNzKrn\nnWCJPyZ5SzA4kiiNANgZBRWKHivrZo+So7RKwaOdcWHmpqKTl/38z5uIqzhl\nL1hRGbUCEqowUTXSa0Vp4mL6MQYKF7Vk03q/VdLbNKXtIpp4yBd8fr+V534m\nFoR1Zdxvt8y1ncM+P+3FYQyiZZ1VA4eng0SmGZ3zK1rACv3Iva3yvISIVEx6\nAxSqf1AxIhQOI5/AvNn/zW113UWbeA5/5fa1EmX1koFrnRnOfOanJRXY/G3d\nu4m+c/+0BXyXiAZoptzUsqyMed+xGdnRJbY0bxEES63VPlRd2nV3exzoIFkv\nvNsEpOoR6SrNtqqgeUSYTxBea2rlYUhOzEr+xTF2y/FEzBu5Rn9kH4iIh7Hy\nlcm7yq2lz6qk55jnceG3ZfPI/o7LPuNDTW5Wq/zC+o5yTYcbEKyb+wsZPm3H\nCVcK\r\n=W6nx\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICVsZgR1xl272LqLKZROIs6a60QdCu0V+XQgZsOBksy+AiB+qTVxyI0OUjv5zm0NIbbjNLahBd0DCMIW4oTSUUSkXw=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.12.8_1588442487765_0.4283502821396856"},"_hasShrinkwrap":false},"0.13.1":{"name":"file-box","version":"0.13.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.13.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"5d38aa86d81df929f5755e13a59ee03bc4a5139e","readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![Build Status](https://api.travis-ci.com/huan/file-box.svg?branch=master)](https://travis-ci.com/huan/file-box)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlais: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.Flie`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FleBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable becasue it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Thanos'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demostrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional informations. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)) zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018-now Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","_id":"file-box@0.13.1","_nodeVersion":"13.14.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-NJ754wtU2FS3t4Kn7VOccv3MBsASr3X1svTURI5cLk7dv58EIc3BnBNwdW87xVAJf1vv0UpRRkrCNy/BScRjFQ==","shasum":"6fe25ecc1332046f068ab66328ae510daaea4cdf","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.13.1.tgz","fileCount":75,"unpackedSize":194582,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9zMtCRA9TVsSAnZWagAAfjoP/iS4g1xap4q+UpAgkKJj\naSD1LNrpwmDdSWajV78pI8zAaKk8kKjTG+ZujUl9lvDAKi4Ow31i8Lkot6rz\nAMlitkxuA67tDtCnpU1Wx2s+rSq7H294TyOlqD410BC5OmNCfZLL3yIq4j7W\nbVy1Kyqw9yauNcwlx7HMv1EsRTKhai+XiOftCvLnYAr+POg53lc/tOCCZl/Z\na5AFzF8f1YT0S0SdVELvRNgmOzMdshX/GU1h6QwyIuDgy60kiJP2pOzDqxZL\novNmmgihbJKcXUVFY7H4J+tcQ2nDcsfvL717MQHFwbZ3JmoqpawmdKPwtXnd\nDCPmxurz+0TTR3r4DCz1MYFcti39vKVlTd2SRyWE6WXFRHCKrUortXN+HHzE\noU5VhdDOCuRyl8XSDV7U3J3Hwa+J5H97Tx547Qc8yiombssxT9DM+zvb+xyh\nh5j6oSz+gt1XvBSE5ow6Th1WreOOWGaFdXLm8lOtBInBDRlhOBEoNMh09A0V\nW4S4N08u1IP7xcOgxOBBBxhdxdcTWet67+pKRzITPrKo3RwfWiqmJ+xbiDBa\ntbKe5BhfUSmsNSjuvpSNMv2uAHtPYbfVpTYAVNYH/d1k1r+QPJlsgtjt6oPL\nW4lzu282EZyvMSxxYEy5+mRH3hCu92gMTw7mRXV6t1s5errneoz3Ndti+/A0\nxP6G\r\n=6GRV\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIG51cd3ZSSYKQpxF8ZyqYSHr6Cy0Nq3HBCO9jg/1Uoh0AiEAgnquW7rabGWKjHfbWeIMt3KPnrc+2JwVeKC25FqQ38U="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.13.1_1593258796560_0.4794432045373034"},"_hasShrinkwrap":false},"0.13.2":{"name":"file-box","version":"0.13.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.13.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"cf6fa4c33d86473fd152d4c9d312261c8747141e","readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![Build Status](https://api.travis-ci.com/huan/file-box.svg?branch=master)](https://travis-ci.com/huan/file-box)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlais: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: NoddeJS.ReadableStream, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.Flie`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FleBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable becasue it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Thanos'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demostrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional informations. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by https://github.com/gulpjs/vinyl and https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368 when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)) zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018-now Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","_id":"file-box@0.13.2","_nodeVersion":"13.14.0","_npmVersion":"6.14.4","dist":{"integrity":"sha512-LO78ethmbUetQDuK32CxNuQ3XWz1O1RsMLZe3k82RxMeNR6jJLOV9ke4G6A9SCD9o6DiOJv+bkt4wqzhiRK33w==","shasum":"85dbcfada832bc25b667a16e62abe4e486a7acce","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.13.2.tgz","fileCount":77,"unpackedSize":197505,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9zQ3CRA9TVsSAnZWagAAdKsP/3QsXL3UntGgesrbThe2\nzwJytzwRzJh69brsDBvbL+yPrDL4KFT/cpjrW1FTJP33/MAFykJKUKFvu4nR\nIPZrFiN0JkUquuAOeW6B0w8E4b+x8nJ68BcgLi283Ww1y4PzmMDHlF4woRLJ\npqybsYqianqu/1uFnoH7flwQQQLuId8np9JAwfPHzhBtYPfwZ/InfXOnqO4Z\nWf6VKSsQQGZaSLE7tdWTAfrQfZ1IszTyhnBWvmL7rVJGWIISABukI3/HwGhy\nZ5B6LMHIMYxIMh45yPxSSFb598RQrQEYhDPVthMbnqFDDr2WDqbxFc2bqnkv\nQCU61OA1Yq02hpdj2S/PdIFKK1NxepVL4/PldqCBFfzDCdoKo9HFsSDKErAD\nJb4EfJHXWrrIt8IBKQZWs/S4VRaL0sWE6dPY6nIKk9HDzLA+CcvVwq8ZLULa\nOCo8gXITBsAT1WEFCfeRsvhmEbMS4D3vTwoPgO3yJBWGg0SO54D3EttYDQoW\n8SIO3ZsPFOgf1IvKHmSWnN/nOvsE4Y0mPLs1M7jycVJW1a1Ux10DYnVrXpDR\n7tgtr9xTNVss/YAyw5HoHgLaT/hC6yVWqMYJ6EyB5pBGg81FW/UEQBgJcwru\n14TasszyAit2HKmCjvpD0HbvS8QeivPTgc4PbSQ1j2VdPxqivL5komhrMurT\n+zzf\r\n=9or0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBVzTX09ysbU1+afUwx17p1vAEIF4pvLVx6rm6v6XbUvAiBftRzDicxcxqKPtHgiB8TkDquHJTlHRq6Rd52ZyRN2Tw=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.13.2_1593259063162_0.6892673226180239"},"_hasShrinkwrap":false},"0.13.3":{"name":"file-box","version":"0.13.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.13.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FleBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility.\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"e5c96483f91096484cb44d45eca116d097c69ff0","_id":"file-box@0.13.3","_nodeVersion":"12.18.1","_npmVersion":"6.14.5","dist":{"integrity":"sha512-Mg/a/XwspzkCXJVmf5prilZPnpup7Nzp87JL23PoP3YErPre+05c8Sg6I97ekifSuK+GAmljlqvonI4k9n9TJg==","shasum":"21551c1ef65928f6d17c774f97803c4f2182c037","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.13.3.tgz","fileCount":77,"unpackedSize":197300,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9zWMCRA9TVsSAnZWagAAVDoP/i/hYVlHgBkuCZDgJCVy\nsH9MFgS3wYx91fddcrljfRTM8lsehgh6Lx6UTePbnpznd3LUf1pAhyDAOpMb\nGrsYJYuCpbabkAofAB1ZuxHnsJon6Tz8aAYriguoL7N7AxF2bck3YzjWO6Cr\nz4/JNTcOifVwEaactSkv0yYoGKFXnMHhquJZoDPjoH9nwvlTGgt/j5aninbu\nAisnag+HyDk+hOLQOsyoku1U29sXxO+UE27Lde0cOyDno8OGWBFgtGiM6K7o\nsCfKd9Io5MmDH+NWprNv6RklFetb9AQzzSdVNI74rjfHM2dRDGOcvBLHwX1g\nkSfBIBK9MRGN0pt2P2aCLQJpzKV0YsvMRPt0oMp8nzUtQMT1stjfSdsjXLhz\nNbtRPMtpPce6UiJKfBYwJ6fR0RqJRvtDJqFPhwCgUWfkA/ARl3VUkMCsLb1u\nmsfbGaVyXTuw4oP9BiWFwYT6pD+OyqBSVgFbdIjDBllGP6vdbti/nGI5HdB2\nVDT1XWu2U+tdqfbPMtivKTTbvo1EeFroXDBaWDEA12n92eCgUzcAZlwYryLo\nw5sCJcMGI70Pnb8V8jJKBRc1f320oKPyGRSSyWrFA3xfNhCr5DUxVhl7YorS\npPVPT/RGQEWF2ClWOysj/LWgt32kYp9DLHUhkNjG09mmELB3jOxQ+L6jK1O2\nkSzk\r\n=+UOT\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCo6pF84yJ0D9DM3qa6GlpObWrteZxkjjzQXbJ03EKQCwIhAO6PTcn3Staf2R6b+t/mmctG3I3UiEXC0ZZcpIB2sHTV"}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.13.3_1593259404546_0.9287097128814386"},"_hasShrinkwrap":false},"0.13.4":{"name":"file-box","version":"0.13.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.13.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FleBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"01e8225eca7d721abbfaad43cfba613fb7a128cf","_id":"file-box@0.13.4","_nodeVersion":"12.18.1","_npmVersion":"6.14.5","dist":{"integrity":"sha512-83didIoc7vq/sh25PvablmAnoJnc1k9MGLNBmdCn3sUPhwzbYx9MOGWwfOCC7kNXvUwCowwEUSpjbj+8k1AMRw==","shasum":"39f5e1bf4e6b828dbf2df1be1a6c80171a7de03d","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.13.4.tgz","fileCount":77,"unpackedSize":197315,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9zZMCRA9TVsSAnZWagAAAmwP/jnMUYB+ObRhSqsD8ICW\nG2DKxjrqijwzGX0jWPkTj5FGY+wcbRgpnEUoQdP3zTN+mK60KcYaznSVQQ2i\nkDRUocmV2GAY6ssnnMMeRPpQh1j+Q2C8eDlCJ74ETS7LEP7Zuwty/3pVGUbq\n7ISKPk/EWFFXzflc8QLJ4hlOA4UHUNKgAeTFzFgWbjSgcPNDft3Ea+j77Gie\n4UOEjWWEsRl7hsd+WkG1R0m1EfamKCiPldWiamqMv8ZEaCQxpaiI+diidYzn\nZzG6rIr1hi2JF7SXBEOduDXgzA7I+8JhQscZHGU7ESNxuz5Cdf0oOf6TZqYp\ngE0t/KpUtPryyS/bbfr501jMa4MKtiYwsN2lxLVv6b3J6+XnArJJ9ZUds4ua\nJbJT44fLsPqVL0iElLXHhJkC56U6UL8LAHZVKQvaeshD6439TLlmhnAhxqjT\nkpEbGdWPa5QN9YDFkzSDlOScOMmNMQdQ72LtN/Tx4H6a2F2lsRQRZKWZW4tu\nFgPIapTL9q1Mn5ptWzugwwo8NcoisZAT3ab7fxHkR6x/J87CXDNfvgPk07ZG\nWB/Wu+si0jiZ1l/fYGu1/S23RWIzB7yD2x2c083UCJ6UckqGjIy6pMBNOM01\n906AIu35QYSLwMAy0elIMASlLWohJh7/eYx3qq/wEThrDgIC50S7Mize0U+E\nktxm\r\n=MwLC\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIF01Mf/SftT4xt419BKiqpkbJ559S38j/Smqnxflpr7sAiEAwZA7gUP6VIoxtn//hanZklIFJ5PgotP8aoXXhs/moz4="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.13.4_1593259595940_0.9131793839656119"},"_hasShrinkwrap":false},"0.13.5":{"name":"file-box","version":"0.13.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.8.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","gts":"^2.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.13.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FleBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"e42d7207bb1cf5b76afb8ead6f72715f4a197b35","_id":"file-box@0.13.5","_nodeVersion":"12.18.1","_npmVersion":"6.14.5","dist":{"integrity":"sha512-xFUQyEpRSSKVe99BJZ447hXqffxrQgAvszubhMyeFiBPS/2xZRzgEX3/rrEP2IARDm2kJskUB2nS4BiFp0JOWA==","shasum":"69375b8e097300750ee508d55455189fafb24aa5","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.13.5.tgz","fileCount":77,"unpackedSize":197345,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJe9zq6CRA9TVsSAnZWagAAn7YQAIuMLuqc1gwxW1T8Buam\nZ7vZm7+7HzqnEBMRLnX7Ep06YYtZxPEAIUAhXAsQtXVz+hqG4Il9W5LgA0ib\nimbt5/XUpGTzgveoxy5QKrgXwn+w88XSKe5QjVnRHr8LcR2V9Om7YPhxuFsf\n0i1+mtwjQf/INJu0dFfk0jZKp5OIFNuSAonF56qBO6U2Jolatkz7WmTeNwPX\nP7NarQzP6DzEL25/c3+6hDfFKYXcI7Iz1Ula4cLhcfFSDb/5+ssIdkymp82v\n19aB0m0fEyaS+wBSlsMDayaLHr8mqCKVqwc1aES6ZSdqxX+LamcrgXVjIdO4\nxfMDieDjahele/oynfAgwF73XUWmTgI+H8w1vdVEFCH5J6mA+PX9J0E7OYi+\nQRuWhDdzPx4lUZBA0KfxzoLtCjo/qW4DmocAPzu14KCh1ovBMejSEQzeRTlT\nv5ZQXI1oGFhZuvfvHNW4Yp/VWaXhKGx2VlF+6qqZ7g2ID0tJDVxGs91W9O/F\nOgy0vOkyvp/YEXEv+62QiWyM8TFdJu/5QmbpEY87un0ESbPOj+NkILy/HIqH\nAvSkIOSvG/cqf/A8bEE6N6aGw2Lcb7J5MM/3t3JEY3o4b5ymBnNw+Dr/yY7X\nWeCrX5XSv0BhkiPHBB6h3lq8tXFvrnS63igxpECFT8mFFWPmF8ExW45tQXxI\n9/Eu\r\n=RWKE\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGJQlkKXkDZPGTGEj1cDenes594x8RW/muBm85XvubIfAiEA6P+Hul67Ubi+lGGjLimzKPnAuHaZrszaLbyVPiNycjY="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.13.5_1593260730439_0.3111648951208654"},"_hasShrinkwrap":false},"0.13.9":{"name":"file-box","version":"0.13.9","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","gts":"^2.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.14.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FleBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"cf6caf5f493ad19097ab00aefc3a9fbfef0ec99c","_id":"file-box@0.13.9","_nodeVersion":"12.18.4","_npmVersion":"6.14.6","dist":{"integrity":"sha512-wUGpR7MDOKwfF9BZ7NY8+dUPxeLWLVODyKdhTdgmO2qPUrur8R1Lt86N2h0nGOs9xTDpCoFoGEQfjrMsWPSJaA==","shasum":"80de8e9e19ebef0c833061017808cb8cd45a0c14","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.13.9.tgz","fileCount":78,"unpackedSize":198057,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJffWQWCRA9TVsSAnZWagAALgUP/0giCowdrD06vHpQWkAh\n4u4vXDCkC3CgOpg3KtWRUyE/OIHxLl+LB6bqeDMJBO/zMWny2VFzWtxB+IlU\n2jEUkZvfyPlsjWXBUPePOCCDMhk8mCHWiBVnJQUYazc/vd1dAjwg1s55tCni\nSQTIZlBk69WA61Ap4WYAl9Wa1uVrd+vRc0qqLR10mIyBWKF35PXlZxibxaxJ\n27h6PrdFyOcGXON1weXIto3Ym1rajul0HMdLLIHRQ8MpUxFu8Km7etn3R44V\nsxgApYR4hOCGJJI+sUaOQN2byJH7tt8JS1YDi4mUMzULap7K5w+NsDeYTxRb\n21rz+8Z/q3EeThM7yoZod8OKaUJzAIjKOT5bNrx4KaSAggo2rxfqG1KAntEg\ni4Mj1cKMqoH1srq5ZnoV9WImmQ/uA2WcGVqOpE6g+YNoQpzWkcHu5TJNTvNl\n11YHtXF5p8LPfKdjsvv60KVvPKuQwiI7VS3hozs/e/CbnUOxz5lN3PpE2n8J\nksByTcwLsgt7IavUINBoeD0CrrGaLX51yp43hahs7FgmP8vbyFTNq/PY+Uaj\nbMioLV+DK1cKDCoXZqNzI1ljutbjdBpQfSWIvG3ipY0ub8gJ2m+DsyG+0TAt\n1mHvPC4vdNZ/W5HCQ4uT+WMuIICprk4CzM1fAyQ6ZFRIgx/Vf+X4LPDhNs/k\nJHpF\r\n=/ahj\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBWlkzh7IN2veWYh9vi+YCZo5Be8EUXUw0MCbdukLkNjAiBSh+Q2tZYoG9rnRlHwXM3ZQ9xO3Vl34l/oWdA5m9fP5w=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.13.9_1602053141590_0.60393931109366"},"_hasShrinkwrap":false},"0.14.2":{"name":"file-box","version":"0.14.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.0","@types/qrcode":"^1.3.4","gts":"^3.0.0","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.0","reflect-metadata":"^0.1.12","shx":"^0.3.2","tstest":"^0.4.2"},"dependencies":{"jimp":"^0.14.0","jsqr":"^1.2.0","mime":"^2.3.1","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"401f5a21467f9790268e3ae61d233330b117f724","_id":"file-box@0.14.2","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-vYLQrBUBLm5b6T40ZGsVJd15YcRcON6Rkf1K4sLUOtK68McdyjeuHgC1mK1s+YQtuOspy1DhpzIGHO4nMyR2hQ==","shasum":"b1a8622823033a29bd409f27c6bfab2c5e9ee5f3","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.14.2.tgz","fileCount":88,"unpackedSize":207982,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmCbdCRA9TVsSAnZWagAAK84P/j5eEKZuFXqRjcMrzJ6+\nbcSAIzbM3Snq6flH9VbuKV5yKQzUjY9gtSBx8k6bbjL8WN4rp5JU+ktyvG7G\nQq7UaHngsDVifpwuoe1ZY4z3nRsVujfPQm3AZx5qFHtEfESsJvNM8GCkKcz0\nM3O7et+8A8XXRoGCTVtrFAf1ynyyghe1oBzo1womFAYChFZbFGUH2zxGNKBs\nh9KlMJMEvKZUyDOKbOkH2rT/rNhEd0tdxZjqZ2s/BSfFyIm4cL+DTQsMdOpJ\nx3he7asSNq78W+WAthu4sXY2nRPiXZwBuxo8C03fLVFSEKngtZCUkreuXWw4\nEtbiAEG2TU/2WhUPeQNu8YlIphYfycSxpAZMyW4GkOg91WODxXlWD40gRgxC\nV7p8j53/jdePHquJzcId3IgJqzgCQvA6E+MTCGr3zO0+aDsdk3sNP9yAQMi7\nXiafBTBWPxK+ff0g0LHZczw+oG+8bCmdr/FyN1THl6MvdVFc51waeFSg8MIh\n5taNc8lyaChdTuXKuqedjJHiKhduQK5ZTezu660FpSiQoBTPEvm7qlz/CvCc\n0kyWLe+l8Mca8x8gTS/00Vfy9scHOf9X+FilXyrHkloGnstAjSbOJQXDZZIk\nfWvTiH65hhIhUED0i0ogsy12sWKuMyzKUN7qLd+GA8/bRo84AgIqJ2YDUTWh\nP/Ys\r\n=GTQI\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICqS2K3uJZ/6g8yBK0ROxDjH+Z5HDktn0C5dakn2+4qQAiBA94ofh8HHADRvyLIaOIyhgNfqu/ia35f0UpfWSqbPUg=="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.14.2_1603806941491_0.9519727084511376"},"_hasShrinkwrap":false},"0.14.3":{"name":"file-box","version":"0.14.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"77e88f5ab3d2293e6422a16cb1357060ab3f1350","_id":"file-box@0.14.3","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JgUhZWBqp3majN/wLHHhtVW76IGNw8ElTM0kFscIf7YbBFqDnrDQndsT+/Qx7SRZgqGGcmY03mc8y//40tt/Ng==","shasum":"37c9843d67983972a21096d9f3004682c8ced572","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.14.3.tgz","fileCount":88,"unpackedSize":207983,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfmCdMCRA9TVsSAnZWagAAs/sP+weV1XXAq1bCufUhamPr\nVx9H9kDdUG5F4uijG3P6SJxNfxFlJ8iEpPnAdoPWREGjfP8yEnI7Gz2u5Vnq\nPh9w2lqgcPILHsRxsKA3XhMCY2USLPVjFAxrHxthqx/dBgzTtHfn8Z7YE7I8\nBo8W3q8jRu4d3NjQ3g6PkmX2AUL/GPj+8R5pCrWDXy+rHyFZzWTjLrpgk5Q7\nWBxz1JXA0bSHdb++qP+GhUlRC/QmIN7jP2HQQw1nQt9TGrpZI7MBhFo5T0+T\naTEjj5jrFdBDx48MCIzkaL9kfaRxh8FcpwQy/OSPABg+8qMWUB0uDVqYwfkR\n6tuvos3kZQ9NToPRYHz1LFw8bkyXk1CUdYMfJ6VZFO+/RE2F6qo88it/Xsc+\nXh5UnTY3OgwVdQuFuxK29qk7ENeMRaPV39+OExfY3oUO244xLqROv2q8Wtjf\n7nCZMA6w2WmhxYEMu/keC8Oe5HYpm19vKy7Nu6zcrwUM/y2lbF/F6FKZIxVb\nQsx+yYGxIl8LnyUCwk14HFs/b4AURTNIhk4qTt2yhtccco2jj4kWajtgH2hf\njfNFJR1zRi3s+uqTXLBanBGo/CAGE/LGEo4wMN+zbY8QyjEaayP8o6ldLDUY\nqbQU7lxxN+L+n2Zg5o84IyLJKfJ2tbmH4ObhnHRLgyVNC3ViX+SrabqPfRBx\nWCD3\r\n=P0oF\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQC44fJaZBBwA5oL+YwynpMR+G2MLiCXameozKykaHGM0wIgGPoe9OBMUuojAMyB1w7ecYuTaZnYdLfYBQE1qS+aFfQ="}]},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.14.3_1603807051714_0.823993283970492"},"_hasShrinkwrap":false},"0.15.0":{"name":"file-box","version":"0.15.0","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"456353da2044024c6e442b5f83bf37f5958810d2","_id":"file-box@0.15.0","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-DOl7vCXFdxlcjW/jztBCHCcc7aKEUgLg4FVERshE2qPKLsmM58VoRwV27IqI03alXqHSxE0mWERLoNa5y+78BA==","shasum":"5f21a2ee350937760f579db60db6a3d540e9cf4b","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.15.0.tgz","fileCount":88,"unpackedSize":208275,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfo8/2CRA9TVsSAnZWagAAbCwP/RUkBqeVSXX03Hf60s+c\nxnhKE+UFlQHpE5uCt4oXhEL0XFhGdP9BKXHY26nConUa6EsCsrYWvPVgfie0\npm2TDe3QOxQI+TVTIrUNqP6QvQE8IjUXQAdwfUJBY2AlJfwHnM3LuN684akS\n6ZwJjBELdlfV7fnWjbj3eBGp9CnW6AsVaFpBU6BvAmzc00s5WDebYxEBcjS9\nSsGQcB3HpOp+SRlA0KxkN6lw3JnMaGRBCObh2CPHjvecAxGK1oJRgiXhY3e5\nOfugcvzLpEQ9BIEpGbnkBukdp8kCKBAMHwT8IWO3ctGUXUJHzcnnbVl+oT+2\nxgMJaCB66qVxdeLf86zn4hWc6zoL5MC7+Ts8e+UWo52ztPZPml1r/iiFXdUA\nxsNZzhKhVgV8m9/YlNSqHmhuECKDCazwCXlO48oEr1UrRtPyyBvoRuFDPwiW\nV1o9wOB+bu4B+CTweT28mjseINcV5qr+evJj50jDHhpcXv/iR0y5XBtFBPGC\ng14PYDafREqHHpt8DPYDz/BDtNRNNSg3/QxuGeRp1pfJfAvaHALt1I0NcwmU\nLK5xYYlabs4x2y0pTdDB0xZ2n0z8eqZMh4CLWV38P4cIOqpor2iknE2VOHt0\nD5iJHO15aUl67YMw9J+izswl8ChylNhnMdriy5G02gezO9Mo2TvDAPagAMLV\nVeeB\r\n=Z5z0\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFgTWhAFifPtson7ahmRANs9Qb7peboEbqJUFQtmlKvHAiEA070htvmAlZ3XwE5kQG8fQxSS/mefbPQhOZhZEkImGMo="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.15.0_1604571124972_0.20240351848470417"},"_hasShrinkwrap":false},"0.15.1":{"name":"file-box","version":"0.15.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"57081b7829f5d2582280dfab7f9ab7a97991bc7a","_id":"file-box@0.15.1","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-rxSfmZhjD08+wqZ9eZmLi1Yf7QvutHmSpgEllDUxiQszsrcHzwIA/KQnnOoV32n0OGjFK1V4+eVABpPyit4kVQ==","shasum":"a2bc8b47a703f920c9bdab76ca2d4e3b60ecf60e","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.15.1.tgz","fileCount":88,"unpackedSize":208453,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfsBPnCRA9TVsSAnZWagAAHYoP/AljhD8kpIVb1L08XCdX\na1Sr9CzuegB3yESd4JcnQ501wv9OQQfxoiE8bzX30y/fiDphj2LLbldnPrK3\nD0y4kXoH8tJBajlELlZduKMFCXhK+r1K7fBPjiVaXANV1towlNAH78pVUf2l\nkNKeSBmjv7qFZKQujoKjgIC8KLDqSZc7hViu04xM6v3R2gzRt2an+lmFEKwB\nKcUX5qOLXYG5D5MqO9iNDScmDEl+hPwXunUYpCLcwFwKUqB4wBR+b+ZgpSUb\nzL3jqdpdsw/08VlFC4Bvr3PSy+VF+Qtu6CHRdWPP75gR2BiilVIL6Zcbtsby\nF1lXxf4Bkx/xQ8Ankk8RfqBrz7Jptz0feKid1a3ewfNdzF3k/Uh1VC59XGZ5\noTBEdx/4O+ak1TgQ0BWF9cdl1uGBN5iJXtDPZltxDTrsXmo9Q7FwDn6xOoTe\nshjFyYR7R1ZvY6ce7y5K0KikK0V/1ZHW4/59N2TVZZCAPbM+3drwdOAFjxSo\nNppd6Dg1WlgnXwz5hSaSBow2EBbw72gtgrANBVKusqtyh7+FUzSlF9iPLCpP\n0OUM57Vd8ON2dBqcbo15hdrsR1kRmFwhtUsyJEgOmPiYV/9KkbN489uGQbBh\nGuyPgR7fNbX0VpoFO60jvT+S5o4xpt9Z0W0qx+OJai7zTexhXhU25FH+dhnO\nmy3T\r\n=pFtl\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDatfyVBwHe6EeTY7FJ4toc/lN54P+/Ob+NH5ah/6UuXQIhAK4yQ75FrY4Ytf2m4+47XY7oE0eljc/Ta+DlgBN7smcN"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.15.1_1605374950771_0.6316577410049473"},"_hasShrinkwrap":false},"0.16.1":{"name":"file-box","version":"0.16.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"7cebe55cd018911d41ff56bf8326976f96f6ecc3","_id":"file-box@0.16.1","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-09b6gn+fs3dZ9rojzBYYx54RLI3jIbqKI7JdWkrqPoxw9WnVL6J6n7oIrxKJlI4EI+PKsauIU98UcjCrQh0C9w==","shasum":"89a5e42374e6905984bfa261aaa9f431a90e79ca","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.16.1.tgz","fileCount":88,"unpackedSize":208625,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJftmrjCRA9TVsSAnZWagAAkCoP/RYrz4w7l5KnpKvVZf5q\n7L0v4oUnacnHBopS9CBkyNyH7UyQAuOAWUKmcOMH6MqUfrfrATofyDZssUy4\nbxB6qLDCIdnvD3MdoSyYPfyUyuUwv9UAwCGpGc45Sf8SvWny0ha0OK2fB9Zm\nQUVG1/JKZAfakPlevf1weQIavJNCyKzBsV8ttlkzTTYVCTY6q/ZvjYCM4dPj\n/iGTlzlsOXDv5qpwA6wR1xJj3OCjza5pTtrRm5sA5kKvqiUv0Nf+Lp2EgR3q\nVXqWOVcBOVpXSDr8ytJyUOqWfPH61+yHuYcr7jpDWghDHswKkkf82XpNRFMx\nfbC6KAPyCNLIIm8Lxt0Cd/ZolLQOX/4cGMjnHWEwGTZo3uSQFEqqjGotQ4oh\nsXtXdL7WS8IbkPp6w2CeuzDYqddwet9VVB0Js1poMP9wiMZ6yvUm2BuOPNlk\nNRckjBD+0L/3a0zRbu7T9JDkD+9YEjmVmMSk3h101WuHM4PPb4qtt1ioweyc\nhxQnMHa3gH4oFNGPJfz7oIHTg3jB8wtp37M8PuDJWFdrFJW9f7dZ7QNVNnsG\nujyRliGVPest2NtZNFkZF4q8XJmqGXrdnJHVc+lPImJcfGg6xip4qzUQvmqS\n2SzRfTjzXWSBym1LbfTYy2HCOrXDVNgYDktAE4fYxHLJbhIg3XtDk7Cp705i\nrPh3\r\n=YV04\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGu6kL8N1eNbrayybHzWQDi+YDkofYt9MEXehLG7X1sTAiAE6MkHWzz3gloy9SChKPWjWzyq64YVHPN552JDi+x7DQ=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.16.1_1605790434557_0.27163005753361724"},"_hasShrinkwrap":false},"0.16.2":{"name":"file-box","version":"0.16.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"6d4c60e91b69b6e55e2bb90ed20131634d1cc25e","_id":"file-box@0.16.2","_nodeVersion":"12.19.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-pgqrmKJDcarMb7d8uXP6s6stUe8OtmLCP6dSkKGV79pJBeZvnU3ZwD1WJT7XfSwT3gOmAemB3GBbPBySsGZUTw==","shasum":"9e4cd94c99ce44ba7c5ebda5e19e29529de45d6c","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.16.2.tgz","fileCount":88,"unpackedSize":208461,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJftnj2CRA9TVsSAnZWagAA3uwP/0K21v/MpgWrr0aX+l9/\nH2FMxPGhU3d/dcIHPiY9GKdJNoKVdII2N3TfYVSiwV4NEL9xnws3JOWWxggN\n754b4qlTKoCRYdLFRsaB0PVR5QlnenuXKIS9jHpwu8hnub+9BvGDIt2ZeJ2b\n8oNsw0Ax0xph1cMez3r0s1lgOcI+4I6yBILja8B1DIuiy8YZO2fWGXD3oG7Y\ni2/QBIUTHImRQWhgvN1mKqp4DzKHMJz89eAHNCN1+OrD8t9+PLBxjrW9Z7lz\nbV8yX+pEv4BzqX1M/GWfwTJoZ3nejMpydFdpnQ29+PYFdu9vJluqCTUdCmba\nObefD9Ob7BGpV7nCQ8h9r5BrPP6GN34gV/7M7SwirHd2B5tEQvpTEZbwoHXW\nPizs2cDZ+J+Rya48VM5m4UbG5/yhN88e9zb+QwtPJp4IGKjFSiD8ku5ZIku9\n+5S61Yzoi9LvgdHNr68UFEmgHPUylcW8VR+nRpIzHZB2H7GAzEzR24RG9QlZ\nZhMpuy1uWk8/ngpiQcO8NoUX6vO1oixqYAWIHLDUE3zSVifR9Z4p7eU8bfDN\nEyh8e7V6OUgL9J81tq0d5bcPAc6ZPuECTClBg9VP8RoWOXZZmZt2iVLnklm0\n7tuW2a5C2fuogglWk8I/XasP7i9AIW5z5TMt7Q5+gMy7yolXZJe8VqxaEz2c\nTk10\r\n=Lr/E\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQD6q/9qMaRH3dtF9UxD3utH1DWGI229Telj3TyqVaF+PwIgfN/0dhC2USvGBcuNddvW4edbNu28cXEz4IlVlvBai7Y="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.16.2_1605794037714_0.9504948519079284"},"_hasShrinkwrap":false},"0.16.3":{"name":"file-box","version":"0.16.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"0aa539acbd1e1100b688e5d47adc8ccafbe5f28c","_id":"file-box@0.16.3","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-JvMQTWb3ZBAlYka5gGX7CRhLtZWC+MjnjxCweIq9flOJO2DvwE17dP/pLufRi3HKDLlLAPQFJSMqcC3nmBGmFg==","shasum":"733c209f5e2a4d016c87f5ed676a5ae00236c7ef","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.16.3.tgz","fileCount":88,"unpackedSize":210532,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfylKICRA9TVsSAnZWagAAOQoP/jdR6XOfReFcdoMbuNJC\nplMvm8CyVnNk1IeV+EJLlfkJm7znt2hzzuZV4GUQPTd9xmBxGmj9Fsb1+PjR\ndDdN29s77ojiyG6oehsveChaJTPKw0+lMtBPVZfnCKoADS3sV8qwOa1NWYWr\n3VqhMPVOi70pbkb3dIeiMH0FTglVX/dikvH1n2WxnNEh8Qs4PznCUFUZjB9E\nS+0N5GlxnghkJjpfYFojoSbudoADvFA0/6QxhoP1P63uer6llP/fIWOPJG+V\nQICoy6Cz8nOst2p5ootzNYRXZC/qcDsICBZfM3LAFOVxgC7r8W9zyejXVZED\nKUohsbpBuZgmIGlJ3qLjFlTvmja0kLplbWuKaHDD/fNbN+Lc1IUAZ0zFWRg6\nKFivjbzGmgNEWSM3Fb2s9JZQrzxbWaSm3XmEZ40imThqEixWjRi44QBxl5qM\n7DE+CiE4OGVcNYtnj4vz7T2Yf9XJB9B/C6FB+GrfbrvmqtuRW7gRBBCvdP0d\n/0dWF4Poa2uiWUAZ9KVy5oUxzlDHlY7TS2VpcG0EhP4nSlFclnTnbgpzsaJk\ndlzSVe4ql6FG/L2jGJPSJvHQVblUZU/byGdfV4pjxvLPshyF2Bonu2Ex8cSZ\ngw4Kg5QL8TP0+xDzgDfrcjziIzlpcf+vwcSePZUQNo3Oqk1U4HwU66N5H0fg\nHRTG\r\n=ZwDK\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDzdwReLtyGWpP9vI06erCFlSvUKBR9WyRolMWPGego/wIhALCQfpTHc40tg1VERCcJqSWnDbRQ441YNoTUsmn3MIAo"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.16.3_1607094919639_0.5956559200875702"},"_hasShrinkwrap":false},"0.16.4":{"name":"file-box","version":"0.16.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/index.js","typings":"dist/src/index.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"d3e7cafeed38891167a5c0c350a6112c7010f79f","_id":"file-box@0.16.4","_nodeVersion":"12.20.0","_npmVersion":"6.14.8","dist":{"integrity":"sha512-XkXZH0DhKK6ONeLIBKa/Gj0Ee5cCkSDgNECPL19Wj9QX6HVXYcxLKcHKSUjuGDcZPfnCN7QYoTpAvOEPX6iNQg==","shasum":"3192bbe184efd8e6fa46c176ab7d5f78f5df892c","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.16.4.tgz","fileCount":88,"unpackedSize":210650,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJfylLUCRA9TVsSAnZWagAARQ4P/iS1m0V7SFH0PLyVJgTX\noNQK67tKonGhngC75zADuZXJxsoxzK3qRm7Xr1X0SNdelxg+l5d9o1G2tNkB\nOlpVMzCrG8d4IhPxRYlP1/xi2je0wKOIWSpAt3/5PbAlFSxT/XpsdZpmGqsE\nB0enCWy40y4g5TBQteNZqPN1UJhtBXM3NMZz/W9LKUHU7pY1FoI4tHTrE8ut\nvrtc0Esn0wLruc/GJho1l1Q3Efz8sUmYj+5BQ5ZBliJvmHweVIx+comRbCQC\nc+5XogR+Kep07Tyznx5tgSSqJXsPyxLteZjV9Zhkz8hUBkvcfbudLOLEux+j\nLknGq3PzZGpECcgwbKa+dFGtY7OXDUgJ/f0gPmx3UzVIQeJbTSuNPkszi9w2\nt+DN1MEuUFltG347g6PkKJ7etf+ofV3HgrmklZe7u3Oxl9C4M0N8OB997I/w\nkPdO+R+KteQ0NpB6TO4CxUD7PbS2CEgigQjh+z2vRAZHkg6J8mmzm6/BL0PK\nUcl9IG41CWpZLwYL6XzdkEYbwxeHZM2+/v4CVtJxr/fgrS5ISN6z+Tn4nZ2H\npLy6j71r2+KSl9kgUDu7u7o68tBwCUiODZOFeA9SlCA8A4F2H0cD1w8cNr30\nB+cfnh2xyGoshSZYWKEW8nytCia78LssfrBhTCyIROv6pIBXkz5te9P8VvDK\nOrhh\r\n=Iqvs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDvrRBw6rZp46En6QqkgZ+KOYQeEXIzkWCyfI8ZB9hDtwIhAJ5cSarta5EhP7jLcqByuymEc4G5lOJz4FaiSMvqx006"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.16.4_1607094996358_0.5255848538561674"},"_hasShrinkwrap":false},"0.16.6":{"name":"file-box","version":"0.16.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/mod.js","typings":"dist/src/mod.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.10.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.3.5","gts":"^3.0.2","pkg-jq":"^0.2.4","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.4.6","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"38fa148db714e9f565190959b602f874041ce6e0","_id":"file-box@0.16.6","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-8+xIzHyL9zUSKR5yMK5hrNAUKIx0rBVNmY7nTWzj1nuAY+d+I8x2siqx1Ulpvnddg/x/FfeK/Z7gqFOWBjj0ew==","shasum":"2b65000bcae7f6bdd61687657d6d0b983a2e2200","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.16.6.tgz","fileCount":93,"unpackedSize":212238,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgJilGCRA9TVsSAnZWagAAUq8QAKOxgjYqmIBtDxlSI6g+\nb2iihEAXio7q1XxOS9qd89tyb8fnOXNuDp0DZA9CJV9ukis0fKW37R6aj+YK\nspH2e1rszKKoJO7hGn92Y53y7Kzzryf2K0ILnA06Z22HvE/DyZlKafBb9nc9\nuNV1shtBeTLUsPXhGIXmFJwsJfWF1hwDOU4O3fAEkJzVD5yUJsmAFyQM9qYr\nbgygGctRucHTurBuUznLGuTJn4Fom1fA0c4Gt8jmAGvAL9C7LPgsa58Ymfso\nE0nGKna+2mpiwapRvNYFJ9E4EPhQz9cXMIM/j7Yojgwq/icu5B1xjsdvO43s\nq6sw05rHVIfgXCk5kJG6i3Xpn1NeASG2gwE7RZaiZ51wygXtm+8Fx3uuqLyQ\ncsDTsaz9bJtyGQ1hfU5bnGhUfMUYP5D8Llf6VAwcRO3hRKgJaABrv8qKFVXT\nzcoHNMHHQwEbt9ZA+KjqP8gpJ/SWpEBwPP8gfbQdYmLXwBrGc5dh+A3iq9Tn\nQgA4IlgC+Wg3ijV9tn15N67ZLvNAEX0sz9sH+3HxfWcJwpWdqfpZOG5AVzGq\ngjGJJJeuyDiTEshebjwxxcRLuG2SdKT9LsaGbu6J6/6+oscK73BFHTw6O8vF\nuvjV1sOpv4udq+RV6POUxgVX1GWi6W5q7SU/2ORtlgPQHAgCu/dAsIqZ3onk\noBHu\r\n=8tU2\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDfuAJY5++FqZcVXAp0mDhXsf2wLkIsbuH2nuh/3neabAiEAjoXvJI5PzgN3pJeON1zpqN8GvKPz/CccuAcFzov8AeA="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.16.6_1613113670211_0.9736137034331056"},"_hasShrinkwrap":false},"0.16.7":{"name":"file-box","version":"0.16.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/mod.js","typings":"dist/src/mod.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.3","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.14.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.0","pkg-jq":"^0.2.11","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.5.0","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"a5e026dfafaa2107cb72a473be8e447ab34a41af","_id":"file-box@0.16.7","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-XeXJwaCItY4UAAnwuUDjrHucCh/K6eGimEmk+gwVJzOaIg5lgIlsCdsy9JJwBSreb0Hw42eBOegXTXjh/gV7Jw==","shasum":"c864eb95e1be7133d07d43a35c70ff0b189134c8","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.16.7.tgz","fileCount":93,"unpackedSize":202095,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgJin2CRA9TVsSAnZWagAAjH8P/1r7dJl8bdL+lYtrKgP/\nSD2+yura70cm2dCaP+BSDevKzvbO/fiNcB7aqeWkAGLHK5oh7plNDZ8T1DsW\nI0KN1pf4TqhKJXVqf3vQA3e9M0pNCV2eKw6HleJsGESe2W8aml9cc2lYAFmf\nVNi7Y3g8NvVNPzSzjFJgQKNri1wq0ytNfYMCCohqZqG2rT0wuc/iwMvIIBcK\neNotoXRUKLLBaqf/VCIvzA6zq3NI/Eg0yi6nXL3LJAbXdTNRCbqmC/zGS0LR\nhtiy86imzMnSyVpM1M4lcQb/mBUbqYy/ntOZSy3+n31GQjyPYsXshxfxamua\nYgv0pMHYND1y3JGVHhEVO43dmcyrM25MO/W93RndX86VXvpzDg4BJ+wiNB3y\n9DX36WDu+zhoOljZsYwKbbScGH7c6JDrAF0Aq3/hHH/7BtKExff73T+1B9KW\nfI6trpb8Hr9PYYN1ZM+gD5rBKZXIvttN0FosMXCOCHr3knJx/Wsti95rSGRO\nTBN/dV8IF0jSlWMvwWYrfjcLE4QaCGgv8FiPhMzYRjm5e2ikjk+4Cz1hxEmq\n0j/C02L9B6cbHFN5s+04+zby+2nTguxB8W3A7QQ9TBN6/JgPqSgUPIcTq+nN\naPTyU4NMnoIlQBWZXlzMOMdy9dsfxEIIBAVMNpw7dJAcnjytVhjCMtbnJizy\nmYSV\r\n=PFt7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDdy68bUZqPbK97myB31YIoRBWieY9jTJBO4BS724yLPgIhAIRaBf9p0tLeAtb1W2jfAQA41RBmL/Ox+xStnMtOwHOL"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.16.7_1613113845877_0.8256258051257443"},"_hasShrinkwrap":false},"0.16.8":{"name":"file-box","version":"0.16.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"dist/src/mod.js","typings":"dist/src/mod.d.ts","directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","pack":"npm pack","test":"npm run lint && npm run test:unit","test:unit":"blue-tape -r ts-node/register \"src/**/*.test.ts\" \"tests/**/*.test.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.12.3","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.14.1","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.0","pkg-jq":"^0.2.11","read-pkg-up":"^7.0.1","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.4.10"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.3.1","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"50a6eb64c3f51272e775e4c55bccb1cf5b25dd86","_id":"file-box@0.16.8","_nodeVersion":"12.20.1","_npmVersion":"6.14.10","dist":{"integrity":"sha512-TVj12voZ9fguExp4gAPWyf7Px06T5fWOzowww1yrp+/jaER5tamgcaJqDdHErRj+5YprMOE9YB87DopetLLhHw==","shasum":"cb358c286020d5546c0c7aa23075f6b417d992b2","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.16.8.tgz","fileCount":88,"unpackedSize":201093,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJgLdawCRA9TVsSAnZWagAAsbYP/0tRBiIbsCR+vvOCe80d\nxt6tANIq89KEhBdlsTkxex8MC15myfd8N/dJ2VqkBDXc+7FRbY+b9yNOdwg3\n8KfCHo07GyThYHXVSYPEd94Tt4w3NCKEFQRhoOOE5NGzPWjVZ/E9RSJctLnp\nGs4hA7YyQfMnElQE2D3MdvnewwlAKRtHZShAwYcVSYONdVfRpgkGeqLauVxH\nXjw3Iz+lASn57fOHo2Okg7XSgIQABEHDeMd4Q7FdE/iEzyP40i3dJw+wQ84V\n7esiHOecFTi8qGLnWxNWiprhNvP6PQjiIiexLUrcqOlQdfpKDsbRIyYYrbs4\nxux/9ZEGU84XNWwW8jmnmWeW0A7hnzr/GUpwLCe7xa3tX231PvE0MOHWtsOA\nE83HZZ6ukMWNr50RxyMYwWHx8oQ2vAzYVi26Cw3jhBq4qH6A+KAZZgQ0uv28\n8JTdQwa37L/3xhAMJLtpnsv7QLgDeCTyavIShCL7Sr5lVmW0aB3Rm59xyc8R\nPHidMMekjmCPwrpajAJWCcWTv0745k6qv2Az13lFnLxczZvBpDwR3ue8Nrlf\nTzc64WM5OuSkVsVBBGFlCG4QJDPOeMY2j6qcHm0aSYNrHxGc2ZyjXnrR3G8K\nyl+9elk7S7UHoxDlNTU5bq+USV8dgJAHRUVBvUHBuNoYNNy9Q5/KTEOtXOXZ\nmEVT\r\n=9ihy\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIHNliBSjar4KwoV3w0tdTJK9a/k6VkvXHmpN1PrnLsKOAiByoOhihYBxFc4DS2Z4PMUx2SrR06zPS7Mzt66t/IiwUg=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.16.8_1613616815658_0.3856806791347269"},"_hasShrinkwrap":false},"0.17.6":{"name":"file-box","version":"0.17.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"./dist/cjs/src/mod.js","typings":"./dist/esm/src/mod.d.ts","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"engines":{"node":">=12"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc && tsc -p tsconfig.cjs.json && (cd dist/cjs; npm init -y > /dev/null)","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"tap --node-arg=--loader=ts-node/esm \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.13.5","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.16.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.5.16"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.17\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"71f4feaf61c9af4dddcc8603de9f3f566b14cf5a","_id":"file-box@0.17.6","_nodeVersion":"16.7.0","_npmVersion":"7.20.3","dist":{"integrity":"sha512-mN3QoRtogMbaiQBqz/IPf9AyrVP4jdd0FQ8jBu9pb+joS0g/6zW6nA0Ia0kd8LOiBjshP8sNkhkj/G40cbdbaQ==","shasum":"0f40558218501318983370f2f8289fad53bc9095","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.17.6.tgz","fileCount":129,"unpackedSize":246109,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJo2LCRA9TVsSAnZWagAAYK0P/1PuGhl5PRI515JlSj/M\nZ/1dpLtNSc+XfAWUjUv0bJMJsUodgbjTdBgOt3P+m3J8lHHHl/7O0g1Rn5Ww\nK0UwAsErQ41p5WwDm4rwiKCTkHJdKi7vBS2jwDMMfMit3dEmoPFyjd7lQxNE\nRcgHLlEOCBawqZlal6h2JpBkYOFW48YMpEtp/QZl5s4ezRWuIUMMGqQH76MA\nlrkrqApmb9BZjwFT62BW6SgmuuQntCoROciyqwtHZ7fhM5+DbEiqbEp+/RFL\n3MuDqJbhbdgryQHoGvri+5YDXGYL5t5WCWWK6Oaq0gqVn7EDqeSs988IbLr5\nQ/CaF8GwfXvSMr0Z40oJvKv5ZI5EeWnu1IweyI7U7TljYe9nealc7W12/C36\nOMAeMbMfxxd+Ya9kDXvJYvQBAnndyXr1vnSWXnjO/6I62D/sueiZ6EzmLdfk\n2Am9ERqePW0OEVzZMkC9Vhulw44Qud7OMjLmWafQg38UUzbTaRFrHxqgWTKE\nK+Hj7KiO/1x8FgrgjcMp3QIv5iuLtmV57TCUgGGKXTyeQfuq3M1FrKQaPFfL\ngXdUZ8Sh6kqjYANrMFpiWvhoD6tnjOjPqQYvEW1TKDrpLoPmWl6gfIu1Hepe\n5H+wGZWrDlb/zBK8JBANZH/Cy58cOaSmGKcSFbjzrYmB3PjUUvUu+O4DEnD0\n5TgU\r\n=LX/h\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDVhIm0/MKtKesMy8w71L5mNZz+YfJheVAkOGT+WjvDmAiBvSa2vwhKTM2adupihiKGTMcJB6zbxVoM2EfhswxoHfA=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.17.6_1629916555037_0.5910748097336367"},"_hasShrinkwrap":false},"0.17.7":{"name":"file-box","version":"0.17.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","main":"./dist/cjs/src/mod.js","typings":"./dist/esm/src/mod.d.ts","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"engines":{"node":">=12"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc && tsc -p tsconfig.cjs.json && (cd dist/cjs; npm init -y > /dev/null)","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"tap --node-arg=--loader=ts-node/esm \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.13.5","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.16.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.5.16"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.17\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"12d10b601e6de8cf35bf25850c473ee9a04db436","_id":"file-box@0.17.7","_nodeVersion":"16.7.0","_npmVersion":"7.20.3","dist":{"integrity":"sha512-3Kxp4+NtoDkqINUdm62KbT2NDKLEmd1UIY/L5iNFnXwZqxJHp+8GgK1s6jUStErsYkYnP3NehJbwBkfCRQF0NA==","shasum":"09684709f2f34aefbb80a96621502ed9430eaf1c","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.17.7.tgz","fileCount":129,"unpackedSize":246109,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJo3nCRA9TVsSAnZWagAAPQ4P/3QuJU8+4LYsWBbXFAJ1\nZ2vrTqGMES+QqLFtlT6zbjPEcNFrjPi8W4/9fYuiTG3IbMdCQewSU14qQnt8\n7Ly3/iqfc3y+zOXUL6PbUkbj0zKdu9bcIZ7chf4/4NTe8yXdgP184Ahtn2AZ\nL1oopSCG8Y0tWWeO9HPEfM+rmU6YOKFa2ueXmt9qDpw/igi9+Ilj2kz5yCHj\n+Up6S4NxesGH9I0OIP/aAWPj6wurnB7rYdrdwi/yHSdf5dVo9FXCWNi88RdA\n0BPd/LfarWaDKPQlmAU8VeogtEkrFGi3UY/FwqRWFU7lr/xcvD/ej+Bzn61W\naLnJLUrq82xu/ipjFWzgnT+eq+2wCIaAaAVDNo/VJy3kOpwUv0o7xFcPF/km\nnmbjYmfN3+TS2f7+rt+iUk6kfR9+ovrk68yRBZ0uf2n44LdsEh99hyPYHTEh\n6iN4cEnK1LR878XJPrTLVRfFoRNL8oHX2O05WoczCO4w1XFATGfTD45fiiQ4\nsgVrt5ytSkjEEWbz7W9HizQDcvcZ4ZVqoHYbUre44yevHAOFmGsitQdOyVIY\nVwpAorLfYwmKYoHD9Zn2TcQ0mmWSww4FHNJIMM2V7Md7VVIekt7QMwr07asJ\nho8VbjRXkAIP7aDnUgLwOITLxbE8jJoZstSq/vQzg/r/4/LbIm8wCOzlhK3J\nIJN2\r\n=r1Cs\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCqjlRjMJ8NwnzcE8+3kaJdDyru4lIeBEPBej8KRPQb4gIgafxOi7MIYU+WrdulH+kU/+SFAeJT0UFZrNIsV1MsWtE="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.17.7_1629916647208_0.7006711708797153"},"_hasShrinkwrap":false},"0.17.8":{"name":"file-box","version":"0.17.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=14"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc && tsc -p tsconfig.cjs.json && npm run fixup","fixup":"echo '{\"type\": \"commonjs\"}' > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"tap --node-arg=--loader=ts-node/esm \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.13.5","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.16.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.5.16"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.17\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"9c5c05f72f8956adbe47c96345de9931d393aaed","_id":"file-box@0.17.8","_nodeVersion":"16.8.0","_npmVersion":"7.21.0","dist":{"integrity":"sha512-SaJZrIWrD+2ekUGQiFMYmKu7xs4beu/Ni7qcVpQQUxvW8CUYg5+QbCYTd2Oj9T4zBOdzVVLaXlN2Wgfc2W7l6A==","shasum":"53a8c0074e99ed790456b62bd285bcb0637af444","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.17.8.tgz","fileCount":129,"unpackedSize":245881,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJwQeCRA9TVsSAnZWagAAxDgP+gLfxi5nloaqYTKmXMVC\nHPiA6n3L8davMckvNpv2YB6w/Zd1/QuEkveDFH4LQVyia5NIQIIe2XC1xYCW\nTJSL64158LqdmeJMAKCAlayoXMSHYcTSQckNk4MEGY9yzR+W511b15F4IvgG\n3BdMsZmdbOJ2JXpCq2LeKNkrvxiW1SIMsuFeSt3iPPApbdaLwSstVsAugM4c\nvv9YjrgZiqoltyA05THxKYBkLYj54cIpt05jxhGwVp3xEh3+3HDWGEYlvFlu\nkiuKPUGr+s/idILQvg1zmuRzXmzo8ZrH0wdkMjETohdUfD6y1zZfROesJFvW\nv9lw3dx3AHqVP+Cn+cWI3l0m1fNxgBTmuyunwL4gER4KeywYPHh8KuU0Z9Zi\nW8LGuyqKwWzbNbeqokFV6ovQ7pHavDcCBxsNm0a3xvl4i/CWUULn3Qqnz00O\nStpOrsKyJOHDTatpGNrNFTdIWZQVmBKlcaSlDyIG/Awl/ZCMmI4dKw6bpdpP\nx14FQq5Jgie6g5Nnu4SoJb7XI5irTUzkCpx2QlVCo6PaMKKqJFIXQyl2lVtT\nu33KrkUOTNpLMBq6o1+ujG0AjA6c8GqNYZ/Gi7CbkDQeMj+dCbyhqX+NTuxj\n8CbqbfI9M1bWJugd8EWstpIg4W/zit2wOhlwcMuG+cBLJEJUFaEujW2/1ZRr\nEYqo\r\n=RoQa\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFBILIgKH8Q6bmeSpOxuD0JeEH4ZSNdc07o0fD1shZsoAiBq61V/eVrMfAsMREyqlBKReyJ3XWvPzyqhKL+VuIuX4A=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.17.8_1629946910454_0.8232595008329682"},"_hasShrinkwrap":false},"0.17.9":{"name":"file-box","version":"0.17.9","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=14"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm run clean && tsc && tsc -p tsconfig.cjs.json && npm run fixup","fixup":"echo '{\"type\": \"commonjs\"}' > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --noEmit","test":"npm run lint && npm run test:unit","test:unit":"tap --node-arg=--loader=ts-node/esm \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.13.5","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.16.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.5.16"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.17\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"58bbae9894e219db8723a23031bfda6e60983934","_id":"file-box@0.17.9","_nodeVersion":"16.8.0","_npmVersion":"7.21.0","dist":{"integrity":"sha512-Bn9+Ra71tg/wP7GE57d1n08jJjGRSr8MD5PyAu963L3lT3W+EPBxgJh6vjqi3QmJMp20QO0u+ARt+klV84g9eQ==","shasum":"ce96b4c882a4411c4ca161e50db3fac0d5173b7b","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.17.9.tgz","fileCount":129,"unpackedSize":245881,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhJyGmCRA9TVsSAnZWagAARaoP/2AXbnUKIz8h1gqICKTF\nEYiavd0JFZ9tU/Z4cotp27ajhwODVs9oAXBxdbIy2IYwMstUFfKTfLXAFKPp\ng6gkkQxLPIySWLbIF4VUZAtNFLXfzojTxrocZXfa5BuIYNA0EYNZYyNLgePA\n8tIuUpEwcQ0KLkp8VpKgFxDRLvfk2nx7WtP9EvDBGQ9Z4OzRKLEUDmJNXJxp\nEbB9Bn0KeVA2jQE2dX9IaVIJfFJt2JN8i72fZUoSG3sjwMT/UFMckEjAZC2i\nlPVh4JMmXHhdYJqWN2jlQmZTg/sMU4Z3P/vMs/ey2t7J+49lnMl39WN5v1BG\ns22TVpsC8K/WEnpyDFq6ZemzNOSgPjnxpJygL6VCgkn05dxocw6lepC0tu4o\nq6b1U9DcaUEqxDUHXdgqcgojZKvtWK+HKUyZ5yRdzUgob7Aen5tpaY3jYmxj\nk28x7qIqJPrE7YQY9/cCElLpfNBJRQaJUGmUx+Rljj9VCLIrSpMOZfdsdlyn\naWFneesaa35W//TGsP3LffPJF1eaHWmvhuDWXY1QjDz9g4kh6XzYdjWRZA6H\nnGoE3cvCLCFfgsWGYMMMWEhtyg1GpIT4yZrX/zuc477bkwDb6yjZ8MmYDcVg\nwd7bf/zCPexAukVyYY3FR4o/QBZPbGkBYbeim33cCE4q7DiqXxcZs3DIPZuv\nsMv0\r\n=O4y7\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICkZlfvy7P8nd8j1MswnM+qjISOLIs/a9FYvJ28fjzmIAiEApp3oeSpTIRB0AfnNDnPLy/Q0ws6yWGFgc/RIZnOIJtY="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.17.9_1629954470425_0.7093118902958149"},"_hasShrinkwrap":false},"0.17.10":{"name":"file-box","version":"0.17.10","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=14"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"echo '{\"type\": \"commonjs\"}' > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.13.5","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.19.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.5.16"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.17\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"d13da57893e14a1b6e1193e91aa9448b3c5e950e","_id":"file-box@0.17.10","_nodeVersion":"16.8.0","_npmVersion":"7.21.0","dist":{"integrity":"sha512-DLEB4AdRdA/oQnmmyfuzBuQQVHndekp80EzhFsYZeeUyfgMVlHN8IxrqJRBRTytuA39KHUWgAs1vslODREgQPA==","shasum":"aca312ff756c0e66d2c732bf46241d43eadb5a49","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.17.10.tgz","fileCount":130,"unpackedSize":250595,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhMalVCRA9TVsSAnZWagAAVv4P/1fA7eg065+0M7dJ0hS3\nzZ/09VDL/sud197WT63M0T09ur80vytSTJE5scLemeJiqQKHoA/aYWP5ImEH\n8Yz1+aCoelIpSYjEqDIvJs2j3tnD939r9iTr/B2gNgHN1QrxTILMlwybmDHS\nttvhO3hv5axcNSpCEuDOH3EaRMpLe+pjl6NGyc7XqzgOTmj+lcHD9rOmkZNt\nLeW/ho2N7Yr3bOlb63cLY8QulrP5nykFABqeFbPGRe5Vi85tEectfgMaYdfS\nb5p8ntJJBDsgLS3xq8g3woYfptuepjV7FMJjRZ2Ii5cfdUVbUiy1mzzjYoBT\nQ5KhScZYF+r53mrYv91p68/zSJ/J7kTZK7VnJaJHvokFiwZ2Q889v/WEJPpq\ng3efn0+sy8GOLXCK849O5eMOSBRqv5hG0eQPvMOeXn8FBmnS9u3xMtUILJjg\n6wx76FPe2H7JmuQYhW0rMFCpIDYtNFgMh4f6nzHnT9kwqRtXHw4FSRxOkH0k\niKWR9hzDtUGwp4MOvkou+cFuhRwdM5sTrbiZyvTr6xqIQnaYhkm7wEOWE0SS\ndl00Oc9DrvEsZdDAujaqBJfE/11iaouhDn0nwdmFkJhFIa6uzBLGRVNBSAc8\n96lo9dAmE/tG9ure7grx4LkFVqTwCbhbV78DN8hLRJP5l+e98QeLSPrFkzSN\nTkmA\r\n=YSMe\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB6IwVh8LJQ/t+YsvlZ48eVeEG7nq6ThFDTrvhu4VxY6AiEAgSiD2AgMDw7rn2FK91cqkBbkbJQF17RNi55nHO3Z+j0="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.17.10_1630644565187_0.005003254864868412"},"_hasShrinkwrap":false},"0.17.11":{"name":"file-box","version":"0.17.11","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=14"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.13.5","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.19.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.5.16"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.17\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"ea84a30d5b9db2be727824da9a1712ca8bf827f5","_id":"file-box@0.17.11","_nodeVersion":"16.8.0","_npmVersion":"7.21.0","dist":{"integrity":"sha512-4XHvdKZDHN8nRut9JZpBMGzrhbtoL5okaZYHxAMYey/SeVUum+F7wE9N6dbZRsDgTiLqYffkqd/BKveA/gEcJQ==","shasum":"5b0181a9ca14dcba28667927139445b94a9c2c94","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.17.11.tgz","fileCount":130,"unpackedSize":250604,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhNOp+CRA9TVsSAnZWagAAhzkP/3WVwPsW9E7NcAZ0KP28\nK8W6R3Fu006yHS2SrL7doEolXLYv4qrZOFaS2c45HxossmR3OxCtN6fZzCIB\naXJwgkrVGA1XqEYUlmKGCZFcbn899xFa+k4G5g1CR6iiLo1t8hb6q3uoIFrB\nba1QCBnPW7teDig0EUq3uQV13jlF0irLp8vn3HXJf+gPCfry4/pxRdsrNB64\nlZpsWwRe7/PaMHThLSC21zsQrNpJ7OdnXHAJzS7RXM7Y/Ao40Lsg3V70c+8n\nVam/6EfVx9KX4LDXvl1fijZgIgYA+ZGxE5TzzgzBMmsgjgTb7ojVaQukXC66\nh5ZsGBIZ7Ahn7+MIZ65lUhpddhM/iFrwK/xAuSt8jUG4hDwrvNcwSA5W2FKe\nqILAwcTlPO+KRLrFh4AUa4nQoxVxziCJBB3FWkrm7rb0Dq2H+k8NHTYubkyh\nlt6gXqM/+7zYu6skBW0vwPaE8Pca/DSgahnW3BgMtdu/pk9/scYvTIHV+KaY\npstkLw1niS+KPd6kCtZsQ4acYicSIJ/knFSj72GksITr8dGobYKKR6hO8Qyq\nPxGh8gUyS7xu596B0OO5Gd7osIL8f+Pm9AZoyldYrfZjS4r78maPXkQRo+EE\nrEOx+S95bCpGgEZq0t3tgQh+yfYzWRnLtYxXm4ndM9xhr6jrx66YP5defwPc\nZnZO\r\n=vgNX\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCa/XrCnJcTLonpJSPX5VuGWg5rDc6LXZVPt+EPvvfqnAIhANtH7XDjVme0u8QaAYXkIftyuUgZgtRBLEWTqn6HBsR2"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.17.11_1630857853967_0.07765127635496838"},"_hasShrinkwrap":false},"0.17.12":{"name":"file-box","version":"0.17.12","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=14"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.13.5","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.19.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.5.16"},"dependencies":{"jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n}\n\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.17\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"087cb542edf33932051051522229abc63f100658","_id":"file-box@0.17.12","_nodeVersion":"16.9.1","_npmVersion":"7.21.1","dist":{"integrity":"sha512-qUPCVoQp8hr0tLZVwiDy5D+HNJt9oFPDRbr/LNBYyX1F9SsCUiWYSiDGq9waUmTQtwvmM5EAlwhHOVhgVZ9Cjw==","shasum":"75bc8b13587d6cb7d1526a5ba39b0b573f735c28","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.17.12.tgz","fileCount":130,"unpackedSize":250719,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhP6LFCRA9TVsSAnZWagAAiVgP/jrrnGKsLbuSC5eaOUxp\n47a7AxkZMtg7Kgp9MstjJ72VrACWezrkU2uKsZ2j1txLfGPX7voDV7JKv7gR\nZQ9YyiKo3l87ejwfrm3VzChoOQOVa0PjCoPSdXiP34NAGvxl+HDhJrXkPf5p\n/pmTXR34hMByxCEj1qAjGJJ+aQwXBPzInVBiZX1Mn1X1AA8DhKCw93S0iT3D\n/vP3M/ihIAkYTkfjkSXxhTaO6+aQWmbaNQVPQth0LsRxKTcEtDA3zwUBAAh1\n2ySPLk54obkkg+UE/uyWlfdh+alxO8YJK3DookwCi7NYk7vtmE95Y25lfUtm\n3NcgevqlMF4OUkX5jXnJkXzsuOjYa9PnHD5BV0IJMaAA9sd9AMU+uTdefFvP\nc4IJbFQYFsMGQtKquIZJMVZYJaDEZFfoK2wWZzfMeY3VKYG+Tz0FY6VVzjxY\nYQWHXKFbuSwRaqdJ/Nj2bR9nYw+a+H/GFco7xzaYc3KOiNPqTwiFJBg5AcBI\nk/B8DseoWC2GGzkdKWVNnD+VVEgNutUVmjvEpelPcP/cQ5PvXSRoM/r6erpU\nMDTXXYeeBjzRhigPZW247WXS/4uwRguj+jiGFgnR6H+Kdj0YCcqyeiTnZutB\nKvHjkRYx9U09XQ9Ycg2/V4rChe/wjj/8dKcYPbK+WUh34IxZEe4bhwRz1w1F\n6hXH\r\n=kmT3\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCRYUiphL+GASzYaCa0in2Ck2cuX/kgbw/Gv6uxyyWcwQIhAK6+escIms/lHeVdVwk4bu/rKulrvG3ATxK6dg89rN2n"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.17.12_1631560389263_0.39857423235040135"},"_hasShrinkwrap":false},"0.19.3":{"name":"file-box","version":"0.19.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (stream: Readable) => Promise<string>\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.19\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"2699aa8cdc0374c1a67d796b8ca7588e5739716d","_id":"file-box@0.19.3","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-pyTy4ktQ/J/QjXiS7KO2Iz1HycoDkDHxTCHkwUoDk6lI635qQrRyISSZn5CvyoO87+ZtDoqnft7uJexTf8EciA==","shasum":"b821591287475d62a2a293070470de7e9164a8cd","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.19.3.tgz","fileCount":130,"unpackedSize":283592,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICah3S79PwdGf0l4SWV2rv2th0alWIV2DJQGNotkPtexAiB3AS4ZO8YU0Ck5HwQ2yk3BWvQ20dmN7Z+yGStyPKop5g=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.19.3_1633408327586_0.5859072650944155"},"_hasShrinkwrap":false},"0.19.4":{"name":"file-box","version":"0.19.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (stream: Readable) => Promise<string>\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.19\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"29030283de4907f5c414382ee8a70eaa615ed6a8","_id":"file-box@0.19.4","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-B2FYnT3AnvBnwU/iIX99QD4112fJAebavoACsj+dpgoLCGygR24AMwKzjFH+IlkC41IWAxPKRDRy2bZbmydVjA==","shasum":"bd05c3c3ff3a0affcb8d313c062bb038fcbef238","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.19.4.tgz","fileCount":130,"unpackedSize":283586,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIB/YUE3dAHcaY8oH8+nr3UKmfZ25KEXjvxOY5FVD8UqYAiEAnIi43sbOzxIhvjFLr0fD1y6lt0Jj2eDJlsWZSJI2i8E="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.19.4_1633412115930_0.10659185593878795"},"_hasShrinkwrap":false},"0.19.5":{"name":"file-box","version":"0.19.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (stream: Readable) => Promise<string>\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.19\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"4ea7b656d8dc266a7fc5698f702ff811dbdc102a","_id":"file-box@0.19.5","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-vxEAHDb8cwJhkgoGuJxPVt6eH/tOMSYYs4vitq3dhU2qkkq38ziaJoECBiTy2rPXdXOuqj6/DDs0UT2fFhEhxQ==","shasum":"2d2fb90def6054e3b91012b3737a52731a70e950","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.19.5.tgz","fileCount":130,"unpackedSize":283744,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDWiLoUj9eeyhW94IcXpcQaiK9ozRZKWJrbEGCQ+y8ruwIhAOd4sU1PbRvCNZk6t3PHsxlpaiTXIIwiOyHGLc2PAkSG"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.19.5_1633441943321_0.47616085740610425"},"_hasShrinkwrap":false},"0.21.2":{"name":"file-box","version":"0.21.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n**To be implemented.**\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type(): FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (stream: Readable) => Promise<string>\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.21\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"bcdd2f27ab08c7a4b7798ed4845ac23e62bcc024","_id":"file-box@0.21.2","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-57r2/C9SwPZ3Z/aDflPT2FCOlJBX7+x6tqrSdg9G710/n6bIzWkoRgj0laEmSIs3r/8XXWKbBUXc14UdQmQqWw==","shasum":"d1bf4313cf19595d38068901b7870664233758d3","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.21.2.tgz","fileCount":130,"unpackedSize":288886,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGPPtiNfy3A7rMDUvule+vJlK30bbvA6HxAOsbIzBs5BAiEAgmfMytKl6sS8Vqh+k4UVjxYLi+qZfpa+74rvZNXD4WE="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.21.2_1633459255638_0.20681639298545096"},"_hasShrinkwrap":false},"0.21.3":{"name":"file-box","version":"0.21.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.21\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"d161b3d8ae6514607208881c9ffa19816401c4de","_id":"file-box@0.21.3","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-1QsnQ6OOaKEzk9TtFY3LHDJkBdwrgR+PJYy5fMLBNPQFVQI9ZTiZZklunw/f9Zjxbz3P+KTHmWBaLyci/oM+lQ==","shasum":"2cdf072fa378147a053dfb095c52f62df3ac571a","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.21.3.tgz","fileCount":130,"unpackedSize":294384,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIAfuUbjxahiK46sgA02k+2HUgDHDMakbhluu4TmoWXjgAiEAzAsv7h4DFsSE1iegAURfhqxX8qQXpToVNQBhpuRkU9U="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.21.3_1633493414583_0.6403073701015369"},"_hasShrinkwrap":false},"0.21.4":{"name":"file-box","version":"0.21.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.test.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.21\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"6540f439d1530fbee886c787d55b3a8a95e2a5a1","_id":"file-box@0.21.4","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-KHmTEAizwMvm11xyvxnCu7r060TEImDLoRh2kzvdZvmgbgVuK0DjyBLvLh09lWfFPD2z+aSmkTXdOLWt8usoRg==","shasum":"43e9f8abe0868949ea7074fa4544ce30ada28426","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.21.4.tgz","fileCount":130,"unpackedSize":298815,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDiw5kf6nQFc4ANlAWGT3vxIUQ/73Ll/5Ahl9DqUvwn2wIhANWbq64PnmNCrf1085Iq51VKHkihI//aFYVpQDQ+4K4u"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.21.4_1633530740853_0.1503661326986181"},"_hasShrinkwrap":false},"0.23.2":{"name":"file-box","version":"0.23.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^3.4.0"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"ecbc56441b20ed34b2883941fc717fe2a63e51de","_id":"file-box@0.23.2","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-lGF+j25d31O7TCP+4eHFnybhvYXcnMtqA3cmCOOZPXRS5wCryMH91woU7jjADNJw22RibxgpkOGi3V7YUE1LdQ==","shasum":"4047fcc60a1360ac77e3db78913a0fab7ae52955","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.2.tgz","fileCount":166,"unpackedSize":358523,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGT4to1KtAuZL+NtlQmAcZ7IMyQAP1/xg91cPMEEOCNeAiEAx8Gx0vf1e8LvJojZBqhVQ46Nmaz5fTa5sN1voEPu9fo="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.2_1633686449694_0.8738555433412176"},"_hasShrinkwrap":false},"0.23.3":{"name":"file-box","version":"0.23.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^3.4.0"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"2ae79b75404306d96c07c8e4bdf7c89b64bc3c47","_id":"file-box@0.23.3","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-NCssE5YDnqT8i3LxjurNBmlQrvJy+B+KJ292S2QtMJuZ1PJ1ovvMWRQ38Q6yzG09yeXMBESIr/HqF4P6aR3XVQ==","shasum":"c6710b61649713d957b9964fb48aeb44b1e08e88","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.3.tgz","fileCount":166,"unpackedSize":358493,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBhuSpHEIKNOZ9QxGYVchMPq5TgJUS78FNwusdobrq14AiEA6zzD9znq9LfU8TxbSYu361BqJGS0C7Ny2hGZM7aoMcI="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.3_1633691290444_0.5386338960968933"},"_hasShrinkwrap":false},"0.23.4":{"name":"file-box","version":"0.23.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^3.4.0"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"0464c7088565ea547d037c2b85f252e75053fb62","_id":"file-box@0.23.4","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-Ec+tV7zXroPtCrcpZoxvzCIhL77RpqdZEQfy/6JAjxOnYBrX3euCzP0LqgbD3nCmM1DuesCqMcc5lyc9UNrsZA==","shasum":"078e4cad4493e49cb35fd8694bd9c9a18ba05158","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.4.tgz","fileCount":166,"unpackedSize":358535,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIBa8M+5XCcgRFCXnNE04W3E4bqlilXUX9vmCNkoD59LNAiEAmDQAQG6NyYCHwu9bXKHib8qIVq3PWzyzsdI5Etn8eFY="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.4_1633693469584_0.7814989658762745"},"_hasShrinkwrap":false},"0.23.5":{"name":"file-box","version":"0.23.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^3.4.0"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"d975d66e9736c6fbf108c30c78eb18d993165dec","_id":"file-box@0.23.5","_nodeVersion":"16.10.0","_npmVersion":"7.24.0","dist":{"integrity":"sha512-12Qk1N3SK5lwUk7F+qzZ9++Zfjv8/VWl47lIZMVCjNN/7Ahaivq2U4QklzWw3jvAvK6afrA5nDcnhk29/G1Xjg==","shasum":"76dbcc258c0ed47d8c021b5b986426df6e792ec6","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.5.tgz","fileCount":166,"unpackedSize":359589,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDTF8XnFdSjvzBDqaeUgYAMBe2ERwtCu6msn52nnLF1kwIhAOBtArr6IlVeqlF6+iYXsFUmt/DadkLRfxzL160vbWCB"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.5_1633705468313_0.6945131521149066"},"_hasShrinkwrap":false},"0.23.6":{"name":"file-box","version":"0.23.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^3.4.0"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"4b3129f2623de6fb0de7f0a4640d0fb7e7f1990a","_id":"file-box@0.23.6","_nodeVersion":"16.11.0","_npmVersion":"8.0.0","dist":{"integrity":"sha512-e3zn+OqK8WWvPboJUt4/FUsGQW3AE2SBKLjcDzQsEmGJp0FzEwUcTDyQTVX0o6K+VTCkXYC1KOplFMY9nPxvbQ==","shasum":"63ca87c71124dcd7295048e0c76f7c96bd99a699","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.6.tgz","fileCount":166,"unpackedSize":359973,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIEtERU7Nb1W8Yi95I8oZBL6fbuIs9RKQBiJpt9Urek3UAiAvbsCfsQ5bRrAjJI/WXBsMB31+/o6/0hXpSN0ML4hWPA=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.6_1633713621912_0.02563624891294869"},"_hasShrinkwrap":false},"0.23.7":{"name":"file-box","version":"0.23.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^3.4.0"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"609fe87a6185fec40744d31fbe811390e7d30b31","_id":"file-box@0.23.7","_nodeVersion":"16.11.0","_npmVersion":"8.0.0","dist":{"integrity":"sha512-CcJYoZl6fDv2FKpmk80yrkfkiy+LX6xARMMSH6qWZGD1O3/2f2gC40bcz4RMCeJj0LCW71f5eAyKGrcdx35tjg==","shasum":"1a4369e49daff91a95a390c01527a16c35ce99b5","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.7.tgz","fileCount":184,"unpackedSize":366825,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAzGjUaGh+A+ktl1Zfjqnz6KdfqKVSP5Of1RGN5HflG7AiBVdTqMwMAIwcgs04iueRxHuAPKpIa3MGKVSwtLH9Szew=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.7_1633848625394_0.6377098975717557"},"_hasShrinkwrap":false},"0.23.8":{"name":"file-box","version":"0.23.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"23cbe7de0acd4bb08386e0af8dba6fd1b3d8606b","_id":"file-box@0.23.8","_nodeVersion":"16.11.0","_npmVersion":"8.0.0","dist":{"integrity":"sha512-0bRJYzlKNRrbw2GHW90oSlmq23y9m9rXJYPDFdLisu+OjeUwiJnJHOuPM0nkHp7fDn8VxmyCcpqZHUju6+7lag==","shasum":"438f3a1b9fdfdcd01a098432888fa7b497dc7f3f","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.8.tgz","fileCount":184,"unpackedSize":367580,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIDzBwsOmn2ybqdPBr521XRVj0nsPV2ZI5MCHuYR8l0thAiBSh8ECnw8hSw4Pl2B0TWPNCTBJ9gruZ3jq/0qiWrm0PA=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.8_1633932128212_0.2652271589625026"},"_hasShrinkwrap":false},"0.23.12":{"name":"file-box","version":"0.23.12","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm run lint && npm run test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^0.14.1","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","cross-env":"^7.0.3","gts":"^3.1.0","npm-run-all":"^4.1.5","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13","shx":"^0.3.3","tstest":"^0.7.3"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.6.20","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by resolver/register helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidResolver()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidRegister()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidResolver(resolver: UuidResolver): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst resolver: UuidResolver = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidResolver(resolver)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidResolver` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidResolver = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidRegister(register: UuidRegister): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst register: UuidRegister = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidRegister(register)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidRegister` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidRegister = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v0.23\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"7bd1fe96365d57ea451937ea067af7e61b11534c","_id":"file-box@0.23.12","_nodeVersion":"16.11.0","_npmVersion":"8.0.0","dist":{"integrity":"sha512-RpORpPpq4MEW7AQnUEY0AuOVMcTqz3As+cbWLylSDz1YCjm/YzL+sEg/QknbOM98NITLW/392Vste4ieyBjnvw==","shasum":"0f918e01bbb0bcecbae6e05b0316deb16443e327","tarball":"https://registry.npmjs.org/file-box/-/file-box-0.23.12.tgz","fileCount":184,"unpackedSize":368857,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQC6epojC7Fncd30kYxhyRus5lwKLqgJGssIOXd1lNHPhwIhANUbZpMedl7T+n1FCciOQ7DuvEHXqcROxdVTRPv/TnEO"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_0.23.12_1633943324860_0.019081223889999777"},"_hasShrinkwrap":false},"1.0.2":{"name":"file-box","version":"1.0.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.9.19","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"7fed745a9a0063042a09f3ba7e97fe15dc9b23e0","_id":"file-box@1.0.2","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-9wnJ4JMkWo/osTEzkA5vJxEnagYKYnupBwlq9aAJQbLqyuV1ZcbTcwGG3s/jr6W83UPszc3l9RMfxybsxy+9RQ==","shasum":"3c7759331bd5d437bd82ba6d86f78613e9afbcff","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.0.2.tgz","fileCount":184,"unpackedSize":377300,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGlozIqkWTEC1ZnoU8tGngt7jgE3l6dQr4qHk7VW55zpAiEA2Jq+t3Aux5UXWq0UjyLiRK6kLzD8JZUf4SLsXtiBO6s="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.0.2_1634705238123_0.2611923243721066"},"_hasShrinkwrap":false},"1.0.3":{"name":"file-box","version":"1.0.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"34c9b988b497127adef542c2f7c1b962b4ea3a45","_id":"file-box@1.0.3","_nodeVersion":"16.11.1","_npmVersion":"8.0.0","dist":{"integrity":"sha512-LY1CXN7PeJ6J1xqCYVf8atNxCx7e+smh3DUCTCPmOOBvsqnqobsXlx6jLZnHMj/M2a+QQa53qygmcNlP/VSB2A==","shasum":"8cd3be051cb48a0162afb3386d6b4566623f6b55","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.0.3.tgz","fileCount":184,"unpackedSize":378056,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIDf6Uq3g9qu8qGNbrE8WlX11zLYNFw5fHq9aqrObMud1AiEA7oldPlfzvgesug43iE7sVqvgB+2j1ruPi6FqELK5djY="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.0.3_1634711941477_0.7738660970088382"},"_hasShrinkwrap":false},"1.0.4":{"name":"file-box","version":"1.0.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"5e367d496e5184e4f4da719662d1d9ce57bcf817","_id":"file-box@1.0.4","_nodeVersion":"16.12.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-/GjWTXv5OCUhiyidBWJoEcKcxZlpGa2JXTpSShZ0iF2g16TrCKhQhPFQSRQZG/5C2dcYjfVDlaQr3cDSLvELqg==","shasum":"8a139d9a5de68f3a6fcfbb2aa7c4034de65dc873","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.0.4.tgz","fileCount":184,"unpackedSize":380395,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIHBfuG5yQrNKEG/tSSuVwFE2l0ckjIqr2GHcBxifg6jMAiEA8P5iKlyPpfvwjmdU3X5z4NwWiFDaThjOO4jcHfaRWP4="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.0.4_1634968514447_0.9831287592672775"},"_hasShrinkwrap":false},"1.0.6":{"name":"file-box","version":"1.0.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"5bfbd6886578b95c35fa8b33aa2575bbf33d1eed","_id":"file-box@1.0.6","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-iYUejzGFs+/ECNuWfIAIGtvBjRsFTsUeBoafKfnd1LrHDulyOcQudb+nQCoUQy1BLGbnwqzJf0EQKGVRilgA7Q==","shasum":"04aad49e4015b487fa50352dc42a80e17f412e74","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.0.6.tgz","fileCount":202,"unpackedSize":396295,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIEB5OCznpa3I1nhzqEt+W/QNWCloEx87dfDAcxaS8GWLAiEAzGHXlyWUep3DxClTpmF3QVbE6zzw1aNinG2jYwCTGRU="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.0.6_1635609868239_0.6243123149404852"},"_hasShrinkwrap":false},"1.2.1":{"name":"file-box","version":"1.2.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"421aaedbeeacc8cc6c474fff70982a588ca4df14","_id":"file-box@1.2.1","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-ZhtMAuVShmsSbjCW7ihJrQ/FGT7CAeP8WbMBIHTb2vxvGHE6eoUKSM47E4AXWiNg6uUDBBf/7ezu4CiSiMbLYg==","shasum":"c81d4483b8234616f130a25fc5033120c50c5536","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.1.tgz","fileCount":202,"unpackedSize":398642,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICdcmgs84sE515frxjKVb6t2uWqHrIAPBArThQr7iFA/AiEAw8GiPHvGmEb1lmf4NkCK/OfGV6+xev/1CyBnJfL8OGc="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.1_1635610570854_0.8184454500652825"},"_hasShrinkwrap":false},"1.2.2":{"name":"file-box","version":"1.2.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"4eaca6ba00eb6ffbd16af36af838d1a52f2efa5d","_id":"file-box@1.2.2","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-AP3e0ugT0qoTk9Me5FhOkvDjR0Nskjf7xyY5llCOIEe/013vZgnqZTesLqxX9htWmpmf4a+DQAFWWx/7B8wE8w==","shasum":"ec737ffaed568fb9f40f43207ed6803f580ee3f4","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.2.tgz","fileCount":202,"unpackedSize":398587,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQD9PcthN7FaY6jm2zVCfcqgoKgjirG1hIc3p1ZEQjAfowIhAMX44GRESchjXq3TqTKuZA7g8eIyBW/M9wEHDVWdg2hV"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.2_1635611031210_0.31376813228654177"},"_hasShrinkwrap":false},"1.2.3":{"name":"file-box","version":"1.2.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16"},"directories":{"doc":"docs"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### master v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"31aeae454ffe59b8602102206bcbf116899ade7d","_id":"file-box@1.2.3","_nodeVersion":"16.3.0","_npmVersion":"7.15.1","dist":{"integrity":"sha512-E/J+8KJc8nAk6DpaYHhivOr+fQANvKXDpbn9t5i4WJdFWh1BSwHGqgHl2dB28uI5kwrfaTrdJdXrrDl23cejeg==","shasum":"0d92bd4ec7a1e021ae450b0771fe37442b72700e","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.3.tgz","fileCount":211,"unpackedSize":402655,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICryenzZGrtMDq5zsvy9L+eoJL/0i7TpbouGQLxO1MwQAiEAkguCrb0kuZSwg/jeYhBcLkdvf60SG76uJieno9s/2RM="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.3_1635611376300_0.1558039158195701"},"_hasShrinkwrap":false},"1.2.4":{"name":"file-box","version":"1.2.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"6c5366258262605780ce5ed33f155efb0f30006f","_id":"file-box@1.2.4","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-uRx3nDaN5AQFRGjY9zfiQPtwcpFK9eqeDCxkEtmpKgWjDlBmjENpN+J6TfatPCv2QE7RQClIMd3OIneCwdmmoA==","shasum":"5f3d9a7117ebca0843c7db4c6508223eaacd3d1a","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.4.tgz","fileCount":202,"unpackedSize":398701,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIBCISnRm0hBdAImt3vYh4HQ0vJmc1GUyE/6XCxamTMS/AiAR+8iYOxBDbIcfF+25MCmOwYe4oWIcYGm6f5hYn7DDLQ=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.4_1635668821208_0.7785904656574354"},"_hasShrinkwrap":false},"1.2.5":{"name":"file-box","version":"1.2.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"d6c6dab0cfdcf9ddb2507a15f9016ddf37218240","_id":"file-box@1.2.5","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-za9EwDwuFo8ZxcJcMdNxXVjYsT5gzEnjf8HBDPhvr4D4Ua5TNzf6d8j3E0b+Si0arWAXJKE/VDO514V51D4ZVA==","shasum":"b27db68b920a041d0c39c8836da2e960644a9dbc","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.5.tgz","fileCount":202,"unpackedSize":398674,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCICOplttAbndnh0iUQaQ8QwDms41ny1uq8rz0svZrlnXWAiABs6NzKNAJoq9MlpUR2QhpWJwgqRj2NK4CivO6sM5pKw=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.5_1636004094011_0.18145187081404135"},"_hasShrinkwrap":false},"1.2.6":{"name":"file-box","version":"1.2.6","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"1aefd7b68467aca0bca49a07da9af586965492b4","_id":"file-box@1.2.6","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-oL+b3Q0qByecYabe8xpjsZDfnImzzxjC5n9Bx8ave90NZIq30hYeJZYq2e65r/JqowVK9GJuarbFFDfoFKvPjw==","shasum":"14bbe0328bf4d18ea9d0a1953202e8de526044cd","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.6.tgz","fileCount":202,"unpackedSize":398674,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDKPEU/WEYtIc71ZNuWP4dnKPmsMN0SMYFrwjQT7sJTJwIgGOQHi3HfCL2QGC9nxBRQ3Hf+P60HEVTFgDYnNPIJNow="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.6_1636004257794_0.45435330962536424"},"_hasShrinkwrap":false},"1.2.7":{"name":"file-box","version":"1.2.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"a7f412f1cf36281e8775d60562e2c529aaaa3128","_id":"file-box@1.2.7","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-UviAXbwHXfd9q+QcLzcRcv9Z5G+/Ig0LJ8D7IYHKLb9Zhsh0A7+5J5tmA0tpUD3uctH2BP5k6oFkUscLGshoPw==","shasum":"702b41cbd7a554fed1dd41877a1fa19c22323d42","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.7.tgz","fileCount":202,"unpackedSize":398705,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCkUp3VIOu4gDMMPHgCaZdmngCC2Lk4NmXHjOlqnI2QawIhAKxUZFV3ybvCdkWB2mw0tQUfx0fNZppzmkghnOIbeMbg"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.7_1636006101054_0.1738810964806159"},"_hasShrinkwrap":false},"1.2.8":{"name":"file-box","version":"1.2.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm run lint:es && npm run lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"950e8e7b1d1b17313c8cd6f209a35dbd6f42cdda","_id":"file-box@1.2.8","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-qI1+MrHXN042JkAL0G8YW1xjnIgjSGsaY1L26AD/WJXineGCZGFJXCos4I052DXp8tp1uy/7eX/q9mQWabB/OQ==","shasum":"f7df55f8637c52230440d95377e181739441e977","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.8.tgz","fileCount":202,"unpackedSize":396838,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGqNUzU8qDLe/dlmewPgHrQ7O7nMa9rlUDbfeL2Ejd33AiB9quy8Gqmp7xEzV0JqzbrvIIxzQFGeIHpe0KlAWN7RBQ=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.8_1636528697778_0.4296362313265132"},"_hasShrinkwrap":false},"1.2.9":{"name":"file-box","version":"1.2.9","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"2321191dedf8bbfa1ea7067085bb5cd260a477a7","_id":"file-box@1.2.9","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-B2qufpTi4va3zSHvzHZ92ZGsCobJKX92HEijR8f1xAw0+Uif5lTSn7aNCbOzp4zVrwR0yMfm52NN5u0r354wgA==","shasum":"409c010e6840348082b22e0be1a8e969ff984a6f","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.9.tgz","fileCount":202,"unpackedSize":396831,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIA9J30GJbpBKKS7EUq0i7en/ljmosy6mnvfTz0AIPPIPAiEA5CgsJNkGD61cACZFTAwbQCXSJ/hCM8b2dp8h1tDAM9M="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.9_1636537912906_0.844728095414601"},"_hasShrinkwrap":false},"1.2.10":{"name":"file-box","version":"1.2.10","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^0.10.5","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"4a226623da98bda7d999cbb2983e141865988b05","_id":"file-box@1.2.10","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-HJ4wPiNLFnXbsvqHSbIjfLlEwRbSONN4SlQgXrvQLzZ60iI/rXa6D7TFi944GkF1K+Gg+VJL0FHAYMsWvEqwUA==","shasum":"fca5b37f4d79261d22c6cd5925e2ef2abf9615ad","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.2.10.tgz","fileCount":202,"unpackedSize":397853,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDOJuGXuUaot88bQLaMf/ZXwzTLR355i5myf634VMK6AgIgXpNzD85Wnzv3SUSwxfPPu50ePr+do2NxIqOs302OeoU="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.2.10_1636818590842_0.14590615890171277"},"_hasShrinkwrap":false},"1.3.1":{"name":"file-box","version":"1.3.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.3 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"961d886516c7a40e4f6308fa62b17e1e689acf2c","_id":"file-box@1.3.1","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-Jn7s/0+gLH6TtxLq6rNxmNr37SBUAfL1FMqJa27PDTdxzZ5j5t0WMz1sBYCd9uwowtZQJyADqe5GeSp/IICHfQ==","shasum":"916f3a0d600c5044c292ced92c3cbd1e7ef4625c","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.3.1.tgz","fileCount":202,"unpackedSize":405141,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCICOnGZ7QKg/huaEJXX42fjm6INvEZekg315pwaCB2pKiAiEAgRjJ6U+zLs578v2vZGiplDxtVen/i4pZ0gFhXNpAkeY="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.3.1_1636889482196_0.7428026185184795"},"_hasShrinkwrap":false},"1.3.2":{"name":"file-box","version":"1.3.2","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.3 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"b9dc66ad2ea7f9c01eef78d3dd1a049c1f5cc753","_id":"file-box@1.3.2","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-qS1Z1CyBn4+/qSzABNFfUQVTU5WwaRDLbUBVhwuS97CX/Z05rv7TgWekR7RKV9vTvtKO4JoHq8VAg1fQYaegSA==","shasum":"550892bd5434ffb4cc107818ad89e0cab1a23750","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.3.2.tgz","fileCount":202,"unpackedSize":405141,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDTJx+Koo7iG1xTOgxgdNENWBnnIY2ixF5AMLeOQOt5qQIgBcW8WPEcj63YLLZw/xvqSZLfti3Y0B+vJhugulMREbI="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.3.2_1636889812460_0.5969669276756031"},"_hasShrinkwrap":false},"1.3.3":{"name":"file-box","version":"1.3.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.3 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"80a2849f4b860c7c58718787b62fa68c3fb24aad","_id":"file-box@1.3.3","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-qFVUt6ur4kyb66MTHLm0dUbvZ6E8BQSMU1nHs7jLKexm1PQDOWJ70hmjotc4Wh+r0RY1wueq3wjMjFS5oOUyEA==","shasum":"4728b2588f3651e9443f16ad05c6f78dff00b99e","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.3.3.tgz","fileCount":202,"unpackedSize":407338,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGXcKRjDU60K5BCCJB5qL4FJ3TQm3rNY6me3oc7STALpAiEAoYxOza6AE7FPPC2pWDhjoHq+6Kc6lSb4q4EJQKp1W8Q="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.3.3_1636974536702_0.9607269147583348"},"_hasShrinkwrap":false},"1.3.4":{"name":"file-box","version":"1.3.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.2","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^0.20.6","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.12.4","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^2.5.2","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string): FileBox`\n\nAlias: `fromLocal()`\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, name?: string, headers?: http.OutgoingHttpHeaders): FileBox`\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name: string): FileBox`\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name: string): FileBox`\n\nDecoded a base64 encoded file data.\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name: string): FileBox`\n\nDecoded a DataURL data.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string)`\n\nLoad a FileBox from a UUID.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.3 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.4 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.5 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.6 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.7 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.8 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.9 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.3 `version(): string`\n\nVersion of the FileBox\n\n#### 3.4 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.5 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.6 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.7 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.8 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.9 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.10 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.11 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.3 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"93860d9d343bfbae056b3420fcfc34d69ca94da2","_id":"file-box@1.3.4","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-jUnt4spqYs4unQlwRa3WkXGyYCvS2FgVJfddScqcDyTNhTzmgpEsxXFtUqnu8sgyVZtRoQsMcmuj60Rdwkj1hA==","shasum":"f3ccc719b99f6c3163230d7c4d27bfaec4549b8b","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.3.4.tgz","fileCount":202,"unpackedSize":407353,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIAm6OYnPkSAyo+HIt8hG+j0VgpTYfj5fPt2mru0ofBiyAiB5uRZfT7I8UDFPpBgkREq3vtyXAOVDzSGkC+t4k/O9xA=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.3.4_1636974799944_0.7062243006382207"},"_hasShrinkwrap":false},"1.4.1":{"name":"file-box","version":"1.4.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^1.0.3","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"8a13cdb7ebed4e175092a8f67ae3bf9459a6edfc","_id":"file-box@1.4.1","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-9MWzDv6bft3oBlcOHnFKbXYK6JySjmzBAs7IzZ3XA6+fJgd72YhK7KlrbC3O8Kll5OGpzdgWvhh4jSoSagOIaw==","shasum":"796f44d5aec5cd366a96261cf303547f1c353f0f","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.1.tgz","fileCount":202,"unpackedSize":410591,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhk4t1CRA9TVsSAnZWagAAvXsQAJziUlQlrH/b+DHEs25g\nUz66MY8kP++JQoq76TnGHZEvmCkpzUVHLHw4VRuC9mytpuDTGRr9dkyo5sg8\nmeHn1EYm7M4dGXXWxWBPZUF/ceLsrBa9LAkIntK9WscawE7ves5L6f/puwgX\nSVv9FGfa1F9Knze05AbZlFwq0+/mx78sYr/JGIivQv6sIHLMFt1AQfuQhgm8\npgN3yWXSfDQj4Lux2kLuE7pqK+J9Fyqs0R2OTrKuBf2YN2EPRmKNpym/Lk5M\nKa5Uz0rUm5TJnK8CtzJzYECOpkfNGeip0wnlwC14sdzcanHZFL1gxjcOGLdh\ndBbusqNjl/VcgzS/cW8I477ZIKpuCsyBqC1kJBl8xzHfs5od9lhehzgWoId/\n2kE1f8nAM8kL2SMrDAIN+GSLMXd9dS3Z3H59N7fcHFYrnp2o1/fzYcmQdTNF\n4H2oRryZYByKZOUQskarO9zouaMZureL+U4K0/yNHKAbrmrwDmRd2P9RENuK\nDmUJRx0sn3HfOvShewvRcQspMcviNrNJxeZycWbEVxPgqxxogNLK76RhO4xA\nSUsO2nYJ7iqu223XIpBqbqUc9HoTSFA7bC7IT8ULhYmfmAD78qGgxNz+90Kc\nfgGxsLG4ZD+J97LeBaJePeYXWIJTeJwUKEJn9uL6htbQRpvcezaJLxvOXUmA\nnWgc\r\n=0V86\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCvW8shg0T2j9Z/hEPx43A0Qy0DiTUjgdwAUHCTaUBbnQIhANA7M4fI52YAKCjgUlzCqs7Cv73kU+GLF2xPxLTw8lXg"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.1_1637059445379_0.8194011024301717"},"_hasShrinkwrap":false},"1.4.3":{"name":"file-box","version":"1.4.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^1.0.3","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"7e238bfbcdbea2368abded27d93dd6c4f2faf426","_id":"file-box@1.4.3","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-rGFN5JpKCHeWNgBQh8AbiP6Gq2joTZgyRl1gK6qhYvkwO/VnQDBZXBWHBtpj+XezfDOgQ1KeuM046Ivyo1VQqQ==","shasum":"8841f9d1c2ae90d187586f9042b158da10410ea2","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.3.tgz","fileCount":202,"unpackedSize":413172,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhm1o3CRA9TVsSAnZWagAA47kQAKAm8MkUzZEgk1g7ggIM\nhoNpHOVq44Tyjm+/t3Ud6mgBh7ywH0+mWX1Q1usX16CsdUtZgltz5E37hcvi\nV5O68Wh1XHoeBfRz8byr7moRrVzj76z2OEDfqy2dqCKqAby8/QfEGcNl5NZ/\nSeOQbey1kSWK3L/0SNdcCBolbaGkhuTcM8DFwGY6Lt0Q1TYy3jbG3Ajk+KmN\nBscUeRmdh9huqaEGKIbfrmNCY598iNBAJ6qRiKTb2/Y/OwRo2iLMeqy6mGuY\nWW/WLCXAh/inIK4vMdnz0n0igX/bXLolvyReiv7SbcU6PhWZ/WFADNIWxk2n\nHIDD+JHdxuDOL+yzUzR+v+qhg+l2R4hxJJwMnJbyvg9xUn/cJCzvE1bxJtYg\nmgvJh3ZOcET9B3bXl7LwKPRIXpe3HZn8u4eprimAbddUqjjbrkVLVyXHnDfh\nLLrhVwWPfDPxjvks+h6nhozZSh/PwbAuixBKs4+jdz4rAhGI5+MhL9snSB0M\n8YcWQ3vahfd1vEvHjEgWkQ8W4hLjqsaabaAhe64/lKOwZY4Lm1iiOejnv/Mw\n613ghrtljGKSxAtyTGcY12zMTv3+jnzgr3J7s3eg3VkduE31zM9xVgRYpIwD\nphbJ6KYtkMqZJjtYpDrI+9DNQTIsVPaoQANP4YEUii4GI/eoN1SMKxCn2pOO\nDVCa\r\n=itfQ\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCufzxJTI4GY3EH/1aNJAoWj5a3jMYcavIGud2kZfMyoAIgGpFwpjJKWPl2VcRto2W2szOMoXNV94tSchBZ36gtRKs="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.3_1637571127080_0.303437621089061"},"_hasShrinkwrap":false},"1.4.4":{"name":"file-box","version":"1.4.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^1.0.3","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"9bf8ac54013c64b51d5943b07716c98b057beb9a","_id":"file-box@1.4.4","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-goJ3pKU1Qzyyha6D4SFyPM59KBmhacm3xI+EdEGneJiSAiaqoHtJoZHdZ7Nqw6Erb/LC1/JH9Epd7Y4rzFpkFg==","shasum":"51f1163f4188dc2a9dbd6d3574460e4da9e198b9","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.4.tgz","fileCount":202,"unpackedSize":413172,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhnEiACRA9TVsSAnZWagAAFtcP/2wZX8hsQRaSdmib4gTu\nZ6WZZE17486gV9w58uO/IugLXexhxOe/kdufLt8LQ42KVVS9b9G6vGJ0DAy6\nhDA+6ndidDlM29CEta1YWR73gmDdl/Vd/odlx1QK21zwQvmKDJBOyq7USeNC\nVn066wqm5CMoZS6aZYpGbj3bhmtz1MuuI27Yk6csERSiyLTiWruwC3HF7RXX\nqEEldBTv7tr9OBD1UTOaJz9FtgimS0/PU+GRx4U/ED7K5iyX65jAh86Lv8CQ\nIRlLqWARMKtkieYT0/+r4Y8/JNpn6HyDBw6vX0b5Hhz+1lkehD8uokJ51meJ\nRQUZ6yyqPLT64LztYSHwto0Oa88cvB5TmJgbimCF+BXk6SLEpmA82Hp8l6rn\nmDqozEEBRkMIRDVPhGHd6/JtzBFj1bZnhISRSzfNEBBwgFdryWiTDJpmraV0\nrntGwDC+5P4qxnj/q2MI+8GtJHxD3+vKOG3YUN/wvr1xvUgPKa975NoXUfcj\n58XZska+vh0YoTz5b+n/A4QyOMNdzPILUx5cWz4akdeEmca1da4YYj0CVw1c\nhYhXDFTjewdsrJCcVYpFv0r7AgSY9gt+PXiaAfkT/OQ7VMZIwx6sfEJrQTT+\npCmvk20YgrACT6skfVI7LfUoEmOdDXiYyDc1lMNPleTT1oQxkm/veT84yOg2\nx/L9\r\n=g7JR\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCd4VJDpteDe5WTzT44UTVPAa110dBCIU0WJtyrUi1pkwIgXjyE0DiKf2wseJAEnIm9voNeHxQdX+dejcdhewXGlkk="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.4_1637632127910_0.9691709836297979"},"_hasShrinkwrap":false},"1.4.5":{"name":"file-box","version":"1.4.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^1.0.3","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"844119459db8ef5d2d5c001d7659039c6edd0377","_id":"file-box@1.4.5","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-2clCZWCrceTJKpgPW/VvCW1Ogep/BKIEKweGGPvPDG7HzLHh0nsNhioNZTX//vyuoU/zLVwO+ehTU2HwaUIXVQ==","shasum":"18785bb74a4014af976e709e31e3316fc3319618","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.5.tgz","fileCount":202,"unpackedSize":413172,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhnEooCRA9TVsSAnZWagAAJCAP/2lRU0H6rU9xsriXakEo\nWM4Rvbb67rxwTDpDN/BBsPdwMrCLU1ur0GB0FVz00xkOa7ef8Y10DTDJM8QG\nUEu+Y2hVRXzUyqf8ttcAPKVPOZTslEcJVu8B+WD/QIQ06kHgIcHsdBA/NlLS\nh2i4ssXYp3+5B6uRIQjqLI8YnwpXub+F2V5rX56dbSaMWKiYqphfFRLczvDb\nJ807ybyjJRvbVnWMMoZ6k8voQiS/BneBwB+Dz06DL26eDoXLH5dw0Q6NkbhM\nDgh+KfbEqGHEDsvSn6EcuBy2dxSPKzBf0PosGbSaHbBmHc4lz29Ng+RpNg/5\n7TXNnyWeRXa4ALnW3DdQ7GyxhXYVujONMwwyqEden8GwhZrzGjfe7M6dNIyW\nIpZPP702z89DuEfeTvGdYYraPqv/8r3NAimW0OYzGPiiQYZsRFKwe15pC/kZ\ns7hM3Ng8nt+c0mwfyB/yFumuYiVAsq/OsXjQVITn4Gzor8eobngkUPLdx7Vv\nskcnx187axV+GvOgr35RhWSAFUh4km7zFS1Txd9QIyfmdPvNS/GUwfMU6rBW\nL4Y1Yh/obKAvaQtTdKzW2AA8loouZFcfiCIU9DqXhRnCjv9T97PyvPsbuQNc\nMJ+EMl1nyXAhlyTDSVKPDIOOAswV4LxEk3QB7cwAQbDwzOHpHtZ6mHi3ixLG\nQbJD\r\n=rpYb\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDkiknVG7luD7aWisF2j988/2lgZexx5KLs0j1nNU89qwIgblpqPmZaKiO+/emMDbIhjX0iTHhVKbD3G6a4K6/KvmI="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.5_1637632552762_0.5030624324824322"},"_hasShrinkwrap":false},"1.4.7":{"name":"file-box","version":"1.4.7","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^1.0.3","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.1","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.4.4","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"8866d43d63d9e8914ae22ec2b49da55c2e6c1d96","_id":"file-box@1.4.7","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-+mLh5oRb4cAVhEwJpmBIFH5wrKvRCa5CXP9VV0sWOQfnM6KaO07s/zbrWp+HXj1V6Ih+ki1VWmODcIfzP7Um8Q==","shasum":"bee48191d4e0ffba27a04f80a994d8ddb1211b5d","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.7.tgz","fileCount":202,"unpackedSize":413326,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhqui2CRA9TVsSAnZWagAA4Y8P/3Lky+OUmZrjiZ6Z014Y\nAFAFHXx/bUP+BKADahji3YQmTixvmKnuX9umRobSpbDUXT/jgUR/qg15RQff\nUoBgzprJyW6TaA0WixVqsgbn0W0lHtiE5iLcc3XV9Y5Q5kbP/TRNXP5zdwW2\n56Iv7PH85RRLdGDLZhrxeTXh2nK9l8Lv0dTSV3dB2A5K6HGaDvTXry/xqA8T\n8Lmog65KuY4+VFg/5CDYVIulw9lHp1av/MQu+/qNvtUWPJcUFVSwhxfGgGeg\n4Iv5CEWguuzZ/NWK/apdFTrNLTj0e1HINQqPmVuuvALcHvJAr1wQJTSy46/n\nL7WcYTJVijkL7fIJ6H0ATWvOnAQ8bZ6gOM94+ldN/7lBj5/tE3Jdqt1jbqud\nmZnYSXBx30vemtRgoknjLsNp+R/wgfy6b9AhY79AHmI5rc64WYtYUZ8t5VRj\no663ncFXcNsA/YiOzPU+aBeXXJHCK09hq7seaYx0gUfa/bT64Qooh3zOOq4/\nITj8MWpbxiWgE4haHLZve29ugHvM995ApQVCxupwyV1GwxJq/Cru0YDm6bVc\nmC5bIto2244wCOGMAnAH5M3RWelj41fa1Qu9hDSeMQ5bPiVMPkTpnVjWVhep\nKM7CV4bX0JbjFks6LjdFCRioNpjEJj6gRZnA1PZtWRh3DkJ4k3sVIQ2KWC4t\ntl4b\r\n=zmcW\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIGfMERGEb2NMfUPnYQmIJDKvINGydCn10gjMe1MbeIz/AiAT5qKIgmhiykyMxfLP9cy4vsbY4kft43ThVyn54qJg6A=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.7_1638590646414_0.05243534799993532"},"_hasShrinkwrap":false},"1.4.8":{"name":"file-box","version":"1.4.8","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"099a6118a3bad6511cced3f33b204ac1baa85e0f","_id":"file-box@1.4.8","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-AjPvEiXdDrrkg8f5IeZst2zoAMis7/P+r6V2YRMeXKKztWvzGFVUCmPyZX3MgOgadaEtu5OZp1kU+pH/6PA26A==","shasum":"5beaa8aa2eeedc199e0d0a35d583b9f1ae72a121","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.8.tgz","fileCount":202,"unpackedSize":416528,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhsvE2CRA9TVsSAnZWagAAtWoP/0szC08b5GKXs9COmoKj\niiHZ8QVzS8p4vTm2d4arg4gclxJ+p+BaJVsO26+NaFLzISIyKimpPg1YD+jJ\n0UQJkMNTt9C+ntNr5kZH3fmCEqo7XOSTZKn9TuVA49EWSAhhpz5/TF3Hl0yV\nPCAo6NIhEsSXahdlJkyS0Yg2F7kcXMOTtZIGXCotcOvU6ZEX2QOF1lLoG0tg\nl/BqaWeUZ8ttwExQeoibwQXwV1boW8uTMsDdjjx7bd+/TMMpASjMEDeIlVFT\nDWRXmXm7b3yt6m7AF1YMcFqqwWVeuYMSx1nqF2kc/sbjWAksPSHpHtYstk5r\naW60M+cHByGoTbjIfDLMea7JsDi2t8qRbdyZGXFylQFDqArjwRITYDw1Sgqy\n3SzHGmVWISKkF7lmSOA4qw14NqoasXgeO7m4gKpfw9WhCYjv+Ad7CgQIUxZo\nnoirMAG5tdpWQLoa7HFGHsXJv5eCptLY+PWLfF9pmyj6Z1KPcHxXdmGExqxi\nHO3U4EUhXhnNefUro1eJq7t5t68P1Xrq9H6zEUSedO+Pw/M3awOtEVGkkhHZ\np/l/tdUcOijmwXrooZmf8PGb6yQoRn31H5nOBOk7fW6cMJh/YjqhnMpaWQAo\nmOz56s0+QO5NnKNdVsKJ5agmL0xj4wHsup60D1aMRAPbv+XJKlS74NluEn/C\neaLl\r\n=KKlt\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCZZ8m0XIKuBwaM0G5GjG+EK3rq1wCzm5LkIiQ91LsEnAIgb2x9AzCABjQZUsA+/CWUI3th/TBRoEoEANz1DH8Y/m4="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.8_1639117110364_0.3021334895976482"},"_hasShrinkwrap":false},"1.4.9":{"name":"file-box","version":"1.4.9","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"cadba10f2b6b5836033a422b620e94353601cbe4","_id":"file-box@1.4.9","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-FRhjUk/S+SF3CNDkMMvxpZ6Hn+qCJ0Er9f/5BpR7iPTWOc3aYfTVp41rDDCJrdMdVZtKJ8dm8MCyotooStAFkg==","shasum":"16e718ac14abe621f571ac372049f4f241c82ce3","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.9.tgz","fileCount":202,"unpackedSize":419490,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhsvRQCRA9TVsSAnZWagAA3sUQAIQtK+GK36bHb2yNF413\nXXz0UvDHfi2YWgPw4c7gG3Rmo1RLwfEXZBm9mo/mchneiaDDbhudaujYKMMj\nRFFGeafsEySYFx3mF8+ZwkUIUA22bLTynH202YqFDTm2nz0Cp8J4pUdPiFDN\nDQmQNPsaedZ0uQrjYX7sHcd5PdFWUNoohtzOUhUaeYw6kdUBltW37Bpiiyub\nZPLUBEPXcQqL3WyT9ibv61Td81QD9pxl2WFi9nmcc6PX4rCd5aj9fBLqLRGS\n5HIFqar5S77idqz1d8IF1hqj23eFN9AZCmtlGWOOzRO8YZ3lqZUXxddvmvuV\nPdmUhg5STfNfyh3fA45jv7/wMKeN2rKaf5tZdX1edKsZxWRGvvKQ4rEq5sjR\nobIbjw9VYrG+2uWEBnDKGT7pO57N1x3UlAduVmt6DqdBn5YSCWDXuOMYoWjH\n90E/+AZVCyj4OdEKXnADA/bciBqBuPXVViif5MuTsTb9VfQuVYx1zIgn9D+G\n0KaJ5dbYh9jX+PBVVqtLtoC4m9/JrF7RaPiPBvkTS9VfuU1RB5FB5+1M/CBz\nEjuSigpW9+4nbQh7vdX6k/cSbkQIPAPFm1XZDyvGXkHbzOz8XyH2ZopicC0z\n9hXFL5jG7T12Kl3Kv50fuKeaZYpo656IevsS++8x0TuGL96JfXtcSCAifrYT\nHxWI\r\n=oCjP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIC1H8LOKeE2J4TmR5YsP9bx2VdeeiL3GvrFIpr1uS1waAiEA+lb1azat48nXWjDh0MYNn2yhUUaqPAeEa0PJ4dOs5ns="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.9_1639117904663_0.03870955653026287"},"_hasShrinkwrap":false},"1.4.10":{"name":"file-box","version":"1.4.10","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"f4f001866485a22dff0cb7992241d88d9638201d","_id":"file-box@1.4.10","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-z7HRVuwlKvhvd88WIRuBLhCjBKu1E7nEnJHiF1jZVXFkhXwg6PrTbclyIlkxR0loU7bNhK6H3PfTYaj6cnyIJw==","shasum":"0258c4deb29008aa4cbe3df8e291b828e7a86bbd","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.10.tgz","fileCount":202,"unpackedSize":419466,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhsvTJCRA9TVsSAnZWagAAQ2cP/AiiwQEjySNsZeq0P2BE\nHzEixirDNU4JBrgbJnI/oCZAHfinELLb/D5VFyrpzi7Seb7m0MQRLhD6Yuuh\n/t1Gj0J1W33oZEgKyXYnFTtOVlMivxF88jCpOmYKyJY7h6RlSShyoJ4Go8ld\nVGv/w5lwIQnjwNCKgD67uR7hShoX+6UvoKR7MRZjkJbszsVji69B2knNEo2a\nmGWBlbr+5Cco2kZTFxs2koBqYa27tXxqN7OW+YdpdfvqcozuG9Iawp7jmUwe\n9zjV7OfsK2zbsPxOEm9KDjSl+8Y8o3rG4Dd3n8BekpgMsmm0VQLymo3Tlnbc\njaQ0QPLxfaYZOAB4lRgL5l9ojxGINZahFlwAkirlJINnAkUlrv6hoibBpF/M\nwcBTi/bGxJ1Rz/uJwF6CuxL00k5QVTiHaaxAJHhuNtPkMky4V+frfcjtodbH\n7brAjL4T3f4PFLAPcKjnFRJUwDrSrdY8cQHlt8TO8XG7qhsB1CFAGIPVsJC8\npfmCcNFt5tWWagDqwLZVH0n3s2f1deC9eV7G/tcmQh3IgeIUM5rEyr5LdUfo\nNY8oM7qTjOhY7mmJgX4NelV0av9o9ezWgCzPBRjT/p9YZwcLiEBcyGioRxpg\nbV+E8G83bE4ooOBfPiw0q2XrlsLa2okMQb081JPrpmEECB6lzSbx9LqdN+p3\nPbw6\r\n=RN5Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCFZjwiOxWHLCsseU+toLDcCw9eLUrla1L7sIj8XmzrRgIhAJcF+NM0M/kZJP6JM2BTeWM1EMQgbSROSEF7hm4G2wGF"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.10_1639118024929_0.29218016416746595"},"_hasShrinkwrap":false},"1.4.11":{"name":"file-box","version":"1.4.11","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"421cf0ce469bda2486777cb5be6c6af7ca6437fe","_id":"file-box@1.4.11","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-Bgf8D11pjOpW7pvkL50EqcAtlt8EtpRofbv3BvvwEU4wK3BRT1wbWMOvaIYlitDCceKFpsJq9bIQWu0MBgz2sA==","shasum":"7740a8ef664a291e62e7498bb95b083918a67c3f","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.11.tgz","fileCount":202,"unpackedSize":419679,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhsvixCRA9TVsSAnZWagAA+zwQAJRhZShboQ3tTDd7e2zY\nc+We5rEf0hNJiwbew0MJPS6mmvSA5EHuFnRzRcGpjkW5HRi6djPgrDx73R66\nMtxSonSZ4p5P9hG4GNvYlGMSMWdujBROGvTGXcfUJDgP3XypPM7pVlkefvHV\nR9xGrUNafU79M2ypFCFJD7Ztvqdh5YAzXHIzU6xxvCyw3LDtpFrmJOxJFTz7\nigyezsFR/NY3/ex8aZAEsmPZ+wfzhrZoyx64tfzm15DVSdGVuQNzRVGZu8BT\nDw0vEL0/Eg5htG/re4QEbhY+SzePVK94+HmJR9FZjphnLm27ffKOCfoAMhON\nxraKbaFo20YE3vvsPt9nPb0wS4wKs4A/OOhIJ9fTLOcAcwU/aaK7fKZNxmbL\nY0EQNqH36NwALy+uLqjH2RSgvscyojC77SweR8myQVkZ429toglNCkVlgpsw\nTjQdt+LfrwIZ8WdIFOxyj+Ejlelz/Wftrf8jbIEVeG9OzmX8qDJYeQdKuGuO\n8ms6U0scCzl2+6vnXKKKHXyDimIk3tOF7FW8VzKDPCI/473+k+HhCG2RAF+2\nzNRJ0Frt9hUG49RketaRCFV7D/y2vzVcTSDpMNNBwRhsSppk5bUnoN3naTbX\n2N9SK7Hk3xnri7Ro4hyCsSGrtS8MHT9P6OYgSQg3WKSJNfOsQm4Sjo5T+w51\nDzNq\r\n=+R5Q\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGo94q9ILJ1vJ/9e5exVMot3nFyB4fQRaQFux7705tsHAiEAq+4DlLqXAuKhuwQRoKTg7YPe6Nl78u0pR4zalrsufbQ="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.11_1639119025620_0.38405211330159195"},"_hasShrinkwrap":false},"1.4.12":{"name":"file-box","version":"1.4.12","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"19c58ddf450d0443ce2611347f6a272139d94231","_id":"file-box@1.4.12","_nodeVersion":"16.13.0","_npmVersion":"8.1.0","dist":{"integrity":"sha512-Y4LoxHhbbm1AEW3R1ky2A/TUbsSNXx7HYkEcRE6gv599MnbVPwmfzfjo25nOWA/OziweN9nZAm07N42LODpehQ==","shasum":"2bc85652d363d13d5142fc2c93e470e2606a535d","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.12.tgz","fileCount":202,"unpackedSize":419697,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJhsvliCRA9TVsSAnZWagAAKnoP/j0UtvYTMehSP5qkfCJ7\naV7rULHxrfrrCbAT6K5dfQvvCQnpBvru2Q2UZbM8ZqaebvuUdceCeQinG38q\nnvAVhC82HyCg1hbPV6QANQPfNB95pLx64stWFHOFqAM2rNHtXd0Av9RLJNdT\nSarXI/bE597T4e36zCLu2YMiU45tx+LJMcO75AoEQaTtVFPaxHJ1XzuwfsML\n1H73iQSGC5qtoEonKLjtj2Z8wx/I4d0GWwc+523FZvEjXdZJ004d3YhW2hpJ\nFUJonIgqBp7tMfako2thfRlME/5WORxu23xY7um+SwBixpzfel1F+wuCBaax\nIm2wT3TLqRVhf5EhzszFQTYPAGR0NX0SwRFQC1h4CPRJP02NYu94SiI72371\ngFybVFFmceEPjz61GzuD+P4RszmRkk7pVJjOZo9KL24k+gloA2sMRcMRpPGA\n5N7Z1dTEjrD0O5A+WN+207CleYqZxedXEr9hDgc1nS1zBEEST+7ZAnAe5VzD\nUQzHW6LcB3dwNQ28HJ0g90P6xPADuxb4bw00xx5n8L6v6CpN5R2/e3ZC9rJ/\nvAearZ6C40yYbi8hcy5prU46pk51lW4KBMUt/gxZ1zr3+m411wdJo5/8x0Ii\nhKpN3RSi35rBMXynyn578je1QLWr9PpNgfKMVLGNxcniBWpKyuu/DBtaQD4Y\n/ld1\r\n=in4a\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIFudD9EGSYjZgcirVqqVm5DNmAnCDV7go8Hx1Y+SzLF/AiEAmVBX8ShOWMeEPF7YrQkaICZkHnUbSslHDdG083F1Ua0="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.12_1639119202744_0.9829388919212798"},"_hasShrinkwrap":false},"1.4.13":{"name":"file-box","version":"1.4.13","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"ef20f0a9f866aee53282c18c3ba1c062cb88b987","_id":"file-box@1.4.13","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-Abhkaqf9kQrVIKuvxJHzE5A1LZf2Gsk+tf9t+aiHG4QyCkcs980JVb+3tgB+eablpJCxQdKcLTgShn4neYQyzA==","shasum":"99f7a78512e63adc228468db8da382f0db89ffb3","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.13.tgz","fileCount":202,"unpackedSize":419666,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh4bRCCRA9TVsSAnZWagAAvK0QAInzTKADM0/ZH9ButJHK\nIGJqcbAQi39Y6KBYhkLonyKcVkqgsd4FGS7q1xneI7KKOYpP1kmmDy9df3Sa\nn3mi0Xtre3bF4yEphUhcizCfjDHmtjDG8jiRR6hSxi/cXf9/mSiGyxT2MiQ5\n542w0a+FQ+JlQW30GJMkWeyFVD9uw1aXG4McJm6uHd7Z/O2SW2ebPth8+pH0\nXfpvhTEqV3uwefiiM5rDUFishheJZO+yInIOYRW+5zJ+bPVfMcD2QB9nMqtn\nbrBbE3QpLZp3Zwif0m/elQlbQZebsa+R6TZ0E40H+oE8iCkZzLVCfnnMXOEv\nsvnDr3y+18o6RkHhy1+I3PBbSoBjUTO/gsSTnBjtYbhhpjYgxe5+Yr8PnN99\nRKOY8ESne/Bg5kUu9/I5uvy9PcL9C/JevbR7AXBovNRn38ieLshMe9AJKPZk\nHryppAA7V/3WqV6tvIlUXXsRTDjJzUkU71Zp6naZlWNAFx4AjH1GCc79mlqs\n4F38+qGTgBy4ywrATxh6VeE2Hh3D8NB+vsLtJqt3O1JdAFX2q/AVmnVKyCQ7\nykqABMkZekljXFHlZcV3NIrcTti4EmKnGYp0JmFn3knq7lLkwTuzzsBkg+Ft\nR4ruC7VNzlcXuNV7z1rXpk5r9Xi6jRzjBvNviAfyGwvRN9/TnS4WcljnOqta\nrLWr\r\n=+xVG\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCIFv5w2ydKI3WGLlqMMvdlr4RWssztCbCa+WDd91dbBeJAiBOzp+zUewHCL0RZgYCTSDLpfPC8G7heuyfTsMUEdFeJQ=="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.13_1642181698365_0.24221254343475684"},"_hasShrinkwrap":false},"1.4.14":{"name":"file-box","version":"1.4.14","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"1b11d22747cf3fae73d52c92aea1b381b4ff2329","_id":"file-box@1.4.14","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-mnSqrURmCapJ9f3IEw6XWokew6wF02+4KxY5xgAU/3l8345sQftzD3tta4hRhlwuCUXv6K5LLOvVg+xc5n/xeA==","shasum":"02df22bd07e2d63de7191a4a81fa6a0ca859eb99","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.14.tgz","fileCount":202,"unpackedSize":419833,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh5ufLCRA9TVsSAnZWagAARh4P/0CsJsvaCreyQ8nRURaH\nLiTNn7/3c7SZlq7e1MyfY9HsD+FXBeV21ve4SXek7lNTJv72c2L5N9GIhB8+\nLRwCZ6R+NYI94OcvaTWnYNnPQRa8gxCVHQ4f9XRuZzUIwe5M9gUvLwUoOUzt\nuGgHkKhX/1wFOVdz/Kyc839IXDjef1qF2fHDZlWTQiPMgBgY5/CyxRgmzVSx\nr2thFuP6dhXg99cHHAVPAhQLAwuzZ8kosSaVHAOeEAOANgjU8NOCDb1Ju9H+\n0371ZSgFd9cH2yvstltrxuz3cbpt2rvUytw4OfWS0VmahuRJxoLW+SfK7MVs\n2kOlSFfRrYmTRA7mIdDGmDgaQnGbYlkTSsnNNHZQoga7PvhzxY7YAeCN3sDc\nLdOgqoeQtGcoTQWgoQdTP9cwFB3hpoUZ78T1JhVa2gylb5yBWWxHnhAOMzIm\nH9ZYHrIgRfO4UJLgEzRlgsN+1MHd0xldapKlsNxTHUL+a3jzbYYE8k1zKD9T\ni37fCGKedbSc55MomQtOBsdVTgbistH6UjP0UjmveF5ZWz5OSRd/f0nZzCQN\nwCVByk4bflEPaQa96x4X3iumgHIYhu0sJZyj7AvQCqGTWYSTanGfq74rUeFF\ncdjelc1aL9La1DJ4dE+WWb38IGCnRHOhcqCSzcu88BBDJTzi/Gwb7o4LcsZY\nRbGy\r\n=N76g\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQDiGIrnzh6x/trBUVTP14LyucwauRezDcVAAb9x0sa/xgIhAOPv0g8jS6ngZW92BigHA9ZdZP/2MN0OWVKVAKbgdjRb"}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.14_1642522571264_0.2652120891772667"},"_hasShrinkwrap":false},"1.4.15":{"name":"file-box","version":"1.4.15","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"latest"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"gitHead":"fc5866840ed4c8af9e04c431938f925f96a3cca4","_id":"file-box@1.4.15","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-13x06z1c33UJm7Urp1AZM/16s5WXr9nJBVqyicyrI+gl5qUYGwz0cimPV0chMQs1MOVpImlY3JHM+JR2MzyC6g==","shasum":"e4dd0a372ba21fda9cc9a6f6e246babc3026a631","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.4.15.tgz","fileCount":202,"unpackedSize":420050,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh58QCCRA9TVsSAnZWagAA5sMP/0bCgv4odQqYMCaLa8NT\n792GcUPjit/j84ERnS2ce5Wl1VNU0H3Qg3GnTkcGLc06XYkMgqyh4tvqtVrb\nxS0X86MPJVyDFJR1/GxvP7dSkNZernq80/DYxwrORIO2oGA4KPRamfeS5u1q\nISUPMm2eIlAylN4y+vZfUjndydkisgrVvugyIoFi+pwMSbiZC7n33xtl7Cu2\nape4d9lk2ALPlfs74kSx6+/DWuLcFBbcl89dmChSZ7NH1LVcGPUTAxnTBEsO\nm2w7L8X+pQubHXUp7gYPqqOWMfvCkgF66W5ONmv9hzUy9+prL8NRfg8dkeXV\nmQWjXZrPR0wZq/ByCdKLUw99oOG6dqipF1cO0pIL60/fdDB7T9KV/kym3yQ3\nZSzF67zY8OvzdzjuAMVR93cjDCnk3k8ZzmP95EiI0LScVUz49JnTb9skwr9h\npNK+RIFUxxdRRc12RKLf5VCIwGd5yCWPSjVIPdz2hn31oHNHb92YbDgKaVTp\n8MiHvZ2bXkFMNzcL+4g1gqnrb8YB80mfDXiiYI1nNcfRbRBwUBbvY1CvNb05\nU4C26IEs040a1T57xhDmleb7CXa2+oU/q4cn/QXU7TtKTfZVMrD9/p1T8CuU\nbDAE23F7LROW6+fMFkTEOX+9crkw3w5/r7jdk1CbRBjQYOQAldpp6kPgEwQc\ntIkK\r\n=VEbu\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCF76/JxjGKrFPOjp4hrgRp/ztL6ekdIWCmqB/bVy+IOQIgVZDB7GTmM25rYjLF1csYJf9vk0e0vqBHxjBTOhoarEc="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.4.15_1642578945961_0.7758278494629833"},"_hasShrinkwrap":false},"1.5.1":{"name":"file-box","version":"1.5.1","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Save URL to File\n1. Convert Buffer to Stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n[API docs on Paka](https://paka.dev/npm/file-box)\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string, name?: string, md5?: string): FileBox`\n\nAlias: `fromLocal()`\n\nAbout optional arguments:\n\nname: filename, if not passed, will be parsed from file path, url, etc.\n\nmd5: file md5 code, only for checking purposes and will not be computed from file.\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, options?: {headers?: HTTP.OutgoingHttpHeaders, name?: string, size?: string, md5?: string}): FileBox` \n\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {name: 'logo.jpg'},\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name?: string, md5?: string): FileBox`\n\nWill be named 'stream.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name?: string, md5?: string): FileBox`\n\nWill be named 'buffer.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name?: string, md5?: string): FileBox`\n\nDecoded a base64 encoded file data. Will be named 'base64.dat' if no name is provided.\n\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name?: string, md5?: string): FileBox`\n\nDecoded a DataURL data. Will be named 'data-url.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string, md5?: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string, options?: {name?: string, size?: string, md5?: string})`\n\nLoad a FileBox from a UUID. Will be named `${uuid}.dat` if no name is provided.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `toStream(): Readable`\n\nGet the stream of file data.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst readableStream = fileBox.toStream()\n```\n\n#### 2.3 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.4 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.5 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.6 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.7 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.8 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.9 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.10 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `md5`\n\nFile md5 of the file in the box. The value is set by user, not computed from file.\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {md5: 'computed-md5-string'}\n)\nconsole.log(fileBox.md5) // Output: computed-md5-string\n```\n\n#### 3.3 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.4 `version(): string`\n\nVersion of the FileBox\n\n#### 3.5 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.6 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.7 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.8 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.9 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.10 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.11 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.12 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.5 (Jan 18, 2022)\n\n1. `fileBox.md5` can be set by user. This filed is for the receiver of the filebox to check, and it is not computed from the file.\n\n### main v1.4 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"b345a2210a09f55073edea5194210cf6d1814535","_id":"file-box@1.5.1","_nodeVersion":"16.13.2","_npmVersion":"8.1.2","dist":{"integrity":"sha512-FNNdv0YgyEdnqAx4HeXqB9wJqG/JGMf6aGmnnjPH7VW7dLVN2g76zjBs0vO9ZrpvTnVnl04lcufm4LTeLW27ug==","shasum":"f0789eb050d504f93746ef830fdaa1ce6a881a83","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.5.1.tgz","fileCount":202,"unpackedSize":424534,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.13\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJh5857CRA9TVsSAnZWagAAhzwP+wYxtPFF9Pns3k8A55Jp\nW+G/7Hi+ZJc51pl+Y5C0HjMkBd1AymZZZB2wUt/dBGwgG/ulDUNtuNjo7v79\nL8QU6Y+uCLV3NcYHcSywSdUru1/PhpK6x+7ideWVyyt4EIMw8usiwCd7Hq9z\nNcIJIqoGIUeArjob/5metvrwYD8YYnbsk0g1AUxJXhD3pcwy7MGSluxkcZ6n\nE4iJNZtohW1dtZ86S9cOYQgKyrhvxK8vrqiBnt80vinleVwJ0FuMyIRnAmt0\nniItqD73FOu96w2JjQUVaJtfaceakmIk4NYNTfiyYQvCH4XP6aJUqdaliLza\nPrpBTv2g8M0k9s1gtw1H37sRbBW7KyePnkYaqa2qi2c1cL3Hre6w2JcIlxem\njGdsS5TwPJ+mR+eKu2DhJ6th0O/fJ98JbVQ8iAVYFHSIF53cp+RCl+JrjqTn\nBXT18c6gaL5vSsHhiJIzI0GXutux8qOG9+r05MYykII3YTH+J8eV3YDpuOyX\ntvU43wVcHw+3oizyrOv1sVJfkWO82tMKAw2CeawEEug1nd4lOJNMbFJ6lvnj\nKtmAI5rK+UbOSD8+rgIafI++eKYbNRZWN2CFP/DJIQZj8M04pK1OFeDR1xN2\nFKVki9aT7eSQyiB6XaFZCgVW6pVIGzOIArqFKOG7KoiPX6pGRadE8VJAu9Nl\nP/Vm\r\n=FXy+\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDIsu9hqM0Qzk0wAbZzWHx2s2UXrrJl9YrSmYAY1/B6RAIgNDMl1HCv3WHNO5o3s9V5VDpFRdBnhZiBr/EJrzh2EWg="}]},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.5.1_1642581626773_0.17055645946464004"},"_hasShrinkwrap":false},"1.5.3":{"name":"file-box","version":"1.5.3","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Load local file\n1. Save URL to local file\n1. Convert buffer to stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 0. Load local file\n */\nconst fileBox0 = FileBox.fromFile('/tmp/file.jpg')\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n[API docs on Paka](https://paka.dev/npm/file-box)\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string, name?: string, md5?: string): FileBox`\n\nAlias: `fromLocal()`\n\nAbout optional arguments:\n\nname: filename, if not passed, will be parsed from file path, url, etc.\n\nmd5: file md5 code, only for checking purposes and will not be computed from file.\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, options?: {headers?: HTTP.OutgoingHttpHeaders, name?: string, size?: string, md5?: string}): FileBox` \n\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {name: 'logo.jpg'},\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name?: string, md5?: string): FileBox`\n\nWill be named 'stream.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name?: string, md5?: string): FileBox`\n\nWill be named 'buffer.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name?: string, md5?: string): FileBox`\n\nDecoded a base64 encoded file data. Will be named 'base64.dat' if no name is provided.\n\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name?: string, md5?: string): FileBox`\n\nDecoded a DataURL data. Will be named 'data-url.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string, md5?: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string, options?: {name?: string, size?: string, md5?: string})`\n\nLoad a FileBox from a UUID. Will be named `${uuid}.dat` if no name is provided.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `toStream(): Readable`\n\nGet the stream of file data.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst readableStream = fileBox.toStream()\n```\n\n#### 2.3 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.4 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.5 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.6 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.7 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.8 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.9 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.10 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `md5`\n\nFile md5 of the file in the box. The value is set by user, not computed from file.\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {md5: 'computed-md5-string'}\n)\nconsole.log(fileBox.md5) // Output: computed-md5-string\n```\n\n#### 3.3 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.4 `version(): string`\n\nVersion of the FileBox\n\n#### 3.5 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.6 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.7 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.8 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.9 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.10 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.11 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.12 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.5 (Jan 18, 2022)\n\n1. `fileBox.md5` can be set by user. This filed is for the receiver of the filebox to check, and it is not computed from the file.\n\n### main v1.4 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"5d1bfb3a56fb692efc90802de1d52076aa239e12","_id":"file-box@1.5.3","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-Zs/sjnNcWMKiwomSaoZDYc73iNu6aTzNubqnxxN1TuCToH0/Y1lKPIM4VVqrDu5J4EZ1VixTZzUdP9Wk6LpzWw==","shasum":"545319e5c59185d05f44999b38db631449aa5423","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.5.3.tgz","fileCount":202,"unpackedSize":423240,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIGzzflRq4lEB7DYVodcByy64rWy3IqMd8nKqnUGwOBNFAiEAvegfuYfe05qLpG+BbGM+XiLRr2c0ChgHg6N0j1E6GtY="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJif62hACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmrXpw/9Ei4yVAOVHzgBDYpx/nRxyXfjVmVdFNcPqf+dENA9sYLMXq4Z\r\nCnSWXyUD8NV75CFenCyXzxCsn2xjx850gZ5RIFvi5kGQIPir6ydhgsYhkq0f\r\n7FKlIS3w3dEgWAhF//dLI5bhX1JfN5Au/ho/RSrSBUP2uPTNEaOYjFIXIBS0\r\nV9TuSHVbPfsulPeA/VcxCKtHO06gzpkO+L5ectdfdsZcwtfUI6ipPCQsU4MO\r\nGeFPkrmGyUpf0049NPRLbXbAYMtCehC2xUTa0pnE0IhZfQUPn7BCSVx5/SlW\r\nh7e0qemopv624LkwtdST4rA3FwSjXccZcObUvqm/A80Sx05yHYPeQl+WYa9h\r\nuPb3maC8Kn2Elrfmi9QnqPLQc3i+6/BPQYt3bY0yTzcQJ/gLftpQ+T6fJS9w\r\nbSC5jEqbHyhAFN9mlUEkuLbpSiQY2+HW4EC+f4Bmey2liXbzzJ1lTLum8/Tv\r\n9l09rbPLKZNwOTwAKoCuY2EAcfgGoAgFdfFyDuHOn4188rcdiFm5bIIZfr2l\r\naKD+7qJc70Z695yq5eGp74JUxdWPsVNDGjqRi8kza97s3hvEmp+nEXddAy/Y\r\nucbegP3HhGsiwcYintj31LwmmUpwdztnmXBt9FB8i5juaTxIHjO5Kuuq74la\r\nmTm0N3f8EpB8jug2Blycyi6GHhwe9+vfwm8=\r\n=cw58\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.5.3_1652534689546_0.9428764497429776"},"_hasShrinkwrap":false},"1.5.4":{"name":"file-box","version":"1.5.4","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Load local file\n1. Save URL to local file\n1. Convert buffer to stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 0. Load local file\n */\nconst fileBox0 = FileBox.fromFile('/tmp/file.jpg')\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n[API docs on Paka](https://paka.dev/npm/file-box)\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string, name?: string, md5?: string): FileBox`\n\nAlias: `fromLocal()`\n\nAbout optional arguments:\n\nname: filename, if not passed, will be parsed from file path, url, etc.\n\nmd5: file md5 code, only for checking purposes and will not be computed from file.\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, options?: {headers?: HTTP.OutgoingHttpHeaders, name?: string, size?: string, md5?: string}): FileBox` \n\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {name: 'logo.jpg'},\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name?: string, md5?: string): FileBox`\n\nWill be named 'stream.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name?: string, md5?: string): FileBox`\n\nWill be named 'buffer.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name?: string, md5?: string): FileBox`\n\nDecoded a base64 encoded file data. Will be named 'base64.dat' if no name is provided.\n\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name?: string, md5?: string): FileBox`\n\nDecoded a DataURL data. Will be named 'data-url.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string, md5?: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string, options?: {name?: string, size?: string, md5?: string})`\n\nLoad a FileBox from a UUID. Will be named `${uuid}.dat` if no name is provided.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `toStream(): Readable`\n\nGet the stream of file data.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst readableStream = fileBox.toStream()\n```\n\n#### 2.3 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.4 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.5 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.6 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.7 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.8 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.9 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.10 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `md5`\n\nFile md5 of the file in the box. The value is set by user, not computed from file.\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {md5: 'computed-md5-string'}\n)\nconsole.log(fileBox.md5) // Output: computed-md5-string\n```\n\n#### 3.3 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.4 `version(): string`\n\nVersion of the FileBox\n\n#### 3.5 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.6 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.7 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.8 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.9 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.10 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.11 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.12 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.5 (Jan 18, 2022)\n\n1. `fileBox.md5` can be set by user. This filed is for the receiver of the filebox to check, and it is not computed from the file.\n\n### main v1.4 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"a7e2e927840709eba088ccb8777c9914047be587","_id":"file-box@1.5.4","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-buNghU+GfW7r1hi/We/XrLnSEELzVp/p6pzJzXowTWc4p6hVecWBkhLHCE9IeKo98996/i7L/YVYoC1Td/IzZA==","shasum":"599be46713c545d287e5902b43c065b5aab392f9","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.5.4.tgz","fileCount":202,"unpackedSize":423214,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEQCID9/asiKHis++qOLPf3ZuJSmu8StUl+NXouOHJl1fEwFAiBGTOE6LfeqzIPvNcf1LiTNfzks88yQUQUjm+Da9lGx+A=="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJif7RvACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmqIYQ//advvZcvl7g4BonN2ls31wPZOM5LrIA+/CwFcBBcEAVnwxFP3\r\nvoCUkl+OZgx+7OlK8S0nGFAkhNtEjwBlRdAgidd7V9Pke6q/kYcju44CND7F\r\n/QWVq3IHJjxuWvJ1DZu8X7ZFGXuS4mkPR6KuGqFw+gbqx496RA5FBnV+Rx5w\r\ndo4FZE0icWu+9ca8CIccnoa7SD3Xkp9vOfoJ1fKPUlh/eWMTfdM49Hli+9GQ\r\niwm+NISgz8kZHC2J4eL/B+JfjapfJIXX/HUn09vid/i9cNHYPFOZ3rC23qz7\r\nn04O3oxzO/rwx9MLwxEoKx9F8f/eGeCCxHUUcWZQYcgFAbF0+GnNHw1Zwj2X\r\ngBEd5jnmTor/dTMQMlqVw7GHPVsjqkmbl2AVdl+2kop9ZPlkbTqssr+up0QH\r\nH2OAcEzZO9SutQnw1+tA1TD6uYGc8jrYOe17aWIpDMSgz6HHSvtUiDl4ylV+\r\nhWm6HCR+YtPu0eZ+PwP3kferuGINsaNrmkCPBNlvTpXdkEThICpgbCS8o2AA\r\neiC8GjWf3kB1fnDvzxA96vh68DQkpRqsDb/fBXlM8E9tiMwdTrabhdn2SBYL\r\nUMHlZVhc25p88EYG4/lhuYj9J3wcyVeIAnmPHL3Twiy3e2buL6V63APM+C5Y\r\n/MsIsR7RW8VLWURrswZCjpozmxp1LUh7de0=\r\n=P6Us\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.5.4_1652536431758_0.013429816977494902"},"_hasShrinkwrap":false},"1.5.5":{"name":"file-box","version":"1.5.5","description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","type":"module","exports":{".":{"import":"./dist/esm/src/mod.js","require":"./dist/cjs/src/mod.js"}},"typings":"./dist/esm/src/mod.d.ts","engines":{"node":">=16","npm":">=7"},"scripts":{"clean":"shx rm -fr dist/*","dist":"npm-run-all clean build dist:commonjs","build":"tsc && tsc -p tsconfig.cjs.json","dist:commonjs":"jq -n \"{ type: \\\"commonjs\\\" }\" > dist/cjs/package.json","lint":"npm-run-all lint:es lint:ts","lint:ts":"tsc --isolatedModules --noEmit","test":"npm-run-all lint test:unit","test:unit":"cross-env NODE_OPTIONS=\"--no-warnings --loader=ts-node/esm\" tap \"src/**/*.spec.ts\" \"tests/*.spec.ts\"","test:pack":"bash -x scripts/npm-pack-testing.sh","lint:es":"eslint --ignore-pattern fixtures/ \"src/**/*.ts\" \"tests/**/*.ts\""},"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"keywords":["file","virtual","cloud","url","stream","http","api"],"author":{"name":"Huan LI","email":"zixia@zixia.net"},"license":"Apache-2.0","bugs":{"url":"https://github.com/huan/file-box/issues"},"homepage":"https://github.com/huan/file-box#readme","devDependencies":{"@chatie/eslint-config":"^1.0.4","@chatie/git-scripts":"^0.6.2","@chatie/semver":"^0.4.7","@chatie/tsconfig":"^4.6.2","@types/isomorphic-fetch":"0.0.35","@types/mime":"^2.0.3","@types/qrcode":"^1.4.1","@types/uuid":"^8.3.3","gts":"^3.1.0","pkg-jq":"^0.2.11","read-pkg-up":"^8.0.0","reflect-metadata":"^0.1.13"},"dependencies":{"brolog":"^1.14.2","clone-class":"^1.0.3","jimp":"^0.16.1","jsqr":"^1.4.0","mime":"^3.0.0","qrcode":"^1.5.0","uuid":"^8.3.2"},"publishConfig":{"access":"public","tag":"next"},"git":{"scripts":{"pre-push":"npx git-scripts-pre-push"}},"readme":"# file-box\n\n[![NPM Version](https://badge.fury.io/js/file-box.svg)](https://badge.fury.io/js/file-box)\n[![NPM](https://github.com/huan/file-box/workflows/NPM/badge.svg)](https://github.com/huan/file-box/actions?query=workflow%3ANPM)\n[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-blue.svg)](https://www.typescriptlang.org/)\n[![ES Modules](https://img.shields.io/badge/ES-Modules-brightgreen)](https://github.com/Chatie/tsconfig/issues/16)\n\nFileBox is a virtual container for packing a file data into it for future read, and easily transport between servers with the least payload, no mater than where it is (local path, remote url, or cloud storage).\n\n![File Box](https://huan.github.io/file-box/images/file-box-logo.jpg)\n\nCurrently the FileBox supports almost all kinds of the data input/output methods/formats:\n\n| File Type | Pack Method | Unpack Method | Description |\n| :--- | :--- | :--- | :--- |\n| Local File | `fromFile()` | `toFile()` | Local file in file system |\n| Remote URL | `fromUrl()` | `toUrl()`(TBW) | Remote file in a HTTP/HTTPS URL |\n| Buffer | `fromBuffer()` | `toBuffer()` | JavaScript Buffer |\n| Stream | `fromStream()` | `toStream()` | JavaScript Stream |\n| Base64 | `fromBase64()` | `toBase64()` | Base64 data |\n| DataURL | `fromDataURL()` | `toDataURL()` | DataURL data |\n| QRCode | `fromQRCode()` | `toQRCode()` | QR Code Image Decode/Encode |\n| UUID | `fromUuid()` | `toUuid()` | UUID by loader/saver helper functions |\n| JSON | `fromJSON()` | `toJSON()` | Serialize/Deserialize FileBox |\n\n## Examples\n\nThe following example demos:\n\n1. Load local file\n1. Save URL to local file\n1. Convert buffer to stream\n1. Pack from Base64 then Unpack to DataURL\n\n```ts\nimport { FileBox } from 'file-box'\n\n/**\n * 0. Load local file\n */\nconst fileBox0 = FileBox.fromFile('/tmp/file.jpg')\n\n/**\n * 1. Save URL to File\n */\nconst fileBox1 = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  'logo.jpg',\n)\nfileBox1.toFile('/tmp/file-box-logo.jpg')\n\n/**\n * 2. Convert Buffer to Stream\n */\nimport fs from 'fs'\nconst fileBox2 = FileBox.fromBuffer(\n  Buffer.from('world'),\n  'hello.txt',\n)\nconst writeStream = fs.createWriteStream('/tmp/hello.txt')\nfileBox2.pipe(writeStream)\n\n/**\n * 3. Pack Base64, Unpack to DataURL\n */\nconst fileBox3 = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox3.toDataURL()\n        .then(console.log)\n// Output: data:text/plain;base64,d29ybGQK\n```\n\n## Known Issues\n\n1. TypeError [ERR_UNESCAPED_CHARACTERS]: Request path contains unescaped characters [#56](https://github.com/huan/file-box/issues/56)\n\n## API Reference\n\n[API docs on Paka](https://paka.dev/npm/file-box)\n\n### 1. Load File in to Box\n\n#### 1.1 `fromFile(filePath: string, name?: string, md5?: string): FileBox`\n\nAlias: `fromLocal()`\n\nAbout optional arguments:\n\nname: filename, if not passed, will be parsed from file path, url, etc.\n\nmd5: file md5 code, only for checking purposes and will not be computed from file.\n\n```ts\nconst fileBox = FileBox.fromLocal('/tmp/test.txt')\n```\n\n#### 1.2 `fromUrl(url: string, options?: {headers?: HTTP.OutgoingHttpHeaders, name?: string, size?: string, md5?: string}): FileBox` \n\n\nAlias: `fromRemote()`\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {name: 'logo.jpg'},\n)\n```\n\n#### 1.3 `fromStream(stream: Readable, name?: string, md5?: string): FileBox`\n\nWill be named 'stream.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromStream(res, '/tmp/download.zip')\n```\n\n#### 1.4 `fromBuffer(buffer: Buffer, name?: string, md5?: string): FileBox`\n\nWill be named 'buffer.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromBuffer(buf, '/tmp/download.zip')\n```\n\n#### 1.5 `FileBox.fromBase64(base64: string, name?: string, md5?: string): FileBox`\n\nDecoded a base64 encoded file data. Will be named 'base64.dat' if no name is provided.\n\n\n```ts\nconst fileBox = FileBox.fromBase64('d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.6 `FileBox.fromDataURL(dataUrl: string, name?: string, md5?: string): FileBox`\n\nDecoded a DataURL data. Will be named 'data-url.dat' if no name is provided.\n\n```ts\nconst fileBox = FileBox.fromDataURL('data:text/plain;base64,d29ybGQK', 'hello.txt')\nfileBox.toFile()\n```\n\n#### 1.7 `FileBox.fromJSON()`\n\nRestore a `FileBox.toJSON()` text string back to a FileBox instance.\n\n```ts\nconst restoredFileBox = FileBox.fromJSON(jsonText)\n```\n\n#### 1.8 `FileBox.fromQRCode(qrCodeValue: string, md5?: string)`\n\nGet a FileBox instance that represent a QR Code value.\n\n```ts\nconst fileBox = FileBox.fromQRCode('https://github.com')\nfileBox.toFile('qrcode.png')\n```\n\n#### 1.9 `FileBox.fromUuid(uuid: string, options?: {name?: string, size?: string, md5?: string})`\n\nLoad a FileBox from a UUID. Will be named `${uuid}.dat` if no name is provided.\n\nSee: `FileBox.setUuidLoader()`\n\n### 2. Get File out from Box\n\n### 2.1 `toFile(name?: string): Promise<void>`\n\nSave file to current work path(cwd) of the local file system with the default `name`.\n\nif `name` specified with a full path, then will use the speficied file name instead.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nawait fileBox.toFile('/tmp/logo.jpg')\n```\n\n#### 2.2 `toStream(): Readable`\n\nGet the stream of file data.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst readableStream = fileBox.toStream()\n```\n\n#### 2.3 `pipe(destination: Writable): Promise<void>`\n\nPipe to a writable stream.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst writableStream = fs.createWritable('/tmp/logo.jpg')\nfileBox.pipe(writableStream)\n```\n\n#### 2.4 `toBase64(): Promise<string>`\n\nGet the base64 data of file.\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst base64Text = await fileBox.toBase64()\nconsole.log(base64Text) // Output: the base64 encoded data of the file\n```\n\n#### 2.5 `toJSON(): string`\n\nGet the `JSON.stringify`-ed text.\n\n**Not Implement Yet: Working In Progress...**\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconst jsonText1 = fileBox.toJSON()\nconst jsonText2 = JSON.stringify(fileBox)\nassert(jsonText1 === jsonText2)\n\nconsole.log(jsonText1) // Output: the stringified data of the fileBox\n\nconst restoredFileBox = fileBox.fromJSON(jsonText1)\nrestoredFileBox.toFile('/tmp/file-box-logo.jpg')\n```\n\n#### 2.6 `toDataURL(): Promise<string>`\n\nGet the DataURL of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst dataUrl = await fileBox.toDataURL()\nconsole.log(dataUrl) // Output: data:text/plain;base64,d29ybGQK'\n```\n\n#### 2.7 `toBuffer(): Promise<Buffer>`\n\nGet the Buffer of the file.\n\n```ts\nconst fileBox = FileBox.fromFile('tests/fixtures/hello.txt')\nconst buffer = await fileBox.toBuffer()\nconsole.log(buffer.toString()) // Output: world\n```\n\n#### 2.8 `toQRCode(): Promise<string>`\n\nDecode the QR Code value from the file.\n\n```ts\nconst fileBox = FileBox.fromFile('qrcode.jpg')\nconst qrCodeValue = await fileBox.toQRCode()\nconsole.log(`QR Code decoded value is: \"${qrCodeValue}\"`)\n// Output: QR Code decoded value is: \"https://github.com\"\n```\n\n#### 2.9 `toUuid(): Promise<string>`\n\nSave the FileBox to a UUID file and return the UUID.\n\nSee: `FileBox.setUuidSaver()`\n\n#### 2.10 `toJSON(): string`\n\nEncode a FileBox instance to JSON string so that we can transfer the FileBox on the wire.\n\n```ts\nconst fileBox = FileBox.fromBase64('RmlsZUJveEJhc2U2NAo=')\n\nconst jsonText = JSON.stringify(fileBox)\n// the above code equals to the following line of code:\n// const jsonText = fileBox.toJSON()\n\n// we will get the serialized data for this FileBox:\nconsole.log(jsonText)\n// Output: {\"name\":\"qrcode.png\",\"metadata\":{},\"boxType\":1,\"base64\":\"RmlsZUJveEJhc2U2NAo=\"}\n\n// restore our fleBox:\n// const newFileBox = FileBox.fromJSON(jsonText)\n```\n\n##### Limitation\n\nBecause we want to enable the `JSON.stringify(fileBox)`, which will call `fileBox.toJSON()`, so the `toJSON()` can not be `async`, which means we can only support limited FileBoxType(s):\n\n1. FileBoxType.Base64\n1. FileBoxType.Url\n1. FileBoxType.QRCode\n\nFor other types like `FileBoxType.File`, `FileBoxType.Buffer`, `FileBoxType.Stream`, etc, we need to transform them to `FileBoxType.Base64` before we call `toJSON`:\n\n```ts\nconst fileBoxLazy = FileBox.fromFile('./test.txt')\nconst base64 = await fileBoxLazy.toBase64()\n\nconst fileBox = FileBox.fromBase64(base64, 'test.txt')\n// fileBox will be serializable because it do not need async operations\n\nconst jsonText = JSON.stringify(fileBox)\nconsole.log(jsonText)\n```\n\n### 3. Misc\n\n#### 3.1 `name`\n\nFile name of the file in the box\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nconsole.log(fileBox.name) // Output: file-box-logo.jpg\n```\n\n#### 3.2 `md5`\n\nFile md5 of the file in the box. The value is set by user, not computed from file.\n\n```ts\nconst fileBox = FileBox.fromUrl(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n  {md5: 'computed-md5-string'}\n)\nconsole.log(fileBox.md5) // Output: computed-md5-string\n```\n\n#### 3.3 `metadata: Metadata { [key: string]: any }`\n\nMetadata for the file in the box. This value can only be assigned once, and will be immutable afterwards, all following assign or modify actions on `metadata` will throw errors\n\n```ts\nconst fileBox = FileBox.fromRemote(\n  'https://huan.github.io/file-box/images/file-box-logo.jpg',\n)\nfileBox.metadata = {\n  author      : 'huan',\n  githubRepo  : 'https://github.com/huan/file-box',\n}\n\nconsole.log(fileBox.metadata)       // Output: { author: 'huan', githubRepo: 'https://github.com/huan/file-box' }\nfileBox.metadata.author = 'Tank'  // Will throw exception\n```\n\n#### 3.4 `version(): string`\n\nVersion of the FileBox\n\n#### 3.5 `toJSON(): string`\n\nSerialize FileBox metadata to JSON.\n\n#### 3.6 `ready(): Promise<void>`\n\nUpdate the necessary internal data and make everything ready for use.\n\n#### 3.7 `syncRemoteName(): Promise<void>`\n\nSync the filename with the HTTP Response Header\n\nHTTP Header Example:\n> Content-Disposition: attachment; filename=\"filename.ext\"\n\n#### 3.8 `type: FileBoxType`\n\nReturn the type of the current FileBox instance.\n\nThe currently supported types are defined at [file-box-type.ts](https://github.com/huan/file-box/blob/master/src/file-box.type.ts#L15) as the following demonstrated:\n\n```ts\nenum FileBoxType {\n  Unknown = 0,\n  Base64  = 1,\n  Url     = 2,\n  QRCode  = 3,\n  Buffer  = 4,\n  File    = 5,\n  Stream  = 6,\n  Uuid    = 7,\n}\n```\n\n#### 3.9 `FileBox.setUuidLoader(loader: UuidLoader): void`\n\nRequired by static method `FileBox.fromUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst loader: UuidLoader = async (uuid: string) => {\n  const stream = new PassThrough()\n  stream.end('hello, world!')\n  return stream\n})\n\nFileBoxUuid.setUuidLoader(loader)\nconst fileBox = FileBoxUuid.fromUuid('12345678-1234-1234-1234-123456789012', 'test.txt')\nawait fileBox.toFile('test.txt')\n```\n\nThe `UuidLoader` is a function that takes a UUID and return a readable stream.\n\n```ts\ntype UuidLoader = (this: FileBox, uuid: string) => Readable\n```\n\n#### 3.10 `FileBox.setUuidSaver(saver: UuidSaver): void`\n\nRequired by instance method `fileBox.toUuid()`\n\n```ts\nclass FileBoxUuid extends FileBox {}\n\nconst saver: UuidSaver = async (stream: Readable) => {\n  // save the stream and get uuid\n  return '12345678-1234-1234-1234-123456789012'\n})\n\nFileBoxUuid.setUuidSaver(saver)\n\nconst fileBox = FileBoxUuid.fromFile('test.txt')\nconst uuid = await fileBox.toUuid()\n```\n\nThe `UuidSaver` is a function that takes a readable stream and return a UUID promise.\n\n```ts\ntype UuidSaver = (this: FileBox, stream: Readable) => Promise<string>\n```\n\n#### 3.11 `size`\n\nThe file box size in bytes. (`-1` means unknown)\n\nIt is not the size of the target (boxed) file itself.\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nconsole.log(fileBox.size)\n// > 20 <- this is the length of the URL string\n```\n\n#### 3.12 `remoteSize`\n\nThe remote file size in bytes. (`-1` or `undefined` means unknown)\n\nFor example:\n\n```ts\nconst fileBox = FileBox.fromUrl('http://example.com/image.png')\nawait fileBox.ready()\nconsole.log(fileBox.remoteSize)\n// > 102400 <- this is the size of the remote image.png\n```\n\n## Features\n\n1. Present A File by Abstracting It's Meta Information that supports Reading & toJSON() API.\n1. Follow DOM File/BLOB Interface\n1. Present a file that could be: Local, Remote, Stream\n1. Lazy load\n1. Serializable\n1. Can be Transfered from server to server, server to browser.\n\n## SCHEMAS\n\n### Url\n\n[Node.js Documentation > URL Strings and URL Objects](https://nodejs.org/docs/latest/api/url.html#url_url_strings_and_url_objects)\n\n```asciiart\n┌─────────────────────────────────────────────────────────────────────────────────────────────┐\n│                                            href                                             │\n├──────────┬──┬─────────────────────┬─────────────────────┬───────────────────────────┬───────┤\n│ protocol │  │        auth         │        host         │           path            │ hash  │\n│          │  │                     ├──────────────┬──────┼──────────┬────────────────┤       │\n│          │  │                     │   hostname   │ port │ pathname │     search     │       │\n│          │  │                     │              │      │          ├─┬──────────────┤       │\n│          │  │                     │              │      │          │ │    query     │       │\n\"  https:   //    user   :   pass   @ sub.host.com : 8080   /p/a/t/h  ?  query=string   #hash \"\n│          │  │          │          │   hostname   │ port │          │                │       │\n│          │  │          │          ├──────────────┴──────┤          │                │       │\n│ protocol │  │ username │ password │        host         │          │                │       │\n├──────────┴──┼──────────┴──────────┼─────────────────────┤          │                │       │\n│   origin    │                     │       origin        │ pathname │     search     │ hash  │\n├─────────────┴─────────────────────┴─────────────────────┴──────────┴────────────────┴───────┤\n│                                            href                                             │\n└─────────────────────────────────────────────────────────────────────────────────────────────┘\n```\n\n### Path\n\n[Node.js Documentation > path.parse(path)](https://nodejs.org/api/path.html#path_path_parse_path)\n\n```asciiart\n┌─────────────────────┬────────────┐\n│          dir        │    base    │\n├──────┬              ├──────┬─────┤\n│ root │              │ name │ ext │\n\"  /    home/user/dir / file  .txt \"\n└──────┴──────────────┴──────┴─────┘\n```\n\n## History\n\n### main v1.5 (Jan 18, 2022)\n\n1. `fileBox.md5` can be set by user. This filed is for the receiver of the filebox to check, and it is not computed from the file.\n\n### main v1.4 (Nov 14, 2021)\n\n1. `fileBox.size` will be serialized to/from JSON, and present the `Content-Length` of the file. (`-1` means unknown)\n1. `mimeType` has been renamed to `mediaType`, and added to the `FileBoxInterface`\n\n### v1.0 (Oct 20, 2021)\n\n1. Suppert ES Module. ([#54](https://github.com/huan/file-box/issues/54))\n1. Add UUID boxType support: `FileBox.fromUuid()` and `FileBox.toUuid()`\n1. Add `size` property to return the size of the file. (`-1` means unknown)\n1. Add `remoteSize` property to present the remote size of the file (if applicable, `-1` means unknown)\n1. Add `UniformResourceNameRegistry` class for providing a production-ready basic UUID management tool.\n1. Add `FileBoxInterface`, `FileBox.isInstance()`, and `FileBox.isInterface()`\n\nBreaking changes:\n\n1. `toJSON` format renamed `boxType` to `type`\n1. `type()` has been changed to `type`\n1. `version()` has been changed to `version`\n\n### v0.16 master\n\n1. Throw error when consume a stream twice to prevent data lost. ([#50](https://github.com/huan/file-box/issues/50))\n\n### v0.14 (Oct 2020)\n\n1. Add `fileBox.type()` to return the `FileBoxType` of a FileBox. ([wechaty/wechaty#1918](https://github.com/wechaty/wechaty/issues/1918#issuecomment-590146993))\n1. Change `Readable` to `stream.Readable` for better compatibility. (Jun 27, 2020)\n1. Add `chunkerTransformStream` to `toStream` ([#44](https://github.com/huan/file-box/issues/44))\n\n### v0.12 (Feb 2020)\n\nAdd support to `JSON.stringify()` ([#25](https://github.com/huan/file-box/issues/25)):\n\n1. `FileBox.fromJSON()` - Static method for deserialization\n1. `fileBox.toJSON()` - Instance method for serialization\n\n### v0.10 (Jan 2020)\n\n1. Add support to QR Code: `FileBox.fromQRCode()` and `FileBox.toQRCode()`\n1. Start using @chatie/tsconfig\n\n### v0.8 (Jun 2018)\n\n1. Add two new factory methods: `fromBase64()`, `fromDataURL()`\n1. Add `toBuffer()`, `toBase64()` and `toDataURL()` to get the Buffer and BASE64 encoded file data\n1. Add `metadata` property to store additional information. ([#3](https://github.com/huan/file-box/issues/3))\n\n### v0.4 (May 2018)\n\n1. Add `headers` option for `fromRemote()` method\n\n### v0.2 (Apr 2018)\n\nInitial version.\n\n## See Also\n\n* [File API - W3C Working Draft, 26 October 2017](https://www.w3.org/TR/FileAPI/)\n* [MIME Sniffing - Living Standard — Last Updated 20 April 2018](https://mimesniff.spec.whatwg.org/#parsable-mime-type)\n* [Using files from web applications](https://developer.mozilla.org/en-US/docs/Web/API/File/Using_files_from_web_applications)\n* [Web technology for developers > Web APIs > File](https://developer.mozilla.org/en-US/docs/Web/API/File)\n* [Web technology for developers > Web APIs > Blob](https://developer.mozilla.org/en-US/docs/Web/API/Blob)\n* [Web technology for developers > Web APIs > FileReader](https://developer.mozilla.org/en-US/docs/Web/API/FileReader)\n* [A simple HTTP Request & Response Service.](https://httpbin.org)\n* [Hurl.it — Make HTTP Requests](https://www.hurl.it)\n\n## Thanks\n\nThis module is inspired by <https://github.com/gulpjs/vinyl> and <https://github.com/DefinitelyTyped/DefinitelyTyped/pull/12368> when I need a virtual File module for my [Chatie](https://github.com/Chatie) project.\n\n## Author\n\n[Huan LI](https://github.com/huan) ([李卓桓](http://linkedin.com/in/zixia)), Microsoft AI MVP, zixia@zixia.net\n\n[![Profile of Huan LI (李卓桓) on StackOverflow](https://stackexchange.com/users/flair/265499.png)](https://stackexchange.com/users/265499)\n\n## Copyright & License\n\n* Docs released under Creative Commons\n* Code released under the Apache-2.0 License\n* Code & Docs © 2018 Huan LI \\<zixia@zixia.net\\>\n","readmeFilename":"README.md","gitHead":"fcae3be890801283ec2790fd57f91d643391517a","_id":"file-box@1.5.5","_nodeVersion":"16.15.0","_npmVersion":"8.5.5","dist":{"integrity":"sha512-NnR7X2KwTL0l/FFDnConXfVdR+qw9riLYwLW4xqihfTna1XBgB1Ac2wmu9T/gNVmsLZbmyZbSOOl+b5ahvAHQg==","shasum":"f9818405beeded7b569151ff575179cf491bf404","tarball":"https://registry.npmjs.org/file-box/-/file-box-1.5.5.tgz","fileCount":202,"unpackedSize":425923,"signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQCqlhu6iCp0Z88BS/I0KfAKgjUmAt64zIGG/Ob6EOqjLgIgVej9Lot04NVjz8AZ7i9GPTOGzTAyWIsvdQ1WKoND+NA="}],"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v4.10.10\r\nComment: https://openpgpjs.org\r\n\r\nwsFzBAEBCAAGBQJif8AfACEJED1NWxICdlZqFiEECWMYAoorWMhJKdjhPU1b\r\nEgJ2VmoZ8Q//UtbqIo/6ghKP9cFHImiK2+oK5IYCsegf7r6xMFUTtqKMbzjt\r\nWIj41uZqFAK1o2dGgCJ1aaLPh1PD41CCRkmlF7TiCpt+bJz50aO1tv7j5Fex\r\n1JVtLm8b4DoksbXq7ESF7AtLQFaH1bNcm4ZZBi3FZcMlQtlHx60RMqfKZNR2\r\nnpyBxK7wNxKtK1voWCrMrjZnQcAX31pVhzLwRAF/WDvO3crKdO8Jg1Ibpj1W\r\namiMcANdOZSiPLUlxVUnzeHnJ8Flsjbr7QcZlBpH3bUda9K52MN8uHXWZk+3\r\nOWsUT+fCAwTeABtFoQjgZIK616/lm+ErlU1ovpE8vUwUYL1lNqMhXQL/jXzk\r\nSu/0vB1DKDY0oTYLQSMrcswT6Wy8DQyYr7uz5EiWSBREn9A2PpPItlcQBaae\r\ntxzhXUsh1OVHQiShCewFKNQzYOVTnCAwp8URhBfSEZWh8QcjTvvijbeWefCs\r\n8pbA8yYubuVXhLoYwV/MddeZCbvdh4hbwYUwgNtEpaBMAv/O1Sf+5JMr/J1x\r\n/QhI2tl/9LpwOXQfPUAjDyVoICVdWJmz33kI0sedDyEU+psJG7tt8+daMmck\r\nNMCYj8Vtio2Lne8mCnY7/4esspVNuAi8TLsngULBwIXtIWXSAgfFs0UwLWwb\r\nw3YwS+/HT6FT3f5MERfAgmfOBTHte6zyTTw=\r\n=eglS\r\n-----END PGP SIGNATURE-----\r\n"},"_npmUser":{"name":"zixia","email":"zixia@zixia.net"},"directories":{},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/file-box_1.5.5_1652539423139_0.28558693681522507"},"_hasShrinkwrap":false}},"time":{"created":"2018-05-13T02:49:56.948Z","0.0.1":"2018-05-13T02:49:57.095Z","modified":"2022-05-14T14:43:43.551Z","0.1.2":"2018-05-15T05:48:44.205Z","0.2.1":"2018-05-15T05:55:17.888Z","0.2.2":"2018-05-16T03:59:45.704Z","0.2.3":"2018-05-17T06:43:24.615Z","0.3.1":"2018-05-26T02:50:31.834Z","0.3.2":"2018-05-26T04:02:15.799Z","0.3.3":"2018-05-26T04:05:06.786Z","0.3.4":"2018-05-26T04:07:51.618Z","0.4.1":"2018-05-26T04:37:58.781Z","0.6.2":"2018-05-26T16:21:25.254Z","0.6.3":"2018-05-27T12:29:53.269Z","0.6.4":"2018-05-28T19:59:25.277Z","0.6.5":"2018-05-29T08:23:57.658Z","0.6.6":"2018-05-29T08:29:11.203Z","0.6.7":"2018-05-29T11:47:50.683Z","0.6.8":"2018-05-29T11:48:21.476Z","0.6.9":"2018-05-29T11:50:09.058Z","0.6.10":"2018-05-29T17:51:59.780Z","0.6.11":"2018-05-29T18:29:55.162Z","0.6.12":"2018-05-29T18:31:07.782Z","0.6.13":"2018-05-29T18:31:53.593Z","0.8.1":"2018-05-30T05:41:11.874Z","0.8.3":"2018-05-31T05:18:38.840Z","0.8.4":"2018-05-31T05:25:23.792Z","0.8.5":"2018-05-31T05:55:27.071Z","0.8.6":"2018-05-31T05:57:41.076Z","0.8.7":"2018-05-31T06:16:29.469Z","0.8.8":"2018-05-31T06:17:42.731Z","0.8.9":"2018-05-31T06:19:38.846Z","0.8.10":"2018-05-31T06:23:19.154Z","0.8.11":"2018-05-31T06:54:35.662Z","0.8.12":"2018-05-31T06:56:35.738Z","0.8.13":"2018-05-31T08:18:45.651Z","0.8.14":"2018-06-01T08:40:50.670Z","0.8.19":"2018-06-04T03:50:03.478Z","0.8.20":"2018-06-13T20:35:33.582Z","0.8.21":"2018-06-14T14:52:39.824Z","0.8.22":"2018-06-17T17:25:31.966Z","0.8.23":"2018-07-30T16:22:49.520Z","0.8.24":"2018-07-31T02:38:14.017Z","0.8.26":"2018-11-27T15:41:03.740Z","0.8.27":"2018-12-19T16:25:13.876Z","0.9.3":"2019-06-04T00:01:52.076Z","0.9.5":"2019-06-22T13:13:24.136Z","0.9.7":"2019-06-22T13:26:48.331Z","0.10.6":"2020-02-05T07:30:30.732Z","0.11.7":"2020-02-12T01:54:24.603Z","0.12.1":"2020-02-12T02:16:18.494Z","0.12.2":"2020-02-21T16:01:21.941Z","0.12.3":"2020-02-21T16:23:52.299Z","0.12.4":"2020-02-23T13:59:28.263Z","0.12.7":"2020-03-10T19:29:55.313Z","0.12.8":"2020-05-02T18:01:27.847Z","0.13.1":"2020-06-27T11:53:16.722Z","0.13.2":"2020-06-27T11:57:43.278Z","0.13.3":"2020-06-27T12:03:24.701Z","0.13.4":"2020-06-27T12:06:36.062Z","0.13.5":"2020-06-27T12:25:30.574Z","0.13.9":"2020-10-07T06:45:41.686Z","0.14.2":"2020-10-27T13:55:41.587Z","0.14.3":"2020-10-27T13:57:31.854Z","0.15.0":"2020-11-05T10:12:05.172Z","0.15.1":"2020-11-14T17:29:10.979Z","0.16.1":"2020-11-19T12:53:54.684Z","0.16.2":"2020-11-19T13:53:57.881Z","0.16.3":"2020-12-04T15:15:19.744Z","0.16.4":"2020-12-04T15:16:36.516Z","0.16.6":"2021-02-12T07:07:50.367Z","0.16.7":"2021-02-12T07:10:46.070Z","0.16.8":"2021-02-18T02:53:35.795Z","0.17.6":"2021-08-25T18:35:55.263Z","0.17.7":"2021-08-25T18:37:27.364Z","0.17.8":"2021-08-26T03:01:50.638Z","0.17.9":"2021-08-26T05:07:50.634Z","0.17.10":"2021-09-03T04:49:25.359Z","0.17.11":"2021-09-05T16:04:14.141Z","0.17.12":"2021-09-13T19:13:09.499Z","0.19.3":"2021-10-05T04:32:07.781Z","0.19.4":"2021-10-05T05:35:16.084Z","0.19.5":"2021-10-05T13:52:23.475Z","0.21.2":"2021-10-05T18:40:55.823Z","0.21.3":"2021-10-06T04:10:15.012Z","0.21.4":"2021-10-06T14:32:21.029Z","0.23.2":"2021-10-08T09:47:29.858Z","0.23.3":"2021-10-08T11:08:10.673Z","0.23.4":"2021-10-08T11:44:29.755Z","0.23.5":"2021-10-08T15:04:28.537Z","0.23.6":"2021-10-08T17:20:22.193Z","0.23.7":"2021-10-10T06:50:25.568Z","0.23.8":"2021-10-11T06:02:08.351Z","0.23.12":"2021-10-11T09:08:45.015Z","1.0.2":"2021-10-20T04:47:18.254Z","1.0.3":"2021-10-20T06:39:01.709Z","1.0.4":"2021-10-23T05:55:14.629Z","1.0.6":"2021-10-30T16:04:28.431Z","1.2.1":"2021-10-30T16:16:11.029Z","1.2.2":"2021-10-30T16:23:51.374Z","1.2.3":"2021-10-30T16:29:36.452Z","1.2.4":"2021-10-31T08:27:01.394Z","1.2.5":"2021-11-04T05:34:54.217Z","1.2.6":"2021-11-04T05:37:37.987Z","1.2.7":"2021-11-04T06:08:21.453Z","1.2.8":"2021-11-10T07:18:17.950Z","1.2.9":"2021-11-10T09:51:53.084Z","1.2.10":"2021-11-13T15:49:51.012Z","1.3.1":"2021-11-14T11:31:22.375Z","1.3.2":"2021-11-14T11:36:52.685Z","1.3.3":"2021-11-15T11:08:56.850Z","1.3.4":"2021-11-15T11:13:20.138Z","1.4.1":"2021-11-16T10:44:05.544Z","1.4.3":"2021-11-22T08:52:07.256Z","1.4.4":"2021-11-23T01:48:48.060Z","1.4.5":"2021-11-23T01:55:52.955Z","1.4.7":"2021-12-04T04:04:06.639Z","1.4.8":"2021-12-10T06:18:30.569Z","1.4.9":"2021-12-10T06:31:44.845Z","1.4.10":"2021-12-10T06:33:45.166Z","1.4.11":"2021-12-10T06:50:25.763Z","1.4.12":"2021-12-10T06:53:22.931Z","1.4.13":"2022-01-14T17:34:58.537Z","1.4.14":"2022-01-18T16:16:11.499Z","1.4.15":"2022-01-19T07:55:46.150Z","1.5.1":"2022-01-19T08:40:27.018Z","1.5.3":"2022-05-14T13:24:49.745Z","1.5.4":"2022-05-14T13:53:51.921Z","1.5.5":"2022-05-14T14:43:43.487Z"},"maintainers":[{"name":"zixia","email":"zixia@zixia.net"}],"description":"Pack a File into Box for easy move/transfer between servers no matter of where it is.(local path, remote url, or cloud storage)","homepage":"https://github.com/huan/file-box#readme","keywords":["file","virtual","cloud","url","stream","http","api"],"repository":{"type":"git","url":"git+https://github.com/huan/file-box.git"},"author":{"name":"Huan LI","email":"zixia@zixia.net"},"bugs":{"url":"https://github.com/huan/file-box/issues"},"license":"Apache-2.0","readme":"","readmeFilename":""}