Merge branch 'dev' of https://gitea.verdnatura.es/verdnatura/salix into dev
This commit is contained in:
commit
7333cb4114
|
@ -1,4 +1,3 @@
|
|||
node_modules
|
||||
front
|
||||
services
|
||||
!services/nginx
|
||||
front/node_modules
|
||||
services
|
|
@ -4,4 +4,5 @@ npm-debug.log
|
|||
.eslintcache
|
||||
datasources.*.json
|
||||
print.*.json
|
||||
db.json
|
||||
db.json
|
||||
junitresults.xml
|
|
@ -25,10 +25,8 @@ RUN npm install --only=prod
|
|||
COPY loopback loopback
|
||||
COPY back back
|
||||
COPY modules modules
|
||||
COPY dist/webpack-assets.json dist/
|
||||
COPY print print
|
||||
COPY \
|
||||
modules.yml \
|
||||
LICENSE \
|
||||
README.md \
|
||||
./
|
||||
|
|
|
@ -45,9 +45,6 @@ pipeline {
|
|||
}
|
||||
}
|
||||
stage('Build') {
|
||||
environment {
|
||||
CREDS = credentials('docker-registry')
|
||||
}
|
||||
steps {
|
||||
nodejs('node-lts') {
|
||||
withEnv(['NODE_ENV=']) {
|
||||
|
@ -56,6 +53,29 @@ pipeline {
|
|||
}
|
||||
sh 'gulp build'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Test') {
|
||||
environment {
|
||||
NODE_ENV = ""
|
||||
FIREFOX_BIN = "/opt/firefox/firefox-bin"
|
||||
}
|
||||
steps {
|
||||
nodejs('node-lts') {
|
||||
sh 'karma start --junit'
|
||||
|
||||
// FIXME: Docker isn't at localhost
|
||||
// sh 'gulp docker'
|
||||
// sh 'gulp backendUnitTest --junit'
|
||||
// sh 'docker rm -f salix-db'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Docker') {
|
||||
environment {
|
||||
CREDS = credentials('docker-registry')
|
||||
}
|
||||
steps {
|
||||
sh 'docker login --username $CREDS_USR --password $CREDS_PSW $REGISTRY'
|
||||
sh 'docker-compose build --parallel'
|
||||
sh 'docker-compose push'
|
||||
|
@ -98,6 +118,7 @@ pipeline {
|
|||
}
|
||||
post {
|
||||
always {
|
||||
junit '*/junit.xml'
|
||||
script {
|
||||
if (!env.GIT_COMMITTER_EMAIL) return
|
||||
try {
|
||||
|
|
|
@ -17,13 +17,10 @@ let SpecReporter = require('jasmine-spec-reporter').SpecReporter;
|
|||
|
||||
let serviceSpecs = [
|
||||
`${__dirname}/**/*[sS]pec.js`,
|
||||
`${__dirname}/../loopback/**/*[sS]pec.js`
|
||||
`${__dirname}/../loopback/**/*[sS]pec.js`,
|
||||
`${__dirname}/../modules/*/back/**/*.[sS]pec.js`
|
||||
];
|
||||
|
||||
let services = require(`../modules.yml`);
|
||||
for (let service of services)
|
||||
serviceSpecs.push(`${__dirname}/../modules/${service}/back/**/*[sS]pec.js`);
|
||||
|
||||
jasmine.loadConfig({
|
||||
spec_dir: '.',
|
||||
spec_files: serviceSpecs,
|
||||
|
|
|
@ -5,7 +5,7 @@ services:
|
|||
restart: unless-stopped
|
||||
build:
|
||||
context: .
|
||||
dockerfile: services/nginx/Dockerfile
|
||||
dockerfile: front/Dockerfile
|
||||
ports:
|
||||
- ${PORT}:80
|
||||
links:
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* eslint no-invalid-this: "off" */
|
||||
|
||||
import config from './config.js';
|
||||
import Nightmare from 'nightmare';
|
||||
import {URL} from 'url';
|
||||
let currentUser;
|
||||
import config from './config.js';
|
||||
|
||||
let currentUser;
|
||||
|
||||
Nightmare.asyncAction = function(name, func) {
|
||||
Nightmare.action(name, function(...args) {
|
||||
|
@ -25,17 +25,42 @@ Nightmare.asyncAction('clearInput', async function(selector) {
|
|||
|
||||
let actions = {
|
||||
login: function(userName, done) {
|
||||
this.goto(`${config.url}#!/login`)
|
||||
.wait(`vn-login input[name=user]`)
|
||||
.write(`vn-login input[name=user]`, userName)
|
||||
.write(`vn-login input[name=password]`, 'nightmare')
|
||||
.click(`vn-login input[type=submit]`)
|
||||
// FIXME: Wait for dom to be ready: https://github.com/segmentio/nightmare/issues/481
|
||||
// .wait(1000)
|
||||
.then(() => {
|
||||
currentUser = userName;
|
||||
done();
|
||||
})
|
||||
if (currentUser)
|
||||
this.waitToClick('#logout');
|
||||
|
||||
let doLogin = () => {
|
||||
this.wait(`vn-login input[name=user]`)
|
||||
.write(`vn-login input[name=user]`, userName)
|
||||
.write(`vn-login input[name=password]`, 'nightmare')
|
||||
.click(`vn-login input[type=submit]`)
|
||||
.then(() => {
|
||||
currentUser = userName;
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
};
|
||||
|
||||
this.waitForURL('#!/login')
|
||||
.then(doLogin)
|
||||
.catch(() => {
|
||||
this.goto(`${config.url}/#!/login`)
|
||||
.then(doLogin)
|
||||
.catch(done);
|
||||
});
|
||||
},
|
||||
|
||||
waitForLogin: function(userName, done) {
|
||||
if (currentUser === userName) {
|
||||
return this.waitToClick('vn-topbar a[ui-sref="home"]')
|
||||
.waitForURL('#!/')
|
||||
.then(done)
|
||||
.catch(done);
|
||||
}
|
||||
return this.login(userName)
|
||||
.waitForURL('#!/')
|
||||
.url()
|
||||
.changeLanguageToEnglish()
|
||||
.then(done)
|
||||
.catch(done);
|
||||
},
|
||||
|
||||
|
@ -65,21 +90,6 @@ let actions = {
|
|||
});
|
||||
},
|
||||
|
||||
waitForLogin: function(userName, done) {
|
||||
if (currentUser === userName) {
|
||||
return this.waitToClick('vn-topbar a[ui-sref="home"]')
|
||||
.waitForURL('#!/')
|
||||
.then(done)
|
||||
.catch(done);
|
||||
}
|
||||
return this.login(userName)
|
||||
.waitForURL('#!/')
|
||||
.url()
|
||||
.changeLanguageToEnglish()
|
||||
.then(done)
|
||||
.catch(done);
|
||||
},
|
||||
|
||||
selectModule: function(moduleName, done) {
|
||||
this.waitToClick(`vn-home a[ui-sref="${moduleName}.index"]`)
|
||||
.waitForURL(moduleName)
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
/* eslint no-console: 0 */
|
||||
import Nightmare from 'nightmare';
|
||||
|
||||
let nightmare;
|
||||
|
||||
export default function createNightmare(width = 1280, height = 720) {
|
||||
|
@ -22,7 +23,6 @@ export default function createNightmare(width = 1280, height = 720) {
|
|||
});
|
||||
|
||||
nightmare.header('Accept-Language', 'en');
|
||||
|
||||
return nightmare;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ RUN apt-get update \
|
|||
&& ln -sf /dev/stderr /var/log/nginx/error.log
|
||||
|
||||
WORKDIR /etc/nginx
|
||||
COPY services/nginx/temp/nginx.conf sites-available/salix
|
||||
COPY front/nginx.conf sites-available/salix
|
||||
RUN rm sites-enabled/default && ln -s ../sites-available/salix sites-enabled/salix
|
||||
|
||||
COPY dist /salix/dist
|
|
@ -3,7 +3,6 @@ import './crud';
|
|||
import './acl-service';
|
||||
import './storage-services';
|
||||
import './template';
|
||||
import './spliting-register';
|
||||
import './interpolate';
|
||||
import './copy';
|
||||
import './equals';
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import ngModule from '../module';
|
||||
import splitingRegister from './spliting-register';
|
||||
import moduleImport from 'module-import';
|
||||
|
||||
factory.$inject = ['$http', '$window', '$ocLazyLoad', '$translatePartialLoader', '$translate', '$q'];
|
||||
export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $translate, $q) {
|
||||
|
@ -8,6 +8,10 @@ export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $t
|
|||
this._loaded = {};
|
||||
}
|
||||
load(moduleName, validations) {
|
||||
let moduleConf = $window.routes.find(i => i && i.module == moduleName);
|
||||
if (!moduleConf)
|
||||
return $q.reject(new Error(`Module not found: ${moduleName}`));
|
||||
|
||||
let loaded = this._loaded;
|
||||
|
||||
if (loaded[moduleName] === true)
|
||||
|
@ -19,8 +23,8 @@ export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $t
|
|||
|
||||
loaded[moduleName] = false;
|
||||
|
||||
let deps = splitingRegister.getDependencies(moduleName);
|
||||
let depPromises = [];
|
||||
let deps = moduleConf.dependencies;
|
||||
|
||||
if (deps) {
|
||||
for (let dep of deps)
|
||||
|
@ -48,9 +52,7 @@ export function factory($http, $window, $ocLazyLoad, $translatePartialLoader, $t
|
|||
}));
|
||||
}
|
||||
|
||||
promises.push(new Promise(resolve => {
|
||||
splitingRegister.modules[moduleName](resolve);
|
||||
}));
|
||||
promises.push(moduleImport(moduleName));
|
||||
|
||||
Promise.all(promises).then(() => {
|
||||
loaded[moduleName] = true;
|
||||
|
|
|
@ -4,9 +4,10 @@ describe('factory vnModuleLoader', () => {
|
|||
|
||||
beforeEach(ngModule('vnCore'));
|
||||
|
||||
beforeEach(angular.mock.inject((_vnModuleLoader_, $rootScope) => {
|
||||
beforeEach(angular.mock.inject((_vnModuleLoader_, $rootScope, $window) => {
|
||||
vnModuleLoader = _vnModuleLoader_;
|
||||
$scope = $rootScope;
|
||||
$window.routes = [{module: 'myModule'}];
|
||||
}));
|
||||
|
||||
describe('load()', () => {
|
||||
|
|
|
@ -1,12 +0,0 @@
|
|||
|
||||
class SplitingRegister {
|
||||
constructor() {
|
||||
this.graph = null;
|
||||
this.modules = {};
|
||||
}
|
||||
getDependencies(moduleName) {
|
||||
return this.graph[moduleName];
|
||||
}
|
||||
}
|
||||
|
||||
export default new SplitingRegister();
|
|
@ -7,7 +7,7 @@ config.$inject = ['$translateProvider', '$translatePartialLoaderProvider'];
|
|||
export function config($translateProvider, $translatePartialLoaderProvider) {
|
||||
$translatePartialLoaderProvider.addPart('core');
|
||||
|
||||
let conf = {urlTemplate: '/static/locale/{part}/{lang}.json'};
|
||||
let conf = {urlTemplate: '/locale/{part}/{lang}.json'};
|
||||
|
||||
let fallbackLang = 'es';
|
||||
let langs = ['en', 'es'];
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
export default function moduleImport(moduleName) {
|
||||
return import(
|
||||
/* webpackInclude: /modules\/[a-z0-9-]+\/front\/index.js$/ */
|
||||
`../modules/${moduleName}/front/index.js`
|
||||
);
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
auth: []
|
||||
client: []
|
||||
core: []
|
||||
item: [client]
|
||||
salix: []
|
||||
ticket: [item, client]
|
||||
order: [item, ticket]
|
||||
claim: [item, client]
|
||||
route: []
|
||||
agency: []
|
||||
travel: []
|
|
@ -7,19 +7,12 @@ server {
|
|||
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
{{#services}}
|
||||
location ~ ^/{{.}}(?:/(.*))?$ {
|
||||
location ~ ^(/[a-zA-Z0-9_-]+)?/(?<path>api(/.*)?)$ {
|
||||
resolver 127.0.0.11;
|
||||
proxy_pass http://api:{{defaultPort}}/$1$is_args$args;
|
||||
proxy_pass http://api:3000/$path$is_args$args;
|
||||
}
|
||||
{{/services}}
|
||||
|
||||
location ~ ^/static(?:/(.*))?$ {
|
||||
location ~ ^(?:/(.*))?$ {
|
||||
alias /salix/dist/$1;
|
||||
autoindex on;
|
||||
}
|
||||
location ~ ^(?:/(.*))?$ {
|
||||
resolver 127.0.0.11;
|
||||
proxy_pass http://api:{{defaultPort}}/$1$is_args$args;
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
<ul ng-if="::$ctrl.items.length > 0" pad-medium-v>
|
||||
<li ng-repeat="item in ::$ctrl.items" name="{{::item.description}}">
|
||||
<a ui-sref="{{::item.state}}" ng-class="{active: item.childs.length == 0 && item.active, expanded: item.active, collapsed: !item.active}"
|
||||
<a ui-sref="{{::item.state}}"
|
||||
ng-class="{active: item.active && !item.childs, expanded: item.active, collapsed: !item.active}"
|
||||
ng-click="$ctrl.setActive(item)">
|
||||
<vn-icon icon="{{::item.icon}}" ng-if="::item.icon"></vn-icon>
|
||||
<vn-icon icon="keyboard_arrow_down" ng-if="::item.childs.length > 0"></vn-icon>
|
||||
|
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
@ -5,7 +5,6 @@
|
|||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=no"/>
|
||||
<meta name="mobile-web-app-capable" content="yes"/>
|
||||
<title vn-title translate></title>
|
||||
<script src="/acl"></script>
|
||||
</head>
|
||||
<body>
|
||||
<vn-app></vn-app>
|
||||
|
|
|
@ -106,7 +106,7 @@ function $exceptionHandler(vnApp, $window, $state, $injector) {
|
|||
if (data && data.error instanceof Object)
|
||||
message = data.error.message;
|
||||
else
|
||||
message = `${exception.status}: ${exception.statusText}`;
|
||||
message = exception.statusText;
|
||||
}
|
||||
} else if (exception.name == 'UserError')
|
||||
messageT = exception.message;
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
import ngModule from './module';
|
||||
import deps from 'modules.yml';
|
||||
import modules from 'spliting';
|
||||
import splitingRegister from 'core/lib/spliting-register';
|
||||
import getMainRoute from 'core/lib/get-main-route';
|
||||
|
||||
function loader(moduleName, validations) {
|
||||
|
@ -14,9 +11,6 @@ function loader(moduleName, validations) {
|
|||
|
||||
config.$inject = ['$stateProvider', '$urlRouterProvider'];
|
||||
function config($stateProvider, $urlRouterProvider) {
|
||||
splitingRegister.graph = deps;
|
||||
splitingRegister.modules = modules;
|
||||
|
||||
$urlRouterProvider.otherwise('/');
|
||||
|
||||
$stateProvider.state('home', {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import './responsive.scss';
|
||||
import './title.scss';
|
||||
import './layout.scss';
|
||||
import './display.scss';
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
/* Desktop - Laptop 1360x768 */
|
||||
@media (max-resolution: 119dpi) and (min-device-width: 1340px) and (max-device-width: 1899px)
|
||||
{
|
||||
body { font-size: 10pt; }
|
||||
}
|
||||
|
||||
/* Mobile - Low DPI */
|
||||
@media
|
||||
(min-resolution: 120dpi),
|
||||
(-webkit-min-device-pixel-ratio: 1.5)
|
||||
{
|
||||
body { font-size: 9pt; }
|
||||
}
|
||||
@media
|
||||
(min-resolution: 144dpi),
|
||||
(-webkit-min-device-pixel-ratio: 1.5)
|
||||
{
|
||||
body { font-size: 11pt; }
|
||||
}
|
||||
|
||||
/* Mobile - Normal DPI */
|
||||
@media
|
||||
(max-device-width: 383px) and (min-resolution: 192dpi),
|
||||
(max-device-width: 383px) and (-webkit-min-device-pixel-ratio: 2)
|
||||
{
|
||||
body { font-size: 10pt; }
|
||||
}
|
||||
@media
|
||||
(min-device-width: 384px) and (min-resolution: 192dpi),
|
||||
(min-device-width: 384px) and (-webkit-min-device-pixel-ratio: 2)
|
||||
{
|
||||
body { font-size: 11pt; }
|
||||
}
|
||||
|
||||
/* Mobile - High DPI */
|
||||
@media
|
||||
(max-device-width: 411px) and (min-resolution: 249dpi),
|
||||
(max-device-width: 411px) and (-webkit-min-device-pixel-ratio: 3)
|
||||
{
|
||||
body { font-size: 10pt; }
|
||||
}
|
||||
@media
|
||||
(min-device-width: 412px) and (min-resolution: 249dpi),
|
||||
(min-device-width: 412px) and (-webkit-min-device-pixel-ratio: 3)
|
||||
{
|
||||
body { font-size: 11pt; }
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
export default {
|
||||
client:
|
||||
cb => require.ensure([], () => cb(require('client/front'))),
|
||||
route:
|
||||
cb => require.ensure([], () => cb(require('route/front'))),
|
||||
item:
|
||||
cb => require.ensure([], () => cb(require('item/front'))),
|
||||
ticket:
|
||||
cb => require.ensure([], () => cb(require('ticket/front'))),
|
||||
order:
|
||||
cb => require.ensure([], () => cb(require('order/front'))),
|
||||
claim:
|
||||
cb => require.ensure([], () => cb(require('claim/front'))),
|
||||
agency:
|
||||
cb => require.ensure([], () => cb(require('agency/front'))),
|
||||
travel:
|
||||
cb => require.ensure([], () => cb(require('travel/front')))
|
||||
};
|
182
gulpfile.js
182
gulpfile.js
|
@ -1,6 +1,5 @@
|
|||
require('require-yaml');
|
||||
const gulp = require('gulp');
|
||||
const fs = require('fs-extra');
|
||||
const exec = require('child_process').exec;
|
||||
const PluginError = require('plugin-error');
|
||||
const argv = require('minimist')(process.argv.slice(2));
|
||||
|
@ -13,53 +12,52 @@ let isWindows = /^win/.test(process.platform);
|
|||
if (argv.NODE_ENV)
|
||||
process.env.NODE_ENV = argv.NODE_ENV;
|
||||
|
||||
let env = process.env.NODE_ENV ? process.env.NODE_ENV : 'development';
|
||||
|
||||
let langs = ['es', 'en'];
|
||||
let srcDir = './front';
|
||||
let modulesDir = './modules';
|
||||
let servicesDir = './services';
|
||||
let modules = require('./modules.yml');
|
||||
let buildDir = 'dist';
|
||||
|
||||
let wpConfig = require('./webpack.config.yml');
|
||||
let buildDir = wpConfig.buildDir;
|
||||
let devServerPort = wpConfig.devServerPort;
|
||||
|
||||
let nginxDir = `${servicesDir}/nginx`;
|
||||
let proxyConf = require(`${nginxDir}/config.yml`);
|
||||
let proxyEnvFile = `${nginxDir}/config.${env}.yml`;
|
||||
|
||||
if (fs.existsSync(proxyEnvFile))
|
||||
Object.assign(proxyConf, require(proxyEnvFile));
|
||||
|
||||
let defaultService = proxyConf.main;
|
||||
let defaultPort = proxyConf.defaultPort;
|
||||
let backSources = [
|
||||
'loopback',
|
||||
'modules/*/back/**',
|
||||
'back'
|
||||
];
|
||||
|
||||
// Development
|
||||
|
||||
const nginx = gulp.series(nginxStart);
|
||||
nginx.description = `Starts/restarts the nginx process`;
|
||||
|
||||
const localesRoutes = gulp.parallel(locales, routes);
|
||||
localesRoutes.description = `Builds locales and routes`;
|
||||
|
||||
const front = gulp.series(buildClean, gulp.parallel(localesRoutes, watch, webpackDevServer));
|
||||
const front = gulp.series(clean, gulp.parallel(localesRoutes, watch, webpackDevServer));
|
||||
front.description = `Starts frontend service`;
|
||||
|
||||
const back = gulp.series(dockerStart, backOnly, nginx);
|
||||
function backOnly(done) {
|
||||
let app = require(`./loopback/server/server`);
|
||||
app.start();
|
||||
app.on('started', done);
|
||||
}
|
||||
backOnly.description = `Starts backend service`;
|
||||
|
||||
function backWatch(done) {
|
||||
const nodemon = require('gulp-nodemon');
|
||||
let sleepBin = isWindows ? 'timeout' : 'sleep';
|
||||
|
||||
nodemon({
|
||||
exec: `${sleepBin} 1 && node --inspect ./node_modules/gulp/bin/gulp.js`,
|
||||
args: ['backOnly'],
|
||||
watch: backSources,
|
||||
done: done
|
||||
});
|
||||
}
|
||||
backWatch.description = `Starts backend in waching mode`;
|
||||
|
||||
const back = gulp.series(dockerStart, backWatch);
|
||||
back.description = `Starts backend and database service`;
|
||||
|
||||
const defaultTask = gulp.parallel(front, back);
|
||||
defaultTask.description = `Starts all application services`;
|
||||
|
||||
function backOnly(done) {
|
||||
let app = require(`./loopback/server/server`);
|
||||
app.start(defaultPort);
|
||||
app.on('started', done);
|
||||
}
|
||||
backOnly.description = `Starts backend service`;
|
||||
|
||||
// backend tests
|
||||
// Backend tests
|
||||
|
||||
function backendUnitTest() {
|
||||
let app = require(`./loopback/server/server`);
|
||||
|
@ -98,13 +96,13 @@ function backTest(done) {
|
|||
nodemon({
|
||||
exec: gulpBin,
|
||||
args: ['dockerAndBackTest'],
|
||||
watch: ['loopback', 'modules/*/back/**', 'back'],
|
||||
watch: backSources,
|
||||
done: done
|
||||
});
|
||||
}
|
||||
backTest.description = `Watches for changes in modules to execute backTest task`;
|
||||
|
||||
// end to end tests
|
||||
// End to end tests
|
||||
|
||||
function e2eOnly() {
|
||||
const jasmine = require('gulp-jasmine');
|
||||
|
@ -130,9 +128,6 @@ smokesOnly.description = `Runs the smokes tests only`;
|
|||
smokes = gulp.series(docker, smokesOnly);
|
||||
smokes.description = `Restarts database and runs the smokes tests`;
|
||||
|
||||
const clean = gulp.parallel(buildClean, nginxClean);
|
||||
clean.description = 'Cleans all generated project files';
|
||||
|
||||
function install() {
|
||||
const install = require('gulp-install');
|
||||
const print = require('gulp-print');
|
||||
|
@ -153,17 +148,17 @@ i.description = `Alias for the 'install' task`;
|
|||
|
||||
// Deployment
|
||||
|
||||
const build = gulp.series(clean, gulp.parallel(localesRoutes, webpack, nginxConf));
|
||||
const build = gulp.series(clean, gulp.parallel(localesRoutes, webpack));
|
||||
build.description = `Generates binaries and configuration files`;
|
||||
|
||||
function buildClean() {
|
||||
function clean() {
|
||||
const del = require('del');
|
||||
const files = [
|
||||
`${buildDir}/*`
|
||||
];
|
||||
return del(files, {force: true});
|
||||
}
|
||||
buildClean.description = `Cleans all files generated by the 'build' task`;
|
||||
clean.description = `Cleans all files generated by the 'build' task`;
|
||||
|
||||
// Webpack
|
||||
|
||||
|
@ -196,12 +191,14 @@ function webpackDevServer(done) {
|
|||
|
||||
for (let entryName in wpConfig.entry) {
|
||||
let entry = wpConfig.entry[entryName];
|
||||
let wdsAssets = [`webpack-dev-server/client?http://127.0.0.1:${devServer.port}/`];
|
||||
if (Array.isArray(entry))
|
||||
wdsAssets = wdsAssets.concat(entry);
|
||||
else
|
||||
wdsAssets.push(entry);
|
||||
wpConfig.entry[entryName] = wdsAssets;
|
||||
if (!Array.isArray(entry))
|
||||
entry = [entry];
|
||||
|
||||
let wdsAssets = [
|
||||
`webpack-dev-server/client?http://localhost:${devServer.port}/`,
|
||||
`webpack/hot/dev-server`
|
||||
];
|
||||
wpConfig.entry[entryName] = wdsAssets.concat(entry);
|
||||
}
|
||||
|
||||
let compiler = webpack(wpConfig);
|
||||
|
@ -232,14 +229,16 @@ function locales() {
|
|||
const mergeJson = require('gulp-merge-json');
|
||||
const yaml = require('gulp-yaml');
|
||||
const merge = require('merge-stream');
|
||||
const fs = require('fs-extra');
|
||||
|
||||
let streams = [];
|
||||
let localePaths = [];
|
||||
|
||||
let modules = fs.readdirSync(modulesDir);
|
||||
for (let mod of modules)
|
||||
localePaths[mod] = `${modulesDir}/${mod}`;
|
||||
|
||||
let baseMods = ['core', 'auth', 'salix'];
|
||||
let baseMods = ['core', 'salix'];
|
||||
for (let mod of baseMods)
|
||||
localePaths[mod] = `${srcDir}/${mod}`;
|
||||
|
||||
|
@ -301,6 +300,8 @@ async function docker() {
|
|||
await execP(`docker build --build-arg STAMP=${stamp} -t salix-db ./services/db`);
|
||||
|
||||
let runChown = process.platform != 'linux';
|
||||
if (argv['run-chown']) runChown = true;
|
||||
|
||||
await execP(`docker run --env RUN_CHOWN=${runChown} -d --name salix-db -p 3306:3306 salix-db`);
|
||||
if (runChown) await dockerWait();
|
||||
}
|
||||
|
@ -340,7 +341,7 @@ function dockerWait() {
|
|||
|
||||
let interval = 100;
|
||||
let elapsedTime = 0;
|
||||
let maxInterval = 30 * 60 * 1000;
|
||||
let maxInterval = 5 * 60 * 1000;
|
||||
|
||||
log('Waiting for MySQL init process...');
|
||||
checker();
|
||||
|
@ -379,84 +380,6 @@ function dockerWait() {
|
|||
}
|
||||
dockerWait.description = `Waits until database service is ready`;
|
||||
|
||||
// Nginx
|
||||
|
||||
let nginxConfFile = 'temp/nginx.conf';
|
||||
let nginxTemp = `${nginxDir}/temp`;
|
||||
|
||||
async function nginxStart() {
|
||||
await nginxConf();
|
||||
let nginxBin = await nginxGetBin();
|
||||
|
||||
if (isWindows)
|
||||
nginxBin = `start /B ${nginxBin}`;
|
||||
|
||||
log(`Application available at http://${proxyConf.host}:${proxyConf.port}/`);
|
||||
await execP(`${nginxBin} -c "${nginxConfFile}" -p "${nginxDir}"`);
|
||||
}
|
||||
nginxStart.description = `Starts the nginx process`;
|
||||
|
||||
async function nginxStop() {
|
||||
try {
|
||||
let nginxBin = await nginxGetBin();
|
||||
await fs.stat(`${nginxTemp}/nginx.pid`);
|
||||
await execP(`${nginxBin} -c "${nginxConfFile}" -p "${nginxDir}" -s stop`);
|
||||
} catch (e) {}
|
||||
}
|
||||
nginxStop.description = `Stops the nginx process`;
|
||||
|
||||
/**
|
||||
* Generates the nginx configuration file. If NODE_ENV is defined and the
|
||||
* 'nginx.[environment].mst' file exists, it is used as a template, otherwise,
|
||||
* the 'nginx.mst' template file is used.
|
||||
*/
|
||||
async function nginxConf() {
|
||||
await nginxStop();
|
||||
const mustache = require('mustache');
|
||||
|
||||
if (!await fs.exists(nginxTemp))
|
||||
await fs.mkdir(nginxTemp);
|
||||
|
||||
let params = {
|
||||
services: modules,
|
||||
defaultService: defaultService,
|
||||
defaultPort: defaultPort,
|
||||
devServerPort: devServerPort,
|
||||
port: proxyConf.port,
|
||||
host: proxyConf.host
|
||||
};
|
||||
|
||||
let confFile = `${nginxDir}/nginx.${env}.mst`;
|
||||
|
||||
if (!await fs.exists(confFile))
|
||||
confFile = `${nginxDir}/nginx.mst`;
|
||||
|
||||
let template = await fs.readFile(confFile, 'utf8');
|
||||
let nginxConfData = mustache.render(template, params);
|
||||
|
||||
await fs.writeFile(`${nginxTemp}/nginx.conf`, nginxConfData);
|
||||
}
|
||||
nginxConf.description = `Generates the nginx configuration file`;
|
||||
|
||||
async function nginxClean() {
|
||||
await nginxStop();
|
||||
const del = require('del');
|
||||
return del([`${nginxTemp}/*`], {force: true});
|
||||
}
|
||||
nginxClean.description = `Cleans all files generated by nginx`;
|
||||
|
||||
async function nginxGetBin() {
|
||||
if (isWindows)
|
||||
return 'nginx';
|
||||
try {
|
||||
let nginxBin = '/usr/sbin/nginx';
|
||||
await fs.stat(nginxBin);
|
||||
return nginxBin;
|
||||
} catch (e) {
|
||||
return 'nginx';
|
||||
}
|
||||
}
|
||||
|
||||
// Helpers
|
||||
|
||||
/**
|
||||
|
@ -485,6 +408,7 @@ module.exports = {
|
|||
front,
|
||||
back,
|
||||
backOnly,
|
||||
backWatch,
|
||||
backendUnitTest,
|
||||
dockerAndBackTest,
|
||||
backTest,
|
||||
|
@ -492,16 +416,10 @@ module.exports = {
|
|||
e2e,
|
||||
smokesOnly,
|
||||
smokes,
|
||||
clean,
|
||||
install,
|
||||
i,
|
||||
build,
|
||||
buildClean,
|
||||
nginxStart,
|
||||
nginx,
|
||||
nginxStop,
|
||||
nginxConf,
|
||||
nginxClean,
|
||||
clean,
|
||||
webpack,
|
||||
webpackDevServer,
|
||||
locales,
|
||||
|
|
|
@ -79,6 +79,7 @@ module.exports = function(config) {
|
|||
'karma-webpack',
|
||||
'karma-chrome-launcher',
|
||||
'karma-firefox-launcher',
|
||||
'karma-junit-reporter',
|
||||
'karma-sourcemap-loader'
|
||||
],
|
||||
|
||||
|
@ -113,5 +114,15 @@ module.exports = function(config) {
|
|||
if (process.env.FIREFOX_BIN)
|
||||
baseConfig.browsers = ['FirefoxHeadless'];
|
||||
|
||||
if (config.junit) {
|
||||
Object.assign(baseConfig, {
|
||||
singleRun: true,
|
||||
reporters: ['dots', 'junit'],
|
||||
junitReporter: {
|
||||
outputFile: 'junit.xml'
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
config.set(baseConfig);
|
||||
};
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<!doctype html>
|
||||
<html ng-app="salix">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=no"/>
|
||||
<meta name="mobile-web-app-capable" content="yes"/>
|
||||
<title vn-title translate></title>
|
||||
</head>
|
||||
<body>
|
||||
<vn-app></vn-app>
|
||||
<script type="text/javascript"
|
||||
src="/static/routes.js?<%= version %>">
|
||||
</script>
|
||||
<% for (let jsFile of assets) { %>
|
||||
<script type="text/javascript" src="<%= jsFile %>"></script>
|
||||
<% } %>
|
||||
</body>
|
||||
</html>
|
|
@ -1,13 +1,4 @@
|
|||
module.exports = function(app) {
|
||||
let bootTimestamp = new Date().getTime();
|
||||
|
||||
app.get('/', function(req, res) {
|
||||
res.render('index.ejs', {
|
||||
assets: app.getWpAssets('salix'),
|
||||
version: bootTimestamp
|
||||
});
|
||||
});
|
||||
|
||||
// FIXME: Fix until the original can be used
|
||||
app.get('/api/modelInfo', function(req, res) {
|
||||
app.models.Schema.modelInfo({req}).then(json => {
|
||||
|
|
|
@ -1,18 +1,7 @@
|
|||
{
|
||||
"initial:before": {
|
||||
"loopback#favicon": {
|
||||
"params": "$!../favicon.ico"
|
||||
}
|
||||
},
|
||||
"initial:before": {},
|
||||
"initial": {
|
||||
"compression": {},
|
||||
"cors": {
|
||||
"params": {
|
||||
"origin": "*",
|
||||
"credentials": true,
|
||||
"maxAge": 86400
|
||||
}
|
||||
},
|
||||
"helmet#xssFilter": {},
|
||||
"helmet#frameguard": {
|
||||
"params": [
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
let cors = require('cors');
|
||||
|
||||
module.exports = function() {
|
||||
return cors({origin: true});
|
||||
};
|
|
@ -1,5 +1,4 @@
|
|||
require('require-yaml');
|
||||
const cookieParser = require('cookie-parser');
|
||||
const loopback = require('loopback');
|
||||
const boot = require('loopback-boot');
|
||||
const DataSource = require('loopback-datasource-juggler').DataSource;
|
||||
|
@ -31,12 +30,7 @@ let rootDir = __dirname;
|
|||
let lbDir = path.resolve(`${rootDir}/..`);
|
||||
let appDir = path.resolve(`${__dirname}/../..`);
|
||||
let localeDir = `${lbDir}/locale`;
|
||||
let viewDir = `${lbDir}/client`;
|
||||
let buildDir = `${appDir}/dist`;
|
||||
let servicesDir = `${appDir}/modules`;
|
||||
let modulesPath = `${appDir}/modules.yml`;
|
||||
|
||||
app.use(cookieParser());
|
||||
let modulesDir = `${appDir}/modules`;
|
||||
|
||||
// Internationalization
|
||||
|
||||
|
@ -49,28 +43,6 @@ if (fs.existsSync(localeDir)) {
|
|||
app.use(i18n.init);
|
||||
}
|
||||
|
||||
// View
|
||||
|
||||
if (fs.existsSync(viewDir)) {
|
||||
app.set('view engine', 'ejs');
|
||||
app.set('views', viewDir);
|
||||
app.use(loopback.static(viewDir));
|
||||
}
|
||||
|
||||
app.getWpAssets = entryPoint => {
|
||||
const wpAssets = require(`${buildDir}/webpack-assets.json`);
|
||||
|
||||
let jsFiles = [];
|
||||
let regex = new RegExp(`(^|~)${entryPoint}($|~)`);
|
||||
|
||||
for (let asset in wpAssets) {
|
||||
if (regex.test(asset))
|
||||
jsFiles.push(wpAssets[asset].js);
|
||||
}
|
||||
|
||||
return jsFiles;
|
||||
};
|
||||
|
||||
// Initialization
|
||||
|
||||
app.disconnect = async function() {
|
||||
|
@ -116,9 +88,9 @@ let bootDirs = [
|
|||
|
||||
addPath(`${appDir}/back`);
|
||||
|
||||
let services = require(modulesPath);
|
||||
for (let service of services)
|
||||
addPath(`${servicesDir}/${service}/back`);
|
||||
let modules = fs.readdirSync(modulesDir);
|
||||
for (let mod of modules)
|
||||
addPath(`${modulesDir}/${mod}/back`);
|
||||
|
||||
function addPath(path) {
|
||||
modelConfigFiles.push(`${path}/model-config.json`);
|
||||
|
|
10
modules.yml
10
modules.yml
|
@ -1,10 +0,0 @@
|
|||
[
|
||||
client,
|
||||
item,
|
||||
ticket,
|
||||
order,
|
||||
claim,
|
||||
route,
|
||||
agency,
|
||||
travel
|
||||
]
|
|
@ -3,6 +3,7 @@
|
|||
"name": "Claims",
|
||||
"icon": "icon-claims",
|
||||
"validations": true,
|
||||
"dependencies": ["item", "client"],
|
||||
"routes": [
|
||||
{
|
||||
"url": "/claim",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"name": "Items",
|
||||
"icon": "inbox",
|
||||
"validations" : true,
|
||||
"dependencies": ["client"],
|
||||
"routes": [
|
||||
{
|
||||
"url": "/item",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"name": "Orders",
|
||||
"icon": "shopping_cart",
|
||||
"validations": true,
|
||||
"dependencies": ["item", "ticket"],
|
||||
"routes": [
|
||||
{
|
||||
"url": "/order",
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
"name": "Tickets",
|
||||
"icon": "icon-ticket",
|
||||
"validations": true,
|
||||
"dependencies": ["item", "client"],
|
||||
"routes": [
|
||||
{
|
||||
"url": "/ticket",
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -6,8 +6,6 @@
|
|||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"compression": "^1.7.3",
|
||||
"cookie-parser": "^1.4.3",
|
||||
"cors": "^2.8.5",
|
||||
"fs-extra": "^5.0.0",
|
||||
"helmet": "^3.15.0",
|
||||
"i18n": "^0.8.3",
|
||||
|
@ -22,18 +20,17 @@
|
|||
"object.pick": "^1.3.0",
|
||||
"request": "^2.88.0",
|
||||
"require-yaml": "0.0.1",
|
||||
"serve-favicon": "^2.5.0",
|
||||
"strong-error-handler": "^2.3.2",
|
||||
"uuid": "^3.3.2",
|
||||
"vn-loopback": "file:./loopback"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.2.2",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
|
||||
"@babel/polyfill": "^7.2.5",
|
||||
"@babel/preset-env": "^7.2.0",
|
||||
"@babel/register": "^7.0.0",
|
||||
"angular-mocks": "^1.7.4",
|
||||
"assets-webpack-plugin": "^3.9.7",
|
||||
"babel-loader": "^8.0.5",
|
||||
"css-loader": "^0.25.0",
|
||||
"del": "^2.2.2",
|
||||
|
@ -54,7 +51,6 @@
|
|||
"gulp-yaml": "^1.0.1",
|
||||
"html-loader": "^0.4.5",
|
||||
"html-webpack-plugin": "^4.0.0-beta.5",
|
||||
"http-proxy-middleware": "^0.19.1",
|
||||
"jasmine": "^2.99.0",
|
||||
"jasmine-reporters": "^2.3.2",
|
||||
"jasmine-spec-reporter": "^4.2.1",
|
||||
|
@ -63,11 +59,11 @@
|
|||
"karma-chrome-launcher": "^2.2.0",
|
||||
"karma-firefox-launcher": "^1.1.0",
|
||||
"karma-jasmine": "^2.0.1",
|
||||
"karma-junit-reporter": "^1.2.0",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^3.0.5",
|
||||
"merge-stream": "^1.0.1",
|
||||
"minimist": "^1.2.0",
|
||||
"mustache": "^2.3.2",
|
||||
"mysql2": "^1.6.1",
|
||||
"nightmare": "^3.0.1",
|
||||
"node-sass": "^4.9.3",
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
temp/*
|
|
@ -1,2 +0,0 @@
|
|||
host: salix
|
||||
port: 80
|
|
@ -1,2 +0,0 @@
|
|||
host: test-salix
|
||||
port: 80
|
|
@ -1,4 +0,0 @@
|
|||
host: localhost
|
||||
port: 5000
|
||||
main: salix
|
||||
defaultPort: 3000
|
|
@ -1,54 +0,0 @@
|
|||
|
||||
worker_processes 1;
|
||||
|
||||
error_log temp/error.log;
|
||||
pid temp/nginx.pid;
|
||||
|
||||
events {
|
||||
worker_connections 1024;
|
||||
}
|
||||
|
||||
http {
|
||||
sendfile on;
|
||||
gzip on;
|
||||
default_type application/octet-stream;
|
||||
|
||||
access_log temp/access.log;
|
||||
client_body_temp_path temp/client-body;
|
||||
proxy_temp_path temp/proxy;
|
||||
fastcgi_temp_path temp/fastcgi;
|
||||
uwsgi_temp_path temp/uwsgi;
|
||||
scgi_temp_path temp/scgi;
|
||||
|
||||
server {
|
||||
listen {{port}};
|
||||
server_name {{host}};
|
||||
autoindex off;
|
||||
|
||||
{{#services}}
|
||||
location ~ ^/{{.}}(?:/(.*))?$ {
|
||||
proxy_pass http://127.0.0.1:{{defaultPort}}/$1$is_args$args;
|
||||
}
|
||||
{{/services}}
|
||||
|
||||
location ~ ^/static(?:/(.*)?)$ {
|
||||
proxy_pass http://127.0.0.1:{{devServerPort}}/$1$is_args$args;
|
||||
}
|
||||
location ~ ^(?:/(.*))?$ {
|
||||
proxy_pass http://127.0.0.1:{{defaultPort}}/$1$is_args$args;
|
||||
}
|
||||
}
|
||||
|
||||
types {
|
||||
text/html html;
|
||||
application/json json;
|
||||
application/javascript js;
|
||||
text/css css scss;
|
||||
text/xml xml;
|
||||
image/x-icon ico;
|
||||
image/png png;
|
||||
image/svg+xml svg;
|
||||
image/gif gif;
|
||||
image/jpeg jpeg jpg;
|
||||
}
|
||||
}
|
|
@ -3,20 +3,16 @@ const webpack = require('webpack');
|
|||
const path = require('path');
|
||||
const merge = require('webpack-merge');
|
||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||
const AssetsWebpackPlugin = require('assets-webpack-plugin');
|
||||
const wpConfig = require('./webpack.config.yml');
|
||||
|
||||
let env = process.env.NODE_ENV || 'development';
|
||||
let mode = env == 'development' ? env : 'production';
|
||||
|
||||
let outputPath = path.join(__dirname, wpConfig.buildDir);
|
||||
|
||||
let baseConfig = {
|
||||
entry: wpConfig.entry,
|
||||
entry: {salix: 'salix'},
|
||||
mode: mode,
|
||||
output: {
|
||||
path: outputPath,
|
||||
publicPath: `${wpConfig.publicPath}/`
|
||||
path: path.join(__dirname, 'dist'),
|
||||
publicPath: '/'
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
@ -25,7 +21,8 @@ let baseConfig = {
|
|||
loader: 'babel-loader',
|
||||
exclude: /node_modules/,
|
||||
query: {
|
||||
presets: ['@babel/preset-env']
|
||||
presets: ['@babel/preset-env'],
|
||||
plugins: ['@babel/plugin-syntax-dynamic-import']
|
||||
}
|
||||
}, {
|
||||
test: /\.yml$/,
|
||||
|
@ -74,11 +71,9 @@ let baseConfig = {
|
|||
}
|
||||
},
|
||||
plugins: [
|
||||
new AssetsWebpackPlugin({
|
||||
path: outputPath
|
||||
}),
|
||||
new HtmlWebpackPlugin({
|
||||
template: 'front/salix/index.ejs',
|
||||
favicon: 'front/salix/favicon.ico',
|
||||
filename: 'index.html',
|
||||
chunks: ['salix']
|
||||
})
|
||||
|
@ -112,15 +107,26 @@ let devConfig = {
|
|||
filename: '[name].js',
|
||||
chunkFilename: '[id].js'
|
||||
},
|
||||
plugins: [
|
||||
new webpack.HotModuleReplacementPlugin()
|
||||
],
|
||||
devServer: {
|
||||
host: 'localhost',
|
||||
port: wpConfig.devServerPort,
|
||||
port: 5000,
|
||||
publicPath: '/',
|
||||
contentBase: wpConfig.buildDir,
|
||||
contentBase: 'dist',
|
||||
quiet: false,
|
||||
noInfo: false,
|
||||
// hot: true,
|
||||
stats: baseConfig.stats
|
||||
hot: true,
|
||||
inline: true,
|
||||
stats: baseConfig.stats,
|
||||
proxy: {
|
||||
'/api': 'http://localhost:3000',
|
||||
'/*/api/**': {
|
||||
target: 'http://localhost:3000',
|
||||
pathRewrite: {'^/[\\w-]+': ''}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
buildDir: dist
|
||||
devServerPort: 3500
|
||||
publicPath: '/static'
|
||||
entry: {
|
||||
salix: salix
|
||||
}
|
Loading…
Reference in New Issue