@ruiapp/rapid-core 0.1.62 → 0.1.65

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 (164) hide show
  1. package/dist/dataAccess/dataAccessTypes.d.ts +7 -7
  2. package/dist/dataAccess/entityManager.d.ts +15 -1
  3. package/dist/helpers/entityHelpers.d.ts +3 -1
  4. package/dist/{dataAccess → helpers}/metaHelper.d.ts +3 -0
  5. package/dist/index.js +225 -69
  6. package/dist/plugins/setting/SettingPlugin.d.ts +21 -0
  7. package/dist/plugins/setting/SettingPluginTypes.d.ts +31 -0
  8. package/dist/plugins/setting/SettingService.d.ts +10 -0
  9. package/dist/plugins/setting/actionHandlers/getSystemSettingValues.d.ts +7 -0
  10. package/dist/plugins/setting/actionHandlers/index.d.ts +3 -0
  11. package/dist/plugins/setting/models/SystemSettingGroupSetting.d.ts +3 -0
  12. package/dist/plugins/setting/models/SystemSettingItem.d.ts +3 -0
  13. package/dist/plugins/setting/models/SystemSettingItemSetting.d.ts +3 -0
  14. package/dist/plugins/setting/models/UserSettingGroupSetting.d.ts +3 -0
  15. package/dist/plugins/setting/models/UserSettingItem.d.ts +3 -0
  16. package/dist/plugins/setting/models/UserSettingItemSetting.d.ts +3 -0
  17. package/dist/plugins/setting/models/index.d.ts +2 -0
  18. package/dist/plugins/setting/routes/getSystemSettingValues.d.ts +12 -0
  19. package/dist/plugins/setting/routes/index.d.ts +12 -0
  20. package/dist/queryBuilder/queryBuilder.d.ts +2 -2
  21. package/dist/types.d.ts +12 -1
  22. package/package.json +1 -1
  23. package/rollup.config.js +16 -16
  24. package/src/bootstrapApplicationConfig.ts +552 -545
  25. package/src/core/actionHandler.ts +22 -22
  26. package/src/core/eventManager.ts +20 -20
  27. package/src/core/facility.ts +7 -7
  28. package/src/core/http/formDataParser.ts +89 -89
  29. package/src/core/http-types.ts +4 -4
  30. package/src/core/pluginManager.ts +175 -175
  31. package/src/core/providers/runtimeProvider.ts +5 -5
  32. package/src/core/request.ts +86 -86
  33. package/src/core/response.ts +76 -76
  34. package/src/core/routeContext.ts +43 -43
  35. package/src/core/routesBuilder.ts +88 -88
  36. package/src/core/server.ts +16 -1
  37. package/src/dataAccess/dataAccessTypes.ts +109 -86
  38. package/src/dataAccess/dataAccessor.ts +137 -137
  39. package/src/dataAccess/entityManager.ts +1298 -1187
  40. package/src/dataAccess/entityMapper.ts +4 -5
  41. package/src/dataAccess/propertyMapper.ts +27 -27
  42. package/src/deno-std/assert/assert.ts +9 -9
  43. package/src/deno-std/assert/assertion_error.ts +7 -7
  44. package/src/deno-std/datetime/to_imf.ts +32 -32
  45. package/src/deno-std/encoding/base64.ts +141 -141
  46. package/src/deno-std/http/cookie.ts +8 -1
  47. package/src/facilities/log/LogFacility.ts +35 -35
  48. package/src/helpers/entityHelpers.ts +76 -21
  49. package/src/{dataAccess → helpers}/filterHelper.ts +3 -1
  50. package/src/helpers/inputHelper.ts +11 -11
  51. package/src/{dataAccess → helpers}/metaHelper.ts +15 -6
  52. package/src/helpers/runCollectionEntityActionHandler.ts +6 -1
  53. package/src/index.ts +41 -41
  54. package/src/plugins/auth/AuthPlugin.ts +7 -1
  55. package/src/plugins/auth/actionHandlers/changePassword.ts +54 -54
  56. package/src/plugins/auth/actionHandlers/createSession.ts +63 -63
  57. package/src/plugins/auth/actionHandlers/deleteSession.ts +18 -18
  58. package/src/plugins/auth/actionHandlers/getMyProfile.ts +35 -35
  59. package/src/plugins/auth/actionHandlers/index.ts +8 -8
  60. package/src/plugins/auth/actionHandlers/resetPassword.ts +38 -38
  61. package/src/plugins/auth/models/AccessToken.ts +56 -56
  62. package/src/plugins/auth/models/index.ts +3 -3
  63. package/src/plugins/auth/routes/changePassword.ts +15 -15
  64. package/src/plugins/auth/routes/getMyProfile.ts +15 -15
  65. package/src/plugins/auth/routes/index.ts +7 -7
  66. package/src/plugins/auth/routes/resetPassword.ts +15 -15
  67. package/src/plugins/auth/routes/signin.ts +15 -15
  68. package/src/plugins/auth/routes/signout.ts +15 -15
  69. package/src/plugins/cronJob/CronJobPlugin.ts +7 -1
  70. package/src/plugins/cronJob/CronJobPluginTypes.ts +49 -49
  71. package/src/plugins/cronJob/actionHandlers/index.ts +4 -4
  72. package/src/plugins/cronJob/actionHandlers/runCronJob.ts +29 -29
  73. package/src/plugins/cronJob/routes/index.ts +3 -3
  74. package/src/plugins/cronJob/routes/runCronJob.ts +15 -15
  75. package/src/plugins/dataManage/DataManagePlugin.ts +7 -1
  76. package/src/plugins/dataManage/actionHandlers/addEntityRelations.ts +20 -20
  77. package/src/plugins/dataManage/actionHandlers/countCollectionEntities.ts +15 -15
  78. package/src/plugins/dataManage/actionHandlers/createCollectionEntitiesBatch.ts +42 -42
  79. package/src/plugins/dataManage/actionHandlers/createCollectionEntity.ts +24 -24
  80. package/src/plugins/dataManage/actionHandlers/deleteCollectionEntityById.ts +7 -4
  81. package/src/plugins/dataManage/actionHandlers/findCollectionEntities.ts +26 -26
  82. package/src/plugins/dataManage/actionHandlers/findCollectionEntityById.ts +21 -21
  83. package/src/plugins/dataManage/actionHandlers/queryDatabase.ts +22 -22
  84. package/src/plugins/dataManage/actionHandlers/removeEntityRelations.ts +20 -20
  85. package/src/plugins/dataManage/actionHandlers/updateCollectionEntityById.ts +35 -35
  86. package/src/plugins/entityAccessControl/EntityAccessControlPlugin.ts +146 -146
  87. package/src/plugins/fileManage/FileManagePlugin.ts +7 -1
  88. package/src/plugins/fileManage/actionHandlers/downloadDocument.ts +36 -36
  89. package/src/plugins/fileManage/actionHandlers/downloadFile.ts +28 -28
  90. package/src/plugins/fileManage/actionHandlers/uploadFile.ts +33 -33
  91. package/src/plugins/fileManage/routes/downloadDocument.ts +15 -15
  92. package/src/plugins/fileManage/routes/downloadFile.ts +15 -15
  93. package/src/plugins/fileManage/routes/index.ts +5 -5
  94. package/src/plugins/fileManage/routes/uploadFile.ts +15 -15
  95. package/src/plugins/metaManage/MetaManagePlugin.ts +37 -9
  96. package/src/plugins/metaManage/actionHandlers/getMetaModelDetail.ts +10 -10
  97. package/src/plugins/metaManage/actionHandlers/listMetaModels.ts +9 -9
  98. package/src/plugins/metaManage/actionHandlers/listMetaRoutes.ts +9 -9
  99. package/src/plugins/routeManage/RouteManagePlugin.ts +7 -1
  100. package/src/plugins/routeManage/actionHandlers/httpProxy.ts +13 -13
  101. package/src/plugins/sequence/SequencePlugin.ts +8 -2
  102. package/src/plugins/sequence/SequencePluginTypes.ts +9 -1
  103. package/src/plugins/sequence/SequenceService.ts +81 -81
  104. package/src/plugins/sequence/actionHandlers/generateSn.ts +32 -32
  105. package/src/plugins/sequence/actionHandlers/index.ts +4 -4
  106. package/src/plugins/sequence/models/SequenceAutoIncrementRecord.ts +49 -49
  107. package/src/plugins/sequence/models/SequenceRule.ts +42 -42
  108. package/src/plugins/sequence/models/index.ts +4 -4
  109. package/src/plugins/sequence/routes/generateSn.ts +15 -15
  110. package/src/plugins/sequence/routes/index.ts +3 -3
  111. package/src/plugins/sequence/segment-utility.ts +11 -11
  112. package/src/plugins/sequence/segments/autoIncrement.ts +6 -1
  113. package/src/plugins/sequence/segments/dayOfMonth.ts +6 -1
  114. package/src/plugins/sequence/segments/index.ts +9 -9
  115. package/src/plugins/sequence/segments/literal.ts +6 -1
  116. package/src/plugins/sequence/segments/month.ts +6 -1
  117. package/src/plugins/sequence/segments/parameter.ts +6 -1
  118. package/src/plugins/sequence/segments/year.ts +6 -1
  119. package/src/plugins/serverOperation/ServerOperationPlugin.ts +91 -91
  120. package/src/plugins/serverOperation/ServerOperationPluginTypes.ts +15 -15
  121. package/src/plugins/serverOperation/actionHandlers/index.ts +4 -4
  122. package/src/plugins/serverOperation/actionHandlers/runServerOperation.ts +15 -15
  123. package/src/plugins/setting/SettingPlugin.ts +71 -0
  124. package/src/plugins/setting/SettingPluginTypes.ts +35 -0
  125. package/src/plugins/setting/SettingService.ts +17 -0
  126. package/src/plugins/setting/actionHandlers/getSystemSettingValues.ts +30 -0
  127. package/src/plugins/setting/actionHandlers/index.ts +4 -0
  128. package/src/plugins/setting/models/SystemSettingGroupSetting.ts +56 -0
  129. package/src/plugins/setting/models/SystemSettingItem.ts +42 -0
  130. package/src/plugins/setting/models/SystemSettingItemSetting.ts +72 -0
  131. package/src/plugins/setting/models/UserSettingGroupSetting.ts +56 -0
  132. package/src/plugins/setting/models/UserSettingItem.ts +49 -0
  133. package/src/plugins/setting/models/UserSettingItemSetting.ts +72 -0
  134. package/src/plugins/setting/models/index.ts +8 -0
  135. package/src/plugins/setting/routes/getSystemSettingValues.ts +15 -0
  136. package/src/plugins/setting/routes/index.ts +3 -0
  137. package/src/plugins/stateMachine/StateMachinePlugin.ts +8 -2
  138. package/src/plugins/stateMachine/StateMachinePluginTypes.ts +9 -1
  139. package/src/plugins/stateMachine/actionHandlers/index.ts +4 -4
  140. package/src/plugins/stateMachine/actionHandlers/sendStateMachineEvent.ts +51 -51
  141. package/src/plugins/stateMachine/models/StateMachine.ts +42 -42
  142. package/src/plugins/stateMachine/models/index.ts +3 -3
  143. package/src/plugins/stateMachine/routes/index.ts +3 -3
  144. package/src/plugins/stateMachine/routes/sendStateMachineEvent.ts +15 -15
  145. package/src/plugins/stateMachine/stateMachineHelper.ts +36 -36
  146. package/src/plugins/webhooks/WebhooksPlugin.ts +13 -2
  147. package/src/plugins/webhooks/pluginConfig.ts +74 -74
  148. package/src/polyfill.ts +5 -5
  149. package/src/proxy/mod.ts +38 -38
  150. package/src/proxy/types.ts +21 -21
  151. package/src/queryBuilder/index.ts +1 -1
  152. package/src/queryBuilder/queryBuilder.ts +473 -473
  153. package/src/server.ts +23 -3
  154. package/src/types.ts +593 -535
  155. package/src/utilities/accessControlUtility.ts +33 -33
  156. package/src/utilities/errorUtility.ts +4 -6
  157. package/src/utilities/fsUtility.ts +61 -61
  158. package/src/utilities/httpUtility.ts +19 -19
  159. package/src/utilities/jwtUtility.ts +26 -26
  160. package/src/utilities/typeUtility.ts +11 -11
  161. package/tsconfig.json +19 -19
  162. package/dist/utilities/rapidUtility.d.ts +0 -2
  163. package/src/utilities/rapidUtility.ts +0 -5
  164. /package/dist/{dataAccess → helpers}/filterHelper.d.ts +0 -0
