oak-domain 1.1.8 → 1.1.9
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.
- package/lib/base-app-domain/Modi/Storage.js +1 -1
- package/lib/compiler/env.d.ts +1 -1
- package/lib/compiler/env.js +1 -1
- package/lib/compiler/schemalBuilder.d.ts +1 -1
- package/lib/compiler/schemalBuilder.js +54 -26
- package/lib/store/CascadeStore.js +182 -153
- package/lib/store/TriggerExecutor.d.ts +2 -1
- package/lib/store/TriggerExecutor.js +6 -0
- package/lib/store/UniversalContext.d.ts +6 -1
- package/lib/store/UniversalContext.js +12 -1
- package/lib/store/filter.d.ts +28 -1
- package/lib/store/filter.js +136 -2
- package/lib/types/Context.d.ts +1 -0
- package/lib/types/Exception.d.ts +3 -1
- package/lib/types/Exception.js +7 -2
- package/lib/types/RowStore.d.ts +1 -0
- package/lib/types/RowStore.js +6 -0
- package/lib/types/Watcher.d.ts +5 -4
- package/lib/utils/SimpleConnector.js +1 -0
- package/lib/utils/lodash.d.ts +2 -1
- package/lib/utils/lodash.js +3 -1
- package/package.json +2 -1
package/lib/compiler/env.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export declare const ENTITY_PATH_IN_OAK_DOMAIN: () => string;
|
|
|
5
5
|
export declare const TYPE_PATH_IN_OAK_DOMAIN: (level?: number) => string;
|
|
6
6
|
export declare const ACTION_CONSTANT_IN_OAK_DOMAIN: (level?: number) => string;
|
|
7
7
|
export declare const RESERVED_ENTITIES: string[];
|
|
8
|
-
export declare const STRING_LITERAL_MAX_LENGTH =
|
|
8
|
+
export declare const STRING_LITERAL_MAX_LENGTH = 24;
|
|
9
9
|
export declare const NUMERICAL_LITERL_DEFAULT_PRECISION = 8;
|
|
10
10
|
export declare const NUMERICAL_LITERL_DEFAULT_SCALE = 2;
|
|
11
11
|
export declare const INT_LITERL_DEFAULT_WIDTH = 4;
|
package/lib/compiler/env.js
CHANGED
|
@@ -33,7 +33,7 @@ exports.ACTION_CONSTANT_IN_OAK_DOMAIN = ACTION_CONSTANT_IN_OAK_DOMAIN;
|
|
|
33
33
|
// export const OUTPUT_PATH = 'app-domain/entities';
|
|
34
34
|
exports.RESERVED_ENTITIES = ['Schema', 'Filter', 'Query', 'SubQuery', 'Entity', 'Selection', 'Operation', 'File', 'Common',
|
|
35
35
|
'Locale', 'Projection', 'Data'];
|
|
36
|
-
exports.STRING_LITERAL_MAX_LENGTH =
|
|
36
|
+
exports.STRING_LITERAL_MAX_LENGTH = 24;
|
|
37
37
|
exports.NUMERICAL_LITERL_DEFAULT_PRECISION = 8;
|
|
38
38
|
exports.NUMERICAL_LITERL_DEFAULT_SCALE = 2;
|
|
39
39
|
exports.INT_LITERL_DEFAULT_WIDTH = 4;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare function analyzeEntities(inputDir: string): void;
|
|
1
|
+
export declare function analyzeEntities(inputDir: string, relativePath?: string): void;
|
|
2
2
|
export declare function buildSchema(outputDir: string): void;
|
|
@@ -150,7 +150,7 @@ function addActionSource(moduleName, name, node) {
|
|
|
150
150
|
var _a;
|
|
151
151
|
var ast = ActionAsts[moduleName];
|
|
152
152
|
var moduleSpecifier = node.moduleSpecifier;
|
|
153
|
-
// 目前应该只会引用oak-domain/src/actions/action里的公共action
|
|
153
|
+
// todo 目前应该只会引用oak-domain/src/actions/action里的公共action,未来如果有交叉引用这里代码要修正(如果domain中也有引用action_constants这里应该也会错)
|
|
154
154
|
(0, assert_1.default)(ts.isStringLiteral(moduleSpecifier) && moduleSpecifier.text === (0, env_1.ACTION_CONSTANT_IN_OAK_DOMAIN)());
|
|
155
155
|
(0, lodash_1.assign)(ast.importedFrom, (_a = {},
|
|
156
156
|
_a[name.text] = node,
|
|
@@ -262,27 +262,26 @@ function dealWithActions(moduleName, filename, node, program, sourceFile, hasRel
|
|
|
262
262
|
});
|
|
263
263
|
pushStatementIntoActionAst(moduleName, factory.createVariableStatement([factory.createModifier(ts.SyntaxKind.ExportKeyword)], factory.createVariableDeclarationList([factory.createVariableDeclaration(factory.createIdentifier("actions"), undefined, undefined, factory.createArrayLiteralExpression(actionTexts.map(function (ele) { return factory.createStringLiteral(ele); }), false))], ts.NodeFlags.Const)), sourceFile);
|
|
264
264
|
}
|
|
265
|
-
|
|
265
|
+
/**
|
|
266
|
+
* entity的引用一定要以 import { Schema as XXX } from '..../XXX'这种形式
|
|
267
|
+
* @param declaration
|
|
268
|
+
* @param filename
|
|
269
|
+
* @returns
|
|
270
|
+
*/
|
|
271
|
+
function getEntityImported(declaration) {
|
|
266
272
|
var moduleSpecifier = declaration.moduleSpecifier, importClause = declaration.importClause;
|
|
267
273
|
var entityImported;
|
|
268
274
|
if (ts.isStringLiteral(moduleSpecifier)) {
|
|
269
|
-
|
|
270
|
-
entityImported = moduleSpecifier.text.slice(2);
|
|
271
|
-
}
|
|
272
|
-
else if (moduleSpecifier.text.startsWith((0, env_1.ENTITY_PATH_IN_OAK_GENERAL_BUSINESS)())) {
|
|
273
|
-
entityImported = moduleSpecifier.text.slice((0, env_1.ENTITY_PATH_IN_OAK_GENERAL_BUSINESS)().length);
|
|
274
|
-
}
|
|
275
|
-
else if (moduleSpecifier.text.startsWith((0, env_1.ENTITY_PATH_IN_OAK_DOMAIN)())) {
|
|
276
|
-
entityImported = moduleSpecifier.text.slice((0, env_1.ENTITY_PATH_IN_OAK_DOMAIN)().length);
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
if (entityImported) {
|
|
275
|
+
var importedFileName_1 = path_1.default.parse(moduleSpecifier.text).name;
|
|
280
276
|
var namedBindings = importClause.namedBindings;
|
|
281
|
-
(
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
277
|
+
if (namedBindings && ts.isNamedImports(namedBindings)) {
|
|
278
|
+
var elements = namedBindings.elements;
|
|
279
|
+
if (elements.find(function (ele) { var _a; return ts.isImportSpecifier(ele) && ele.name.text === importedFileName_1 && ((_a = ele.propertyName) === null || _a === void 0 ? void 0 : _a.text) === 'Schema'; })) {
|
|
280
|
+
entityImported = importedFileName_1;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
285
283
|
}
|
|
284
|
+
return entityImported;
|
|
286
285
|
}
|
|
287
286
|
function checkLocaleEnumAttrs(node, attrs, filename) {
|
|
288
287
|
var members = node.members;
|
|
@@ -312,7 +311,7 @@ function checkLocaleExpressionPropertyExists(root, attr, exists, filename) {
|
|
|
312
311
|
}
|
|
313
312
|
});
|
|
314
313
|
}
|
|
315
|
-
function analyzeEntity(filename, path, program) {
|
|
314
|
+
function analyzeEntity(filename, path, program, relativePath) {
|
|
316
315
|
var _a;
|
|
317
316
|
var fullPath = "".concat(path, "/").concat(filename);
|
|
318
317
|
var sourceFile = program.getSourceFile(fullPath);
|
|
@@ -336,14 +335,30 @@ function analyzeEntity(filename, path, program) {
|
|
|
336
335
|
var enumStringAttrs = [];
|
|
337
336
|
var states = [];
|
|
338
337
|
var localEnumStringTypes = [];
|
|
338
|
+
var additionalImports = [];
|
|
339
339
|
var localeDef = undefined;
|
|
340
340
|
ts.forEachChild(sourceFile, function (node) {
|
|
341
341
|
var _a, _b, _c, _d;
|
|
342
342
|
if (ts.isImportDeclaration(node)) {
|
|
343
|
-
var entityImported = getEntityImported(node
|
|
343
|
+
var entityImported = getEntityImported(node);
|
|
344
344
|
if (entityImported) {
|
|
345
345
|
referencedSchemas.push(entityImported);
|
|
346
346
|
}
|
|
347
|
+
else if (!process.env.COMPLING_IN_DOMAIN && !(relativePath === null || relativePath === void 0 ? void 0 : relativePath.startsWith(env_1.LIB_OAK_DOMAIN))) {
|
|
348
|
+
/**import了domain以外的其它定义类型,需要被复制到生成的Schema文件中
|
|
349
|
+
* 这里必须注意,1、假设了domain当中定义的几个entity不会引用其它文件上的定义(除了type里的那些通用类型,默认都会被输出到文件中)
|
|
350
|
+
* 2、假设了其它项目文件不会引用domain当中除了type通用类型之外的其它内容,否则不会被输出到文件中
|
|
351
|
+
* 这里主要是对import的处理比较粗略,日后有需要的时候再精修
|
|
352
|
+
*/
|
|
353
|
+
var moduleSpecifier = node.moduleSpecifier, importClause = node.importClause;
|
|
354
|
+
if (ts.isStringLiteral(moduleSpecifier) && !moduleSpecifier.text.startsWith(env_1.LIB_OAK_DOMAIN)) {
|
|
355
|
+
// 编译后的路径默认要深一层
|
|
356
|
+
var moduleSpecifier2Text = relativePath
|
|
357
|
+
? path_1.default.join(relativePath, moduleSpecifier.text).replace(/\\/g, '/')
|
|
358
|
+
: path_1.default.join('..', moduleSpecifier.text).replace(/\\/g, '/');
|
|
359
|
+
additionalImports.push(factory.updateImportDeclaration(node, undefined, undefined, importClause, factory.createStringLiteral(moduleSpecifier2Text), undefined));
|
|
360
|
+
}
|
|
361
|
+
}
|
|
347
362
|
}
|
|
348
363
|
if (ts.isInterfaceDeclaration(node)) {
|
|
349
364
|
// schema 定义
|
|
@@ -417,6 +432,10 @@ function analyzeEntity(filename, path, program) {
|
|
|
417
432
|
var types = type.types;
|
|
418
433
|
if (ts.isLiteralTypeNode(types[0]) && ts.isStringLiteral(types[0].literal)) {
|
|
419
434
|
enumStringAttrs.push(name.text);
|
|
435
|
+
types.forEach(function (ele) {
|
|
436
|
+
(0, assert_1.default)(ts.isLiteralTypeNode(ele) && ts.isStringLiteral(ele.literal), "\u300C".concat(filename, "\u300D\u4E0D\u652F\u6301\u6DF7\u5408\u578B\u7684\u679A\u4E3E\u5C5E\u6027\u5B9A\u4E49\u300C").concat(attrName, "\u300D"));
|
|
437
|
+
(0, assert_1.default)(ele.literal.text.length < env_1.STRING_LITERAL_MAX_LENGTH, "\u300C".concat(filename, "\u300D\u4E2D\u5B9A\u4E49\u7684\u5C5E\u6027\u679A\u4E3E\u300C").concat(attrName, "\u300D\u7684\u5B57\u7B26\u4E32\u957F\u5EA6\u5E94\u5C0F\u4E8E").concat(env_1.STRING_LITERAL_MAX_LENGTH));
|
|
438
|
+
});
|
|
420
439
|
}
|
|
421
440
|
}
|
|
422
441
|
}
|
|
@@ -552,6 +571,10 @@ function analyzeEntity(filename, path, program) {
|
|
|
552
571
|
if (ts.isUnionTypeNode(node.type) && ts.isLiteralTypeNode(node.type.types[0]) && ts.isStringLiteral(node.type.types[0].literal)) {
|
|
553
572
|
// 本文件内定义的枚举类型
|
|
554
573
|
localEnumStringTypes.push(node.name.text);
|
|
574
|
+
node.type.types.forEach(function (ele) {
|
|
575
|
+
(0, assert_1.default)(ts.isLiteralTypeNode(ele) && ts.isStringLiteral(ele.literal), "\u300C".concat(filename, "\u300D\u4E0D\u652F\u6301\u6DF7\u5408\u578B\u7684\u5E38\u91CF\u5B9A\u4E49\u300C").concat(node.name.text, "\u300D"));
|
|
576
|
+
(0, assert_1.default)(ele.literal.text.length < env_1.STRING_LITERAL_MAX_LENGTH, "\u300C".concat(filename, "\u300D\u4E2D\u5B9A\u4E49\u7684\u5E38\u91CF\u679A\u4E3E\u300C").concat(node.name.text, "\u300D\u7684\u5B57\u7B26\u4E32\u957F\u5EA6\u5E94\u5C0F\u4E8E").concat(env_1.STRING_LITERAL_MAX_LENGTH));
|
|
577
|
+
});
|
|
555
578
|
}
|
|
556
579
|
}
|
|
557
580
|
}
|
|
@@ -793,6 +816,8 @@ function analyzeEntity(filename, path, program) {
|
|
|
793
816
|
actionType: actionType,
|
|
794
817
|
static: _static,
|
|
795
818
|
hasRelationDef: hasRelationDef,
|
|
819
|
+
enumStringAttrs: enumStringAttrs.concat(states),
|
|
820
|
+
additionalImports: additionalImports,
|
|
796
821
|
};
|
|
797
822
|
if (hasFulltextIndex) {
|
|
798
823
|
(0, lodash_1.assign)(schema, {
|
|
@@ -2628,6 +2653,10 @@ function outputSchema(outputDir, printer) {
|
|
|
2628
2653
|
factory.createImportSpecifier(false, undefined, factory.createIdentifier("RelationAction")),
|
|
2629
2654
|
])), factory.createStringLiteral((0, env_1.ACTION_CONSTANT_IN_OAK_DOMAIN)()), undefined));
|
|
2630
2655
|
}
|
|
2656
|
+
var additionalImports = Schema[entity].additionalImports;
|
|
2657
|
+
if ((additionalImports === null || additionalImports === void 0 ? void 0 : additionalImports.length) > 0) {
|
|
2658
|
+
statements.push.apply(statements, tslib_1.__spreadArray([], tslib_1.__read(additionalImports), false));
|
|
2659
|
+
}
|
|
2631
2660
|
constructSchema(statements, entity);
|
|
2632
2661
|
constructFilter(statements, entity);
|
|
2633
2662
|
constructProjection(statements, entity);
|
|
@@ -2709,8 +2738,8 @@ function outputAction(outputDir, printer) {
|
|
|
2709
2738
|
(0, fs_1.writeFileSync)(fileName, result, { flag: 'w' });
|
|
2710
2739
|
}
|
|
2711
2740
|
function constructAttributes(entity) {
|
|
2712
|
-
var
|
|
2713
|
-
var
|
|
2741
|
+
var _a = Schema[entity], schemaAttrs = _a.schemaAttrs, enumStringAttrs = _a.enumStringAttrs;
|
|
2742
|
+
var _b = ManyToOne, _c = entity, manyToOneSet = _b[_c];
|
|
2714
2743
|
var result = [];
|
|
2715
2744
|
schemaAttrs.forEach(function (attr) {
|
|
2716
2745
|
var attrAssignments = [];
|
|
@@ -2786,11 +2815,11 @@ function constructAttributes(entity) {
|
|
|
2786
2815
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("ref")), factory.createPropertyAssignment(factory.createIdentifier("ref"), factory.createStringLiteral((0, string_1.firstLetterLowerCase)(text2_6))));
|
|
2787
2816
|
}
|
|
2788
2817
|
else {
|
|
2789
|
-
if (
|
|
2818
|
+
if (enumStringAttrs.includes(name.text)) {
|
|
2790
2819
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("varchar")), factory.createPropertyAssignment(factory.createIdentifier("params"), factory.createObjectLiteralExpression([factory.createPropertyAssignment(factory.createIdentifier("length"), factory.createNumericLiteral(env_1.STRING_LITERAL_MAX_LENGTH))], true)));
|
|
2791
2820
|
}
|
|
2792
2821
|
else {
|
|
2793
|
-
//
|
|
2822
|
+
// todo 引用的非string定义,目前没有处理int类型的引用,等遇到了再处理
|
|
2794
2823
|
attrAssignments.push(factory.createPropertyAssignment(factory.createIdentifier("type"), factory.createStringLiteral("object")));
|
|
2795
2824
|
}
|
|
2796
2825
|
}
|
|
@@ -3065,7 +3094,6 @@ function analyzeInModi() {
|
|
|
3065
3094
|
if (schema.toModi || schema.inModi || schema.actionType === 'readOnly' || schema.static) {
|
|
3066
3095
|
return;
|
|
3067
3096
|
}
|
|
3068
|
-
console.log('setInModi', entity);
|
|
3069
3097
|
schema.inModi = true;
|
|
3070
3098
|
var related = getRelateEntities(entity);
|
|
3071
3099
|
related.forEach(function (ele) { return setInModi(ele); });
|
|
@@ -3077,7 +3105,7 @@ function analyzeInModi() {
|
|
|
3077
3105
|
}
|
|
3078
3106
|
}
|
|
3079
3107
|
}
|
|
3080
|
-
function analyzeEntities(inputDir) {
|
|
3108
|
+
function analyzeEntities(inputDir, relativePath) {
|
|
3081
3109
|
var files = (0, fs_1.readdirSync)(inputDir);
|
|
3082
3110
|
var fullFilenames = files.map(function (ele) {
|
|
3083
3111
|
var entity = ele.slice(0, ele.indexOf('.'));
|
|
@@ -3088,7 +3116,7 @@ function analyzeEntities(inputDir) {
|
|
|
3088
3116
|
});
|
|
3089
3117
|
var program = ts.createProgram(fullFilenames, { allowJs: true });
|
|
3090
3118
|
files.forEach(function (filename) {
|
|
3091
|
-
analyzeEntity(filename, inputDir, program);
|
|
3119
|
+
analyzeEntity(filename, inputDir, program, relativePath);
|
|
3092
3120
|
});
|
|
3093
3121
|
analyzeInModi();
|
|
3094
3122
|
}
|
|
@@ -280,7 +280,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
280
280
|
}
|
|
281
281
|
else {
|
|
282
282
|
(0, assert_1.default)(relation instanceof Array);
|
|
283
|
-
var _g = projection2[attr], subProjection_1 = _g.data, subFilter_1 = _g.filter, indexFrom_1 = _g.indexFrom, count_1 = _g.count,
|
|
283
|
+
var _g = projection2[attr], subProjection_1 = _g.data, subFilter_1 = _g.filter, indexFrom_1 = _g.indexFrom, count_1 = _g.count, subSorter_1 = _g.sorter;
|
|
284
284
|
var _h = tslib_1.__read(relation, 2), entity2_1 = _h[0], foreignKey_1 = _h[1];
|
|
285
285
|
if (foreignKey_1) {
|
|
286
286
|
// 基于属性的一对多
|
|
@@ -298,6 +298,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
298
298
|
$in: ids,
|
|
299
299
|
},
|
|
300
300
|
_a), subFilter_1]),
|
|
301
|
+
sorter: subSorter_1,
|
|
301
302
|
indexFrom: indexFrom_1,
|
|
302
303
|
count: count_1
|
|
303
304
|
}, context, option)];
|
|
@@ -332,6 +333,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
332
333
|
$in: ids,
|
|
333
334
|
}
|
|
334
335
|
}, subFilter_1]),
|
|
336
|
+
sorter: subSorter_1,
|
|
335
337
|
indexFrom: indexFrom_1,
|
|
336
338
|
count: count_1
|
|
337
339
|
}, context, option)];
|
|
@@ -1005,36 +1007,34 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1005
1007
|
*/
|
|
1006
1008
|
CascadeStore.prototype.cascadeUpdate = function (entity, operation, context, option) {
|
|
1007
1009
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
1008
|
-
var action, data, filter, id, opData, result,
|
|
1009
|
-
var e_3, _a,
|
|
1010
|
-
return tslib_1.__generator(this, function (
|
|
1011
|
-
switch (
|
|
1010
|
+
var action, data, filter, id, opData, result, data_1, data_1_1, d, od, e_3_1, operation2, count;
|
|
1011
|
+
var e_3, _a, _b, _c;
|
|
1012
|
+
return tslib_1.__generator(this, function (_d) {
|
|
1013
|
+
switch (_d.label) {
|
|
1012
1014
|
case 0:
|
|
1013
1015
|
action = operation.action, data = operation.data, filter = operation.filter, id = operation.id;
|
|
1014
1016
|
result = {};
|
|
1015
|
-
if (!(['create', 'create-l'].includes(action) && data instanceof Array)) return [3 /*break*/,
|
|
1016
|
-
multipleCreate = this.supportMultipleCreate();
|
|
1017
|
-
if (!multipleCreate) return [3 /*break*/, 9];
|
|
1017
|
+
if (!(['create', 'create-l'].includes(action) && data instanceof Array)) return [3 /*break*/, 9];
|
|
1018
1018
|
opData = [];
|
|
1019
|
-
|
|
1019
|
+
_d.label = 1;
|
|
1020
1020
|
case 1:
|
|
1021
|
-
|
|
1021
|
+
_d.trys.push([1, 6, 7, 8]);
|
|
1022
1022
|
data_1 = tslib_1.__values(data), data_1_1 = data_1.next();
|
|
1023
|
-
|
|
1023
|
+
_d.label = 2;
|
|
1024
1024
|
case 2:
|
|
1025
1025
|
if (!!data_1_1.done) return [3 /*break*/, 5];
|
|
1026
1026
|
d = data_1_1.value;
|
|
1027
1027
|
return [4 /*yield*/, this.destructCascadeUpdate(entity, action, d, context, option, result)];
|
|
1028
1028
|
case 3:
|
|
1029
|
-
od =
|
|
1029
|
+
od = _d.sent();
|
|
1030
1030
|
opData.push(od);
|
|
1031
|
-
|
|
1031
|
+
_d.label = 4;
|
|
1032
1032
|
case 4:
|
|
1033
1033
|
data_1_1 = data_1.next();
|
|
1034
1034
|
return [3 /*break*/, 2];
|
|
1035
1035
|
case 5: return [3 /*break*/, 8];
|
|
1036
1036
|
case 6:
|
|
1037
|
-
e_3_1 =
|
|
1037
|
+
e_3_1 = _d.sent();
|
|
1038
1038
|
e_3 = { error: e_3_1 };
|
|
1039
1039
|
return [3 /*break*/, 8];
|
|
1040
1040
|
case 7:
|
|
@@ -1043,55 +1043,23 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1043
1043
|
}
|
|
1044
1044
|
finally { if (e_3) throw e_3.error; }
|
|
1045
1045
|
return [7 /*endfinally*/];
|
|
1046
|
-
case 8: return [3 /*break*/,
|
|
1047
|
-
case 9:
|
|
1048
|
-
_e.trys.push([9, 14, 15, 16]);
|
|
1049
|
-
data_2 = tslib_1.__values(data), data_2_1 = data_2.next();
|
|
1050
|
-
_e.label = 10;
|
|
1046
|
+
case 8: return [3 /*break*/, 11];
|
|
1047
|
+
case 9: return [4 /*yield*/, this.destructCascadeUpdate(entity, action, data, context, option, result, filter)];
|
|
1051
1048
|
case 10:
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
return [4 /*yield*/, this.cascadeUpdate(entity, {
|
|
1055
|
-
id: id,
|
|
1056
|
-
action: action,
|
|
1057
|
-
data: dataEle,
|
|
1058
|
-
}, context, option)];
|
|
1049
|
+
opData = _d.sent();
|
|
1050
|
+
_d.label = 11;
|
|
1059
1051
|
case 11:
|
|
1060
|
-
result2 = _e.sent();
|
|
1061
|
-
this.mergeOperationResult(result, result2);
|
|
1062
|
-
_e.label = 12;
|
|
1063
|
-
case 12:
|
|
1064
|
-
data_2_1 = data_2.next();
|
|
1065
|
-
return [3 /*break*/, 10];
|
|
1066
|
-
case 13: return [3 /*break*/, 16];
|
|
1067
|
-
case 14:
|
|
1068
|
-
e_4_1 = _e.sent();
|
|
1069
|
-
e_4 = { error: e_4_1 };
|
|
1070
|
-
return [3 /*break*/, 16];
|
|
1071
|
-
case 15:
|
|
1072
|
-
try {
|
|
1073
|
-
if (data_2_1 && !data_2_1.done && (_b = data_2.return)) _b.call(data_2);
|
|
1074
|
-
}
|
|
1075
|
-
finally { if (e_4) throw e_4.error; }
|
|
1076
|
-
return [7 /*endfinally*/];
|
|
1077
|
-
case 16: return [2 /*return*/, result];
|
|
1078
|
-
case 17: return [3 /*break*/, 20];
|
|
1079
|
-
case 18: return [4 /*yield*/, this.destructCascadeUpdate(entity, action, data, context, option, result, filter)];
|
|
1080
|
-
case 19:
|
|
1081
|
-
opData = _e.sent();
|
|
1082
|
-
_e.label = 20;
|
|
1083
|
-
case 20:
|
|
1084
1052
|
operation2 = Object.assign({}, operation, {
|
|
1085
1053
|
data: opData,
|
|
1086
1054
|
});
|
|
1087
1055
|
return [4 /*yield*/, this.doUpdateSingleRow(entity, operation2, context, option)];
|
|
1088
|
-
case
|
|
1089
|
-
count =
|
|
1090
|
-
this.mergeOperationResult(result, (
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1056
|
+
case 12:
|
|
1057
|
+
count = _d.sent();
|
|
1058
|
+
this.mergeOperationResult(result, (_b = {},
|
|
1059
|
+
_b[entity] = (_c = {},
|
|
1060
|
+
_c[operation2.action] = count,
|
|
1061
|
+
_c),
|
|
1062
|
+
_b));
|
|
1095
1063
|
return [2 /*return*/, result];
|
|
1096
1064
|
}
|
|
1097
1065
|
});
|
|
@@ -1106,11 +1074,11 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1106
1074
|
*/
|
|
1107
1075
|
CascadeStore.prototype.doUpdateSingleRow = function (entity, operation, context, option) {
|
|
1108
1076
|
return tslib_1.__awaiter(this, void 0, void 0, function () {
|
|
1109
|
-
var data, action, operId, filter, now, _a, modiCreate, addTimestamp_1, result_1,
|
|
1110
|
-
var
|
|
1077
|
+
var data, action, operId, filter, now, _a, modiCreate, addTimestamp_1, result_1, createInner, multipleCreate, data_2, data_2_1, d, createSingleOper, e_4_1, createOper, _b, ids_1, selection, rows, modiUpsert, upsertModis, _c, originData, originId, createOper, updateAttrCount, result_2;
|
|
1078
|
+
var e_4, _d, _e, _f, _g, _h, _j, _k, _l, _m;
|
|
1111
1079
|
var _this = this;
|
|
1112
|
-
return tslib_1.__generator(this, function (
|
|
1113
|
-
switch (
|
|
1080
|
+
return tslib_1.__generator(this, function (_o) {
|
|
1081
|
+
switch (_o.label) {
|
|
1114
1082
|
case 0:
|
|
1115
1083
|
data = operation.data, action = operation.action, operId = operation.id, filter = operation.filter;
|
|
1116
1084
|
now = Date.now();
|
|
@@ -1141,7 +1109,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1141
1109
|
};
|
|
1142
1110
|
return [4 /*yield*/, this.cascadeUpdate('modi', modiCreate, context, option)];
|
|
1143
1111
|
case 2:
|
|
1144
|
-
|
|
1112
|
+
_o.sent();
|
|
1145
1113
|
return [2 /*return*/, 1];
|
|
1146
1114
|
case 3:
|
|
1147
1115
|
addTimestamp_1 = function (data2) {
|
|
@@ -1156,67 +1124,128 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1156
1124
|
else {
|
|
1157
1125
|
addTimestamp_1(data);
|
|
1158
1126
|
}
|
|
1159
|
-
|
|
1127
|
+
createInner = function (operation2) { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
1128
|
+
var e_5;
|
|
1129
|
+
return tslib_1.__generator(this, function (_a) {
|
|
1130
|
+
switch (_a.label) {
|
|
1131
|
+
case 0:
|
|
1132
|
+
_a.trys.push([0, 2, , 3]);
|
|
1133
|
+
return [4 /*yield*/, this.updateAbjointRow(entity, operation2, context, option)];
|
|
1134
|
+
case 1:
|
|
1135
|
+
result_1 = _a.sent();
|
|
1136
|
+
return [3 /*break*/, 3];
|
|
1137
|
+
case 2:
|
|
1138
|
+
e_5 = _a.sent();
|
|
1139
|
+
/* 这段代码是处理插入时有重复的行,现在看有问题,等实际需求出现再写
|
|
1140
|
+
if (e instanceof OakCongruentRowExists) {
|
|
1141
|
+
if (option.allowExists) {
|
|
1142
|
+
// 如果允许存在,对已存在行进行update,剩下的行继续insert
|
|
1143
|
+
const congruentRow = e.getData() as ED[T]['OpSchema'];
|
|
1144
|
+
if (data instanceof Array) {
|
|
1145
|
+
const rest = data.filter(
|
|
1146
|
+
ele => ele.id !== congruentRow.id
|
|
1147
|
+
);
|
|
1148
|
+
if (rest.length === data.length) {
|
|
1149
|
+
throw e;
|
|
1150
|
+
}
|
|
1151
|
+
const result2 = await this.updateAbjointRow(
|
|
1152
|
+
entity,
|
|
1153
|
+
Object.assign({}, operation, {
|
|
1154
|
+
data: rest,
|
|
1155
|
+
}),
|
|
1156
|
+
context,
|
|
1157
|
+
option
|
|
1158
|
+
);
|
|
1159
|
+
|
|
1160
|
+
const row = data.find(
|
|
1161
|
+
ele => ele.id === congruentRow.id
|
|
1162
|
+
);
|
|
1163
|
+
const updateData = omit(row, ['id', '$$createAt$$']);
|
|
1164
|
+
const result3 = await this.updateAbjointRow(
|
|
1165
|
+
entity,
|
|
1166
|
+
{
|
|
1167
|
+
id: await generateNewId(),
|
|
1168
|
+
action: 'update',
|
|
1169
|
+
data: updateData,
|
|
1170
|
+
filter: {
|
|
1171
|
+
id: congruentRow.id,
|
|
1172
|
+
} as any,
|
|
1173
|
+
},
|
|
1174
|
+
context,
|
|
1175
|
+
option
|
|
1176
|
+
);
|
|
1177
|
+
|
|
1178
|
+
return result2 + result3;
|
|
1179
|
+
}
|
|
1180
|
+
else {
|
|
1181
|
+
if (data.id !== congruentRow.id) {
|
|
1182
|
+
throw e;
|
|
1183
|
+
}
|
|
1184
|
+
const updateData = omit(data, ['id', '$$createAt$$']);
|
|
1185
|
+
const result2 = await this.updateAbjointRow(
|
|
1186
|
+
entity,
|
|
1187
|
+
{
|
|
1188
|
+
id: await generateNewId(),
|
|
1189
|
+
action: 'update',
|
|
1190
|
+
data: updateData,
|
|
1191
|
+
filter: {
|
|
1192
|
+
id: congruentRow.id,
|
|
1193
|
+
} as any,
|
|
1194
|
+
},
|
|
1195
|
+
context,
|
|
1196
|
+
option
|
|
1197
|
+
);
|
|
1198
|
+
return result2;
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
} */
|
|
1202
|
+
throw e_5;
|
|
1203
|
+
case 3: return [2 /*return*/];
|
|
1204
|
+
}
|
|
1205
|
+
});
|
|
1206
|
+
}); };
|
|
1207
|
+
if (!(data instanceof Array)) return [3 /*break*/, 13];
|
|
1208
|
+
multipleCreate = this.supportMultipleCreate();
|
|
1209
|
+
if (!multipleCreate) return [3 /*break*/, 5];
|
|
1210
|
+
return [4 /*yield*/, createInner(operation)];
|
|
1160
1211
|
case 4:
|
|
1161
|
-
|
|
1162
|
-
return [
|
|
1212
|
+
_o.sent();
|
|
1213
|
+
return [3 /*break*/, 12];
|
|
1163
1214
|
case 5:
|
|
1164
|
-
|
|
1165
|
-
|
|
1215
|
+
_o.trys.push([5, 10, 11, 12]);
|
|
1216
|
+
data_2 = tslib_1.__values(data), data_2_1 = data_2.next();
|
|
1217
|
+
_o.label = 6;
|
|
1166
1218
|
case 6:
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
}
|
|
1176
|
-
return [4 /*yield*/, this.updateAbjointRow(entity, Object.assign({}, operation, {
|
|
1177
|
-
data: rest,
|
|
1178
|
-
}), context, option)];
|
|
1219
|
+
if (!!data_2_1.done) return [3 /*break*/, 9];
|
|
1220
|
+
d = data_2_1.value;
|
|
1221
|
+
createSingleOper = {
|
|
1222
|
+
id: 'any',
|
|
1223
|
+
action: 'create',
|
|
1224
|
+
data: d,
|
|
1225
|
+
};
|
|
1226
|
+
return [4 /*yield*/, createInner(createSingleOper)];
|
|
1179
1227
|
case 7:
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
return [4 /*yield*/, generateNewId()];
|
|
1187
|
-
case 8: return [4 /*yield*/, _b.apply(this, _c.concat([(_h.id = _t.sent(),
|
|
1188
|
-
_h.action = 'update',
|
|
1189
|
-
_h.data = updateData,
|
|
1190
|
-
_h.filter = {
|
|
1191
|
-
id: congruentRow_1.id,
|
|
1192
|
-
},
|
|
1193
|
-
_h), context,
|
|
1194
|
-
option]))];
|
|
1195
|
-
case 9:
|
|
1196
|
-
result3 = _t.sent();
|
|
1197
|
-
return [2 /*return*/, result2 + result3];
|
|
1228
|
+
_o.sent();
|
|
1229
|
+
_o.label = 8;
|
|
1230
|
+
case 8:
|
|
1231
|
+
data_2_1 = data_2.next();
|
|
1232
|
+
return [3 /*break*/, 6];
|
|
1233
|
+
case 9: return [3 /*break*/, 12];
|
|
1198
1234
|
case 10:
|
|
1199
|
-
|
|
1200
|
-
|
|
1235
|
+
e_4_1 = _o.sent();
|
|
1236
|
+
e_4 = { error: e_4_1 };
|
|
1237
|
+
return [3 /*break*/, 12];
|
|
1238
|
+
case 11:
|
|
1239
|
+
try {
|
|
1240
|
+
if (data_2_1 && !data_2_1.done && (_d = data_2.return)) _d.call(data_2);
|
|
1201
1241
|
}
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
_j.data = updateData,
|
|
1210
|
-
_j.filter = {
|
|
1211
|
-
id: congruentRow_1.id,
|
|
1212
|
-
},
|
|
1213
|
-
_j), context,
|
|
1214
|
-
option]))];
|
|
1215
|
-
case 12:
|
|
1216
|
-
result2 = _t.sent();
|
|
1217
|
-
return [2 /*return*/, result2];
|
|
1218
|
-
case 13: throw e_5;
|
|
1219
|
-
case 14: return [3 /*break*/, 15];
|
|
1242
|
+
finally { if (e_4) throw e_4.error; }
|
|
1243
|
+
return [7 /*endfinally*/];
|
|
1244
|
+
case 12: return [3 /*break*/, 15];
|
|
1245
|
+
case 13: return [4 /*yield*/, createInner(operation)];
|
|
1246
|
+
case 14:
|
|
1247
|
+
_o.sent();
|
|
1248
|
+
_o.label = 15;
|
|
1220
1249
|
case 15:
|
|
1221
1250
|
if (!option.dontCollect) {
|
|
1222
1251
|
context.opRecords.push({
|
|
@@ -1228,20 +1257,20 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1228
1257
|
if (!(!option.dontCreateOper && !['oper', 'operEntity', 'modiEntity', 'modi'].includes(entity))) return [3 /*break*/, 22];
|
|
1229
1258
|
// 按照框架要求生成Oper和OperEntity这两个内置的对象
|
|
1230
1259
|
(0, assert_1.default)(operId);
|
|
1231
|
-
|
|
1260
|
+
_e = {
|
|
1232
1261
|
id: 'dummy',
|
|
1233
1262
|
action: 'create'
|
|
1234
1263
|
};
|
|
1235
|
-
|
|
1264
|
+
_f = {
|
|
1236
1265
|
id: operId,
|
|
1237
1266
|
action: action,
|
|
1238
1267
|
data: data
|
|
1239
1268
|
};
|
|
1240
1269
|
return [4 /*yield*/, context.getCurrentUserId()];
|
|
1241
1270
|
case 16:
|
|
1242
|
-
|
|
1271
|
+
_f.operatorId = _o.sent();
|
|
1243
1272
|
if (!(data instanceof Array)) return [3 /*break*/, 18];
|
|
1244
|
-
|
|
1273
|
+
_g = {
|
|
1245
1274
|
id: 'dummy',
|
|
1246
1275
|
action: 'create'
|
|
1247
1276
|
};
|
|
@@ -1260,34 +1289,34 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1260
1289
|
});
|
|
1261
1290
|
}); }))];
|
|
1262
1291
|
case 17:
|
|
1263
|
-
|
|
1264
|
-
|
|
1292
|
+
_b = (_g.data = _o.sent(),
|
|
1293
|
+
_g);
|
|
1265
1294
|
return [3 /*break*/, 20];
|
|
1266
1295
|
case 18:
|
|
1267
|
-
|
|
1296
|
+
_h = {
|
|
1268
1297
|
id: 'dummy',
|
|
1269
1298
|
action: 'create'
|
|
1270
1299
|
};
|
|
1271
|
-
|
|
1300
|
+
_j = {};
|
|
1272
1301
|
return [4 /*yield*/, generateNewId()];
|
|
1273
1302
|
case 19:
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
|
|
1277
|
-
|
|
1278
|
-
|
|
1279
|
-
|
|
1303
|
+
_b = [(_h.data = (_j.id = _o.sent(),
|
|
1304
|
+
_j.entity = entity,
|
|
1305
|
+
_j.entityId = data.id,
|
|
1306
|
+
_j),
|
|
1307
|
+
_h)];
|
|
1308
|
+
_o.label = 20;
|
|
1280
1309
|
case 20:
|
|
1281
|
-
createOper = (
|
|
1282
|
-
|
|
1283
|
-
|
|
1310
|
+
createOper = (_e.data = (_f.operEntity$oper = _b,
|
|
1311
|
+
_f),
|
|
1312
|
+
_e);
|
|
1284
1313
|
return [4 /*yield*/, this.cascadeUpdate('oper', createOper, context, {
|
|
1285
1314
|
dontCollect: true,
|
|
1286
1315
|
dontCreateOper: true,
|
|
1287
1316
|
})];
|
|
1288
1317
|
case 21:
|
|
1289
|
-
|
|
1290
|
-
|
|
1318
|
+
_o.sent();
|
|
1319
|
+
_o.label = 22;
|
|
1291
1320
|
case 22: return [2 /*return*/, result_1];
|
|
1292
1321
|
case 23:
|
|
1293
1322
|
ids_1 = (0, filter_1.getRelevantIds)(filter);
|
|
@@ -1304,9 +1333,9 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1304
1333
|
dontCollect: true,
|
|
1305
1334
|
})];
|
|
1306
1335
|
case 24:
|
|
1307
|
-
rows =
|
|
1336
|
+
rows = _o.sent();
|
|
1308
1337
|
ids_1.push.apply(ids_1, tslib_1.__spreadArray([], tslib_1.__read((rows.map(function (ele) { return ele.id; }))), false));
|
|
1309
|
-
|
|
1338
|
+
_o.label = 25;
|
|
1310
1339
|
case 25:
|
|
1311
1340
|
if (!(option.modiParentEntity && !['modi', 'modiEntity'].includes(entity))) return [3 /*break*/, 31];
|
|
1312
1341
|
modiUpsert = void 0;
|
|
@@ -1340,9 +1369,9 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1340
1369
|
count: 1,
|
|
1341
1370
|
}, context, option)];
|
|
1342
1371
|
case 26:
|
|
1343
|
-
upsertModis =
|
|
1372
|
+
upsertModis = _o.sent();
|
|
1344
1373
|
if (upsertModis.length > 0) {
|
|
1345
|
-
|
|
1374
|
+
_c = upsertModis[0], originData = _c.data, originId = _c.id;
|
|
1346
1375
|
modiUpsert = {
|
|
1347
1376
|
id: 'dummy',
|
|
1348
1377
|
action: 'update',
|
|
@@ -1354,14 +1383,14 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1354
1383
|
}
|
|
1355
1384
|
};
|
|
1356
1385
|
}
|
|
1357
|
-
|
|
1386
|
+
_o.label = 27;
|
|
1358
1387
|
case 27:
|
|
1359
1388
|
if (!!modiUpsert) return [3 /*break*/, 29];
|
|
1360
|
-
|
|
1389
|
+
_k = {
|
|
1361
1390
|
id: 'dummy',
|
|
1362
1391
|
action: 'create'
|
|
1363
1392
|
};
|
|
1364
|
-
|
|
1393
|
+
_l = {
|
|
1365
1394
|
id: operId,
|
|
1366
1395
|
targetEntity: entity,
|
|
1367
1396
|
entity: option.modiParentEntity,
|
|
@@ -1375,7 +1404,7 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1375
1404
|
},
|
|
1376
1405
|
}
|
|
1377
1406
|
};
|
|
1378
|
-
|
|
1407
|
+
_m = {
|
|
1379
1408
|
id: 'dummy',
|
|
1380
1409
|
action: 'create'
|
|
1381
1410
|
};
|
|
@@ -1394,14 +1423,14 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1394
1423
|
});
|
|
1395
1424
|
}); }))];
|
|
1396
1425
|
case 28:
|
|
1397
|
-
modiUpsert = (
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1426
|
+
modiUpsert = (_k.data = (_l.modiEntity$modi = (_m.data = _o.sent(),
|
|
1427
|
+
_m),
|
|
1428
|
+
_l),
|
|
1429
|
+
_k);
|
|
1430
|
+
_o.label = 29;
|
|
1402
1431
|
case 29: return [4 /*yield*/, this.cascadeUpdate('modi', modiUpsert, context, option)];
|
|
1403
1432
|
case 30:
|
|
1404
|
-
|
|
1433
|
+
_o.sent();
|
|
1405
1434
|
return [2 /*return*/, 1];
|
|
1406
1435
|
case 31:
|
|
1407
1436
|
createOper = function () { return tslib_1.__awaiter(_this, void 0, void 0, function () {
|
|
@@ -1496,15 +1525,15 @@ var CascadeStore = /** @class */ (function (_super) {
|
|
|
1496
1525
|
return [4 /*yield*/, createOper()];
|
|
1497
1526
|
case 34:
|
|
1498
1527
|
// 如果不是update动作而是用户自定义的动作,这里还是要记录oper
|
|
1499
|
-
|
|
1528
|
+
_o.sent();
|
|
1500
1529
|
return [2 /*return*/, 0];
|
|
1501
1530
|
case 35: return [2 /*return*/, 0];
|
|
1502
1531
|
case 36: return [4 /*yield*/, this.updateAbjointRow(entity, operation, context, option)];
|
|
1503
1532
|
case 37:
|
|
1504
|
-
result_2 =
|
|
1533
|
+
result_2 = _o.sent();
|
|
1505
1534
|
return [4 /*yield*/, createOper()];
|
|
1506
1535
|
case 38:
|
|
1507
|
-
|
|
1536
|
+
_o.sent();
|
|
1508
1537
|
return [2 /*return*/, result_2];
|
|
1509
1538
|
}
|
|
1510
1539
|
});
|
|
@@ -3,7 +3,7 @@ import { EntityDict as BaseEntityDict } from '../base-app-domain';
|
|
|
3
3
|
import { Logger } from "../types/Logger";
|
|
4
4
|
import { Checker } from '../types/Auth';
|
|
5
5
|
import { Context } from '../types/Context';
|
|
6
|
-
import { Trigger, Executor } from "../types/Trigger";
|
|
6
|
+
import { Trigger, Executor, CheckerType } from "../types/Trigger";
|
|
7
7
|
/**
|
|
8
8
|
* update可能会传入多种不同的action,此时都需要检查update trigger
|
|
9
9
|
*/
|
|
@@ -16,6 +16,7 @@ export declare class TriggerExecutor<ED extends EntityDict & BaseEntityDict, Cxt
|
|
|
16
16
|
private contextBuilder;
|
|
17
17
|
constructor(contextBuilder: (cxtString: string) => Promise<Cxt>, logger?: Logger);
|
|
18
18
|
registerChecker<T extends keyof ED>(checker: Checker<ED, T, Cxt>): void;
|
|
19
|
+
getCheckers<T extends keyof ED>(entity: T, action: ED[T]['Action'], checkerTypes?: CheckerType[]): Trigger<ED, T, Cxt>[] | undefined;
|
|
19
20
|
registerTrigger<T extends keyof ED>(trigger: Trigger<ED, T, Cxt>): void;
|
|
20
21
|
unregisterTrigger<T extends keyof ED>(trigger: Trigger<ED, T, Cxt>): void;
|
|
21
22
|
private preCommitTrigger;
|
|
@@ -43,6 +43,12 @@ var TriggerExecutor = /** @class */ (function (_super) {
|
|
|
43
43
|
};
|
|
44
44
|
this.registerTrigger(trigger);
|
|
45
45
|
};
|
|
46
|
+
TriggerExecutor.prototype.getCheckers = function (entity, action, checkerTypes) {
|
|
47
|
+
var _a;
|
|
48
|
+
var triggers = this.triggerMap[entity] && ((_a = this.triggerMap[entity][action]) === null || _a === void 0 ? void 0 : _a.filter(function (trigger) { return (typeof trigger.action === 'string' && trigger.action === action || (trigger.action).includes(action))
|
|
49
|
+
&& (!checkerTypes || trigger.checkerType && checkerTypes.includes(trigger.checkerType)); }));
|
|
50
|
+
return triggers;
|
|
51
|
+
};
|
|
46
52
|
TriggerExecutor.prototype.registerTrigger = function (trigger) {
|
|
47
53
|
var _a;
|
|
48
54
|
var _this = this;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { IncomingHttpHeaders } from 'http';
|
|
1
3
|
import { EntityDict, OpRecord, RowStore, TxnOption, Context } from "../types";
|
|
2
4
|
export declare abstract class UniversalContext<ED extends EntityDict> implements Context<ED> {
|
|
3
5
|
rowStore: RowStore<ED, this>;
|
|
@@ -5,11 +7,14 @@ export declare abstract class UniversalContext<ED extends EntityDict> implements
|
|
|
5
7
|
opRecords: OpRecord<ED>[];
|
|
6
8
|
private scene?;
|
|
7
9
|
private rwLock;
|
|
10
|
+
private headers?;
|
|
8
11
|
events: {
|
|
9
12
|
commit: Array<() => Promise<void>>;
|
|
10
13
|
rollback: Array<() => Promise<void>>;
|
|
11
14
|
};
|
|
12
|
-
constructor(store: RowStore<ED, UniversalContext<ED
|
|
15
|
+
constructor(store: RowStore<ED, UniversalContext<ED>>, headers?: IncomingHttpHeaders);
|
|
16
|
+
setHeaders(headers: IncomingHttpHeaders): void;
|
|
17
|
+
getHeader(key: string): string | string[] | undefined;
|
|
13
18
|
getScene(): string | undefined;
|
|
14
19
|
setScene(scene?: string): void;
|
|
15
20
|
private resetEvents;
|
|
@@ -5,7 +5,7 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
6
6
|
var concurrent_1 = require("../utils/concurrent");
|
|
7
7
|
var UniversalContext = /** @class */ (function () {
|
|
8
|
-
function UniversalContext(store) {
|
|
8
|
+
function UniversalContext(store, headers) {
|
|
9
9
|
this.rowStore = store;
|
|
10
10
|
this.opRecords = [];
|
|
11
11
|
this.rwLock = new concurrent_1.RWLock();
|
|
@@ -13,7 +13,18 @@ var UniversalContext = /** @class */ (function () {
|
|
|
13
13
|
commit: [],
|
|
14
14
|
rollback: [],
|
|
15
15
|
};
|
|
16
|
+
if (headers) {
|
|
17
|
+
this.headers = headers;
|
|
18
|
+
}
|
|
16
19
|
}
|
|
20
|
+
UniversalContext.prototype.setHeaders = function (headers) {
|
|
21
|
+
this.headers = headers;
|
|
22
|
+
};
|
|
23
|
+
UniversalContext.prototype.getHeader = function (key) {
|
|
24
|
+
if (this.headers) {
|
|
25
|
+
return this.headers[key];
|
|
26
|
+
}
|
|
27
|
+
};
|
|
17
28
|
UniversalContext.prototype.getScene = function () {
|
|
18
29
|
return this.scene;
|
|
19
30
|
};
|
package/lib/store/filter.d.ts
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { StorageSchema } from '../types';
|
|
2
2
|
import { EntityDict } from "../types/Entity";
|
|
3
3
|
export declare function addFilterSegment<ED extends EntityDict, T extends keyof ED>(...filters: ED[T]['Selection']['filter'][]): ED[T]["Selection"]["filter"];
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function unionFilterSegment<ED extends EntityDict, T extends keyof ED>(...filters: ED[T]['Selection']['filter'][]): ED[T]["Selection"]["filter"];
|
|
5
|
+
export declare function combineFilters<ED extends EntityDict, T extends keyof ED>(filters: Array<ED[T]['Selection']['filter']>, union?: true): ED[T]["Selection"]["filter"];
|
|
5
6
|
/**
|
|
6
7
|
* 判断filter是否包含conditionalFilter中的查询条件,即filter查询的结果一定满足conditionalFilter的约束
|
|
7
8
|
* filter = {
|
|
@@ -40,3 +41,29 @@ export declare function repel<ED extends EntityDict, T extends keyof ED>(entity:
|
|
|
40
41
|
* @returns
|
|
41
42
|
*/
|
|
42
43
|
export declare function getRelevantIds<ED extends EntityDict, T extends keyof ED>(filter: ED[T]['Selection']['filter']): string[];
|
|
44
|
+
/**
|
|
45
|
+
* 判断两个过滤条件是否完全一致
|
|
46
|
+
* @param entity
|
|
47
|
+
* @param schema
|
|
48
|
+
* @param filter1
|
|
49
|
+
* @param filter2
|
|
50
|
+
*/
|
|
51
|
+
export declare function same<ED extends EntityDict, T extends keyof ED>(entity: T, schema: StorageSchema<ED>, filter1: ED[T]['Selection']['filter'], filter2: ED[T]['Selection']['filter']): boolean;
|
|
52
|
+
/**
|
|
53
|
+
* 寻找在树形结构中满足条件的数据行的上层数据
|
|
54
|
+
* 例如在area表中,如果“杭州市”满足这一条件,则希望查到更高层的“浙江省”和“中国”,即可构造出满足条件的filter
|
|
55
|
+
* @param entity
|
|
56
|
+
* @param parentKey parentId属性名
|
|
57
|
+
* @param filter 查询当前行的条件
|
|
58
|
+
* @param level
|
|
59
|
+
*/
|
|
60
|
+
export declare function makeTreeAncestorFilter<ED extends EntityDict, T extends keyof ED>(entity: T, parentKey: string, filter: ED[T]['Selection']['filter'], level?: number, includeAll?: boolean, includeSelf?: boolean): ED[T]['Selection']['filter'];
|
|
61
|
+
/**
|
|
62
|
+
* 寻找在树形结构中满足条件的数据行的下层数据
|
|
63
|
+
* 例如在area表中,如果“杭州市”满足这一条件,则希望查到更低层的“西湖区”,即可构造出满足条件的filter
|
|
64
|
+
* @param entity
|
|
65
|
+
* @param parentKey parentId属性名
|
|
66
|
+
* @param filter 查询当前行的条件
|
|
67
|
+
* @param level
|
|
68
|
+
*/
|
|
69
|
+
export declare function makeTreeDescendantFilter<ED extends EntityDict, T extends keyof ED>(entity: T, parentKey: string, filter: ED[T]['Selection']['filter'], level?: number, includeAll?: boolean, includeSelf?: boolean): ED[T]['Selection']['filter'];
|
package/lib/store/filter.js
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getRelevantIds = exports.repel = exports.contains = exports.combineFilters = exports.addFilterSegment = void 0;
|
|
3
|
+
exports.makeTreeDescendantFilter = exports.makeTreeAncestorFilter = exports.same = exports.getRelevantIds = exports.repel = exports.contains = exports.combineFilters = exports.unionFilterSegment = exports.addFilterSegment = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
|
+
var assert_1 = tslib_1.__importDefault(require("assert"));
|
|
5
6
|
var lodash_1 = require("../utils/lodash");
|
|
6
7
|
function addFilterSegment() {
|
|
7
8
|
var filters = [];
|
|
@@ -52,7 +53,45 @@ function addFilterSegment() {
|
|
|
52
53
|
return filter;
|
|
53
54
|
}
|
|
54
55
|
exports.addFilterSegment = addFilterSegment;
|
|
55
|
-
function
|
|
56
|
+
function unionFilterSegment() {
|
|
57
|
+
var e_1, _a;
|
|
58
|
+
var filters = [];
|
|
59
|
+
for (var _i = 0; _i < arguments.length; _i++) {
|
|
60
|
+
filters[_i] = arguments[_i];
|
|
61
|
+
}
|
|
62
|
+
var allOnlyOneOr = true;
|
|
63
|
+
try {
|
|
64
|
+
for (var filters_1 = tslib_1.__values(filters), filters_1_1 = filters_1.next(); !filters_1_1.done; filters_1_1 = filters_1.next()) {
|
|
65
|
+
var f = filters_1_1.value;
|
|
66
|
+
if (Object.keys(f).length > 1 || !f.$or) {
|
|
67
|
+
allOnlyOneOr = false;
|
|
68
|
+
break;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
73
|
+
finally {
|
|
74
|
+
try {
|
|
75
|
+
if (filters_1_1 && !filters_1_1.done && (_a = filters_1.return)) _a.call(filters_1);
|
|
76
|
+
}
|
|
77
|
+
finally { if (e_1) throw e_1.error; }
|
|
78
|
+
}
|
|
79
|
+
if (allOnlyOneOr) {
|
|
80
|
+
// 优化特殊情况,全部都是$or,直接合并
|
|
81
|
+
var ors = filters.map(function (ele) { return ele.$or; });
|
|
82
|
+
return {
|
|
83
|
+
$or: ors.reduce(function (prev, next) { return prev.concat(next); }, [])
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
$or: filters,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
exports.unionFilterSegment = unionFilterSegment;
|
|
91
|
+
function combineFilters(filters, union) {
|
|
92
|
+
if (union) {
|
|
93
|
+
return unionFilterSegment.apply(void 0, tslib_1.__spreadArray([], tslib_1.__read(filters), false));
|
|
94
|
+
}
|
|
56
95
|
return addFilterSegment.apply(void 0, tslib_1.__spreadArray([], tslib_1.__read(filters), false));
|
|
57
96
|
}
|
|
58
97
|
exports.combineFilters = combineFilters;
|
|
@@ -150,3 +189,98 @@ function getRelevantIds(filter) {
|
|
|
150
189
|
return result;
|
|
151
190
|
}
|
|
152
191
|
exports.getRelevantIds = getRelevantIds;
|
|
192
|
+
/**
|
|
193
|
+
* 判断两个过滤条件是否完全一致
|
|
194
|
+
* @param entity
|
|
195
|
+
* @param schema
|
|
196
|
+
* @param filter1
|
|
197
|
+
* @param filter2
|
|
198
|
+
*/
|
|
199
|
+
function same(entity, schema, filter1, filter2) {
|
|
200
|
+
// 当前只需要判断是不是id相等就行了,在runningTree的operation合并的时间使用
|
|
201
|
+
if (!filter1 || !filter1.id || Object.keys(filter1).length > 1 || !filter2 || !filter2.id || Object.keys(filter2).length > 1) {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
return filter1.id === filter2.id;
|
|
205
|
+
}
|
|
206
|
+
exports.same = same;
|
|
207
|
+
/**
|
|
208
|
+
* 寻找在树形结构中满足条件的数据行的上层数据
|
|
209
|
+
* 例如在area表中,如果“杭州市”满足这一条件,则希望查到更高层的“浙江省”和“中国”,即可构造出满足条件的filter
|
|
210
|
+
* @param entity
|
|
211
|
+
* @param parentKey parentId属性名
|
|
212
|
+
* @param filter 查询当前行的条件
|
|
213
|
+
* @param level
|
|
214
|
+
*/
|
|
215
|
+
function makeTreeAncestorFilter(entity, parentKey, filter, level, includeAll, includeSelf) {
|
|
216
|
+
var _a;
|
|
217
|
+
if (level === void 0) { level = 1; }
|
|
218
|
+
(0, assert_1.default)(level >= 0);
|
|
219
|
+
var idInFilters = [];
|
|
220
|
+
if (includeSelf) {
|
|
221
|
+
idInFilters.push(filter);
|
|
222
|
+
}
|
|
223
|
+
var currentLevelInFilter = filter;
|
|
224
|
+
while (level > 0) {
|
|
225
|
+
currentLevelInFilter = {
|
|
226
|
+
id: {
|
|
227
|
+
$in: {
|
|
228
|
+
entity: entity,
|
|
229
|
+
data: (_a = {},
|
|
230
|
+
_a[parentKey] = 1,
|
|
231
|
+
_a),
|
|
232
|
+
filter: currentLevelInFilter,
|
|
233
|
+
}
|
|
234
|
+
},
|
|
235
|
+
};
|
|
236
|
+
if (includeAll) {
|
|
237
|
+
idInFilters.push(currentLevelInFilter);
|
|
238
|
+
}
|
|
239
|
+
level--;
|
|
240
|
+
}
|
|
241
|
+
;
|
|
242
|
+
if (includeAll) {
|
|
243
|
+
return {
|
|
244
|
+
$or: idInFilters,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
return currentLevelInFilter;
|
|
248
|
+
}
|
|
249
|
+
exports.makeTreeAncestorFilter = makeTreeAncestorFilter;
|
|
250
|
+
/**
|
|
251
|
+
* 寻找在树形结构中满足条件的数据行的下层数据
|
|
252
|
+
* 例如在area表中,如果“杭州市”满足这一条件,则希望查到更低层的“西湖区”,即可构造出满足条件的filter
|
|
253
|
+
* @param entity
|
|
254
|
+
* @param parentKey parentId属性名
|
|
255
|
+
* @param filter 查询当前行的条件
|
|
256
|
+
* @param level
|
|
257
|
+
*/
|
|
258
|
+
function makeTreeDescendantFilter(entity, parentKey, filter, level, includeAll, includeSelf) {
|
|
259
|
+
var _a;
|
|
260
|
+
if (level === void 0) { level = 1; }
|
|
261
|
+
(0, assert_1.default)(level >= 0);
|
|
262
|
+
(0, assert_1.default)(parentKey.endsWith('Id'));
|
|
263
|
+
var parentKeyRef = parentKey.slice(0, parentKey.length - 2);
|
|
264
|
+
var idInFilters = [];
|
|
265
|
+
if (includeSelf) {
|
|
266
|
+
idInFilters.push(filter);
|
|
267
|
+
}
|
|
268
|
+
var currentLevelInFilter = filter;
|
|
269
|
+
while (level > 0) {
|
|
270
|
+
currentLevelInFilter = (_a = {},
|
|
271
|
+
_a[parentKeyRef] = currentLevelInFilter,
|
|
272
|
+
_a);
|
|
273
|
+
if (includeAll) {
|
|
274
|
+
idInFilters.push(currentLevelInFilter);
|
|
275
|
+
}
|
|
276
|
+
level--;
|
|
277
|
+
}
|
|
278
|
+
;
|
|
279
|
+
if (includeAll) {
|
|
280
|
+
return {
|
|
281
|
+
$or: idInFilters,
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
return currentLevelInFilter;
|
|
285
|
+
}
|
|
286
|
+
exports.makeTreeDescendantFilter = makeTreeDescendantFilter;
|
package/lib/types/Context.d.ts
CHANGED
package/lib/types/Exception.d.ts
CHANGED
|
@@ -65,8 +65,10 @@ export declare class OakRowLockedException extends OakUserException {
|
|
|
65
65
|
*/
|
|
66
66
|
export declare class OakCongruentRowExists<ED extends EntityDict, T extends keyof ED> extends OakUserException {
|
|
67
67
|
private data;
|
|
68
|
-
|
|
68
|
+
private entity;
|
|
69
|
+
constructor(entity: T, data: ED[T]['OpSchema'], message?: string);
|
|
69
70
|
getData(): ED[T]["OpSchema"];
|
|
71
|
+
getEntity(): T;
|
|
70
72
|
toString(): string;
|
|
71
73
|
}
|
|
72
74
|
export declare function makeException(data: {
|
package/lib/types/Exception.js
CHANGED
|
@@ -172,19 +172,24 @@ exports.OakRowLockedException = OakRowLockedException;
|
|
|
172
172
|
*/
|
|
173
173
|
var OakCongruentRowExists = /** @class */ (function (_super) {
|
|
174
174
|
tslib_1.__extends(OakCongruentRowExists, _super);
|
|
175
|
-
function OakCongruentRowExists(data, message) {
|
|
175
|
+
function OakCongruentRowExists(entity, data, message) {
|
|
176
176
|
var _this = _super.call(this, message) || this;
|
|
177
177
|
_this.data = data;
|
|
178
|
+
_this.entity = entity;
|
|
178
179
|
return _this;
|
|
179
180
|
}
|
|
180
181
|
OakCongruentRowExists.prototype.getData = function () {
|
|
181
182
|
return this.data;
|
|
182
183
|
};
|
|
184
|
+
OakCongruentRowExists.prototype.getEntity = function () {
|
|
185
|
+
return this.entity;
|
|
186
|
+
};
|
|
183
187
|
OakCongruentRowExists.prototype.toString = function () {
|
|
184
188
|
return JSON.stringify({
|
|
185
189
|
name: this.constructor.name,
|
|
186
190
|
message: this.message,
|
|
187
191
|
data: this.data,
|
|
192
|
+
entity: this.entity,
|
|
188
193
|
});
|
|
189
194
|
};
|
|
190
195
|
return OakCongruentRowExists;
|
|
@@ -215,7 +220,7 @@ function makeException(data) {
|
|
|
215
220
|
return new OakUnloggedInException(data.message);
|
|
216
221
|
}
|
|
217
222
|
case OakCongruentRowExists.name: {
|
|
218
|
-
return new OakCongruentRowExists(data.data, data.message);
|
|
223
|
+
return new OakCongruentRowExists(data.entity, data.data, data.message);
|
|
219
224
|
}
|
|
220
225
|
case OakRowLockedException.name: {
|
|
221
226
|
return new OakRowLockedException(data.message);
|
package/lib/types/RowStore.d.ts
CHANGED
|
@@ -19,4 +19,5 @@ export declare abstract class RowStore<ED extends EntityDict, Cxt extends Contex
|
|
|
19
19
|
abstract rollback(txnId: string): Promise<void>;
|
|
20
20
|
getSchema(): StorageSchema<ED>;
|
|
21
21
|
mergeOperationResult(result: OperationResult<ED>, toBeMerged: OperationResult<ED>): void;
|
|
22
|
+
mergeMultipleResults(toBeMerged: OperationResult<ED>[]): OperationResult<ED>;
|
|
22
23
|
}
|
package/lib/types/RowStore.js
CHANGED
|
@@ -22,6 +22,12 @@ var RowStore = /** @class */ (function () {
|
|
|
22
22
|
}
|
|
23
23
|
}
|
|
24
24
|
};
|
|
25
|
+
RowStore.prototype.mergeMultipleResults = function (toBeMerged) {
|
|
26
|
+
var _this = this;
|
|
27
|
+
var result = {};
|
|
28
|
+
toBeMerged.forEach(function (ele) { return _this.mergeOperationResult(result, ele); });
|
|
29
|
+
return result;
|
|
30
|
+
};
|
|
25
31
|
RowStore.$$LEVEL = 'store';
|
|
26
32
|
RowStore.$$CODES = {
|
|
27
33
|
primaryKeyConfilict: [1, '主键重复'],
|
package/lib/types/Watcher.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
import { SelectRowShape } from ".";
|
|
1
2
|
import { Context } from "./Context";
|
|
2
|
-
import { EntityDict, OperationResult
|
|
3
|
+
import { EntityDict, OperationResult } from "./Entity";
|
|
3
4
|
declare type ActionData<ED extends EntityDict, T extends keyof ED> = ED[T]['Update']['data'] | ED[T]['Remove']['data'];
|
|
4
5
|
export interface BBWatcher<ED extends EntityDict, T extends keyof ED> {
|
|
5
6
|
name: string;
|
|
@@ -8,12 +9,12 @@ export interface BBWatcher<ED extends EntityDict, T extends keyof ED> {
|
|
|
8
9
|
action: ED[T]['Operation']['action'];
|
|
9
10
|
actionData: ActionData<ED, T> | (() => Promise<ActionData<ED, T>>);
|
|
10
11
|
}
|
|
11
|
-
export interface WBWatcher<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED
|
|
12
|
+
export interface WBWatcher<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>, Proj extends ED[T]['Selection']['data'] = ED[T]['Selection']['data']> {
|
|
12
13
|
name: string;
|
|
13
14
|
entity: T;
|
|
14
15
|
filter: ED[T]['Selection']['filter'] | (() => Promise<ED[T]['Selection']['filter']>);
|
|
15
|
-
projection:
|
|
16
|
-
fn: (context: Cxt, data:
|
|
16
|
+
projection: Proj | (() => Promise<Proj>);
|
|
17
|
+
fn: (context: Cxt, data: SelectRowShape<ED[T]['Schema'], Proj>[]) => Promise<OperationResult<ED>>;
|
|
17
18
|
}
|
|
18
19
|
export declare type Watcher<ED extends EntityDict, T extends keyof ED, Cxt extends Context<ED>> = BBWatcher<ED, T> | WBWatcher<ED, T, Cxt>;
|
|
19
20
|
export {};
|
package/lib/utils/lodash.d.ts
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* 像assign, keys尽量使用Object的函数
|
|
4
4
|
*/
|
|
5
5
|
import unset from 'lodash/unset';
|
|
6
|
+
import uniqBy from 'lodash/uniqBy';
|
|
6
7
|
import pull from 'lodash/pull';
|
|
7
8
|
import uniq from 'lodash/uniq';
|
|
8
9
|
import get from 'lodash/get';
|
|
@@ -16,4 +17,4 @@ import isEqual from 'lodash/isEqual';
|
|
|
16
17
|
import union from 'lodash/union';
|
|
17
18
|
import difference from 'lodash/difference';
|
|
18
19
|
import groupBy from 'lodash/groupBy';
|
|
19
|
-
export { unset, pull, uniq, get, set, intersection, omit, merge, cloneDeep, pick, isEqual, union, difference, groupBy, };
|
|
20
|
+
export { unset, pull, uniq, uniqBy, get, set, intersection, omit, merge, cloneDeep, pick, isEqual, union, difference, groupBy, };
|
package/lib/utils/lodash.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.groupBy = exports.difference = exports.union = exports.isEqual = exports.pick = exports.cloneDeep = exports.merge = exports.omit = exports.intersection = exports.set = exports.get = exports.uniq = exports.pull = exports.unset = void 0;
|
|
3
|
+
exports.groupBy = exports.difference = exports.union = exports.isEqual = exports.pick = exports.cloneDeep = exports.merge = exports.omit = exports.intersection = exports.set = exports.get = exports.uniqBy = exports.uniq = exports.pull = exports.unset = void 0;
|
|
4
4
|
var tslib_1 = require("tslib");
|
|
5
5
|
/**
|
|
6
6
|
* 避免lodash打包体积过大
|
|
@@ -8,6 +8,8 @@ var tslib_1 = require("tslib");
|
|
|
8
8
|
*/
|
|
9
9
|
var unset_1 = tslib_1.__importDefault(require("lodash/unset"));
|
|
10
10
|
exports.unset = unset_1.default;
|
|
11
|
+
var uniqBy_1 = tslib_1.__importDefault(require("lodash/uniqBy"));
|
|
12
|
+
exports.uniqBy = uniqBy_1.default;
|
|
11
13
|
var pull_1 = tslib_1.__importDefault(require("lodash/pull"));
|
|
12
14
|
exports.pull = pull_1.default;
|
|
13
15
|
var uniq_1 = tslib_1.__importDefault(require("lodash/uniq"));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oak-domain",
|
|
3
|
-
"version": "1.1.
|
|
3
|
+
"version": "1.1.9",
|
|
4
4
|
"author": {
|
|
5
5
|
"name": "XuChang"
|
|
6
6
|
},
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"@types/uuid": "^8.3.0",
|
|
31
31
|
"assert": "^2.0.0",
|
|
32
32
|
"cross-env": "^7.0.2",
|
|
33
|
+
"cross-spawn": "^7.0.3",
|
|
33
34
|
"fs-extra": "^10.0.0",
|
|
34
35
|
"mocha": "^8.2.1",
|
|
35
36
|
"ts-node": "~10.9.1",
|