@modular-rest/server 1.11.5 → 1.11.6

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.
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@modular-rest/server",
3
- "version": "1.11.5",
3
+ "version": "1.11.6",
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": {
@@ -32,8 +32,9 @@
32
32
  "keypair": "^1.0.4",
33
33
  "koa": "^2.5.3",
34
34
  "koa-body": "^4.2.0",
35
+ "koa-mount": "^4.0.0",
35
36
  "koa-router": "^7.4.0",
36
- "koa-static-server": "^1.5.2",
37
+ "koa-static": "^5.0.0",
37
38
  "mongoose": "^5.10.9",
38
39
  "nested-property": "^4.0.0"
39
40
  },
@@ -43,4 +44,4 @@
43
44
  "@types/koa__cors": "^5.0.0",
44
45
  "typescript": "^5.3.3"
45
46
  }
46
- }
47
+ }
@@ -1,7 +1,8 @@
1
1
  const koa = require("koa");
2
2
  const cors = require("@koa/cors");
3
3
  const koaBody = require("koa-body");
4
- const koaStatic = require("koa-static-server");
4
+ const koaStatic = require("koa-static");
5
+ const mount = require("koa-mount");
5
6
  const path = require("path");
6
7
  const Combination = require("./class/combinator");
7
8
  const DataProvider = require("./services/data_provider/service");
@@ -13,8 +14,8 @@ const defaultServiceRoot = __dirname + "/services";
13
14
  * @typedef {import('koa')} Koa
14
15
  * @typedef {import('http').Server} server
15
16
  * @typedef {import('@koa/cors').Options} Cors
16
- * @typedef {import('./class/security').PermissionGroup} PermissionGroup
17
- * @typedef {import('./class/database_trigger.js')} DatabaseTrigger
17
+ * @typedef {import('./class/security.js').PermissionGroup} PermissionGroup
18
+ * @typedef {import('./class/cms_trigger.js')} CmsTrigger
18
19
  */
19
20
 
20
21
  const { config, setConfig } = require("./config");
@@ -25,18 +26,19 @@ const { config, setConfig } = require("./config");
25
26
  * cors?: Cors; // CORS options.
26
27
  * modulesPath?: string; // Root directory of your router.js/db.js files.
27
28
  * uploadDirectory?: string; // Root directory of your uploaded files.
28
- * staticPath?: {
29
- * rootDir?: string; // Root directory of your static files.
30
- * rootPath?: string; // Root path of your static files.
31
- * notFoundFile?: string; // Not found file.
32
- * log?: boolean; // Log requests to console.
33
- * last?: boolean; // Don't execute any downstream middleware.
34
- * maxage?: number; // Browser cache max-age in milliseconds.
35
- * hidden?: boolean; // Allow transfer of hidden files.
36
- * gzip?: boolean; // Try to serve the gzipped version of a file automatically when gzip is supported by a client and if the requested file exists.
37
- * brotli?: boolean; // Try to serve the brotli version of a file automatically when brotli is supported by a client and if the requested file exists.
38
- * index?: string; // Index file.
39
- * };
29
+ * koaBodyOptions?: object; // Options for koa-body.
30
+ * staticPath?: {
31
+ * rootDir: string; // Root directory of your static files.
32
+ * rootPath: string; // Root path of your static files, defaults to '/assets'.
33
+ * maxage?: number; // Browser cache max-age in milliseconds. Defaults to 0.
34
+ * hidden?: boolean; // Allow transfer of hidden files. Defaults to false.
35
+ * index?: string; // Default file name. Defaults to 'index.html'.
36
+ * defer?: boolean; // If true, serves after return next(), allowing any downstream middleware to respond first. Defaults to false.
37
+ * gzip?: boolean; // Try to serve the gzipped version of a file automatically when gzip is supported by a client and if the requested file with .gz extension exists. Defaults to true.
38
+ * br?: boolean; // Try to serve the brotli version of a file automatically when brotli is supported by a client and if the requested file with .br extension exists. Note that brotli is only accepted over https. Defaults to false.
39
+ * setHeaders?: Function; // Function to set custom headers on response.
40
+ * extensions?: boolean|Array; // Try to match extensions from passed array to search for file when no extension is suffixed in URL. First found is served. Defaults to false.
41
+ * };
40
42
  * onBeforeInit?: (koaApp:Koa) => void; // A callback called before initializing the Koa server.
41
43
  * onAfterInit?: (koaApp:Koa) => void; // A callback called after server initialization.
