Skip to content

Commit ed3b5e3

Browse files
author
pooya parsa
committed
initial commit
0 parents  commit ed3b5e3

File tree

14 files changed

+5449
-0
lines changed

14 files changed

+5449
-0
lines changed

.circleci/config.yml

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
version: 2
2+
3+
jobs:
4+
build:
5+
docker:
6+
- image: circleci/node
7+
steps:
8+
# Checkout repository
9+
- checkout
10+
11+
# Restore cache
12+
- restore_cache:
13+
key: yarn-{{ checksum "yarn.lock" }}
14+
15+
# Install dependencies
16+
- run:
17+
name: Install Dependencies
18+
command: NODE_ENV=dev yarn
19+
20+
# Keep cache
21+
- save_cache:
22+
key: yarn-{{ checksum "yarn.lock" }}
23+
paths:
24+
- "node_modules"
25+
26+
# Lint
27+
- run:
28+
name: Lint
29+
command: yarn lint
30+
31+
# Test
32+
- run:
33+
name: Tests
34+
command: yarn jest
35+
36+
# Coverage
37+
- run:
38+
name: Coverage
39+
command: yarn codecov

.editorconfig

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
root = true
2+
3+
[*]
4+
end_of_line = lf
5+
insert_final_newline = true
6+
trim_trailing_whitespace = true
7+
charset = utf-8
8+
9+
[*.js]
10+
indent_style = space
11+
indent_size = 2
12+
13+
[{package.json,*.yml,*.cjson}]
14+
indent_style = space
15+
indent_size = 2

