oak-domain 4.0.1 → 4.0.3

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 (207) hide show
  1. package/lib/actions/action.d.ts +16 -16
  2. package/lib/actions/action.js +17 -17
  3. package/lib/actions/relation.d.ts +5 -5
  4. package/lib/actions/relation.js +25 -25
  5. package/lib/base-app-domain/ActionAuth/Schema.d.ts +186 -186
  6. package/lib/base-app-domain/ActionAuth/Storage.js +39 -39
  7. package/lib/base-app-domain/ActionDefDict.d.ts +8 -8
  8. package/lib/base-app-domain/ActionDefDict.js +9 -9
  9. package/lib/base-app-domain/EntityDict.d.ts +28 -28
  10. package/lib/base-app-domain/I18n/Schema.d.ts +129 -129
  11. package/lib/base-app-domain/I18n/Schema.js +2 -2
  12. package/lib/base-app-domain/I18n/Storage.d.ts +3 -3
  13. package/lib/base-app-domain/I18n/Storage.js +59 -59
  14. package/lib/base-app-domain/Modi/Action.d.ts +10 -10
  15. package/lib/base-app-domain/Modi/Action.js +14 -14
  16. package/lib/base-app-domain/Modi/Schema.d.ts +136 -136
  17. package/lib/base-app-domain/Modi/Storage.js +63 -63
  18. package/lib/base-app-domain/ModiEntity/Schema.d.ts +384 -384
  19. package/lib/base-app-domain/ModiEntity/Storage.js +30 -30
  20. package/lib/base-app-domain/Oper/Schema.d.ts +153 -153
  21. package/lib/base-app-domain/Oper/Storage.js +38 -38
  22. package/lib/base-app-domain/OperEntity/Schema.d.ts +373 -373
  23. package/lib/base-app-domain/OperEntity/Storage.js +30 -30
  24. package/lib/base-app-domain/Path/Schema.d.ts +149 -149
  25. package/lib/base-app-domain/Path/Schema.js +2 -2
  26. package/lib/base-app-domain/Path/Storage.d.ts +3 -3
  27. package/lib/base-app-domain/Path/Storage.js +54 -54
  28. package/lib/base-app-domain/Relation/Schema.d.ts +188 -188
  29. package/lib/base-app-domain/Relation/Storage.js +54 -54
  30. package/lib/base-app-domain/Relation.d.ts +2 -2
  31. package/lib/base-app-domain/Relation.js +4 -4
  32. package/lib/base-app-domain/RelationAuth/Schema.d.ts +214 -214
  33. package/lib/base-app-domain/RelationAuth/Storage.js +44 -44
  34. package/lib/base-app-domain/Storage.js +31 -31
  35. package/lib/base-app-domain/User/Action.d.ts +10 -10
  36. package/lib/base-app-domain/User/Action.js +12 -12
  37. package/lib/base-app-domain/User/Schema.d.ts +210 -210
  38. package/lib/base-app-domain/User/Storage.js +33 -33
  39. package/lib/base-app-domain/UserEntityClaim/Schema.d.ts +264 -264
  40. package/lib/base-app-domain/UserEntityClaim/Schema.js +2 -2
  41. package/lib/base-app-domain/UserEntityClaim/Storage.d.ts +3 -3
  42. package/lib/base-app-domain/UserEntityClaim/Storage.js +37 -37
  43. package/lib/base-app-domain/UserEntityGrant/Schema.d.ts +131 -131
  44. package/lib/base-app-domain/UserEntityGrant/Storage.js +25 -25
  45. package/lib/base-app-domain/UserRelation/Schema.d.ts +208 -208
  46. package/lib/base-app-domain/UserRelation/Storage.js +56 -56
  47. package/lib/base-app-domain/_SubQuery.d.ts +142 -142
  48. package/lib/base-app-domain/index.d.ts +4 -4
  49. package/lib/base-app-domain/index.js +7 -7
  50. package/lib/checkers/index.d.ts +5 -5
  51. package/lib/checkers/index.js +13 -13
  52. package/lib/compiler/entities.d.ts +2 -2
  53. package/lib/compiler/entities.js +7 -7
  54. package/lib/compiler/env.d.ts +13 -13
  55. package/lib/compiler/env.js +45 -45
  56. package/lib/compiler/localeBuilder.d.ts +1 -1
  57. package/lib/compiler/localeBuilder.js +49 -18
  58. package/lib/compiler/routerBuilder.d.ts +1 -0
  59. package/lib/compiler/routerBuilder.js +263 -0
  60. package/lib/compiler/schemalBuilder.d.ts +27 -27
  61. package/lib/compiler/schemalBuilder.js +3565 -3565
  62. package/lib/entities/ActionAuth.d.ts +10 -10
  63. package/lib/entities/ActionAuth.js +31 -31
  64. package/lib/entities/I18n.d.ts +9 -9
  65. package/lib/entities/I18n.js +36 -36
  66. package/lib/entities/Modi.js +49 -49
  67. package/lib/entities/ModiEntity.js +18 -18
  68. package/lib/entities/Oper.js +21 -21
  69. package/lib/entities/OperEntity.js +18 -18
  70. package/lib/entities/Path.d.ts +8 -8
  71. package/lib/entities/Path.js +35 -35
  72. package/lib/entities/Relation.d.ts +8 -8
  73. package/lib/entities/Relation.js +35 -35
  74. package/lib/entities/RelationAuth.d.ts +8 -8
  75. package/lib/entities/RelationAuth.js +34 -34
  76. package/lib/entities/User.js +31 -31
  77. package/lib/entities/UserEntityClaim.d.ts +13 -13
  78. package/lib/entities/UserEntityClaim.js +17 -17
  79. package/lib/entities/UserEntityGrant.d.ts +9 -9
  80. package/lib/entities/UserEntityGrant.js +15 -15
  81. package/lib/entities/UserRelation.d.ts +10 -10
  82. package/lib/entities/UserRelation.js +38 -38
  83. package/lib/index.d.ts +23 -23
  84. package/lib/index.js +37 -37
  85. package/lib/store/AsyncRowStore.d.ts +65 -65
  86. package/lib/store/AsyncRowStore.js +9 -5
  87. package/lib/store/CascadeStore.d.ts +109 -106
  88. package/lib/store/CascadeStore.js +1748 -1740
  89. package/lib/store/RelationAuth.d.ts +7 -0
  90. package/lib/store/RelationAuth.js +11 -4
  91. package/lib/store/SyncRowStore.d.ts +29 -29
  92. package/lib/store/SyncRowStore.js +50 -50
  93. package/lib/store/TriggerExecutor.d.ts +41 -41
  94. package/lib/store/TriggerExecutor.js +468 -468
  95. package/lib/store/actionAuth.d.ts +4 -4
  96. package/lib/store/actionAuth.js +25 -25
  97. package/lib/store/actionDef.d.ts +10 -10
  98. package/lib/store/actionDef.js +278 -278
  99. package/lib/store/checker.d.ts +26 -26
  100. package/lib/store/checker.js +2 -2
  101. package/lib/store/filter.d.ts +85 -85
  102. package/lib/store/filter.js +1652 -1652
  103. package/lib/store/modi.d.ts +13 -13
  104. package/lib/store/modi.js +254 -254
  105. package/lib/store/relation.d.ts +12 -12
  106. package/lib/store/relation.js +67 -67
  107. package/lib/timers/oper.d.ts +18 -18
  108. package/lib/timers/oper.js +57 -57
  109. package/lib/timers/vaccum.d.ts +20 -20
  110. package/lib/timers/vaccum.js +111 -111
  111. package/lib/triggers/index.d.ts +5 -5
  112. package/lib/triggers/index.js +8 -8
  113. package/lib/types/Action.d.ts +20 -20
  114. package/lib/types/AppLoader.d.ts +17 -17
  115. package/lib/types/AppLoader.js +10 -10
  116. package/lib/types/Auth.d.ts +70 -70
  117. package/lib/types/Cluster.d.ts +5 -5
  118. package/lib/types/Cluster.js +2 -2
  119. package/lib/types/Connector.d.ts +38 -38
  120. package/lib/types/Connector.js +2 -2
  121. package/lib/types/DataType.d.ts +25 -25
  122. package/lib/types/DataType.js +6 -6
  123. package/lib/types/Demand.d.ts +89 -89
  124. package/lib/types/Demand.js +10 -10
  125. package/lib/types/Endpoint.d.ts +11 -11
  126. package/lib/types/Entity.d.ts +209 -209
  127. package/lib/types/Entity.js +15 -15
  128. package/lib/types/EntityDesc.d.ts +9 -9
  129. package/lib/types/EntityDesc.js +2 -2
  130. package/lib/types/Environment.d.ts +90 -90
  131. package/lib/types/Environment.js +2 -2
  132. package/lib/types/Exception.d.ts +10 -2
  133. package/lib/types/Exception.js +32 -2
  134. package/lib/types/Expression.d.ts +163 -163
  135. package/lib/types/Expression.js +397 -397
  136. package/lib/types/Geo.d.ts +18 -18
  137. package/lib/types/Locale.d.ts +25 -25
  138. package/lib/types/Logger.d.ts +6 -6
  139. package/lib/types/Polyfill.d.ts +24 -24
  140. package/lib/types/Port.d.ts +18 -18
  141. package/lib/types/RowStore.d.ts +19 -19
  142. package/lib/types/RowStore.js +33 -33
  143. package/lib/types/Storage.d.ts +58 -58
  144. package/lib/types/Style.d.ts +11 -11
  145. package/lib/types/Timer.d.ts +20 -20
  146. package/lib/types/Trigger.d.ts +118 -118
  147. package/lib/types/Trigger.js +35 -35
  148. package/lib/types/Watcher.d.ts +19 -19
  149. package/lib/types/index.d.ts +26 -26
  150. package/lib/types/index.js +29 -29
  151. package/lib/types/schema/DataTypes.d.ts +34 -34
  152. package/lib/utils/SimpleConnector.d.ts +64 -64
  153. package/lib/utils/SimpleConnector.js +206 -206
  154. package/lib/utils/assert.d.ts +6 -5
  155. package/lib/utils/assert.js +9 -9
  156. package/lib/utils/concurrent.d.ts +15 -15
  157. package/lib/utils/concurrent.js +63 -63
  158. package/lib/utils/date.js +18 -18
  159. package/lib/utils/domain.d.ts +1 -1
  160. package/lib/utils/domain.js +11 -11
  161. package/lib/utils/geo.js +24 -24
  162. package/lib/utils/lodash.d.ts +24 -24
  163. package/lib/utils/lodash.js +46 -46
  164. package/lib/utils/mask.js +34 -34
  165. package/lib/utils/money.d.ts +6 -6
  166. package/lib/utils/money.js +51 -51
  167. package/lib/utils/projection.d.ts +4 -4
  168. package/lib/utils/projection.js +15 -15
  169. package/lib/utils/random/random.js +19 -19
  170. package/lib/utils/random/random.mp.js +14 -14
  171. package/lib/utils/random/random.native.d.ts +1 -1
  172. package/lib/utils/random/random.native.js +14 -14
  173. package/lib/utils/random/random.web.js +11 -11
  174. package/lib/utils/string.d.ts +28 -28
  175. package/lib/utils/string.js +69 -69
  176. package/lib/utils/url/index.d.ts +7 -7
  177. package/lib/utils/url/index.js +8 -8
  178. package/lib/utils/url/index.mp.d.ts +3 -3
  179. package/lib/utils/url/index.mp.js +8 -8
  180. package/lib/utils/url/index.native.d.ts +12 -12
  181. package/lib/utils/url/index.native.js +7 -7
  182. package/lib/utils/url/index.web.d.ts +12 -12
  183. package/lib/utils/url/index.web.js +7 -7
  184. package/lib/utils/url/whatwg-url/index.d.ts +3 -3
  185. package/lib/utils/url/whatwg-url/index.js +16 -16
  186. package/lib/utils/url/whatwg-url/lib/URL-impl.d.ts +20 -20
  187. package/lib/utils/url/whatwg-url/lib/URL-impl.js +175 -175
  188. package/lib/utils/url/whatwg-url/lib/URL.d.ts +1 -1
  189. package/lib/utils/url/whatwg-url/lib/URL.js +298 -298
  190. package/lib/utils/url/whatwg-url/lib/URLSearchParams-impl.d.ts +19 -19
  191. package/lib/utils/url/whatwg-url/lib/URLSearchParams-impl.js +126 -126
  192. package/lib/utils/url/whatwg-url/lib/URLSearchParams.d.ts +1 -1
  193. package/lib/utils/url/whatwg-url/lib/URLSearchParams.js +426 -426
  194. package/lib/utils/url/whatwg-url/lib/infra.d.ts +12 -12
  195. package/lib/utils/url/whatwg-url/lib/infra.js +25 -25
  196. package/lib/utils/url/whatwg-url/lib/url-state-machine.d.ts +24 -24
  197. package/lib/utils/url/whatwg-url/lib/url-state-machine.js +1238 -1238
  198. package/lib/utils/url/whatwg-url/lib/urlencoded.d.ts +15 -15
  199. package/lib/utils/url/whatwg-url/lib/urlencoded.js +162 -162
  200. package/lib/utils/url/whatwg-url/lib/utils.d.ts +37 -37
  201. package/lib/utils/url/whatwg-url/lib/utils.js +101 -101
  202. package/lib/utils/uuid.d.ts +17 -17
  203. package/lib/utils/uuid.js +218 -218
  204. package/lib/utils/validator.d.ts +26 -26
  205. package/lib/utils/validator.js +131 -131
  206. package/lib/utils/version.js +21 -21
  207. package/package.json +2 -1
