oak-domain 5.0.18 → 5.0.20

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.
@@ -100,8 +100,9 @@ function makeWebAllRouters(namespaceDir, projectDir, routerFileDir) {
100
100
  const nsIndexJsonFile = (0, path_1.join)(namespaceDir, ns, 'index.json');
101
101
  let path2 = `/${ns}`;
102
102
  let notFound2 = '', first2 = '';
103
+ let params2 = {};
103
104
  if ((0, fs_extra_1.existsSync)(nsIndexJsonFile)) {
104
- const { path, notFound, first } = require(nsIndexJsonFile);
105
+ const { path, notFound, first, params } = require(nsIndexJsonFile);
105
106
  if (path) {
106
107
  path2 = path.replace(/\\/g, '/');
107
108
  }
@@ -114,11 +115,19 @@ function makeWebAllRouters(namespaceDir, projectDir, routerFileDir) {
114
115
  first2 = first2.slice(1);
115
116
  }
116
117
  }
118
+ if (params) {
119
+ params2 = params;
120
+ }
117
121
  }
118
122
  let firstPage;
119
123
  const children = Object.values(pages).filter((ele) => ele.hasWeb).map(({ path, oakDisablePulldownRefresh }) => {
124
+ let path2 = path;
125
+ if (params2[path]) {
126
+ // 如果有参数,接在path后面
127
+ path2 += path2 ? `/:${params2[path]}` : `:${params2[path]}`;
128
+ }
120
129
  const properties = [
121
- factory.createPropertyAssignment('path', factory.createStringLiteral(path)),
130
+ factory.createPropertyAssignment('path', factory.createStringLiteral(path2)),
122
131
  factory.createPropertyAssignment('namespace', factory.createStringLiteral(ns)),
123
132
  factory.createPropertyAssignment('meta', factory.createObjectLiteralExpression([
124
133
  factory.createPropertyAssignment('oakDisablePulldownRefresh', oakDisablePulldownRefresh ? factory.createTrue() : factory.createFalse())
@@ -1229,7 +1229,12 @@ class CascadeStore extends RowStore_1.RowStore {
1229
1229
  // 变成对modi的插入
1230
1230
  // 优化,这里如果是对同一个targetEntity反复update,则变成对最后一条create/update的modi进行update,以避免发布文章这样的需求时产生过多的modi
1231
1231
  let modiUpsert;
1232
- if (action !== 'remove') {
1232
+ if (action === 'update') {
1233
+ // 如果action本身是update,且没有实际update属性,这里可以忽略
1234
+ const updateAttrCount = Object.keys(data).length;
1235
+ if (updateAttrCount === 0) {
1236
+ return {};
1237
+ }
1233
1238
  const upsertModis = await this.selectAbjointRowAsync('modi', {
1234
1239
  data: {
1235
1240
  id: 1,
@@ -79,7 +79,7 @@ function createUniqueCheckers(schema) {
79
79
  entity,
80
80
  action: 'create',
81
81
  type: 'logicalData',
82
- priority: types_1.CHECKER_MAX_PRIORITY,
82
+ priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
83
83
  checker: (operation, context) => {
84
84
  const { data } = operation;
85
85
  if (data instanceof Array) {
@@ -95,9 +95,9 @@ function createUniqueCheckers(schema) {
95
95
  }
96
96
  }, {
97
97
  entity,
98
- action: 'update',
98
+ action: 'update', // 只检查update,其它状态转换的action应该不会涉及unique约束的属性
99
99
  type: 'logicalData',
100
- priority: types_1.CHECKER_MAX_PRIORITY,
100
+ priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
101
101
  checker: (operation, context) => {
102
102
  const { data, filter: operationFilter } = operation;
103
103
  if (data) {
@@ -227,7 +227,7 @@ function createActionTransformerCheckers(actionDefDict) {
227
227
  action: 'create',
228
228
  type: 'logical',
229
229
  entity,
230
- priority: 10,
230
+ priority: 10, // 优先级要高,先于真正的data检查进行
231
231
  checker: (operation) => {
232
232
  const { data } = operation;
233
233
  if (data instanceof Array) {
@@ -39,4 +39,12 @@ export declare class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt
39
39
  action: 'select';
40
40
  }, context: Cxt, option: OperateOption | SelectOption, result?: Partial<ED[T]['Schema']>[]): Promise<void> | void;
41
41
  checkpoint(timestamp: number): Promise<number>;
42
+ /**
43
+ * 由外部来控制进行按volatileTrigger逐个进行checkpoint
44
+ * @param name
45
+ * @param timestamp
46
+ * @param instanceCount
47
+ * @param instanceId
48
+ */
49
+ independentCheckPoint(name: string, timestamp: number, instanceCount?: number, instanceId?: number): Promise<number>;
42
50
  }
@@ -49,8 +49,12 @@ class TriggerExecutor {
49
49
  await context.commit();
50
50
  }
51
51
  catch (err) {
52
- await context.rollback();
53
- if (!(err instanceof types_1.OakMakeSureByMySelfException)) {
52
+ if (!(err instanceof types_1.OakPartialSuccess)) {
53
+ await context.rollback();
54
+ this.logger.error('error on volatile trigger', entity, trigger.name, ids.join(','), err);
55
+ }
56
+ else {
57
+ await context.commit();
54
58
  this.logger.error('error on volatile trigger', entity, trigger.name, ids.join(','), err);
55
59
  }
56
60
  // throw err;
@@ -363,6 +367,12 @@ class TriggerExecutor {
363
367
  filter: {
364
368
  id: {
365
369
  $in: ids,
370
+ },
371
+ [Entity_1.TriggerDataAttribute]: {
372
+ $exists: true,
373
+ },
374
+ [Entity_1.TriggerUuidAttribute]: {
375
+ $exists: true,
366
376
  }
367
377
  }
368
378
  }, { includedDeleted: true, blockTrigger: true });
@@ -473,10 +483,6 @@ class TriggerExecutor {
473
483
  async checkpoint(timestamp) {
474
484
  let result = 0;
475
485
  for (const entity of this.volatileEntities) {
476
- if (entity === 'oper') {
477
- // oper上的跨事务同步是系统synchronizer统一处理
478
- continue;
479
- }
480
486
  const filter = {
481
487
  [Entity_1.TriggerUuidAttribute]: {
482
488
  $exists: true,
@@ -486,12 +492,6 @@ class TriggerExecutor {
486
492
  }
487
493
  };
488
494
  const context = this.contextBuilder();
489
- if (context.clusterInfo?.usingCluster) {
490
- const { instanceCount, instanceId } = context.clusterInfo;
491
- filter.$$seq$$ = {
492
- $mod: [instanceCount, instanceId],
493
- };
494
- }
495
495
  await context.begin();
496
496
  try {
497
497
  const rows = await context.select(entity, {
@@ -532,15 +532,108 @@ class TriggerExecutor {
532
532
  }
533
533
  }
534
534
  await context.commit();
535
+ result += rows.length;
535
536
  }
536
537
  catch (err) {
537
- await context.rollback();
538
- if (!(err instanceof types_1.OakMakeSureByMySelfException)) {
539
- this.logger.error(`执行checkpoint时出错,对象是「${entity}」,异常是`, err);
538
+ if (!(err instanceof types_1.OakPartialSuccess)) {
539
+ await context.rollback();
540
+ this.logger.error(`error in checkpoint on entity 「${entity}」`, err);
541
+ }
542
+ else {
543
+ await context.commit();
544
+ this.logger.error(`error in checkpoint on entity 「${entity}」`, err);
540
545
  }
541
546
  }
542
547
  }
543
548
  return result;
544
549
  }
550
+ /**
551
+ * 由外部来控制进行按volatileTrigger逐个进行checkpoint
552
+ * @param name
553
+ * @param timestamp
554
+ * @param instanceCount
555
+ * @param instanceId
556
+ */
557
+ async independentCheckPoint(name, timestamp, instanceCount, instanceId) {
558
+ const trigger = this.triggerNameMap[name];
559
+ (0, assert_1.default)(trigger && trigger.when === 'commit');
560
+ const { fn, entity, grouped } = trigger;
561
+ const filter = {
562
+ [Entity_1.TriggerDataAttribute]: {
563
+ name,
564
+ },
565
+ [Entity_1.TriggerUuidAttribute]: {
566
+ $exists: true,
567
+ },
568
+ [Entity_1.UpdateAtAttribute]: {
569
+ $lt: timestamp,
570
+ },
571
+ };
572
+ if (instanceCount) {
573
+ filter.$$seq$$ = {
574
+ $mod: [instanceCount, instanceId]
575
+ };
576
+ }
577
+ const context = this.contextBuilder();
578
+ await context.begin();
579
+ try {
580
+ const rows = await context.select(entity, {
581
+ data: {
582
+ id: 1,
583
+ },
584
+ filter,
585
+ }, {
586
+ includedDeleted: true,
587
+ dontCollect: true,
588
+ });
589
+ if (rows.length > 0) {
590
+ // 要用id来再锁一次,不然会锁住filter的范围,影响并发性
591
+ // by Xc 20240314,在haina-busi和haina-cn数据sync过程中发现这个问题
592
+ const rows2 = await context.select(entity, {
593
+ data: {
594
+ id: 1,
595
+ [Entity_1.TriggerDataAttribute]: 1,
596
+ [Entity_1.TriggerUuidAttribute]: 1,
597
+ },
598
+ filter: {
599
+ id: {
600
+ $in: rows.map(ele => ele.id),
601
+ },
602
+ },
603
+ }, {
604
+ includedDeleted: true,
605
+ dontCollect: true,
606
+ forUpdate: 'skip locked', // 如果加不上锁就下次再处理,或者有可能应用自己在处理
607
+ });
608
+ if (grouped) {
609
+ // grouped不需要上下文了吧,内部一定会用root
610
+ await this.execVolatileTrigger(entity, name, rows.map(ele => ele.id), context, {});
611
+ }
612
+ else {
613
+ const groupedRowDict = (0, lodash_1.groupBy)(rows2, Entity_1.TriggerUuidAttribute);
614
+ for (const uuid in groupedRowDict) {
615
+ const rs = groupedRowDict[uuid];
616
+ const { [Entity_1.TriggerDataAttribute]: triggerData } = rs[0];
617
+ const { cxtStr, option } = triggerData;
618
+ await context.initialize(JSON.parse(cxtStr), true);
619
+ await this.execVolatileTrigger(entity, name, rs.map(ele => ele.id), context, option);
620
+ }
621
+ }
622
+ }
623
+ await context.commit();
624
+ return rows.length;
625
+ }
626
+ catch (err) {
627
+ if (!(err instanceof types_1.OakPartialSuccess)) {
628
+ await context.rollback();
629
+ this.logger.error('error on volatile trigger', entity, trigger.name, err);
630
+ }
631
+ else {
632
+ await context.commit();
633
+ this.logger.error('error on volatile trigger', entity, trigger.name, err);
634
+ }
635
+ return 0;
636
+ }
637
+ }
545
638
  }
546
639
  exports.TriggerExecutor = TriggerExecutor;
@@ -21,6 +21,8 @@ export declare class OakException<ED extends EntityDict & BaseEntityDict> extend
21
21
  }
22
22
  export declare class OakMakeSureByMySelfException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
23
23
  }
24
+ export declare class OakPartialSuccess<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
25
+ }
24
26
  export declare class OakDataException<ED extends EntityDict & BaseEntityDict> extends OakException<ED> {
25
27
  }
26
28
  export declare class OakNoRelationDefException<ED extends EntityDict & BaseEntityDict, T extends keyof ED> extends OakDataException<ED> {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakMakeSureByMySelfException = exports.OakException = void 0;
3
+ exports.makeException = exports.OakExternalException = exports.OakPreConditionUnsetException = exports.OakDeadlock = exports.OakCongruentRowExists = exports.OakRowLockedException = exports.OakUnloggedInException = exports.OakUserInvisibleException = exports.OakUserUnpermittedException = exports.OakAttrCantUpdateException = exports.OakAttrNotNullException = exports.OakInputIllegalException = exports.OakRowInconsistencyException = exports.OakServerProxyException = exports.OakNetworkException = exports.OakImportDataParseException = exports.OakUniqueViolationException = exports.OakUserException = exports.OakRowUnexistedException = exports.OakOperExistedException = exports.OakNoRelationDefException = exports.OakDataException = exports.OakPartialSuccess = exports.OakMakeSureByMySelfException = exports.OakException = void 0;
4
4
  const relation_1 = require("../store/relation");
5
5
  const lodash_1 = require("../utils/lodash");
6
6
  class OakException extends Error {
@@ -90,10 +90,14 @@ class OakException extends Error {
90
90
  tag3;
91
91
  }
92
92
  exports.OakException = OakException;
93
- // 这个异常表示模块自己处理跨事务一致性,框架pass(在分布式数据传递时会用到)
93
+ // 这个异常表示模块自己处理跨事务一致性,框架pass(在分布式数据传递时会用到)(backend-base老版本有使用先保留)
94
94
  class OakMakeSureByMySelfException extends OakException {
95
95
  }
96
96
  exports.OakMakeSureByMySelfException = OakMakeSureByMySelfException;
97
+ // 这个异常表示事务虽然没有完全成功,但是仍然应该提交并抛出异常(在分布式数据传递时会用到)
98
+ class OakPartialSuccess extends OakException {
99
+ }
100
+ exports.OakPartialSuccess = OakPartialSuccess;
97
101
  class OakDataException extends OakException {
98
102
  }
99
103
  exports.OakDataException = OakDataException;
@@ -12,6 +12,7 @@ export type FreeTimer<ED extends EntityDict, Cxt extends AsyncContext<ED>> = {
12
12
  name: string;
13
13
  cron: RecurrenceRule | RecurrenceSpecDateRange | RecurrenceSpecObjLit | Date | string | number;
14
14
  timer: FreeOperateFn<ED, Cxt>;
15
+ singleton?: true;
15
16
  };
16
17
  export type Routine<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> = FreeRoutine<ED, Cxt> | Watcher<ED, T, Cxt>;
17
18
  export type Timer<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> = FreeTimer<ED, Cxt> | Watcher<ED, T, Cxt> & {
@@ -39,6 +39,8 @@ interface TriggerCrossTxn<ED extends EntityDict, Cxt extends AsyncContext<ED> |
39
39
  when: 'commit';
40
40
  strict?: 'takeEasy' | 'makeSure';
41
41
  cs?: true;
42
+ singleton?: true;
43
+ grouped?: true;
42
44
  fn: (event: {
43
45
  ids: string[];
44
46
  }, context: Cxt, option: OperateOption) => Promise<((context: Cxt, option: OperateOption) => Promise<any>) | void>;
@@ -8,6 +8,7 @@ export interface BBWatcher<ED extends EntityDict, T extends keyof ED> {
8
8
  filter: ED[T]['Selection']['filter'] | (() => ED[T]['Selection']['filter']);
9
9
  action: Omit<ED[T]['Action'], 'create' | ReadOnlyAction>;
10
10
  actionData: ActionData<ED, T> | (() => Promise<ActionData<ED, T>>);
11
+ singleton?: true;
11
12
  }
12
13
  export interface WBWatcher<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> {
13
14
  name: string;
@@ -15,6 +16,7 @@ export interface WBWatcher<ED extends EntityDict, T extends keyof ED, Cxt extend
15
16
  filter: ED[T]['Selection']['filter'] | (() => Promise<ED[T]['Selection']['filter']>);
16
17
  projection: ED[T]['Selection']['data'] | (() => Promise<ED[T]['Selection']['data']>);
17
18
  fn: (context: Cxt, data: Partial<ED[T]['Schema']>[]) => Promise<OperationResult<ED>>;
19
+ singleton?: true;
18
20
  }
19
21
  export type Watcher<ED extends EntityDict, T extends keyof ED, Cxt extends AsyncContext<ED>> = BBWatcher<ED, T> | WBWatcher<ED, T, Cxt>;
20
22
  export {};
@@ -1,3 +1,4 @@
1
+ /// <reference types="node" />
1
2
  /**
2
3
  * 防止assert打包体积过大,从这里引用
3
4
  */
@@ -60,7 +60,7 @@ function destructRelationPath(schema, entity, path, relationFilter, recursive) {
60
60
  },
61
61
  filter: relationFilter,
62
62
  } // as ED['userRelation']['Selection']
63
- },
63
+ }, // as ED[keyof ED]['Selection']['data'],
64
64
  getData: (d) => {
65
65
  return d.userRelation$entity;
66
66
  },
@@ -13,8 +13,10 @@ const isPassword = (text) => {
13
13
  return ((text) && (typeof text === "string") && (/^[a-zA-Z0-9!.@]{8,16}$/.test(text)));
14
14
  };
15
15
  exports.isPassword = isPassword;
16
- const isCaptcha = (text) => {
17
- return ((text) && (typeof text === "string") && (/^\d{4}$/.test(text)));
16
+ const isCaptcha = (text, num) => {
17
+ const n = num || 4;
18
+ const regex = new RegExp(`^\\d{${n}}$`);
19
+ return ((text) && (typeof text === "string") && (regex.test(text)));
18
20
  };
19
21
  exports.isCaptcha = isCaptcha;
20
22
  const isIdCardNumber = (text) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oak-domain",
3
- "version": "5.0.18",
3
+ "version": "5.0.20",
4
4
  "author": {
5
5
  "name": "XuChang"
6
6
  },
@@ -1,26 +1,26 @@
1
- import { String } from '../types/DataType';
2
- import { EntityShape } from '../types/Entity';
3
- import { Schema as Modi } from './Modi';
4
- import { EntityDesc } from '../types/EntityDesc';
5
-
6
- export interface Schema extends EntityShape {
7
- modi: Modi,
8
- entity: String<32>;
9
- entityId: String<64>;
10
- };
11
-
12
- const entityDesc: EntityDesc<Schema> = {
13
- locales: {
14
- zh_CN: {
15
- name: '更新对象连接',
16
- attr: {
17
- modi: '更新',
18
- entity: '关联对象',
19
- entityId: '关联对象id',
20
- },
21
- },
22
- },
23
- configuration: {
24
- actionType: 'appendOnly',
25
- }
26
- };
1
+ import { String } from '../types/DataType';
2
+ import { EntityShape } from '../types/Entity';
3
+ import { Schema as Modi } from './Modi';
4
+ import { EntityDesc } from '../types/EntityDesc';
5
+
6
+ export interface Schema extends EntityShape {
7
+ modi: Modi,
8
+ entity: String<32>;
9
+ entityId: String<64>;
10
+ };
11
+
12
+ const entityDesc: EntityDesc<Schema> = {
13
+ locales: {
14
+ zh_CN: {
15
+ name: '更新对象连接',
16
+ attr: {
17
+ modi: '更新',
18
+ entity: '关联对象',
19
+ entityId: '关联对象id',
20
+ },
21
+ },
22
+ },
23
+ configuration: {
24
+ actionType: 'appendOnly',
25
+ }
26
+ };
@@ -1,27 +1,27 @@
1
- import { String } from '../types/DataType';
2
- import { EntityShape, Configuration } from '../types/Entity';
3
- import { LocaleDef } from '../types/Locale';
4
- import { Schema as Oper } from './Oper';
5
- import { EntityDesc } from '../types/EntityDesc';
6
-
7
- export interface Schema extends EntityShape {
8
- oper: Oper,
9
- entity: String<32>;
10
- entityId: String<64>;
11
- };
12
-
13
- const entityDesc: EntityDesc<Schema> = {
14
- locales: {
15
- zh_CN: {
16
- name: '操作对象连接',
17
- attr: {
18
- oper: '操作',
19
- entity: '关联对象',
20
- entityId: '关联对象id',
21
- },
22
- },
23
- },
24
- configuration: {
25
- actionType: 'appendOnly',
26
- }
27
- };
1
+ import { String } from '../types/DataType';
2
+ import { EntityShape, Configuration } from '../types/Entity';
3
+ import { LocaleDef } from '../types/Locale';
4
+ import { Schema as Oper } from './Oper';
5
+ import { EntityDesc } from '../types/EntityDesc';
6
+
7
+ export interface Schema extends EntityShape {
8
+ oper: Oper,
9
+ entity: String<32>;
10
+ entityId: String<64>;
11
+ };
12
+
13
+ const entityDesc: EntityDesc<Schema> = {
14
+ locales: {
15
+ zh_CN: {
16
+ name: '操作对象连接',
17
+ attr: {
18
+ oper: '操作',
19
+ entity: '关联对象',
20
+ entityId: '关联对象id',
21
+ },
22
+ },
23
+ },
24
+ configuration: {
25
+ actionType: 'appendOnly',
26
+ }
27
+ };
@@ -1,43 +1,43 @@
1
- import { String } from '../types/DataType';
2
- import { EntityShape } from '../types/Entity';
3
- import { EntityDesc } from '../types/EntityDesc';
4
-
5
- export interface Schema extends EntityShape {
6
- entity: String<32>;
7
- entityId?: String<64>; // 可以为空
8
- name?: String<32>;
9
- display?: String<32>;
10
- };
11
-
12
- const entityDesc: EntityDesc<Schema> = {
13
- locales: {
14
- zh_CN: {
15
- name: '用户授权',
16
- attr: {
17
- name: '关系',
18
- entity: '目标对象',
19
- entityId: '目标对象id',
20
- display: '显示值',
21
- },
22
- },
23
- },
24
- indexes: [
25
- {
26
- name: 'index_targetEntity_entityId_name',
27
- attributes: [
28
- {
29
- name: 'entity',
30
- },
31
- {
32
- name: 'entityId',
33
- },
34
- {
35
- name: 'name',
36
- }
37
- ],
38
- config: {
39
- unique: true,
40
- },
41
- },
42
- ]
43
- };
1
+ import { String } from '../types/DataType';
2
+ import { EntityShape } from '../types/Entity';
3
+ import { EntityDesc } from '../types/EntityDesc';
4
+
5
+ export interface Schema extends EntityShape {
6
+ entity: String<32>;
7
+ entityId?: String<64>; // 可以为空
8
+ name?: String<32>;
9
+ display?: String<32>;
10
+ };
11
+
12
+ const entityDesc: EntityDesc<Schema> = {
13
+ locales: {
14
+ zh_CN: {
15
+ name: '用户授权',
16
+ attr: {
17
+ name: '关系',
18
+ entity: '目标对象',
19
+ entityId: '目标对象id',
20
+ display: '显示值',
21
+ },
22
+ },
23
+ },
24
+ indexes: [
25
+ {
26
+ name: 'index_targetEntity_entityId_name',
27
+ attributes: [
28
+ {
29
+ name: 'entity',
30
+ },
31
+ {
32
+ name: 'entityId',
33
+ },
34
+ {
35
+ name: 'name',
36
+ }
37
+ ],
38
+ config: {
39
+ unique: true,
40
+ },
41
+ },
42
+ ]
43
+ };
@@ -1,30 +1,30 @@
1
- import { String } from '../types/DataType';
2
- import { EntityShape } from '../types/Entity';
3
- import { EntityDesc } from '../types/EntityDesc';
4
- import { Schema as UserEntityGrant } from './UserEntityGrant';
5
- import { Schema as User } from './User';
6
- import { Schema as Relation } from './Relation';
7
- import { Schema as UserRelation } from './UserRelation';
8
-
9
- export interface Schema extends EntityShape {
10
- ueg: UserEntityGrant;
11
- user: User;
12
- relation: Relation;
13
- claimEntityId: String<64>;
14
- userRelation: UserRelation;
15
- };
16
-
17
- const entityDesc: EntityDesc<Schema, ''> = {
18
- locales: {
19
- zh_CN: {
20
- name: '用户授权领取',
21
- attr: {
22
- ueg: '授权',
23
- user: '用户',
24
- relation: '关系',
25
- claimEntityId: '对象Id',
26
- userRelation: '用户关系',
27
- },
28
- },
29
- },
1
+ import { String } from '../types/DataType';
2
+ import { EntityShape } from '../types/Entity';
3
+ import { EntityDesc } from '../types/EntityDesc';
4
+ import { Schema as UserEntityGrant } from './UserEntityGrant';
5
+ import { Schema as User } from './User';
6
+ import { Schema as Relation } from './Relation';
7
+ import { Schema as UserRelation } from './UserRelation';
8
+
9
+ export interface Schema extends EntityShape {
10
+ ueg: UserEntityGrant;
11
+ user: User;
12
+ relation: Relation;
13
+ claimEntityId: String<64>;
14
+ userRelation: UserRelation;
15
+ };
16
+
17
+ const entityDesc: EntityDesc<Schema, ''> = {
18
+ locales: {
19
+ zh_CN: {
20
+ name: '用户授权领取',
21
+ attr: {
22
+ ueg: '授权',
23
+ user: '用户',
24
+ relation: '关系',
25
+ claimEntityId: '对象Id',
26
+ userRelation: '用户关系',
27
+ },
28
+ },
29
+ },
30
30
  };
@@ -1,24 +1,24 @@
1
- import { String } from '../types/DataType';
2
- import { EntityShape } from '../types/Entity';
3
- import { EntityDesc } from '../types/EntityDesc';
4
-
5
- type RelationIds = string[];
6
-
7
- export interface Schema extends EntityShape {
8
- relationEntity: String<32>;
9
- relationEntityFilter: Object;
10
- relationIds: RelationIds;
11
- };
12
-
13
- const entityDesc: EntityDesc<Schema, ''> = {
14
- locales: {
15
- zh_CN: {
16
- name: '用户授权',
17
- attr: {
18
- relationIds: '关系',
19
- relationEntity: '关联对象',
20
- relationEntityFilter: '对象限定条件',
21
- },
22
- },
23
- },
24
- };
1
+ import { String } from '../types/DataType';
2
+ import { EntityShape } from '../types/Entity';
3
+ import { EntityDesc } from '../types/EntityDesc';
4
+
5
+ type RelationIds = string[];
6
+
7
+ export interface Schema extends EntityShape {
8
+ relationEntity: String<32>;
9
+ relationEntityFilter: Object;
10
+ relationIds: RelationIds;
11
+ };
12
+
13
+ const entityDesc: EntityDesc<Schema, ''> = {
14
+ locales: {
15
+ zh_CN: {
16
+ name: '用户授权',
17
+ attr: {
18
+ relationIds: '关系',
19
+ relationEntity: '关联对象',
20
+ relationEntityFilter: '对象限定条件',
21
+ },
22
+ },
23
+ },
24
+ };
@@ -1,50 +1,50 @@
1
- import { String } from '../types/DataType';
2
- import { LocaleDef } from '../types/Locale';
3
- import { EntityShape } from '../types/Entity';
4
- import { Index } from '../types/Storage';
5
- import { Schema as User } from './User';
6
- import { Schema as Relation } from './Relation';
7
- import { EntityDesc } from '../types/EntityDesc';
8
-
9
- export interface Schema extends EntityShape {
10
- user: User;
11
- relation: Relation;
12
- entity: String<32>;
13
- entityId: String<64>;
14
- };
15
-
16
- const entityDesc: EntityDesc<Schema> = {
17
- locales: {
18
- zh_CN: {
19
- name: '用户对象关系',
20
- attr: {
21
- user: '关系',
22
- relation: '目标关系',
23
- entity: '目标对象',
24
- entityId: '目标对象ID',
25
- },
26
- },
27
- },
28
- indexes: [
29
- {
30
- name: 'index_user_entity_entityId_relation',
31
- attributes: [
32
- {
33
- name: 'user',
34
- },
35
- {
36
- name: 'entity',
37
- },
38
- {
39
- name: 'entityId',
40
- },
41
- {
42
- name: 'relation',
43
- },
44
- ],
45
- config: {
46
- unique: true,
47
- },
48
- },
49
- ]
50
- };
1
+ import { String } from '../types/DataType';
2
+ import { LocaleDef } from '../types/Locale';
3
+ import { EntityShape } from '../types/Entity';
4
+ import { Index } from '../types/Storage';
5
+ import { Schema as User } from './User';
6
+ import { Schema as Relation } from './Relation';
7
+ import { EntityDesc } from '../types/EntityDesc';
8
+
9
+ export interface Schema extends EntityShape {
10
+ user: User;
11
+ relation: Relation;
12
+ entity: String<32>;
13
+ entityId: String<64>;
14
+ };
15
+
16
+ const entityDesc: EntityDesc<Schema> = {
17
+ locales: {
18
+ zh_CN: {
19
+ name: '用户对象关系',
20
+ attr: {
21
+ user: '关系',
22
+ relation: '目标关系',
23
+ entity: '目标对象',
24
+ entityId: '目标对象ID',
25
+ },
26
+ },
27
+ },
28
+ indexes: [
29
+ {
30
+ name: 'index_user_entity_entityId_relation',
31
+ attributes: [
32
+ {
33
+ name: 'user',
34
+ },
35
+ {
36
+ name: 'entity',
37
+ },
38
+ {
39
+ name: 'entityId',
40
+ },
41
+ {
42
+ name: 'relation',
43
+ },
44
+ ],
45
+ config: {
46
+ unique: true,
47
+ },
48
+ },
49
+ ]
50
+ };