oak-domain 4.4.0 → 5.0.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.
Files changed (68) hide show
  1. package/LICENSE +232 -0
  2. package/README.md +3 -0
  3. package/lib/base-app-domain/ActionDefDict.d.ts +1 -1
  4. package/lib/base-app-domain/ActionDefDict.js +4 -4
  5. package/lib/base-app-domain/I18n/Storage.js +0 -1
  6. package/lib/base-app-domain/Modi/Action.d.ts +1 -1
  7. package/lib/base-app-domain/Modi/Action.js +2 -2
  8. package/lib/base-app-domain/Modi/Style.d.ts +3 -0
  9. package/lib/base-app-domain/Modi/Style.js +16 -0
  10. package/lib/base-app-domain/ModiEntity/Schema.d.ts +14 -0
  11. package/lib/base-app-domain/OperEntity/Schema.d.ts +14 -0
  12. package/lib/base-app-domain/StyleDict.d.ts +3 -0
  13. package/lib/base-app-domain/StyleDict.js +9 -0
  14. package/lib/base-app-domain/User/Action.d.ts +1 -1
  15. package/lib/base-app-domain/User/Action.js +2 -2
  16. package/lib/base-app-domain/User/Style.d.ts +3 -0
  17. package/lib/base-app-domain/User/Style.js +14 -0
  18. package/lib/base-app-domain/index.d.ts +1 -0
  19. package/lib/base-app-domain/index.js +1 -0
  20. package/lib/compiler/dependencyBuilder.d.ts +21 -0
  21. package/lib/compiler/dependencyBuilder.js +873 -0
  22. package/lib/compiler/env.d.ts +1 -1
  23. package/lib/compiler/env.js +2 -8
  24. package/lib/compiler/localeBuilder.js +13 -7
  25. package/lib/compiler/routerBuilder.js +29 -44
  26. package/lib/compiler/schemalBuilder.js +67 -8
  27. package/lib/entities/I18n.js +0 -3
  28. package/lib/entities/Modi.js +13 -0
  29. package/lib/entities/User.js +11 -0
  30. package/lib/store/AsyncRowStore.d.ts +1 -1
  31. package/lib/store/IntrinsicCheckers.d.ts +2 -2
  32. package/lib/store/IntrinsicCheckers.js +79 -13
  33. package/lib/store/IntrinsicLogics.d.ts +2 -2
  34. package/lib/store/IntrinsicLogics.js +3 -3
  35. package/lib/store/RelationAuth.js +3 -3
  36. package/lib/store/TriggerExecutor.d.ts +1 -1
  37. package/lib/store/TriggerExecutor.js +18 -12
  38. package/lib/store/checker.js +5 -5
  39. package/lib/store/filter.d.ts +48 -1
  40. package/lib/store/filter.js +51 -8
  41. package/lib/types/Action.d.ts +1 -1
  42. package/lib/types/Configuration.d.ts +42 -7
  43. package/lib/types/Configuration.js +0 -1
  44. package/lib/types/Connector.d.ts +3 -0
  45. package/lib/types/EntityDesc.d.ts +10 -3
  46. package/lib/types/Style.d.ts +35 -6
  47. package/lib/utils/SimpleConnector.d.ts +6 -10
  48. package/lib/utils/SimpleConnector.js +33 -20
  49. package/lib/utils/lodash.d.ts +10 -1
  50. package/lib/utils/lodash.js +27 -1
  51. package/lib/utils/module/combine.common.d.ts +15 -0
  52. package/lib/utils/module/combine.common.js +27 -0
  53. package/lib/utils/module/combine.d.ts +1 -0
  54. package/lib/utils/module/combine.dev.d.ts +17 -0
  55. package/lib/utils/module/combine.dev.js +55 -0
  56. package/lib/utils/module/combine.js +4 -0
  57. package/lib/utils/module/combine.prod.d.ts +8 -0
  58. package/lib/utils/module/combine.prod.js +8 -0
  59. package/lib/utils/module/combine.server.d.ts +17 -0
  60. package/lib/utils/module/combine.server.js +55 -0
  61. package/package.json +1 -1
  62. package/src/entities/I18n.ts +42 -45
  63. package/src/entities/Modi.ts +13 -0
  64. package/src/entities/User.ts +59 -48
  65. package/lib/actions/relation.d.ts +0 -5
  66. package/lib/actions/relation.js +0 -25
  67. package/lib/base-app-domain/UserEntityGrant/Action.d.ts +0 -5
  68. package/lib/base-app-domain/UserEntityGrant/Action.js +0 -5
