@modular-rest/server 1.11.12 → 1.11.14

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.
Files changed (112) hide show
  1. package/.nvmrc +1 -0
  2. package/.prettierrc.json +9 -0
  3. package/.releaserc.json +24 -0
  4. package/README.md +79 -94
  5. package/dist/index.js +79 -0
  6. package/docs/.keep +0 -0
  7. package/docs/system-access-type.md +26 -0
  8. package/package.json +58 -45
  9. package/src/application.ts +206 -0
  10. package/src/class/cms_trigger.ts +68 -0
  11. package/src/class/collection_definition.ts +134 -0
  12. package/src/class/combinator.ts +176 -0
  13. package/src/class/database_trigger.ts +99 -0
  14. package/src/class/db_schemas.ts +44 -0
  15. package/src/class/{directory.js → directory.ts} +40 -18
  16. package/src/class/paginator.ts +51 -0
  17. package/src/class/reply.ts +59 -0
  18. package/src/class/security.ts +250 -0
  19. package/src/class/trigger_operator.ts +142 -0
  20. package/src/class/user.ts +199 -0
  21. package/src/class/validator.ts +123 -0
  22. package/src/config.ts +122 -0
  23. package/src/defult-permissions.ts +31 -0
  24. package/src/events.ts +59 -0
  25. package/src/helper/data_insertion.ts +94 -0
  26. package/src/helper/presetup_services.ts +96 -0
  27. package/src/index.ts +146 -0
  28. package/src/middlewares.ts +75 -0
  29. package/src/play-test.ts +8 -0
  30. package/src/services/data_provider/router.ts +191 -0
  31. package/src/services/data_provider/service.ts +305 -0
  32. package/src/services/data_provider/typeCasters.ts +15 -0
  33. package/src/services/file/db.ts +29 -0
  34. package/src/services/file/router.ts +88 -0
  35. package/src/services/file/service.ts +387 -0
  36. package/src/services/functions/router.ts +34 -0
  37. package/src/services/functions/service.ts +203 -0
  38. package/src/services/jwt/router.ts +73 -0
  39. package/src/services/jwt/service.ts +139 -0
  40. package/src/services/user_manager/db.ts +87 -0
  41. package/src/services/user_manager/permissionManager.ts +49 -0
  42. package/src/services/user_manager/router.ts +193 -0
  43. package/src/services/user_manager/service.ts +698 -0
  44. package/tsconfig.json +16 -9
  45. package/typedoc.mjs +41 -0
  46. package/LICENSE +0 -21
  47. package/package-lock.json +0 -1373
  48. package/src/application.js +0 -239
  49. package/src/class/cms_trigger.js +0 -20
  50. package/src/class/collection_definition.js +0 -33
  51. package/src/class/combinator.js +0 -133
  52. package/src/class/database_trigger.js +0 -20
  53. package/src/class/db_schemas.js +0 -18
  54. package/src/class/paginator.js +0 -31
  55. package/src/class/reply.js +0 -37
  56. package/src/class/security.js +0 -141
  57. package/src/class/trigger_operator.js +0 -39
  58. package/src/class/user.js +0 -112
  59. package/src/class/validator.js +0 -91
  60. package/src/config.js +0 -67
  61. package/src/events.js +0 -15
  62. package/src/helper/data_insertion.js +0 -64
  63. package/src/helper/presetup_services.js +0 -31
  64. package/src/index.js +0 -66
  65. package/src/middlewares.js +0 -44
  66. package/src/services/data_provider/router.js +0 -552
  67. package/src/services/data_provider/service.js +0 -262
  68. package/src/services/data_provider/typeCasters.js +0 -10
  69. package/src/services/file/db.js +0 -29
  70. package/src/services/file/router.js +0 -92
  71. package/src/services/file/service.js +0 -231
  72. package/src/services/functions/router.js +0 -37
  73. package/src/services/functions/service.js +0 -74
  74. package/src/services/jwt/router.js +0 -70
  75. package/src/services/jwt/service.js +0 -37
  76. package/src/services/user_manager/db.js +0 -83
  77. package/src/services/user_manager/permissionManager.js +0 -43
  78. package/src/services/user_manager/router.js +0 -176
  79. package/src/services/user_manager/service.js +0 -377
  80. package/types/application.d.ts +0 -97
  81. package/types/class/cms_trigger.d.ts +0 -24
  82. package/types/class/collection_definition.d.ts +0 -36
  83. package/types/class/combinator.d.ts +0 -30
  84. package/types/class/database_trigger.d.ts +0 -28
  85. package/types/class/db_schemas.d.ts +0 -2
  86. package/types/class/directory.d.ts +0 -2
  87. package/types/class/paginator.d.ts +0 -8
  88. package/types/class/reply.d.ts +0 -8
  89. package/types/class/security.d.ts +0 -109
  90. package/types/class/trigger_operator.d.ts +0 -19
  91. package/types/class/user.d.ts +0 -24
  92. package/types/class/validator.d.ts +0 -9
  93. package/types/config.d.ts +0 -101
  94. package/types/events.d.ts +0 -7
  95. package/types/helper/data_insertion.d.ts +0 -4
  96. package/types/helper/presetup_services.d.ts +0 -5
  97. package/types/index.d.ts +0 -72
  98. package/types/middlewares.d.ts +0 -9
  99. package/types/services/data_provider/router.d.ts +0 -3
  100. package/types/services/data_provider/service.d.ts +0 -40
  101. package/types/services/data_provider/typeCasters.d.ts +0 -3
  102. package/types/services/file/db.d.ts +0 -3
  103. package/types/services/file/router.d.ts +0 -3
  104. package/types/services/file/service.d.ts +0 -81
  105. package/types/services/functions/router.d.ts +0 -3
  106. package/types/services/functions/service.d.ts +0 -23
  107. package/types/services/jwt/router.d.ts +0 -3
  108. package/types/services/jwt/service.d.ts +0 -10
  109. package/types/services/user_manager/db.d.ts +0 -3
  110. package/types/services/user_manager/permissionManager.d.ts +0 -3
  111. package/types/services/user_manager/router.d.ts +0 -3
  112. package/types/services/user_manager/service.d.ts +0 -131
