yekonga-server
Version:
Yekonga Server
649 lines (573 loc) • 25.1 kB
Markdown
# Yekonga Server
[](https://oclif.io)
[](https://npmjs.org/package/yekonga-server)
[](https://npmjs.org/package/yekonga-server)
[](https://github.com/https://github.com/robertkonga/yekonga-server/yekonga-server/blob/master/package.json)
Yekonga Server is an open source backend that can be deployed to any infrastructure that can run Node.js.
## Description
Yekonga Server works with the Express web application framework. It can be added to existing web applications, or run by itself.
## Contents
- [Getting Started](#getting-started)
- [Installing](#installing)
- [Create server](#Create-server)
- [Running Yekonga Server](#running-yekonga-server)
- [Database Structure](#database-structure)
- [Configuration](#configuration)
- [Configuration value can be accessed as below](#configuration-value-can-be-accessed-as-below)
- [Configuration is the json file with below data](#configuration-is-the-json-file-with-below-data)
- [Permissions configuration](#permissions-configuration)
- [Graphql configuration](#graphql-configuration)
- [Graphql.authQuery configuration](#graphql-authQuery-configuration)
- [Database configuration](#database-configuration)
- [Database.{key} configuration](#databasekey-configuration)
- [Authentication configuration](#authentication-configuration)
- [Ports configuration](#ports-configuration)
- [Mail configuration](#mail-configuration)
- [Mail.smtp configuration](#mailsmtp-configuration)
- [Database Function](#database-function)
- [DataModel Functions](#datamodel-functions)
- [Database Functions](#database-functions)
- [Cloud Functions](#cloud-functions)
- [Define Functions](#define-functions)
- [Trigger Functions](#trigger-functions)
- [Custom url](#custom-url)
- [Helper functions](#helper-functions)
- [Graphql](#graphql)
- [Custom Action](#custom-action)
- [Custom Graphql](#custom-graphql)
- [Author](#author)
- [Version History](#version-history)
- [License](#license)
## Getting Started
### Installing
you can install globelly
```
npm install -g yekonga-server
```
OR direct to your project
```
npm install --save yekonga-server
```
### Create server
```sh-session
VERSION
yekonga-server/2.1.7 win32-x64 node-v14.15.4
USAGE
$ yekonga [COMMAND]
COMMANDS
create Describe the command here
generate Describe the command here
help display help for yekonga
```
### Create project command
```sh-session
USAGE
$ yekonga create [PROJECT]
OPTIONS
-d, --dirname=dirname app directory name
-f, --force Force generate / overide existing
-h, --help show CLI help
-n, --name=name app name
-p, --port=port [default: 1093] server running port
-p, --public=public [default: public] generate public directory
-t, --triggers create triggers function
-t, --template generate template
-v, --version show CLI version
```
### Generate triggers command
```sh-session
USAGE
$ yekonga generate
OPTIONS
-c, --config=config App config file name
-d, --database=database App database structure file name
-f, --force Force generate / overide existing
-h, --help show CLI help
-t, --trigger=trigger Trigger name
-t, --triggers Force generate / overide existing
-v, --version show CLI version
```
### Running Yekonga Server
```js
require('yekonga-server');
// configation json file
const config = require('./config.json');
// database structure json file
const database = require('./database.json');
// set configarations
Yekonga.setConfig(config, database);
// start the server
Yekonga.startServer();
```
## Database structure
database structure is json array of objects, Database structure sample json file with `"users"` collection
```json
[
{
"_id": { "collection": "users" },
"userId": { "type": "String", "default": null, "required": true },
"firstName": { "type": "String", "default": null, "required": true },
"lastName": { "type": "String", "default": null, "required": true },
"email": { "type": "String", "default": null, "required": true },
"password": { "type": "String", "default": null, "required": true },
"role": { "type": "String", "default": null, "required": true },
"token": { "type": "String", "default": null, "required": false },
"status": { "type": "Number", "default": 0, "required": true },
"isActive": { "type": "Boolean", "default": false, "required": true },
"createdAt": { "type": "Date", "default": "now", "required": false },
"updatedAt": { "type": "Date", "default": "now", "required": false }
},
]
```
Take one field of users collection
```json
"userId": { "type": "String", "default": null, "required": true },
```
* ```"userId"``` is the field of the collection/table
* ```"type"``` => ```userId.type``` is data type to be stored
* ```"default"``` => ```userId.default``` is default value
* ```"required"``` => ```userId.required``` werether the value required or not
Database structure can be accessed via
```js
Yekonga.Schema
```
## Configuration
#### Configuration value can be accessed as below
```js
// config value can be access by
Yekonga.Config.{key}
// example
Yekonga.Config.appName
Yekonga.Config.ports.server
```
#### Configuration is the json file with below data
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `appName` | System | String | Option | Name of the application |
| `appId` | null | String | Option | Application ID |
| `masterKey` | null | String | Option | application key |
| `enableAppKey` | false | boolean | Option | Make api access require appId or not |
| `domain` | null | string | Option | main domain that allow to access app |
| `domainAlias` | [] | array | Option | all alowed domains |
| `address` | System | String | Option | host IP address
| `baseUrl` | System | String | Option | - |
| `restApi` | System | String | Option | - |
| `restAuthApi` | System | String | Option | - |
| `secureOnly` | System | String | Option | - |
| `debug` | System | String | Option | - |
| `endToEndEncryption` | System | String | Option | - |
| `authPlaygroundEnable` | System | String | Option | - |
| `apiPlaygroundEnable` | System | String | Option | - |
| `enableDashboard` | false | boolean | Option | - |
| `allowCreateFrontend` | false | boolean | Option | - |
| `namingConvection` | camelcase | String | Option | `camelcase`, `underscorecase`|
| `columnNamingConvection` | underscorecase | String | Option | - |
| `namingConvectionOptions` | ["camelcase", "underscorecase"] | array | Option | - |
| `public` | public | String | Option | - |
| `cloud` | null | String | Option | - |
| `logFile` | null | String | Option | - |
| `emailTemplate` | null | String | Option | - |
| `googleApiKey` | null | String | Option | - |
| `permissions` | [more...](#permissions-configuration) | object | Option | - |
| `graphql` | [more...](#graphql-configuration) | object | Option | - |
| `defaultDatabase` | mongoDB | String | Option | - | |
| `database` | [more...](#database-configuration) | object | required | - |
| `authentication` | [more...](#authentication-configuration) | object | Option | - |
| `ports` | [more...](#ports-configuration) | object | Option | - |
| `mail` | [more...](#mail-configuration) | object | Option | - |
#### Permissions configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `authActions` | [] | array | Option | - |
| `guestActions` | [] | array | Option | - |
#### Graphql configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `apiRoute` | null | string | Option | graphql api route |
| `apiAuthRoute` | null | string | Option | graphql api route |
| `customTypes` | null | string | Option | relative path of custom graphql schema |
| `customResolvers` | null | string | Option | relative path of custom graphql resolver |
| `customAuthTypes` | null | string | Option | relative path of auth custom graphql schema |
| `customAuthResolvers` | null | string | Option | relative path of auth custom graphql resolver |
| `enabledForClasses` | [] | array | Option | - |
| `disabledForClasses` | [] | array | Option | - |
| `authResolvers` | [] | array | Option | - |
| `authClasses` | [] | array | Option | - |
| `guestResolvers` | [] | array | Option | - |
| `guestClasses` | [] | array | Option | - |
| `authQuery` | [more...](#graphql.authQuery-onfiguration) | string | Option | - |
#### Graphql.authQuery configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `user` | [] | array | Option | field that are to be queried on users
| `account` | [] | array | Option | field that are to be queried on accounts
#### Database configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `{key}` | [more...](#Database.{key}-configuration) | object | Option | - |
#### Database.{key} configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `type` | null | string | Option | - |
| `host` | null | string | Option | - |
| `port` | null | string | Option | - |
| `databaseName` | null | string | Option | - |
| `username` | null | string | Option | - |
| `password` | null | string | Option | - |
| `prefix` | null | string | Option | - |
| `generateID` | null | string | Option | - |
| `generateIDLengh` | null | string | Option | - |
#### Authentication configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `saltRound` | 7 | number | Option | - |
| `algorithm` | HS512 | string | Option | - |
| `tokenSecret` | null | string | Option | - |
| `cryptojsKey` | null | string | Option | - |
| `cryptojsIv` | null | string | Option | - |
#### Ports configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `server` | null | number | Option | - |
| `secure` | null | number | Option | - |
| `socket` | null | number | Option | - |
| `redis` | null | number | Option | - |
#### Mail configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `smtp` | [more...](#Mail.smtp-configuration) | object | Option | - |
#### Mail.smtp configuration
| Key | Default Value | Type | | Description |
|-|-|-|-|-|
| `service` | null | string | Option | - |
| `host` | null | string | Option | - |
| `port` | null | number | Option | - |
| `secure` | null | boolean | Option | - |
| `from` | null | string | Option | - |
| `domain` | null | string | Option | - |
| `username` | null | string | Option | - |
| `password` | null | string | Option | - |
## Database Function
### DataModel Functions
> All DataModel method return promise
```js
Yekonga.DataModel.{Class}.{method}(args);
```
| Method | Params | Result | Description |
|-|-|-|-|
| `findOne` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `find` | `filter`, `context`, `isAdmin` | array | return array of object of Model class eg `User` |
| `paginate` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `download` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `summary` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `count` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `sum` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `max` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `min` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `graph` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `create` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `update` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
| `delete` | `filter`, `context`, `isAdmin` | object | return object of Model class eg `User` |
#### Examples
```js
let user = await Yekonga.DataModel.User.findOne({}, null, true);
```
### Database Functions
#### Examples
```js
// single user object
let users = Yekonga.DB.table('users')
.where('userId', 'xxx')
.findOne();
// list of users
let users = Yekonga.DB.table('users').find();
```
## Cloud Functions
### Define Functions
Define function
```js
Yekonga.Cloud.define('someFunction', async function(data) {
});
```
Run defined function
```js
Yekonga.Cloud.run('someFunction', data);
```
### Trigger Functions
Before Login
```js
Yekonga.Cloud.beforeLogin(async (data) => { /* code goes here */ });
```
After Login
```js
Yekonga.Cloud.afterLogin(async (data) => { /* code goes here */ });
```
Before OTP
```js
Yekonga.Cloud.beforeOtp(async (data) => { /* code goes here */ });
```
After OTP
```js
Yekonga.Cloud.afterOtp(async (data) => { /* code goes here */ });
```
Before Registration
```js
Yekonga.Cloud.beforeRegistration(async (data) => { /* code goes here */ });
```
After Registration
```js
Yekonga.Cloud.afterRegistration(async (data) => { /* code goes here */ });
```
Before Reset Password
```js
Yekonga.Cloud.beforeResetPassword(async (data) => { /* code goes here */ });
```
After Reset Password
```js
Yekonga.Cloud.afterResetPassword(async (data) => { /* code goes here */ });
```
Before Change Password
```js
Yekonga.Cloud.beforeChangePassword(async (data) => { /* code goes here */ });
```
After Change Password
```js
Yekonga.Cloud.afterChangePassword(async (data) => { /* code goes here */ });
```
Before Logout
```js
Yekonga.Cloud.beforeLogout(async (data) => { /* code goes here */ });
```
After Logout
```js
Yekonga.Cloud.afterLogout(async (data) => { /* code goes here */ });
```
Before Find
```js
Yekonga.Cloud.beforeFind('User', async (filter, context) => { /* code goes here */ });
```
After Find
```js
Yekonga.Cloud.afterFind('User', async (filter, context) => { /* code goes here */ });
```
Before Save
```js
Yekonga.Cloud.beforeSave('User', async (input, filter, context) => { /* code goes here */ });
```
After Save
```js
Yekonga.Cloud.afterSave('User', async (result, input, context) => { /* code goes here */ });
```
Before Create
```js
Yekonga.Cloud.beforeCreate('User', async (input, filter, context) => { /* code goes here */ });
```
After Create
```js
Yekonga.Cloud.afterCreate('User', async (result, input, context) => { /* code goes here */ });
```
Before Update
```js
Yekonga.Cloud.beforeUpdate('User', async (input, filter, context) => { /* code goes here */ });
```
After Update
```js
Yekonga.Cloud.afterUpdate('User', async (result, input, context) => { /* code goes here */ });
```
Before Delete
```js
Yekonga.Cloud.beforeDelete('User', async (filter, context) => { /* code goes here */ });
```
After Delete
```js
Yekonga.Cloud.afterDelete('User', async (result, context) => { /* code goes here */ });
```
### Custom url
```js
const app = Yekonga.route;
app.get('/custom-url', function(req, res){
return res.send('This is custom url');
});
```
### Helper functions
| Method | Params | Result | Description |
|-|-|-|-|
| Yekonga.Helper.execAsync | (cmd, pipe, callback) | String | - | | String | - |
| Yekonga.Helper.encrypt | (data) | String | - |
| Yekonga.Helper.decrypt | (data) | String | - |
| Yekonga.Helper.bcrypt | (value) | String | - |
| Yekonga.Helper.formatPhone | (value) | String | - |
| Yekonga.Helper.get, async (url, headers) | String | - |
| Yekonga.Helper.post, async (url, body, headers, multipart) | String | - |
| Yekonga.Helper.request | (method, options) | String | - |
| Yekonga.Helper.saveFile | (data, dir) | String | - |
| Yekonga.Helper.generateFile | (template, options) | String | - |
| Yekonga.Helper.createFile | (file, data, isRoot) | String | - |
| Yekonga.Helper.writeFile | (file, data, isRoot) | String | - |
| Yekonga.Helper.readFile | (file) | String | - |
| Yekonga.Helper.copy | (source, dist, root) | String | - |
| Yekonga.Helper.rootPath | (filename) | String | - |
| Yekonga.Helper.realpath | (filename) | String | - |
| Yekonga.Helper.setLocation | (location) | String | - |
| Yekonga.Helper.checkLocation | (name, tag, parent) | String | - |
| Yekonga.Helper.storeFile | (req, res) | String | - |
| Yekonga.Helper.setLocalAddress, async (content) | String | - |
| Yekonga.Helper.getSystemInfo | () | String | - |
| Yekonga.Helper.textTemplate | (templateString, data) | String | - |
| Yekonga.Helper.uuid | () | String | - |
| Yekonga.Helper.uuid3 | () | String | - |
| Yekonga.Helper.uuid4 | () | String | - |
| Yekonga.Helper.uuid5 | () | String | - |
| Yekonga.Helper.uniqueId | (table) | String | - |
| Yekonga.Helper.getRandomString | (length, type) | String | - |
| Yekonga.Helper.getRandomInt | (length) | String | - |
| Yekonga.Helper.getHexString | (length) | String | - |
| Yekonga.Helper.databaseUUID | () | String | - |
| Yekonga.Helper.getTitle | (value) | String | - |
| Yekonga.Helper.getHeading | (value) | String | - |
| Yekonga.Helper.getSentence | (value) | String | - |
| Yekonga.Helper.getSlug | (value) | String | - |
| Yekonga.Helper.getLink | (value) | String | - |
| Yekonga.Helper.getName | (value) | String | - |
| Yekonga.Helper.getTable | (value) | String | - |
| Yekonga.Helper.getClass | (value) | String | - |
| Yekonga.Helper.getClassVariable | (value, singular) | String | - |
| Yekonga.Helper.getVariable | (value) | String | - |
| Yekonga.Helper.getColumn | (value) | String | - |
| Yekonga.Helper.formatToVariables | (value) | String | - |
| Yekonga.Helper.formatToColumn | (value) | String | - |
| Yekonga.Helper.getDefaultValues | (value) | String | - |
| Yekonga.Helper.getValidFields | (input, validFields, isCreate, relations) | String | - |
| Yekonga.Helper.getUnderscore | (value) | String | - |
| Yekonga.Helper.isRelation | (value) | String | - |
| Yekonga.Helper.isBoolean | (value) | String | - |
| Yekonga.Helper.toPlural | (value) | String | - |
| Yekonga.Helper.toSingular | (value) | String | - |
| Yekonga.Helper.getTableByName | (value) | String | - |
| Yekonga.Helper.getPrimaryName | (schema) | String | - |
| Yekonga.Helper.getChildren | (schema) | String | - |
| Yekonga.Helper.getParents | (schema) | String | - |
| Yekonga.Helper.getRelationName | (table) | String | - |
| Yekonga.Helper.getAbbreviation | (name) | String | - |
| Yekonga.Helper.getTimestampInt | (value) | String | - |
| Yekonga.Helper.getIsoTimestamp | (value) | String | - |
| Yekonga.Helper.toTimestampString | (value, format = 'YYYY-MM-DD HH:mm:ss') | String | - |
| Yekonga.Helper.getTimestamp | (format = 'YYYY-MM-DD HH:mm:ss') | String | - |
| Yekonga.Helper.getDate | (format = 'YYYY-MM-DD') | String | - |
| Yekonga.Helper.getTime | (format = 'HH:mm') | String | - |
| Yekonga.Helper.copyJson | (value) | String | - |
| Yekonga.Helper.isGeneralTable | (data, ignore = false) | String | - |
| Yekonga.Helper.isId | (name) | String | - |
| Yekonga.Helper.isColumnUrl | (name) | String | - |
| Yekonga.Helper.isColumnMultiple | (name) | String | - |
| Yekonga.Helper.isLongText | (name) | String | - |
| Yekonga.Helper.isTimestampColumn | (name, data) | String | - |
| Yekonga.Helper.isSearchColumn | (name, data) | String | - |
| Yekonga.Helper.isTypeColumn | (name, data) | String | - |
| Yekonga.Helper.isMap | (name) | String | - |
| Yekonga.Helper.isNumeric | (value) | String | - |
| Yekonga.Helper.getGraphqlType | (name, field, isInput = false) | String | - |
| Yekonga.Helper.getMongodbType | (name, field) | String | - |
| Yekonga.Helper.getMongodbDefault | (name, field) | String | - |
| Yekonga.Helper.getType | (name, value) | String | - |
| Yekonga.Helper.getInput | (name, type) | String | - |
| Yekonga.Helper.bcryptPassword | (value) | String | - |
| Yekonga.Helper.attemptLogin | async (key, value, password, type = "normal") | String | - |
| Yekonga.Helper.getLoginData | async (user, accountId = null) | String | - |
| Yekonga.Helper.getToken | (payload) | String | - |
| Yekonga.Helper.getRelatedTable | (value) | String | - |
| Yekonga.Helper.getSchemaOf | (name) | String | - |
| Yekonga.Helper.schemaToData | (name) | String | - |
| Yekonga.Helper.getTableDataWithRelations | () | String | - |
| Yekonga.Helper.translate | async (content, from, to) | String | - |
| Yekonga.Helper.colorize = function colorize(color, output) | String | - |
| Yekonga.Helper.printLog | (title, text, color = 'white', newLine = true) | String | - |
| Yekonga.Helper.log | (title, text, color = 'white') | String | - |
| Yekonga.Helper.logInline | (title, text, color = 'white') | String | - |
| Yekonga.Helper.wait | async (time = 10000) | String | - |
| Yekonga.Helper.hasManyThrough | (child, data) | String | - |
| Yekonga.Helper.addSlashes | (value) | String | - |
| Yekonga.Helper.escape | (value) | String | - |
| Yekonga.Helper.validateEmail | (email) | String | - |
| Yekonga.Helper.isEmail | (email) | String | - |
| Yekonga.Helper.translateProcess | async (live, locale, lang, flag) | String | - |
| Yekonga.Helper.createLanguage | async (db, locale, lang, flag) | String | - |
| Yekonga.Helper.saveTranslation | async (db, row) | String | - |
| Yekonga.Helper.savePermission | async (db, row) | String | - |
| Yekonga.Helper.translateBandle | async (trans, locale, db) | String | - |
| Yekonga.Helper.encryptUrl | (body) | String | - |
| Yekonga.Helper.decryptUrl | (body) | String | - |
| Yekonga.Helper.isPermitted | (key, defaultValue = false) | String | - |
| Yekonga.Helper.sendMail | async (options) | String | - |
| Yekonga.Helper.getEmailContent | (name, content) | String | - |
| Yekonga.Helper.getRegistrationEmail | async (name, content) | String | - |
| Yekonga.Helper.getResetPasswordEmail | async (name, content) | String | - |
## Graphql
### Custom Action
#### Action for approve user example
```js
Yekonga.Cloud.setAction('User', 'approve', async ({params})=>{
const {where, action, accessRole } = (params)? params: {};
return await Yekonga.DataModel.User.update({ status: 1}, where, null, true);
})
```
The mutation for above will be as shown below
```graphql
mutation {
userAction(where:{userId:{equalTo:"xxx"}}, action:"approve") {
status
message
}
}
```
>
> * `User` is class name
> * `approve` is action name, can be anything `string`
>
### Custom Graphql
Custom graphql schema must be configued on the `customTypes` in [Graphql Configuration](#Graphql-Configuration) in config file
> Note: for auth Custom graphql resolver must be configued on the `customAuthTypes` in [Graphql Configuration](#Graphql-Configuration) in config file
>
#### Graphql schema example
```graphql
type BlockUserResponse {
status: Boolean,
success: Boolean
}
extend type Query {
blockUser ( userId: String! ): BlockUserResponse,
}
```
Custom graphql resolver must be configued on the `customResolvers` in [Graphql Configuration](#Graphql-Configuration) in config file
> Note: for auth Custom graphql resolver must be configued on the `customAuthResolvers` in [Graphql Configuration](#Graphql-Configuration) in config file
>
#### Graphql resolver example
```js
module.exports = {
Query: {
blockUser: async function(parent, params, context) {
// code goes here
return {status: false, success: false}
}
}
}
```
## Authors
Contributors names and contact info
ex. Robert Konga
ex. [@robertkonga](https://twitter.com/robertkonga)
## Version History
* 2.0.0
* Various bug fixes and optimizations
* See [commit change]() or See [release history]()
* 1.1.0
* Initial Release
## License
This project is licensed under the [NAME HERE] License - see the LICENSE.md file for details
<!-- ## Acknowledgments
Inspiration, code snippets, etc.
* [awesome-readme](https://github.com/matiassingers/awesome-readme)
* [PurpleBooth](https://gist.github.com/PurpleBooth/109311bb0361f32d87a2)
* [dbader](https://github.com/dbader/readme-template)
* [zenorocha](https://gist.github.com/zenorocha/4526327)
* [fvcproductions](https://gist.github.com/fvcproductions/1bfc2d4aecb01a834b46) -->