Update for zeit/now support

pull/72/head
Alex Kern 9 years ago
parent 2153fd2fdf
commit d52db44264

@ -1,53 +1,4 @@
# Logs
log
logs
*.log
npm-debug.log*
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
# OSX
.DS_Store .DS_Store
.DS_Store? node_modules
._* dist
.Spotlight-V100
.Trashes
ehthumbs.db
Thumbs.db
.AppleDouble
.LSOverride
Icon
# Java
*.class
# Git
.git
# FilePizza
src
resources resources
log
*.pem

40
.gitignore vendored

@ -1,39 +1,3 @@
# Logs .DS_Store
log node_modules
logs
*.log
# Runtime data
pids
*.pid
*.seed
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Compiled binary addons (http://nodejs.org/api/addons.html)
build/Release
# Dependency directory
# Commenting this out is preferred by some people, see
# https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git-
node_modules/*
# Users Environment Variables
.lock-wscript
# Compiled assets
dist dist
css/index.css
# New Relic
newrelic.js
# SSL Keys
*.pem

@ -1,14 +1,9 @@
FROM node:latest FROM node:latest
MAINTAINER Alex Kern <alex@pavlovml.com> MAINTAINER Alex Kern <alex@kern.io>
# install
RUN mkdir -p /filepizza
WORKDIR /filepizza
COPY package.json Makefile ./
RUN make install
COPY . ./ COPY . ./
RUN npm install && npm run build
# run
ENV NODE_ENV production ENV NODE_ENV production
EXPOSE 80 EXPOSE 80
CMD ./dist/index.js CMD node ./dist/index.js

@ -1,40 +0,0 @@
# ==============================================================================
# config
.PHONY: all build clean install push run
all: run
WATCH ?= false
TAG ?= latest
# ==============================================================================
# phony targets
build:
./node_modules/.bin/babel src --ignore __tests__,__mocks__ --out-dir dist
./node_modules/.bin/webpack --optimize-minimize ./src/client
docker build -t kern/filepizza:$(TAG) .
clean:
@ rm -rf node_modules
@ rm -rf dist
install:
npm install
push: build
docker push kern/filepizza:$(TAG)
run: | node_modules
@ if [ "$(WATCH)" = false ]; then \
./node_modules/.bin/babel-node src; \
else \
./node_modules/.bin/nodemon ./node_modules/.bin/babel-node -i dist src; \
fi
# ==============================================================================
# file targets
node_modules:
npm install

@ -15,30 +15,26 @@ A hosted instance of FilePizza is available at [file.pizza](http://file.pizza).
The recommended way to deploy FilePizza is as a [Docker container](https://hub.docker.com/r/kern/filepizza). The recommended way to deploy FilePizza is as a [Docker container](https://hub.docker.com/r/kern/filepizza).
You can also install FilePizza via the command-line: $ docker run -p 8080:8080 -e PORT=8080 -it kern/filepizza:latest
$ npm install filepizza -g You can also use [zeit/now](https://zeit.co/now):
$ filepizza
You can specify the port that FilePizza's HTTP server uses by setting the `PORT` environment variable (default 3000): $ now --npm --public -e NODE_ENV=production
$ env PORT=8080 filepizza If you'd like to use [Twilio's STUN/TURN service](https://www.twilio.com/stun-turn) for better connectivity behind NATs, you can specify your SID and token using the `TWILIO_SID` and `TWILIO_TOKEN` environment variables, respectively.
If you'd like to use [Twilio's STUN/TURN service](https://www.twilio.com/stun-turn) for better connectivity behind NATs, you can specify your SID and token like so:
$ env TWILIO_SID=abcdef TWILIO_TOKEN=ghijkl filepizza
## Development ## Development
$ git clone https://github.com/kern/filepizza.git $ git clone https://github.com/kern/filepizza.git
$ npm install $ npm install
$ npm run watch $ npm build
$ npm start
FilePizza is an isomorphic React application which uses the Flux application architecture. ES6 features are used liberally and compiled using Babel. Views are rendered on the server, store data is serialized and sent to the client, which then picks up where the server left off. FilePizza is an isomorphic React application which uses the Flux application architecture. ES6 features are used liberally and compiled using Babel. Views are rendered on the server, store data is serialized and sent to the client, which then picks up where the server left off.
Both client and server JavaScript files can be found in `lib/`. `lib/server.js` and `lib/client.js` are the server and client entrypoints, respectively. `lib/components/`, `lib/stores/`, and `lib/actions/` contain the corresponding Flux modules, implemented using [alt](https://github.com/goatslacker/alt). `lib/routes.js` serves as the isomorphic routes file using [react-router](https://github.com/rackt/react-router). Both client and server JavaScript files can be found in `lib/`. `lib/server.js` and `lib/client.js` are the server and client entrypoints, respectively. `lib/components/`, `lib/stores/`, and `lib/actions/` contain the corresponding Flux modules, implemented using [alt](https://github.com/goatslacker/alt). `lib/routes.js` serves as the isomorphic routes file using [react-router](https://github.com/rackt/react-router).
Stylesheets are automatically compiled using Stylus and are available at `/css`. Client-side JavaScript is compiled using Browserify and is available at `/js`. Client-side JavaScript and CSS are compiled using webpack and are available at `/app.js`.
## FAQ ## FAQ

@ -0,0 +1,22 @@
import "babel-polyfill";
import "./index.styl";
import React from "react";
import ReactRouter from "react-router";
import routes from "./routes";
import alt from "./alt";
import webrtcSupport from "webrtcsupport";
import SupportActions from "./actions/SupportActions";
let bootstrap = document.getElementById("bootstrap").innerHTML;
alt.bootstrap(bootstrap);
window.FilePizza = () => {
ReactRouter.run(routes, ReactRouter.HistoryLocation, function(Handler) {
React.render(<Handler data={bootstrap} />, document);
});
if (!webrtcSupport.support) SupportActions.noSupport();
let isChrome = navigator.userAgent.toLowerCase().indexOf("chrome") > -1;
if (isChrome) SupportActions.isChrome();
};

@ -0,0 +1,97 @@
import Bootstrap from "./Bootstrap";
import ErrorPage from "./ErrorPage";
import FrozenHead from "react-frozenhead";
import React from "react";
import SupportStore from "../stores/SupportStore";
import { RouteHandler } from "react-router";
import ga from "react-google-analytics";
ga("create", "UA-62785624-1", "auto");
ga("send", "pageview");
export default class App extends React.Component {
constructor() {
super();
this.state = SupportStore.getState();
this._onChange = () => {
this.setState(SupportStore.getState());
};
}
componentDidMount() {
SupportStore.listen(this._onChange);
}
componentWillUnmount() {
SupportStore.unlisten(this._onChange);
}
render() {
return (
<html lang="en">
<FrozenHead>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:url" content="https://file.pizza" />
<meta
property="og:title"
content="FilePizza - Your files, delivered."
/>
<meta
property="og:description"
content="Peer-to-peer file transfers in your web browser."
/>
<meta
property="og:image"
content="https://file.pizza/images/fb.png"
/>
<title>FilePizza - Your files, delivered.</title>
<link rel="stylesheet" href="/fonts/fonts.css" />
<Bootstrap data={this.props.data} />
<script src="https://cdn.jsdelivr.net/webtorrent/latest/webtorrent.min.js" />
<script src="/app.js" />
</FrozenHead>
<body>
<div className="container">
{this.state.isSupported ? <RouteHandler /> : <ErrorPage />}
</div>
<footer className="footer">
<p>
<script
id="fb13c4g"
dangerouslySetInnerHTML={{
__html:
"(function(i){var f,s=document.getElementById(i);f=document.createElement('iframe');f.src='//api.flattr.com/button/view/?uid=kern&button=compact&url=http%3A%2F%2Fgithub.com%2Fkern%2Ffilepizza';f.title='Flattr';f.height=20;f.width=110;f.style.borderWidth=0;s.parentNode.insertBefore(f,s);})('fb13c4g');"
}}
/>{" "}
Donations: <strong>1P7yFQAC3EmpvsB7K9s6bKPvXEP1LPoQnY</strong>
</p>
<p className="byline">
Cooked up by{" "}
<a href="http://kern.io" target="_blank">
Alex Kern
</a>{" "}
&amp;{" "}
<a href="http://neeraj.io" target="_blank">
Neeraj Baid
</a>{" "}
while eating <strong>Sliver</strong> @ UC Berkeley &middot;{" "}
<a href="https://github.com/kern/filepizza#faq" target="_blank">
FAQ
</a>{" "}
&middot;{" "}
<a href="https://github.com/kern/filepizza" target="_blank">
Fork us
</a>
</p>
</footer>
<script>FilePizza()</script>
<ga.Initializer />
</body>
</html>
);
}
}

@ -0,0 +1,44 @@
var twilio = require("twilio");
var winston = require("winston");
if (process.env.TWILIO_SID && process.env.TWILIO_TOKEN) {
var twilioSID = process.env.TWILIO_SID;
var twilioToken = process.env.TWILIO_TOKEN;
var client = twilio(twilioSID, twilioToken);
winston.info("Using Twilio TURN service");
} else {
var client = null;
}
var DEFAULT_ICE_SERVERS = [
{
urls: "stun:stun.l.google.com:19302"
}
];
var CACHE_LIFETIME = 5 * 60 * 1000; // 5 minutes
var cachedPromise = null;
function clearCache() {
cachedPromise = null;
}
exports.getICEServers = function() {
if (client == null) return Promise.resolve(DEFAULT_ICE_SERVERS);
if (cachedPromise) return cachedPromise;
cachedPromise = new Promise(function(resolve, reject) {
client.tokens.create({}, function(err, token) {
if (err) {
winston.error(err);
return resolve(DEFAULT_ICE_SERVERS);
}
winston.info("Retrieved ICE servers from Twilio");
setTimeout(clearCache, CACHE_LIFETIME);
resolve(token.ice_servers);
});
});
return cachedPromise;
};

@ -1,3 +1,5 @@
@import "nib";
beige = #F9F2E7 beige = #F9F2E7
dark-gray = #333 dark-gray = #333
gray = #777 gray = #777

@ -0,0 +1,124 @@
var db = require("./db");
var express = require("express");
var expressWinston = require("express-winston");
var forceSSL = require("express-force-ssl");
var fs = require("fs");
var http = require("http");
var https = require("https");
var ice = require("./ice");
var path = require("path");
var socketIO = require("socket.io");
var winston = require("winston");
var app = express();
if (process.env.SECURE) {
var server = https.Server(
{
key: fs.readFileSync(process.env.SSL_KEY || "key.pem"),
cert: fs.readFileSync(process.env.SSL_CERT || "cert.pem")
},
app
);
var port = process.env.PORT || 443;
var insecurePort = process.env.INSECURE_PORT || 80;
http.Server(app).listen(80);
} else {
var server = http.Server(app);
var port =
process.env.PORT || (process.env.NODE_ENV === "production" ? 80 : 3000);
}
var io = socketIO(server);
io.set("transports", ["polling"]);
var logDir = path.resolve(__dirname, "../log");
winston.add(winston.transports.DailyRotateFile, {
filename: logDir + "/access.log",
level: "info"
});
winston.add(winston.transports.File, {
filename: logDir + "/error.log",
level: "error",
handleExceptions: true,
json: false
});
server.on("error", function(err) {
winston.error(err.message);
process.exit(1);
});
process.on("unhandledRejection", (reason, p) => {
p.catch(err => {
log.error("Exiting due to unhandled rejection!");
log.error(err);
process.exit(1);
});
});
process.on("uncaughtException", err => {
log.error("Exiting due to uncaught exception!");
log.error(err);
process.exit(1);
});
server.listen(port, function(err) {
var host = server.address().address;
var port = server.address().port;
winston.info("FilePizza listening on %s:%s", host, port);
});
if (!process.env.QUIET) {
app.use(
expressWinston.logger({
winstonInstance: winston,
expressFormat: true
})
);
}
if (process.env.FORCE_SSL) {
app.set("forceSSLOptions", {
trustXFPHeader: true
});
app.use(forceSSL);
}
app.get("/app.js", require("./middleware/javascript"));
app.use(require("./middleware/static"));
app.use([
require("./middleware/bootstrap"),
require("./middleware/error"),
require("./middleware/react")
]);
io.on("connection", function(socket) {
var upload = null;
socket.on("upload", function(metadata, res) {
if (upload) return;
db.create(socket).then(u => {
upload = u;
upload.fileName = metadata.fileName;
upload.fileSize = metadata.fileSize;
upload.fileType = metadata.fileType;
upload.infoHash = metadata.infoHash;
res(upload.token);
});
});
socket.on("rtcConfig", function(_, res) {
ice.getICEServers().then(function(iceServers) {
res({ iceServers: iceServers });
});
});
socket.on("disconnect", function() {
db.remove(upload);
});
});

@ -8,7 +8,8 @@
"license": "BSD-3-Clause", "license": "BSD-3-Clause",
"homepage": "https://github.com/kern/filepizza", "homepage": "https://github.com/kern/filepizza",
"scripts": { "scripts": {
"start": "make run" "start": "node ./dist/index.js",
"build": "babel lib --ignore __tests__,__mocks__ --out-dir dist && webpack -p ./lib/client"
}, },
"repository": { "repository": {
"type": "git", "type": "git",
@ -33,45 +34,39 @@
}, },
"dependencies": { "dependencies": {
"alt": "^0.14.4", "alt": "^0.14.4",
"babel-cli": "^6.6.5", "babel-cli": "^6.16.0",
"babel-core": "^6.14.0", "babel-core": "^6.17.0",
"babel-loader": "^6.2.4", "babel-loader": "^6.2.5",
"babel-plugin-add-module-exports": "^0.1.2", "babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-react-jsx": "^6.7.4", "babel-plugin-transform-react-jsx": "^6.7.4",
"babel-polyfill": "^6.16.0", "babel-polyfill": "^6.16.0",
"babel-preset-es2015": "^6.14.0", "babel-preset-es2015": "^6.14.0",
"babel-preset-stage-0": "^6.5.0", "babel-preset-stage-0": "^6.16.0",
"classnames": "^1.2.0", "classnames": "^1.2.0",
"css-loader": "^0.28.4",
"express": "^4.12.0", "express": "^4.12.0",
"express-force-ssl": "^0.3.1", "express-force-ssl": "^0.3.1",
"express-winston": "^0.3.1", "express-winston": "^0.3.1",
"filepizza-socket": "^1.0.0", "filepizza-socket": "^1.0.0",
"json-loader": "^0.5.4",
"newrelic": "^1.21.1", "newrelic": "^1.21.1",
"nib": "^1.1.0", "nib": "^1.1.0",
"node-uuid": "^1.4.3", "node-uuid": "^1.4.3",
"nodemon": "^1.4.1",
"react": "^0.13.0", "react": "^0.13.0",
"react-frozenhead": "^0.3.0", "react-frozenhead": "^0.3.0",
"react-google-analytics": "^0.2.0", "react-google-analytics": "^0.2.0",
"react-router": "^0.13.1", "react-router": "^0.13.1",
"socket.io": "^1.3.5", "socket.io": "^1.3.5",
"socket.io-client": "^1.3.5", "socket.io-client": "^1.3.5",
"style-loader": "^0.18.2",
"stylus": "^0.50.0", "stylus": "^0.50.0",
"stylus-loader": "^3.0.1",
"twilio": "^2.9.1", "twilio": "^2.9.1",
"webpack": "^1.12.14", "webpack": "^1.12.14",
"webpack-dev-middleware": "^1.6.1",
"webrtcsupport": "^2.2.0", "webrtcsupport": "^2.2.0",
"winston": "^1.0.1", "winston": "^1.0.1",
"xkcd-password": "^1.2.0" "xkcd-password": "^1.2.0"
},
"devDependencies": {
"babel-cli": "^6.16.0",
"babel-core": "^6.17.0",
"babel-loader": "^6.2.5",
"babel-plugin-add-module-exports": "^0.2.1",
"babel-plugin-transform-react-jsx": "^6.8.0",
"babel-preset-es2015": "^6.16.0",
"babel-preset-stage-0": "^6.16.0",
"json-loader": "^0.5.4",
"nodemon": "^1.4.1",
"webpack-dev-middleware": "^1.6.1"
} }
} }

@ -1,22 +0,0 @@
import 'babel-polyfill'
import React from 'react'
import ReactRouter from 'react-router'
import routes from './routes'
import alt from './alt'
import webrtcSupport from 'webrtcsupport'
import SupportActions from './actions/SupportActions'
let bootstrap = document.getElementById('bootstrap').innerHTML
alt.bootstrap(bootstrap)
window.FilePizza = () => {
ReactRouter.run(routes, ReactRouter.HistoryLocation, function (Handler) {
React.render(<Handler data={bootstrap} />, document)
})
if (!webrtcSupport.support) SupportActions.noSupport()
let isChrome = navigator.userAgent.toLowerCase().indexOf('chrome') > -1
if (isChrome) SupportActions.isChrome()
}

@ -1,71 +0,0 @@
import Bootstrap from './Bootstrap'
import ErrorPage from './ErrorPage'
import FrozenHead from 'react-frozenhead'
import React from 'react'
import SupportStore from '../stores/SupportStore'
import { RouteHandler } from 'react-router'
import ga from 'react-google-analytics'
ga('create', 'UA-62785624-1', 'auto');
ga('send', 'pageview');
export default class App extends React.Component {
constructor() {
super()
this.state = SupportStore.getState()
this._onChange = () => {
this.setState(SupportStore.getState())
}
}
componentDidMount() {
SupportStore.listen(this._onChange)
}
componentWillUnmount() {
SupportStore.unlisten(this._onChange)
}
render() {
return <html lang="en">
<FrozenHead>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta property="og:url" content="http://file.pizza" />
<meta property="og:title" content="FilePizza - Your files, delivered." />
<meta property="og:description" content="Peer-to-peer file transfers in your web browser." />
<meta property="og:image" content="http://file.pizza/images/fb.png" />
<title>FilePizza - Your files, delivered.</title>
<link rel="stylesheet" href="/fonts/fonts.css" />
<link rel="stylesheet" href="/app.css" />
<Bootstrap data={this.props.data} />
<script src="https://cdn.jsdelivr.net/webtorrent/latest/webtorrent.min.js" />
<script src="/app.js" />
</FrozenHead>
<body>
<div className="container">
{this.state.isSupported
? <RouteHandler />
: <ErrorPage />}
</div>
<footer className="footer">
<p>
<script id="fb13c4g" dangerouslySetInnerHTML={{__html: "(function(i){var f,s=document.getElementById(i);f=document.createElement('iframe');f.src='//api.flattr.com/button/view/?uid=kern&button=compact&url=http%3A%2F%2Fgithub.com%2Fkern%2Ffilepizza';f.title='Flattr';f.height=20;f.width=110;f.style.borderWidth=0;s.parentNode.insertBefore(f,s);})('fb13c4g');"}} /> Donations: <strong>1P7yFQAC3EmpvsB7K9s6bKPvXEP1LPoQnY</strong>
</p>
<p className="byline">
Cooked up by <a href="http://kern.io" target="_blank">Alex Kern</a> &amp; <a href="http://neeraj.io" target="_blank">Neeraj Baid</a> while eating <strong>Sliver</strong> @ UC Berkeley &middot; <a href="https://github.com/kern/filepizza#faq" target="_blank">FAQ</a> &middot; <a href="https://github.com/kern/filepizza" target="_blank">Fork us</a>
</p>
</footer>
<script>FilePizza()</script>
<ga.Initializer />
</body>
</html>
}
}

@ -1,45 +0,0 @@
var twilio = require('twilio')
var winston = require('winston')
if (process.env.TWILIO_SID && process.env.TWILIO_TOKEN) {
var twilioSID = process.env.TWILIO_SID
var twilioToken = process.env.TWILIO_TOKEN
var client = twilio(twilioSID, twilioToken)
// winston.info('Created Twilio client', { sid: twilioSID, token: twilioToken })
} else {
var client = null
}
var DEFAULT_ICE_SERVERS = [
{
url: 'stun:23.21.150.121', // deprecated, replaced by `urls`
urls: 'stun:23.21.150.121'
}
]
var CACHE_LIFETIME = 5 * 60 * 1000 // 5 minutes
var cachedPromise = null
function clearCache() {
cachedPromise = null
}
exports.getICEServers = function () {
if (client == null) return Promise.resolve(DEFAULT_ICE_SERVERS)
if (cachedPromise) return cachedPromise
cachedPromise = new Promise(function (resolve, reject) {
client.tokens.create({}, function(err, token) {
if (err) {
winston.error(err)
return resolve(DEFAULT_ICE_SERVERS)
}
winston.info('Retrieved ICE servers from Twilio', token.ice_servers)
setTimeout(clearCache, CACHE_LIFETIME)
resolve(token.ice_servers)
})
})
return cachedPromise
}

@ -1,26 +0,0 @@
var express = require('express')
var nib = require('nib')
var path = require('path')
var stylus = require('stylus')
var CSS_PATH = path.resolve(__dirname, '../../css')
var COMPILED_PATH = path.resolve(__dirname, '../../css/index.css')
var routes = module.exports = new express.Router()
routes.use(function (req, res, next) {
req.url = '/index.css'
next()
}, stylus.middleware({
src: CSS_PATH,
dest: CSS_PATH,
compile: function (str, path) {
return stylus(str)
.set('filename', path)
.set('compress', true)
.use(nib())
.import('nib')
}
}), function (req, res) {
res.sendFile(COMPILED_PATH)
})

@ -1,119 +0,0 @@
var db = require('./db')
var express = require('express')
var expressWinston = require('express-winston')
var forceSSL = require('express-force-ssl')
var fs = require('fs')
var http = require('http')
var https = require('https')
var ice = require('./ice')
var path = require('path')
var socketIO = require('socket.io')
var winston = require('winston')
var app = express()
if (process.env.SECURE) {
var server = https.Server({
key: fs.readFileSync(process.env.SSL_KEY || 'key.pem'),
cert: fs.readFileSync(process.env.SSL_CERT || 'cert.pem')
}, app)
var port = process.env.PORT || 443
var insecurePort = process.env.INSECURE_PORT || 80
http.Server(app).listen(80)
} else {
var server = http.Server(app)
var port = process.env.PORT || (process.env.NODE_ENV === 'production' ? 80 : 3000)
}
var io = socketIO(server)
io.set('transports', ['polling'])
var logDir = path.resolve(__dirname, '../log')
winston.add(winston.transports.DailyRotateFile, {
filename: logDir + '/access.log',
level: 'info'
})
winston.add(winston.transports.File, {
filename: logDir + '/error.log',
level: 'error',
handleExceptions: true,
json: false
})
server.on('error', function (err) {
console.error(err.message)
process.exit(1)
})
process.on('unhandledRejection', (reason, p) => {
p.catch(err => {
log.error('Exiting due to unhandled rejection!')
log.error(err)
process.exit(1)
})
})
process.on('uncaughtException', err => {
log.error('Exiting due to uncaught exception!')
log.error(err)
process.exit(1)
})
server.listen(port, function (err) {
var host = server.address().address
var port = server.address().port
console.log('FilePizza listening on %s:%s', host, port)
})
app.use(expressWinston.logger({
winstonInstance: winston,
expressFormat: true
}))
if (process.env.FORCE_SSL) {
app.set('forceSSLOptions', {
trustXFPHeader: true
})
app.use(forceSSL)
}
app.get('/app.js', require('./middleware/javascript'))
app.get('/app.css', require('./middleware/css'))
app.use(require('./middleware/static'))
app.use([
require('./middleware/bootstrap'),
require('./middleware/error'),
require('./middleware/react')
])
io.on('connection', function (socket) {
var upload = null
socket.on('upload', function (metadata, res) {
if (upload) return
db.create(socket).then((u) => {
upload = u
upload.fileName = metadata.fileName
upload.fileSize = metadata.fileSize
upload.fileType = metadata.fileType
upload.infoHash = metadata.infoHash
res(upload.token)
})
})
socket.on('rtcConfig', function (_, res) {
ice.getICEServers().then(function (iceServers) {
res({ iceServers: iceServers })
})
})
socket.on('disconnect', function () {
db.remove(upload)
})
})

@ -1,9 +1,11 @@
const nib = require("nib");
module.exports = { module.exports = {
entry: './src/client', entry: "./lib/client",
target: 'web', target: "web",
output: { output: {
filename: 'dist/bundle.js' filename: "dist/bundle.js"
}, },
module: { module: {
@ -11,16 +13,24 @@ module.exports = {
{ {
test: /\.js$/, test: /\.js$/,
exclude: /node_modules/, exclude: /node_modules/,
loader: 'babel-loader' loader: "babel-loader"
}, },
{ {
test: /\.json$/, test: /\.json$/,
loader: 'json' loader: "json"
},
{
test: /\.styl$/,
loader: "style-loader!css-loader!stylus-loader"
} }
] ]
}, },
node: { node: {
fs: 'empty' fs: "empty"
},
stylus: {
use: [nib()]
} }
} };

Loading…
Cancel
Save