.eslintrc.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
extends: standard

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.vscode
2+
node_modules
3+
*.log
4+
.DS_Store
5+
coverage

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2019 - Pooya Parsa <[email protected]>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
# 🇭TTP 🇫ilesystem
2+
3+
[![Standard JS][standard-src]][standard-href]
4+
[![david dm][david-src]][david-href]
5+
[![codecov][codecov-src]][codecov-href]
6+
[![circleci][circleci-src]][circleci-href]
7+
8+
[![npm version][npm-v-src]][npm-v-href]
9+
[![npm downloads][npm-dt-src]][npm-dt-href]
10+
[![package phobia][packagephobia-src]][packagephobia-href]
11+
12+
### **NOTE** This module is under development and not ready for any production use!
13+
14+
Expose filesystem via HTTP and access it from the other side!
15+
16+
This module works best with [memory-fs](https://github.com/webpack/memory-fs).
17+
18+
## Install
19+
20+
Install package:
21+
22+
```bash
23+
yarn add httpfs
24+
```
25+
26+
OR
27+
28+
```bash
29+
npm install httpfs
30+
```
31+
32+
## Server
33+
34+
Serving real fs is not a good idea. In this example we serve a virtual filesystem.
35+
36+
```js
37+
const HTTPFSMiddleware = require('httpfs/lib/middleware')
38+
const express = require('express')
39+
const MFS = require('memory-fs')
40+
41+
// Create a new express app listening on port 8080
42+
const app = express()
43+
app.listen(8080)
44+
45+
// Create a new Virtual FileSystem with a test file
46+
const mfs = new MFS()
47+
mfs.mkdirpSync('/test')
48+
mfs.writeFileSync('/test/file.txt', 'Works!')
49+
50+
// Create and register fs middleware
51+
app.use('/mfs', HTTPFSMiddleware(mfs))
52+
```
53+
54+
You can now browse filesystem via a normal browser via http://localhost:8080/mfs/
55+
56+
## Client
57+
58+
Supported methods:
59+
60+
- `exists(path): Promise<Boolean>`
61+
- `readFile(path): Promise<String>`
62+
63+
```js
64+
const HTTPFSAClient = require('httpfs/lib/client')
65+
66+
const fs = new HTTPFSAClient({
67+
endpoint: 'http://localhost:8080/mfs'
68+
})
69+
70+
fs.readFile('/test/file.txt').then((contents) => {
71+
console.log('File contents:', contents)
72+
})
73+
```
74+
75+
### Options
76+
77+
- `endpoint`: HTTP Endpoint of server
78+
- `maxAge`: Time for cache
79+
80+
## License
81+
82+
MIT. Made with 💖
83+
84+
<!-- Refs -->
85+
[standard-src]: https://flat.badgen.net/badge/code%20style/standard/green
86+
[standard-href]: https://standardjs.com
87+
88+
[npm-v-src]: https://flat.badgen.net/npm/v/httpfs/latest
89+
[npm-v-href]: https://npmjs.com/package/httpfs
90+
91+
[npm-dt-src]: https://flat.badgen.net/npm/dt/httpfs
92+
[npm-dt-href]: https://npmjs.com/package/httpfs
93+
94+
[packagephobia-src]: https://flat.badgen.net/packagephobia/install/httpfs
95+
[packagephobia-href]: https://packagephobia.now.sh/result?p=httpfs
96+
97+
[david-src]: https://flat.badgen.net/david/dep/jsless/httpfs
98+
[david-href]: https://david-dm.org/jsless/httpfs
99+
100+
[codecov-src]: https://flat.badgen.net/codecov/c/github/jsless/httpfs/master
101+
[codecov-href]: https://codecov.io/gh/jsless/httpfs
102+
103+
[circleci-src]: https://flat.badgen.net/circleci/github/jsless/httpfs/master
104+
[circleci-href]: https://circleci.com/gh/jsless/httpfs

jest.config.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module.exports = {
2+
'testEnvironment': 'node',
3+
'collectCoverage': true,
4+
'collectCoverageFrom': [
5+
'lib/**/*.js'
6+
]
7+
}

lib/client.js

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const fetch = require('node-fetch')
2+
const pMemoize = require('p-memoize')
3+
4+
module.exports = class HTTPFSClient {
5+
constructor ({ endpoint, maxAge = 1000 }) {
6+
this.endpoint = endpoint.replace(/\/$/, '')
7+
this._request = pMemoize(this._request, { maxAge })
8+
}
9+
10+
_url (path) {
11+
return this.endpoint + path
12+
}
13+
14+
async _request (path, options) {
15+
const url = this._url(path)
16+
const res = await fetch(url, options)
17+
return res
18+
}
19+
20+
async exists (path) {
21+
const res = await this._request(path)
22+
switch (res.status) {
23+
case 200: return true
24+
case 404: return false
25+
default: throw new Error('Invalid status ' + res.status)
26+
}
27+
}
28+
29+
async readFile (path) {
30+
const res = await this._request(path)
31+
return res.text()
32+
}
33+
}

lib/middleware.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
module.exports = function HTTPFSMiddleware (mfs) {
2+
return (req, res) => {
3+
// Resource path is url relative to /mfs
4+
const resourcePath = req.url
5+
6+
// Stat path
7+
let stat
8+
try {
9+
stat = mfs.statSync(resourcePath)
10+
} catch (e) {
11+
res.statusCode = 404
12+
return res.end('No such a file or directory: ' + resourcePath)
13+
}
14+
15+
// Directory listing
16+
if (stat.isDirectory()) {
17+
return res.end(`
18+
<html>
19+
<body>
20+
<h1>Index of ${resourcePath}</h1>
21+
<ul>
22+
${mfs.readdirSync(resourcePath).map(link => `<li><a href="${link}/">${link}</a></li>`).join('\n')}
23+
</ul>
24+
</body>
25+
</html>
26+
`)
27+
}
28+
29+
// Serve file
30+
res.end(mfs.readFileSync(resourcePath))
31+
}
32+
}

package.json

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{
2+
"name": "httpfs",
3+
"version": "0.0.1",
4+
"license": "MIT",
5+
"description": "Expose filesystem via HTTP and access it from the other side!",
6+
"repository": "jesless/httpfs",
7+
"contributes": [
8+
"Pooya Parsa <[email protected]>"
9+
],
10+
"scripts": {
11+
"lint": "eslint lib",
12+
"test": "npm run lint && npm run jest",
13+
"jest": "jest",
14+
"release": "standard-version && git push --follow-tags && npm publish",
15+
"prepare": "npm run test"
16+
},
17+
"files": [
18+
"lib"
19+
],
20+
"devDependencies": {
21+
"codecov": "^3.1.0",
22+
"eslint": "^5.9.0",
23+
"eslint-config-standard": "^12.0.0",
24+
"eslint-plugin-import": "^2.14.0",
25+
"eslint-plugin-jest": "^22.1.0",
26+
"eslint-plugin-node": "^8.0.0",
27+
"eslint-plugin-promise": "^4.0.1",
28+
"eslint-plugin-standard": "^4.0.0",
29+
"express": "^4.16.4",
30+
"jest": "^24.0.0",
31+
"memory-fs": "^0.4.1",
32+
"standard-version": "^4.4.0"
33+
},
34+
"dependencies": {
35+
"errno": "^0.1.7",
36+
"node-fetch": "^2.3.0",
37+
"p-memoize": "^2.1.0"
38+
}
39+
}

0 commit comments

Comments
 (0)