@@ -6,7 +6,7 @@ export type RowFilterExistenceOperators = "exists" | "notExists";
6
6
  export type RowFilterOperators = RowFilterRelationalOperators | RowFilterSetOperators | RowFilterLogicalOperators | RowFilterUnaryOperators | RowFilterExistenceOperators;
7
7
  export type RowFilterOptions = FindRowRelationalFilterOptions | FindRowSetFilterOptions | FindRowLogicalFilterOptions | FindRowUnaryFilterOptions | FindRowExistenceFilterOptions;
8
8
  export type RowNonRelationPropertyFilterOptions = FindRowRelationalFilterOptions | FindRowSetFilterOptions | FindRowUnaryFilterOptions;
9
- export type ColumnQueryOptions = string | ColumnNameWithTableName;
9
+ export type ColumnSelectOptions = string | ColumnNameWithTableName;
10
10
  export type ColumnNameWithTableName = {
11
11
  name: string;
12
12
  tableName?: string;
@@ -15,16 +15,16 @@ export interface FindRowOptions {
15
15
  filters?: RowFilterOptions[];
16
16
  orderBy?: FindRowOrderByOptions[];
17
17
  pagination?: FindRowPaginationOptions;
18
- fields?: ColumnQueryOptions[];
18
+ fields?: ColumnSelectOptions[];
19
19
  keepNonPropertyFields?: boolean;
20
20
  }
21
21
  export interface FindRowRelationalFilterOptions {
22
- field: ColumnQueryOptions;
22
+ field: ColumnSelectOptions;
23
23
  operator: RowFilterRelationalOperators;
24
24
  value: any;
25
25
  }
26
26
  export interface FindRowSetFilterOptions {
27
- field: ColumnQueryOptions;
27
+ field: ColumnSelectOptions;
28
28
  operator: RowFilterSetOperators;
29
29
  value: any[];
30
30
  itemType?: string;
@@ -34,11 +34,11 @@ export interface FindRowLogicalFilterOptions {
34
34
  filters: RowFilterOptions[];
35
35
  }
36
36
  export interface FindRowUnaryFilterOptions {
37
- field: ColumnQueryOptions;
37
+ field: ColumnSelectOptions;
38
38
  operator: RowFilterUnaryOperators;
39
39
  }
40
40
  export interface FindRowExistenceFilterOptions {
41
- field: ColumnQueryOptions;
41
+ field: ColumnSelectOptions;
42
42
  operator: RowFilterExistenceOperators;
43
43
  filters: RowFilterOptions[];
44
44
  }
@@ -48,7 +48,7 @@ export interface FindRowPaginationOptions {
48
48
  withoutTotal?: boolean;
49
49
  }
50
50
  export interface FindRowOrderByOptions {
51
- field: ColumnQueryOptions;
51
+ field: ColumnSelectOptions;
52
52
  desc?: boolean;
53
53
  }
54
54
  export interface CountRowOptions {
@@ -1,5 +1,19 @@
1
- import { AddEntityRelationsOptions, CountEntityOptions, CountEntityResult, CreateEntityOptions, DeleteEntityByIdOptions, FindEntityByIdOptions, FindEntityOptions, IRpdDataAccessor, RemoveEntityRelationsOptions, RpdDataModel, UpdateEntityByIdOptions } from "../types";
1
+ import { AddEntityRelationsOptions, CountEntityOptions, CountEntityResult, CreateEntityOptions, DeleteEntityByIdOptions, FindEntityByIdOptions, FindEntityOptions, FindEntitySelectRelationOptions, IRpdDataAccessor, RemoveEntityRelationsOptions, RpdDataModel, RpdDataModelProperty, UpdateEntityByIdOptions } from "../types";
2
2
  import { IRpdServer, RapidPlugin } from "../core/server";
3
+ export type FindOneRelationEntitiesOptions = {
4
+ server: IRpdServer;
5
+ mainModel: RpdDataModel;
6
+ relationProperty: RpdDataModelProperty;
7
+ relationEntityIds: any[];
8
+ selectRelationOptions?: FindEntitySelectRelationOptions;
9
+ };
10
+ export type FindManyRelationEntitiesOptions = {
11
+ server: IRpdServer;
12
+ mainModel: RpdDataModel;
13
+ relationProperty: RpdDataModelProperty;
14
+ mainEntityIds: any[];
15
+ selectRelationOptions?: FindEntitySelectRelationOptions;
16
+ };
3
17
  export default class EntityManager<TEntity = any> {
4
18
  #private;
5
19
  constructor(server: IRpdServer, dataAccessor: IRpdDataAccessor);
@@ -1 +1,3 @@
1
- export declare function getEntityPartChanges(before: any, after: any): Record<string, any> | null;
1
+ import { IRpdServer } from "../core/server";
2
+ import { RpdDataModel } from "../types";
3
+ export declare function getEntityPartChanges(server: IRpdServer, model: RpdDataModel, before: any, after: any): Record<string, any> | null;
@@ -1,5 +1,8 @@
1
1
  import { IRpdServer } from "../core/server";
2
2
  import { RpdDataModel, RpdDataModelProperty } from "../types";
3
+ export declare function isRelationProperty(property: RpdDataModelProperty): boolean;
4
+ export declare function isOneRelationProperty(property: RpdDataModelProperty): boolean;
5
+ export declare function isManyRelationProperty(property: RpdDataModelProperty): boolean;
3
6
  export declare function getEntityProperties(server: IRpdServer, model: RpdDataModel): RpdDataModelProperty[];
4
7
  export declare function getEntityPropertiesIncludingBase(server: IRpdServer, model: RpdDataModel): RpdDataModelProperty[];
5
8
  export declare function getEntityPropertyByCode(server: IRpdServer, model: RpdDataModel, propertyCode: string): RpdDataModelProperty;
package/dist/index.js CHANGED
@@ -277,9 +277,11 @@ class QueryBuilder {
277
277
  command += `${this.quoteObject(derivedModel.tableName)}.* FROM `;
278
278
  }
279
279
  else {
280
- command += columns.map((column) => {
280
+ command += columns
281
+ .map((column) => {
281
282
  return this.quoteColumn(column, ctx.emitTableAlias);
282
- }).join(", ");
283
+ })
284
+ .join(", ");
283
285
  command += " FROM ";
284
286
  }
285
287
  command += `${this.quoteTable(derivedModel)} LEFT JOIN ${this.quoteTable(baseModel)} ON ${this.quoteObject(derivedModel.tableName)}.id = ${this.quoteObject(baseModel.tableName)}.id`;
@@ -1091,7 +1093,12 @@ function validateValue(name, value) {
1091
1093
  return;
1092
1094
  for (let i = 0; i < value.length; i++) {
1093
1095
  const c = value.charAt(i);
1094
- if (c < String.fromCharCode(0x21) || c == String.fromCharCode(0x22) || c == String.fromCharCode(0x2c) || c == String.fromCharCode(0x3b) || c == String.fromCharCode(0x5c) || c == String.fromCharCode(0x7f)) {
1096
+ if (c < String.fromCharCode(0x21) ||
1097
+ c == String.fromCharCode(0x22) ||
1098
+ c == String.fromCharCode(0x2c) ||
1099
+ c == String.fromCharCode(0x3b) ||
1100
+ c == String.fromCharCode(0x5c) ||
1101
+ c == String.fromCharCode(0x7f)) {
1095
1102
  throw new Error("RFC2616 cookie '" + name + "' cannot contain character '" + c + "'");
1096
1103
  }
1097
1104
  if (c > String.fromCharCode(0x80)) {
@@ -1338,6 +1345,13 @@ var bootstrapApplicationConfig = {
1338
1345
  type: "text",
1339
1346
  required: false,
1340
1347
  },
1348
+ {
1349
+ name: "displayPropertyCode",
1350
+ code: "displayPropertyCode",
1351
+ columnName: "display_property_code",
1352
+ type: "text",
1353
+ required: false,
1354
+ },
1341
1355
  {
1342
1356
  name: "properties",
1343
1357
  code: "properties",
@@ -1798,8 +1812,10 @@ var bootstrapApplicationConfig$1 = /*#__PURE__*/Object.freeze({
1798
1812
 
1799
1813
  function isRelationProperty(property) {
1800
1814
  return property.type === "relation" || property.type === "relation[]";
1801
- }
1802
-
1815
+ }
1816
+ function isOneRelationProperty(property) {
1817
+ return isRelationProperty(property) && property.relation === "one";
1818
+ }
1803
1819
  function getEntityPropertiesIncludingBase(server, model) {
1804
1820
  if (!model.base) {
1805
1821
  return model.properties;
@@ -1815,10 +1831,7 @@ function getEntityPropertiesIncludingBase(server, model) {
1815
1831
  return property;
1816
1832
  });
1817
1833
  }
1818
- return [
1819
- ...baseProperties,
1820
- ...model.properties,
1821
- ];
1834
+ return [...baseProperties, ...model.properties];
1822
1835
  }
1823
1836
  function getEntityPropertyByCode(server, model, propertyCode) {
1824
1837
  return getEntityProperty(server, model, (e) => e.code === propertyCode);
@@ -1895,8 +1908,8 @@ function mapEntityToDbRow(server, model, entity) {
1895
1908
  if (!entity) {
1896
1909
  return result;
1897
1910
  }
1898
- const row = result.row = {};
1899
- const baseRow = result.baseRow = {};
1911
+ const row = (result.row = {});
1912
+ const baseRow = (result.baseRow = {});
1900
1913
  if (!model.properties || !model.properties.length) {
1901
1914
  return result;
1902
1915
  }
@@ -1944,25 +1957,80 @@ function mapPropertyNameToColumnName(model, propertyName) {
1944
1957
  return property.columnName || property.code;
1945
1958
  }
1946
1959
 
1947
- function getEntityPartChanges(before, after) {
1960
+ function getEntityPartChanges(server, model, before, after) {
1948
1961
  if (!before) {
1949
1962
  throw new Error("Argument 'before' can not be null.");
1950
1963
  }
1951
1964
  if (!after) {
1952
1965
  throw new Error("Argument 'after' can not be null.");
1953
1966
  }
1954
- let changed = null;
1967
+ let changed = false;
1968
+ let changes = {};
1955
1969
  for (const key in after) {
1956
- if (after[key] != before[key]) {
1957
- if (changed) {
1958
- changed[key] = after[key];
1970
+ const property = getEntityPropertyByCode(server, model, key);
1971
+ if (isOneRelationProperty(property)) {
1972
+ const afterValue = after[key];
1973
+ const beforeValue = before[key] || before[property.targetIdColumnName];
1974
+ if (afterValue) {
1975
+ if (lodash.isNumber(afterValue)) {
1976
+ if (beforeValue) {
1977
+ if (lodash.isNumber(beforeValue)) {
1978
+ if (afterValue != beforeValue) {
1979
+ changed = true;
1980
+ changes[key] = afterValue;
1981
+ }
1982
+ }
1983
+ else {
1984
+ if (afterValue != beforeValue.id) {
1985
+ changed = true;
1986
+ changes[key] = afterValue;
1987
+ }
1988
+ }
1989
+ }
1990
+ else {
1991
+ changed = true;
1992
+ changes[key] = afterValue;
1993
+ }
1994
+ }
1995
+ else {
1996
+ if (beforeValue) {
1997
+ if (lodash.isNumber(beforeValue)) {
1998
+ if (afterValue.id != beforeValue) {
1999
+ changed = true;
2000
+ changes[key] = afterValue;
2001
+ }
2002
+ }
2003
+ else {
2004
+ if (afterValue.id != beforeValue.id) {
2005
+ changed = true;
2006
+ changes[key] = afterValue;
2007
+ }
2008
+ }
2009
+ }
2010
+ else {
2011
+ changed = true;
2012
+ changes[key] = afterValue;
2013
+ }
2014
+ }
1959
2015
  }
1960
2016
  else {
1961
- changed = { [key]: after[key] };
2017
+ if (beforeValue) {
2018
+ changed = true;
2019
+ changes[key] = null;
2020
+ }
2021
+ }
2022
+ }
2023
+ else {
2024
+ if (after[key] != before[key]) {
2025
+ changed = true;
2026
+ changes[key] = after[key];
1962
2027
  }
1963
2028
  }
1964
2029
  }
1965
- return changed;
2030
+ if (changed) {
2031
+ return changes;
2032
+ }
2033
+ return null;
1966
2034
  }
1967
2035
 
1968
2036
  function getNowStringWithTimezone() {
@@ -2001,16 +2069,18 @@ async function findEntities(server, dataAccessor, options) {
2001
2069
  singularCode: model.base,
2002
2070
  });
2003
2071
  }
2004
- let propertiesToSlect;
2072
+ let propertiesToSelect;
2073
+ let relationOptions = options.relations || {};
2074
+ let relationPropertyCodes = Object.keys(relationOptions) || [];
2005
2075
  if (!options.properties || !options.properties.length) {
2006
- propertiesToSlect = getEntityPropertiesIncludingBase(server, model).filter((property) => !isRelationProperty(property));
2076
+ propertiesToSelect = getEntityPropertiesIncludingBase(server, model).filter((property) => !isRelationProperty(property) || relationPropertyCodes.includes(property.code));
2007
2077
  }
2008
2078
  else {
2009
- propertiesToSlect = getEntityPropertiesIncludingBase(server, model).filter((property) => options.properties.includes(property.code));
2079
+ propertiesToSelect = getEntityPropertiesIncludingBase(server, model).filter((property) => options.properties.includes(property.code) || relationPropertyCodes.includes(property.code));
2010
2080
  }
2011
2081
  const columnsToSelect = [];
2012
2082
  const relationPropertiesToSelect = [];
2013
- lodash.forEach(propertiesToSlect, (property) => {
2083
+ lodash.forEach(propertiesToSelect, (property) => {
2014
2084
  if (isRelationProperty(property)) {
2015
2085
  relationPropertiesToSelect.push(property);
2016
2086
  if (property.relation === "one" && !property.linkTableName) {
@@ -2058,6 +2128,31 @@ async function findEntities(server, dataAccessor, options) {
2058
2128
  }
2059
2129
  });
2060
2130
  }
2131
+ if (options.extraColumnsToSelect) {
2132
+ lodash.forEach(options.extraColumnsToSelect, (extraColumnToSelect) => {
2133
+ const columnSelectOptionExists = lodash.find(columnsToSelect, (item) => {
2134
+ if (typeof item === "string") {
2135
+ if (typeof extraColumnToSelect === "string") {
2136
+ return item === extraColumnToSelect;
2137
+ }
2138
+ else {
2139
+ return item == extraColumnToSelect.name;
2140
+ }
2141
+ }
2142
+ else {
2143
+ if (typeof extraColumnToSelect === "string") {
2144
+ return item.name === extraColumnToSelect;
2145
+ }
2146
+ else {
2147
+ return item.name == extraColumnToSelect.name;
2148
+ }
2149
+ }
2150
+ });
2151
+ if (!columnSelectOptionExists) {
2152
+ columnsToSelect.push(extraColumnToSelect);
2153
+ }
2154
+ });
2155
+ }
2061
2156
  const rowFilters = await convertEntityFiltersToRowFilters(server, model, baseModel, options.filters);
2062
2157
  const findRowOptions = {
2063
2158
  filters: rowFilters,
@@ -2074,27 +2169,45 @@ async function findEntities(server, dataAccessor, options) {
2074
2169
  for (const relationProperty of relationPropertiesToSelect) {
2075
2170
  const isManyRelation = relationProperty.relation === "many";
2076
2171
  if (relationProperty.linkTableName) {
2077
- const targetModel = server.getModel({ singularCode: relationProperty.targetSingularCode });
2078
- if (!targetModel) {
2172
+ const relationModel = server.getModel({ singularCode: relationProperty.targetSingularCode });
2173
+ if (!relationModel) {
2079
2174
  continue;
2080
2175
  }
2081
2176
  if (isManyRelation) {
2082
- const relationLinks = await findManyRelationLinksViaLinkTable(server, targetModel, relationProperty, entityIds);
2177
+ const relationLinks = await findManyRelationLinksViaLinkTable({
2178
+ server,
2179
+ mainModel: relationModel,
2180
+ relationProperty,
2181
+ mainEntityIds: entityIds,
2182
+ selectRelationOptions: relationOptions[relationProperty.code],
2183
+ });
2083
2184
  lodash.forEach(rows, (row) => {
2084
2185
  row[relationProperty.code] = lodash.filter(relationLinks, (link) => {
2085
2186
  return link[relationProperty.selfIdColumnName] == row["id"];
2086
- }).map((link) => mapDbRowToEntity(server, targetModel, link.targetEntity, options.keepNonPropertyFields));
2187
+ }).map((link) => mapDbRowToEntity(server, relationModel, link.targetEntity, options.keepNonPropertyFields));
2087
2188
  });
2088
2189
  }
2089
2190
  }
2090
2191
  else {
2091
2192
  let relatedEntities;
2092
2193
  if (isManyRelation) {
2093
- relatedEntities = await findManyRelatedEntitiesViaIdPropertyCode(server, model, relationProperty, entityIds);
2194
+ relatedEntities = await findManyRelatedEntitiesViaIdPropertyCode({
2195
+ server,
2196
+ mainModel: model,
2197
+ relationProperty,
2198
+ mainEntityIds: entityIds,
2199
+ selectRelationOptions: relationOptions[relationProperty.code],
2200
+ });
2094
2201
  }
2095
2202
  else {
2096
2203
  const targetEntityIds = lodash.uniq(lodash.reject(lodash.map(rows, (entity) => entity[relationProperty.targetIdColumnName]), isNullOrUndefined));
2097
- relatedEntities = await findOneRelatedEntitiesViaIdPropertyCode(server, model, relationProperty, targetEntityIds);
2204
+ relatedEntities = await findOneRelatedEntitiesViaIdPropertyCode({
2205
+ server,
2206
+ mainModel: model,
2207
+ relationProperty,
2208
+ relationEntityIds: targetEntityIds,
2209
+ selectRelationOptions: relationOptions[relationProperty.code],
2210
+ });
2098
2211
  }
2099
2212
  const targetModel = server.getModel({
2100
2213
  singularCode: relationProperty.targetSingularCode,
@@ -2354,68 +2467,99 @@ async function convertEntityFiltersToRowFilters(server, model, baseModel, filter
2354
2467
  }
2355
2468
  return replacedFilters;
2356
2469
  }
2357
- async function findManyRelationLinksViaLinkTable(server, targetModel, relationProperty, entityIds) {
2470
+ async function findManyRelationLinksViaLinkTable(options) {
2471
+ const { server, relationProperty, mainModel: relationModel, mainEntityIds, selectRelationOptions } = options;
2358
2472
  const command = `SELECT * FROM ${server.queryBuilder.quoteTable({
2359
2473
  schema: relationProperty.linkSchema,
2360
2474
  tableName: relationProperty.linkTableName,
2361
2475
  })} WHERE ${server.queryBuilder.quoteObject(relationProperty.selfIdColumnName)} = ANY($1::int[])`;
2362
- const params = [entityIds];
2476
+ const params = [mainEntityIds];
2363
2477
  const links = await server.queryDatabaseObject(command, params);
2364
2478
  const targetEntityIds = links.map((link) => link[relationProperty.targetIdColumnName]);
2479
+ const dataAccessor = server.getDataAccessor({
2480
+ namespace: relationModel.namespace,
2481
+ singularCode: relationModel.singularCode,
2482
+ });
2365
2483
  const findEntityOptions = {
2366
2484
  filters: [
2367
2485
  {
2368
- field: {
2369
- name: "id",
2370
- },
2486
+ field: "id",
2371
2487
  operator: "in",
2372
2488
  value: targetEntityIds,
2373
2489
  },
2374
2490
  ],
2491
+ keepNonPropertyFields: true,
2375
2492
  };
2376
- const dataAccessor = server.getDataAccessor({
2377
- namespace: targetModel.namespace,
2378
- singularCode: targetModel.singularCode,
2379
- });
2380
- const targetEntities = await dataAccessor.find(findEntityOptions);
2493
+ if (selectRelationOptions) {
2494
+ if (typeof selectRelationOptions !== "boolean") {
2495
+ if (selectRelationOptions.properties) {
2496
+ findEntityOptions.properties = ["id", ...selectRelationOptions.properties];
2497
+ }
2498
+ if (selectRelationOptions.relations) {
2499
+ findEntityOptions.relations = selectRelationOptions.relations;
2500
+ }
2501
+ }
2502
+ }
2503
+ const targetEntities = await findEntities(server, dataAccessor, findEntityOptions);
2381
2504
  lodash.forEach(links, (link) => {
2382
2505
  link.targetEntity = lodash.find(targetEntities, (e) => e["id"] == link[relationProperty.targetIdColumnName]);
2383
2506
  });
2384
2507
  return links;
2385
2508
  }
2386
- function findManyRelatedEntitiesViaIdPropertyCode(server, model, relationProperty, entityIds) {
2509
+ async function findManyRelatedEntitiesViaIdPropertyCode(options) {
2510
+ const { server, relationProperty, mainEntityIds, selectRelationOptions } = options;
2511
+ const dataAccessor = server.getDataAccessor({
2512
+ singularCode: relationProperty.targetSingularCode,
2513
+ });
2387
2514
  const findEntityOptions = {
2388
2515
  filters: [
2389
2516
  {
2390
- field: {
2391
- name: relationProperty.selfIdColumnName,
2392
- },
2517
+ field: relationProperty.selfIdColumnName,
2393
2518
  operator: "in",
2394
- value: entityIds,
2519
+ value: mainEntityIds,
2395
2520
  },
2396
2521
  ],
2522
+ extraColumnsToSelect: [relationProperty.selfIdColumnName],
2523
+ keepNonPropertyFields: true,
2397
2524
  };
2525
+ if (selectRelationOptions) {
2526
+ if (typeof selectRelationOptions !== "boolean") {
2527
+ if (selectRelationOptions.properties) {
2528
+ findEntityOptions.properties = ["id", ...selectRelationOptions.properties];
2529
+ }
2530
+ if (selectRelationOptions.relations) {
2531
+ findEntityOptions.relations = selectRelationOptions.relations;
2532
+ }
2533
+ }
2534
+ }
2535
+ return await findEntities(server, dataAccessor, findEntityOptions);
2536
+ }
2537
+ async function findOneRelatedEntitiesViaIdPropertyCode(options) {
2538
+ const { server, relationProperty, relationEntityIds, selectRelationOptions } = options;
2398
2539
  const dataAccessor = server.getDataAccessor({
2399
2540
  singularCode: relationProperty.targetSingularCode,
2400
2541
  });
2401
- return dataAccessor.find(findEntityOptions);
2402
- }
2403
- function findOneRelatedEntitiesViaIdPropertyCode(server, model, relationProperty, targetEntityIds) {
2404
2542
  const findEntityOptions = {
2405
2543
  filters: [
2406
2544
  {
2407
- field: {
2408
- name: "id",
2409
- },
2545
+ field: "id",
2410
2546
  operator: "in",
2411
- value: targetEntityIds,
2547
+ value: relationEntityIds,
2412
2548
  },
2413
2549
  ],
2550
+ keepNonPropertyFields: true,
2414
2551
  };
2415
- const dataAccessor = server.getDataAccessor({
2416
- singularCode: relationProperty.targetSingularCode,
2417
- });
2418
- return dataAccessor.find(findEntityOptions);
2552
+ if (selectRelationOptions) {
2553
+ if (typeof selectRelationOptions !== "boolean") {
2554
+ if (selectRelationOptions.properties) {
2555
+ findEntityOptions.properties = ["id", ...selectRelationOptions.properties];
2556
+ }
2557
+ if (selectRelationOptions.relations) {
2558
+ findEntityOptions.relations = selectRelationOptions.relations;
2559
+ }
2560
+ }
2561
+ }
2562
+ return await findEntities(server, dataAccessor, findEntityOptions);
2419
2563
  }
2420
2564
  async function createEntity(server, dataAccessor, options, plugin) {
2421
2565
  const model = dataAccessor.getModel();
@@ -2494,7 +2638,7 @@ async function createEntity(server, dataAccessor, options, plugin) {
2494
2638
  targetRow[property.targetIdColumnName] = targetEntityId;
2495
2639
  }
2496
2640
  }
2497
- else {
2641
+ else if (lodash.isNumber(fieldValue)) {
2498
2642
  // fieldValue is id;
2499
2643
  const targetEntityId = fieldValue;
2500
2644
  const targetEntity = await findById(server, targetDataAccessor, {
@@ -2507,6 +2651,10 @@ async function createEntity(server, dataAccessor, options, plugin) {
2507
2651
  newEntityOneRelationProps[property.code] = targetEntity;
2508
2652
  targetRow[property.targetIdColumnName] = targetEntityId;
2509
2653
  }
2654
+ else {
2655
+ newEntityOneRelationProps[property.code] = null;
2656
+ targetRow[property.targetIdColumnName] = null;
2657
+ }
2510
2658
  }
2511
2659
  let newBaseRow;
2512
2660
  if (model.base) {
@@ -2615,14 +2763,15 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
2615
2763
  throw new Error("Id is required when updating an entity.");
2616
2764
  }
2617
2765
  const entity = await findById(server, dataAccessor, {
2618
- id,
2619
2766
  routeContext,
2767
+ id,
2768
+ keepNonPropertyFields: true,
2620
2769
  });
2621
2770
  if (!entity) {
2622
2771
  throw new Error(`${model.namespace}.${model.singularCode} with id "${id}" was not found.`);
2623
2772
  }
2624
2773
  let { entityToSave } = options;
2625
- let changes = getEntityPartChanges(entity, entityToSave);
2774
+ let changes = getEntityPartChanges(server, model, entity, entityToSave);
2626
2775
  if (!changes && !options.operation) {
2627
2776
  return entity;
2628
2777
  }
@@ -2652,7 +2801,7 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
2652
2801
  sender: plugin,
2653
2802
  routeContext: options.routeContext,
2654
2803
  });
2655
- changes = getEntityPartChanges(entity, entityToSave);
2804
+ changes = getEntityPartChanges(server, model, entity, entityToSave);
2656
2805
  const oneRelationPropertiesToUpdate = [];
2657
2806
  const manyRelationPropertiesToUpdate = [];
2658
2807
  lodash.keys(changes).forEach((propertyCode) => {
@@ -2700,7 +2849,7 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
2700
2849
  targetRow[property.targetIdColumnName] = targetEntityId;
2701
2850
  }
2702
2851
  }
2703
- else {
2852
+ else if (lodash.isNumber(fieldValue)) {
2704
2853
  // fieldValue is id;
2705
2854
  const targetEntityId = fieldValue;
2706
2855
  const targetEntity = await findById(server, targetDataAccessor, {
@@ -2713,6 +2862,10 @@ async function updateEntityById(server, dataAccessor, options, plugin) {
2713
2862
  updatedEntityOneRelationProps[property.code] = targetEntity;
2714
2863
  targetRow[property.targetIdColumnName] = targetEntityId;
2715
2864
  }
2865
+ else {
2866
+ updatedEntityOneRelationProps[property.code] = null;
2867
+ targetRow[property.targetIdColumnName] = null;
2868
+ }
2716
2869
  }
2717
2870
  let updatedRow = row;
2718
2871
  if (Object.keys(row).length) {
@@ -2946,11 +3099,11 @@ class EntityManager {
2946
3099
  const command = `INSERT INTO ${queryBuilder.quoteTable({
2947
3100
  schema: relationProperty.linkSchema,
2948
3101
  tableName: relationProperty.linkTableName,
2949
- })} (${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)})
2950
- SELECT $1, $2 WHERE NOT EXISTS (
2951
- SELECT ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}
2952
- FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
2953
- WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}=$2
3102
+ })} (${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)})
3103
+ SELECT $1, $2 WHERE NOT EXISTS (
3104
+ SELECT ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}, ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}
3105
+ FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
3106
+ WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}=$2
2954
3107
  )`;
2955
3108
  const params = [id, relation.id];
2956
3109
  await server.queryDatabaseObject(command, params);
@@ -2990,7 +3143,7 @@ class EntityManager {
2990
3143
  const { queryBuilder } = server;
2991
3144
  if (relationProperty.linkTableName) {
2992
3145
  for (const relation of relations) {
2993
- const command = `DELETE FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
3146
+ const command = `DELETE FROM ${queryBuilder.quoteTable({ schema: relationProperty.linkSchema, tableName: relationProperty.linkTableName })}
2994
3147
  WHERE ${queryBuilder.quoteObject(relationProperty.selfIdColumnName)}=$1 AND ${queryBuilder.quoteObject(relationProperty.targetIdColumnName)}=$2;`;
2995
3148
  const params = [id, relation.id];
2996
3149
  await server.queryDatabaseObject(command, params);
@@ -3701,7 +3854,10 @@ async function syncDatabaseSchema(server, applicationConfig) {
3701
3854
  }
3702
3855
  else if (property.relation === "many") {
3703
3856
  if (property.linkTableName) {
3704
- const tableInDb = lodash.find(tablesInDb, { table_schema: property.linkSchema || server.databaseConfig.dbDefaultSchema, table_name: property.linkTableName });
3857
+ const tableInDb = lodash.find(tablesInDb, {
3858
+ table_schema: property.linkSchema || server.databaseConfig.dbDefaultSchema,
3859
+ table_name: property.linkTableName,
3860
+ });
3705
3861
  if (!tableInDb) {
3706
3862
  columnDDL = generateLinkTableDDL(queryBuilder, {
3707
3863
  linkSchema: property.linkSchema,
@@ -6101,9 +6257,9 @@ class EntityAccessControlPlugin {
6101
6257
  if (!userId) {
6102
6258
  return;
6103
6259
  }
6104
- const actions = await server.queryDatabaseObject(`select distinct a.* from sys_actions a
6105
- inner join oc_role_sys_action_links ra on a.id = ra.action_id
6106
- inner join oc_role_user_links ru on ru.role_id = ra.role_id
6260
+ const actions = await server.queryDatabaseObject(`select distinct a.* from sys_actions a
6261
+ inner join oc_role_sys_action_links ra on a.id = ra.action_id
6262
+ inner join oc_role_user_links ru on ru.role_id = ra.role_id
6107
6263
  where ru.user_id = $1;`, [userId]);
6108
6264
  routeContext.state.allowedActions = actions.map((item) => item.code);
6109
6265
  }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Setting plugin
3
+ */
4
+ import { RpdApplicationConfig } from "../../types";
5
+ import { IRpdServer, RapidPlugin, RpdConfigurationItemOptions, RpdServerPluginConfigurableTargetOptions, RpdServerPluginExtendingAbilities } from "../../core/server";
6
+ import SettingService from "./SettingService";
7
+ declare class SettingPlugin implements RapidPlugin {
8
+ #private;
9
+ get settingService(): SettingService;
10
+ get code(): string;
11
+ get description(): string;
12
+ get extendingAbilities(): RpdServerPluginExtendingAbilities[];
13
+ get configurableTargets(): RpdServerPluginConfigurableTargetOptions[];
14
+ get configurations(): RpdConfigurationItemOptions[];
15
+ registerActionHandlers(server: IRpdServer): Promise<any>;
16
+ configureModels(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
17
+ configureServices(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
18
+ configureRoutes(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<any>;
19
+ onApplicationLoaded(server: IRpdServer, applicationConfig: RpdApplicationConfig): Promise<void>;
20
+ }
21
+ export default SettingPlugin;
@@ -0,0 +1,31 @@
1
+ export type SettingGroupSetting = {
2
+ code: string;
3
+ name: string;
4
+ description?: string;
5
+ permissionAssignments?: PermissionAssignment[];
6
+ };
7
+ export type SettingItemSetting = {
8
+ group: SettingGroupSetting;
9
+ orderNum: number;
10
+ type: string;
11
+ code: string;
12
+ name: string;
13
+ description?: string;
14
+ config?: any;
15
+ };
16
+ export type SystemSettingItem = {
17
+ groupCode: string;
18
+ itemCode: string;
19
+ value: any;
20
+ };
21
+ export type UserSettingItem = {
22
+ userId: number;
23
+ groupCode: string;
24
+ itemCode: string;
25
+ value: any;
26
+ };
27
+ export type PermissionAssignment = {
28
+ assigneeType: string;
29
+ assigneeId: number;
30
+ actions: string[];
31
+ };
@@ -0,0 +1,10 @@
1
+ import { IRpdServer } from "../../core/server";
2
+ export interface GetSystemSettingValuesInput {
3
+ groupCode: string;
4
+ }
5
+ export default class SequenceService {
6
+ #private;
7
+ constructor(server: IRpdServer);
8
+ getSystemSettingValues(input: GetSystemSettingValuesInput): Promise<void>;
9
+ setSystemSettingValue(groupCode: string, itemCode: string, value: any): Promise<void>;
10
+ }