From 82427dedfb26fb00ee160777c281f45ab0ffdf7f Mon Sep 17 00:00:00 2001 From: lewis ma Date: Mon, 26 Sep 2016 19:16:10 +0800 Subject: [PATCH] add assets --- .gitignore | 7 + assets.js | 78 ++++++++ backpack.config.js | 28 ++- backpack.js | 45 ++++- package.json | 8 +- patch/body-parser/1.13.3/urlencoded.js | 266 +++++++++++++++++++++++++ src/app.js | 17 +- src/appifi/routes/stylesheets.js | 55 +++++ src/fruitmix/lib/xstat.js | 3 +- src/fruitmix/routes/users.js | 1 - src/fruitmix/util/async.js | 4 +- 11 files changed, 491 insertions(+), 21 deletions(-) create mode 100644 assets.js create mode 100644 patch/body-parser/1.13.3/urlencoded.js create mode 100644 src/appifi/routes/stylesheets.js diff --git a/.gitignore b/.gitignore index 945d1d75..f0686940 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,14 @@ public/bundle.js # release folder release/ +# appifi.js +appifi.js +assets/ +xxhash.node +xattr.node + # + family/ fruitfiles/ tmpTestFoder/ diff --git a/assets.js b/assets.js new file mode 100644 index 00000000..1579a3d4 --- /dev/null +++ b/assets.js @@ -0,0 +1,78 @@ +var fs = require('fs') + +let xxhashBase64, xxhash, xattrBase64, xattr, bundlejs, indexHtml, robotoCSS, styleCSS, + robotoThinBase64, robotoThin, robotoLightBase64, robotoLight, + robotoRegularBase64, robotoRegular, robotoMediumBase64, robotoMedium, + robotoBoldBase64, robotoBold, robotoBlackBase64, robotoBlack + +if (global.WEBPACK) { + + xxhashBase64 = require('raw!./assets/xxhash.node.base64') + xattrBase64 = require('raw!./assets/xattr.node.base64') + + robotoThinBase64 = require('raw!./assets/robotoThin.base64') + robotoLightBase64 = require('raw!./assets/robotoLight.base64') + robotoRegularBase64 = require('raw!./assets/robotoRegular.base64') + robotoMediumBase64 = require('raw!./assets/robotoMedium.base64') + robotoBoldBase64 = require('raw!./assets/robotoBold.base64') + robotoBlackBase64 = require('raw!./assets/robotoBlack.base64') + + bundlejs = require('raw!./assets/bundle.js.raw') + indexHtml = require('raw!./assets/index.html.raw') + + robotoCSS = require('raw!./assets/roboto.css.raw') + styleCSS = require('raw!./assets/style.css.raw') +} + +if (xxhashBase64) { + let decode = Buffer.from(xxhashBase64.toString(), 'base64') + fs.writeFileSync('./xxhash.node', decode) + xxhash = require('xxhash') + + console.log('hash hash') + console.log(xxhash.hash(Buffer.from('hello'), 1234)) +} + +if (xattrBase64) { + let decode = Buffer.from(xattrBase64.toString(), 'base64') + fs.writeFileSync('./xattr.node', decode) +} + +function loadFont (base64, name) { + if (base64) + return Buffer.from(base64, 'base64') + else + return fs.readFileSync('./public/stylesheets/Roboto-' + name + '-webfont.woff') +} + +robotoThin = loadFont(robotoThinBase64, 'Thin') +robotoLight = loadFont(robotoLightBase64, 'Light') +robotoRegular = loadFont(robotoRegularBase64, 'Regular') +robotoMedium = loadFont(robotoMediumBase64, 'Medium') +robotoBold = loadFont(robotoBoldBase64, 'Bold') +robotoBlack = loadFont(robotoBlackBase64, 'Black') + +if (!bundlejs) { + bundlejs = fs.readFileSync('./public/bundle.js').toString() +} + +if (!indexHtml) { + indexHtml = fs.readFileSync('./public/index.html').toString() +} + +if (!robotoCSS) { + robotoCSS = fs.readFileSync('./public/stylesheets/roboto.css') +} + +if (!styleCSS) { + styleCSS = fs.readFileSync('./public/stylesheets/style.css') +} + +console.log('assets loaded') + +module.exports = { + bundlejs, indexHtml, robotoCSS, styleCSS, + robotoThin, robotoLight, robotoRegular, robotoMedium, robotoBold, robotoBlack +} + +setTimeout(() => require('./src/app'), 1000) diff --git a/backpack.config.js b/backpack.config.js index 8f510f2a..91e5ad39 100644 --- a/backpack.config.js +++ b/backpack.config.js @@ -5,7 +5,7 @@ module.exports = { // base dir for resolving entry option context: __dirname, - entry: ['./build/app'], + entry: ['./assets.js'], node: { __filename: false, __dirname: false, @@ -19,21 +19,35 @@ module.exports = { }, externals: { -// "body-parser": "commonjs body-parser", -// "express": "commonjs express", - "fs-xattr": "commonjs fs-xattr", - "xxhash": "commonjs xxhash" + "../build/Release/hash": "commonjs ./xxhash.node", + "./build/Release/xattr": "commonjs ./xattr.node", }, module: { preLoaders: [ { test: /\.json$/, loader: 'json' }, - { test: /\.node$/, loader: 'node' }, ], + + loaders: [ + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel-loader', + query: { + presets: ['es2015', 'bluebird'], + plugins: [ + "transform-async-to-bluebird", + "transform-promise-to-bluebird", + "transform-runtime" + ] + } + } + ] }, plugins: [ - new webpack.DefinePlugin({ "global.GENTLY": false }) + new webpack.DefinePlugin({ "global.GENTLY": false }), + new webpack.DefinePlugin({ "global.WEBPACK": true }) ], } diff --git a/backpack.js b/backpack.js index 06b506d6..e4d387c2 100644 --- a/backpack.js +++ b/backpack.js @@ -1,8 +1,41 @@ -var webpack = require('webpack') +var fs = require('fs') +var child = require('child_process') -var config = require('./backpack.config') +const commands = [ + + // clean + 'rm -rf assets', + + // mkdir + 'mkdir assets', + + // patch body-parser + 'cp patch/body-parser/1.13.3/urlencoded.js node_modules/body-parser/lib/types/urlencoded.js', + + // xattr bin + 'base64 node_modules/fs-xattr/build/Release/xattr.node > assets/xattr.node.base64', + + // xxhash bin + 'base64 node_modules/xxhash/build/Release/hash.node > assets/xxhash.node.base64', + + // fonts + 'base64 public/stylesheets/Roboto-Thin-webfont.woff > assets/robotoThin.base64', + 'base64 public/stylesheets/Roboto-Light-webfont.woff > assets/robotoLight.base64', + 'base64 public/stylesheets/Roboto-Regular-webfont.woff > assets/robotoRegular.base64', + 'base64 public/stylesheets/Roboto-Medium-webfont.woff > assets/robotoMedium.base64', + 'base64 public/stylesheets/Roboto-Bold-webfont.woff > assets/robotoBold.base64', + 'base64 public/stylesheets/Roboto-Black-webfont.woff > assets/robotoBlack.base64', + + // other assets + 'cp public/index.html assets/index.html.raw', + 'cp public/bundle.js assets/bundle.js.raw', + 'cp public/stylesheets/roboto.css assets/roboto.css.raw', + 'cp public/stylesheets/style.css assets/style.css.raw', +] + +child.spawnSync('node_modules/.bin/webpack', ['--config', 'webpack.config.js', '-p'], { stdio: 'inherit' }) + +commands.forEach(item => child.execSync(item)) + +child.spawnSync('node_modules/.bin/webpack', ['--config', 'backpack.config.js', '-p'], { stdio: 'inherit' }) -compiler = webpack(config) -compiler.run((err, stats) => { - console.log(err || stats) -}) diff --git a/package.json b/package.json index a046045c..7f36ccd8 100644 --- a/package.json +++ b/package.json @@ -6,6 +6,7 @@ "start": "node build/app.js", "build": "babel src --out-dir build", "devel": "nodemon --exec babel-node --ignore web --ignore public/bundle.js src/app.js", + "devel-assets": "nodemon --exec babel-node --ignore web --ignore public/bundle.js assets.js", "devel-appstore": "nodemon --exec babel-node --ignore web --ignore public/bundle.js src/app.js --appstore-master", "webpack": "webpack --watch --watch-poll", "unit": "node_modules/.bin/mocha --compilers js:babel-core/register --recursive test", @@ -33,11 +34,10 @@ "babel-preset-es2015": "^6.9.0", "babel-preset-react": "^6.5.0", "babel-preset-react-hmre": "^1.1.1", - "babel-preset-stage-0": "^6.5.0", "bcryptjs": "^2.3.0", + "binary-loader": "0.0.1", "bluebird": "^3.4.1", - "body-parser": "~1.13.2", - "bonjour": "^3.5.0", + "body-parser": "1.13.3", "canonical-json": "0.0.4", "chai": "^3.5.0", "chai-as-promised": "^5.3.0", @@ -51,6 +51,7 @@ "eslint": "^2.10.2", "eslint-plugin-react": "^5.1.1", "express": "~4.13.1", + "file-loader": "^0.9.0", "filter-object": "^2.1.0", "fs-xattr": "^0.1.14", "json-loader": "^0.5.4", @@ -65,6 +66,7 @@ "passport": "^0.3.2", "passport-http": "^0.3.0", "passport-jwt": "^2.1.0", + "raw-loader": "^0.5.1", "react": "^15.2.1", "react-addons-css-transition-group": "^15.2.0", "react-click-outside": "^2.1.0", diff --git a/patch/body-parser/1.13.3/urlencoded.js b/patch/body-parser/1.13.3/urlencoded.js new file mode 100644 index 00000000..8601c1f1 --- /dev/null +++ b/patch/body-parser/1.13.3/urlencoded.js @@ -0,0 +1,266 @@ +/*! + * body-parser + * Copyright(c) 2014 Jonathan Ong + * Copyright(c) 2014-2015 Douglas Christopher Wilson + * MIT Licensed + */ + +'use strict' + +/** + * Module dependencies. + * @private + */ + +var bytes = require('bytes') +var contentType = require('content-type') +var createError = require('http-errors') +var debug = require('debug')('body-parser:urlencoded') +var deprecate = require('depd')('body-parser') +var read = require('../read') +var typeis = require('type-is') +var qs = require('qs') +var querystring = require('querystring') + +/** + * Module exports. + */ + +module.exports = urlencoded + +/** + * Cache of parser modules. + */ + +var parsers = Object.create(null) + +/** + * Create a middleware to parse urlencoded bodies. + * + * @param {object} [options] + * @return {function} + * @public + */ + +function urlencoded(options) { + var opts = options || {} + + // notice because option default will flip in next major + if (opts.extended === undefined) { + deprecate('undefined extended: provide extended option') + } + + var extended = opts.extended !== false + var inflate = opts.inflate !== false + var limit = typeof opts.limit !== 'number' + ? bytes.parse(opts.limit || '100kb') + : opts.limit + var type = opts.type || 'application/x-www-form-urlencoded' + var verify = opts.verify || false + + if (verify !== false && typeof verify !== 'function') { + throw new TypeError('option verify must be function') + } + + // create the appropriate query parser + var queryparse = extended + ? extendedparser(opts) + : simpleparser(opts) + + // create the appropriate type checking function + var shouldParse = typeof type !== 'function' + ? typeChecker(type) + : type + + function parse(body) { + return body.length + ? queryparse(body) + : {} + } + + return function urlencodedParser(req, res, next) { + if (req._body) { + return debug('body already parsed'), next() + } + + req.body = req.body || {} + + // skip requests without bodies + if (!typeis.hasBody(req)) { + return debug('skip empty body'), next() + } + + debug('content-type %j', req.headers['content-type']) + + // determine if request should be parsed + if (!shouldParse(req)) { + return debug('skip parsing'), next() + } + + // assert charset + var charset = getCharset(req) || 'utf-8' + if (charset !== 'utf-8') { + debug('invalid charset') + next(createError(415, 'unsupported charset "' + charset.toUpperCase() + '"', { + charset: charset + })) + return + } + + // read + read(req, res, next, parse, debug, { + debug: debug, + encoding: charset, + inflate: inflate, + limit: limit, + verify: verify + }) + } +} + +/** + * Get the extended query parser. + * + * @param {object} options + */ + +function extendedparser(options) { + var parameterLimit = options.parameterLimit !== undefined + ? options.parameterLimit + : 1000 + var parse = qs.parse + + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number') + } + + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0 + } + + return function queryparse(body) { + var paramCount = parameterCount(body, parameterLimit) + + if (paramCount === undefined) { + debug('too many parameters') + throw createError(413, 'too many parameters') + } + + var arrayLimit = Math.max(100, paramCount) + + debug('parse extended urlencoding') + return parse(body, { + allowDots: false, + allowPrototypes: true, + arrayLimit: arrayLimit, + depth: Infinity, + parameterLimit: parameterLimit + }) + } +} + +/** + * Get the charset of a request. + * + * @param {object} req + * @api private + */ + +function getCharset(req) { + try { + return contentType.parse(req).parameters.charset.toLowerCase() + } catch (e) { + return undefined + } +} + +/** + * Count the number of parameters, stopping once limit reached + * + * @param {string} body + * @param {number} limit + * @api private + */ + +function parameterCount(body, limit) { + var count = 0 + var index = 0 + + while ((index = body.indexOf('&', index)) !== -1) { + count++ + index++ + + if (count === limit) { + return undefined + } + } + + return count +} + +/** + * Get parser for module name dynamically. + * + * @param {string} name + * @return {function} + * @api private + */ +/** +function parser(name) { + var mod = parsers[name] + + if (mod) { + return mod.parse + } + + // load module + mod = parsers[name] = require(name) + + return mod.parse +} +**/ +/** + * Get the simple query parser. + * + * @param {object} options + */ + +function simpleparser(options) { + var parameterLimit = options.parameterLimit !== undefined + ? options.parameterLimit + : 1000 + var parse = querystring.parse + + if (isNaN(parameterLimit) || parameterLimit < 1) { + throw new TypeError('option parameterLimit must be a positive number') + } + + if (isFinite(parameterLimit)) { + parameterLimit = parameterLimit | 0 + } + + return function queryparse(body) { + var paramCount = parameterCount(body, parameterLimit) + + if (paramCount === undefined) { + debug('too many parameters') + throw createError(413, 'too many parameters') + } + + debug('parse urlencoding') + return parse(body, undefined, undefined, {maxKeys: parameterLimit}) + } +} + +/** + * Get the simple type checker. + * + * @param {string} type + * @return {function} + */ + +function typeChecker(type) { + return function checkType(req) { + return Boolean(typeis(req, type)) + } +} diff --git a/src/app.js b/src/app.js index eab2a3d4..c2b8e8ec 100644 --- a/src/app.js +++ b/src/app.js @@ -23,7 +23,6 @@ app.use(logger('dev', { app.use(bodyParser.json()) app.use(bodyParser.urlencoded({ extended: false })) app.use(cookieParser()) -app.use(express.static(path.join(__dirname, '../public'))) /* * module init @@ -60,7 +59,21 @@ appstore.reload() /* * routes */ -app.use('/', require('./appifi/routes/index')) +// app.use('/', require('./appifi/routes/index')) + +app.get('/', (req, res) => { + res.set('Content-Type', 'text/html').send(assets.indexHtml) +}) + +app.get('/index.html', (req, res) => { + res.set('Content-Type', 'text/html').send(assets.indexHtml) +}) + +app.get('/bundle.js', (req, res) => { + res.set('Content-Type', 'application/javascript').send(assets.bundlejs) +}) + +app.use('/stylesheets', require('./appifi/routes/stylesheets')) app.use('/appstore', require('./appifi/routes/appstore')) app.use('/server', require('./appifi/routes/server')) diff --git a/src/appifi/routes/stylesheets.js b/src/appifi/routes/stylesheets.js new file mode 100644 index 00000000..1fd016d0 --- /dev/null +++ b/src/appifi/routes/stylesheets.js @@ -0,0 +1,55 @@ +import express from 'express' + +import assets from '../../../assets' + +const router = express.Router() + +router.get('/style.css', (req, res) => { + res + .set('Content-Type', 'text/css') + .send(assets.styleCSS) +}) + +router.get('/roboto.css', (req, res) => { + res + .set('Content-Type', 'text/css') + .send(assets.robotoCSS) +}) + +router.get('/Roboto-Thin-webfont.woff', (req, res) => { + res + .set('Content-Type', 'application/font-woff') + .send(assets.robotoThin) +}) + +router.get('/Roboto-Light-webfont.woff', (req, res) => { + res + .set('Content-Type', 'application/font-woff') + .send(assets.robotoLight) +}) + +router.get('/Roboto-Regular-webfont.woff', (req, res) => { + res + .set('Content-Type', 'application/font-woff') + .send(assets.robotoRegular) +}) + +router.get('/Roboto-Medium-webfont.woff', (req, res) => { + res + .set('Content-Type', 'application/font-woff') + .send(assets.robotoMedium) +}) + +router.get('/Roboto-Bold-webfont.woff', (req, res) => { + res + .set('Content-Type', 'application/font-woff') + .send(assets.robotoBold) +}) + +router.get('/Roboto-Black-webfont.woff', (req, res) => { + res + .set('Content-Type', 'application/font-woff') + .send(assets.robotoBlack) +}) + +module.exports = router diff --git a/src/fruitmix/lib/xstat.js b/src/fruitmix/lib/xstat.js index 33dbef41..98ec41d9 100644 --- a/src/fruitmix/lib/xstat.js +++ b/src/fruitmix/lib/xstat.js @@ -1,6 +1,7 @@ import fs from 'fs' import Promise from 'bluebird' -import xattr from 'fs-xattr' +console.log('xstat import fs-xattr') +const xattr = require('fs-xattr') import UUID from 'node-uuid' import validator from 'validator' import shallowequal from 'shallowequal' diff --git a/src/fruitmix/routes/users.js b/src/fruitmix/routes/users.js index 97e6f9f4..725f492a 100644 --- a/src/fruitmix/routes/users.js +++ b/src/fruitmix/routes/users.js @@ -4,7 +4,6 @@ const auth = require('../middleware/auth').default const uuid = require('node-uuid') var url = require('url') var spawnSync = require('child_process').spawnSync -var xattr = require('fs-xattr') router.get('/', auth.jwt(), (req, res) => { diff --git a/src/fruitmix/util/async.js b/src/fruitmix/util/async.js index 9c73d644..493da847 100644 --- a/src/fruitmix/util/async.js +++ b/src/fruitmix/util/async.js @@ -3,7 +3,9 @@ import Promise from 'bluebird' import mkdirp from 'mkdirp' import rimraf from 'rimraf' import fs from 'fs' -import xattr from 'fs-xattr' + +console.log('async require fs-xattr') +const xattr = require('fs-xattr') Promise.promisifyAll(fs) Promise.promisifyAll(xattr)