@modular-rest/server 1.4.2 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/src/application.js +147 -143
- package/src/helper/presetup_services.js +27 -29
- package/src/index.js +49 -49
- package/src/middlewares.js +28 -22
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@modular-rest/server",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "a nodejs module based on KOAJS for developing Rest-APIs in a modular solution.",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
"@koa/cors": "^3.1.0",
|
|
27
27
|
"colog": "^1.0.4",
|
|
28
28
|
"file-system": "^2.2.2",
|
|
29
|
-
"generate-rsa-keypair": "^0.2.1",
|
|
30
29
|
"jsonwebtoken": "^8.5.1",
|
|
30
|
+
"keypair": "^1.0.4",
|
|
31
31
|
"koa": "^2.5.3",
|
|
32
32
|
"koa-body": "^4.2.0",
|
|
33
33
|
"koa-router": "^7.4.0",
|
package/src/application.js
CHANGED
|
@@ -1,19 +1,22 @@
|
|
|
1
|
-
let koa = require(
|
|
2
|
-
const cors = require(
|
|
3
|
-
const koaBody = require(
|
|
4
|
-
const koaStatic = require(
|
|
5
|
-
var path = require(
|
|
6
|
-
var Combination = require(
|
|
7
|
-
let DataProvider = require(
|
|
8
|
-
let UserService = require(
|
|
1
|
+
let koa = require("koa");
|
|
2
|
+
const cors = require("@koa/cors");
|
|
3
|
+
const koaBody = require("koa-body");
|
|
4
|
+
const koaStatic = require("koa-static-server");
|
|
5
|
+
var path = require("path");
|
|
6
|
+
var Combination = require("./class/combinator");
|
|
7
|
+
let DataProvider = require("./services/data_provider/service");
|
|
8
|
+
let UserService = require("./services/user_manager/service");
|
|
9
9
|
|
|
10
|
-
let defaultServiceRoot = __dirname +
|
|
10
|
+
let defaultServiceRoot = __dirname + "/services";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* @param {{
|
|
14
14
|
* cors: any; // Options for @koa/cors middleware.
|
|
15
15
|
* modulesPath: string; // Root directory of your router.js/db.js files.
|
|
16
|
-
*
|
|
16
|
+
* static: {
|
|
17
|
+
* dir: string; // Root directory for uploaded files.
|
|
18
|
+
* rootPath: string; // Root path for uploaded files.
|
|
19
|
+
* };
|
|
17
20
|
* onBeforeInit: (koaApp) => void; // A callback called before initializing the Koa server.
|
|
18
21
|
* onAfterInit: (koaApp) => void; // A callback called after server initialization.
|
|
19
22
|
* port: number; // Server port.
|
|
@@ -36,145 +39,146 @@ let defaultServiceRoot = __dirname + '/services';
|
|
|
36
39
|
* }} options
|
|
37
40
|
*/
|
|
38
41
|
module.exports = async function createRest(options) {
|
|
42
|
+
options = {
|
|
43
|
+
port: 3000,
|
|
44
|
+
dontListen: false,
|
|
45
|
+
mongo: {
|
|
46
|
+
atlas: false,
|
|
47
|
+
mongoBaseAddress: "mongodb://localhost:27017",
|
|
48
|
+
dbPrefix: "mrest_",
|
|
49
|
+
},
|
|
50
|
+
adminUser: {
|
|
51
|
+
email: "admin@email.com",
|
|
52
|
+
password: "@dmin",
|
|
53
|
+
},
|
|
54
|
+
|
|
55
|
+
...options,
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
let app = new koa();
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Plug in Cors
|
|
62
|
+
*/
|
|
63
|
+
app.use(cors(options.cors || {}));
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Plug in BodyParser
|
|
67
|
+
*/
|
|
68
|
+
let bodyParserOptions = {
|
|
69
|
+
multipart: true,
|
|
70
|
+
};
|
|
71
|
+
app.use(koaBody(bodyParserOptions));
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Plug In KoaStatic
|
|
75
|
+
*/
|
|
76
|
+
if (options.staticPath) {
|
|
77
|
+
app.use(
|
|
78
|
+
koaStatic({
|
|
79
|
+
rootDir: options.static.dir,
|
|
80
|
+
rootPath: options.static.rootPath || "/assets/",
|
|
81
|
+
})
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Run before hook
|
|
87
|
+
*/
|
|
88
|
+
if (options.onBeforeInit) options.onBeforeInit(app);
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Setup default services
|
|
92
|
+
*
|
|
93
|
+
* - Collect and plug in router.js/db.js of default services
|
|
94
|
+
* - Setting up default services
|
|
95
|
+
*/
|
|
96
|
+
|
|
97
|
+
// Plug in default routes
|
|
98
|
+
await Combination.combineRoutesByFilePath(path.join(defaultServiceRoot), app);
|
|
99
|
+
|
|
100
|
+
// Collect default databaseDefinitions
|
|
101
|
+
let defaultDatabaseDefinitionList =
|
|
102
|
+
await Combination.combineModulesByFilePath({
|
|
103
|
+
rootDirectory: defaultServiceRoot,
|
|
104
|
+
filename: {
|
|
105
|
+
name: "db",
|
|
106
|
+
extension: ".js",
|
|
107
|
+
},
|
|
108
|
+
combineWithRoot: true,
|
|
109
|
+
});
|
|
39
110
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
multipart: true
|
|
68
|
-
};
|
|
69
|
-
app.use(koaBody(bodyParserOptions));
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Plug In KoaStatic
|
|
73
|
-
*/
|
|
74
|
-
if (options.staticPath)
|
|
75
|
-
app.use(koaStatic({
|
|
76
|
-
rootDir: options.staticPath,
|
|
77
|
-
rootPath: '/assets/',
|
|
78
|
-
|
|
79
|
-
}));
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Run before hook
|
|
83
|
-
*/
|
|
84
|
-
if (options.onBeforeInit) options.onBeforeInit(app);
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Setup default services
|
|
88
|
-
*
|
|
89
|
-
* - Collect and plug in router.js/db.js of default services
|
|
90
|
-
* - Setting up default services
|
|
91
|
-
*/
|
|
92
|
-
|
|
93
|
-
// Plug in default routes
|
|
94
|
-
await Combination.combineRoutesByFilePath(
|
|
95
|
-
path.join(defaultServiceRoot), app);
|
|
96
|
-
|
|
97
|
-
// Collect default databaseDefinitions
|
|
98
|
-
let defaultDatabaseDefinitionList = await Combination.combineModulesByFilePath({
|
|
99
|
-
rootDirectory: defaultServiceRoot,
|
|
100
|
-
filename: {
|
|
101
|
-
name: 'db',
|
|
102
|
-
extension: '.js'
|
|
103
|
-
},
|
|
104
|
-
combineWithRoot: true
|
|
111
|
+
// Plug in default databaseDefinitions
|
|
112
|
+
await DataProvider.addCollectionDefinitionByList({
|
|
113
|
+
list: defaultDatabaseDefinitionList,
|
|
114
|
+
mongoOption: options.mongo,
|
|
115
|
+
});
|
|
116
|
+
|
|
117
|
+
// Setting up default services
|
|
118
|
+
await require("./helper/presetup_services").setup(options);
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* User Services
|
|
122
|
+
*
|
|
123
|
+
* Plug in routes and database
|
|
124
|
+
*/
|
|
125
|
+
if (options.modulesPath) {
|
|
126
|
+
// Plug in user routes
|
|
127
|
+
await Combination.combineRoutesByFilePath(options.modulesPath, app);
|
|
128
|
+
|
|
129
|
+
// Collect user CollectionDefinitions (db.js files)
|
|
130
|
+
let userDatabaseDetail = [];
|
|
131
|
+
userDatabaseDetail = await Combination.combineModulesByFilePath({
|
|
132
|
+
rootDirectory: options.modulesPath,
|
|
133
|
+
filename: {
|
|
134
|
+
name: "db",
|
|
135
|
+
extension: ".js",
|
|
136
|
+
},
|
|
137
|
+
combineWithRoot: true,
|
|
105
138
|
});
|
|
106
139
|
|
|
107
|
-
//
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
mongoOption: options.mongo
|
|
111
|
-
})
|
|
112
|
-
|
|
113
|
-
// Setting up default services
|
|
114
|
-
await require('./helper/presetup_services').setup(options);
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* User Services
|
|
118
|
-
*
|
|
119
|
-
* Plug in routes and database
|
|
120
|
-
*/
|
|
121
|
-
if (options.modulesPath) {
|
|
122
|
-
|
|
123
|
-
// Plug in user routes
|
|
124
|
-
await Combination.combineRoutesByFilePath(options.modulesPath, app);
|
|
125
|
-
|
|
126
|
-
// Collect user CollectionDefinitions (db.js files)
|
|
127
|
-
let userDatabaseDetail = [];
|
|
128
|
-
userDatabaseDetail = await Combination.combineModulesByFilePath({
|
|
129
|
-
rootDirectory: options.modulesPath,
|
|
130
|
-
filename: {
|
|
131
|
-
name: 'db',
|
|
132
|
-
extension: '.js'
|
|
133
|
-
},
|
|
134
|
-
combineWithRoot: true
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
// combine additional CollectionDefinitions
|
|
138
|
-
if (options.collectionDefinitions) {
|
|
139
|
-
userDatabaseDetail.concat(options.collectionDefinitions)
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
// Plug in user CollectionDefinitions
|
|
143
|
-
await DataProvider.addCollectionDefinitionByList({
|
|
144
|
-
list: userDatabaseDetail || [],
|
|
145
|
-
mongoOption: options.mongo
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
// Plug in Verification method
|
|
149
|
-
if (typeof options.verificationCodeGeneratorMethod == 'function') {
|
|
150
|
-
UserService.main.setCustomVerificationCodeGeneratorMethod(
|
|
151
|
-
options.verificationCodeGeneratorMethod
|
|
152
|
-
)
|
|
153
|
-
}
|
|
140
|
+
// combine additional CollectionDefinitions
|
|
141
|
+
if (options.collectionDefinitions) {
|
|
142
|
+
userDatabaseDetail.concat(options.collectionDefinitions);
|
|
154
143
|
}
|
|
155
144
|
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return new Promise((done, reject) => {
|
|
162
|
-
|
|
163
|
-
let server;
|
|
164
|
-
|
|
165
|
-
if (!options.dontListen) {
|
|
166
|
-
server = app.listen(options.port);
|
|
167
|
-
console.log('\x1b[35m', `KOAS has been launched on: localhost:${options.port}`);
|
|
168
|
-
}
|
|
145
|
+
// Plug in user CollectionDefinitions
|
|
146
|
+
await DataProvider.addCollectionDefinitionByList({
|
|
147
|
+
list: userDatabaseDetail || [],
|
|
148
|
+
mongoOption: options.mongo,
|
|
149
|
+
});
|
|
169
150
|
|
|
151
|
+
// Plug in Verification method
|
|
152
|
+
if (typeof options.verificationCodeGeneratorMethod == "function") {
|
|
153
|
+
UserService.main.setCustomVerificationCodeGeneratorMethod(
|
|
154
|
+
options.verificationCodeGeneratorMethod
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Run the server
|
|
161
|
+
*
|
|
162
|
+
* return KOA app object
|
|
163
|
+
*/
|
|
164
|
+
return new Promise((done, reject) => {
|
|
165
|
+
let server;
|
|
166
|
+
|
|
167
|
+
if (!options.dontListen) {
|
|
168
|
+
server = app.listen(options.port);
|
|
169
|
+
console.log(
|
|
170
|
+
"\x1b[35m",
|
|
171
|
+
`KOAS has been launched on: localhost:${options.port}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
170
174
|
|
|
171
|
-
|
|
172
|
-
|
|
175
|
+
// on after init
|
|
176
|
+
if (options.onAfterInit) options.onAfterInit(app);
|
|
173
177
|
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
});
|
|
178
|
+
//done
|
|
179
|
+
done({
|
|
180
|
+
app,
|
|
181
|
+
server,
|
|
179
182
|
});
|
|
180
|
-
}
|
|
183
|
+
});
|
|
184
|
+
};
|
|
@@ -1,34 +1,32 @@
|
|
|
1
|
-
let DataInsertion = require(
|
|
2
|
-
let JWT = require(
|
|
3
|
-
let FileService = require(
|
|
1
|
+
let DataInsertion = require("./data_insertion");
|
|
2
|
+
let JWT = require("../services/jwt/service");
|
|
3
|
+
let FileService = require("../services/file/service");
|
|
4
4
|
|
|
5
5
|
module.exports.setup = async ({ keypair, adminUser, uploadDirectory }) => {
|
|
6
|
+
/**
|
|
7
|
+
* Json web Token
|
|
8
|
+
*
|
|
9
|
+
* Setup private and public keys for JWT module
|
|
10
|
+
*/
|
|
11
|
+
if (!keypair) {
|
|
12
|
+
// generate new keypair
|
|
13
|
+
const generateKeypair = require("keypair");
|
|
14
|
+
keypair = generateKeypair();
|
|
15
|
+
}
|
|
6
16
|
|
|
7
|
-
|
|
8
|
-
* Json web Token
|
|
9
|
-
*
|
|
10
|
-
* Setup private and public keys for JWT module
|
|
11
|
-
*/
|
|
12
|
-
if (!keypair) {
|
|
13
|
-
// generate new keypair
|
|
14
|
-
var generateRSAKeypair = require('generate-rsa-keypair')
|
|
15
|
-
keypair = generateRSAKeypair()
|
|
16
|
-
}
|
|
17
|
+
JWT.main.setKies(keypair.private, keypair.public);
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Data Insertion
|
|
21
|
+
*
|
|
22
|
+
* Insert permissions and admin user
|
|
23
|
+
* for the first time
|
|
24
|
+
*/
|
|
25
|
+
await DataInsertion.createPermissions();
|
|
26
|
+
await DataInsertion.createAdminUser(adminUser);
|
|
19
27
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
*/
|
|
26
|
-
await DataInsertion.createPermissions();
|
|
27
|
-
await DataInsertion.createAdminUser(adminUser)
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* File Service
|
|
31
|
-
*/
|
|
32
|
-
FileService.setUploadDirectory(uploadDirectory);
|
|
33
|
-
|
|
34
|
-
}
|
|
28
|
+
/**
|
|
29
|
+
* File Service
|
|
30
|
+
*/
|
|
31
|
+
FileService.setUploadDirectory(uploadDirectory);
|
|
32
|
+
};
|
package/src/index.js
CHANGED
|
@@ -1,57 +1,57 @@
|
|
|
1
1
|
// Application
|
|
2
|
-
const createRest = require(
|
|
3
|
-
const Schema = require(
|
|
2
|
+
const createRest = require("./application");
|
|
3
|
+
const Schema = require("mongoose").Schema;
|
|
4
4
|
|
|
5
5
|
// Utilities
|
|
6
|
-
const paginator = require(
|
|
7
|
-
const reply = require(
|
|
8
|
-
const validator = require(
|
|
9
|
-
const {
|
|
10
|
-
|
|
11
|
-
} = require('./services/data_provider/service');
|
|
12
|
-
const TypeCasters = require('./services/data_provider/typeCasters');
|
|
6
|
+
const paginator = require("./class/paginator");
|
|
7
|
+
const reply = require("./class/reply");
|
|
8
|
+
const validator = require("./class/validator");
|
|
9
|
+
const { getCollection } = require("./services/data_provider/service");
|
|
10
|
+
const TypeCasters = require("./services/data_provider/typeCasters");
|
|
13
11
|
|
|
14
12
|
// Base class
|
|
15
|
-
const CollectionDefinition = require(
|
|
16
|
-
const Schemas = require(
|
|
17
|
-
const DatabaseTrigger = require(
|
|
18
|
-
const SecurityClass = require(
|
|
13
|
+
const CollectionDefinition = require("./class/collection_definition");
|
|
14
|
+
const Schemas = require("./class/db_schemas");
|
|
15
|
+
const DatabaseTrigger = require("./class/database_trigger");
|
|
16
|
+
const SecurityClass = require("./class/security");
|
|
19
17
|
|
|
20
|
-
const middleware = require(
|
|
18
|
+
const middleware = require("./middlewares");
|
|
21
19
|
|
|
22
20
|
module.exports = {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
21
|
+
createRest,
|
|
22
|
+
|
|
23
|
+
//
|
|
24
|
+
// Utilities
|
|
25
|
+
//
|
|
26
|
+
reply,
|
|
27
|
+
TypeCasters,
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* @type {import('./class/paginator').create}
|
|
31
|
+
*/
|
|
32
|
+
paginator,
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @type {import('./class/validator')}
|
|
36
|
+
*/
|
|
37
|
+
validator,
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* @type {import('./services/data_provider/service').getCollection}
|
|
41
|
+
* @return {import('mongoose').Model} Mongoose model https://mongoosejs.com/docs/api/model.html
|
|
42
|
+
*/
|
|
43
|
+
getCollection,
|
|
44
|
+
|
|
45
|
+
//
|
|
46
|
+
// Base class
|
|
47
|
+
//
|
|
48
|
+
CollectionDefinition,
|
|
49
|
+
Schemas,
|
|
50
|
+
Schema,
|
|
51
|
+
DatabaseTrigger,
|
|
52
|
+
|
|
53
|
+
...SecurityClass,
|
|
54
|
+
|
|
55
|
+
// Middlewares
|
|
56
|
+
middleware,
|
|
57
|
+
};
|
package/src/middlewares.js
CHANGED
|
@@ -1,24 +1,30 @@
|
|
|
1
|
-
let validateObject = require(
|
|
2
|
-
const userManager = require(
|
|
1
|
+
let validateObject = require("./class/validator");
|
|
2
|
+
const userManager = require("./services/user_manager/service");
|
|
3
3
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Authentication middleware
|
|
6
|
+
* It checks if incoming request has a valid token in header.authorization
|
|
7
|
+
*
|
|
8
|
+
* @param {Object} ctx - Koa context
|
|
9
|
+
* @param {Function} next - Koa next function
|
|
10
|
+
* @returns {Promise<void>}
|
|
11
|
+
*/
|
|
12
|
+
module.exports.auth = async (ctx, next) => {
|
|
13
|
+
let headers = ctx.header;
|
|
14
|
+
let headersValidated = validateObject(headers, "authorization");
|
|
8
15
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
16
|
+
if (!headersValidated.isValid) ctx.throw(401, "authentication is required");
|
|
17
|
+
|
|
18
|
+
let token = headers.authorization;
|
|
19
|
+
|
|
20
|
+
await userManager.main
|
|
21
|
+
.getUserByToken(token)
|
|
22
|
+
.then(async (user) => {
|
|
23
|
+
ctx.state.user = user;
|
|
24
|
+
await next();
|
|
25
|
+
})
|
|
26
|
+
.catch((err) => {
|
|
27
|
+
console.log(err);
|
|
28
|
+
ctx.throw(err.status || 412, err.message);
|
|
29
|
+
});
|
|
30
|
+
};
|