Skip to content

Commit ba4cf4a

Browse files
initial commit
0 parents  commit ba4cf4a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+10552
-0
lines changed

.babelrc

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"env": {
3+
"test": {
4+
"plugins": [ "istanbul" ]
5+
}
6+
}
7+
}

.dockerignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
node_modules
2+
npm-debug.log

.eslintrc.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
module.exports = {
2+
'env': {
3+
'es6': true,
4+
'node': true,
5+
'mocha': true
6+
},
7+
'extends': 'airbnb',
8+
'parserOptions': {
9+
'ecmaVersion': 2018,
10+
'sourceType': 'module'
11+
},
12+
'rules': {
13+
'indent': [
14+
'error',
15+
2
16+
],
17+
'linebreak-style': [
18+
'error',
19+
'unix'
20+
],
21+
'quotes': [
22+
'error',
23+
'single'
24+
],
25+
'semi': [
26+
'error',
27+
'never'
28+
],
29+
'import/no-unresolved': 'off',
30+
'no-underscore-dangle': 'off',
31+
'guard-for-in': 'off',
32+
'no-restricted-syntax': 'off',
33+
'no-await-in-loop': 'off',
34+
},
35+
overrides: [
36+
{
37+
files: ['*-test.js', '*.spec.js'],
38+
rules: {
39+
'no-unused-expressions': 'off',
40+
'func-names': 'off',
41+
'prefer-arrow-callback': 'off'
42+
}
43+
}
44+
],
45+
globals: {
46+
'expect': true,
47+
'factory': true,
48+
'sandbox': true,
49+
'server': true
50+
}
51+
}

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
.nyc_output
3+
docs
4+
coverage
5+
.DS_store

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Admin Bro
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const NotImplementedError = require('../../utils/not-implemented-error')
2+
3+
/**
4+
* Representation of an ORM/database AdminBro
5+
*/
6+
class AbstractDatabase {
7+
/**
8+
* Return name of the database
9+
* @return {String}
10+
*/
11+
name() {
12+
throw new NotImplementedError()
13+
}
14+
15+
/**
16+
* returns array of all models (collections/tables) in the database
17+
* @return {AbstractModel[]}
18+
*/
19+
models() {
20+
throw new NotImplementedError()
21+
}
22+
23+
/**
24+
* returns model for given name
25+
* @return {AbstractModel}
26+
*/
27+
find(modelName) {
28+
throw new NotImplementedError()
29+
}
30+
}
31+
32+
module.exports = AbstractDatabase
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
class AbstractInstance {
2+
constructor(args) {
3+
this.args = args
4+
}
5+
6+
save(params) {
7+
8+
}
9+
}
10+
11+
module.exports = AbstractInstance
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
const NotImplementedError = require('../../utils/not-implemented-error')
2+
3+
/**
4+
* Representation of a ORM Model in AdminBro
5+
*/
6+
class AbstractModel {
7+
/**
8+
* Return name of the model
9+
* @return {String}
10+
*/
11+
name() {
12+
throw new NotImplementedError()
13+
}
14+
15+
/**
16+
* returns array of properties
17+
* @return {AbstractProperty[]}
18+
*/
19+
properties() {
20+
throw new NotImplementedError()
21+
}
22+
23+
/**
24+
* returns property object for given field
25+
* @return {AbstractProperty}
26+
*/
27+
property(name) {
28+
throw new NotImplementedError()
29+
}
30+
31+
/**
32+
* Returns number of elements for given model
33+
* @return {[type]} [description]
34+
*/
35+
count() {
36+
throw new NotImplementedError()
37+
}
38+
39+
/**
40+
* Returns actual records for given model
41+
* @param {Object} where query
42+
* @param {Number} options.limit how many records should be taken
43+
* @param {Number} options.offset offset
44+
* @return {Object[]} list of all records
45+
*/
46+
find(where, { limit=20, offset=0 }) {
47+
throw new NotImplementedError()
48+
}
49+
}
50+
51+
module.exports = AbstractModel
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
const TITLE_COLUMN_NAMES = ['title', 'name', 'subject']
2+
3+
class AbstractProperty {
4+
5+
/**
6+
* Name of the property
7+
* @return {[type]} [description]
8+
*/
9+
name() {
10+
11+
}
12+
13+
/**
14+
* Return type of a property
15+
* @return {String} One of available property types:
16+
* [id, string, object, float, number, boolean,
17+
* text, date]
18+
*/
19+
type() {
20+
21+
}
22+
23+
/**
24+
* When properties are nested - parent property should have its children
25+
* @return {AbstractProperty[]} [description]
26+
*/
27+
childProperties() {
28+
return null
29+
}
30+
}
31+
32+
module.exports = AbstractProperty
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
const MongooseDatabase = require('./mongoose/database')
2+
3+
const DatabaseFactory = (database) => {
4+
if (database.constructor.name === 'Mongoose') {
5+
return database.connections.map(connection => new MongooseDatabase(connection))
6+
}
7+
throw new Error(`unsupported database type ${database}`)
8+
}
9+
10+
module.exports = DatabaseFactory
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const AbstractDatabase = require('../abstract/database')
2+
const Model = require('./model')
3+
4+
/**
5+
* Adapter for mongoose database
6+
*/
7+
class Database extends AbstractDatabase {
8+
constructor(connection) {
9+
super(connection)
10+
this.connection = connection
11+
}
12+
13+
models() {
14+
return Model.all(this.connection)
15+
}
16+
17+
name() {
18+
return this.connection.name
19+
}
20+
21+
find(modelName) {
22+
return Model.find(this.connection, modelName)
23+
}
24+
}
25+
26+
module.exports = Database
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
const AbstractInstance = require('../abstract/instance')
2+
3+
class Instance extends AbstractInstance {
4+
}
5+
6+
module.exports = Instance
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const AbstractModel = require('../abstract/model')
2+
const Instance = require('./instance')
3+
const Property = require('./property')
4+
5+
/**
6+
* Adapter for mongoose model
7+
*/
8+
class Model extends AbstractModel {
9+
/**
10+
* Return all available models for given connection
11+
* @param {Object} mongooseConnection mongoose connection object
12+
* @return {Model[]} list of all models in given mongo database
13+
*
14+
* @example
15+
* const mongoose = require('mongoose')
16+
*
17+
* const connection = await mongoose.connect(process.env.MONGO_URL)
18+
* Model.all(connection)
19+
*/
20+
static all(mongooseConnection) {
21+
return mongooseConnection.modelNames().map(name => Model.find(mongooseConnection, name))
22+
}
23+
24+
/**
25+
* Return Model object for given collection name
26+
* @param {Object} mongooseConnection mongoose connection object
27+
* @param {String} name name of mongoose model
28+
* @return {Model} model adapter for given mongodb model
29+
*
30+
* @example
31+
* const mongoose = require('mongoose')
32+
*
33+
* const connection = await mongoose.connect(process.env.MONGO_URL)
34+
* Model.all(connection)
35+
*/
36+
static find(mongooseConnection, name) {
37+
const mongoModel = mongooseConnection.model(name)
38+
return new Model(mongoModel)
39+
}
40+
41+
constructor(mongoModel) {
42+
super(mongoModel)
43+
this.model = mongoModel
44+
}
45+
46+
async count() {
47+
return this.model.countDocuments()
48+
}
49+
50+
async find(query, { limit = 20, offset = 0 }) {
51+
const raw = await this.model.find({}).skip(offset).limit(limit)
52+
return raw.map(m => new Instance(m))
53+
}
54+
55+
name() {
56+
return this.model.modelName
57+
}
58+
59+
properties() {
60+
const properties = []
61+
for (const [name, path] of Object.entries(this.model.schema.paths)) {
62+
const prop = new Property(name, path)
63+
properties.push(prop)
64+
}
65+
return properties
66+
}
67+
68+
property(name) {
69+
return new Property(name, this.model.schema.paths[name])
70+
}
71+
}
72+
73+
module.exports = Model
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
const AbstractProperty = require('../abstract/property')
2+
3+
class Property extends AbstractProperty {
4+
constructor(name, mongoosePath) {
5+
super()
6+
this.name = name
7+
this.path = mongoosePath
8+
}
9+
}
10+
11+
module.exports = Property
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class NotImplementedError extends Error {
2+
constructor(args) {
3+
super(args)
4+
this.message = 'You have to implement this'
5+
}
6+
}
7+
8+
module.exports = NotImplementedError

admin/backend/utils/renderer.js

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
const pug = require('pug')
2+
const sass = require('node-sass')
3+
const { promisify } = require('util')
4+
5+
class Renderer {
6+
constructor(view, data) {
7+
this.view = view
8+
this.data = data
9+
10+
this.styles_path = 'admin/frontend/styles/index.css.sass'
11+
this.views_path = 'admin/frontend/views/'
12+
}
13+
14+
async styles() {
15+
const style = await promisify(sass.render)({
16+
file: this.styles_path,
17+
})
18+
return style.css.toString('utf-8')
19+
}
20+
21+
async render() {
22+
const data = {
23+
adminStyles: await this.styles(),
24+
...this.data,
25+
}
26+
const viewFunction = pug.compileFile(`${this.views_path}${this.view}.pug`)
27+
return viewFunction(data)
28+
}
29+
}
30+
31+
module.exports = Renderer

admin/frontend/styles/index.css.sass

Whitespace-only changes.

0 commit comments

Comments
 (0)