package/.nvmrc ADDED
@@ -0,0 +1 @@
1
+ v21.5.0
package/.prettierrc.json CHANGED
@@ -0,0 +1,9 @@
1
+ {
2
+ "semi": true,
3
+ "tabWidth": 2,
4
+ "printWidth": 100,
5
+ "singleQuote": true,
6
+ "trailingComma": "es5",
7
+ "bracketSpacing": true,
8
+ "arrowParens": "avoid"
9
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "extends": "semantic-release-monorepo",
3
+ "branches": ["main"],
4
+ "tagFormat": "@modular-rest/server_v${version}",
5
+ "plugins": [
6
+ ["@semantic-release/commit-analyzer", {
7
+ "preset": "angular",
8
+ "releaseRules": [
9
+ {"type": "docs", "scope": "README", "release": "patch"},
10
+ {"type": "feat", "release": "minor"},
11
+ {"type": "fix", "release": "patch"},
12
+ {"type": "perf", "release": "patch"},
13
+ {"type": "revert", "release": "patch"},
14
+ {"type": "style", "release": "patch"},
15
+ {"type": "test", "release": "patch"},
16
+ {"type": "ci", "release": "patch"},
17
+ {"type": "chore", "release": "patch"}
18
+ ]
19
+ }],
20
+ "@semantic-release/release-notes-generator",
21
+ "@semantic-release/npm",
22
+ "@semantic-release/github"
23
+ ]
24
+ }
package/README.md CHANGED
@@ -1,114 +1,99 @@
1
- # Modular-Rest
2
- a nodejs module based on KOAJS for developing Rest-APIs in a modular solution.
3
- - modular-rest is only for developing rest api, and is not based on MVC.
4
- - each route would be a module in this system. you can define your base routes on difrent folders then the Modular-Rest would combine all routes to main app object.
1
+ # @modular-rest/server-ts
5
2
 