42
44
  * port?: number; // Server port.
@@ -57,7 +59,8 @@ const { config, setConfig } = require("./config");
57
59
  * verificationCodeGeneratorMethod: () => string; // A method to return a verification code when registering a new user.
58
60
  * collectionDefinitions?: CollectionDefinition[]; // An array of additional collection definitions.
59
61
  * permissionGroups?: PermissionGroup[]; // An array of additional permission groups.
60
- * authTriggers?: DatabaseTrigger[]; // An array of additional database triggers for the auth collection.
62
+ * authTriggers?: CmsTrigger[]; // An array of additional database triggers for the auth collection.
63
+ * fileTriggers?: CmsTrigger[]; // An array of additional database triggers for the auth collection.
61
64
  * }} options
62
65
  * @returns {Promise<{app: Koa, server: Server}>}
63
66
  */
@@ -90,6 +93,7 @@ async function createRest(options) {
90
93
  */
91
94
  const bodyParserOptions = {
92
95
  multipart: true,
96
+ ...(config.koaBodyOptions || {}),
93
97
  };
94
98
  app.use(koaBody(bodyParserOptions));
95
99
 
@@ -97,7 +101,18 @@ async function createRest(options) {
97
101
  * Plug In KoaStatic
98
102
  */
99
103
  if (config.staticPath) {
100
- app.use(koaStatic(config.staticPath));
104
+ const defaultStaticPath = config.staticPath.rootDir;
105
+ const defaultStaticRootPath = config.staticPath.rootPath || "/assets";
106
+
107
+ delete config.staticPath.rootDir;
108
+ delete config.staticPath.rootPath;
109
+
110
+ app.use(
111
+ mount(
112
+ defaultStaticRootPath,
113
+ koaStatic(defaultStaticPath, config.staticPath)
114
+ )
115
+ );
101
116
  }
102
117
 
103
118
  /**
@@ -0,0 +1,20 @@
1
+ /**
2
+ * `CmsTrigger` is a class that defines a callback to be called on a specific database transaction.
3
+ *
4
+ * @class
5
+ */
6
+ class CmsTrigger {
7
+ /**
8
+ * Creates a new instance of `CmsTrigger`.
9
+ *
10
+ * @param {'update-one' | 'insert-one' | 'remove-one' } operation - The operation to be triggered.
11
+ * @param {function({query: any, queryResult: any}): void} [callback=(context) => {}] - The callback to be called when the operation is executed. The callback function takes an object as parameter with two properties: 'query' and 'queryResult'.
12
+ * @constructor
13
+ */
14
+ constructor(operation, callback = (context) => {}) {
15
+ this.operation = operation;
16
+ this.callback = callback;
17
+ }
18
+ }
19
+
20
+ module.exports = CmsTrigger;
@@ -11,6 +11,7 @@ module.exports = {
11
11
  // Tag being used as the parent dir for files
12
12
  // uploadDir/$format/$tag/timestamp.format
13
13
  tag: String,
14
+ size: Number,
14
15
  },
15
16
  { timestamps: true }
16
17
  ),
@@ -6,8 +6,9 @@
6
6
  * @returns {Object} - An object containing pagination information.
7
7
  */
8
8
  function create(count, perPage, page) {
9
- let totalPgaes = Math.ceil(count / perPage);
10
- if (page > totalPgaes) page = 1;
9
+ const totalPages = Math.ceil(count / perPage);
10
+
11
+ if (page > totalPages) page = 1;
11
12
 
12
13
  let from = 0;
13
14
  if (perPage == 1) from = page - 1;
@@ -16,7 +17,7 @@ function create(count, perPage, page) {
16
17
  if (page <= 1) from = 0;
17
18
 
18
19
  let result = {
19
- 'pages': totalPgaes,
20
+ 'pages': totalPages,
20
21
  'page': page,
21
22
  'from': from,
22
23
  'to': perPage
@@ -9,7 +9,7 @@ function create(status, detail = {}) {
9
9
 
10
10
  let result = detail || {};
11
11
 
12
- // defin status
12
+ // define status
13
13
  switch (status) {
14
14
  case 's':
15
15
  result['status'] = 'success';
@@ -8,13 +8,13 @@
8
8
  function validate(obj, requiredFields) {
9
9
  /*
10
10
  this method could validate an Object by given field's name list and return bool.
11
- - requiredFields: is a string that contains keys being spareted by " ".
11
+ - requiredFields: is a string that contains keys being spared by " ".
12
12
  */
13
13
  let type = typeof requiredFields;
14
14
  let result;
15
15
 
16
16
  if (type == 'string')
17
- result = ckeckSimple(obj, requiredFields);
17
+ result = checkSimple(obj, requiredFields);
18
18
  else if (type == 'object')
19
19
  result = checkComplex(obj, requiredFields);
20
20
 
@@ -25,7 +25,7 @@ function validate(obj, requiredFields) {
25
25
 
26
26
  module.exports = validate;
27
27
 
28
- function ckeckSimple(obj, requiredFields = '') {
28
+ function checkSimple(obj, requiredFields = '') {
29
29
  let isValide = false;
30
30
  let requires = requiredFields.split(' ');
31
31
 
package/src/config.js CHANGED
@@ -1,27 +1,28 @@
1
1
  /**
2
2
  * @typedef {import('koa')} Koa
3
3
  * @typedef {import('@koa/cors').Options} Cors
4
- * @typedef {import('./class/collection_definition')} CollectionDefinition
5
- * @typedef {import('./class/security').PermissionGroup} PermissionGroup
6
- * @typedef {import('./class/database_trigger.js')} DatabaseTrigger
4
+ * @typedef {import('./class/collection_definition.js')} CollectionDefinition
5
+ * @typedef {import('./class/security.js').PermissionGroup} PermissionGroup
6
+ * @typedef {import('./class/cms_trigger.js')} CmsTrigger
7
7
  */
8
8
 
9
9
  /**
10
10
  * @typedef {{
11
11
  * cors?: Cors; // CORS options.
12
12
  * modulesPath?: string; // Root directory of your router.js/db.js files.
13
- * staticPath?: {
14
- * rootDir?: string; // Root directory of your static files.
15
- * rootPath?: string; // Root path of your static files.
16
- * notFoundFile?: string; // Not found file.
17
- * log?: boolean; // Log requests to console.
18
- * last?: boolean; // Don't execute any downstream middleware.
19
- * maxage?: number; // Browser cache max-age in milliseconds.
20
- * hidden?: boolean; // Allow transfer of hidden files.
21
- * gzip?: boolean; // Try to serve the gzipped version of a file automatically when gzip is supported by a client and if the requested file exists.
22
- * brotli?: boolean; // Try to serve the brotli version of a file automatically when brotli is supported by a client and if the requested file exists.
23
- * index?: string; // Index file.
24
- * };
13
+ * koaBodyOptions?: object; // Options for koa-body.
14
+ * staticPath?: {
15
+ * rootDir: string; // Root directory of your static files.
16
+ * rootPath: string; // Root path of your static files, defaults to '/assets'.
17
+ * maxage?: number; // Browser cache max-age in milliseconds. Defaults to 0.
18
+ * hidden?: boolean; // Allow transfer of hidden files. Defaults to false.
19
+ * index?: string; // Default file name. Defaults to 'index.html'.
20
+ * defer?: boolean; // If true, serves after return next(), allowing any downstream middleware to respond first. Defaults to false.
21
+ * gzip?: boolean; // Try to serve the gzipped version of a file automatically when gzip is supported by a client and if the requested file with .gz extension exists. Defaults to true.
22
+ * br?: boolean; // Try to serve the brotli version of a file automatically when brotli is supported by a client and if the requested file with .br extension exists. Note that brotli is only accepted over https. Defaults to false.
23
+ * setHeaders?: Function; // Function to set custom headers on response.
24
+ * extensions?: boolean|Array; // Try to match extensions from passed array to search for file when no extension is suffixed in URL. First found is served. Defaults to false.
25
+ * };
25
26
  * onBeforeInit?: (koaApp:Koa) => void; // A callback called before initializing the Koa server.
26
27
  * onAfterInit?: (koaApp:Koa) => void; // A callback called after server initialization.
27
28
  * port?: number; // Server port.
@@ -43,6 +44,7 @@
43
44
  * collectionDefinitions?: CollectionDefinition[]; // An array of additional collection definitions.
44
45
  * permissionGroups?: PermissionGroup[]; // An array of additional permission groups.
45
46
  * authTriggers?: DatabaseTrigger[]; // An array of additional database triggers for the auth collection.
47
+ * fileTriggers?: CmsTrigger[]; // An array of additional database triggers for the auth collection.
46
48
  * }} Config
47
49
  * @exports Config
48
50
  */
package/src/index.js CHANGED
@@ -9,36 +9,58 @@ const validator = require("./class/validator");
9
9
  const { getCollection } = require("./services/data_provider/service");
10
10
  const { defineFunction } = require("./services/functions/service");
11
11
  const TypeCasters = require("./services/data_provider/typeCasters");
12
+ const userManager = require("./services/user_manager/service");
13
+ const {
14
+ getFile,
15
+ getFileLink,
16
+ getFilePath,
17
+ removeFile,
18
+ storeFile,
19
+ } = require("./services/file/service");
12
20
 
13
21
  // Base class
14
22
  const CollectionDefinition = require("./class/collection_definition");
15
23
  const Schemas = require("./class/db_schemas");
16
24
  const DatabaseTrigger = require("./class/database_trigger");
25
+ const CmsTrigger = require("./class/cms_trigger");
17
26
  const SecurityClass = require("./class/security");
18
27
  const middleware = require("./middlewares");
19
- const userManager = require("./services/user_manager/service");
20
28
 
21
29
  module.exports = {
22
30
  createRest,
23
31
 
24
- // Route utilities
25
- reply,
26
- TypeCasters,
27
- paginator,
28
- validator,
29
-
30
- // Service utilities
31
- getCollection,
32
- defineFunction,
33
-
34
32
  // Database
35
33
  CollectionDefinition,
36
34
  Schemas,
37
35
  Schema,
38
36
  DatabaseTrigger,
37
+ CmsTrigger,
39
38
  ...SecurityClass,
40
39
 
41
- // Middlewares
40
+ // Function
41
+ defineFunction,
42
+
43
+ // Private utilities
44
+ TypeCasters,
45
+ validator,
46
+
47
+ // Route utilities
48
+ reply,
49
+ paginator,
50
+
51
+ // Database utilities
52
+ getCollection,
53
+
54
+ // File Utilities
55
+ getFile,
56
+ getFileLink,
57
+ getFilePath,
58
+ removeFile,
59
+ storeFile,
60
+
61
+ // Middleware utilities
42
62
  middleware,
63
+
64
+ // User utilities
43
65
  userManager: userManager.main,
44
66
  };
@@ -1,9 +1,10 @@
1
- let Mongoose = require('mongoose');
1
+ const Mongoose = require('mongoose');
2
+
2
3
  module.exports = {
3
4
  'ObjectId': Mongoose.Types.ObjectId,
4
5
  'Date': (dateValue) => {
5
- let strDate = dateValue.toString();
6
- let mongoDateFormateInString = new Date(strDate).toISOString().split('T')[0];
6
+ const strDate = dateValue.toString();
7
+ const mongoDateFormateInString = new Date(strDate).toISOString().split('T')[0];
7
8
  return new Date(mongoDateFormateInString);
8
9
  }
9
10
  }
@@ -1,27 +1,29 @@
1
- var mongoose = require('mongoose');
2
- var Schemas = require('../../class/db_schemas');
1
+ var mongoose = require("mongoose");
2
+ var Schemas = require("../../class/db_schemas");
3
3
 
4
- let CollectionDefinition = require('../../class/collection_definition');
5
- let { Permission, PermissionTypes } = require('../../class/security');
4
+ let CollectionDefinition = require("../../class/collection_definition");
5
+ let { Permission, PermissionTypes } = require("../../class/security");
6
+ const { config } = require("../../config");
6
7
 
7
8
  module.exports = [
8
- new CollectionDefinition({
9
- db: 'cms',
10
- collection: 'file',
11
- schema: Schemas.file,
12
- permissions: [
13
- new Permission({
14
- type: PermissionTypes.upload_file_access,
15
- read: true,
16
- write: true,
17
- onlyOwnData: false,
18
- }),
19
- new Permission({
20
- type: PermissionTypes.remove_file_access,
21
- read: true,
22
- write: true,
23
- onlyOwnData: false,
24
- }),
25
- ],
26
- }),
27
- ]
9
+ new CollectionDefinition({
10
+ db: "cms",
11
+ collection: "file",
12
+ schema: Schemas.file,
13
+ permissions: [
14
+ new Permission({
15
+ type: PermissionTypes.upload_file_access,
16
+ read: true,
17
+ write: true,
18
+ onlyOwnData: false,
19
+ }),
20
+ new Permission({
21
+ type: PermissionTypes.remove_file_access,
22
+ read: true,
23
+ write: true,
24
+ onlyOwnData: false,
25
+ }),
26
+ ],
27
+ triggers: config.fileTriggers || [],
28
+ }),
29
+ ];