@ruiapp/rapid-core 0.1.41 → 0.1.43

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 (126) hide show
  1. package/dist/dataAccess/dataAccessTypes.d.ts +63 -0
  2. package/dist/dataAccess/dataAccessor.d.ts +5 -4
  3. package/dist/dataAccess/entityMapper.d.ts +7 -2
  4. package/dist/dataAccess/metaHelper.d.ts +6 -0
  5. package/dist/index.js +576 -324
  6. package/dist/plugins/sequence/SequencePluginTypes.d.ts +1 -0
  7. package/dist/queryBuilder/queryBuilder.d.ts +12 -22
  8. package/dist/types.d.ts +34 -5
  9. package/dist/utilities/errorUtility.d.ts +3 -0
  10. package/package.json +1 -1
  11. package/rollup.config.js +13 -17
  12. package/src/bootstrapApplicationConfig.ts +25 -4
  13. package/src/core/actionHandler.ts +2 -5
  14. package/src/core/eventManager.ts +1 -4
  15. package/src/core/facility.ts +1 -1
  16. package/src/core/http/formDataParser.ts +31 -43
  17. package/src/core/pluginManager.ts +13 -39
  18. package/src/core/providers/runtimeProvider.ts +1 -1
  19. package/src/core/request.ts +3 -3
  20. package/src/core/response.ts +2 -7
  21. package/src/core/routeContext.ts +2 -6
  22. package/src/core/routesBuilder.ts +46 -55
  23. package/src/core/server.ts +8 -34
  24. package/src/dataAccess/dataAccessTypes.ts +86 -0
  25. package/src/dataAccess/dataAccessor.ts +46 -24
  26. package/src/dataAccess/entityManager.ts +294 -245
  27. package/src/dataAccess/entityMapper.ts +32 -15
  28. package/src/dataAccess/filterHelper.ts +1 -3
  29. package/src/dataAccess/metaHelper.ts +45 -0
  30. package/src/dataAccess/propertyMapper.ts +3 -3
  31. package/src/deno-std/datetime/to_imf.ts +2 -17
  32. package/src/deno-std/encoding/base64.ts +1 -5
  33. package/src/deno-std/http/cookie.ts +26 -59
  34. package/src/facilities/log/LogFacility.ts +0 -1
  35. package/src/helpers/entityHelpers.ts +1 -4
  36. package/src/helpers/runCollectionEntityActionHandler.ts +2 -10
  37. package/src/plugins/auth/AuthPlugin.ts +2 -5
  38. package/src/plugins/auth/actionHandlers/changePassword.ts +6 -10
  39. package/src/plugins/auth/actionHandlers/createSession.ts +14 -15
  40. package/src/plugins/auth/actionHandlers/deleteSession.ts +1 -5
  41. package/src/plugins/auth/actionHandlers/getMyProfile.ts +5 -9
  42. package/src/plugins/auth/actionHandlers/index.ts +1 -7
  43. package/src/plugins/auth/actionHandlers/resetPassword.ts +3 -7
  44. package/src/plugins/auth/models/AccessToken.ts +2 -2
  45. package/src/plugins/auth/models/index.ts +1 -3
  46. package/src/plugins/auth/routes/changePassword.ts +1 -1
  47. package/src/plugins/auth/routes/getMyProfile.ts +1 -1
  48. package/src/plugins/auth/routes/index.ts +1 -7
  49. package/src/plugins/auth/routes/resetPassword.ts +1 -1
  50. package/src/plugins/auth/routes/signin.ts +1 -1
  51. package/src/plugins/auth/routes/signout.ts +1 -1
  52. package/src/plugins/cronJob/CronJobPlugin.ts +12 -21
  53. package/src/plugins/cronJob/CronJobPluginTypes.ts +9 -9
  54. package/src/plugins/cronJob/actionHandlers/index.ts +1 -3
  55. package/src/plugins/cronJob/actionHandlers/runCronJob.ts +3 -8
  56. package/src/plugins/cronJob/routes/index.ts +1 -3
  57. package/src/plugins/cronJob/routes/runCronJob.ts +1 -1
  58. package/src/plugins/dataManage/DataManagePlugin.ts +5 -11
  59. package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +1 -5
  60. package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +5 -14
  61. package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +8 -9
  62. package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +7 -8
  63. package/src/plugins/dataManage/actionHandlers/deleteCollectionEntityById.ts +1 -5
  64. package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +15 -24
  65. package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +1 -5
  66. package/src/plugins/dataManage/actionHandlers/queryDatabase.ts +1 -5
  67. package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +1 -5
  68. package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +1 -5
  69. package/src/plugins/entityAccessControl/EntityAccessControlPlugin.ts +5 -6
  70. package/src/plugins/entityWatch/EntityWatchPlugin.ts +18 -17
  71. package/src/plugins/entityWatch/EntityWatchPluginTypes.ts +3 -10
  72. package/src/plugins/fileManage/FileManagePlugin.ts +1 -3
  73. package/src/plugins/fileManage/actionHandlers/downloadDocument.ts +2 -6
  74. package/src/plugins/fileManage/actionHandlers/downloadFile.ts +2 -6
  75. package/src/plugins/fileManage/actionHandlers/uploadFile.ts +3 -7
  76. package/src/plugins/fileManage/routes/downloadDocument.ts +1 -1
  77. package/src/plugins/fileManage/routes/downloadFile.ts +1 -1
  78. package/src/plugins/fileManage/routes/index.ts +1 -5
  79. package/src/plugins/fileManage/routes/uploadFile.ts +1 -1
  80. package/src/plugins/metaManage/MetaManagePlugin.ts +45 -92
  81. package/src/plugins/metaManage/actionHandlers/getMetaModelDetail.ts +1 -5
  82. package/src/plugins/metaManage/actionHandlers/listMetaModels.ts +1 -5
  83. package/src/plugins/metaManage/actionHandlers/listMetaRoutes.ts +1 -5
  84. package/src/plugins/routeManage/RouteManagePlugin.ts +2 -7
  85. package/src/plugins/routeManage/actionHandlers/httpProxy.ts +1 -5
  86. package/src/plugins/sequence/SequencePlugin.ts +14 -16
  87. package/src/plugins/sequence/SequencePluginTypes.ts +20 -29
  88. package/src/plugins/sequence/SequenceService.ts +16 -15
  89. package/src/plugins/sequence/actionHandlers/generateSn.ts +2 -7
  90. package/src/plugins/sequence/actionHandlers/index.ts +1 -3
  91. package/src/plugins/sequence/models/SequenceAutoIncrementRecord.ts +2 -2
  92. package/src/plugins/sequence/models/SequenceRule.ts +2 -2
  93. package/src/plugins/sequence/models/index.ts +1 -4
  94. package/src/plugins/sequence/routes/generateSn.ts +1 -1
  95. package/src/plugins/sequence/routes/index.ts +1 -3
  96. package/src/plugins/sequence/segment-utility.ts +1 -1
  97. package/src/plugins/sequence/segments/autoIncrement.ts +4 -8
  98. package/src/plugins/sequence/segments/dayOfMonth.ts +3 -7
  99. package/src/plugins/sequence/segments/index.ts +1 -8
  100. package/src/plugins/sequence/segments/literal.ts +1 -1
  101. package/src/plugins/sequence/segments/month.ts +3 -7
  102. package/src/plugins/sequence/segments/parameter.ts +3 -7
  103. package/src/plugins/sequence/segments/year.ts +3 -7
  104. package/src/plugins/serverOperation/ServerOperationPlugin.ts +12 -22
  105. package/src/plugins/serverOperation/ServerOperationPluginTypes.ts +1 -1
  106. package/src/plugins/serverOperation/actionHandlers/index.ts +1 -3
  107. package/src/plugins/stateMachine/StateMachinePlugin.ts +19 -22
  108. package/src/plugins/stateMachine/StateMachinePluginTypes.ts +6 -7
  109. package/src/plugins/stateMachine/actionHandlers/index.ts +1 -3
  110. package/src/plugins/stateMachine/actionHandlers/sendStateMachineEvent.ts +3 -7
  111. package/src/plugins/stateMachine/models/StateMachine.ts +2 -2
  112. package/src/plugins/stateMachine/models/index.ts +1 -3
  113. package/src/plugins/stateMachine/routes/index.ts +1 -3
  114. package/src/plugins/stateMachine/routes/sendStateMachineEvent.ts +1 -1
  115. package/src/plugins/webhooks/WebhooksPlugin.ts +9 -41
  116. package/src/polyfill.ts +1 -1
  117. package/src/proxy/mod.ts +4 -13
  118. package/src/queryBuilder/queryBuilder.ts +149 -106
  119. package/src/server.ts +19 -44
  120. package/src/types.ts +54 -79
  121. package/src/utilities/accessControlUtility.ts +4 -4
  122. package/src/utilities/errorUtility.ts +17 -0
  123. package/src/utilities/fsUtility.ts +12 -13
  124. package/src/utilities/httpUtility.ts +1 -5
  125. package/src/utilities/jwtUtility.ts +6 -10
  126. package/tsconfig.json +1 -1