6
- this module has one method:
7
- - `createRest`: is the main functionality of the module.
3
+ TypeScript version of a Node.js module based on Koa.js for developing REST APIs in a modular solution.
8
4
 
9
- **Note**: active "javascript.implicitProjectConfig.checkJs": true in your vscode settings.
5
+ ## Version 1.12 Breaking Changes
10
6
 
11
- ## Install
7
+ The 1.12 release includes several breaking changes:
12
8
 
13
- Install using [npm](https://www.npmjs.com/package/modular-rest):
9
+ - Complete rewrite in TypeScript with full type safety and improved IDE support
10
+ - Auto-generated API documentation using TypeDoc
11
+ - Changed configuration structure for better TypeScript support
14
12
 
15
- ```sh
16
- npm i modular-rest --save
13
+ ## Migration Status
14
+
15
+ This is a TypeScript migration of the original [@modular-rest/server](https://github.com/modular-rest/modular-rest) package. While maintaining compatibility with the JavaScript version, it adds type safety and better developer experience.
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install @modular-rest/server-ts
21
+ # or
22
+ yarn add @modular-rest/server-ts
17
23
  ```
18
24
 
19
- ## use modular-rest `createRest`
20
-
21
- to work with modular-rest you need an `app.js` and a `routers` folder. then configuring `app.js` and put your each router as a subfolder into the `routers` folder.
22
-
23
-
24
- ### configuring `app.js`
25
- simple configuration of `app.js` with `koa-router` module.
26
-
27
- ```js
28
- const modularRest = require('modular-rest');
29
- let koaBody = require('koa-body');
30
-
31
- let option = {
32
- root: require('path').join(__dirname, 'routers'),
33
- onBeforInit: BeforInit, // befor anything
34
- onInit: Init, // after collecting routers
35
- onAfterInit: AfterInit, // affter launch server
36
- port: 80,
37
-
38
- // if it would be true, app doesn't listen to port,
39
- // and a raw app object with all routers will be returned.
40
- // this option is for virtual host middlewares
41
- dontlisten: false,
42
-
43
- // collecting other services from subfolders
44
- otherSrvice: [
45
- {
46
- filename: {name: 'fn', extension:'.js'},
47
- rootDirectory: require('path').join(__dirname, 'routers'),
48
- option: {
49
- // if this option woulde be true, the property of each service will be attached to rootObject
50
- // the `name` property will be rejected and only the main property of each service would be recognize.
51
- // it would be useful when you want to collect all mongoose models in one root object.
52
- combineWithRoot: false,
53
-
54
- // convert the rootObject to an array
55
- // the `name` property will be rejected and only the main property of each service would be recognize.
56
- convertToArray: false,
57
- }
58
- }
59
- ],
60
- };
61
-
62
- function BeforInit(app)
63
- {
64
- // use a body parser
65
- // it must be used befor init
66
- app.use(koaBody());
67
- }
68
-
69
- function Init(app, otherSrvice)
70
- {
71
- // use otherSrvice
72
- // all your other services will injected to `otherSrvice` object.
73
- // eahc service would be accessible by its filename
74
- global.services = otherSrvice['fn'];
75
- }
76
-
77
- function AfterInit(app, otherSrvice) {
78
- // do something
79
- }
80
-
81
- modularRest.createRest(option).then(app => {
82
- // do something
25
+ ## Usage
26
+
27
+ ```typescript
28
+ import { createRest } from '@modular-rest/server-ts';
29
+
30
+ // Create a Koa application with modular-rest
31
+ createRest({
32
+ port: 3000,
33
+ modulesPath: __dirname + '/modules',
34
+ uploadDirectory: __dirname + '/uploads',
35
+ staticPath: {
36
+ rootDir: __dirname + '/assets',
37
+ rootPath: '/assets'
38
+ },
39
+ mongo: {
40
+ mongoBaseAddress: 'mongodb://localhost:27017',
41
+ dbPrefix: 'myapp_'
42
+ },
43
+ adminUser: {
44
+ email: 'admin@example.com',
45
+ password: 'securePassword'
46
+ }
47
+ }).then(({ app, server }) => {
48
+ console.log('Server started successfully');
83
49
  });
84
50
  ```
85
51
 
86
- ### configuring a route
87
- 1. go to `routers` folder and create a subfolder called `search` folder.
88
- 2. go to `search` folder and create a `route.js` file, then put these lines into it.
52
+ ## Key Features
89
53
 
90
- ```js
91
- let Router = require('koa-router');
92
- let name = 'search';
54
+ - Modular REST API development with Koa.js
55
+ - Built-in MongoDB integration
56
+ - User authentication and authorization
57
+ - File upload and management
58
+ - Event system
59
+ - Extensible architecture
93
60
 
94
- let search = new Router();
95
- search.get('/', (ctx) => {
96
- ctx.body = 'send me a post request';
97
- });
61
+ ## TypeScript Support
62
+
63
+ This package includes full TypeScript type definitions for all API components. The entire codebase is written in TypeScript, providing:
64
+
65
+ - IntelliSense and autocompletion in modern IDEs
66
+ - Type safety for all API operations
67
+ - Better compile-time error detection
68
+ - Improved developer experience
69
+
70
+ ## Documentation
98
71
 
99
- search.post('/', (ctx) => {
100
- ctx.body = `Request Body: ${JSON.stringify(ctx.request.body)}`;
101
- })
72
+ The API documentation is automatically generated using TypeDoc. You can access the latest documentation:
102
73
 
103
- module.exports.name = name;
104
- module.exports.main = search;
74
+ - In the `docs` directory of this repository
75
+ - On the [modular-rest documentation site](https://modular-rest.github.io/docs)
76
+
77
+ ## Development
78
+
79
+ To build the package:
80
+
81
+ ```bash
82
+ yarn build
105
83
  ```
106
84
 
107
- ### Requesting
108
- your search web service is:
85
+ To run the development build with watch mode:
86
+
87
+ ```bash
88
+ yarn dev
109
89
  ```
110
- http://localhost:80/search
90
+
91
+ To generate documentation:
92
+
93
+ ```bash
94
+ yarn docs
111
95
  ```
112
96
 
97
+ ## License
113
98
 
114
- thank you for using Modular-Rest :)
99
+ MIT
package/dist/index.js ADDED
@@ -0,0 +1,79 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.userManager = exports.middleware = exports.fileService = exports.getCollection = exports.paginator = exports.reply = exports.validator = exports.TypeCasters = exports.defineFunction = exports.AccessTypes = exports.PermissionGroup = exports.PermissionTypes = exports.Permission = exports.AccessDefinition = exports.CmsTrigger = exports.DatabaseTrigger = exports.Schema = exports.schemas = exports.defineCollection = exports.CollectionDefinition = exports.createRest = void 0;
40
+ // Application
41
+ const application_1 = require("./application");
42
+ Object.defineProperty(exports, "createRest", { enumerable: true, get: function () { return application_1.createRest; } });
43
+ const mongoose_1 = require("mongoose");
44
+ Object.defineProperty(exports, "Schema", { enumerable: true, get: function () { return mongoose_1.Schema; } });
45
+ // Utilities
46
+ const paginator = __importStar(require("./class/paginator"));
47
+ exports.paginator = paginator;
48
+ const reply = __importStar(require("./class/reply"));
49
+ exports.reply = reply;
50
+ const validator_1 = require("./class/validator");
51
+ Object.defineProperty(exports, "validator", { enumerable: true, get: function () { return validator_1.validator; } });
52
+ const service_1 = require("./services/data_provider/service");
53
+ Object.defineProperty(exports, "getCollection", { enumerable: true, get: function () { return service_1.getCollection; } });
54
+ const service_2 = require("./services/functions/service");
55
+ Object.defineProperty(exports, "defineFunction", { enumerable: true, get: function () { return service_2.defineFunction; } });
56
+ const typeCasters_1 = __importDefault(require("./services/data_provider/typeCasters"));
57
+ exports.TypeCasters = typeCasters_1.default;
58
+ const service_3 = require("./services/user_manager/service");
59
+ Object.defineProperty(exports, "userManager", { enumerable: true, get: function () { return service_3.main; } });
60
+ const service_4 = require("./services/file/service");
61
+ Object.defineProperty(exports, "fileService", { enumerable: true, get: function () { return service_4.main; } });
62
+ // Base class
63
+ const collection_definition_1 = require("./class/collection_definition");
64
+ Object.defineProperty(exports, "CollectionDefinition", { enumerable: true, get: function () { return collection_definition_1.CollectionDefinition; } });
65
+ Object.defineProperty(exports, "defineCollection", { enumerable: true, get: function () { return collection_definition_1.defineCollection; } });
66
+ const db_schemas_1 = require("./class/db_schemas");
67
+ Object.defineProperty(exports, "schemas", { enumerable: true, get: function () { return db_schemas_1.schemas; } });
68
+ const database_trigger_1 = __importDefault(require("./class/database_trigger"));
69
+ exports.DatabaseTrigger = database_trigger_1.default;
70
+ const cms_trigger_1 = __importDefault(require("./class/cms_trigger"));
71
+ exports.CmsTrigger = cms_trigger_1.default;
72
+ const security_1 = require("./class/security");
73
+ Object.defineProperty(exports, "AccessDefinition", { enumerable: true, get: function () { return security_1.AccessDefinition; } });
74
+ Object.defineProperty(exports, "Permission", { enumerable: true, get: function () { return security_1.Permission; } });
75
+ Object.defineProperty(exports, "PermissionTypes", { enumerable: true, get: function () { return security_1.PermissionTypes; } });
76
+ Object.defineProperty(exports, "PermissionGroup", { enumerable: true, get: function () { return security_1.PermissionGroup; } });
77
+ Object.defineProperty(exports, "AccessTypes", { enumerable: true, get: function () { return security_1.AccessTypes; } });
78
+ const middleware = __importStar(require("./middlewares"));
79
+ exports.middleware = middleware;
package/docs/.keep ADDED
File without changes
@@ -0,0 +1,26 @@
1
+ ### System Access Types
2
+
3
+ The permission system works by matching the user's assigned permission types (stored in their permission group) against the required permissions defined on collections and functions. This allows for flexible and granular access control.
4
+
5
+ For example, a collection could be configured to:
6
+
7
+ - Allow read access for users with 'user_access' permission
8
+ - Restrict write operations to users with 'advanced_settings' permission
9
+ - Only let users who has the 'upload_file_access' access type in their permission group to upload new files
10
+
11
+ **Built-in Permission Types**
12
+
13
+ The system comes with the following pre-defined permission types:
14
+
15
+ | Permission Type | Description |
16
+ | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
17
+ | `god_access` | Grants unrestricted super admin access. Users with this permission can perform any operation and access all collections and functions. |
18
+ | `user_access` | Basic user-level access for authenticated users. Typically grants read access to most collections and basic functionality. |
19
+ | `upload_file_access` | Required specifically for file upload operations. Users need this permission to upload files to the system. |
20
+ | `remove_file_access` | Required for file deletion operations. Users need this permission to remove files from the system. |
21
+ | `anonymous_access` | Used for unauthenticated access. Defines what operations are available to users who are not logged in. |
22
+ | `advanced_settings` | Grants access to advanced system configuration and administrative features. More privileged than basic user access. |
23
+
24
+ These permission types can be combined in permission groups to create different access levels. For example, an admin user might have both `advanced_settings` and `user_access`, while a basic user would only have `user_access`.
25
+
26
+ You can also define custom permission types for specific needs in your application. The permission system is flexible enough to accommodate any additional access types you require.
package/package.json CHANGED
@@ -1,47 +1,60 @@
1
1
  {
2
- "name": "@modular-rest/server",
3
- "version": "1.11.12",
4
- "description": "a nodejs module based on KOAJS for developing Rest-APIs in a modular solution.",
5
- "main": "src/index.js",
6
- "scripts": {
7
- "test": "echo \"Error: no test specified\" && exit 1",
8
- "generate:types": "tsc"
9
- },
10
- "types": "./types/index.d.ts",
11
- "repository": {
12
- "type": "git",
13
- "url": "git+https://github.com/modular-rest/modular-rest.git"
14
- },
15
- "keywords": [
16
- "app",
17
- "rest",
18
- "api",
19
- "koa"
20
- ],
21
- "author": "Navid Shad <navidshad72@gmail.com> (http://navid-shad.ir)",
22
- "license": "MIT",
23
- "bugs": {
24
- "url": "https://github.com/modular-rest/modular-rest/issues"
25
- },
26
- "homepage": "https://github.com/modular-rest/modular-rest#readme",
27
- "dependencies": {
28
- "@koa/cors": "^3.1.0",
29
- "colog": "^1.0.4",
30
- "file-system": "^2.2.2",
31
- "jsonwebtoken": "^8.5.1",
32
- "keypair": "^1.0.4",
33
- "koa": "^2.5.3",
34
- "koa-body": "^4.2.0",
35
- "koa-mount": "^4.0.0",
36
- "koa-router": "^7.4.0",
37
- "koa-static": "^5.0.0",
38
- "mongoose": "^5.10.9",
39
- "nested-property": "^4.0.0"
40
- },
41
- "devDependencies": {
42
- "@types/bson": "4.2.0",
43
- "@types/koa": "^2.14.0",
44
- "@types/koa__cors": "^5.0.0",
45
- "typescript": "^5.3.3"
46
- }
2
+ "name": "@modular-rest/server",
3
+ "version": "1.11.14",
4
+ "description": "TypeScript version of a nodejs module based on KOAJS for developing Rest-APIs in a modular solution.",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "test": "echo \"Error: no test specified\" && exit 1",
11
+ "play-test": "tsc -p tsconfig.json && node dist/play-test.js",
12
+ "docs": "typedoc --router kind src/index.ts"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git+https://github.com/modular-rest/modular-rest.git"
17
+ },
18
+ "keywords": [
19
+ "app",
20
+ "rest",
21
+ "api",
22
+ "koa",
23
+ "typescript"
24
+ ],
25
+ "author": "Navid Shad <navidshad72@gmail.com> (http://navid-shad.ir)",
26
+ "license": "MIT",
27
+ "bugs": {
28
+ "url": "https://github.com/modular-rest/modular-rest/issues"
29
+ },
30
+ "homepage": "https://github.com/modular-rest/modular-rest#readme",
31
+ "dependencies": {
32
+ "@koa/cors": "^3.1.0",
33
+ "colog": "^1.0.4",
34
+ "file-system": "^2.2.2",
35
+ "jsonwebtoken": "^8.5.1",
36
+ "keypair": "^1.0.4",
37
+ "koa": "^2.5.3",
38
+ "koa-body": "6.0.1",
39
+ "koa-mount": "^4.0.0",
40
+ "koa-router": "^7.4.0",
41
+ "koa-static": "^5.0.0",
42
+ "mongoose": "^5.10.9",
43
+ "nested-property": "^4.0.0"
44
+ },
45
+ "devDependencies": {
46
+ "@types/bson": "4.2.0",
47
+ "@types/jsonwebtoken": "^9.0.5",
48
+ "@types/koa": "^2.14.0",
49
+ "@types/koa-mount": "^4.0.5",
50
+ "@types/koa-router": "^7.4.8",
51
+ "@types/koa-static": "^4.0.4",
52
+ "@types/koa__cors": "^5.0.0",
53
+ "@types/mongoose": "^5.10.5",
54
+ "@types/node": "^20.10.0",
55
+ "typedoc": "^0.28.1",
56
+ "typedoc-plugin-markdown": "^4.6.0",
57
+ "typedoc-plugin-missing-exports": "^4.0.0",
58
+ "typescript": "^5.3.3"
59
+ }
47
60
  }
