Migrated to Fusebox

This commit is contained in:
NGPixel 2017-03-26 22:07:40 -04:00
parent d4e0b74975
commit 5189ec3835
21 changed files with 59663 additions and 217 deletions

15
.deployexclude Normal file
View File

@ -0,0 +1,15 @@
client/js
client/scss
coverage
data
logs
node_modules
npm
repo
test
.*
*.log
*.tar.gz
*.zip
config.yml
fuse.js

7
.eslintignore Normal file
View File

@ -0,0 +1,7 @@
**/node_modules/**
**/*.min.js
assets/**
coverage/**
repo/**
data/**
logs/**

View File

@ -1,23 +1,12 @@
{
"parserOptions": {
"ecmaVersion": 8,
"ecmaFeatures": {
"experimentalObjectRestSpread": true,
"jsx": true
},
"sourceType": "module"
},
"extends": "standard",
"env": {
"node": true,
"es6": true,
"node": true
"jest": true
},
"plugins": [
"standard",
"promise"
],
"globals": {
"document": false,
"navigator": false,
@ -41,134 +30,5 @@
"ROOTPATH": true,
"IS_DEBUG": true,
"PROCNAME": true
},
"rules": {
"accessor-pairs": 2,
"arrow-spacing": [2, { "before": true, "after": true }],
"block-spacing": [2, "always"],
"brace-style": [2, "1tbs", { "allowSingleLine": true }],
"camelcase": [2, { "properties": "never" }],
"comma-dangle": [2, "never"],
"comma-spacing": [2, { "before": false, "after": true }],
"comma-style": [2, "last"],
"constructor-super": 2,
"curly": [2, "multi-line"],
"dot-location": [2, "property"],
"eol-last": 2,
"eqeqeq": [2, "always", {"null": "ignore"}],
"func-call-spacing": [2, "never"],
"handle-callback-err": [2, "^(err|error)$" ],
"indent": [2, 2, { "SwitchCase": 1 }],
"key-spacing": [2, { "beforeColon": false, "afterColon": true }],
"keyword-spacing": [2, { "before": true, "after": true }],
"new-cap": [2, { "newIsCap": true, "capIsNew": false }],
"new-parens": 2,
"no-array-constructor": 2,
"no-caller": 2,
"no-class-assign": 2,
"no-cond-assign": 2,
"no-const-assign": 2,
"no-constant-condition": [2, { "checkLoops": false }],
"no-control-regex": 2,
"no-debugger": 2,
"no-delete-var": 2,
"no-dupe-args": 2,
"no-dupe-class-members": 2,
"no-dupe-keys": 2,
"no-duplicate-case": 2,
"no-duplicate-imports": 2,
"no-empty-character-class": 2,
"no-empty-pattern": 2,
"no-eval": 2,
"no-ex-assign": 2,
"no-extend-native": 2,
"no-extra-bind": 2,
"no-extra-boolean-cast": 2,
"no-extra-parens": [2, "functions"],
"no-fallthrough": 2,
"no-floating-decimal": 2,
"no-func-assign": 2,
"no-global-assign": 2,
"no-implied-eval": 2,
"no-inner-declarations": [2, "functions"],
"no-invalid-regexp": 2,
"no-irregular-whitespace": 2,
"no-iterator": 2,
"no-label-var": 2,
"no-labels": [2, { "allowLoop": false, "allowSwitch": false }],
"no-lone-blocks": 2,
"no-mixed-spaces-and-tabs": 2,
"no-multi-spaces": 2,
"no-multi-str": 2,
"no-multiple-empty-lines": [2, { "max": 1 }],
"no-negated-in-lhs": 2,
"no-new": 2,
"no-new-func": 2,
"no-new-object": 2,
"no-new-require": 2,
"no-new-symbol": 2,
"no-new-wrappers": 2,
"no-obj-calls": 2,
"no-octal": 2,
"no-octal-escape": 2,
"no-path-concat": 2,
"no-proto": 2,
"no-redeclare": 2,
"no-regex-spaces": 2,
"no-return-assign": [2, "except-parens"],
"no-self-assign": 2,
"no-self-compare": 2,
"no-sequences": 2,
"no-shadow-restricted-names": 2,
"no-sparse-arrays": 2,
"no-tabs": 2,
"no-template-curly-in-string": 2,
"no-this-before-super": 2,
"no-throw-literal": 2,
"no-trailing-spaces": 2,
"no-undef": 2,
"no-undef-init": 2,
"no-unexpected-multiline": 2,
"no-unmodified-loop-condition": 2,
"no-unneeded-ternary": [2, { "defaultAssignment": false }],
"no-unreachable": 2,
"no-unsafe-finally": 2,
"no-unsafe-negation": 2,
"no-unused-vars": [2, { "vars": "all", "args": "none" }],
"no-useless-call": 2,
"no-useless-computed-key": 2,
"no-useless-constructor": 2,
"no-useless-escape": 2,
"no-useless-rename": 2,
"no-whitespace-before-property": 2,
"no-with": 2,
"object-property-newline": [2, { "allowMultiplePropertiesPerLine": true }],
"one-var": [2, { "initialized": "never" }],
"operator-linebreak": [2, "after", { "overrides": { "?": "before", ":": "before" } }],
"padded-blocks": [2, "never"],
"quotes": [2, "single", { "avoidEscape": true, "allowTemplateLiterals": true }],
"rest-spread-spacing": [2, "never"],
"semi": [2, "never"],
"semi-spacing": [2, { "before": false, "after": true }],
"space-before-blocks": [2, "always"],
"space-before-function-paren": [2, "always"],
"space-in-parens": [2, "never"],
"space-infix-ops": 2,
"space-unary-ops": [2, { "words": true, "nonwords": false }],
"spaced-comment": [2, "always", { "line": { "markers": ["*package", "!", ","] }, "block": { "balanced": true, "markers": ["*package", "!", ","], "exceptions": ["*"] } }],
"template-curly-spacing": [2, "never"],
"unicode-bom": [2, "never"],
"use-isnan": 2,
"valid-typeof": 2,
"wrap-iife": [2, "any", { "functionPrototypeMethods": true }],
"yield-star-spacing": [2, "both"],
"yoda": [2, "never"],
"standard/object-curly-even-spacing": [2, "either"],
"standard/array-bracket-even-spacing": [2, "either"],
"standard/computed-property-even-spacing": [2, "even"],
"promise/param-names": 2
}
}

4
.gitignore vendored
View File

@ -41,8 +41,8 @@ jspm_packages
# Optional REPL history
.node_repl_history
# SublimeText Files
*.sublime-workspace
# Fusebox
.fusebox
# Config Files
config.yml

View File

@ -2,7 +2,7 @@ language: node_js
node_js:
- '7'
- '6'
#- '4'
- '4'
addons:
apt:
sources:
@ -18,20 +18,20 @@ cache:
directories:
- node_modules
before_script:
- npm run build
- npm install -g snyk
- snyk auth $SNYK_TOKEN
before_deploy:
- npm install github:requarks/core -f
- npm install -g gulp
- gulp deploy
- tar -czf wiki-js.tar.gz * -X='.deployexclude'
- zip -R -q 'wiki-js' -x@.deployexclude
- snyk monitor
deploy:
provider: releases
api_key:
secure: TyasQ2QnWQoBhsiwm88oHoeJ+PWBZnbWEJwu6JdN5HA9cXqIdHqd1msCh84gGtKRfL2EObw4AvDwLSEd5mIM0cmQfTiokYbmb7OSjOq880rbZwtXt9t9KkC5b+TIxkhJzkzi7vIpssTeNkVJBbo/R3m0suaCRqzypkW5mhVcsFhhZ8oVCZnI1uZAXCwFNMcFFUAHxWYE98tW5bfxknRU1NJFcXysN8VXskIZ82wQQBAzZ1aQgVyMl6Uw2hns399hxCx8gVKWOIdbpO1bliHBMdm5z+lR5i723IQnHpYJf4gWvPf3oHnSS1ocrJeWVoBqanC5Iu3QhwOvPLPw/AUcJOqhvS/QiGZ2AuA9GwtBpYNVYYGD9RqcODBKZy0fWluwCuVNNoQHmwMWVP7lRnwP+SNtLzzV5ZC8mrjb4B9KGoBUR8Q7lz8cMtLoPOixk1WdWOpIFzKcw/fy8Ze6cnnFKrzsPVUZy3E3SKit3GuP6Nd7ghO0Kxp4x0eAlqFDYRZ9nG55ctd0i2b5u1r+VArt21dk2aMFxL6i67funIraEndLQFHhRgPVmjemJBRXf8j8OYrGStTsm0S26IXo3iVh/NJakIg6mEFJ3j4BXPEjCUmIW0iD6sKGTeNH6jaON+DV4T+ErGnYzgwO5KIfo9cI00DqjG0tjBQ45lWaLGy6PEo=
file:
- dist/wiki-js.zip
- dist/wiki-js.tar.gz
- wiki-js.zip
- wiki-js.tar.gz
skip_cleanup: true
overwrite: true
on:

59306
assets/js/bundle.min.js vendored Normal file

File diff suppressed because one or more lines are too long

20
client/index.js Normal file
View File

@ -0,0 +1,20 @@
'use strict'
let logic = document.documentElement.dataset.logic
switch (logic) {
case 'login':
require('./scss/login.scss')
require('./js/login.js')
break
case 'configure':
require('./scss/configure.scss')
require('./js/configure.js')
break
default:
require('./node_modules/highlight.js/styles/tomorrow.css')
require('./node_modules/simplemde/dist/simplemde.min.css')
require('./scss/app.scss')
require('./js/app.js')
break
}

View File

@ -1,6 +1,12 @@
'use strict'
/* global jQuery, _, io, Sticky, alertsData, Alerts */
/* global alertsData */
import jQuery from 'jquery'
import _ from 'lodash'
import Sticky from 'sticky-js'
import io from 'socket.io-client'
import Alerts from './components/alerts.js'
/* eslint-disable spaced-comment */
jQuery(document).ready(function ($) {

View File

@ -1,11 +1,12 @@
'use strict'
/* global Vue, _ */
import Vue from 'vue'
import _ from 'lodash'
/**
* Alerts
*/
class Alerts { // eslint-disable-line no-unused-vars
class Alerts {
/**
* Constructor
*
@ -107,3 +108,5 @@ class Alerts { // eslint-disable-line no-unused-vars
}
}
}
export default Alerts

View File

@ -1,6 +1,10 @@
'use strict'
/* global jQuery, _, Vue, VeeValidate, axios */
import jQuery from 'jquery'
import _ from 'lodash'
import Vue from 'vue'
import VeeValidate from 'vee-validate'
import axios from 'axios'
Vue.use(VeeValidate, {
enableAutoClasses: true,

View File

@ -1,6 +1,6 @@
'use strict'
/* global jQuery */
import jQuery from 'jquery'
jQuery(document).ready(function ($) {
$('#login-user').focus()

View File

@ -26,4 +26,4 @@ $primary: 'indigo';
//@import './layout/_content';
//@import './pages/_account';
@import './pages/_welcome';
@import './pages/_welcome';

127
fuse.js Normal file
View File

@ -0,0 +1,127 @@
'use strict'
/**
* FUSEBOX
*
* Client & Server compiler / watcher
*/
const fsbx = require('fuse-box')
const colors = require('colors/safe')
const _ = require('lodash')
// Parse cmd arguments
const args = require('yargs')
.option('d', {
alias: 'dev',
describe: 'Start in Developer mode',
type: 'boolean'
})
.option('c', {
alias: 'configure',
describe: 'Use Configure mode',
type: 'boolean',
implies: 'd'
})
.help('h')
.alias('h', 'help')
.argv
if (args.d) {
// =============================================
// DEVELOPER MODE
// =============================================
console.info(colors.bgWhite.black(' Starting Fuse in DEVELOPER mode... '))
const nodemon = require('nodemon')
// Client
const fuse = fsbx.FuseBox.init({
homeDir: './client',
outFile: './assets/js/bundle.min.js',
alias: {
vue: 'vue/dist/vue.js'
},
plugins: [
[ fsbx.SassPlugin({ includePaths: ['../core'] }), fsbx.CSSPlugin() ],
fsbx.BabelPlugin({ comments: false, presets: ['es2015'] }),
fsbx.JSONPlugin()
],
debug: false,
log: true
})
fuse.devServer('>index.js', {
port: 4444,
httpServer: false
})
// Server
_.delay(() => {
if (args.c) {
nodemon({
exec: 'node wiki configure',
ignore: ['assets/', 'client/', 'data/', 'repo/', 'tests/'],
ext: 'js json',
watch: [
'configure.js'
],
env: { 'NODE_ENV': 'development' }
})
} else {
nodemon({
script: './server.js',
args: [],
ignore: ['assets/', 'client/', 'data/', 'repo/', 'tests/'],
ext: 'js json',
watch: [
'controllers',
'libs',
'locales',
'middlewares',
'models',
'agent.js',
'server.js'
],
env: { 'NODE_ENV': 'development' }
})
}
}, 1000)
} else {
// =============================================
// BUILD MODE
// =============================================
console.info(colors.bgWhite.black(' Starting Fuse in BUILD mode... '))
const fuse = fsbx.FuseBox.init({
homeDir: './client',
outFile: './assets/js/bundle.min.js',
plugins: [
[ fsbx.SassPlugin({ outputStyle: 'compressed', includePaths: ['./node_modules/requarks-core'] }), fsbx.CSSPlugin() ],
fsbx.BabelPlugin({
config: {
comments: false,
presets: ['es2015']
}
}),
fsbx.JSONPlugin(),
fsbx.UglifyJSPlugin({
compress: { unused: false }
})
],
debug: false,
log: true
})
fuse.bundle('>index.js').then(() => {
console.info(colors.green.bold('Assets compilation + bundling completed.'))
}).catch(err => {
console.error(colors.green.red(' X Bundle compilation failed! ' + err.message))
process.exit(1)
})
}

View File

@ -25,21 +25,21 @@ const paths = {
scripts: {
combine: [
'./node_modules/socket.io-client/dist/socket.io.min.js',
'./node_modules/jquery/dist/jquery.min.js',
'./node_modules/jquery/dist/jquery.min.js', // done
'./node_modules/vue/dist/vue.min.js',
'./node_modules/vee-validate/dist/vee-validate.min.js',
'./node_modules/axios/dist/axios.min.js',
'./node_modules/jquery-smooth-scroll/jquery.smooth-scroll.min.js',
'./node_modules/jquery-simple-upload/simpleUpload.min.js',
'./node_modules/jquery-contextmenu/dist/jquery.contextMenu.min.js',
'./node_modules/sticky-js/dist/sticky.min.js',
'./node_modules/sticky-js/dist/sticky.min.js', // done
'./node_modules/simplemde/dist/simplemde.min.js',
'./node_modules/ace-builds/src-min-noconflict/ace.js',
'./node_modules/ace-builds/src-min-noconflict/ext-modelist.js',
'./node_modules/ace-builds/src-min-noconflict/mode-markdown.js',
'./node_modules/ace-builds/src-min-noconflict/theme-tomorrow_night.js',
'./node_modules/filesize.js/dist/filesize.min.js',
'./node_modules/lodash/lodash.min.js'
'./node_modules/lodash/lodash.min.js' // done
],
ace: [
'./node_modules/ace-builds/src-min-noconflict/mode-*.js',

View File

@ -6,11 +6,17 @@
"scripts": {
"start": "node wiki start",
"stop": "node wiki stop",
"dev": "gulp dev",
"test": "snyk test && standard && pug-lint ./views",
"build": "node fuse",
"dev": "node fuse -d",
"dev-configure": "node fuse -d -c",
"test": "jest",
"snyk-protect": "snyk protect",
"__prepublish": "npm run snyk-protect"
"__prepublish": "npm run snyk-protect",
"pre-commit": "npm run test"
},
"pre-commit": [
"pre-commit"
],
"bin": {
"wiki": "wiki.js"
},
@ -114,37 +120,26 @@
},
"devDependencies": {
"ace-builds": "^1.2.6",
"babel-cli": "^6.24.0",
"babel-jest": "^19.0.0",
"babel-preset-es2015": "^6.24.0",
"chai": "^3.5.0",
"chai-as-promised": "^6.0.0",
"codacy-coverage": "^2.0.0",
"colors": "^1.1.2",
"eslint": "^3.18.0",
"eslint-config-standard": "^7.1.0",
"eslint-plugin-import": "^2.2.0",
"eslint-plugin-node": "^4.2.1",
"eslint-plugin-promise": "^3.5.0",
"eslint-plugin-standard": "^2.1.1",
"gulp": "^3.9.1",
"gulp-babel": "^6.1.2",
"gulp-clean-css": "^3.0.4",
"gulp-concat": "^2.6.1",
"gulp-gzip": "^1.4.0",
"gulp-include": "^2.3.1",
"gulp-nodemon": "^2.2.1",
"gulp-plumber": "^1.1.0",
"gulp-sass": "^3.0.0",
"gulp-tar": "^1.9.0",
"gulp-uglify": "^2.1.2",
"gulp-watch": "^4.3.11",
"gulp-zip": "^4.0.0",
"istanbul": "^0.4.5",
"fuse-box": "^1.3.128",
"jest": "^19.0.2",
"jquery": "^3.2.1",
"jquery-contextmenu": "^2.4.4",
"jquery-simple-upload": "^1.0.0",
"jquery-smooth-scroll": "^2.0.0",
"merge-stream": "^1.0.1",
"mocha": "^3.2.0",
"mocha-lcov-reporter": "^1.3.0",
"node-sass": "^4.5.1",
"nodemon": "^1.11.0",
"pre-commit": "^1.2.2",
"pug-lint": "^2.4.0",
"run-sequence": "^1.2.2",
"snyk": "^1.25.1",
"standard": "^9.0.2",
"sticky-js": "^1.1.9",
@ -172,14 +167,19 @@
"CORE_PATH",
"ROOTPATH",
"IS_DEBUG",
"PROCNAME"
],
"ignore": [
"assets/**/*",
"data/**/*",
"node_modules/**/*",
"repo/**/*"
"PROCNAME",
"describe",
"it",
"expect"
]
},
"jest": {
"collectCoverage": false,
"testMatch": [
"**/test/**/*.js?(x)",
"**/?(*.)(spec|test).js?(x)"
],
"verbose": true
},
"snyk": true
}

View File

@ -1,3 +0,0 @@
'use strict'
// TODO

77
test/lint.js Normal file
View File

@ -0,0 +1,77 @@
'use strict'
const fs = require('fs-extra')
const colors = require('colors')
expect.extend({
/**
* Expect ESLint results to have no errors
* @param {*} received ESLint results
* @param {*} argument Arguments
* @returns {object} Matcher result
*/
toESLint (received, argument) {
if (received && received.errorCount > 0) {
let errorMsgBuf = []
for (let i = 0; i < received.results.length; i++) {
const result = received.results[i]
if (result.errorCount <= 0) {
continue
}
for (let x = 0; x < result.messages.length; x++) {
const m = result.messages[x]
errorMsgBuf.push(colors.grey(`└── ${result.filePath}\t${m.line}:${m.column}\t${m.message}`))
}
}
if (errorMsgBuf.length > 0) {
return {
message: () => (errorMsgBuf.join(`\n`)),
pass: false
}
}
}
return {
pass: true
}
},
/**
* Expect PugLint results to have no errors
* @param {*} received PugLint results
* @param {*} argument Arguments
* @returns {object} Matcher result
*/
toPugLint (received, argument) {
if (received && received.length > 0) {
let errorMsgBuf = []
for (let i = 0; i < received.length; i++) {
errorMsgBuf.push(colors.grey(`└── ${received[i].message}`))
}
return {
message: () => (errorMsgBuf.join(`\n`)),
pass: false
}
}
return {
pass: true
}
}
})
describe('Code Linting', () => {
it('should pass ESLint validation', () => {
const CLIEngine = require('eslint').CLIEngine
const cli = new CLIEngine()
let report = cli.executeOnFiles(['**/*.js'])
expect(report).toESLint()
})
it('should pass PugLint validation', () => {
const PugLint = require('pug-lint')
const lint = new PugLint()
const pugConfig = fs.readJsonSync('.pug-lintrc.json')
lint.configure(pugConfig)
let report = lint.checkPath('./views')
expect(report).toPugLint()
})
})

39
test/security.js Normal file
View File

@ -0,0 +1,39 @@
'use strict'
const colors = require('colors')
expect.extend({
/**
* Expect Snyk results to have no errors
* @param {*} received Snyk results
* @param {*} argument Arguments
* @returns {object} Matcher result
*/
toPassSnyk (received, argument) {
if (received && received.ok === false) {
let errorMsgBuf = []
for (let i = 0; i < received.vulnerabilities.length; i++) {
const result = received.vulnerabilities[i]
let vulnPath = result.from.slice(1).join(' > ')
errorMsgBuf.push(colors.red(`└──[${result.severity}] ${result.packageName}\t${result.title}`))
errorMsgBuf.push(colors.grey(`\t${vulnPath}`))
}
return {
message: () => (errorMsgBuf.join(`\n`)),
pass: false
}
}
return {
pass: true
}
}
})
describe('Security', () => {
it('should pass Snyk test', () => {
const snyk = require('snyk').test
return snyk('./').then(report => {
expect(report).toPassSnyk()
})
}, 20000)
})

View File

@ -1,5 +1,5 @@
doctype html
html
html(data-logic='login')
head
meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(charset='UTF-8')
@ -17,13 +17,8 @@ html
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
link(rel='manifest', href='/manifest.json')
// CSS
link(type='text/css', rel='stylesheet', href='/css/libs.css')
link(type='text/css', rel='stylesheet', href='/css/login.css')
// JS
script(type='text/javascript', src='/js/libs.js')
script(type='text/javascript', src='/js/login.js')
// JS / CSS
script(type='text/javascript', src='/js/bundle.min.js')
body
#bg

View File

@ -1,5 +1,5 @@
doctype html
html
html(data-logic='configure')
head
meta(http-equiv='X-UA-Compatible', content='IE=edge')
meta(charset='UTF-8')
@ -9,13 +9,8 @@ html
each favsize in [32, 96, 16]
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
// CSS
link(type='text/css', rel='stylesheet', href='/css/libs.css')
link(type='text/css', rel='stylesheet', href='/css/configure.css')
// JS
script(type='text/javascript', src='/js/libs.js')
script(type='text/javascript', src='/js/configure.js')
// JS / CSS
script(type='text/javascript', src='/js/bundle.min.js')
block head

View File

@ -17,13 +17,8 @@ html
link(rel='icon', type='image/png', sizes=favsize + 'x' + favsize, href='/favicons/favicon-' + favsize + 'x' + favsize + '.png')
link(rel='manifest', href='/manifest.json')
// CSS
link(type='text/css', rel='stylesheet', href='/css/libs.css')
link(type='text/css', rel='stylesheet', href='/css/app.css')
// JS
script(type='text/javascript', src='/js/libs.js')
script(type='text/javascript', src='/js/app.js')
// JS / CSS
script(type='text/javascript', src='/js/bundle.min.js')
block head