minimonolith 0.5.0 → 0.6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "minimonolith",
3
3
  "type": "module",
4
- "version": "0.5.0",
4
+ "version": "0.6.0",
5
5
  "main": "index.js",
6
6
  "license": "MIT",
7
7
  "scripts": {
@@ -1,7 +1,8 @@
1
1
  import lambdaAPICreateAPI from 'lambda-api';
2
2
 
3
- import { healthHandler } from '../healthHandler/index.js';
4
- import { serviceHandler } from '../serviceHandler/index.js';
3
+ import { registerHealthService } from '../registerHealthService/index.js';
4
+ import { registerDatabaseService } from '../registerDatabaseService/index.js';
5
+ import { registerService } from '../registerService/index.js';
5
6
  import { apiHandler } from './apiHandler.js';
6
7
 
7
8
  const addCORS = API => {
@@ -15,6 +16,10 @@ const addCORS = API => {
15
16
  console.log('OPTIONS_SUCCESS');
16
17
  res.status(200).send({})
17
18
  });
19
+ };
20
+
21
+ const addService = API => {
22
+
18
23
  }
19
24
 
20
25
  const createAPI = () => {
@@ -23,13 +28,17 @@ const createAPI = () => {
23
28
  addCORS(API);
24
29
 
25
30
  API.registerService = (SERVICE_NAME, SRC_FOLDER='', MODULE_FOLDER='node_modules/') =>
26
- serviceHandler(API, SERVICE_NAME, SRC_FOLDER, MODULE_FOLDER);
31
+ registerService(API, SERVICE_NAME, SRC_FOLDER, MODULE_FOLDER);
32
+
33
+ API.registerHealthService = () => registerHealthService(API);
27
34
 
28
- API.registerHealthService = () =>
29
- healthHandler(API);
35
+ API.registerDatabaseService = async () => { await registerDatabaseService(API) };
30
36
 
31
37
  API.handler = () => apiHandler(API);
32
38
 
39
+ API.SERVICES = {};
40
+
41
+
33
42
  return API;
34
43
  }
35
44
 
@@ -0,0 +1,4 @@
1
+ import { registerDatabaseService } from './registerDatabaseService.js';
2
+ import { registerModel } from './loadModels.js';
3
+
4
+ export { registerDatabaseService, registerModel };
@@ -1,3 +1,5 @@
1
+ const ROUTE_CODE = 'LOAD_MODELS';
2
+
1
3
  const modelSchemas = {};
2
4
 
3
5
  export const registerModel = async (SERVICE_NAME, SERVICE_URL) => {
@@ -5,7 +7,7 @@ export const registerModel = async (SERVICE_NAME, SERVICE_URL) => {
5
7
  modelSchemas[SERVICE_NAME] = SERVICE_MODEL_MODULE.modelSchema(SERVICE_NAME);
6
8
  }
7
9
 
8
- export const loadModels = (orm, types) => {
10
+ const loadModels = (orm, types) => {
9
11
  const MODELS = Object.keys(modelSchemas).reduce((loadedModels, serviceName) => {
10
12
  loadedModels[serviceName] = modelSchemas[serviceName](orm, types);
11
13
  return loadedModels;
@@ -14,3 +16,15 @@ export const loadModels = (orm, types) => {
14
16
  Object.entries(MODELS).forEach(([serviceName, model]) => { model.associate(MODELS); });
15
17
  return MODELS;
16
18
  }
19
+
20
+ const loadAndSyncModels = async (orm, types) => {
21
+ if (!process.env.TEST_ENVIRONMENT) console.log(ROUTE_CODE, 'Loading sequelize models');
22
+ const MODELS = loadModels(orm, types);
23
+
24
+ if (!process.env.TEST_ENVIRONMENT) console.log(ROUTE_CODE, 'Syncing sequelize');
25
+ await orm.sync({ alter: process.env.LOCAL ? true : false });
26
+
27
+ return MODELS;
28
+ };
29
+
30
+ export { loadAndSyncModels };
@@ -0,0 +1,61 @@
1
+ import Sequelize from 'sequelize';
2
+ //import SequelizeDynamo from 'dynamo-sequelize';
3
+ import { loadAndSyncModels } from './loadModels.js';
4
+
5
+ const ROUTE_CODE = 'DB_CONNECTION';
6
+
7
+ const tryAuthenticating = async (orm, connectionRetries) => {
8
+ if (!process.env.TEST_ENVIRONMENT) console.log(ROUTE_CODE, 'Authenticating sequelize intent:', connectionRetries);
9
+ await orm.authenticate();
10
+ };
11
+
12
+ const createORMInstance = () => {
13
+ if (process.env.TEST_ENVIRONMENT) {
14
+ const orm = new Sequelize('sqlite::memory:');
15
+ orm.options.logging = false;
16
+ return orm;
17
+ } else {
18
+ const dialect = 'mysql', logging = false, dialectOptions = null;
19
+ const db=process.env.DB_DB, user=process.env.DB_USER,
20
+ pass=process.env.DB_PASS, host=process.env.DB_ENDPOINT;
21
+ console.log(ROUTE_CODE,
22
+ 'Trying to connect using { ' + user + ', ' + pass + ', ' + host + ', ' + db + ' }');
23
+ return new Sequelize(db, user, pass, { host, dialect, dialectOptions, logging });
24
+ }
25
+ };
26
+
27
+
28
+ const establishConnection = async () => {
29
+ const MAX_RETRIES = 5;
30
+ const INITIAL_WAIT_TIME_MS = 100;
31
+ let connectionRetries = 0;
32
+ let waitTime = INITIAL_WAIT_TIME_MS;
33
+ const orm = createORMInstance();
34
+
35
+ while (connectionRetries < MAX_RETRIES) {
36
+ try {
37
+ await tryAuthenticating(orm, connectionRetries);
38
+ break;
39
+ } catch (databaseConnectionError) {
40
+ await new Promise(resolve => setTimeout(resolve, waitTime));
41
+ waitTime *= 2; connectionRetries += 1;
42
+ }
43
+ }
44
+
45
+ return orm;
46
+ };
47
+
48
+ const registerDatabaseService = async API => {
49
+ try {
50
+ const orm = await establishConnection();
51
+ API.MODELS = await loadAndSyncModels(orm, Sequelize);
52
+
53
+ } catch (DB_ERROR) {
54
+ console.error({
55
+ ROUTE_CODE,
56
+ DB_ERROR
57
+ });
58
+ }
59
+ };
60
+
61
+ export { registerDatabaseService };
@@ -1,14 +1,14 @@
1
- const healthCheck = () => {
1
+ const healthHandler = () => {
2
2
  return "API running...";
3
3
  }
4
4
 
5
- const healthHandler = API => {
5
+ const registerHealthService = API => {
6
6
  API.get('/', async (req, res) => {
7
7
  console.log('HEALTH_CHECK ENTERING');
8
- const response = healthCheck();
8
+ const response = healthHandler();
9
9
  console.log('HEALTH_CHECK SUCCESS');
10
10
  return { response };
11
11
  });
12
12
  }
13
13
 
14
- export { healthHandler };
14
+ export { registerHealthService };
@@ -0,0 +1,3 @@
1
+ import { registerHealthService } from './healthHandler.js';
2
+
3
+ export { registerHealthService };
@@ -0,0 +1,4 @@
1
+ import { registerService } from './registerService.js';
2
+
3
+ export { registerService };
4
+
@@ -1,16 +1,13 @@
1
- import { databaseHandler } from '../databaseHandler/index.js';
2
1
  import { validationHandler } from './validationHandler.js';
3
2
 
4
- const methodHandlerErrorThrower = async (e, METHOD, ROUTE_CODE) => {
5
-
6
- const { MODELS, databaseErrorResponse } = await databaseHandler(e);
7
- if (databaseErrorResponse) return databaseErrorResponse;
3
+ const methodHandlerErrorThrower = async (event, API, METHOD, ROUTE_CODE) => {
8
4
 
9
5
  const validationErrorResponse =
10
- await validationHandler(e, METHOD, MODELS, ROUTE_CODE);
6
+ await validationHandler(event, METHOD, API.MODELS, ROUTE_CODE);
11
7
  if (validationErrorResponse) return validationErrorResponse;
12
8
 
13
- const methodResponse = await METHOD.handler(e, MODELS);
9
+ const eventContext = { event, MODELS: API.MODELS, SERVICES: API.SERVICES, ROUTE_CODE };
10
+ const methodResponse = await METHOD.handler(eventContext);
14
11
 
15
12
  if (!process.env.TEST_ENVIRONMENT) console.log(ROUTE_CODE, methodResponse);
16
13
  return methodResponse;
@@ -28,10 +25,10 @@ const methodErrorHandler = (METHOD_ERROR, METHOD, ROUTE_CODE) => {
28
25
  return methodErrorResponse;
29
26
  }
30
27
 
31
- const methodHandler = async (METHOD, ROUTE_CODE, e) => {
28
+ const methodHandler = async (API, METHOD, ROUTE_CODE, event) => {
32
29
  try {
33
30
  if (!process.env.TEST_ENVIRONMENT) console.log(ROUTE_CODE, 'ENTERING');
34
- const methodResponse = await methodHandlerErrorThrower(e, METHOD, ROUTE_CODE);
31
+ const methodResponse = await methodHandlerErrorThrower(event, API, METHOD, ROUTE_CODE);
35
32
  return methodResponse;
36
33
  } catch (METHOD_ERROR) {
37
34
  const methodErrorResponse = methodErrorHandler(METHOD_ERROR, METHOD, ROUTE_CODE);
@@ -1,31 +1,35 @@
1
1
  import url from 'url'
2
2
 
3
3
  import { getProjectRoot } from '../pathHandler/index.js';
4
- import { registerModel } from '../databaseHandler/index.js';
4
+ import { registerModel } from '../registerDatabaseService/index.js';
5
5
  import { methodHandler } from './methodHandler.js';
6
6
  import { getMethodType } from './getMethodType.js';
7
7
  import { getMethodRouteCode } from './getMethodRouteCode.js';
8
8
  import { registerMethods } from './registerMethods.js';
9
9
 
10
- const serviceHandler = async (API, SERVICE_NAME, SRC_FOLDER, MODULE_FOLDER) => {
10
+ const registerService = async (API, SERVICE_NAME, SRC_FOLDER, MODULE_FOLDER) => {
11
11
  try {
12
12
  const PROJECT_ROOT_PATH = getProjectRoot(import.meta.url, MODULE_FOLDER)+'/';
13
13
  const PROJECT_RELATIVE_SERVICE_PATH = './' + SRC_FOLDER + `${SERVICE_NAME}/`;
14
14
  const SERVICE_URL = new URL(PROJECT_RELATIVE_SERVICE_PATH, PROJECT_ROOT_PATH);
15
- const SERVICE_MODULE = await import(`${SERVICE_URL}index.js`);
16
15
 
17
- //if (SERVICE_MODULE.modelSchema) registerModel(SERVICE_NAME, SERVICE_MODULE.modelSchema);
16
+ const SERVICE_MODULE = await import(`${SERVICE_URL}index.js`);
18
17
  if (SERVICE_MODULE.model) registerModel(SERVICE_NAME, SERVICE_URL);
19
18
  const SERVICE_METHODS = await registerMethods(SERVICE_MODULE.methods)(SERVICE_URL);
20
19
 
20
+ API.SERVICES[SERVICE_NAME] = {};
21
21
  Object.keys(SERVICE_METHODS).forEach(METHOD_NAME => {
22
- const methodType = getMethodType(METHOD_NAME);
23
- API[methodType](`/${SERVICE_NAME}/${METHOD_NAME}`, async (req, res) => {
22
+
23
+ API.SERVICES[SERVICE_NAME][METHOD_NAME] = async (req, res) => {
24
24
  const ROUTE_CODE = getMethodRouteCode(SERVICE_NAME, METHOD_NAME);
25
25
  const { statusCode, body } =
26
- await methodHandler(SERVICE_METHODS[METHOD_NAME], ROUTE_CODE, req);
26
+ await methodHandler(API, SERVICE_METHODS[METHOD_NAME], ROUTE_CODE, req);
27
27
  res.status(statusCode).json(body);
28
- });
28
+ }
29
+
30
+ const methodType = getMethodType(METHOD_NAME);
31
+ API[methodType](`/${SERVICE_NAME}/${METHOD_NAME}`,
32
+ API.SERVICES[SERVICE_NAME][METHOD_NAME]);
29
33
  });
30
34
  } catch (SERVICE_HANDLER_ERROR) {
31
35
  console.error({
@@ -36,4 +40,4 @@ const serviceHandler = async (API, SERVICE_NAME, SRC_FOLDER, MODULE_FOLDER) => {
36
40
  }
37
41
  }
38
42
 
39
- export { serviceHandler };
43
+ export { registerService };
@@ -1,86 +0,0 @@
1
- import Sequelize from 'sequelize';
2
- //import SequelizeDynamo from 'dynamo-sequelize';
3
- import { loadModels } from './modelsHandler.js';
4
-
5
- const dialect = 'mysql';
6
- const logging = false;
7
- const dialectOptions = null;
8
- const ROUTE_CODE = 'DB_CONNECTION';
9
- let sequelize = null;
10
- let MODELS = null;
11
-
12
- const tryAuthenticating = async (connectionRetries) => {
13
- if (!process.env.TEST_ENVIRONMENT)
14
- console.log(ROUTE_CODE, 'Authenticating sequelize intent:', connectionRetries);
15
- await sequelize.authenticate();
16
- };
17
-
18
- const createSequelizeInstance = () => {
19
- if (process.env.TEST_ENVIRONMENT) {
20
- sequelize = new Sequelize('sqlite::memory:');
21
- sequelize.options.logging = false;
22
- } else {
23
- const db=process.env.DB_DB, user=process.env.DB_USER,
24
- pass=process.env.DB_PASS, host=process.env.DB_ENDPOINT;
25
- console.log(ROUTE_CODE,
26
- 'Trying to connect using { ' + user + ', ' + pass + ', ' + host + ', ' + db + ' }');
27
- sequelize = new Sequelize(db, user, pass, { host, dialect, dialectOptions, logging });
28
- }
29
- };
30
-
31
-
32
- const establishConnection = async () => {
33
- const MAX_RETRIES = 5;
34
- const INITIAL_WAIT_TIME_MS = 100;
35
- let connectionRetries = 0;
36
- let waitTime = INITIAL_WAIT_TIME_MS;
37
-
38
- while (connectionRetries < MAX_RETRIES) {
39
- try {
40
- if (!sequelize) createSequelizeInstance();
41
- await tryAuthenticating(connectionRetries);
42
- break;
43
- } catch (databaseConnectionError) {
44
- await new Promise(resolve => setTimeout(resolve, waitTime));
45
- waitTime *= 2; connectionRetries += 1;
46
- createSequelizeInstance();
47
- }
48
- }
49
-
50
- return sequelize;
51
- };
52
-
53
-
54
- const loadAndSyncModels = async () => {
55
- if (!process.env.TEST_ENVIRONMENT)
56
- console.log(ROUTE_CODE, 'Loading sequelize models');
57
- MODELS = loadModels(sequelize, Sequelize);
58
-
59
- if (!process.env.TEST_ENVIRONMENT)
60
- console.log(ROUTE_CODE, 'Syncing sequelize');
61
- await sequelize.sync({ alter: process.env.LOCAL ? true : false });
62
- };
63
-
64
- const databaseHandler = async () => {
65
- try {
66
- await establishConnection();
67
- await loadAndSyncModels();
68
- return { MODELS };
69
- } catch (DB_ERROR) {
70
- console.error({
71
- ROUTE_CODE,
72
- DB_ERROR
73
- });
74
-
75
- const databaseErrorResponse = {
76
- statusCode: 500,
77
- body: {
78
- ROUTE_CODE,
79
- error: DB_ERROR.toString(),
80
- },
81
- };
82
- return { databaseErrorResponse };
83
- }
84
- };
85
-
86
- export { databaseHandler };
@@ -1,4 +0,0 @@
1
- import { databaseHandler } from './databaseHandler.js';
2
- import { registerModel } from './modelsHandler.js';
3
-
4
- export { databaseHandler, registerModel };
@@ -1,3 +0,0 @@
1
- import { healthHandler } from './healthHandler.js';
2
-
3
- export { healthHandler };
@@ -1,4 +0,0 @@
1
- import { serviceHandler } from './serviceHandler.js';
2
-
3
- export { serviceHandler };
4
-
@@ -1,8 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- const VALIDATOR = (MODELS, ROUTE_CODE) =>
4
- z.object({
5
- id: z.number(),
6
- }).strict();
7
-
8
- export { VALIDATOR };
@@ -1,6 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- const VALIDATOR = (MODELS, ROUTE_CODE) =>
4
- z.undefined();
5
-
6
- export { VALIDATOR };
package/todoList/index.js DELETED
@@ -1,2 +0,0 @@
1
- export const model = true;
2
- export const methods = ['get', 'post', 'delete'];
package/todoList/model.js DELETED
@@ -1,17 +0,0 @@
1
- export const modelSchema = serviceName => (sequelize, type) => {
2
- const schema = sequelize.define(serviceName, {
3
- name: {
4
- type: type.STRING,
5
- allowNull: false
6
- },
7
- });
8
-
9
- schema.associate = MODELS => {
10
- schema.hasMany(MODELS.todo, {
11
- foreignKey: 'todoListId',
12
- as: 'todoElements',
13
- });
14
- };
15
-
16
- return schema;
17
- };
@@ -1,8 +0,0 @@
1
- import { z } from 'zod';
2
-
3
- const VALIDATOR = (MODELS, ROUTE_CODE) =>
4
- z.object({
5
- name: z.string(),
6
- }).strict();
7
-
8
- export { VALIDATOR };
File without changes
File without changes