@@ -1,4 +1,4 @@
1
- import { EntityDict } from '../types/Entity';
2
- import { Trigger } from '../types';
3
- import { AsyncContext } from './AsyncRowStore';
4
- export declare const triggers: Trigger<EntityDict, 'actionAuth', AsyncContext<EntityDict>>[];
1
+ import { EntityDict } from '../types/Entity';
2
+ import { Trigger } from '../types';
3
+ import { AsyncContext } from './AsyncRowStore';
4
+ export declare const triggers: Trigger<EntityDict, 'actionAuth', AsyncContext<EntityDict>>[];
@@ -1,25 +1,25 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.triggers = void 0;
4
- const uuid_1 = require("../utils/uuid");
5
- exports.triggers = [
6
- {
7
- name: '当actionAuth的deActions被置空后,删除此条数据',
8
- entity: 'actionAuth',
9
- action: 'update',
10
- fn: async ({ operation }, context, option) => {
11
- const { data, filter } = operation;
12
- if (data.deActions && data.deActions.length === 0) {
13
- await context.operate('actionAuth', {
14
- id: await (0, uuid_1.generateNewIdAsync)(),
15
- action: 'remove',
16
- data: {},
17
- filter,
18
- }, option);
19
- return 1;
20
- }
21
- return 0;
22
- },
23
- when: 'after',
24
- }
25
- ];
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.triggers = void 0;
4
+ const uuid_1 = require("../utils/uuid");
5
+ exports.triggers = [
6
+ {
7
+ name: '当actionAuth的deActions被置空后,删除此条数据',
8
+ entity: 'actionAuth',
9
+ action: 'update',
10
+ fn: async ({ operation }, context, option) => {
11
+ const { data, filter } = operation;
12
+ if (data.deActions && data.deActions.length === 0) {
13
+ await context.operate('actionAuth', {
14
+ id: await (0, uuid_1.generateNewIdAsync)(),
15
+ action: 'remove',
16
+ data: {},
17
+ filter,
18
+ }, option);
19
+ return 1;
20
+ }
21
+ return 0;
22
+ },
23
+ when: 'after',
24
+ }
25
+ ];
@@ -1,10 +1,10 @@
1
- import { ActionDictOfEntityDict, BBWatcher, Checker, EntityDict, StorageSchema, Trigger } from "../types";
2
- import { SyncContext } from "./SyncRowStore";
3
- import { AsyncContext } from "./AsyncRowStore";
4
- import { EntityDict as BaseEntityDict } from '../base-app-domain/EntityDict';
5
- export declare function getFullProjection<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>): ED[T]["Selection"]["data"];
6
- export declare function makeIntrinsicCTWs<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDictOfEntityDict<ED>): {
7
- triggers: Trigger<ED, keyof ED, Cxt>[];
8
- checkers: Checker<ED, keyof ED, Cxt | FrontCxt>[];
9
- watchers: BBWatcher<ED, keyof ED>[];
10
- };
1
+ import { ActionDictOfEntityDict, BBWatcher, Checker, EntityDict, StorageSchema, Trigger } from "../types";
2
+ import { SyncContext } from "./SyncRowStore";
3
+ import { AsyncContext } from "./AsyncRowStore";
4
+ import { EntityDict as BaseEntityDict } from '../base-app-domain/EntityDict';
5
+ export declare function getFullProjection<ED extends EntityDict & BaseEntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>): ED[T]["Selection"]["data"];
6
+ export declare function makeIntrinsicCTWs<ED extends EntityDict & BaseEntityDict, Cxt extends AsyncContext<ED>, FrontCxt extends SyncContext<ED>>(schema: StorageSchema<ED>, actionDefDict: ActionDictOfEntityDict<ED>): {
7
+ triggers: Trigger<ED, keyof ED, Cxt>[];
8
+ checkers: Checker<ED, keyof ED, Cxt | FrontCxt>[];
9
+ watchers: BBWatcher<ED, keyof ED>[];
10
+ };
@@ -1,278 +1,278 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.makeIntrinsicCTWs = exports.getFullProjection = void 0;
4
- const types_1 = require("../types");
5
- const lodash_1 = require("../utils/lodash");
6
- const filter_1 = require("./filter");
7
- const checkers_1 = require("../checkers");
8
- const triggers_1 = require("../triggers");
9
- const actionAuth_1 = require("./actionAuth");
10
- function getFullProjection(entity, schema) {
11
- const { attributes } = schema[entity];
12
- const projection = {
13
- id: 1,
14
- $$createAt$$: 1,
15
- $$updateAt$$: 1,
16
- $$deleteAt$$: 1,
17
- };
18
- Object.keys(attributes).forEach((k) => Object.assign(projection, {
19
- [k]: 1,
20
- }));
21
- return projection;
22
- }
23
- exports.getFullProjection = getFullProjection;
24
- function makeIntrinsicWatchers(schema) {
25
- const watchers = [];
26
- for (const entity in schema) {
27
- const { attributes } = schema[entity];
28
- const { expiresAt, expired } = attributes;
29
- if (expiresAt && expiresAt.type === 'datetime' && expired && expired.type === 'boolean') {
30
- // 如果有定义expiresAt和expired,则自动生成一个检查的watcher
31
- watchers.push({
32
- entity,
33
- name: `对象${entity}上的过期自动watcher`,
34
- filter: () => {
35
- return {
36
- expired: false,
37
- expiresAt: {
38
- $lte: Date.now(),
39
- },
40
- };
41
- },
42
- action: 'update',
43
- actionData: {
44
- expired: true,
45
- },
46
- });
47
- }
48
- }
49
- return watchers;
50
- }
51
- function checkUniqueBetweenRows(rows, uniqAttrs) {
52
- // 先检查这些行本身之间有无unique冲突
53
- const dict = {};
54
- for (const row of rows) {
55
- let s = '';
56
- for (const a of uniqAttrs) {
57
- if (row[a] === null || row[a] === undefined) {
58
- s + row.id;
59
- }
60
- else {
61
- s + `-${row[a]}`;
62
- }
63
- }
64
- if (dict[s]) {
65
- throw new types_1.OakUniqueViolationException([{
66
- id: row.id,
67
- attrs: uniqAttrs,
68
- }]);
69
- }
70
- else {
71
- dict[s] = 1;
72
- }
73
- }
74
- }
75
- function checkCountLessThan(count, uniqAttrs, than = 0, id) {
76
- if (count instanceof Promise) {
77
- return count.then((count2) => {
78
- if (count2 > than) {
79
- throw new types_1.OakUniqueViolationException([{
80
- id,
81
- attrs: uniqAttrs,
82
- }]);
83
- }
84
- });
85
- }
86
- if (count > than) {
87
- throw new types_1.OakUniqueViolationException([{
88
- id,
89
- attrs: uniqAttrs,
90
- }]);
91
- }
92
- }
93
- function checkUnique(entity, row, context, uniqAttrs, extraFilter) {
94
- const filter = (0, lodash_1.pick)(row, uniqAttrs);
95
- for (const a in filter) {
96
- if (filter[a] === null || filter[a] === undefined) {
97
- delete filter[a];
98
- }
99
- }
100
- if (Object.keys(filter).length < uniqAttrs.length) {
101
- // 说明有null值,不需要检查约束
102
- return;
103
- }
104
- const filter2 = extraFilter ? (0, filter_1.combineFilters)(entity, context.getSchema(), [filter, extraFilter]) : filter;
105
- const count = context.count(entity, { filter: filter2 }, { dontCollect: true });
106
- return checkCountLessThan(count, uniqAttrs, 0, row.id);
107
- }
108
- function makeIntrinsicCTWs(schema, actionDefDict) {
109
- const checkers = (0, checkers_1.createDynamicCheckers)(schema);
110
- const triggers = (0, triggers_1.createDynamicTriggers)(schema);
111
- // action状态转换矩阵相应的checker
112
- for (const entity in actionDefDict) {
113
- for (const attr in actionDefDict[entity]) {
114
- const def = actionDefDict[entity][attr];
115
- const { stm, is } = def;
116
- for (const action in stm) {
117
- const actionStm = stm[action];
118
- const conditionalFilter = typeof actionStm[0] === 'string' ? {
119
- [attr]: actionStm[0],
120
- } : {
121
- [attr]: {
122
- $in: actionStm[0],
123
- },
124
- };
125
- checkers.push({
126
- action: action,
127
- type: 'row',
128
- entity,
129
- filter: conditionalFilter,
130
- errMsg: '',
131
- });
132
- // 这里用data类型的checker改数据了不太好,先这样
133
- checkers.push({
134
- action: action,
135
- type: 'data',
136
- entity,
137
- checker: (data) => {
138
- Object.assign(data, {
139
- [attr]: stm[action][1],
140
- });
141
- }
142
- });
143
- }
144
- if (is) {
145
- checkers.push({
146
- action: 'create',
147
- type: 'data',
148
- entity,
149
- priority: 10,
150
- checker: (data) => {
151
- if (data instanceof Array) {
152
- data.forEach(ele => {
153
- if (!ele[attr]) {
154
- Object.assign(ele, {
155
- [attr]: is,
156
- });
157
- }
158
- });
159
- }
160
- else {
161
- if (!data[attr]) {
162
- Object.assign(data, {
163
- [attr]: is,
164
- });
165
- }
166
- }
167
- }
168
- });
169
- }
170
- }
171
- }
172
- // unique索引相应的checker
173
- for (const entity in schema) {
174
- const { indexes } = schema[entity];
175
- if (indexes) {
176
- for (const index of indexes) {
177
- if (index.config?.unique) {
178
- const { attributes } = index;
179
- const uniqAttrs = attributes.map(ele => ele.name);
180
- checkers.push({
181
- entity,
182
- action: 'create',
183
- type: 'logicalData',
184
- priority: types_1.CHECKER_MAX_PRIORITY,
185
- checker: (operation, context) => {
186
- const { data } = operation;
187
- if (data instanceof Array) {
188
- checkUniqueBetweenRows(data, uniqAttrs);
189
- const checkResult = data.map(ele => checkUnique(entity, ele, context, uniqAttrs));
190
- if (checkResult[0] instanceof Promise) {
191
- return Promise.all(checkResult).then(() => undefined);
192
- }
193
- }
194
- else if (data) {
195
- return checkUnique(entity, data, context, uniqAttrs);
196
- }
197
- }
198
- }, {
199
- entity,
200
- action: 'update',
201
- type: 'logicalData',
202
- priority: types_1.CHECKER_MAX_PRIORITY,
203
- checker: (operation, context) => {
204
- const { data, filter: operationFilter } = operation;
205
- if (data) {
206
- const attrs = Object.keys(data);
207
- const refAttrs = (0, lodash_1.intersection)(attrs, uniqAttrs);
208
- if (refAttrs.length === 0) {
209
- // 如果本次更新和unique约束的属性之间没有交集则直接返回
210
- return;
211
- }
212
- for (const attr of refAttrs) {
213
- // 如果有更新为null值,不用再检查约束
214
- if (data[attr] === null || data[attr] === undefined) {
215
- return;
216
- }
217
- }
218
- if (refAttrs.length === uniqAttrs.length) {
219
- // 如果更新了全部属性,直接检查
220
- const filter = (0, lodash_1.pick)(data, refAttrs);
221
- // 在这些行以外的行不和更新后的键值冲突
222
- const count = context.count(entity, {
223
- filter: (0, filter_1.combineFilters)(entity, context.getSchema(), [filter, {
224
- $not: operationFilter,
225
- }]),
226
- }, { dontCollect: true });
227
- const checkCount = checkCountLessThan(count, uniqAttrs, 0, operationFilter?.id);
228
- // 更新的行只能有一行
229
- const rowCount = context.count(entity, {
230
- filter: operationFilter,
231
- }, { dontCollect: true });
232
- const checkRowCount = checkCountLessThan(rowCount, uniqAttrs, 1, operationFilter?.id);
233
- // 如果更新的行数为零似乎也可以,但这应该不可能出现吧,by Xc 20230131
234
- if (checkRowCount instanceof Promise) {
235
- return Promise.all([checkCount, checkRowCount]).then(() => undefined);
236
- }
237
- }
238
- // 否则需要结合本行现有的属性来进行检查
239
- const projection = { id: 1 };
240
- for (const attr of uniqAttrs) {
241
- Object.assign(projection, {
242
- [attr]: 1,
243
- });
244
- }
245
- const checkWithRows = (rows2) => {
246
- const rows22 = rows2.map(ele => Object.assign(ele, data));
247
- // 先检查这些行本身之间是否冲突
248
- checkUniqueBetweenRows(rows22, uniqAttrs);
249
- const checkResults = rows22.map((row) => checkUnique(entity, row, context, uniqAttrs, {
250
- $not: operationFilter
251
- }));
252
- if (checkResults[0] instanceof Promise) {
253
- return Promise.all(checkResults).then(() => undefined);
254
- }
255
- };
256
- const currentRows = context.select(entity, {
257
- data: projection,
258
- filter: operationFilter,
259
- }, { dontCollect: true });
260
- if (currentRows instanceof Promise) {
261
- return currentRows.then((row2) => checkWithRows(row2));
262
- }
263
- return checkWithRows(currentRows);
264
- }
265
- }
266
- });
267
- }
268
- }
269
- }
270
- }
271
- triggers.push(...actionAuth_1.triggers);
272
- return {
273
- triggers,
274
- checkers,
275
- watchers: makeIntrinsicWatchers(schema),
276
- };
277
- }
278
- exports.makeIntrinsicCTWs = makeIntrinsicCTWs;
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.makeIntrinsicCTWs = exports.getFullProjection = void 0;
4
+ const types_1 = require("../types");
5
+ const lodash_1 = require("../utils/lodash");
6
+ const filter_1 = require("./filter");
7
+ const checkers_1 = require("../checkers");
8
+ const triggers_1 = require("../triggers");
9
+ const actionAuth_1 = require("./actionAuth");
10
+ function getFullProjection(entity, schema) {
11
+ const { attributes } = schema[entity];
12
+ const projection = {
13
+ id: 1,
14
+ $$createAt$$: 1,
15
+ $$updateAt$$: 1,
16
+ $$deleteAt$$: 1,
17
+ };
18
+ Object.keys(attributes).forEach((k) => Object.assign(projection, {
19
+ [k]: 1,
20
+ }));
21
+ return projection;
22
+ }
23
+ exports.getFullProjection = getFullProjection;
24
+ function makeIntrinsicWatchers(schema) {
25
+ const watchers = [];
26
+ for (const entity in schema) {
27
+ const { attributes } = schema[entity];
28
+ const { expiresAt, expired } = attributes;
29
+ if (expiresAt && expiresAt.type === 'datetime' && expired && expired.type === 'boolean') {
30
+ // 如果有定义expiresAt和expired,则自动生成一个检查的watcher
31
+ watchers.push({
32
+ entity,
33
+ name: `对象${entity}上的过期自动watcher`,
34
+ filter: () => {
35
+ return {
36
+ expired: false,
37
+ expiresAt: {
38
+ $lte: Date.now(),
39
+ },
40
+ };
41
+ },
42
+ action: 'update',
43
+ actionData: {
44
+ expired: true,
45
+ },
46
+ });
47
+ }
48
+ }
49
+ return watchers;
50
+ }
51
+ function checkUniqueBetweenRows(rows, uniqAttrs) {
52
+ // 先检查这些行本身之间有无unique冲突
53
+ const dict = {};
54
+ for (const row of rows) {
55
+ let s = '';
56
+ for (const a of uniqAttrs) {
57
+ if (row[a] === null || row[a] === undefined) {
58
+ s + row.id;
59
+ }
60
+ else {
61
+ s + `-${row[a]}`;
62
+ }
63
+ }
64
+ if (dict[s]) {
65
+ throw new types_1.OakUniqueViolationException([{
66
+ id: row.id,
67
+ attrs: uniqAttrs,
68
+ }]);
69
+ }
70
+ else {
71
+ dict[s] = 1;
72
+ }
73
+ }
74
+ }
75
+ function checkCountLessThan(count, uniqAttrs, than = 0, id) {
76
+ if (count instanceof Promise) {
77
+ return count.then((count2) => {
78
+ if (count2 > than) {
79
+ throw new types_1.OakUniqueViolationException([{
80
+ id,
81
+ attrs: uniqAttrs,
82
+ }]);
83
+ }
84
+ });
85
+ }
86
+ if (count > than) {
87
+ throw new types_1.OakUniqueViolationException([{
88
+ id,
89
+ attrs: uniqAttrs,
90
+ }]);
91
+ }
92
+ }
93
+ function checkUnique(entity, row, context, uniqAttrs, extraFilter) {
94
+ const filter = (0, lodash_1.pick)(row, uniqAttrs);
95
+ for (const a in filter) {
96
+ if (filter[a] === null || filter[a] === undefined) {
97
+ delete filter[a];
98
+ }
99
+ }
100
+ if (Object.keys(filter).length < uniqAttrs.length) {
101
+ // 说明有null值,不需要检查约束
102
+ return;
103
+ }
104
+ const filter2 = extraFilter ? (0, filter_1.combineFilters)(entity, context.getSchema(), [filter, extraFilter]) : filter;
105
+ const count = context.count(entity, { filter: filter2 }, { dontCollect: true });
106
+ return checkCountLessThan(count, uniqAttrs, 0, row.id);
107
+ }
108
+ function makeIntrinsicCTWs(schema, actionDefDict) {
109
+ const checkers = (0, checkers_1.createDynamicCheckers)(schema);
110
+ const triggers = (0, triggers_1.createDynamicTriggers)(schema);
111
+ // action状态转换矩阵相应的checker
112
+ for (const entity in actionDefDict) {
113
+ for (const attr in actionDefDict[entity]) {
114
+ const def = actionDefDict[entity][attr];
115
+ const { stm, is } = def;
116
+ for (const action in stm) {
117
+ const actionStm = stm[action];
118
+ const conditionalFilter = typeof actionStm[0] === 'string' ? {
119
+ [attr]: actionStm[0],
120
+ } : {
121
+ [attr]: {
122
+ $in: actionStm[0],
123
+ },
124
+ };
125
+ checkers.push({
126
+ action: action,
127
+ type: 'row',
128
+ entity,
129
+ filter: conditionalFilter,
130
+ errMsg: '',
131
+ });
132
+ // 这里用data类型的checker改数据了不太好,先这样
133
+ checkers.push({
134
+ action: action,
135
+ type: 'data',
136
+ entity,
137
+ checker: (data) => {
138
+ Object.assign(data, {
139
+ [attr]: stm[action][1],
140
+ });
141
+ }
142
+ });
143
+ }
144
+ if (is) {
145
+ checkers.push({
146
+ action: 'create',
147
+ type: 'data',
148
+ entity,
149
+ priority: 10, // 优先级要高,先于真正的data检查进行
150
+ checker: (data) => {
151
+ if (data instanceof Array) {
152
+ data.forEach(ele => {
153
+ if (!ele[attr]) {
154
+ Object.assign(ele, {
155
+ [attr]: is,
156
+ });
157
+ }
158
+ });
159
+ }
160
+ else {
161
+ if (!data[attr]) {
162
+ Object.assign(data, {
163
+ [attr]: is,
164
+ });
165
+ }
166
+ }
167
+ }
168
+ });
169
+ }
170
+ }
171
+ }
172
+ // unique索引相应的checker
173
+ for (const entity in schema) {
174
+ const { indexes } = schema[entity];
175
+ if (indexes) {
176
+ for (const index of indexes) {
177
+ if (index.config?.unique) {
178
+ const { attributes } = index;
179
+ const uniqAttrs = attributes.map(ele => ele.name);
180
+ checkers.push({
181
+ entity,
182
+ action: 'create',
183
+ type: 'logicalData',
184
+ priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
185
+ checker: (operation, context) => {
186
+ const { data } = operation;
187
+ if (data instanceof Array) {
188
+ checkUniqueBetweenRows(data, uniqAttrs);
189
+ const checkResult = data.map(ele => checkUnique(entity, ele, context, uniqAttrs));
190
+ if (checkResult[0] instanceof Promise) {
191
+ return Promise.all(checkResult).then(() => undefined);
192
+ }
193
+ }
194
+ else if (data) {
195
+ return checkUnique(entity, data, context, uniqAttrs);
196
+ }
197
+ }
198
+ }, {
199
+ entity,
200
+ action: 'update', // 只检查update,其它状态转换的action应该不会涉及unique约束的属性
201
+ type: 'logicalData',
202
+ priority: types_1.CHECKER_MAX_PRIORITY, // 优先级要放在最低,所有前置的checker/trigger将数据完整之后再在这里检测
203
+ checker: (operation, context) => {
204
+ const { data, filter: operationFilter } = operation;
205
+ if (data) {
206
+ const attrs = Object.keys(data);
207
+ const refAttrs = (0, lodash_1.intersection)(attrs, uniqAttrs);
208
+ if (refAttrs.length === 0) {
209
+ // 如果本次更新和unique约束的属性之间没有交集则直接返回
210
+ return;
211
+ }
212
+ for (const attr of refAttrs) {
213
+ // 如果有更新为null值,不用再检查约束
214
+ if (data[attr] === null || data[attr] === undefined) {
215
+ return;
216
+ }
217
+ }
218
+ if (refAttrs.length === uniqAttrs.length) {
219
+ // 如果更新了全部属性,直接检查
220
+ const filter = (0, lodash_1.pick)(data, refAttrs);
221
+ // 在这些行以外的行不和更新后的键值冲突
222
+ const count = context.count(entity, {
223
+ filter: (0, filter_1.combineFilters)(entity, context.getSchema(), [filter, {
224
+ $not: operationFilter,
225
+ }]),
226
+ }, { dontCollect: true });
227
+ const checkCount = checkCountLessThan(count, uniqAttrs, 0, operationFilter?.id);
228
+ // 更新的行只能有一行
229
+ const rowCount = context.count(entity, {
230
+ filter: operationFilter,
231
+ }, { dontCollect: true });
232
+ const checkRowCount = checkCountLessThan(rowCount, uniqAttrs, 1, operationFilter?.id);
233
+ // 如果更新的行数为零似乎也可以,但这应该不可能出现吧,by Xc 20230131
234
+ if (checkRowCount instanceof Promise) {
235
+ return Promise.all([checkCount, checkRowCount]).then(() => undefined);
236
+ }
237
+ }
238
+ // 否则需要结合本行现有的属性来进行检查
239
+ const projection = { id: 1 };
240
+ for (const attr of uniqAttrs) {
241
+ Object.assign(projection, {
242
+ [attr]: 1,
243
+ });
244
+ }
245
+ const checkWithRows = (rows2) => {
246
+ const rows22 = rows2.map(ele => Object.assign(ele, data));
247
+ // 先检查这些行本身之间是否冲突
248
+ checkUniqueBetweenRows(rows22, uniqAttrs);
249
+ const checkResults = rows22.map((row) => checkUnique(entity, row, context, uniqAttrs, {
250
+ $not: operationFilter
251
+ }));
252
+ if (checkResults[0] instanceof Promise) {
253
+ return Promise.all(checkResults).then(() => undefined);
254
+ }
255
+ };
256
+ const currentRows = context.select(entity, {
257
+ data: projection,
258
+ filter: operationFilter,
259
+ }, { dontCollect: true });
260
+ if (currentRows instanceof Promise) {
261
+ return currentRows.then((row2) => checkWithRows(row2));
262
+ }
263
+ return checkWithRows(currentRows);
264
+ }
265
+ }
266
+ });
267
+ }
268
+ }
269
+ }
270
+ }
271
+ triggers.push(...actionAuth_1.triggers);
272
+ return {
273
+ triggers,
274
+ checkers,
275
+ watchers: makeIntrinsicWatchers(schema),
276
+ };
277
+ }
278
+ exports.makeIntrinsicCTWs = makeIntrinsicCTWs;