@@ -0,0 +1,206 @@
1
+ import Koa from 'koa';
2
+ import cors from '@koa/cors';
3
+ import koaBody from 'koa-body';
4
+ import koaStatic from 'koa-static';
5
+ import mount from 'koa-mount';
6
+ import path from 'path';
7
+ import { Server } from 'http';
8
+ import Combination from './class/combinator';
9
+ import * as DataProvider from './services/data_provider/service';
10
+ import { MongoOption } from './services/data_provider/service';
11
+ import * as UserService from './services/user_manager/service';
12
+ import { config, setConfig, RestOptions, StaticPathOptions } from './config';
13
+ import { permissionGroups as defaultPermissionGroups } from './defult-permissions';
14
+
15
+ const defaultServiceRoot = __dirname + '/services';
16
+
17
+ /**
18
+ * Create a modular REST instance with Koa and MongoDB support.
19
+ *
20
+ * @param {RestOptions} options - Options for the REST instance
21
+ * @expandType RestOptions
22
+ *
23
+ * @returns {Promise<{ app: Koa; server?: Server }>} - A promise that resolves to the Koa app and server
24
+ *
25
+ * @example
26
+ * import { createRest } from '@modular-rest/server';
27
+ *
28
+ * const app = createRest({
29
+ * port: '80',
30
+ * mongo: {
31
+ * mongoBaseAddress: 'mongodb://localhost:27017',
32
+ * dbPrefix: 'mrest_'
33
+ * },
34
+ * onBeforeInit: (koaApp) => {
35
+ * // do something before init with the koa app
36
+ * }
37
+ * })
38
+ */
39
+ export async function createRest(options: RestOptions): Promise<{ app: Koa; server?: Server }> {
40
+ setConfig({
41
+ port: 3000,
42
+ dontListen: false,
43
+ mongo: {
44
+ mongoBaseAddress: 'mongodb://localhost:27017',
45
+ dbPrefix: 'mrest_',
46
+ },
47
+ adminUser: {
48
+ email: 'admin@email.com',
49
+ password: '@dmin',
50
+ },
51
+ ...options,
52
+ });
53
+
54
+ if (config.permissionGroups === undefined) {
55
+ config.permissionGroups = defaultPermissionGroups;
56
+ }
57
+
58
+ const app = new Koa();
59
+
60
+ /**
61
+ * Plug in Cors
62
+ */
63
+ app.use(cors(config.cors || {}));
64
+
65
+ /**
66
+ * Plug in BodyParser
67
+ */
68
+ const bodyParserOptions = {
69
+ multipart: true,
70
+ ...(config.koaBodyOptions || {}),
71
+ };
72
+ app.use(koaBody(bodyParserOptions));
73
+
74
+ /**
75
+ * Plug In KoaStatic
76
+ */
77
+ if (config.staticPath) {
78
+ const defaultStaticPath = config.staticPath.actualPath || '';
79
+ const defaultStaticRootPath = config.staticPath.path || '/assets';
80
+
81
+ const staticOptions: Partial<StaticPathOptions> = { ...config.staticPath };
82
+
83
+ delete staticOptions.actualPath;
84
+ delete staticOptions.path;
85
+
86
+ app.use(mount(defaultStaticRootPath, koaStatic(defaultStaticPath, staticOptions)));
87
+ }
88
+
89
+ /**
90
+ * Run before hook
91
+ */
92
+ if (config.onBeforeInit) config.onBeforeInit(app);
93
+
94
+ /**
95
+ * Setup default services
96
+ *
97
+ * - Collect and plug in router.js/db.js of default services
98
+ * - Setting up default services
99
+ */
100
+
101
+ // 1. Plug in default routes
102
+ await Combination.combineRoutesByFilePath(path.join(defaultServiceRoot), app);
103
+
104
+ // Collect default databaseDefinitions
105
+ const defaultDatabaseDefinitionList = await Combination.combineModulesByFilePath({
106
+ rootDirectory: defaultServiceRoot,
107
+ filename: {
108
+ name: 'db',
109
+ extension: '.js',
110
+ },
111
+ combineWithRoot: true,
112
+ });
113
+
114
+ // 2. Plug in default databaseDefinitions
115
+ await DataProvider.addCollectionDefinitionByList({
116
+ list: defaultDatabaseDefinitionList,
117
+ mongoOption: config.mongo as MongoOption,
118
+ });
119
+
120
+ /**
121
+ * User Services
122
+ *
123
+ * 3. Plug in routes and database
124
+ */
125
+ if (config.modulesPath) {
126
+ // Plug in user routes
127
+ await Combination.combineRoutesByFilePath(config.modulesPath, app);
128
+
129
+ // Collect user CollectionDefinitions (db.js files)
130
+ let userDatabaseDetail: any[] = [];
131
+ userDatabaseDetail = await Combination.combineModulesByFilePath({
132
+ rootDirectory: config.modulesPath,
133
+ filename: {
134
+ name: 'db',
135
+ extension: '.js',
136
+ },
137
+ combineWithRoot: true,
138
+ });
139
+
140
+ // Combine additional CollectionDefinitions
141
+ if (config.collectionDefinitions) {
142
+ userDatabaseDetail = userDatabaseDetail.concat(config.collectionDefinitions);
143
+ }
144
+
145
+ // Plug in user CollectionDefinitions
146
+ await DataProvider.addCollectionDefinitionByList({
147
+ list: userDatabaseDetail || [],
148
+ mongoOption: config.mongo as MongoOption,
149
+ });
150
+
151
+ // Plug in Verification method
152
+ if (typeof config.verificationCodeGeneratorMethod === 'function') {
153
+ UserService.main.setCustomVerificationCodeGeneratorMethod(
154
+ config.verificationCodeGeneratorMethod
155
+ );
156
+ }
157
+
158
+ // 4. plug in modular functions
159
+ await Combination.combineFunctionsByFilePath({
160
+ rootDirectory: config.modulesPath,
161
+ filename: {
162
+ name: 'functions',
163
+ extension: '.js',
164
+ },
165
+ });
166
+
167
+ // 5. Plug in additional defined functions
168
+ if (config.functions) {
169
+ Combination.addFunctionsByArray(config.functions);
170
+ }
171
+ }
172
+
173
+ // 4. Setting up default services
174
+ try {
175
+ await require('./helper/presetup_services').setup(options);
176
+ } catch (e) {
177
+ return Promise.reject(e);
178
+ }
179
+
180
+ /**
181
+ * Run the server
182
+ *
183
+ * return KOA app object
184
+ */
185
+ return new Promise((done, reject) => {
186
+ try {
187
+ let server: Server | undefined;
188
+
189
+ if (!config.dontListen) {
190
+ server = app.listen(config.port);
191
+
192
+ console.log('\x1b[35m', `KOAS has been launched on: localhost:${config.port}`);
193
+ }
194
+
195
+ // on after init
196
+ if (config.onAfterInit) config.onAfterInit(app);
197
+
198
+ done({
199
+ app,
200
+ server,
201
+ });
202
+ } catch (err) {
203
+ reject(err);
204
+ }
205
+ });
206
+ }