@@ -39,15 +39,21 @@ class TriggerExecutor {
39
39
  this.volatileEntities = [];
40
40
  this.counter = 0;
41
41
  this.onVolatileTrigger = onVolatileTrigger || (async (entity, trigger, ids, cxtStr, option) => {
42
- const context = await this.contextBuilder(cxtStr);
43
- await context.begin();
42
+ const context = this.contextBuilder();
43
+ if (!context.getCurrentTxnId()) {
44
+ await context.begin();
45
+ }
46
+ await context.initialize(JSON.parse(cxtStr));
44
47
  try {
45
48
  await this.execVolatileTrigger(entity, trigger.name, ids, context, option);
46
49
  await context.commit();
47
50
  }
48
51
  catch (err) {
49
52
  await context.rollback();
50
- this.logger.error('error on volatile trigger', entity, trigger.name, ids.join(','), err);
53
+ if (!(err instanceof types_1.OakMakeSureByMySelfException)) {
54
+ this.logger.error('error on volatile trigger', entity, trigger.name, ids.join(','), err);
55
+ }
56
+ // throw err;
51
57
  }
52
58
  });
53
59
  }
@@ -271,8 +277,8 @@ class TriggerExecutor {
271
277
  }
272
278
  }
273
279
  const number = trigger.fn({ operation: operation }, context, option);
274
- if (number > 0) {
275
- this.logger.info(`触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
280
+ if (number > 0 && process.env.NODE_ENV === 'development') {
281
+ this.logger.info(`前触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
276
282
  }
277
283
  }
278
284
  (0, assert_1.default)(commitTriggers.length === 0, `前台不应有commitTrigger`);
@@ -294,8 +300,8 @@ class TriggerExecutor {
294
300
  }
295
301
  }
296
302
  const number = await trigger.fn({ operation: operation }, context, option);
297
- if (number > 0) {
298
- this.logger.info(`触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
303
+ if (number > 0 && process.env.NODE_ENV === 'development') {
304
+ this.logger.info(`前触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
299
305
  }
300
306
  return execPreTrigger(idx + 1);
301
307
  };
@@ -382,8 +388,8 @@ class TriggerExecutor {
382
388
  operation: operation,
383
389
  result: result,
384
390
  }, context, option);
385
- if (number > 0) {
386
- this.logger.info(`触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
391
+ if (number > 0 && process.env.NODE_ENV === 'development') {
392
+ this.logger.info(`后触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
387
393
  }
388
394
  }
389
395
  }
@@ -398,8 +404,8 @@ class TriggerExecutor {
398
404
  operation: operation,
399
405
  result: result,
400
406
  }, context, option);