@@ -7,16 +7,13 @@ import { isNullOrUndefined } from "~/utilities/typeUtility";
7
7
  import { Next, RouteContext } from "./routeContext";
8
8
  import { cloneDeep } from "lodash";
9
9
 
10
- export async function buildRoutes(
11
- server: IRpdServer,
12
- applicationConfig: RpdApplicationConfig,
13
- ) {
10
+ export async function buildRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig) {
14
11
  const logger = server.getLogger();
15
12
  const router = new Router();
16
13
 
17
14
  let baseUrl = server.config.baseUrl;
18
15
  if (baseUrl) {
19
- if (baseUrl.endsWith('/')) {
16
+ if (baseUrl.endsWith("/")) {
20
17
  baseUrl = baseUrl.substring(0, baseUrl.length - 1);
21
18
  }
22
19
  } else {
@@ -30,67 +27,61 @@ export async function buildRoutes(
30
27
 
31
28
  const routePath = baseUrl + routeConfig.endpoint;
32
29
 
33
- (router as any)[routeConfig.method.toLowerCase()](
34
- routePath,
35
- async (routerContext: RouteContext, next: Next) => {
36
- routerContext.routeConfig = cloneDeep(routeConfig);
37
- const { request, params } = routerContext;
30
+ (router as any)[routeConfig.method.toLowerCase()](routePath, async (routerContext: RouteContext, next: Next) => {
31
+ routerContext.routeConfig = cloneDeep(routeConfig);
32
+ const { request, params } = routerContext;
38
33
 
39
- let search = request.url.search;
40
- if (search && search.startsWith("?")) {
41
- search = search.substring(1);
42
- }
43
- const query = qs.parse(search);
44
- const input = Object.assign({}, params, query);
34
+ let search = request.url.search;
35
+ if (search && search.startsWith("?")) {
36
+ search = search.substring(1);
37
+ }
38
+ const query = qs.parse(search);
39
+ const input = Object.assign({}, params, query);
45
40
 
46
- const requestMethod = request.method;
47
- if (
48
- (requestMethod === "POST" || requestMethod === "PUT" ||
49
- requestMethod === "PATCH")
50
- ) {
51
- const body = request.body;
52
- if (body) {
53
- Object.assign(input, body.value);
54
- }
41
+ const requestMethod = request.method;
42
+ if (requestMethod === "POST" || requestMethod === "PUT" || requestMethod === "PATCH") {
43
+ const body = request.body;
44
+ if (body) {
45
+ Object.assign(input, body.value);
55
46
  }
47
+ }
56
48
 
57
- // Normalize input value
58
-
59
- logger.debug("Processing rapid request.", {
60
- method: requestMethod,
61
- url: request.url.toString(),
62
- input
63
- });
49
+ // Normalize input value
64
50
 
65
- let handlerContext: ActionHandlerContext = {
66
- logger,
67
- routerContext,
68
- next,
69
- server,
70
- applicationConfig,
71
- input,
72
- };
51
+ logger.debug("Processing rapid request.", {
52
+ method: requestMethod,
53
+ url: request.url.toString(),
54
+ input,
55
+ });
73
56
 
74
- await server.beforeRunRouteActions(handlerContext);
57
+ let handlerContext: ActionHandlerContext = {
58
+ logger,
59
+ routerContext,
60
+ next,
61
+ server,
62
+ applicationConfig,
63
+ input,
64
+ };
75
65
 
76
- for (const actionConfig of routeConfig.actions) {
77
- const actionCode = actionConfig.code;
78
- const handler = server.getActionHandlerByCode(actionCode);
79
- if (!handler) {
80
- throw new Error("Unknown handler: " + actionCode);
81
- }
66
+ await server.beforeRunRouteActions(handlerContext);
82
67
 
83
- const result = handler(handlerContext, actionConfig.config);
84
- if (result instanceof Promise) {
85
- await result;
86
- }
68
+ for (const actionConfig of routeConfig.actions) {
69
+ const actionCode = actionConfig.code;
70
+ const handler = server.getActionHandlerByCode(actionCode);
71
+ if (!handler) {
72
+ throw new Error("Unknown handler: " + actionCode);
87
73
  }
88
74
 
89
- if (!isNullOrUndefined(handlerContext.output)) {
90
- routerContext.json(handlerContext.output, handlerContext.status);
75
+ const result = handler(handlerContext, actionConfig.config);
76
+ if (result instanceof Promise) {
77
+ await result;
91
78
  }
92
- },
93
- );
79
+ }
80
+
81
+ if (!isNullOrUndefined(handlerContext.output)) {
82
+ routerContext.json(handlerContext.output, handlerContext.status);
83
+ }
84
+ });
94
85
  });
95
86
 
96
87
  return router.routes();
@@ -13,25 +13,14 @@ export interface IRpdServer {
13
13
 
14
14
  registerFacilityFactory(factory: FacilityFactory);
15
15
 
16
- getFacility<TFacility=any>(name: string, options?: any): Promise<TFacility>;
16
+ getFacility<TFacility = any>(name: string, options?: any): Promise<TFacility>;
17
17
 
18
- queryDatabaseObject: (
19
- sql: string,
20
- params?: unknown[] | Record<string, unknown>,
21
- ) => Promise<any[]>;
22
- tryQueryDatabaseObject: (
23
- sql: string,
24
- params?: unknown[] | Record<string, unknown>,
25
- ) => Promise<any[]>;
18
+ queryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>) => Promise<any[]>;
19
+ tryQueryDatabaseObject: (sql: string, params?: unknown[] | Record<string, unknown>) => Promise<any[]>;
26
20
  registerMiddleware(middleware: any): void;
27
- registerActionHandler(
28
- plugin: RapidPlugin,
29
- options: IPluginActionHandler,
30
- ): void;
21
+ registerActionHandler(plugin: RapidPlugin, options: IPluginActionHandler): void;
31
22
  getActionHandlerByCode(code: string): ActionHandler | undefined;
32
- getDataAccessor<T = any>(
33
- options: GetDataAccessorOptions,
34
- ): IRpdDataAccessor<T>;
23
+ getDataAccessor<T = any>(options: GetDataAccessorOptions): IRpdDataAccessor<T>;
35
24
  getEntityManager<TEntity = any>(singularCode: string): EntityManager<TEntity>;
36
25
  registerService(name: string, service: any);
37
26
  getService<TService>(name: string): TService;
@@ -39,30 +28,15 @@ export interface IRpdServer {
39
28
  appendApplicationConfig(config: Partial<RpdApplicationConfig>);
40
29
  appendModelProperties(modelSingularCode: string, properties: RpdDataModelProperty[]);
41
30
  getModel(options: GetModelOptions): RpdDataModel | undefined;
42
- registerEventHandler<K extends keyof RpdServerEventTypes>(
43
- eventName: K,
44
- listener: (...args: RpdServerEventTypes[K]) => void,
45
- ): this;
46
- emitEvent<K extends keyof RpdServerEventTypes>(
47
- eventName: K,
48
- payload: RpdServerEventTypes[K][1],
49
- sender?: RapidPlugin,
50
- ): void;
31
+ registerEventHandler<K extends keyof RpdServerEventTypes>(eventName: K, listener: (...args: RpdServerEventTypes[K]) => void): this;
32
+ emitEvent<K extends keyof RpdServerEventTypes>(eventName: K, payload: RpdServerEventTypes[K][1], sender?: RapidPlugin): void;
51
33
  handleRequest(request: Request, next: Next): Promise<Response>;
52
34
  beforeRunRouteActions(handlerContext: ActionHandlerContext): Promise<void>;
53
35
  beforeCreateEntity(model: RpdDataModel, options: CreateEntityOptions): Promise<void>;
54
36
  beforeUpdateEntity(model: RpdDataModel, options: UpdateEntityByIdOptions, currentEntity: any): Promise<void>;
55
37
  }
56
38
 
57
-
58
-
59
- export type RpdConfigurationItemTypes =
60
- | "integer"
61
- | "text"
62
- | "boolean"
63
- | "date"
64
- | "datetime"
65
- | "json";
39
+ export type RpdConfigurationItemTypes = "integer" | "text" | "boolean" | "date" | "datetime" | "json";
66
40
 
67
41
  export interface RpdConfigurationItemOptions {
68
42
  /**
@@ -0,0 +1,86 @@
1
+ export type RowFilterRelationalOperators = "eq" | "ne" | "lt" | "lte" | "gt" | "gte" | "contains" | "notContains" | "containsCS" | "notContainsCS" | "startsWith" | "notStartsWith" | "endsWith" | "notEndsWith";
2
+
3
+ export type RowFilterSetOperators = "in" | "notIn";
4
+
5
+ export type RowFilterLogicalOperators = "or" | "and";
6
+
7
+ export type RowFilterUnaryOperators = "null" | "notNull";
8
+
9
+ export type RowFilterExistenceOperators = "exists" | "notExists";
10
+
11
+ export type RowFilterOperators = RowFilterRelationalOperators | RowFilterSetOperators | RowFilterLogicalOperators | RowFilterUnaryOperators | RowFilterExistenceOperators;
12
+
13
+ export type RowFilterOptions = FindRowRelationalFilterOptions | FindRowSetFilterOptions | FindRowLogicalFilterOptions | FindRowUnaryFilterOptions | FindRowExistenceFilterOptions;
14
+
15
+ export type RowNonRelationPropertyFilterOptions = FindRowRelationalFilterOptions | FindRowSetFilterOptions | FindRowUnaryFilterOptions;
16
+
17
+ export type ColumnQueryOptions = string | ColumnNameWithTableName;
18
+
19
+ export type ColumnNameWithTableName = {
20
+ name: string;
21
+ tableName?: string;
22
+ }
23
+
24
+ export interface FindRowOptions {
25
+ filters?: RowFilterOptions[];
26
+ orderBy?: FindRowOrderByOptions[];
27
+ pagination?: FindRowPaginationOptions;
28
+ // TODO: may be `columns` is a better name.
29
+ fields?: ColumnQueryOptions[];
30
+ keepNonPropertyFields?: boolean;
31
+ }
32
+
33
+
34
+ export interface FindRowRelationalFilterOptions {
35
+ // TODO: may be `column` is a better name.
36
+ field: ColumnQueryOptions;
37
+ operator: RowFilterRelationalOperators;
38
+ value: any;
39
+ }
40
+
41
+ export interface FindRowSetFilterOptions {
42
+ field: ColumnQueryOptions;
43
+ operator: RowFilterSetOperators;
44
+ value: any[];
45
+ itemType?: string;
46
+ }
47
+
48
+ export interface FindRowLogicalFilterOptions {
49
+ operator: RowFilterLogicalOperators;
50
+ filters: RowFilterOptions[];
51
+ }
52
+
53
+ export interface FindRowUnaryFilterOptions {
54
+ field: ColumnQueryOptions;
55
+ operator: RowFilterUnaryOperators;
56
+ }
57
+
58
+ export interface FindRowExistenceFilterOptions {
59
+ field: ColumnQueryOptions;
60
+ operator: RowFilterExistenceOperators;
61
+ filters: RowFilterOptions[];
62
+ }
63
+
64
+ export interface FindRowPaginationOptions {
65
+ offset: number;
66
+ limit: number;
67
+ withoutTotal?: boolean;
68
+ }
69
+
70
+ export interface FindRowOrderByOptions {
71
+ field: ColumnQueryOptions;
72
+ desc?: boolean;
73
+ }
74
+
75
+ export interface CountRowOptions {
76
+ filters?: RowFilterOptions[];
77
+ }
78
+
79
+ export interface UpdateRowOptions {
80
+ filters?: RowFilterOptions[];
81
+ entity: any;
82
+ }
83
+
84
+ export interface DeleteRowOptions {
85
+ filters?: RowFilterOptions[];
86
+ }
@@ -1,16 +1,10 @@
1
- import {
2
- CountEntityOptions,
3
- FindEntityOptions,
4
- CreateEntityOptions,
5
- IRpdDataAccessor,
6
- RpdDataModel,
7
- UpdateEntityOptions,
8
- IDatabaseAccessor,
9
- } from "~/types";
1
+ import { CreateEntityOptions, IRpdDataAccessor, RpdDataModel, IDatabaseAccessor, DatabaseQuery } from "~/types";
10
2
  import QueryBuilder from "~/queryBuilder/queryBuilder";
11
3
  import { first, set } from "lodash";
12
4
  import { IRpdServer } from "~/core/server";
13
5
  import { Logger } from "~/facilities/log/LogFacility";
6
+ import { newDatabaseError } from "~/utilities/errorUtility";
7
+ import { CountRowOptions, FindRowOptions, UpdateRowOptions } from "./dataAccessTypes";
14
8
 
15
9
  export interface IDataAccessorOptions {
16
10
  model: RpdDataModel;
@@ -21,9 +15,11 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
21
15
  #logger: Logger;
22
16
  #model: RpdDataModel;
23
17
  #queryBuilder: QueryBuilder;
18
+ #server: IRpdServer;
24
19
  #databaseAccessor: IDatabaseAccessor;
25
20
 
26
21
  constructor(server: IRpdServer, databaseAccessor: IDatabaseAccessor, options: IDataAccessorOptions) {
22
+ this.#server = server;
27
23
  this.#logger = server.getLogger();
28
24
  this.#databaseAccessor = databaseAccessor;
29
25
  this.#queryBuilder = options.queryBuilder;
@@ -44,11 +40,13 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
44
40
  }
45
41
 
46
42
  async updateById(id: any, entity: Partial<T>): Promise<{ count: number }> {
47
- const options: UpdateEntityOptions = {
43
+ const options: UpdateRowOptions = {
48
44
  entity,
49
45
  filters: [
50
46
  {
51
- field: "id",
47
+ field: {
48
+ name: "id",
49
+ },
52
50
  operator: "eq",
53
51
  value: id,
54
52
  },
@@ -59,35 +57,57 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
59
57
  return first(result);
60
58
  }
61
59
 
62
- async find(options: FindEntityOptions): Promise<T[]> {
60
+ async find(options: FindRowOptions): Promise<T[]> {
63
61
  this.#logger.debug(`Finding '${this.#model.singularCode}' entity.`, { options });
64
- const query = this.#queryBuilder.select(this.#model, options);
65
- return await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
62
+ let query: DatabaseQuery;
63
+ if (this.#model.base) {
64
+ const baseModel = this.#server.getModel({
65
+ singularCode: this.#model.base,
66
+ });
67
+ query = this.#queryBuilder.selectDerived(this.#model, baseModel, options);
68
+ } else {
69
+ query = this.#queryBuilder.select(this.#model, options);
70
+ }
71
+
72
+ try {
73
+ return await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
74
+ } catch (err) {
75
+ throw newDatabaseError(`Failed to find entities. ${err.message}`, err);
76
+ }
66
77
  }
67
78
 
68
- async findOne(options: FindEntityOptions): Promise<T> {
79
+ async findOne(options: FindRowOptions): Promise<T> {
69
80
  set(options, "pagination.limit", 1);
70
81
  const list = await this.find(options);
71
82
  return first(list);
72
83
  }
73
84
 
74
85
  async findById(id: any): Promise<T | null> {
75
- const options: FindEntityOptions = {
86
+ const options: FindRowOptions = {
76
87
  filters: [
77
88
  {
78
- field: "id",
89
+ field: {
90
+ name: "id",
91
+ },
79
92
  operator: "eq",
80
93
  value: id,
81
94
  },
82
95
  ],
83
96
  };
84
- const query = this.#queryBuilder.select(this.#model, options);
85
- const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
86
- return first(result);
97
+ const result = await this.findOne(options);
98
+ return result;
87
99
  }
88
100
 
89
- async count(options: CountEntityOptions): Promise<any> {
90
- const query = this.#queryBuilder.count(this.#model, options);
101
+ async count(options: CountRowOptions): Promise<any> {
102
+ let query: DatabaseQuery;
103
+ if (this.#model.base) {
104
+ const baseModel = this.#server.getModel({
105
+ singularCode: this.#model.base,
106
+ });
107
+ query = this.#queryBuilder.countDerived(this.#model, baseModel, options);
108
+ } else {
109
+ query = this.#queryBuilder.count(this.#model, options);
110
+ }
91
111
  const result = await this.#databaseAccessor.queryDatabaseObject(query.command, query.params);
92
112
 
93
113
  const row = first(result);
@@ -100,10 +120,12 @@ export default class DataAccessor<T = any> implements IRpdDataAccessor<T> {
100
120
  }
101
121
 
102
122
  async deleteById(id: any) {
103
- const options: FindEntityOptions = {
123
+ const options: FindRowOptions = {
104
124
  filters: [
105
125
  {
106
- field: "id",
126
+ field: {
127
+ name: "id",
128
+ },
107
129
  operator: "eq",
108
130
  value: id,
109
131
  },