minimonolith 0.21.2 → 0.22.1
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/README.md +57 -32
- package/index.js +14 -5
- package/package.json +2 -1
- package/src/api/get/index.js +19 -0
- package/src/api/getNewAPI/index.js +13 -0
- package/src/api/getSyncedHandler/index.js +24 -0
- package/src/api/index.js +3 -3
- package/src/api/postService/index.js +32 -0
- package/src/autotest/getMethodTest/back.index.js +29 -0
- package/src/autotest/getMethodTest/index.js +12 -0
- package/src/autotest/getTestServerResponse/index.js +14 -0
- package/src/autotest/index.js +3 -0
- package/src/control/get/index.js +3 -0
- package/src/control/index.js +3 -0
- package/src/database/index.js +3 -3
- package/src/database/post/index.js +28 -0
- package/src/database/postConnection/index.js +25 -0
- package/src/environment/getDBEnvVars/index.js +4 -0
- package/src/environment/getENVEnvVars/index.js +4 -0
- package/src/environment/index.js +4 -0
- package/src/{development/loadEnvFile.js → environment/postEnvFile/index.js} +4 -5
- package/src/environment/postTestEnvironment/index.js +6 -0
- package/src/error/index.js +4 -0
- package/src/error/postCompiletime/index.js +13 -0
- package/src/error/postRuntime/index.js +7 -0
- package/src/event/getParsedEvent/index.js +9 -0
- package/src/event/index.js +3 -0
- package/src/health/index.js +2 -2
- package/src/health/post/index.js +10 -0
- package/src/log/index.js +5 -0
- package/src/log/post/index.js +3 -0
- package/src/log/postError/index.js +3 -0
- package/src/log/postQA/index.js +3 -0
- package/src/{service/parseMethodCode.js → method/getParsedCode/index.js} +1 -1
- package/src/method/getResponseCode/index.js +9 -0
- package/src/{service/getMethodRouteCode.js → method/getRouteCode/index.js} +2 -4
- package/src/{service/getMethodType.js → method/getType/index.js} +1 -3
- package/src/method/index.js +7 -0
- package/src/method/post/index.js +48 -0
- package/src/method/postResponse/index.js +13 -0
- package/src/middleware/index.js +4 -0
- package/src/middleware/postCors/index.js +21 -0
- package/src/middleware/postError/index.js +10 -0
- package/src/model/getSynced/index.js +22 -0
- package/src/model/index.js +3 -2
- package/src/model/post/index.js +11 -0
- package/src/path/{getProjectRoot.js → getProjectRoot/index.js} +1 -3
- package/src/path/index.js +2 -2
- package/src/{development/serverHandler.js → server/getNodejsServerHandler/index.js} +19 -22
- package/src/server/getServerFactory/index.js +13 -0
- package/src/server/index.js +3 -0
- package/src/{database/validation.js → validation/dbValidation.js} +1 -3
- package/src/validation/get/index.js +19 -0
- package/src/{zod/optionalZObject.js → validation/getOptionalObject/index.js} +1 -1
- package/src/validation/index.js +8 -0
- package/src/validation/postError/index.js +15 -0
- package/src/api/apiHandler.js +0 -13
- package/src/api/createAPI.js +0 -51
- package/src/crasher/crasher.js +0 -1
- package/src/crasher/index.js +0 -3
- package/src/database/databaseService.js +0 -49
- package/src/development/createDevEnvironment.js +0 -10
- package/src/development/createTestEnvironment.js +0 -9
- package/src/development/index.js +0 -4
- package/src/development/lambdaServer.js +0 -11
- package/src/health/healthService.js +0 -15
- package/src/logger/index.js +0 -3
- package/src/logger/logger.js +0 -5
- package/src/model/loadModels.js +0 -33
- package/src/service/index.js +0 -4
- package/src/service/methodHandler.js +0 -25
- package/src/service/registerMethod.js +0 -36
- package/src/service/registerService.js +0 -70
- package/src/zod/index.js +0 -5
package/README.md
CHANGED
|
@@ -31,12 +31,12 @@ This file is used for local development. It runs a local server using `minimonol
|
|
|
31
31
|
|
|
32
32
|
```js
|
|
33
33
|
// server.js
|
|
34
|
-
import {
|
|
35
|
-
const { runLambdaServer, loadEnvFile } = await devEnvironment();
|
|
36
|
-
loadEnvFile(); // .env file loaded by default
|
|
34
|
+
import { getServer } from 'minimonolith';
|
|
37
35
|
|
|
38
|
-
const
|
|
39
|
-
|
|
36
|
+
const lambdaServer = await getServer(); // loads .env by default, could give '.env.test'
|
|
37
|
+
const { lambdaHandler } = await import('./index.js');
|
|
38
|
+
|
|
39
|
+
lambdaServer(lambdaHandler, 8080);
|
|
40
40
|
```
|
|
41
41
|
|
|
42
42
|
### index.js
|
|
@@ -47,15 +47,21 @@ This file serves as the root of the code in a deployed AWS Lambda:
|
|
|
47
47
|
// index.js
|
|
48
48
|
'use strict';
|
|
49
49
|
|
|
50
|
-
import {
|
|
50
|
+
import { getNewAPI } from 'minimonolith';
|
|
51
|
+
|
|
52
|
+
// Define environment
|
|
53
|
+
const { DEV_ENV, PROD_ENV, TEST_ENV } = process.env;
|
|
54
|
+
const API = await getNewAPI({ DEV_ENV, PROD_ENV, TEST_ENV });
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
await API.postHealthService();
|
|
57
|
+
await API.postService('todo');
|
|
58
|
+
await API.postCORSService();
|
|
53
59
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
await API.
|
|
60
|
+
// Database Authentication
|
|
61
|
+
const { DB_DIALECT, DB_HOST, DB_DB, DB_USER, DB_PASSWORD, DB_STORAGE } = process.env;
|
|
62
|
+
await API.postDatabaseService({ DB_DIALECT, DB_HOST, DB_DB, DB_USER, DB_PASSWORD, DB_STORAGE });
|
|
57
63
|
|
|
58
|
-
export const lambdaHandler = await API.
|
|
64
|
+
export const lambdaHandler = await API.getSyncedHandler()
|
|
59
65
|
```
|
|
60
66
|
|
|
61
67
|
### todo/index.js
|
|
@@ -114,6 +120,22 @@ export default ({ MODELS }) => ({
|
|
|
114
120
|
})
|
|
115
121
|
```
|
|
116
122
|
|
|
123
|
+
## Response Codes
|
|
124
|
+
|
|
125
|
+
### Success
|
|
126
|
+
|
|
127
|
+
- POST -> 201
|
|
128
|
+
- DELETE -> 204
|
|
129
|
+
- Everything else -> 200
|
|
130
|
+
|
|
131
|
+
### Invalid Request
|
|
132
|
+
|
|
133
|
+
- ANY -> 400
|
|
134
|
+
|
|
135
|
+
### Runtime Error
|
|
136
|
+
|
|
137
|
+
- ANY -> 500
|
|
138
|
+
|
|
117
139
|
## App Environments
|
|
118
140
|
|
|
119
141
|
There are 4 possible environments:
|
|
@@ -129,52 +151,55 @@ To better understand their relevance:
|
|
|
129
151
|
2. The "new concept" QA environments (PROD=FALSE) aim at logging data about the system which on production environments would be forbiden personal information
|
|
130
152
|
- This is relevant because replication of QA activities (even security QA activities) depend heavily on this
|
|
131
153
|
|
|
132
|
-
The current App environment is determined on the values of
|
|
154
|
+
The current App environment is determined on the values of DEV ENV [TRUE/FALSE] and PROD_ENV [TRUE/FALSE]
|
|
155
|
+
Assuming using same env variables as used at index.js above
|
|
133
156
|
|
|
134
157
|
```makefile
|
|
135
158
|
# .env standard dev environment
|
|
136
|
-
|
|
137
|
-
|
|
159
|
+
DEV_ENV=TRUE
|
|
160
|
+
PROD_ENV=FALSE
|
|
161
|
+
TEST_ENV=FALSE
|
|
138
162
|
[...]
|
|
139
163
|
```
|
|
140
164
|
|
|
141
|
-
*NOTICE*:
|
|
165
|
+
*NOTICE*: Default environment it is assumed standard PROD environment (DEV=FLASE + PROD=TRUE)
|
|
142
166
|
- This means that sequelize will not alter automatically tables having mismatches with defined model.js files
|
|
143
167
|
- Database dialect/credentials detected will not be printed
|
|
144
168
|
- Critical errors will not make the app crash
|
|
145
169
|
|
|
146
170
|
## Database Authentication
|
|
147
171
|
|
|
148
|
-
To set up authentication for the database
|
|
172
|
+
To set up authentication for the database you need to pass necessary variables to postDatabaseService as at index.js above.
|
|
173
|
+
Assuming using same env variables as used at index.js above
|
|
149
174
|
|
|
150
175
|
For MySQL:
|
|
151
176
|
|
|
152
177
|
```makefile
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
178
|
+
DEV_ENV=TRUE
|
|
179
|
+
PROD_ENV=FALSE
|
|
180
|
+
DB_DIALECT=mysql
|
|
181
|
+
DB_HOST=<your_database_endpoint>
|
|
182
|
+
DB_PORT=<your_database_port>
|
|
183
|
+
DB_DB=<your_database_name>
|
|
184
|
+
DB_USER=<your_database_username>
|
|
185
|
+
DB_PASS=<your_database_password>
|
|
161
186
|
```
|
|
162
187
|
|
|
163
188
|
For SQLite:
|
|
164
189
|
|
|
165
190
|
```makefile
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
191
|
+
DEV_ENV=TRUE
|
|
192
|
+
PROD_ENV=FALSE
|
|
193
|
+
DB_DIALECT=sqlite
|
|
194
|
+
DB_DB=<your_database_name>
|
|
195
|
+
DB_STORAGE=:memory: # For in-memory SQLite database
|
|
170
196
|
# Or
|
|
171
|
-
|
|
172
|
-
MM_API_DB_DATABASE=<your_database_name>
|
|
197
|
+
DB_STORAGE=path/to/your/sqlite/file.db # For file-based SQLite database
|
|
173
198
|
```
|
|
174
199
|
|
|
175
200
|
Make sure to replace the placeholders with your actual database credentials.
|
|
176
|
-
- `
|
|
177
|
-
- `
|
|
201
|
+
- `DEV_ENV=TRUE` allows Sequelize to alter table structure automatically when working locally
|
|
202
|
+
- `PROD_ENV=FALSE` allows logging of DB credentials for debugging purposes in non-production environments
|
|
178
203
|
- We consider high quality logging important for app performance and evolution
|
|
179
204
|
- However we recommend automatic DB credentials updates (daily) High quality logging does not mean
|
|
180
205
|
giving away your infraestructure to hackers
|
package/index.js
CHANGED
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
1
|
+
import API_SERVICE from './src/api/index.js';
|
|
2
|
+
import SERVER_SERVICE from './src/server/index.js';
|
|
3
|
+
import VALIDATION_SERVICE from './src/validation/index.js';
|
|
4
|
+
import AUTOTEST_SERVICE from './src/autotest/index.js';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
const { getNewAPI } = API_SERVICE;
|
|
7
|
+
const { getServerFactory } = SERVER_SERVICE;
|
|
8
|
+
const { z, zdb } = VALIDATION_SERVICE;
|
|
9
|
+
const { getMethodTest } = AUTOTEST_SERVICE;
|
|
10
|
+
|
|
11
|
+
export {
|
|
12
|
+
getServerFactory, getNewAPI,
|
|
13
|
+
z, zdb,
|
|
14
|
+
getMethodTest,
|
|
15
|
+
};
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "minimonolith",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.22.1",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"scripts": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"@aws-sdk/client-s3": "^3.304.0",
|
|
23
23
|
"@aws-sdk/s3-request-presigner": "^3.304.0",
|
|
24
|
+
"cross-fetch": "^3.1.5",
|
|
24
25
|
"dotenv": "^16.0.3",
|
|
25
26
|
"jest": "^29.5.0",
|
|
26
27
|
"mysql2": "^3.2.0",
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import getLambdaAPI from 'lambda-api';
|
|
2
|
+
|
|
3
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
4
|
+
import HEALTH_SERVICE from '../../health/index.js';
|
|
5
|
+
import DATABASE_SERVICE from '../../database/index.js';
|
|
6
|
+
import MIDDLEWARE_SERVICE from '../../middleware/index.js';
|
|
7
|
+
|
|
8
|
+
import postService from '../postService/index.js';
|
|
9
|
+
import getSyncedHandler from '../getSyncedHandler/index.js';
|
|
10
|
+
|
|
11
|
+
const API = getLambdaAPI();
|
|
12
|
+
API.postCORSMiddleware = MIDDLEWARE_SERVICE.postCors;
|
|
13
|
+
API.postHealthService = HEALTH_SERVICE.post;
|
|
14
|
+
API.postService = postService;
|
|
15
|
+
API.postDatabaseService = DATABASE_SERVICE.post;
|
|
16
|
+
API.postErrorMiddleware = MIDDLEWARE_SERVICE.postError;
|
|
17
|
+
API.getSyncedHandler = getSyncedHandler;
|
|
18
|
+
|
|
19
|
+
export default () => API;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import getAPI from '../get/index.js';
|
|
2
|
+
|
|
3
|
+
export default ({ DEV_ENV='FALSE', PROD_ENV='TRUE', TEST_ENV='FALSE' } = {}) => {
|
|
4
|
+
getAPI().SERVICES = {};
|
|
5
|
+
getAPI().SCHEMAS = {};
|
|
6
|
+
getAPI().MODELS = {};
|
|
7
|
+
getAPI().ORM = undefined;
|
|
8
|
+
getAPI().DEV_ENV = DEV_ENV;
|
|
9
|
+
getAPI().PROD_ENV = PROD_ENV;
|
|
10
|
+
getAPI().TEST_ENV = TEST_ENV;
|
|
11
|
+
getAPI().postCORSMiddleware();
|
|
12
|
+
return getAPI();
|
|
13
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import MODEL_SERVICE from '../../model/index.js';
|
|
2
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
3
|
+
|
|
4
|
+
import getAPI from '../get/index.js';
|
|
5
|
+
|
|
6
|
+
const META_SERVICE='API', META_METHOD='GET_SYNCED_HANDLER', META_ROUTE=META_SERVICE+'_'+META_METHOD;
|
|
7
|
+
|
|
8
|
+
export default async () => {
|
|
9
|
+
getAPI().postErrorMiddleware();
|
|
10
|
+
if (getAPI().ORM) await MODEL_SERVICE.getSynced();
|
|
11
|
+
//else LOG_SERVICE.post({ META_ROUTE, INFO: 'NO_DATABASE_SERVICE_POSTED' });
|
|
12
|
+
|
|
13
|
+
LOG_SERVICE.post({ META_ROUTE, INFO: 'LISTENING' });
|
|
14
|
+
|
|
15
|
+
return async (event, context) => {
|
|
16
|
+
LOG_SERVICE.post({
|
|
17
|
+
ROUTE_CODE: 'LAMBDA_EVENT',
|
|
18
|
+
PATH: event.requestContext?.http?.path,
|
|
19
|
+
METHOD: event.requestContext?.http?.method,
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
return await getAPI().run(event, context);
|
|
23
|
+
};
|
|
24
|
+
};
|
package/src/api/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import get from './get/index.js';
|
|
2
|
+
import getNewAPI from './getNewAPI/index.js';
|
|
3
3
|
|
|
4
|
-
export {
|
|
4
|
+
export default { get, getNewAPI };
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import url from 'url'
|
|
3
|
+
|
|
4
|
+
import PATH_SERVICE from '../../path/index.js';
|
|
5
|
+
import MODEL_SERVICE from '../../model/index.js';
|
|
6
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
7
|
+
import METHOD_SERVICE from '../../method/index.js';
|
|
8
|
+
import VALIDATION_SERVICE from '../../validation/index.js';
|
|
9
|
+
import ERROR_SERVICE from '../../error/index.js';
|
|
10
|
+
|
|
11
|
+
import getAPI from '../get/index.js';
|
|
12
|
+
|
|
13
|
+
const META_SERVICE_NAME = 'API', META_METHOD_NAME = 'POST_SERVICE';
|
|
14
|
+
|
|
15
|
+
export default async (SERVICE_NAME, SRC_FOLDER='', MODULES_FOLDER='node_modules/') => {
|
|
16
|
+
|
|
17
|
+
LOG_SERVICE.post(META_SERVICE_NAME, META_METHOD_NAME, SERVICE_NAME);
|
|
18
|
+
getAPI().SERVICES[SERVICE_NAME] = {};
|
|
19
|
+
try {
|
|
20
|
+
|
|
21
|
+
const projectRootPath = PATH_SERVICE.getProjectRoot(import.meta.url, MODULES_FOLDER)+'/';
|
|
22
|
+
const projectRelativeServicePath = './' + SRC_FOLDER + `${SERVICE_NAME}/`;
|
|
23
|
+
const SERVICE_URL = new URL(projectRelativeServicePath, projectRootPath);
|
|
24
|
+
await MODEL_SERVICE.post(SERVICE_NAME, SERVICE_URL);
|
|
25
|
+
|
|
26
|
+
const SERVICE_MODULE = await import(`${SERVICE_URL}index.js`);
|
|
27
|
+
LOG_SERVICE.post('METHODS_TO_BE_POSTED', SERVICE_MODULE.default);
|
|
28
|
+
for (const METHOD_CODE of SERVICE_MODULE.default) await METHOD_SERVICE.post(SERVICE_NAME, SERVICE_URL, METHOD_CODE);
|
|
29
|
+
|
|
30
|
+
} catch (META_METHOD_ERROR) {
|
|
31
|
+
ERROR_SERVICE.postCompiletime({ META_SERVICE_NAME, META_METHOD_NAME, META_METHOD_ERROR }); }
|
|
32
|
+
};
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import url from 'url';
|
|
2
|
+
import fetch from 'cross-fetch';
|
|
3
|
+
|
|
4
|
+
import getTestServerResponse from '../getTestServerResponse/index.js';
|
|
5
|
+
|
|
6
|
+
export default (serverHandler, expectedCode) => async params => {
|
|
7
|
+
const URL = new url.URL(params.path, 'http://localhost/');
|
|
8
|
+
|
|
9
|
+
const request = {
|
|
10
|
+
method: params.method,
|
|
11
|
+
url: URL.pathname + URL.search,
|
|
12
|
+
headers: {
|
|
13
|
+
...params.headers,
|
|
14
|
+
'Content-Type': 'application/json',
|
|
15
|
+
},
|
|
16
|
+
on(eventName, callback) {
|
|
17
|
+
if (eventName === 'data' && params.body) {
|
|
18
|
+
callback(Buffer.from(JSON.stringify(params.body)));
|
|
19
|
+
}
|
|
20
|
+
if (eventName === 'end') { callback(); }
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
const response = getTestServerResponse();
|
|
25
|
+
serverHandler(request, response);
|
|
26
|
+
|
|
27
|
+
const result = await response.asyncResult();
|
|
28
|
+
expect(result.statusCode).toBe(expectedCode);
|
|
29
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export default async server => {
|
|
2
|
+
const fetch = (await import('cross-fetch')).default;
|
|
3
|
+
|
|
4
|
+
return async ({ path, method, expectedCode, headers, body }) => {
|
|
5
|
+
|
|
6
|
+
const port = server.address().port
|
|
7
|
+
const url = `http://localhost:${port}${path}`;
|
|
8
|
+
|
|
9
|
+
const response = await fetch(url, { method, headers, body });
|
|
10
|
+
expect(response.status).toBe(expectedCode);
|
|
11
|
+
};
|
|
12
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import http from 'http';
|
|
2
|
+
|
|
3
|
+
export default () => {
|
|
4
|
+
let resolveAsyncResult;
|
|
5
|
+
const asyncResultPromise = new Promise(resolve => { resolveAsyncResult = resolve; });
|
|
6
|
+
|
|
7
|
+
const res = {
|
|
8
|
+
statusCode: null,
|
|
9
|
+
asyncResult: () => asyncResultPromise,
|
|
10
|
+
end: body => { res.body = body; resolveAsyncResult(res); },
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
return res;
|
|
14
|
+
};
|
package/src/database/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import post from './post/index.js';
|
|
2
|
+
import postConnection from './postConnection/index.js';
|
|
3
3
|
|
|
4
|
-
export {
|
|
4
|
+
export default { post, postConnection };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import Sequelize from 'sequelize';
|
|
2
|
+
//import SequelizeDynamo from 'dynamo-sequelize';
|
|
3
|
+
|
|
4
|
+
import API_SERVICE from '../../api/index.js';
|
|
5
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
6
|
+
import ERROR_SERVICE from '../../error/index.js';
|
|
7
|
+
|
|
8
|
+
import postConnection from '../postConnection/index.js'
|
|
9
|
+
|
|
10
|
+
const META_SERVICE='DATABASE', META_METHOD='POST', META_ROUTE=META_SERVICE+'_'+META_METHOD;
|
|
11
|
+
|
|
12
|
+
export default async ({ DB_DIALECT='sqlite', DB_HOST=undefined, DB_PORT=undefined, DB_DB=undefined,
|
|
13
|
+
DB_USER=undefined, DB_PASS=undefined, DB_STORAGE=':memory:'} = {}) => {
|
|
14
|
+
|
|
15
|
+
try {
|
|
16
|
+
const SEQUELIZE_OPTIONS = { dialect: DB_DIALECT, host: DB_HOST,
|
|
17
|
+
port: DB_PORT, storage: DB_STORAGE, logging: false };
|
|
18
|
+
|
|
19
|
+
LOG_SERVICE.postQA({ META_ROUTE, DB_VARS: {
|
|
20
|
+
DB_DIALECT, DB_HOST, DB_PORT, DB_DB, DB_USER, DB_PASS, DB_STORAGE }});
|
|
21
|
+
|
|
22
|
+
API_SERVICE.get().ORM = new Sequelize(DB_DB, DB_USER, DB_PASS, SEQUELIZE_OPTIONS);
|
|
23
|
+
await postConnection(API_SERVICE.get().ORM);
|
|
24
|
+
|
|
25
|
+
} catch (META_METHOD_ERROR) {
|
|
26
|
+
ERROR_SERVICE.postCompiletime({ META_ROUTE, META_METHOD_ERROR });
|
|
27
|
+
}
|
|
28
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
2
|
+
|
|
3
|
+
const META_SERVICE_NAME='DATABASE', META_METHOD_NAME='POST_CONNECTION';
|
|
4
|
+
|
|
5
|
+
export default async ORM => {
|
|
6
|
+
const MAX_RETRIES = 5, INITIAL_WAIT = 100;
|
|
7
|
+
let connectionRetries = 0, waitTime = INITIAL_WAIT;
|
|
8
|
+
|
|
9
|
+
while (connectionRetries < MAX_RETRIES) {
|
|
10
|
+
try {
|
|
11
|
+
LOG_SERVICE.post({ META_SERVICE_NAME, META_METHOD_NAME, AUTH_INTENT: connectionRetries });
|
|
12
|
+
await ORM.authenticate();
|
|
13
|
+
break;
|
|
14
|
+
|
|
15
|
+
} catch (META_METHOD_ERROR) {
|
|
16
|
+
await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
17
|
+
|
|
18
|
+
connectionRetries += 1;
|
|
19
|
+
const jitter = Math.random() * 0.3 + 0.7;
|
|
20
|
+
waitTime = Math.min(2 * waitTime * jitter, INITIAL_WAIT * Math.pow(2, MAX_RETRIES));
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return connectionRetries;
|
|
25
|
+
};
|
|
@@ -2,13 +2,12 @@ import path from 'path';
|
|
|
2
2
|
import url from 'url';
|
|
3
3
|
import dotenv from 'dotenv';
|
|
4
4
|
|
|
5
|
-
import
|
|
5
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
6
|
+
import PATH_SERVICE from '../../path/index.js';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
const projectRootFileUrl = getProjectRoot(import.meta.url, MODULE_FOLDER);
|
|
8
|
+
export default (ENV_FILE, MODULE_FOLDER) => {
|
|
9
|
+
const projectRootFileUrl = PATH_SERVICE.getProjectRoot(import.meta.url, MODULE_FOLDER);
|
|
9
10
|
const projectRootPath = url.fileURLToPath(projectRootFileUrl+'/');
|
|
10
11
|
const envFilePath = path.resolve(projectRootPath, ENV_FILE)
|
|
11
12
|
dotenv.config({ path: envFilePath });
|
|
12
13
|
};
|
|
13
|
-
|
|
14
|
-
export { loadEnvFile };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import API_SERVICE from '../../api/index.js';
|
|
2
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
3
|
+
|
|
4
|
+
export default ({ META_SERVICE_NAME, META_METHOD_NAME, ROUTE_CODE, META_METHOD_ERROR }) => {
|
|
5
|
+
LOG_SERVICE.postError({
|
|
6
|
+
META_SERVICE_NAME,
|
|
7
|
+
META_METHOD_NAME,
|
|
8
|
+
ROUTE_CODE,
|
|
9
|
+
META_METHOD_ERROR,
|
|
10
|
+
STACK_TRACE: META_METHOD_ERROR?.stack,
|
|
11
|
+
});
|
|
12
|
+
if (API_SERVICE.get().DEV_ENV==='TRUE') throw META_METHOD_ERROR;
|
|
13
|
+
};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export default event => {
|
|
2
|
+
const { body, params, query, requestContext } = event;
|
|
3
|
+
const claims = requestContext.authorizer?.jwt?.claims
|
|
4
|
+
|
|
5
|
+
const tempUnifiedBody = { ...body, ...params, ...query };
|
|
6
|
+
const unifiedBody = Object.keys(tempUnifiedBody).length > 0 ? tempUnifiedBody : undefined;
|
|
7
|
+
|
|
8
|
+
return { body: unifiedBody, claims };
|
|
9
|
+
}
|
package/src/health/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import
|
|
1
|
+
import post from './post/index.js';
|
|
2
2
|
|
|
3
|
-
export {
|
|
3
|
+
export default { post };
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import API_SERVICE from '../../api/index.js';
|
|
2
|
+
import LOG_SERVICE from '../../log/index.js';
|
|
3
|
+
|
|
4
|
+
export default () => {
|
|
5
|
+
API_SERVICE.get().get('/', async (req, res) => {
|
|
6
|
+
const SERVICE_RESPONSE = "API_RUNNING";
|
|
7
|
+
LOG_SERVICE.post({ SERVICE_RESPONSE });
|
|
8
|
+
return { SERVICE_RESPONSE: "API_RUNNING" };
|
|
9
|
+
});
|
|
10
|
+
}
|
package/src/log/index.js
ADDED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export default (SERVICE_NAME, METHOD_CODE) => {
|
|
2
2
|
const methodPathParts = METHOD_CODE.split(":");
|
|
3
3
|
const pathParams = methodPathParts.slice(1).map(param => `:${param}`);
|
|
4
4
|
const rawMethodName = methodPathParts[0];
|
|
@@ -5,10 +5,8 @@ const getUpperSnakeCase = str => {
|
|
|
5
5
|
.toUpperCase();
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
export default (SERVICE_NAME, METHOD_NAME) => {
|
|
9
9
|
const snakeServiceName = getUpperSnakeCase(SERVICE_NAME);
|
|
10
10
|
const snakeMethodName = getUpperSnakeCase(METHOD_NAME);
|
|
11
11
|
return snakeServiceName + '_' + snakeMethodName;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export { getMethodRouteCode };
|
|
12
|
+
};
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
const methodsAvailable = ['post', 'get', 'patch', 'put', 'delete'];
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
export default METHOD_NAME => {
|
|
4
4
|
const methodMatched = METHOD_NAME.match(/^[a-z]*/);
|
|
5
5
|
if (!methodMatched || !methodsAvailable.includes(methodMatched[0]))
|
|
6
6
|
throw new Error('UNKNOWN_METHOD_TYPE: ' + METHOD_NAME);
|
|
7
7
|
|
|
8
8
|
return methodMatched[0];
|
|
9
9
|
}
|
|
10
|
-
|
|
11
|
-
export { getMethodType };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import post from './post/index.js';
|
|
2
|
+
import getParsedCode from './getParsedCode/index.js';
|
|
3
|
+
import getType from './getType/index.js';
|
|
4
|
+
import getRouteCode from './getRouteCode/index.js';
|
|
5
|
+
import postResponse from './postResponse/index.js';
|
|
6
|
+
|
|
7
|
+
export default { post, getParsedCode, getType, getRouteCode, postResponse };
|