@ruiapp/rapid-core 0.1.20 → 0.1.21

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 (38) hide show
  1. package/dist/core/actionHandler.d.ts +2 -0
  2. package/dist/core/request.d.ts +2 -1
  3. package/dist/core/routeContext.d.ts +3 -1
  4. package/dist/core/server.d.ts +2 -0
  5. package/dist/dataAccess/dataAccessor.d.ts +2 -1
  6. package/dist/facilities/log/LogFacility.d.ts +33 -0
  7. package/dist/index.js +99 -171
  8. package/dist/plugins/auth/AuthPlugin.d.ts +0 -9
  9. package/dist/plugins/dataManage/DataManagePlugin.d.ts +0 -10
  10. package/dist/plugins/metaManage/MetaManagePlugin.d.ts +0 -8
  11. package/dist/plugins/routeManage/RouteManagePlugin.d.ts +0 -9
  12. package/dist/plugins/webhooks/WebhooksPlugin.d.ts +0 -6
  13. package/dist/server.d.ts +4 -1
  14. package/package.json +4 -1
  15. package/src/core/actionHandler.ts +2 -0
  16. package/src/core/request.ts +6 -2
  17. package/src/core/routeContext.ts +5 -1
  18. package/src/core/routesBuilder.ts +7 -2
  19. package/src/core/server.ts +2 -0
  20. package/src/dataAccess/dataAccessor.ts +6 -2
  21. package/src/facilities/log/LogFacility.ts +36 -0
  22. package/src/helpers/runCollectionEntityActionHandler.ts +3 -7
  23. package/src/plugins/auth/AuthPlugin.ts +3 -30
  24. package/src/plugins/dataManage/DataManagePlugin.ts +0 -31
  25. package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +3 -7
  26. package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +3 -7
  27. package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +3 -7
  28. package/src/plugins/dataManage/actionHandlers/deleteCollectionEntityById.ts +2 -2
  29. package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +2 -2
  30. package/src/plugins/dataManage/actionHandlers/queryDatabase.ts +3 -7
  31. package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +2 -6
  32. package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +3 -8
  33. package/src/plugins/entityAccessControl/EntityAccessControlPlugin.ts +3 -0
  34. package/src/plugins/metaManage/MetaManagePlugin.ts +10 -33
  35. package/src/plugins/routeManage/RouteManagePlugin.ts +4 -30
  36. package/src/plugins/routeManage/actionHandlers/httpProxy.ts +2 -1
  37. package/src/plugins/webhooks/WebhooksPlugin.ts +24 -34
  38. package/src/server.ts +22 -8
@@ -42,12 +42,6 @@ class MetaManager implements RapidPlugin {
42
42
  return [];
43
43
  }
44
44
 
45
- async initPlugin(server: IRpdServer): Promise<any> {
46
- }
47
-
48
- async registerMiddlewares(server: IRpdServer): Promise<any> {
49
- }
50
-
51
45
  async registerActionHandlers(server: IRpdServer): Promise<any> {
52
46
  server.registerActionHandler(this, listMetaModels);
53
47
  server.registerActionHandler(this, listMetaRoutes);
@@ -69,37 +63,20 @@ class MetaManager implements RapidPlugin {
69
63
  );
70
64
  }
71
65
 
72
- async registerMessageHandlers(server: IRpdServer): Promise<any> {
73
- }
74
-
75
- async registerTaskProcessors(server: IRpdServer): Promise<any> {
76
- }
77
-
78
- async onLoadingApplication(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
79
- }
80
-
81
66
  async configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
67
+ const logger = server.getLogger();
82
68
  try {
69
+ logger.info("Loading meta of models...");
83
70
  const models: RpdDataModel[] = await listCollections(server, applicationConfig);
84
71
  server.appendApplicationConfig({ models });
85
- } catch (ex) {
86
- console.warn("Failed to loading existing meta of models.", ex);
72
+ } catch (error) {
73
+ logger.crit("Failed to load meta of models.", { error });
87
74
  }
88
75
  }
89
76
 
90
- async configureModelProperties(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
91
- }
92
-
93
- async configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
94
- }
95
-
96
77
  async onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
97
- console.log("metaManager.onApplicationLoaded");
98
78
  await syncDatabaseSchema(server, applicationConfig);
99
79
  }
100
-
101
- async onApplicationReady(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
102
- }
103
80
  }
104
81
 
105
82
  export default MetaManager;
