{"id":13980987,"url":"https://github.com/ebidel/filer.js","last_synced_at":"2025-05-15T15:00:20.173Z","repository":{"id":57159093,"uuid":"1937059","full_name":"ebidel/filer.js","owner":"ebidel","description":"A wrapper library for the HTML5 Filesystem API what reuses UNIX commands (cp, mv, ls) for its API.","archived":false,"fork":false,"pushed_at":"2019-04-11T12:59:23.000Z","size":5406,"stargazers_count":1485,"open_issues_count":26,"forks_count":155,"subscribers_count":46,"default_branch":"master","last_synced_at":"2025-05-07T20:54:11.985Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ebidel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-06-22T19:35:18.000Z","updated_at":"2025-03-28T00:04:03.000Z","dependencies_parsed_at":"2022-08-30T14:51:25.154Z","dependency_job_id":null,"html_url":"https://github.com/ebidel/filer.js","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebidel%2Ffiler.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebidel%2Ffiler.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebidel%2Ffiler.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ebidel%2Ffiler.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ebidel","download_url":"https://codeload.github.com/ebidel/filer.js/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254283236,"owners_count":22045135,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-09T04:01:48.435Z","updated_at":"2025-05-15T15:00:20.105Z","avatar_url":"https://github.com/ebidel.png","language":"JavaScript","funding_links":[],"categories":["JavaScript"],"sub_categories":[],"readme":"filer.js\n=======\n\nfiler.js is a [well-tested](tests) wrapper library for the [HTML5 Filesystem API](http://dev.w3.org/2009/dap/file-system/pub/FileSystem/),\nan API which enables web applications to read and write files and folders to\nits own sandboxed filesystem.\n\nUnlike other wrapper libraries [[1], [2]], filer.js takes a different approach\nby reusing familiar UNIX commands (`cp`, `mv`, `ls`) for its API. The goal is to\nmake the HTML5 API more approachable for developers that have done file I/O in\nother languages.\n\n[1]: https://github.com/ajaxorg/webfs\n[2]: http://code.google.com/p/closure-library/source/browse/trunk/closure/goog/fs/fs.js\n\n**Check out the [demo app](http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html):**\n\n\u003ca href=\"http://html5-demos.appspot.com/static/filesystem/filer.js/demos/index.html\"\u003e\n  \u003cimg src=\"https://raw.github.com/ebidel/filer.js/master/demos/images/demo_screenshot.png\" title=\"Demo app screenshot\" alt=\"Demo app screenshot\"\u003e\n\u003c/a\u003e\n\nSupported Browsers\n------------------\n\n* Chrome\n\nThe HTML5 Filesystem API is only supported in Chrome. Therefore, the library only works in Chrome.\n\nGetting started\n=======\n\nI highly recommended that you familiarize yourself with the HTML5 Filesystem API.\nI've written a book on the topic, [\"Using the HTML5 Filesystem API\"](http://shop.oreilly.com/product/0636920021360.do), and there are two great articles on HTML5 Rocks that walk you through all of its\ndifferent methods and capabilities:\n\n1. [Exploring the FileSystem APIs](http://www.html5rocks.com/tutorials/file/filesystem/)\n2. [The Synchronous FileSystem API for Workers](http://www.html5rocks.com/tutorials/file/filesystem-sync/)\n\nUsage\n-----\n\nInstall the polyfill:\n\n    npm install filer.js --save\n\nDrop it on your page:\n\n    \u003cscript src=\"node_modules/filer/dist/filer.min.js\" async\u003e\u003c/script\u003e\n\nThe underlying Filesystem API is asynchronous, therefore, the library calls are\nmostly asynchronous. This means you'll be passing callbacks all over the place.\n\nFirst, create a `Filer` object:\n\n    var filer = new Filer();\n\nNext, initialize the library:\n\n```javascript\nfiler.init({persistent: false, size: 1024 * 1024}, function(fs) {\n  // filer.size == Filer.DEFAULT_FS_SIZE\n  // filer.isOpen == true\n  // filer.fs == fs\n}, onError);\n```\n\nThe first argument is an optional initialization object that can contain two\nproperties, `persistent` (the type of storage to use) and `size`. The second and\nthird arguments are a success and error callback, respectively:\n\nThe success callback is passed a `LocalFileSystem` object. If you don't initialize\nthe the filesystem with a size, a default size of `Filer.DEFAULT_FS_SIZE` (1MB)\nwill be used. Thus, the previous call can be simplified to:\n\n```javascript\nfiler.init({}, function(fs) {\n  ...\n}, onError);\n\nfiler.init(); // All parameters are optional.\n```\n\n**Error handling**\n\nMany methods take an optional error callback as their last argument. It can be a\ngood idea to setup a global error handler for all methods to use:\n\n```javascript\nfunction onError(e) {\n  console.log('Error' + e.name);\n}\n```\n\nExamples\n============\n\n## General rule of thumb\n\nFor versatility, the library accepts paths to files or directories as string\narguments (a path) or as filesystem URLs. It also can take the\n`FileEntry`/`DirectoryEntry` object representing the file/directory.\n\nls()\n-----\n\n*List the contents of a directory.*\n\nThe first arg is a path, filesystem URL, or DirectoryEntry to return the contents\nfor. The second and third arguments, are success and error callbacks, respectively.\n\n```javascript\n// Pass a path.\nfiler.ls('/', function(entries) {\n  // entries in the root directory.\n}, onError);\n\nfiler.ls('.', function(entries) {\n  // entries in the current working directory.\n}, onError);\n\nfiler.ls('path/to/some/dir/', function(entries) {\n  // entries in \"path/to/some/dir/\"\n}, onError);\n\n// Pass a filesystem: URL.\nvar fsURL = filer.fs.root.toURL(); // e.g. 'filesystem:http://example.com/temporary/';\nfiler.ls(fsURL, function(entries) {\n  // entries in the root folder.\n}, onError);\n\n// Pass a DirectorEntry.\nfiler.ls(filer.fs.root, function(entries) {\n  // entries in the root directory.\n}, onError);\n```\n\ndf()\n-----\n\n*Displays disk space usage.*\n\nThe first and second arguments, are success and error callbacks. Used space, Free space and currently allocated total space are passed to the success callback.\n\n```javascript\n\nfiler.df(function(used, free, cap) {\n  // used, free and capacity in bytes.\n}, onError);\n```\n\ncd()\n-----\n\n*Allows you to change into another directory.*\n\nThis is a convenience method. When using `cd()`, future operations are treated\nrelative to the new directory. The success callback is passed the `DirectoryEntry`\nchanged into.\n\n```javascript\n// Passing a path.\nfiler.cd('/path/to/folder', function(dirEntry) {\n  ...\n}, onError);\n\n// Passing a filesystem: URL.\nvar fsURL = filer.fs.root.toURL(); // e.g. 'filesystem:http://example.com/temporary/';\nfiler.cd(fsURL + 'myDir', function(dirEntry) {\n  // cwd becomes /myDir.\n}, onError);\n\n// Passing a DirectoryEntry.\nfiler.cd(dirEntry, function(dirEntry2) {\n  // dirEntry == dirEntry2\n}, onError);\n\nfiler.cd('/path/to/folder'); // Both callbacks are optional.\n```\n\ncreate()\n-----\n\n*Creates an empty file.*\n\n`create()` creates an empty file in the current working directory. If you wish\nto write data to a file, see the `write()` method.\n\n**Important Note** : Directory path leading to the file must exist before calling create!\n\n```javascript\nfiler.create('myFile.txt', false, function(fileEntry) {\n  // fileEntry.name == 'myFile.txt'\n}, onError);\n\nfiler.create('/path/to/some/dir/myFile.txt', true, function(fileEntry) {\n  // fileEntry.fullPath == '/path/to/some/dir/myFile.txt'\n}, onError);\n\nfiler.create('myFile.txt'); // Last 3 args are optional.\n```\n\nThe second (optional) argument is a boolean. Setting it to true throws an error\nif the file you're trying to create already exists.\n\nmkdir()\n-----\n\n*Creates an empty directory.*\n\n```javascript\nfiler.mkdir('myFolder', false, function(dirEntry) {\n  // dirEntry.isDirectory == true\n  // dirEntry.name == 'myFolder'\n}, onError);\n```\n\nYou can pass `mkdir()` a folder name or a path to create. In the latter,\nit behaves like UNIX's `mkdir -p`, creating each intermediate directory as needed.\n\nFor example, the following would create a new hierarchy (\"music/genres/jazz\") in\nthe current folder:\n\n```javascript\nfiler.mkdir('music/genres/jazz/', false, function(dirEntry) {\n  // dirEntry.name == 'jazz' // Note: dirEntry is the last entry created.\n}, onError);\n```\n\nThe second argument to `mkdir()` a boolean indicating whether or not an error\nshould be thrown if the directory already exists. The last two are a success\ncallback and optional error callback.\n\nrm()\n-----\n\n*Removes a file or directory.*\n\nIf you're removing a directory, it is removed recursively. \n\n```javascript\nfiler.rm('myFile.txt', function() {\n  ...\n}, onError);\n\nfiler.rm('/path/to/some/someFile.txt', function() {\n  ...\n}, onError);\n\nvar fsURL = filer.pathToFilesystemURL('/path/to/some/directory');\nfiler.rm(fsURL, function() {\n  ...\n}, onError);\n\nfiler.rm(directorEntry, function() {\n  ...\n}, onError);\n```\n\ncp()\n-----\n\n*Copies a file or directory.*\n\nThe first argument to `cp()` is the source file/directory you wish to copy,\nfollowed by the destination folder for the source to be copied into.\n\nNote: The src and dest arguments need to be the same type. For example, if pass\na string path for the first argument, the destination cannot be a FileEntry.\nIt must be a string path (or filesystem URL) as well.\n\n```javascript\n// Pass string paths.\nfiler.cp('myFile.txt', '/path/to/other/folder', null, function(entry) {\n  // entry.fullPath == '/path/to/other/folder/myFile.txt'\n}, onError);\n\n// Pass filesystem URLs.\nvar srcFsURL = 'filesystem:http://example.com/temporary/myDir';\nvar destFsURL = 'filesystem:http://example.com/temporary/anotherDir';\nfiler.cp(srcFsURL, destFsURL, null, function(entry) {\n  // filer.pathToFilesystemURL(entry.fullPath) == 'filesystem:http://example.com/temporary/anotherDir/myDir'\n}, onError);\n\n// Pass Entry objects.\nfiler.cp(srcEntry, destinationFolderEntry, null, function(entry) {\n  ...\n}, onError);\n\n// Mixing string paths with filesystem URLs work too:\nfiler.cp(srcEntry.toURL(), '/myDir', null, function(entry) {\n  ...\n}, onError);\n```\n\nIf you wish to copy the entry under a new name, specify the third newName argument:\n\n```javascript\n// Copy myFile.txt to myFile2.txt in the current directory.\nfiler.cp('myFile.txt', '.', 'myFile2.txt', function(entry) {\n  // entry.name == 'myFile2.txt'\n}, onError);\n```\n\nmv()\n-----\n\n*Moves a file or directory.*\n\nThe first argument to move is the source file or directory to move, the second\nis a destination directory, and the third is an optional new name for the file/folder\nwhen it is moved.\n\n```javascript\n// Pass string paths.\nfiler.mv('path/to/myfile.mp3', '/another/dir', null, function(fileEntry) {\n  // fileEntry.fullPath == '/another/dir/myfile.mp3'\n}, onError);\n\n// Pass a filesystem URL. This example renames file.txt to somethingElse.txt in\n// the same directory.\nfiler.mv('filesystem:http://example.com/temporary/file.txt', '.', 'somethingElse.txt', function(fileEntry) {\n  // fileEntry.fullPath == '/somethingElse.txt'\n}, onError);\n\n// Pass a FileEntry or DirectoryEntry.\nfiler.mv(folderEntry, destDirEntry, function(dirEntry) {\n  // folder is moved into destDirEntry\n}, onError);\n\nfiler.mv('myFile.txt', './someDir'); // The new name and both callbacks are optional.\n\n```\n\nopen()\n-----\n\n*Returns a File object.*\n\n```javascript\n// Pass a path.\nfiler.open('myFile.txt', function(file) {\n  // Use FileReader to read file.\n  var reader = new FileReader();\n  reader.onload = function(e) {\n    ...\n  }\n  read.readAsArrayBuffer(file);\n}, onError);\n\n// Pass a filesystem URL.\nfiler.open(fileEntry.toURL(), function(file) {\n  ...\n}, onError);\n\n// Pass a FileEntry.\nfiler.open(fileEntry, function(file) {\n  ...\n}, onError);\n```\n\nwrite()\n-----\n\n*Writes content to a file.*\n\n`write()` takes a `string` (path or filesystem URL) or `FileEntry` as it's first argument.\nThis is the file to write data to. If the does not exist, it is created. Otherwise,\nthe file's contents are overwritten if it already exists.\n\nThe second argument is an object with three properties:\n- `data`: the content to write into the file.\n- `type`: optional mimetype of the content.\n- `append`: optional true if data should be appended to the file.\n\nThe success callback for this method is passed the `FileEntry` for the file that\nwas written to and the `FileWriter` object used to do the writing.\n\n```javascript\n// Write files from a file input.\ndocument.querySelector('input[type=\"file\"]').onchange = function(e) {\n  var file = e.target.files[0];\n  filer.write(file.name, {data: file, type: file.type}, function(fileEntry, fileWriter) {\n    ...\n  }, onError);\n};\n\n// Create a Blob and write it out.\nvar bb = new BlobBuilder();\nbb.append('body { background: red; }');\nfiler.write('styles.css', {data: bb.getBlob('text/css'), type: 'text/css'},\n  function(fileEntry, fileWriter) {\n    ...\n  },\n  onError\n);\n\n// Create a typed array and write the ArrayBuffer.\nvar uint8 = new Uint8Array([1,2,3,4,5]);\nfiler.write(fileEntry, {data: uint8.buffer},\n  function(fileEntry, fileWriter) {\n    ...\n  },\n  onError\n);\n\n// Write string data.\nfiler.write('path/to/file.txt', {data: '1234567890', type: 'text/plain'},\n  function(fileEntry, fileWriter) {\n    ...\n  },\n  onError\n);\n\n// Append to a file.\nfiler.write('path/to/file.txt', {data: '1234567890', type: 'text/plain', append: true},\n  function(fileEntry, fileWriter) {\n    ...\n  },\n  onError\n);\n```\n\nUtility methods\n============\n\nThe library contains a few utility methods to help you out.\n\n```javascript\nUtil.fileToObjectURL(Blob|File);\n\nUtil.fileToArrayBuffer(blob, function(arrayBuffer) {\n  ...\n});\n\nvar blob = Util.arrayBufferToBlob((new Uint8Array(10)).buffer, opt_contentType);\n\nUtil.arrayBufferToBinaryString((new Uint8Array(10)).buffer, function(binStr) {\n  ...\n});\n\nUtil.strToObjectURL(binaryStr, opt_contentType);\n\nUtil.strToDataURL(binaryStr, contentType) // e.g. \"data:application/pdf;base64,Ym9keSB7IG...\"\n// For plaintext (non-binary data):\n// Util.strToDataURL('body { background: green; }', 'text/css', false) == data:text/css,body { background: green; }\n\nUtil.arrayToBinaryString(bytes); // bytes is an Array, each varying from 0-255.\n\nUtil.getFileExtension('myfile.txt') == '.txt'\n\n// Util.toArray(DOMList/NodeList) == Array\ndocument.querySelector('input[type=\"file\"]').onchange = function(e) {\n  Util.toArray(this.files).forEach(function(file, i) {\n    // blah blah blah.\n  });\n};\n```\n\n## Contributing\n\n### Building\n\nInstall the dependencies and compile the library by running `gulp`:\n\n    npm install\n    gulp\n\nThis will output a built file to `dist/filer.min.js`.\n\n### Releasing\n\nTo cut a new release, run:\n\n    npm version patch\n\nAlso update components.json with the new version. Then run:\n\n    gulp\n    npm publish\n\n[![Analytics](https://ga-beacon.appspot.com/UA-46812528-1/ebidel/filer.js/README)](https://github.com/igrigorik/ga-beacon)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febidel%2Ffiler.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Febidel%2Ffiler.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Febidel%2Ffiler.js/lists"}