401
- if (number > 0) {
402
- this.logger.info(`触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
407
+ if (number > 0 && process.env.NODE_ENV === 'development') {
408
+ this.logger.info(`后触发器「${trigger.name}」成功触发了「${number}」行数据更改`);
403
409
  }
404
410
  return execPostTrigger(idx + 1);
405
411
  };
@@ -441,7 +447,7 @@ class TriggerExecutor {
441
447
  $lt: timestamp,
442
448
  }
443
449
  };
444
- const context = await this.contextBuilder();
450
+ const context = this.contextBuilder();
445
451
  if (context.clusterInfo?.usingCluster) {
446
452
  const { instanceCount, instanceId } = context.clusterInfo;
447
453
  filter.$$seq$$ = {
@@ -46,7 +46,7 @@ function translateCheckerInAsyncContext(checker, schema) {
46
46
  case 'row': {
47
47
  const { filter, errMsg, inconsistentRows } = checker;
48
48
  const fn = (async ({ operation }, context, option) => {
49
- const { filter: operationFilter, data, action } = operation;
49
+ const { filter: operationFilter, data, action, bornAt } = operation;
50
50
  const filter2 = typeof filter === 'function' ? await filter(operation, context, option) : filter;
51
51
  if (['select', 'count', 'stat'].includes(action)) {
52
52
  operation.filter = (0, filter_1.combineFilters)(entity, context.getSchema(), [operationFilter, filter2]);
@@ -88,11 +88,11 @@ function translateCheckerInAsyncContext(checker, schema) {
88
88
  (0, assert_1.default)(data);
89
89
  if (data instanceof Array) {
90
90
  for (const d of data) {
91
- await checkSingle((0, filter_1.translateCreateDataToFilter)(schema, entity, d));
91
+ await checkSingle((0, filter_1.translateCreateDataToFilter)(schema, entity, d, !!bornAt));
92
92
  }
93
93
  }
94
94
  else {
95
- await checkSingle((0, filter_1.translateCreateDataToFilter)(schema, entity, data));
95
+ await checkSingle((0, filter_1.translateCreateDataToFilter)(schema, entity, data, !!bornAt));
96
96
  }
97
97
  return;
98
98
  }
@@ -139,7 +139,7 @@ function translateCheckerInSyncContext(checker, schema) {
139
139
  case 'row': {
140
140
  const { filter, errMsg, entity } = checker;
141
141
  const fn = (operation, context, option) => {
142
- const { filter: operationFilter, data, action } = operation;
142
+ const { filter: operationFilter, data, action, bornAt } = operation;
143
143
  const filter2 = typeof filter === 'function' ? filter(operation, context, option) : filter;
144
144
  let operationFilter2 = operationFilter;
145
145
  if (action === 'create') {
@@ -147,7 +147,7 @@ function translateCheckerInSyncContext(checker, schema) {
147
147
  // 前端的策略是,有data用data,无data用filter
148
148
  // 目前前端应该不可能制造出来createMultiple
149
149
  (0, assert_1.default)(!(data instanceof Array));
150
- operationFilter2 = (0, filter_1.translateCreateDataToFilter)(schema, entity, data);
150
+ operationFilter2 = (0, filter_1.translateCreateDataToFilter)(schema, entity, data, !!bornAt);
151
151
  }
152
152
  }
153
153
  (0, assert_1.default)(!(filter2 instanceof Promise));
@@ -2,8 +2,16 @@ import { EntityDict as BaseEntityDict, StorageSchema } from '../types';
2
2
  import { EntityDict } from "../base-app-domain";
3
3
  import { AsyncContext } from './AsyncRowStore';
4
4
  import { SyncContext } from './SyncRowStore';
5
- export declare function translateCreateDataToFilter<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(schema: StorageSchema<ED>, entity: T, data: ED[T]['CreateSingle']['data']): ED[T]["Selection"]["filter"];
5
+ export declare function translateCreateDataToFilter<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(schema: StorageSchema<ED>, entity: T, data: ED[T]['CreateSingle']['data'], allowUnrecoganized: boolean): ED[T]["Selection"]["filter"];
6
6
  export declare function combineFilters<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>, filters: Array<ED[T]['Selection']['filter']>, union?: true): ED[T]["Selection"]["filter"] | undefined;
7
+ type DeducedFilter<ED extends EntityDict & BaseEntityDict, T extends keyof ED> = {
8
+ entity: T;
9
+ filter: ED[T]['Selection']['filter'];
10
+ };
11
+ type DeducedFilterCombination<ED extends EntityDict & BaseEntityDict> = {
12
+ $or?: (DeducedFilterCombination<ED> | DeducedFilter<ED, keyof ED>)[];
13
+ $and?: (DeducedFilterCombination<ED> | DeducedFilter<ED, keyof ED>)[];
14
+ };
7
15
  /**
8
16
  * 在以下判断相容或相斥的过程中,相容/相斥的事实标准是:满足两个条件的查询集合是否被包容/互斥,但如果两个filter在逻辑上相容或者相斥,在事实上不一定相容或者相斥
9
17
  * 例如:{ a: 1 } 和 { a: { $ne: 1 } } 是明显不相容的查询,但如果数据为空集,则这两个查询并不能否定其相容
@@ -35,6 +43,44 @@ export declare function combineFilters<ED extends EntityDict & BaseEntityDict, T
35
43
  * @attention: 1)这里的测试不够充分,有些算子之间的相容或相斥可能有遗漏, 2)有新的算子加入需要修改代码
36
44
  */
37
45
  export declare function judgeValueRelation(value1: any, value2: any, contained: boolean): boolean | undefined;
46
+ /**
47
+ * 根据filter对compared查询的各个条件进行逐项分析
48
+ * @param entity
49
+ * @param schema
50
+ * @param filter
51
+ * @param compared
52
+ * @param contained
53
+ * @returns
54
+ * sureAttributes中包含被判定肯定相容或肯定不相斥的属性(不用再继续判定了)
55
+ * uncertainAttributes中包含的是无法判定结果的属性
56
+ * totalAndDeducedFilters包含的是判定过程中推论的相容的充分条件(and关系)
57
+ * totalOrDeducedFilters包含的是判定过程中推论的相斥的充分条件(or关系)
58
+ */
59
+ export declare function analyzeFilterRelation<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>, filter: NonNullable<ED[T]['Selection']['filter']>, compared: NonNullable<ED[T]['Selection']['filter']>, contained: boolean): boolean | {
60
+ totalAndDeducedFilters: (DeducedFilterCombination<ED> | DeducedFilter<ED, T>)[];
61
+ totalOrDeducedFilters: (DeducedFilterCombination<ED> | DeducedFilter<ED, T>)[];
62
+ uncertainAttributes: string[];
63
+ sureAttributes: string[];
64
+ };
65
+ /**
66
+ *
67
+ * 判断filter是否包含contained中的查询条件,即filter查询的结果一定是contained查询结果的子集
68
+ * filter = {
69
+ * a: 1
70
+ * b: 2,
71
+ * c: 3,
72
+ * },
73
+ * conditionalFilter = {
74
+ * a: 1
75
+ * }
76
+ * 则包含
77
+ * @param entity
78
+ * @param schema
79
+ * @param filter
80
+ * @param contained
81
+ * @returns
82
+ */
83
+ export declare function contains<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>, filter: ED[T]['Selection']['filter'], contained: ED[T]['Selection']['filter']): boolean | DeducedFilterCombination<ED>;
38
84
  /**
39
85
  * 从filter中判断是否有确定的id对象,如果有则返回这些id,没有返回空数组
40
86
  * @param filter
@@ -84,3 +130,4 @@ export declare function checkFilterRepel<ED extends EntityDict & BaseEntityDict,
84
130
  * @param filter
85
131
  */
86
132
  export declare function translateFilterToObjectPredicate(filter: Record<string, any>): {};
133
+ export {};
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.translateFilterToObjectPredicate = exports.checkFilterRepel = exports.checkFilterContains = exports.makeTreeDescendantFilter = exports.makeTreeAncestorFilter = exports.same = exports.getRelevantIds = exports.judgeValueRelation = exports.combineFilters = exports.translateCreateDataToFilter = void 0;
3
+ exports.translateFilterToObjectPredicate = exports.checkFilterRepel = exports.checkFilterContains = exports.makeTreeDescendantFilter = exports.makeTreeAncestorFilter = exports.same = exports.getRelevantIds = exports.contains = exports.analyzeFilterRelation = exports.judgeValueRelation = exports.combineFilters = exports.translateCreateDataToFilter = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const assert_1 = tslib_1.__importDefault(require("assert"));
6
6
  const types_1 = require("../types");
7
7
  const lodash_1 = require("../utils/lodash");
8
8
  const relation_1 = require("./relation");
9
- function translateCreateDataToFilter(schema, entity, data) {
9
+ function translateCreateDataToFilter(schema, entity, data, allowUnrecoganized) {
10
10
  const data2 = {};
11
11
  for (const attr in data) {
12
- const rel = (0, relation_1.judgeRelation)(schema, entity, attr);
12
+ const rel = (0, relation_1.judgeRelation)(schema, entity, attr, allowUnrecoganized);
13
13
  if (rel === 1) {
14
14
  // 只需要记住id和各种外键属性,不这样处理有些古怪的属性比如coordinate,其作为createdata和作为filter并不同构
15
15
  if (!['geometry', 'geography', 'st_geometry', 'st_point'].includes(schema[entity].attributes[attr]?.type)) {
@@ -43,9 +43,24 @@ function addFilterSegment(entity, schema, ...filters) {
43
43
  if (!filter[attr]) {
44
44
  filter[attr] = value;
45
45
  }
46
- // 只优化一种情况,就是两个都等值且相等
46
+ // 优化两个都等值且相等
47
47
  else if (filter[attr] === value) {
48
48
  }
49
+ // value定义的查询被当前查询包含
50
+ else if (contains(entity, schema, {
51
+ [attr]: value,
52
+ }, {
53
+ [attr]: filter[attr],
54
+ }) === true) {
55
+ filter[attr] = value;
56
+ }
57
+ // 当前查询被value所定义的查询包含
58
+ else if (contains(entity, schema, {
59
+ [attr]: filter[attr],
60
+ }, {
61
+ [attr]: value
62
+ }) == true) {
63
+ }
49
64
  else {
50
65
  addIntoAnd({
51
66
  [attr]: value,
@@ -1041,15 +1056,20 @@ function judgeFilterSingleAttrRelation(entity, schema, attr, filter, compared, c
1041
1056
  // 到这里说明无法直接判断此attr上的相容或者相斥,也无法把判定推断到更深层的算子之上
1042
1057
  return;
1043
1058
  }
1044
- /** 判断filter条件对compared条件是否相容或相斥
1059
+ /**
1060
+ * 根据filter对compared查询的各个条件进行逐项分析
1045
1061
  * @param entity
1046
1062
  * @param schema
1047
1063
  * @param filter
1048
1064
  * @param compared
1049
- * @param contained: true代表判定filter包容compared(filter的查询结果是compared查询结果的子集), false代表判定filter与compared相斥(filter的查询结果与compared没有交集)
1050
- * @returns 返回true说明肯定相容(相斥),返回false说明无法判定相容(相斥),返回DeducedFilterCombination说明需要进一步判断此推断的条件
1065
+ * @param contained
1066
+ * @returns
1067
+ * sureAttributes中包含被判定肯定相容或肯定不相斥的属性(不用再继续判定了)
1068
+ * uncertainAttributes中包含的是无法判定结果的属性
1069
+ * totalAndDeducedFilters包含的是判定过程中推论的相容的充分条件(and关系)
1070
+ * totalOrDeducedFilters包含的是判定过程中推论的相斥的充分条件(or关系)
1051
1071
  */
1052
- function judgeFilterRelation(entity, schema, filter, compared, contained) {
1072
+ function analyzeFilterRelation(entity, schema, filter, compared, contained) {
1053
1073
  const totalAndDeducedFilters = [];
1054
1074
  const totalOrDeducedFilters = [];
1055
1075
  const uncertainAttributes = [];
@@ -1239,6 +1259,28 @@ function judgeFilterRelation(entity, schema, filter, compared, contained) {
1239
1259
  }
1240
1260
  }
1241
1261
  }
1262
+ return {
1263
+ totalAndDeducedFilters,
1264
+ totalOrDeducedFilters,
1265
+ uncertainAttributes,
1266
+ sureAttributes,
1267
+ };
1268
+ }
1269
+ exports.analyzeFilterRelation = analyzeFilterRelation;
1270
+ /** 判断filter条件对compared条件是否相容或相斥
1271
+ * @param entity
1272
+ * @param schema
1273
+ * @param filter
1274
+ * @param compared
1275
+ * @param contained: true代表判定filter包容compared(filter的查询结果是compared查询结果的子集), false代表判定filter与compared相斥(filter的查询结果与compared没有交集)
1276
+ * @returns 返回true说明肯定相容(相斥),返回false说明无法判定相容(相斥),返回DeducedFilterCombination说明需要进一步判断此推断的条件
1277
+ */
1278
+ function judgeFilterRelation(entity, schema, filter, compared, contained) {
1279
+ const result = analyzeFilterRelation(entity, schema, filter, compared, contained);
1280
+ if (typeof result === 'boolean') {
1281
+ return result;
1282
+ }
1283
+ const { sureAttributes, uncertainAttributes, totalAndDeducedFilters, totalOrDeducedFilters, } = result;
1242
1284
  if (contained) {
1243
1285
  if (sureAttributes.length === Object.keys(compared).length) {
1244
1286
  return true;
@@ -1296,6 +1338,7 @@ function contains(entity, schema, filter, contained) {
1296
1338
  return judgeFilterRelation(entity, schema, filter, contained, true);
1297
1339
  // return false;
1298
1340
  }
1341
+ exports.contains = contains;
1299
1342
  /**
1300
1343
  * 判断filter1和filter2是否相斥,即filter1和filter2查询的结果一定没有交集
1301
1344
  * filter1 = {
@@ -8,7 +8,7 @@ export type ActionDef<A extends Action, S extends State> = {
8
8
  };
9
9
  is?: S;
10
10
  };
11
- export type ActionDictOfEntityDict<E extends EntityDict> = {
11
+ export type ActionDefDict<E extends EntityDict> = {
12
12
  [T in keyof E]?: {
13
13
  [A in keyof E[T]['OpSchema']]?: ActionDef<string, string>;
14
14
  };
@@ -1,25 +1,33 @@
1
+ import { AuthDeduceRelationMap, EntityDict } from './Entity';
2
+ import { EntityDict as BaseEntityDict } from "../base-app-domain";
3
+ import { AsyncContext } from '../store/AsyncRowStore';
4
+ import { SyncConfig } from "./Sync";
5
+ import { AttrUpdateMatrix } from './EntityDesc';
6
+ import { ActionDefDict } from './Action';
7
+ import { StyleDict } from './Style';
1
8
  /**
2
- * 后台环境配置
9
+ * 后台配置
3
10
  */
4
- export type ServerConfiguration = {
11
+ export type ServerConfiguration<ED extends BaseEntityDict & EntityDict, Cxt extends AsyncContext<ED>> = {
5
12
  database: {
6
13
  type: 'mysql';
7
14
  host: string;
8
15
  database: string;
9
- port: number;
16
+ port?: number;
10
17
  user: string;
11
18
  password?: string;
12
19
  connectionLimit: number;
13
20
  charset: "utf8mb4_general_ci";
14
21
  };
15
- http: {
16
- port: number;
22
+ workDir: {
23
+ path: string;
17
24
  };
25
+ sync?: SyncConfig<ED, Cxt>;
18
26
  };
19
27
  /**
20
- * 前后台共用的配置
28
+ * 前后台访问配置
21
29
  */
22
- export type ProjectConfiguration = {
30
+ export type AccessConfiguration = {
23
31
  routerPrefixes?: {
24
32
  aspect?: string;
25
33
  endpoint?: string;
@@ -27,6 +35,33 @@ export type ProjectConfiguration = {
27
35
  getSubscribePoint?: string;
28
36
  bridge?: string;
29
37
  };
38
+ http: {
39
+ hostname: string;
40
+ port?: number;
41
+ ssl?: boolean;
42
+ path?: string;
43
+ };
44
+ };
45
+ /**
46
+ * 业务逻辑的通用配置
47
+ */
48
+ export type CommonConfiguration<ED extends BaseEntityDict & EntityDict> = {
49
+ attrUpdateMatrix: AttrUpdateMatrix<ED>;
50
+ actionDefDict: ActionDefDict<ED>;
51
+ authDeduceRelationMap: AuthDeduceRelationMap<ED>;
52
+ selectFreeEntities?: (keyof ED)[];
53
+ updateFreeDict?: {
54
+ [A in keyof ED]?: string[];
55
+ };
56
+ cacheSavedEntities?: (keyof ED)[];
57
+ cacheKeepFreshPeriod?: number;
58
+ };
59
+ export type DependencyConfiguration = string[];
60
+ /**
61
+ * 渲染相关定义
62
+ */
63
+ export type RenderConfiguration<ED extends BaseEntityDict & EntityDict> = {
64
+ styleDict: StyleDict<ED>;
30
65
  };
31
66
  /**
32
67
  * 编译环境配置
@@ -1,3 +1,2 @@
1
1
  "use strict";
2
- // 将项目的所有配置规范化到一起(未完成)by Xc 20240207
3
2
  Object.defineProperty(exports, "__esModule", { value: true });
@@ -36,4 +36,7 @@ export interface Connector<ED extends EntityDict, FrontCxt extends SyncContext<E
36
36
  url: string;
37
37
  headers?: Record<string, string>;
38
38
  };
39
+ getFullData: (keys?: (keyof ED)[]) => Promise<{
40
+ [T in keyof ED]?: ED[T]['OpSchema'][];
41
+ }>;
39
42
  }
@@ -1,12 +1,19 @@
1
1
  import { LocaleDef } from './Locale';
2
2
  import { Index } from './Storage';
3
3
  import { EntityShape, Configuration, EntityDict } from './Entity';
4
- export type EntityDesc<Schema extends EntityShape, Action extends string = '', Relation extends string = '', V extends Record<string, string> = {}> = {
5
- locales: LocaleDef<Schema, Action, Relation, V>;
4
+ import { StyleDesc } from './Style';
5
+ export type EntityDesc<Schema extends EntityShape, Action extends string = '', Relation extends string = '', V extends Record<string, string> = {
6
+ ['##oak_illegal##']: '';
7
+ }> = {
8
+ locales: LocaleDef<Schema, Action, Relation, keyof V extends '##oak_illegal##' ? {} : V>;
6
9
  indexes?: Index<Schema>[];
7
10
  configuration?: Configuration;
8
11
  recursiveDepth?: number;
9
- };
12
+ } & (Action extends '' ? (keyof V extends '##oak_illegal##' ? {} : {
13
+ style: StyleDesc<Action, V>;
14
+ }) : {
15
+ style: StyleDesc<Action, V>;
16
+ });
10
17
  export type AttrUpdateMatrix<ED extends EntityDict> = {
11
18
  [T in keyof ED]?: {
12
19
  [A in keyof ED[T]['Update']['data']]?: {
@@ -1,11 +1,40 @@
1
- import { EntityDict } from './Entity';
1
+ import { EntityDict, GeneralEntityShape } from './Entity';
2
2
  import { EntityDict as BaseEntityDict } from '../base-app-domain';
3
- type ThemeColor = 'default' | 'success' | 'warning' | 'error' | 'primary' | 'danger';
4
- export type ColorDict<ED extends BaseEntityDict & EntityDict> = {
5
- [T in keyof ED]?: {
6
- [A in keyof ED[T]['OpSchema']]?: {
7
- [E in ED[T]['OpSchema'][A]]?: ThemeColor | `#${string}`;
3
+ type Color = `#${string}`;
4
+ type IconName = string;
5
+ export type StyleDesc<Action extends string = '', V extends Record<string, string> = {
6
+ ['##oak_illegal##']: '';
7
+ }> = Action extends '' ? (keyof V extends '##oak_illegal##' ? {} : {
8
+ color: {
9
+ [A in keyof V]: {
10
+ [E in V[A]]: Color;
8
11
  };
9
12
  };
13
+ }) : (keyof V extends '##oak_illegal##' ? {
14
+ icon: {
15
+ [A in Action]?: IconName;
16
+ };
17
+ } : {
18
+ icon: {
19
+ [A in Action]?: IconName;
20
+ };
21
+ color: {
22
+ [A in keyof V]: {
23
+ [E in V[A]]: Color;
24
+ };
25
+ };
26
+ });
27
+ export type StyleDef<ED extends GeneralEntityShape, Action extends string> = {
28
+ color?: {
29
+ [A in keyof ED]?: {
30
+ [E in ED[A]]?: Color;
31
+ };
32
+ };
33
+ icon?: {
34
+ [A in Action]?: IconName;
35
+ };
36
+ };
37
+ export type StyleDict<ED extends BaseEntityDict & EntityDict> = {
38
+ [T in keyof ED]?: StyleDef<ED[T]['OpSchema'], ED[T]['Action']>;
10
39
  };
11
40
  export {};
@@ -2,24 +2,20 @@
2
2
  import { IncomingHttpHeaders } from "http";
3
3
  import { SyncContext } from '../store/SyncRowStore';
4
4
  import { Connector, EntityDict, OakException, OpRecord } from "../types";
5
- type ServerOption = {
6
- protocol: string;
7
- hostname: string;
8
- port?: number;
9
- apiPath?: string;
10
- };
11
- export declare class SimpleConnector<ED extends EntityDict, FrontCxt extends SyncContext<ED>> implements Connector<ED, FrontCxt> {
5
+ import { AccessConfiguration } from '../types/Configuration';
6
+ export default class SimpleConnector<ED extends EntityDict, FrontCxt extends SyncContext<ED>> implements Connector<ED, FrontCxt> {
12
7
  static ASPECT_ROUTER: string;
13
8
  static BRIDGE_ROUTER: string;
14
9
  static SUBSCRIBE_ROUTER: string;
15
10
  static SUBSCRIBE_POINT_ROUTER: string;
16
11
  static ENDPOINT_ROUTER: string;
12
+ private serverUrl;
17
13
  private serverAspectUrl;
18
14
  private serverBridgeUrl;
19
15
  private serverSubscribePointUrl;
20
- private option;
16
+ private configuration;
21
17
  private makeException;
22
- constructor(option: ServerOption, makeException: (exceptionData: any) => OakException<ED>);
18
+ constructor(configuration: AccessConfiguration, makeException: (exceptionData: any) => OakException<ED>);
23
19
  protected makeHeadersAndBody(name: string, data: any, context?: FrontCxt): Promise<{
24
20
  headers: Record<string, string>;
25
21
  body: FormData;
@@ -77,5 +73,5 @@ export declare class SimpleConnector<ED extends EntityDict, FrontCxt extends Syn
77
73
  url: string;
78
74
  headers?: Record<string, string> | undefined;
79
75
  };
76
+ getFullData(): Promise<{}>;
80
77
  }
81
- export {};
@@ -1,6 +1,5 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.SimpleConnector = void 0;
4
3
  const tslib_1 = require("tslib");
5
4
  const assert_1 = tslib_1.__importDefault(require("assert"));
6
5
  const stream_1 = require("stream");
@@ -12,25 +11,34 @@ class SimpleConnector {
12
11
  static SUBSCRIBE_ROUTER = process.env.OAK_SUBSCRIBE_ROUTER || '/subscribe';
13
12
  static SUBSCRIBE_POINT_ROUTER = '/subscribePoint';
14
13
  static ENDPOINT_ROUTER = '/endpoint';
14
+ serverUrl;
15
15
  serverAspectUrl;
16
16
  serverBridgeUrl;
17
17
  serverSubscribePointUrl;
18
- option;
18
+ configuration;
19
19
  makeException;
20
- constructor(option, makeException) {
21
- this.option = option;
22
- const { protocol, hostname, port, apiPath } = option;
20
+ constructor(configuration, makeException) {
21
+ this.configuration = configuration;
22
+ const { routerPrefixes, http } = configuration;
23
+ const { ssl, hostname, port, path } = http;
24
+ const protocol = ssl ? 'https:' : 'http:';
23
25
  let serverUrl = `${protocol}//${hostname}`;
26
+ this.serverUrl = serverUrl;
24
27
  if (typeof port === 'number') {
25
28
  serverUrl += `:${port}`;
26
29
  }
27
- if (apiPath) {
28
- (0, assert_1.default)(apiPath.startsWith('/'), 'apiPath前缀必须存在/');
29
- serverUrl += apiPath;
30
+ if (path) {
31
+ if (path.startsWith('/')) {
32
+ serverUrl += path;
33
+ }
34
+ else {
35
+ serverUrl += `/${path}`;
36
+ }
30
37
  }
31
- this.serverAspectUrl = `${serverUrl}${SimpleConnector.ASPECT_ROUTER}`;
32
- this.serverBridgeUrl = `${serverUrl}${SimpleConnector.BRIDGE_ROUTER}`;
33
- this.serverSubscribePointUrl = `${serverUrl}${SimpleConnector.SUBSCRIBE_POINT_ROUTER}`;
38
+ this.serverAspectUrl = `${serverUrl}${routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER}`;
39
+ this.serverBridgeUrl = `${serverUrl}${routerPrefixes?.bridge || SimpleConnector.BRIDGE_ROUTER}`;
40
+ this.serverSubscribePointUrl = `${serverUrl}${routerPrefixes?.getSubscribePoint ||
41
+ SimpleConnector.SUBSCRIBE_POINT_ROUTER}`;
34
42
  this.makeException = makeException;
35
43
  }
36
44
  async makeHeadersAndBody(name, data, context) {
@@ -100,18 +108,18 @@ class SimpleConnector {
100
108
  }
101
109
  catch (err) {
102
110
  // fetch返回异常一定是网络异常
103
- throw new types_1.OakNetworkException(`请求[${this.serverAspectUrl}],发生网络异常`);
111
+ throw new types_1.OakNetworkException(`接口请求时发生网络异常`);
104
112
  }
105
113
  return this.parseAspectResult(response);
106
114
  }
107
115
  getRouter() {
108
- return SimpleConnector.ASPECT_ROUTER;
116
+ return this.configuration.routerPrefixes?.aspect || SimpleConnector.ASPECT_ROUTER;
109
117
  }
110
118
  getSubscribeRouter() {
111
- return SimpleConnector.SUBSCRIBE_ROUTER;
119
+ return this.configuration.routerPrefixes?.subscribe || SimpleConnector.SUBSCRIBE_ROUTER;
112
120
  }
113
121
  getSubscribePointRouter() {
114
- return SimpleConnector.SUBSCRIBE_POINT_ROUTER;
122
+ return this.configuration.routerPrefixes?.getSubscribePoint || SimpleConnector.SUBSCRIBE_POINT_ROUTER;
115
123
  }
116
124
  async getSubscribePoint() {
117
125
  let response;
@@ -130,9 +138,10 @@ class SimpleConnector {
130
138
  response.headers.get('content-type');
131
139
  if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
132
140
  const { url, path, port, namespace } = await response.json();
133
- let url2 = url || `${this.option.protocol}//${this.option.hostname}`;
134
- (0, assert_1.default)(port);
135
- url2 += `:${port}`;
141
+ let url2 = url || this.serverUrl;
142
+ if (port) {
143
+ url2 += `:${port}`;
144
+ }
136
145
  if (namespace) {
137
146
  url2 += namespace;
138
147
  }
@@ -146,7 +155,7 @@ class SimpleConnector {
146
155
  }
147
156
  }
148
157
  getEndpointRouter() {
149
- return SimpleConnector.ENDPOINT_ROUTER;
158
+ return this.configuration.routerPrefixes?.endpoint || SimpleConnector.ENDPOINT_ROUTER;
150
159
  }
151
160
  parseRequest(headers, body, files) {
152
161
  const { 'oak-cxt': oakCxtStr, 'oak-aspect': aspectName } = headers;
@@ -213,5 +222,9 @@ class SimpleConnector {
213
222
  headers: headers && JSON.parse(headers),
214
223
  };
215
224
  }
225
+ async getFullData() {
226
+ console.error('前后台模式下暂时不支持此操作,请到数据库查看数据');
227
+ return {};
228
+ }
216
229
  }
217
- exports.SimpleConnector = SimpleConnector;
230
+ exports.default = SimpleConnector;
@@ -12,6 +12,7 @@ import intersection from 'lodash/intersection';
12
12
  import intersectionBy from 'lodash/intersectionBy';
13
13
  import omit from 'lodash/omit';
14
14
  import merge from 'lodash/merge';
15
+ import mergeWith from 'lodash/mergeWith';
15
16
  import cloneDeep from 'lodash/cloneDeep';
16
17
  import pick from 'lodash/pick';
17
18
  import isEqual from 'lodash/isEqual';
@@ -21,4 +22,12 @@ import differenceBy from 'lodash/differenceBy';
21
22
  import groupBy from 'lodash/groupBy';
22
23
  import unionBy from 'lodash/unionBy';
23
24
  import pullAll from 'lodash/pullAll';
24
- export { unset, pull, uniq, uniqBy, get, set, intersection, intersectionBy, omit, merge, cloneDeep, pick, isEqual, union, difference, differenceBy, groupBy, unionBy, pullAll, };
25
+ /**
26
+ * merge两个对象,遇到array时使用连接合并
27
+ * @param object
28
+ * @param source
29
+ * @returns
30
+ */
31
+ declare function mergeConcatArray(object: any, source: any): any;
32
+ declare function mergeConcatMany<T>(array: Array<T>): T;
33
+ export { unset, pull, uniq, uniqBy, get, set, intersection, intersectionBy, omit, merge, mergeWith, mergeConcatArray, mergeConcatMany, cloneDeep, pick, isEqual, union, difference, differenceBy, groupBy, unionBy, pullAll, };