@@ -236,13 +213,14 @@ async function syncDatabaseSchema(
236
213
  server: IRpdServer,
237
214
  applicationConfig: RpdApplicationConfig,
238
215
  ) {
239
- console.log("Synchronizing database schema...");
216
+ const logger = server.getLogger();
217
+ logger.info("Synchronizing database schema...");
240
218
  const sqlQueryTableInformations = `SELECT table_schema, table_name FROM information_schema.tables`;
241
219
  const tablesInDb: TableInformation[] = await server.queryDatabaseObject(sqlQueryTableInformations);
242
220
  const { queryBuilder } = server;
243
221
 
244
222
  for (const model of applicationConfig.models) {
245
- console.debug(`Checking data table for '${model.namespace}.${model.singularCode}'...`);
223
+ logger.debug(`Checking data table for '${model.namespace}.${model.singularCode}'...`);
246
224
 
247
225
  const expectedTableSchema = model.schema || server.databaseConfig.dbDefaultSchema;
248
226
  const expectedTableName = model.tableName;
@@ -257,7 +235,7 @@ async function syncDatabaseSchema(
257
235
  const columnsInDb: ColumnInformation[] = await server.queryDatabaseObject(sqlQueryColumnInformations, []);
258
236
 
259
237
  for (const model of applicationConfig.models) {
260
- console.debug(`Checking data columns for '${model.namespace}.${model.singularCode}'...`);
238
+ logger.debug(`Checking data columns for '${model.namespace}.${model.singularCode}'...`);
261
239
 
262
240
  for (const property of model.properties) {
263
241
  let columnDDL;
@@ -265,7 +243,7 @@ async function syncDatabaseSchema(
265
243
  if (property.relation === "one") {
266
244
  const targetModel = applicationConfig.models.find(item => item.singularCode === property.targetSingularCode);
267
245
  if (!targetModel) {
268
- console.warn(`Cannot find target model with singular code "${property.targetSingularCode}".`)
246
+ logger.warn(`Cannot find target model with singular code "${property.targetSingularCode}".`)
269
247
  }
270
248
 
271
249
  const columnInDb: ColumnInformation | undefined = find(columnsInDb, {
@@ -298,7 +276,7 @@ async function syncDatabaseSchema(
298
276
  } else {
299
277
  const targetModel = applicationConfig.models.find(item => item.singularCode === property.targetSingularCode);
300
278
  if (!targetModel) {
301
- console.warn(`Cannot find target model with singular code "${property.targetSingularCode}".`)
279
+ logger.warn(`Cannot find target model with singular code "${property.targetSingularCode}".`)
302
280
  continue;
303
281
  }
304
282
 
@@ -398,7 +376,6 @@ function generateCreateColumnDDL(queryBuilder: IQueryBuilder, options: {
398
376
  } else {
399
377
  const columnType = pgPropertyTypeColumnMap[options.type];
400
378
  if (!columnType) {
401
- console.log('options', options);
402
379
  throw new Error(`Property type "${options.type}" is not supported.`);
403
380
  }
404
381
  columnDDL += ` ${columnType}`;
@@ -30,12 +30,6 @@ class RouteManager implements RapidPlugin {
30
30
  return [];
31
31
  }
32
32
 
33
- async initPlugin(server: IRpdServer): Promise<any> {
34
- }
35
-
36
- async registerMiddlewares(server: IRpdServer): Promise<any> {
37
- }
38
-
39
33
  async registerActionHandlers(server: IRpdServer): Promise<any> {
40
34
  server.registerActionHandler(this, httpProxy);
41
35
  }
@@ -47,23 +41,10 @@ class RouteManager implements RapidPlugin {
47
41
  // server.registerEventHandler("entity.delete", handleEntityEvent.bind(null, server))
48
42
  }
49
43
 
50
- async registerMessageHandlers(server: IRpdServer): Promise<any> {
51
- }
52
-
53
- async registerTaskProcessors(server: IRpdServer): Promise<any> {
54
- }
55
-
56
- async onLoadingApplication(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
57
- }
58
-
59
- async configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
60
- }
61
-
62
- async configureModelProperties(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
63
- }
64
-
65
44
  async configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
45
+ const logger = server.getLogger();
66
46
  try {
47
+ logger.info("Loading meta of routes...");
67
48
  const entityManager = server.getEntityManager("route");
68
49
  const routes = await entityManager.findEntities({
69
50
  orderBy: [
@@ -71,17 +52,10 @@ class RouteManager implements RapidPlugin {
71
52
  ],
72
53
  });
73
54
  applicationConfig.routes.push(...routes);
74
- } catch (ex) {
75
- console.warn("Failed to loading existing meta of routes.", ex.message);
55
+ } catch (error) {
56
+ logger.crit("Failed to load meta of routes.", { error });
76
57
  }
77
58
  }
78
-
79
- async onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
80
- console.log("[routeManager.onApplicationLoaded] onApplicationLoaded");
81
- }
82
-
83
- async onApplicationReady(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
84
- }
85
59
  }
86
60
 
87
61
  export default RouteManager;
@@ -10,7 +10,8 @@ export async function handler(
10
10
  ctx: ActionHandlerContext,
11
11
  options: RunProxyHandlerOptions,
12
12
  ) {
13
- console.debug(`Running ${code} handler...`);
13
+ const { logger } = ctx;
14
+ logger.debug(`Running ${code} handler...`);
14
15
 
15
16
  await doProxy(ctx.routerContext, options);
16
17
  }
@@ -30,16 +30,23 @@ export interface Webhook {
30
30
  function listWebhooks(
31
31
  server: IRpdServer,
32
32
  ) {
33
- const entityManager = server.getEntityManager("webhook");
34
- return entityManager.findEntities({
35
- filters: [
36
- {
37
- field: "enabled",
38
- operator: "eq",
39
- value: true,
40
- },
41
- ],
42
- });
33
+ const logger = server.getLogger();
34
+ logger.info("Loading meta of webhooks...");
35
+
36
+ try {
37
+ const entityManager = server.getEntityManager("webhook");
38
+ return entityManager.findEntities({
39
+ filters: [
40
+ {
41
+ field: "enabled",
42
+ operator: "eq",
43
+ value: true,
44
+ },
45
+ ],
46
+ });
47
+ } catch (error) {
48
+ logger.crit("Failed to load meta of webhooks.", { error });
49
+ }
43
50
  }
44
51
 
45
52
 
@@ -70,15 +77,6 @@ class WebhooksPlugin implements RapidPlugin {
70
77
  return [];
71
78
  }
72
79
 
73
- async initPlugin(server: IRpdServer): Promise<any> {
74
- }
75
-
76
- async registerMiddlewares(server: IRpdServer): Promise<any> {
77
- }
78
-
79
- async registerActionHandlers(server: IRpdServer): Promise<any> {
80
- }
81
-
82
80
  async registerEventHandlers(server: IRpdServer): Promise<any> {
83
81
  const events: (keyof RpdServerEventTypes)[] = [
84
82
  "entity.create",
@@ -93,15 +91,6 @@ class WebhooksPlugin implements RapidPlugin {
93
91
  }
94
92
  }
95
93
 
96
- async registerMessageHandlers(server: IRpdServer): Promise<any> {
97
- }
98
-
99
- async registerTaskProcessors(server: IRpdServer): Promise<any> {
100
- }
101
-
102
- async onLoadingApplication(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
103
- }
104
-
105
94
  async configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
106
95
  server.appendApplicationConfig({
107
96
  models: pluginConfig.models,
@@ -115,7 +104,6 @@ class WebhooksPlugin implements RapidPlugin {
115
104
  }
116
105
 
117
106
  async onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any> {
118
- console.log("[webhooks.onApplicationLoaded] loading webhooks");
119
107
  this.#webhooks = await listWebhooks(server);
120
108
  }
121
109
 
@@ -145,6 +133,8 @@ class WebhooksPlugin implements RapidPlugin {
145
133
  return;
146
134
  }
147
135
 
136
+ const logger = server.getLogger();
137
+
148
138
  for (const webhook of this.#webhooks) {
149
139
  if (indexOf(webhook.events, event) === -1) {
150
140
  continue;
@@ -157,8 +147,9 @@ class WebhooksPlugin implements RapidPlugin {
157
147
  continue;
158
148
  }
159
149
 
160
- console.debug(`Triggering webhook. ${webhook.url}`);
150
+ logger.debug(`Triggering webhook. ${webhook.url}`);
161
151
  // TODO: It's better to trigger webhook through message queue.
152
+ const requestBody = { event, payload };
162
153
  try {
163
154
  await fetchWithTimeout(webhook.url, {
164
155
  method: "post",
@@ -166,11 +157,10 @@ class WebhooksPlugin implements RapidPlugin {
166
157
  "Content-Type": "application/json",
167
158
  "x-webhook-secret": webhook.secret || "",
168
159
  },
169
- body: JSON.stringify({ event, payload }),
160
+ body: JSON.stringify(requestBody),
170
161
  });
171
- } catch (err) {
172
- console.warn(new Error("Failed to call webhook. " + err.message));
173
- console.warn(err);
162
+ } catch (error) {
163
+ logger.error("Failed to call webhook.", { error, webhookUrl: webhook.url, requestBody });
174
164
  }
175
165
  }
176
166
  }
package/src/server.ts CHANGED
@@ -24,8 +24,10 @@ import { RapidRequest } from "./core/request";
24
24
  import bootstrapApplicationConfig from "./bootstrapApplicationConfig";
25
25
  import EntityManager from "./dataAccess/entityManager";
26
26
  import { bind, cloneDeep, find, merge, omit } from "lodash";
27
+ import { Logger } from "./facilities/log/LogFacility";
27
28
 
28
29
  export interface InitServerOptions {
30
+ logger: Logger;
29
31
  databaseAccessor: IDatabaseAccessor;
30
32
  databaseConfig: IDatabaseConfig;
31
33
  serverConfig: RapidServerConfig;
@@ -34,6 +36,7 @@ export interface InitServerOptions {
34
36
  }
35
37
 
36
38
  export class RapidServer implements IRpdServer {
39
+ #logger: Logger;
37
40
  #pluginManager: PluginManager;
38
41
  #plugins: RapidPlugin[];
39
42
  #eventManager: EventManager<RpdServerEventTypes>;
@@ -50,6 +53,8 @@ export class RapidServer implements IRpdServer {
50
53
  #buildedRoutes: (ctx: any, next: any) => any;
51
54
 
52
55
  constructor(options: InitServerOptions) {
56
+ this.#logger = options.logger;
57
+
53
58
  this.#pluginManager = new PluginManager(this);
54
59
  this.#eventManager = new EventManager();
55
60
  this.#middlewares = [];
@@ -70,6 +75,10 @@ export class RapidServer implements IRpdServer {
70
75
  this.#plugins = options.plugins || [];
71
76
  }
72
77
 
78
+ getLogger(): Logger {
79
+ return this.#logger;
80
+ }
81
+
73
82
  getApplicationConfig() {
74
83
  return this.#applicationConfig;
75
84
  }
@@ -158,7 +167,7 @@ export class RapidServer implements IRpdServer {
158
167
  throw new Error(`Data model ${namespace}.${singularCode} not found.`);
159
168
  }
160
169
 
161
- dataAccessor = new DataAccessor<T>(this.#databaseAccessor, {
170
+ dataAccessor = new DataAccessor<T>(this, this.#databaseAccessor, {
162
171
  model,
163
172
  queryBuilder: this.queryBuilder as QueryBuilder,
164
173
  });
@@ -199,7 +208,7 @@ export class RapidServer implements IRpdServer {
199
208
  sender: RapidPlugin,
200
209
  payload: RpdServerEventTypes[K][1],
201
210
  ) {
202
- console.log(`Emit event "${eventName}"`, payload);
211
+ this.#logger.debug(`Emitting '${eventName}' event.`, { eventName, payload });
203
212
  await this.#eventManager.emit<K>(eventName, sender, payload as any);
204
213
 
205
214
  // TODO: should move this logic into metaManager
@@ -213,7 +222,7 @@ export class RapidServer implements IRpdServer {
213
222
  }
214
223
 
215
224
  async start() {
216
- console.log("Starting rapid server...");
225
+ this.#logger.info("Starting rapid server...");
217
226
  const pluginManager = this.#pluginManager;
218
227
  await pluginManager.loadPlugins(this.#plugins);
219
228
 
@@ -227,7 +236,7 @@ export class RapidServer implements IRpdServer {
227
236
 
228
237
  await this.configureApplication();
229
238
 
230
- console.log(`Application ready.`);
239
+ this.#logger.info(`Rapid server ready.`);
231
240
  await pluginManager.onApplicationReady(this.#applicationConfig);
232
241
  }
233
242
 
@@ -250,14 +259,19 @@ export class RapidServer implements IRpdServer {
250
259
  }
251
260
 
252
261
  async queryDatabaseObject(sql: string, params?: unknown[] | Record<string,unknown>) : Promise<any[]> {
253
- return await this.#databaseAccessor.queryDatabaseObject(sql, params);
262
+ try {
263
+ return await this.#databaseAccessor.queryDatabaseObject(sql, params);
264
+ } catch (err) {
265
+ this.#logger.error("Failed to query database object.", { errorMessage: err.message, sql, params });
266
+ throw err;
267
+ }
254
268
  }
255
269
 
256
270
  async tryQueryDatabaseObject(sql: string, params?: unknown[] | Record<string,unknown>) : Promise<any[]> {
257
271
  try {
258
272
  return await this.queryDatabaseObject(sql, params);
259
273
  } catch (err) {
260
- console.error(err.message);
274
+ this.#logger.error("Failed to query database object.", { errorMessage: err.message, sql, params });
261
275
  }
262
276
 
263
277
  return [];
@@ -268,9 +282,9 @@ export class RapidServer implements IRpdServer {
268
282
  }
269
283
 
270
284
  async handleRequest(request: Request, next: Next) {
271
- const rapidRequest = new RapidRequest(request);
285
+ const rapidRequest = new RapidRequest(this, request);
272
286
  await rapidRequest.parseBody();
273
- const routeContext = new RouteContext(rapidRequest);
287
+ const routeContext = new RouteContext(this, rapidRequest);
274
288
  await this.#pluginManager.onPrepareRouteContext(routeContext);
275
289
 
276
290
  await this.#buildedRoutes(routeContext, next);