..
This commit is contained in:
parent
94156bed0e
commit
81d214b50a
1
.gitignore
vendored
1
.gitignore
vendored
@ -4,3 +4,4 @@ node_modules
|
||||
.DS_Store
|
||||
npm-debug.log
|
||||
package-lock.json
|
||||
yarn.lock
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
module.exports = {
|
||||
database: {
|
||||
username: 'acana_wms',
|
||||
password: 'a85*MukC45.',
|
||||
database: 'acana_wms',
|
||||
username: 'lqdvi',
|
||||
password: 'Z286y386*a',
|
||||
database: 'lqdvi_v2',
|
||||
host: 'localhost',
|
||||
dialect: 'mysql'
|
||||
dialect: 'mysql',
|
||||
},
|
||||
|
||||
session: {
|
||||
|
||||
@ -1,58 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Dependencies.
|
||||
const glob = require('glob');
|
||||
const { get, upperFirst, camelCase } = require('lodash');
|
||||
const utils = require('../utils');
|
||||
const models = require('./models');
|
||||
|
||||
module.exports.nested = function() {
|
||||
return Promise.all([
|
||||
|
||||
// Load root configurations.
|
||||
new Promise((resolve, reject) => {
|
||||
glob('./config/index.js', {
|
||||
cwd: this.config.appPath,
|
||||
dot: true
|
||||
}, (err, files) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
utils.loadConfig.call(this, files).then(resolve).catch(reject);
|
||||
});
|
||||
})
|
||||
]);
|
||||
};
|
||||
|
||||
|
||||
module.exports.app = async function() {
|
||||
|
||||
// Set connections.
|
||||
this.connections = {};
|
||||
|
||||
// Set current environment config.
|
||||
this.config.currentEnvironment = this.config.environments[this.config.environment] || {};
|
||||
|
||||
// default settings
|
||||
this.config.port = get(this.config.currentEnvironment, 'server.port') || this.config.port;
|
||||
this.config.host = get(this.config.currentEnvironment, 'server.host') || this.config.host;
|
||||
|
||||
// Set current URL
|
||||
this.config.url = getURLFromSegments({
|
||||
hostname: this.config.host,
|
||||
port: this.config.port
|
||||
});
|
||||
|
||||
// Set models
|
||||
this.models = models.call(this);
|
||||
|
||||
};
|
||||
|
||||
const getURLFromSegments = function ({ hostname, port, ssl = false }) {
|
||||
const protocol = ssl ? 'https' : 'http';
|
||||
const defaultPort = ssl ? 443 : 80;
|
||||
const portString = (port === undefined || parseInt(port) === defaultPort) ? '' : `:${port}`;
|
||||
|
||||
return `${protocol}://${hostname}${portString}`;
|
||||
};
|
||||
120
core/express.js
120
core/express.js
@ -14,78 +14,76 @@ const router = require('./router');
|
||||
const error = require('../middlewares/error');
|
||||
const access = require('../middlewares/access');
|
||||
|
||||
module.exports = async function () {
|
||||
/**
|
||||
* Express instance
|
||||
* @public
|
||||
*/
|
||||
const app = express();
|
||||
/**
|
||||
* Express instance
|
||||
* @public
|
||||
*/
|
||||
const app = express();
|
||||
|
||||
// request logging. dev: console | production: file
|
||||
//app.use(morgan(logs));
|
||||
// request logging. dev: console | production: file
|
||||
//app.use(morgan(logs));
|
||||
|
||||
// parse body params and attache them to req.body
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
// parse body params and attache them to req.body
|
||||
app.use(bodyParser.json());
|
||||
app.use(bodyParser.urlencoded({
|
||||
extended: true
|
||||
}));
|
||||
|
||||
// set up the response-time middleware
|
||||
app.use(responseTime());
|
||||
// set up the response-time middleware
|
||||
app.use(responseTime());
|
||||
|
||||
// gzip compression
|
||||
app.use(compress());
|
||||
// gzip compression
|
||||
app.use(compress());
|
||||
|
||||
// lets you use HTTP verbs such as PUT or DELETE
|
||||
// in places where the client doesn't support it
|
||||
app.use(methodOverride());
|
||||
// lets you use HTTP verbs such as PUT or DELETE
|
||||
// in places where the client doesn't support it
|
||||
app.use(methodOverride());
|
||||
|
||||
// secure apps by setting various HTTP headers
|
||||
app.use(helmet());
|
||||
// secure apps by setting various HTTP headers
|
||||
app.use(helmet());
|
||||
|
||||
|
||||
// enable CORS - Cross Origin Resource Sharing
|
||||
app.use(cors({
|
||||
exposeHeaders: [
|
||||
"WWW-Authenticate",
|
||||
"Server-Authorization"
|
||||
],
|
||||
maxAge: 31536000,
|
||||
credentials: true,
|
||||
allowMethods: [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"PATCH",
|
||||
"DELETE",
|
||||
"OPTIONS",
|
||||
"HEAD"
|
||||
],
|
||||
allowHeaders: [
|
||||
"Content-Type",
|
||||
"Authorization",
|
||||
"X-Frame-Options",
|
||||
"Origin"
|
||||
],
|
||||
}));
|
||||
|
||||
|
||||
// Access validator
|
||||
app.use(passport.initialize());
|
||||
passport.use('jwt', access.jwt.call(this));
|
||||
// enable CORS - Cross Origin Resource Sharing
|
||||
app.use(cors({
|
||||
exposeHeaders: [
|
||||
"WWW-Authenticate",
|
||||
"Server-Authorization"
|
||||
],
|
||||
maxAge: 31536000,
|
||||
credentials: true,
|
||||
allowMethods: [
|
||||
"GET",
|
||||
"POST",
|
||||
"PUT",
|
||||
"PATCH",
|
||||
"DELETE",
|
||||
"OPTIONS",
|
||||
"HEAD"
|
||||
],
|
||||
allowHeaders: [
|
||||
"Content-Type",
|
||||
"Authorization",
|
||||
"X-Frame-Options",
|
||||
"Origin"
|
||||
],
|
||||
}));
|
||||
|
||||
|
||||
// Set routes
|
||||
app.use('/api', await router.call(this));
|
||||
// Access validator
|
||||
app.use(passport.initialize());
|
||||
passport.use('jwt', access.jwt);
|
||||
|
||||
// if error is not an instanceOf APIError, convert it.
|
||||
app.use(error.converter);
|
||||
|
||||
// catch 404 and forward to error handler
|
||||
app.use(error.notFound);
|
||||
// Set routes
|
||||
app.use('/api', router());
|
||||
|
||||
// error handler, send stacktrace only during development
|
||||
app.use(error.handler);
|
||||
// if error is not an instanceOf APIError, convert it.
|
||||
app.use(error.converter);
|
||||
|
||||
return app;
|
||||
}
|
||||
// catch 404 and forward to error handler
|
||||
app.use(error.notFound);
|
||||
|
||||
// error handler, send stacktrace only during development
|
||||
app.use(error.handler);
|
||||
|
||||
module.exports = app;
|
||||
@ -1,10 +1,12 @@
|
||||
'use strict';
|
||||
|
||||
const { nested, app } = require('./configurations');
|
||||
//const { nested, app } = require('./configurations');
|
||||
const express = require('./express');
|
||||
const logger = require('./logger');
|
||||
const modules = require('./modules');
|
||||
const models = require('./models');
|
||||
|
||||
//const modules = require('./modules');
|
||||
|
||||
//const middlewares = require('./middlewares');
|
||||
//const hooks = require('./hooks');
|
||||
//const plugins = require('./plugins');
|
||||
@ -12,11 +14,11 @@ const models = require('./models');
|
||||
//const store = require('./store');
|
||||
|
||||
module.exports = {
|
||||
nestedConfigurations: nested,
|
||||
//nestedConfigurations: nested,
|
||||
express,
|
||||
logger,
|
||||
appConfigurations: app,
|
||||
modules,
|
||||
//appConfigurations: app,
|
||||
//modules,
|
||||
models,
|
||||
//middlewares,
|
||||
//hooks,
|
||||
|
||||
@ -2,6 +2,10 @@ const glob = require('glob');
|
||||
const path = require('path');
|
||||
const Sequelize = require('sequelize');
|
||||
|
||||
const config = require('../config');
|
||||
const log = require('./logger');
|
||||
|
||||
|
||||
const modulesDir = path.resolve(__dirname + '/../modules/')
|
||||
const basename = path.basename(__dirname);
|
||||
const globOptions = {
|
||||
@ -11,39 +15,33 @@ const globOptions = {
|
||||
absolute: true,
|
||||
}
|
||||
|
||||
module.exports = async function () {
|
||||
const server = this;
|
||||
log.info('Configurando DB.');
|
||||
|
||||
server.log.info('Configurando DB.');
|
||||
const sequelize = new Sequelize(
|
||||
config.database.database,
|
||||
config.database.username,
|
||||
config.database.password,
|
||||
config.database, {
|
||||
dialect: 'mysql',
|
||||
operatorAliases: false
|
||||
}
|
||||
);
|
||||
|
||||
const sequelize = new Sequelize(
|
||||
server.config.database.database,
|
||||
server.config.database.username,
|
||||
server.config.database.password,
|
||||
server.config.database, {
|
||||
dialect: 'mysql',
|
||||
operatorAliases: false
|
||||
}
|
||||
);
|
||||
const db = {};
|
||||
db.sequelize = sequelize;
|
||||
db.Sequelize = Sequelize;
|
||||
|
||||
const db = {};
|
||||
db.sequelize = sequelize;
|
||||
db.Sequelize = Sequelize;
|
||||
|
||||
glob.sync("**/*.model.js", globOptions)
|
||||
.forEach(function (file) {
|
||||
var model = sequelize.import(file);
|
||||
log.info('Loading "' + model.name + '" model.');
|
||||
db[model.name] = model;
|
||||
});
|
||||
|
||||
Object.keys(db).forEach(function (modelName) {
|
||||
if (db[modelName].associate) {
|
||||
db[modelName].associate(db);
|
||||
}
|
||||
glob.sync("**/*.model.js", globOptions)
|
||||
.forEach(function (file) {
|
||||
var model = sequelize.import(file);
|
||||
log.info('Loading "' + model.name + '" model.');
|
||||
db[model.name] = model;
|
||||
});
|
||||
|
||||
server.log.debug(db);
|
||||
Object.keys(db).forEach(function (modelName) {
|
||||
if (db[modelName].associate) {
|
||||
db[modelName].associate(db);
|
||||
}
|
||||
});
|
||||
|
||||
return db;
|
||||
}
|
||||
module.exports = db;
|
||||
@ -1,58 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
// Dependencies.
|
||||
const glob = require('glob');
|
||||
const { setWith, merge, get, isObject, isFunction } = require('lodash');
|
||||
|
||||
const optionalPath = path => {
|
||||
return path
|
||||
.replace(/(\.settings|.json|.js)/g, '')
|
||||
.split('/')
|
||||
.slice(1, path.split('/').length - 1)
|
||||
.join('.')
|
||||
.toLowerCase();
|
||||
};
|
||||
|
||||
const aggregatePath = path => {
|
||||
return path
|
||||
.replace(/(\.settings|.json|.js)/g, '')
|
||||
.split('/')
|
||||
.slice(1)
|
||||
.join('.')
|
||||
.toLowerCase();
|
||||
};
|
||||
|
||||
const setConfig = function (ctx, path, type, loader) {
|
||||
const objPath = type === 'optional' ?
|
||||
optionalPath(path) :
|
||||
aggregatePath(path);
|
||||
|
||||
// Load value.
|
||||
const value = loader(path);
|
||||
// Merge doesn't work for none-object value and function.
|
||||
const obj = isObject(value) && !isFunction(value) ? merge(get(ctx, objPath), value) : value;
|
||||
|
||||
// Assignation.
|
||||
return setWith(ctx, objPath, obj, Object);
|
||||
};
|
||||
|
||||
module.exports = function() {
|
||||
return Promise.all([
|
||||
|
||||
new Promise((resolve, reject) => {
|
||||
// Load configurations.
|
||||
glob('./modules/*/!(config)/*.*(js|json)', {
|
||||
cwd: this.config.appPath
|
||||
}, (err, files) => {
|
||||
if (err) {
|
||||
return reject(err);
|
||||
}
|
||||
|
||||
files.map(p => setConfig(this, p, 'aggregate', this.loadFile));
|
||||
|
||||
resolve();
|
||||
});
|
||||
}),
|
||||
|
||||
]);
|
||||
};
|
||||
@ -12,8 +12,7 @@ const globOptions = {
|
||||
absolute: true,
|
||||
}
|
||||
|
||||
|
||||
module.exports = async function () {
|
||||
module.exports = function () {
|
||||
const router = express.Router();
|
||||
|
||||
router.get('/_health', (req, res, next) => {
|
||||
@ -24,9 +23,8 @@ module.exports = async function () {
|
||||
});
|
||||
});
|
||||
|
||||
glob.sync("*/config/routes.js", globOptions)
|
||||
glob.sync("**/*.routes.js", globOptions)
|
||||
.forEach(function (file) {
|
||||
console.log(file);
|
||||
router.use('/v2', require(file));
|
||||
});
|
||||
|
||||
|
||||
@ -1,29 +1,26 @@
|
||||
'use strict';
|
||||
|
||||
const config = require('../config');
|
||||
const { logger } = require('../core');
|
||||
|
||||
const JwtStrategy = require('passport-jwt').Strategy;
|
||||
const { ExtractJwt } = require('passport-jwt');
|
||||
//const User = this.models.User;
|
||||
|
||||
const jwtOptions = {
|
||||
secretOrKey: config.session.secret_token,
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Bearer'),
|
||||
};
|
||||
|
||||
module.exports.jwt = async function() {
|
||||
const config = this.config;
|
||||
const jwt = async (payload, done) => {
|
||||
logger.info(payload);
|
||||
try {
|
||||
//const user = await User.findById(payload.sub);
|
||||
//if (user) return done(null, user);
|
||||
return done(null, false);
|
||||
} catch (error) {
|
||||
return done(error, false);
|
||||
}
|
||||
};
|
||||
|
||||
const JwtStrategy = require('passport-jwt').Strategy;
|
||||
const { ExtractJwt } = require('passport-jwt');
|
||||
//const User = this.models.User;
|
||||
|
||||
const jwtOptions = {
|
||||
secretOrKey: config.session.secret_token,
|
||||
jwtFromRequest: ExtractJwt.fromAuthHeaderWithScheme('Bearer'),
|
||||
};
|
||||
|
||||
const jwt = async (payload, done) => {
|
||||
this.log.info(payload);
|
||||
try {
|
||||
//const user = await User.findById(payload.sub);
|
||||
//if (user) return done(null, user);
|
||||
return done(null, false);
|
||||
} catch (error) {
|
||||
return done(error, false);
|
||||
}
|
||||
};
|
||||
|
||||
return new JwtStrategy(jwtOptions, jwt);
|
||||
}
|
||||
module.exports.jwt = new JwtStrategy(jwtOptions, jwt);
|
||||
16
modules/blog/blog.routes.js
Normal file
16
modules/blog/blog.routes.js
Normal file
@ -0,0 +1,16 @@
|
||||
const routes = require('express').Router();
|
||||
const models = require('../../core/models');
|
||||
const postService = require('./post.service')(models.Post);
|
||||
const postController = require('./post.controller')(postService);
|
||||
|
||||
routes.use((req, res, next) => {
|
||||
// here we can access the req.params object and make auth checks
|
||||
next();
|
||||
});
|
||||
|
||||
routes.get('/posts', function (req, res) {
|
||||
data = postController.find(req)
|
||||
res.status(200).json(data);
|
||||
});
|
||||
|
||||
module.exports = routes;
|
||||
36
modules/blog/category.model.js
Executable file
36
modules/blog/category.model.js
Executable file
@ -0,0 +1,36 @@
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
const Category = sequelize.define('Category', {
|
||||
id: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true
|
||||
},
|
||||
name: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
sort: {
|
||||
// Se cambia el nombre del campo de 'order' a 'sort' porque 'order' es una palabra reservada SQL y da problemas al generar las consultas SQL.
|
||||
field: 'order', // <- Chapuza!! El nombre del campo en MySQL es una palabra reservada en SQL.
|
||||
type: DataTypes.INTEGER,
|
||||
defaultValue: 0,
|
||||
allowNull: false,
|
||||
}
|
||||
}, {
|
||||
tableName: 'category',
|
||||
freezeTableName: true,
|
||||
timestamps: false
|
||||
});
|
||||
|
||||
Category.beforeCreate((category) => {
|
||||
category.dataValues.id = Math.floor(Math.random() * (999 - 8)) + 8;
|
||||
})
|
||||
|
||||
Category.associate = function (models) {
|
||||
Category.Posts = Category.belongsToMany(models.Post, {
|
||||
through: models.PostCategory,
|
||||
foreignKey: 'categoryId'
|
||||
});
|
||||
};
|
||||
|
||||
return Category;
|
||||
};
|
||||
20
modules/blog/post-category.model.js
Executable file
20
modules/blog/post-category.model.js
Executable file
@ -0,0 +1,20 @@
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
const PostCategory = sequelize.define('PostCategory', {
|
||||
postId: {
|
||||
type: DataTypes.UUID,
|
||||
primaryKey: true,
|
||||
foreignKey: true
|
||||
},
|
||||
categoryId: {
|
||||
type: DataTypes.INTEGER,
|
||||
primaryKey: true,
|
||||
foreignKey: true
|
||||
}
|
||||
}, {
|
||||
tableName: 'post-category',
|
||||
freezeTableName: true,
|
||||
timestamps: false
|
||||
});
|
||||
|
||||
return PostCategory;
|
||||
};
|
||||
76
modules/blog/post.controller.js
Normal file
76
modules/blog/post.controller.js
Normal file
@ -0,0 +1,76 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Post.js controller
|
||||
*
|
||||
* @description: A set of functions called "actions" for managing `Post`.
|
||||
*/
|
||||
|
||||
module.exports = function (modelService) {
|
||||
return {
|
||||
|
||||
/**
|
||||
* Retrieve post records.
|
||||
*
|
||||
* @return {Object|Array}
|
||||
*/
|
||||
|
||||
find: async (ctx) => {
|
||||
if (ctx.query._q) {
|
||||
return modelService.search(ctx.query);
|
||||
} else {
|
||||
return modelService.fetchAll(ctx.query);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve a post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
findOne: async (ctx) => {
|
||||
return modelService.fetch(ctx.params);
|
||||
},
|
||||
|
||||
/**
|
||||
* Count post records.
|
||||
*
|
||||
* @return {Number}
|
||||
*/
|
||||
|
||||
count: async (ctx) => {
|
||||
return modelService.count(ctx.query);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a/an post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
create: async (ctx) => {
|
||||
return modelService.add(ctx.request.body);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update a/an post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
update: async (ctx, next) => {
|
||||
return modelService.edit(ctx.params, ctx.request.body);
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy a/an post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
destroy: async (ctx, next) => {
|
||||
return modelService.remove(ctx.params);
|
||||
}
|
||||
};
|
||||
}
|
||||
51
modules/blog/post.model.js
Normal file
51
modules/blog/post.model.js
Normal file
@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
|
||||
module.exports = function (sequelize, DataTypes) {
|
||||
const Post = sequelize.define('Post', {
|
||||
id: {
|
||||
type: DataTypes.UUID,
|
||||
defaultValue: DataTypes.UUIDV4,
|
||||
primaryKey: true,
|
||||
},
|
||||
/*userId: {
|
||||
type: DataTypes.UUID,
|
||||
allowNull: true,
|
||||
primaryKey: false,
|
||||
unique: false,
|
||||
foreignKey: true
|
||||
},*/
|
||||
date: {
|
||||
type: DataTypes.DATE,
|
||||
allowNull: false,
|
||||
defaultValue: DataTypes.NOW
|
||||
},
|
||||
image: {
|
||||
type: DataTypes.STRING,
|
||||
defaultValue: ""
|
||||
},
|
||||
title: {
|
||||
type: DataTypes.STRING,
|
||||
allowNull: false
|
||||
},
|
||||
content: {
|
||||
type: DataTypes.TEXT,
|
||||
allowNull: false
|
||||
},
|
||||
}, {
|
||||
tableName: 'post',
|
||||
freezeTableName: true,
|
||||
timestamps: true,
|
||||
updatedAt: false,
|
||||
});
|
||||
|
||||
Post.associate = function (models) {
|
||||
Post.Categories = Post.belongsToMany(models.Category, {
|
||||
through: models.PostCategory,
|
||||
foreignKey: 'postId'
|
||||
});
|
||||
//Post.Comments = Post.hasMany(models.PostComment, { foreignKey: 'postId' });
|
||||
//Post.Reactions = Post.hasMany(models.PostReaction, { foreignKey: 'postId' });
|
||||
//Post.User = Post.belongsTo(models.User, { foreignKey: 'userId' });
|
||||
};
|
||||
return Post;
|
||||
};
|
||||
252
modules/blog/post.service.js
Normal file
252
modules/blog/post.service.js
Normal file
@ -0,0 +1,252 @@
|
||||
/* global Post */
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Post.js service
|
||||
*
|
||||
* @description: A set of functions similar to controller's actions to avoid code duplication.
|
||||
*/
|
||||
|
||||
// Public dependencies.
|
||||
const _ = require('lodash');
|
||||
|
||||
module.exports = function (Post) {
|
||||
return {
|
||||
|
||||
/**
|
||||
* Promise to fetch all posts.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
fetchAll: (params) => {
|
||||
// Convert `params` object to filters compatible with Bookshelf.
|
||||
const filters = []; //strapi.utils.models.convertParams('post', params);
|
||||
// Select field to populate.
|
||||
/*const populate = Post.associations
|
||||
.filter(ast => ast.autoPopulate !== false)
|
||||
.map(ast => ast.alias);*/
|
||||
|
||||
/*return Post.query(function (qb) {
|
||||
_.forEach(filters.where, (where, key) => {
|
||||
if (_.isArray(where.value) && where.symbol !== 'IN' && where.symbol !== 'NOT IN') {
|
||||
for (const value in where.value) {
|
||||
qb[value ? 'where' : 'orWhere'](key, where.symbol, where.value[value])
|
||||
}
|
||||
} else {
|
||||
qb.where(key, where.symbol, where.value);
|
||||
}
|
||||
});
|
||||
|
||||
if (filters.sort) {
|
||||
qb.orderBy(filters.sort.key, filters.sort.order);
|
||||
}
|
||||
|
||||
qb.offset(filters.start);
|
||||
qb.limit(filters.limit);
|
||||
}).fetchAll({
|
||||
withRelated: filters.populate || populate
|
||||
});*/
|
||||
|
||||
const findOptions = {}
|
||||
|
||||
return Post.findAll(findOptions);
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to fetch a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
fetch: (params) => {
|
||||
// Select field to populate.
|
||||
const populate = Post.associations
|
||||
.filter(ast => ast.autoPopulate !== false)
|
||||
.map(ast => ast.alias);
|
||||
|
||||
return Post.forge(_.pick(params, 'id')).fetch({
|
||||
withRelated: populate
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to count a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
count: (params) => {
|
||||
// Convert `params` object to filters compatible with Bookshelf.
|
||||
const filters = strapi.utils.models.convertParams('post', params);
|
||||
|
||||
return Post.query(function (qb) {
|
||||
_.forEach(filters.where, (where, key) => {
|
||||
if (_.isArray(where.value)) {
|
||||
for (const value in where.value) {
|
||||
qb[value ? 'where' : 'orWhere'](key, where.symbol, where.value[value]);
|
||||
}
|
||||
} else {
|
||||
qb.where(key, where.symbol, where.value);
|
||||
}
|
||||
});
|
||||
}).count();
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to add a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
add: async (values) => {
|
||||
// Extract values related to relational data.
|
||||
const relations = _.pick(values, Post.associations.map(ast => ast.alias));
|
||||
const data = _.omit(values, Post.associations.map(ast => ast.alias));
|
||||
|
||||
// Create entry with no-relational data.
|
||||
const entry = await Post.forge(data).save();
|
||||
|
||||
// Create relational data and return the entry.
|
||||
return Post.updateRelations({
|
||||
id: entry.id,
|
||||
values: relations
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to edit a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
edit: async (params, values) => {
|
||||
// Extract values related to relational data.
|
||||
const relations = _.pick(values, Post.associations.map(ast => ast.alias));
|
||||
const data = _.omit(values, Post.associations.map(ast => ast.alias));
|
||||
|
||||
// Create entry with no-relational data.
|
||||
const entry = await Post.forge(params).save(data);
|
||||
|
||||
// Create relational data and return the entry.
|
||||
return Post.updateRelations(Object.assign(params, {
|
||||
values: relations
|
||||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to remove a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
remove: async (params) => {
|
||||
params.values = {};
|
||||
Post.associations.map(association => {
|
||||
switch (association.nature) {
|
||||
case 'oneWay':
|
||||
case 'oneToOne':
|
||||
case 'manyToOne':
|
||||
case 'oneToManyMorph':
|
||||
params.values[association.alias] = null;
|
||||
break;
|
||||
case 'oneToMany':
|
||||
case 'manyToMany':
|
||||
case 'manyToManyMorph':
|
||||
params.values[association.alias] = [];
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
|
||||
await Post.updateRelations(params);
|
||||
|
||||
return Post.forge(params).destroy();
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to search a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
search: async (params) => {
|
||||
// Convert `params` object to filters compatible with Bookshelf.
|
||||
const filters = strapi.utils.models.convertParams('post', params);
|
||||
// Select field to populate.
|
||||
const populate = Post.associations
|
||||
.filter(ast => ast.autoPopulate !== false)
|
||||
.map(ast => ast.alias);
|
||||
|
||||
const associations = Post.associations.map(x => x.alias);
|
||||
const searchText = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => ['string', 'text'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const searchNoText = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => !['string', 'text', 'boolean', 'integer', 'decimal', 'float'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const searchInt = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => ['integer', 'decimal', 'float'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const searchBool = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => ['boolean'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const query = (params._q || '').replace(/[^a-zA-Z0-9.-\s]+/g, '');
|
||||
|
||||
return Post.query(qb => {
|
||||
// Search in columns which are not text value.
|
||||
searchNoText.forEach(attribute => {
|
||||
qb.orWhereRaw(`LOWER(${attribute}) LIKE '%${_.toLower(query)}%'`);
|
||||
});
|
||||
|
||||
if (!_.isNaN(_.toNumber(query))) {
|
||||
searchInt.forEach(attribute => {
|
||||
qb.orWhereRaw(`${attribute} = ${_.toNumber(query)}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (query === 'true' || query === 'false') {
|
||||
searchBool.forEach(attribute => {
|
||||
qb.orWhereRaw(`${attribute} = ${_.toNumber(query === 'true')}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Search in columns with text using index.
|
||||
switch (Post.client) {
|
||||
case 'mysql':
|
||||
qb.orWhereRaw(`MATCH(${searchText.join(',')}) AGAINST(? IN BOOLEAN MODE)`, `*${query}*`);
|
||||
break;
|
||||
case 'pg':
|
||||
{
|
||||
const searchQuery = searchText.map(attribute =>
|
||||
_.toLower(attribute) === attribute ?
|
||||
`to_tsvector(${attribute})` :
|
||||
`to_tsvector('${attribute}')`
|
||||
);
|
||||
|
||||
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ to_tsquery(?)`, query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (filters.sort) {
|
||||
qb.orderBy(filters.sort.key, filters.sort.order);
|
||||
}
|
||||
|
||||
if (filters.skip) {
|
||||
qb.offset(_.toNumber(filters.skip));
|
||||
}
|
||||
|
||||
if (filters.limit) {
|
||||
qb.limit(_.toNumber(filters.limit));
|
||||
}
|
||||
}).fetchAll({
|
||||
withRelated: populate
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
@ -1,12 +0,0 @@
|
||||
const routes = require('express').Router();
|
||||
|
||||
routes.use((req, res, next) => {
|
||||
// here we can access the req.params object and make auth checks
|
||||
next();
|
||||
});
|
||||
|
||||
routes.get('/posts', function (req, res) {
|
||||
res.status(200).json({ message: 'Connected!' });
|
||||
});
|
||||
|
||||
module.exports = routes;
|
||||
@ -1,74 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Post.js controller
|
||||
*
|
||||
* @description: A set of functions called "actions" for managing `Post`.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* Retrieve post records.
|
||||
*
|
||||
* @return {Object|Array}
|
||||
*/
|
||||
|
||||
find: async (ctx) => {
|
||||
if (ctx.query._q) {
|
||||
return strapi.services.post.search(ctx.query);
|
||||
} else {
|
||||
return strapi.services.post.fetchAll(ctx.query);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve a post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
findOne: async (ctx) => {
|
||||
return strapi.services.post.fetch(ctx.params);
|
||||
},
|
||||
|
||||
/**
|
||||
* Count post records.
|
||||
*
|
||||
* @return {Number}
|
||||
*/
|
||||
|
||||
count: async (ctx) => {
|
||||
return strapi.services.post.count(ctx.query);
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a/an post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
create: async (ctx) => {
|
||||
return strapi.services.post.add(ctx.request.body);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update a/an post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
update: async (ctx, next) => {
|
||||
return strapi.services.post.edit(ctx.params, ctx.request.body) ;
|
||||
},
|
||||
|
||||
/**
|
||||
* Destroy a/an post record.
|
||||
*
|
||||
* @return {Object}
|
||||
*/
|
||||
|
||||
destroy: async (ctx, next) => {
|
||||
return strapi.services.post.remove(ctx.params);
|
||||
}
|
||||
};
|
||||
@ -1,55 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Lifecycle callbacks for the `Post` model.
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
// Before saving a value.
|
||||
// Fired before an `insert` or `update` query.
|
||||
// beforeSave: async (model, attrs, options) => {},
|
||||
|
||||
// After saving a value.
|
||||
// Fired after an `insert` or `update` query.
|
||||
// afterSave: async (model, response, options) => {},
|
||||
|
||||
// Before fetching a value.
|
||||
// Fired before a `fetch` operation.
|
||||
// beforeFetch: async (model, columns, options) => {},
|
||||
|
||||
// After fetching a value.
|
||||
// Fired after a `fetch` operation.
|
||||
// afterFetch: async (model, response, options) => {},
|
||||
|
||||
// Before fetching all values.
|
||||
// Fired before a `fetchAll` operation.
|
||||
// beforeFetchAll: async (model, columns, options) => {},
|
||||
|
||||
// After fetching all values.
|
||||
// Fired after a `fetchAll` operation.
|
||||
// afterFetchAll: async (model, response, options) => {},
|
||||
|
||||
// Before creating a value.
|
||||
// Fired before an `insert` query.
|
||||
// beforeCreate: async (model, attrs, options) => {},
|
||||
|
||||
// After creating a value.
|
||||
// Fired after an `insert` query.
|
||||
// afterCreate: async (model, attrs, options) => {},
|
||||
|
||||
// Before updating a value.
|
||||
// Fired before an `update` query.
|
||||
// beforeUpdate: async (model, attrs, options) => {},
|
||||
|
||||
// After updating a value.
|
||||
// Fired after an `update` query.
|
||||
// afterUpdate: async (model, attrs, options) => {},
|
||||
|
||||
// Before destroying a value.
|
||||
// Fired before a `delete` query.
|
||||
// beforeDestroy: async (model, attrs, options) => {},
|
||||
|
||||
// After destroying a value.
|
||||
// Fired after a `delete` query.
|
||||
// afterDestroy: async (model, attrs, options) => {}
|
||||
};
|
||||
@ -1,20 +0,0 @@
|
||||
{
|
||||
"connection": "default",
|
||||
"collectionName": "posts",
|
||||
"info": {
|
||||
"name": "post",
|
||||
"description": ""
|
||||
},
|
||||
"options": {
|
||||
"increments": true,
|
||||
"timestamps": true,
|
||||
"comment": ""
|
||||
},
|
||||
"attributes": {
|
||||
"Título": {
|
||||
"default": "",
|
||||
"type": "string",
|
||||
"required": true
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,243 +0,0 @@
|
||||
/* global Post */
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Post.js service
|
||||
*
|
||||
* @description: A set of functions similar to controller's actions to avoid code duplication.
|
||||
*/
|
||||
|
||||
// Public dependencies.
|
||||
const _ = require('lodash');
|
||||
|
||||
// Strapi utilities.
|
||||
//const utils = require('strapi-hook-bookshelf/lib/utils/');
|
||||
|
||||
module.exports = {
|
||||
|
||||
/**
|
||||
* Promise to fetch all posts.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
fetchAll: (params) => {
|
||||
// Convert `params` object to filters compatible with Bookshelf.
|
||||
const filters = strapi.utils.models.convertParams('post', params);
|
||||
// Select field to populate.
|
||||
const populate = Post.associations
|
||||
.filter(ast => ast.autoPopulate !== false)
|
||||
.map(ast => ast.alias);
|
||||
|
||||
return Post.query(function(qb) {
|
||||
_.forEach(filters.where, (where, key) => {
|
||||
if (_.isArray(where.value) && where.symbol !== 'IN' && where.symbol !== 'NOT IN') {
|
||||
for (const value in where.value) {
|
||||
qb[value ? 'where' : 'orWhere'](key, where.symbol, where.value[value])
|
||||
}
|
||||
} else {
|
||||
qb.where(key, where.symbol, where.value);
|
||||
}
|
||||
});
|
||||
|
||||
if (filters.sort) {
|
||||
qb.orderBy(filters.sort.key, filters.sort.order);
|
||||
}
|
||||
|
||||
qb.offset(filters.start);
|
||||
qb.limit(filters.limit);
|
||||
}).fetchAll({
|
||||
withRelated: filters.populate || populate
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to fetch a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
fetch: (params) => {
|
||||
// Select field to populate.
|
||||
const populate = Post.associations
|
||||
.filter(ast => ast.autoPopulate !== false)
|
||||
.map(ast => ast.alias);
|
||||
|
||||
return Post.forge(_.pick(params, 'id')).fetch({
|
||||
withRelated: populate
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to count a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
count: (params) => {
|
||||
// Convert `params` object to filters compatible with Bookshelf.
|
||||
const filters = strapi.utils.models.convertParams('post', params);
|
||||
|
||||
return Post.query(function(qb) {
|
||||
_.forEach(filters.where, (where, key) => {
|
||||
if (_.isArray(where.value)) {
|
||||
for (const value in where.value) {
|
||||
qb[value ? 'where' : 'orWhere'](key, where.symbol, where.value[value]);
|
||||
}
|
||||
} else {
|
||||
qb.where(key, where.symbol, where.value);
|
||||
}
|
||||
});
|
||||
}).count();
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to add a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
add: async (values) => {
|
||||
// Extract values related to relational data.
|
||||
const relations = _.pick(values, Post.associations.map(ast => ast.alias));
|
||||
const data = _.omit(values, Post.associations.map(ast => ast.alias));
|
||||
|
||||
// Create entry with no-relational data.
|
||||
const entry = await Post.forge(data).save();
|
||||
|
||||
// Create relational data and return the entry.
|
||||
return Post.updateRelations({ id: entry.id , values: relations });
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to edit a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
edit: async (params, values) => {
|
||||
// Extract values related to relational data.
|
||||
const relations = _.pick(values, Post.associations.map(ast => ast.alias));
|
||||
const data = _.omit(values, Post.associations.map(ast => ast.alias));
|
||||
|
||||
// Create entry with no-relational data.
|
||||
const entry = await Post.forge(params).save(data);
|
||||
|
||||
// Create relational data and return the entry.
|
||||
return Post.updateRelations(Object.assign(params, { values: relations }));
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to remove a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
remove: async (params) => {
|
||||
params.values = {};
|
||||
Post.associations.map(association => {
|
||||
switch (association.nature) {
|
||||
case 'oneWay':
|
||||
case 'oneToOne':
|
||||
case 'manyToOne':
|
||||
case 'oneToManyMorph':
|
||||
params.values[association.alias] = null;
|
||||
break;
|
||||
case 'oneToMany':
|
||||
case 'manyToMany':
|
||||
case 'manyToManyMorph':
|
||||
params.values[association.alias] = [];
|
||||
break;
|
||||
default:
|
||||
}
|
||||
});
|
||||
|
||||
await Post.updateRelations(params);
|
||||
|
||||
return Post.forge(params).destroy();
|
||||
},
|
||||
|
||||
/**
|
||||
* Promise to search a/an post.
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
|
||||
search: async (params) => {
|
||||
// Convert `params` object to filters compatible with Bookshelf.
|
||||
const filters = strapi.utils.models.convertParams('post', params);
|
||||
// Select field to populate.
|
||||
const populate = Post.associations
|
||||
.filter(ast => ast.autoPopulate !== false)
|
||||
.map(ast => ast.alias);
|
||||
|
||||
const associations = Post.associations.map(x => x.alias);
|
||||
const searchText = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => ['string', 'text'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const searchNoText = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => !['string', 'text', 'boolean', 'integer', 'decimal', 'float'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const searchInt = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => ['integer', 'decimal', 'float'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const searchBool = Object.keys(Post._attributes)
|
||||
.filter(attribute => attribute !== Post.primaryKey && !associations.includes(attribute))
|
||||
.filter(attribute => ['boolean'].includes(Post._attributes[attribute].type));
|
||||
|
||||
const query = (params._q || '').replace(/[^a-zA-Z0-9.-\s]+/g, '');
|
||||
|
||||
return Post.query(qb => {
|
||||
// Search in columns which are not text value.
|
||||
searchNoText.forEach(attribute => {
|
||||
qb.orWhereRaw(`LOWER(${attribute}) LIKE '%${_.toLower(query)}%'`);
|
||||
});
|
||||
|
||||
if (!_.isNaN(_.toNumber(query))) {
|
||||
searchInt.forEach(attribute => {
|
||||
qb.orWhereRaw(`${attribute} = ${_.toNumber(query)}`);
|
||||
});
|
||||
}
|
||||
|
||||
if (query === 'true' || query === 'false') {
|
||||
searchBool.forEach(attribute => {
|
||||
qb.orWhereRaw(`${attribute} = ${_.toNumber(query === 'true')}`);
|
||||
});
|
||||
}
|
||||
|
||||
// Search in columns with text using index.
|
||||
switch (Post.client) {
|
||||
case 'mysql':
|
||||
qb.orWhereRaw(`MATCH(${searchText.join(',')}) AGAINST(? IN BOOLEAN MODE)`, `*${query}*`);
|
||||
break;
|
||||
case 'pg': {
|
||||
const searchQuery = searchText.map(attribute =>
|
||||
_.toLower(attribute) === attribute
|
||||
? `to_tsvector(${attribute})`
|
||||
: `to_tsvector('${attribute}')`
|
||||
);
|
||||
|
||||
qb.orWhereRaw(`${searchQuery.join(' || ')} @@ to_tsquery(?)`, query);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (filters.sort) {
|
||||
qb.orderBy(filters.sort.key, filters.sort.order);
|
||||
}
|
||||
|
||||
if (filters.skip) {
|
||||
qb.offset(_.toNumber(filters.skip));
|
||||
}
|
||||
|
||||
if (filters.limit) {
|
||||
qb.limit(_.toNumber(filters.limit));
|
||||
}
|
||||
}).fetchAll({
|
||||
withRelated: populate
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -20,6 +20,7 @@
|
||||
"nodemon": "^1.18.9"
|
||||
},
|
||||
"dependencies": {
|
||||
"args-list": "^0.3.3",
|
||||
"async": "^2.6.2",
|
||||
"body-parser": "^1.18.3",
|
||||
"buffer": "^5.2.1",
|
||||
@ -27,7 +28,6 @@
|
||||
"compression": "^1.7.4",
|
||||
"cors": "^2.8.5",
|
||||
"crypto": "^1.0.1",
|
||||
"events": "^3.0.0",
|
||||
"express": "^4.16.4",
|
||||
"express-validation": "^1.0.2",
|
||||
"fs": "^0.0.1-security",
|
||||
|
||||
188
server.js
188
server.js
@ -1,136 +1,76 @@
|
||||
#!/usr/bin/env node
|
||||
'use strict';
|
||||
|
||||
const { EventEmitter } = require('events');
|
||||
const http = require('http');
|
||||
const { toLower } = require('lodash');
|
||||
const utils = require('./utils');
|
||||
const { assign, toLower } = require('lodash');
|
||||
|
||||
const {
|
||||
express,
|
||||
logger,
|
||||
nestedConfigurations,
|
||||
appConfigurations
|
||||
} = require('./core');
|
||||
const config = require('./config');
|
||||
const { express, logger, models } = require('./core');
|
||||
|
||||
class Server extends EventEmitter {
|
||||
constructor() {
|
||||
super();
|
||||
const currentState = assign({
|
||||
launchedAt: Date.now(),
|
||||
appPath: process.cwd(),
|
||||
host: process.env.HOST || process.env.HOSTNAME || 'localhost',
|
||||
port: process.env.PORT || 1337,
|
||||
environment: toLower(process.env.NODE_ENV) || 'development',
|
||||
connections: {}
|
||||
}, config);
|
||||
|
||||
this.setMaxListeners(100);
|
||||
|
||||
// Logger.
|
||||
this.log = logger;
|
||||
|
||||
// Default configurations.
|
||||
this.config = {
|
||||
launchedAt: Date.now(),
|
||||
appPath: process.cwd(),
|
||||
host: process.env.HOST || process.env.HOSTNAME || 'localhost',
|
||||
port: process.env.PORT || 1337,
|
||||
environment: toLower(process.env.NODE_ENV) || 'development',
|
||||
environments: {},
|
||||
};
|
||||
|
||||
// Bind context functions.
|
||||
this.loadFile = utils.loadFile.bind(this);
|
||||
function stop(server) {
|
||||
// Destroy server and available connections.
|
||||
if (server) {
|
||||
server.close();
|
||||
}
|
||||
|
||||
async init() {
|
||||
this.emit('server:init');
|
||||
await nestedConfigurations.call(this);
|
||||
await appConfigurations.call(this);
|
||||
|
||||
/*await Promise.all([
|
||||
modules.call(this),
|
||||
]).then(results => {
|
||||
this.modules = results[0];
|
||||
});*/
|
||||
}
|
||||
|
||||
async start() {
|
||||
try {
|
||||
|
||||
// Emit starting event.
|
||||
this.emit('server:starting');
|
||||
|
||||
await this.init();
|
||||
|
||||
// Expose `express`.
|
||||
this.app = await express.call(this);
|
||||
|
||||
// Mount the HTTP server.
|
||||
this.server = http.createServer(this.app);
|
||||
await this.enhancer.call(this);
|
||||
|
||||
// Launch server.
|
||||
this.server.listen(this.config.port, async (err) => {
|
||||
|
||||
if (err) {
|
||||
this.log.debug(`⚠️ Server wasn't able to start properly.`);
|
||||
this.log.error(err);
|
||||
return this.stop();
|
||||
}
|
||||
|
||||
this.log.info('Time: ' + new Date());
|
||||
this.log.info('Launched in: ' + (Date.now() - this.config.launchedAt) + ' ms');
|
||||
this.log.info('Environment: ' + this.config.environment);
|
||||
this.log.info('Process PID: ' + process.pid);
|
||||
//this.log.info(`Version: ${this.config.info.strapi} (node v${this.config.info.node})`);
|
||||
this.log.info('To shut down your server, press <CTRL> + C at any time');
|
||||
this.log.info(`⚡️ Server: ${this.config.url}`);
|
||||
|
||||
// Emit started event.
|
||||
this.emit('server:started');
|
||||
});
|
||||
} catch (err) {
|
||||
this.log.debug(`⛔️ Server wasn't able to start properly.`);
|
||||
this.log.error(err);
|
||||
console.log(err);
|
||||
this.stop();
|
||||
}
|
||||
}
|
||||
|
||||
async enhancer() {
|
||||
this.connections = {};
|
||||
|
||||
this.server.on('connection', conn => {
|
||||
const key = conn.remoteAddress + ':' + conn.remotePort;
|
||||
this.connections[key] = conn;
|
||||
|
||||
conn.on('close', () => {
|
||||
delete this.connections[key];
|
||||
});
|
||||
});
|
||||
|
||||
this.server.on('error', err => {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
this.log.debug(`⛔️ Server wasn't able to start properly.`);
|
||||
this.log.error(`The port ${err.port} is already used by another application.`);
|
||||
this.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
});
|
||||
}
|
||||
|
||||
stop() {
|
||||
this.emit('server:stoping');
|
||||
|
||||
// Destroy server and available connections.
|
||||
if (this.server) {
|
||||
this.server.close();
|
||||
}
|
||||
|
||||
process.send('stop');
|
||||
// Kill process.
|
||||
process.exit(1);
|
||||
}
|
||||
process.send('stop');
|
||||
// Kill process.
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const server = http.createServer(express);
|
||||
server.on('connection', conn => {
|
||||
const key = conn.remoteAddress + ':' + conn.remotePort;
|
||||
currentState.connections[key] = conn;
|
||||
|
||||
(() => {
|
||||
const server = new Server();
|
||||
server.start();
|
||||
})();
|
||||
conn.on('close', () => {
|
||||
delete currentState.connections[key];
|
||||
});
|
||||
});
|
||||
|
||||
server.on('error', err => {
|
||||
if (err.code === 'EADDRINUSE') {
|
||||
logger.debug(`⛔️ Server wasn't able to start properly.`);
|
||||
logger.error(`The port ${err.port} is already used by another application.`);
|
||||
stop(server);
|
||||
return;
|
||||
}
|
||||
|
||||
console.error(err);
|
||||
});
|
||||
|
||||
try {
|
||||
models.sequelize.sync().then(() => {
|
||||
// Launch server.
|
||||
server.listen(currentState.port, (err) => {
|
||||
if (err) {
|
||||
logger.debug(`⚠️ Server wasn't able to start properly.`);
|
||||
logger.error(err);
|
||||
return stop(server);
|
||||
}
|
||||
|
||||
logger.info('Time: ' + new Date());
|
||||
logger.info('Launched in: ' + (Date.now() - currentState.launchedAt) + ' ms');
|
||||
logger.info('Environment: ' + currentState.environment);
|
||||
logger.info('Process PID: ' + process.pid);
|
||||
//logger.info(`Version: ${this.config.info.strapi} (node v${this.config.info.node})`);
|
||||
logger.info('To shut down your server, press <CTRL> + C at any time');
|
||||
logger.info(`⚡️ Server: http://${currentState.host}:${currentState.port}`);
|
||||
|
||||
});
|
||||
});
|
||||
} catch (err) {
|
||||
logger.debug(`⛔️ Server wasn't able to start properly.`);
|
||||
logger.error(err);
|
||||
console.error(err);
|
||||
stop(server);
|
||||
}
|
||||
|
||||
10
yarn.lock
10
yarn.lock
@ -119,6 +119,11 @@ argparse@^1.0.7:
|
||||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
args-list@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/args-list/-/args-list-0.3.3.tgz#d3fa5b7fe49ec96efb1e99adf20e7cfacc179956"
|
||||
integrity sha1-0/pbf+SeyW77Hpmt8g58+swXmVY=
|
||||
|
||||
arr-diff@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
|
||||
@ -971,11 +976,6 @@ etag@~1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
events@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/events/-/events-3.0.0.tgz#9a0a0dfaf62893d92b875b8f2698ca4114973e88"
|
||||
integrity sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==
|
||||
|
||||
execa@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user