oak-domain 5.1.22 → 5.1.24

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.
@@ -1,3 +1,22 @@
1
+ import * as ts from 'typescript';
2
+ declare const Schema: Record<string, {
3
+ schemaAttrs: Array<ts.PropertySignature>;
4
+ fulltextIndex?: true;
5
+ indexes?: ts.ArrayLiteralExpression;
6
+ sourceFile: ts.SourceFile;
7
+ enumAttributes: Record<string, string[]>;
8
+ locale: ts.ObjectLiteralExpression;
9
+ toModi: boolean;
10
+ toLog: boolean;
11
+ actionType: string;
12
+ static: boolean;
13
+ inModi: boolean;
14
+ relations: false | string[];
15
+ extendsFrom: string[];
16
+ importAttrFrom: Record<string, [string, string | undefined]>;
17
+ }>;
18
+ export declare function constructAttributes(entity: string): ts.PropertyAssignment[];
19
+ export declare function translateLocaleObject(locale: ts.ObjectLiteralExpression): Record<string, any>;
1
20
  /**
2
21
  * 此函数不再使用
3
22
  * @param map
@@ -23,6 +42,9 @@ export declare function registerFixedDestinationPathMap(map: Record<string, stri
23
42
  * @param map
24
43
  */
25
44
  export declare function registerDeducedRelationMap(map: Record<string, string>): void;
45
+ export declare const getAnalizedSchema: () => typeof Schema;
26
46
  export declare function analyzeEntities(inputDir: string, relativePath?: string): void;
27
47
  export declare function buildSchemaBackup(outputDir: string): void;
48
+ export declare function getProjectionKeys(entity: string): string[];
28
49
  export declare function buildSchema(outputDir: string): void;
50
+ export {};
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildSchema = exports.buildSchemaBackup = exports.analyzeEntities = exports.registerDeducedRelationMap = exports.registerFixedDestinationPathMap = exports.registerIgnoredRelationPathMap = exports.registerFreeEntities = exports.registerIgnoredForeignKeyMap = void 0;
3
+ exports.buildSchema = exports.getProjectionKeys = exports.buildSchemaBackup = exports.analyzeEntities = exports.getAnalizedSchema = exports.registerDeducedRelationMap = exports.registerFixedDestinationPathMap = exports.registerIgnoredRelationPathMap = exports.registerFreeEntities = exports.registerIgnoredForeignKeyMap = exports.translateLocaleObject = exports.constructAttributes = void 0;
4
4
  const tslib_1 = require("tslib");
5
5
  const path_1 = tslib_1.__importDefault(require("path"));
6
6
  const assert_1 = tslib_1.__importDefault(require("assert"));
@@ -2256,6 +2256,64 @@ function _constructOpProjection(statements, entity) {
2256
2256
  exprNode,
2257
2257
  ])));
2258
2258
  }
2259
+ function getOpProjectionKeys(entity) {
2260
+ const { schemaAttrs, enumAttributes } = Schema[entity];
2261
+ const { [entity]: manyToOneSet } = ManyToOne;
2262
+ const result = [
2263
+ 'id',
2264
+ '$$createAt$$',
2265
+ '$$updateAt$$',
2266
+ '$$seq$$',
2267
+ ];
2268
+ for (const attr of schemaAttrs) {
2269
+ const { type, name } = attr;
2270
+ const attrName = name.text;
2271
+ if (ts.isTypeReferenceNode(type)) {
2272
+ const { typeName } = type;
2273
+ if (ts.isIdentifier(typeName)) {
2274
+ const typeStr = typeName.text;
2275
+ switch (typeStr) {
2276
+ case 'String':
2277
+ case 'Text':
2278
+ case 'Int':
2279
+ case 'Uint':
2280
+ case 'Float':
2281
+ case 'Double':
2282
+ case 'Boolean':
2283
+ case 'Datetime':
2284
+ case 'Image':
2285
+ case 'File':
2286
+ case 'SingleGeo':
2287
+ case 'Geo':
2288
+ case 'Price':
2289
+ case 'Decimal':
2290
+ result.push(attrName);
2291
+ break;
2292
+ case 'Object':
2293
+ result.push(attrName);
2294
+ break;
2295
+ default: {
2296
+ const refEntity = typeStr === 'Schema' ? entity : typeStr;
2297
+ const isManyToOne = manyToOneSet?.some(([e]) => e === refEntity);
2298
+ if (isManyToOne) {
2299
+ result.push(`${attrName}Id`);
2300
+ }
2301
+ else if (!enumAttributes?.[attrName]) {
2302
+ result.push(attrName);
2303
+ }
2304
+ else {
2305
+ result.push(attrName);
2306
+ }
2307
+ }
2308
+ }
2309
+ }
2310
+ }
2311
+ else {
2312
+ result.push(attrName);
2313
+ }
2314
+ }
2315
+ return result;
2316
+ }
2259
2317
  /**
2260
2318
  * 构造Query
2261
2319
  * @param statements
@@ -3951,6 +4009,26 @@ function constructAttributes(entity) {
3951
4009
  });
3952
4010
  return result;
3953
4011
  }
4012
+ exports.constructAttributes = constructAttributes;
4013
+ function translateLocaleObject(locale) {
4014
+ const result = {};
4015
+ locale.properties.forEach((ele) => {
4016
+ (0, assert_1.default)(ts.isPropertyAssignment(ele) && (ts.isIdentifier(ele.name) || ts.isStringLiteral(ele.name)), `locale对象中的属性定义不正确`);
4017
+ const name = ele.name.text;
4018
+ if (ts.isStringLiteral(ele.initializer)) {
4019
+ result[name] = ele.initializer.text;
4020
+ }
4021
+ else if (ts.isObjectLiteralExpression(ele.initializer)) {
4022
+ const subObj = translateLocaleObject(ele.initializer);
4023
+ result[name] = subObj;
4024
+ }
4025
+ else {
4026
+ throw new Error(`locale对象中的属性${name}的定义不正确`);
4027
+ }
4028
+ });
4029
+ return result;
4030
+ }
4031
+ exports.translateLocaleObject = translateLocaleObject;
3954
4032
  function outputLocale(outputDir, printer) {
3955
4033
  const locales = {};
3956
4034
  const entities = [];
@@ -4768,6 +4846,10 @@ function outputStyleDict(outputDir, printer) {
4768
4846
  const filename = path_1.default.join(outputDir, 'StyleDict.ts');
4769
4847
  (0, fs_1.writeFileSync)(filename, result, { flag: 'w' });
4770
4848
  }
4849
+ const getAnalizedSchema = () => {
4850
+ return Schema;
4851
+ };
4852
+ exports.getAnalizedSchema = getAnalizedSchema;
4771
4853
  function analyzeEntities(inputDir, relativePath) {
4772
4854
  const files = (0, fs_1.readdirSync)(inputDir);
4773
4855
  const fullFilenames = files.map(ele => {
@@ -5474,6 +5556,76 @@ function _outputEntityDict(outputDir, printer) {
5474
5556
  const fileName = path_1.default.join(outputDir, 'EntityDict.ts');
5475
5557
  (0, fs_1.writeFileSync)(fileName, result, { flag: 'w' });
5476
5558
  }
5559
+ function getProjectionKeys(entity) {
5560
+ const keys = [];
5561
+ const { schemaAttrs } = Schema[entity];
5562
+ const { [entity]: manyToOneSet = [] } = ManyToOne;
5563
+ for (const attr of schemaAttrs) {
5564
+ const { type, name } = attr;
5565
+ const attrName = name.text;
5566
+ if (ts.isTypeReferenceNode(type)) {
5567
+ const typeName = type.typeName;
5568
+ if (ts.isIdentifier(typeName)) {
5569
+ const text = typeName.text;
5570
+ switch (text) {
5571
+ case 'String':
5572
+ case 'Text':
5573
+ case 'Int':
5574
+ case 'Uint':
5575
+ case 'Float':
5576
+ case 'Double':
5577
+ case 'Boolean':
5578
+ case 'Datetime':
5579
+ case 'Image':
5580
+ case 'File':
5581
+ case 'SingleGeo':
5582
+ case 'Geo':
5583
+ case 'Price':
5584
+ case 'Decimal':
5585
+ case 'Object':
5586
+ break;
5587
+ default:
5588
+ const text2 = text === 'Schema' ? entity : text;
5589
+ const manyToOneItem = manyToOneSet.find(([refEntity]) => refEntity === text2);
5590
+ if (manyToOneItem) {
5591
+ keys.push(attrName); // 外键属性
5592
+ }
5593
+ }
5594
+ }
5595
+ }
5596
+ }
5597
+ if (ReversePointerRelations[entity]) {
5598
+ for (const one of ReversePointerRelations[entity]) {
5599
+ const text2 = one === 'Schema' ? entity : one;
5600
+ keys.push((0, string_1.firstLetterLowerCase)(one));
5601
+ }
5602
+ }
5603
+ const { [entity]: oneToManySet = [] } = OneToMany;
5604
+ const foreignKeySet = {};
5605
+ for (const [entityName, foreignKey] of oneToManySet) {
5606
+ if (!foreignKeySet[entityName]) {
5607
+ foreignKeySet[entityName] = [];
5608
+ }
5609
+ foreignKeySet[entityName].push(foreignKey);
5610
+ }
5611
+ for (const entityName in foreignKeySet) {
5612
+ const entityNameLc = (0, string_1.firstLetterLowerCase)(entityName);
5613
+ for (const foreignKey of foreignKeySet[entityName]) {
5614
+ const identifier = `${entityNameLc}$${foreignKey}`;
5615
+ keys.push(identifier);
5616
+ const aggrKey = _getAggrKey(entityNameLc, foreignKey);
5617
+ if (typeof aggrKey === 'string') {
5618
+ keys.push(aggrKey);
5619
+ }
5620
+ else {
5621
+ // 如果是 union 类型,用映射表达式模拟(如 ["xxx$$aggr", `xxx$$${number}$$aggr`])
5622
+ keys.push(`${identifier}$$aggr`);
5623
+ }
5624
+ }
5625
+ }
5626
+ return [...new Set([...keys, ...getOpProjectionKeys(entity)])];
5627
+ }
5628
+ exports.getProjectionKeys = getProjectionKeys;
5477
5629
  function _outputSchema(outputDir, printer) {
5478
5630
  for (const entity in Schema) {
5479
5631
  const statements = [
@@ -33,7 +33,7 @@ export declare abstract class CascadeStore<ED extends EntityDict & BaseEntityDic
33
33
  protected abstract updateAbjointRowAsync<T extends keyof ED, OP extends OperateOption, Cxt extends AsyncContext<ED>>(entity: T, operation: ED[T]['Create'] | ED[T]['Update'] | ED[T]['Remove'], context: Cxt, option: OP): Promise<number>;
34
34
  protected abstract aggregateAbjointRowSync<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): AggregationResult<ED[T]['Schema']>;
35
35
  protected abstract aggregateAbjointRowAsync<T extends keyof ED, OP extends SelectOption, Cxt extends AsyncContext<ED>>(entity: T, aggregation: ED[T]['Aggregation'], context: Cxt, option: OP): Promise<AggregationResult<ED[T]['Schema']>>;
36
- protected destructCascadeSelect<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, projection2: ED[T]['Projection'], context: Cxt, cascadeSelectFn: <T2 extends keyof ED>(entity2: T2, selection: ED[T2]['Selection'], context: Cxt, op: OP) => Partial<ED[T2]['Schema']>[] | Promise<Partial<ED[T2]['Schema']>[]>, aggregateFn: <T2 extends keyof ED>(entity2: T2, aggregation: ED[T2]['Aggregation'], context: Cxt, op: OP) => AggregationResult<ED[T2]['Schema']> | Promise<AggregationResult<ED[T2]['Schema']>>, option: OP): {
36
+ protected destructCascadeSelect<T extends keyof ED, OP extends SelectOption, Cxt extends SyncContext<ED> | AsyncContext<ED>>(entity: T, projection2: ED[T]['Projection'], context: Cxt, cascadeSelectFn: <T2 extends keyof ED>(entity2: T2, selection: ED[T2]['Selection'], context: Cxt, op: OP) => Partial<ED[T2]['Schema']>[] | Promise<Partial<ED[T2]['Schema']>[]>, aggregateFn: <T2 extends keyof ED>(entity2: T2, aggregation: ED[T2]['Aggregation'], context: Cxt, op: OP) => AggregationResult<ED[T2]['Schema']> | Promise<AggregationResult<ED[T2]['Schema']>>, option: OP, selectionId?: string): {
37
37
  projection: ED[T]["Projection"];
38
38
  cascadeSelectionFns: ((result: Partial<ED[T]['Schema']>[]) => Promise<void> | void)[];
39
39
  };
@@ -317,7 +317,7 @@ class CascadeStore extends RowStore_1.RowStore {
317
317
  registerSelectionRewriter(rewriter) {
318
318
  this.selectionRewriters.push(rewriter);
319
319
  }
320
- destructCascadeSelect(entity, projection2, context, cascadeSelectFn, aggregateFn, option) {
320
+ destructCascadeSelect(entity, projection2, context, cascadeSelectFn, aggregateFn, option, selectionId) {
321
321
  const cascadeSelectionFns = [];
322
322
  const supportMtoJoin = this.supportManyToOneJoin();
323
323
  const { toModi } = this.getSchema()[entity];
@@ -352,7 +352,7 @@ class CascadeStore extends RowStore_1.RowStore {
352
352
  });
353
353
  }
354
354
  });
355
- const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(attr, projection2[attr], context, cascadeSelectFn, aggregateFn, option);
355
+ const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(attr, projection2[attr], context, cascadeSelectFn, aggregateFn, option, selectionId);
356
356
  subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => {
357
357
  return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2));
358
358
  }));
@@ -372,6 +372,7 @@ class CascadeStore extends RowStore_1.RowStore {
372
372
  throw new types_1.OakRowUnexistedException([{
373
373
  entity: attr,
374
374
  selection: {
375
+ id: selectionId,
375
376
  data: projection2[attr],
376
377
  filter: {
377
378
  id: {
@@ -400,6 +401,7 @@ class CascadeStore extends RowStore_1.RowStore {
400
401
  };
401
402
  if (entityIds.length > 0) {
402
403
  const subRows = cascadeSelectFn.call(this, attr, {
404
+ id: selectionId,
403
405
  data: projection2[attr],
404
406
  filter: {
405
407
  id: {
@@ -440,7 +442,7 @@ class CascadeStore extends RowStore_1.RowStore {
440
442
  }
441
443
  });
442
444
  }
443
- const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(relation, projection2[attr], context, cascadeSelectFn, aggregateFn, option);
445
+ const { projection: subProjection, cascadeSelectionFns: subCascadeSelectionFns, } = this.destructCascadeSelect(relation, projection2[attr], context, cascadeSelectFn, aggregateFn, option, selectionId);
444
446
  subCascadeSelectionFns.forEach(ele => cascadeSelectionFns.push((result) => {
445
447
  return ele(result.map(ele2 => ele2[attr]).filter(ele2 => !!ele2));
446
448
  }));
@@ -489,6 +491,7 @@ class CascadeStore extends RowStore_1.RowStore {
489
491
  };
490
492
  if (ids.length > 0) {
491
493
  const subRows = cascadeSelectFn.call(this, relation, {
494
+ id: selectionId,
492
495
  data: projection2[attr],
493
496
  filter: {
494
497
  id: {
@@ -506,7 +509,7 @@ class CascadeStore extends RowStore_1.RowStore {
506
509
  }
507
510
  else {
508
511
  (0, assert_1.default)(relation instanceof Array);
509
- const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange } = projection2[attr];
512
+ const { data: subProjection, filter: subFilter, indexFrom, count, sorter: subSorter, total, randomRange, id: subSelectionId } = projection2[attr];
510
513
  const [entity2, foreignKey] = relation;
511
514
  const isAggr = attr.endsWith('$$aggr');
512
515
  const otmAggrFn = (result) => {
@@ -573,6 +576,7 @@ class CascadeStore extends RowStore_1.RowStore {
573
576
  },
574
577
  }, subFilter]);
575
578
  const subRows = cascadeSelectFn.call(this, entity2, {
579
+ id: subSelectionId || selectionId,
576
580
  data: subProjection,
577
581
  filter: filter2,
578
582
  sorter: subSorter,
@@ -600,6 +604,7 @@ class CascadeStore extends RowStore_1.RowStore {
600
604
  entityId: row.id,
601
605
  }, subFilter]);
602
606
  const subRows = cascadeSelectFn.call(this, entity2, {
607
+ id: subSelectionId || selectionId,
603
608
  data: subProjection,
604
609
  filter: filter2,
605
610
  sorter: subSorter,
@@ -1662,7 +1667,7 @@ class CascadeStore extends RowStore_1.RowStore {
1662
1667
  * @param rows
1663
1668
  * @param context
1664
1669
  */
1665
- addToResultSelections(entity, rows, context) {
1670
+ addToResultSelections(entity, rows, context, id) {
1666
1671
  if (this.supportManyToOneJoin()) {
1667
1672
  // 这里的外键连接有可能为空,需要使用所有的行的attr的并集来测试
1668
1673
  const attrs = (0, lodash_1.uniq)(rows.map(ele => Object.keys(ele)).flat());
@@ -1671,29 +1676,29 @@ class CascadeStore extends RowStore_1.RowStore {
1671
1676
  const data = {};
1672
1677
  const rel = this.judgeRelation(entity, attr);
1673
1678
  if (rel === 2) {
1674
- this.addToResultSelections(attr, rows.map(ele => ele[attr]).filter(ele => !!ele), context);
1679
+ this.addToResultSelections(attr, rows.map(ele => ele[attr]).filter(ele => !!ele), context, id);
1675
1680
  }
1676
1681
  else if (typeof rel === 'string') {
1677
- this.addToResultSelections(rel, rows.map(ele => ele[attr]).filter(ele => !!ele), context);
1682
+ this.addToResultSelections(rel, rows.map(ele => ele[attr]).filter(ele => !!ele), context, id);
1678
1683
  }
1679
1684
  else if (rel instanceof Array) {
1680
- this.addToResultSelections(rel[0], rows.map(ele => ele[attr]).reduce((prev, current) => prev.concat(current), []), context);
1685
+ this.addToResultSelections(rel[0], rows.map(ele => ele[attr]).reduce((prev, current) => prev.concat(current), []), context, id);
1681
1686
  }
1682
1687
  else {
1683
1688
  attrsToPick.push(attr);
1684
1689
  }
1685
1690
  }
1686
1691
  const originRows = rows.map(ele => (0, lodash_1.pick)(ele, attrsToPick));
1687
- this.addSingleRowToResultSelections(entity, originRows, context);
1692
+ this.addSingleRowToResultSelections(entity, originRows, context, id);
1688
1693
  }
1689
1694
  else {
1690
- this.addSingleRowToResultSelections(entity, rows, context);
1695
+ this.addSingleRowToResultSelections(entity, rows, context, id);
1691
1696
  }
1692
1697
  }
1693
- addSingleRowToResultSelections(entity, rows, context) {
1698
+ addSingleRowToResultSelections(entity, rows, context, id) {
1694
1699
  const { opRecords } = context;
1695
1700
  let lastOperation = opRecords[opRecords.length - 1];
1696
- if (lastOperation && lastOperation.a === 's') {
1701
+ if (lastOperation && lastOperation.a === 's' && id === lastOperation.id) {
1697
1702
  const entityBranch = lastOperation.d[entity];
1698
1703
  if (entityBranch) {
1699
1704
  rows.forEach((row) => {
@@ -1714,6 +1719,7 @@ class CascadeStore extends RowStore_1.RowStore {
1714
1719
  }
1715
1720
  else {
1716
1721
  lastOperation = {
1722
+ id,
1717
1723
  a: 's',
1718
1724
  d: {},
1719
1725
  };
@@ -1733,8 +1739,8 @@ class CascadeStore extends RowStore_1.RowStore {
1733
1739
  });
1734
1740
  }
1735
1741
  async cascadeSelectAsync(entity, selection, context, option) {
1736
- const { data, filter, indexFrom, count, sorter, total, randomRange, distinct } = selection;
1737
- const { projection, cascadeSelectionFns } = this.destructCascadeSelect(entity, data, context, this.cascadeSelectAsync, this.aggregateAsync, option);
1742
+ const { data, filter, indexFrom, count, sorter, total, randomRange, distinct, id: selectionId } = selection;
1743
+ const { projection, cascadeSelectionFns } = this.destructCascadeSelect(entity, data, context, this.cascadeSelectAsync, this.aggregateAsync, option, selectionId);
1738
1744
  const rows2 = await this.selectAbjointRowAsync(entity, {
1739
1745
  data: projection,
1740
1746
  filter,
@@ -1758,7 +1764,7 @@ class CascadeStore extends RowStore_1.RowStore {
1758
1764
  });
1759
1765
  }
1760
1766
  if (!option.dontCollect) {
1761
- this.addToResultSelections(entity, rows, context);
1767
+ this.addToResultSelections(entity, rows, context, selection.id);
1762
1768
  }
1763
1769
  if (cascadeSelectionFns.length > 0) {
1764
1770
  const ruException = [];
@@ -262,9 +262,19 @@ function createActionTransformerCheckers(actionDefDict) {
262
262
  * @param filters
263
263
  * @param context
264
264
  */
265
- function cascadelyCheckUpdateFilters(entity, schema, data, filter, matrix, restAttrs, context) {
265
+ function cascadelyCheckUpdateFilters(entity, schema, action, data, filter, matrix, restAttrs, context) {
266
266
  const successAttrs = (0, lodash_1.difference)(Object.keys(data), restAttrs);
267
267
  const successAttrFilter = (0, lodash_1.pick)(data, successAttrs);
268
+ const checkConditionalFilter = (cf) => {
269
+ // 此时看应用了success的attributes更新后,能否消除掉f中的部分条件
270
+ const result = (0, filter_1.analyzeFilterRelation)(entity, schema, successAttrFilter, cf, true);
271
+ if (typeof result === 'boolean') {
272
+ return result;
273
+ }
274
+ const { sureAttributes } = result;
275
+ const f2 = (0, lodash_1.omit)(cf, sureAttributes);
276
+ return (0, filter_1.checkFilterContains)(entity, context, f2, filter, true);
277
+ };
268
278
  /**
269
279
  * 先找到能直接更新成功的属性
270
280
  */
@@ -273,15 +283,14 @@ function cascadelyCheckUpdateFilters(entity, schema, data, filter, matrix, restA
273
283
  if (!f) {
274
284
  return true;
275
285
  }
276
- (0, assert_1.default)(typeof f !== 'function', '此处是原来写的时候的疏漏情况,跑出来再改。by Xc 20250214');
277
- // 此时看应用了success的attributes更新后,能否消除掉f中的部分条件
278
- const result = (0, filter_1.analyzeFilterRelation)(entity, schema, successAttrFilter, f, true);
279
- if (typeof result === 'boolean') {
280
- return result;
286
+ if (typeof f === 'function') {
287
+ const cf = f({ action, data, filter }, context);
288
+ if (cf instanceof Promise) {
289
+ return cf.then((cf2) => cf2 ? checkConditionalFilter(cf2) : true);
290
+ }
291
+ return cf ? checkConditionalFilter(cf) : true;
281
292
  }
282
- const { sureAttributes } = result;
283
- const f2 = (0, lodash_1.omit)(f, sureAttributes);
284
- return (0, filter_1.checkFilterContains)(entity, context, f2, filter, true);
293
+ return checkConditionalFilter(f);
285
294
  });
286
295
  const checkResult1 = (lar) => {
287
296
  const legalAttrs = [];
@@ -301,7 +310,7 @@ function cascadelyCheckUpdateFilters(entity, schema, data, filter, matrix, restA
301
310
  if (legalAttrs.length === 0) {
302
311
  throw new types_1.OakAttrCantUpdateException(entity, illegalAttrs, '更新的行当前属性不满足约束,请仔细检查数据');
303
312
  }
304
- return cascadelyCheckUpdateFilters(entity, schema, data, filter, matrix, illegalAttrs, context);
313
+ return cascadelyCheckUpdateFilters(entity, schema, action, data, filter, matrix, illegalAttrs, context);
305
314
  };
306
315
  if (legalAttrResult.find(ele => ele instanceof Promise)) {
307
316
  return Promise.all(legalAttrResult).then((lar) => checkResult1(lar));
@@ -352,7 +361,7 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
352
361
  return result.then((v) => {
353
362
  if (!v) {
354
363
  if (attrs.length > 1) {
355
- return cascadelyCheckUpdateFilters(entity, schema, data, filter, matrix, attrs, context);
364
+ return cascadelyCheckUpdateFilters(entity, schema, action || 'select', data, filter, matrix, attrs, context);
356
365
  }
357
366
  throw new types_1.OakAttrCantUpdateException(entity, attrs);
358
367
  }
@@ -360,7 +369,7 @@ function createAttrUpdateCheckers(schema, attrUpdateMatrix) {
360
369
  }
361
370
  if (!result) {
362
371
  if (attrs.length > 1) {
363
- return cascadelyCheckUpdateFilters(entity, schema, data, filter, matrix, attrs, context);
372
+ return cascadelyCheckUpdateFilters(entity, schema, action || 'select', data, filter, matrix, attrs, context);
364
373
  }
365
374
  throw new types_1.OakAttrCantUpdateException(entity, attrs, '更新的行当前属性不满足约束,请仔细检查数据');
366
375
  }
@@ -1045,6 +1045,11 @@ class RelationAuth {
1045
1045
  if (actionAuths && actionAuths.length > 0) {
1046
1046
  return checkChildren(actionAuths);
1047
1047
  }
1048
+ // 如果这个entity是updateFree,直接过掉到子结点判定
1049
+ const { action, entity } = node;
1050
+ if (this.updateFreeDict[entity] && this.updateFreeDict[entity].includes(action)) {
1051
+ return checkChildren([]);
1052
+ }
1048
1053
  // 没有能根据父亲传下来的actionAuth判定,只能自己找
1049
1054
  const result = this.findActionAuthsOnNode(node, context);
1050
1055
  const checkResult = (result2) => {
@@ -1083,9 +1088,6 @@ class RelationAuth {
1083
1088
  }
1084
1089
  checkOperation(entity, operation, context) {
1085
1090
  const { action, filter, data } = operation;
1086
- if (this.updateFreeDict[entity] && this.updateFreeDict[entity].includes(action)) {
1087
- return true;
1088
- }
1089
1091
  const userId = context.getCurrentUserId();
1090
1092
  if (!userId) {
1091
1093
  throw new types_1.OakUnloggedInException();
@@ -45,6 +45,11 @@ export type ServerConfiguration = {
45
45
  headers?: string[];
46
46
  methods?: string[];
47
47
  };
48
+ ui?: {
49
+ disable?: boolean;
50
+ username?: string;
51
+ password?: string;
52
+ };
48
53
  internalExceptionMask?: string;
49
54
  koaBody?: IKoaBodyOptions;
50
55
  socket?: (ctx: Koa.ParameterizedContext<any, KoaRouter.IRouterParamContext<any, {}>, any>) => {
@@ -182,6 +182,7 @@ export type CascadeRelationAuth<R extends string> = {
182
182
  [K in R]?: CascadeRelationItem | (CascadeRelationItem | CascadeRelationItem[])[];
183
183
  };
184
184
  export type SelectOpResult<ED extends EntityDict> = {
185
+ id?: string;
185
186
  a: 's';
186
187
  d: {
187
188
  [T in keyof ED]?: {
@@ -1,7 +1,11 @@
1
1
  import { LocaleDef } from './Locale';
2
2
  import { Index } from './Storage';
3
3
  import { EntityShape, Configuration, EntityDict } from './Entity';
4
+ import { EntityDict as BaseEntityDict } from '../base-app-domain';
4
5
  import { StyleDesc } from './Style';
6
+ import { AsyncContext } from '../store/AsyncRowStore';
7
+ import { SyncContext } from '../store/SyncRowStore';
8
+ import { SyncOrAsync } from './Polyfill';
5
9
  export type EntityDesc<Schema extends EntityShape, Action extends string = '', Relation extends string = '', V extends Record<string, string> = {
6
10
  ['##oak_illegal##']: '';
7
11
  }> = {
@@ -14,11 +18,15 @@ export type EntityDesc<Schema extends EntityShape, Action extends string = '', R
14
18
  }) : {
15
19
  style: StyleDesc<Action, V>;
16
20
  });
17
- export type AttrUpdateMatrix<ED extends EntityDict> = {
21
+ export type AttrUpdateMatrix<ED extends EntityDict & BaseEntityDict> = {
18
22
  [T in keyof ED]?: {
19
23
  [A in keyof ED[T]['Update']['data']]?: {
20
24
  actions?: ED[T]['Action'][];
21
- filter?: (NonNullable<ED[T]['Filter']>) | ((action: ED[T]['Action']) => ED[T]['Filter'] | undefined);
25
+ filter?: (NonNullable<ED[T]['Filter']>) | ((option: {
26
+ action: ED[T]['Action'];
27
+ data: ED[T]['Update']['data'];
28
+ filter?: ED[T]['Update']['filter'];
29
+ }, context: AsyncContext<ED> | SyncContext<ED>) => SyncOrAsync<ED[T]['Filter'] | undefined>);
22
30
  };
23
31
  };
24
32
  };
@@ -12,6 +12,7 @@ export declare class OakException<ED extends EntityDict & BaseEntityDict> extend
12
12
  name: string;
13
13
  message: string;
14
14
  _module: string | undefined;
15
+ params: Record<string, any> | undefined;
15
16
  opRecords: OpRecord<ED>[];
16
17
  tag1: string | undefined;
17
18
  tag2: boolean | undefined;
@@ -80,6 +80,7 @@ class OakException extends Error {
80
80
  name: this.constructor.name,
81
81
  message: this.message,
82
82
  _module: this._module,
83
+ params: this.params,
83
84
  opRecords: this.opRecords,
84
85
  tag1: this.tag1,
85
86
  tag2: this.tag2,
@@ -36,7 +36,7 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
36
36
  opRecords: any;
37
37
  message: string | null;
38
38
  } | {
39
- result: ArrayBuffer;
39
+ result: ReadableStream<Uint8Array> | null;
40
40
  message: string | null;
41
41
  opRecords?: undefined;
42
42
  }>;
@@ -45,7 +45,7 @@ export default class SimpleConnector<ED extends EntityDict & BaseEntityDict, Fro
45
45
  opRecords: any;
46
46
  message: string | null;
47
47
  } | {
48
- result: ArrayBuffer;
48
+ result: ReadableStream<Uint8Array> | null;
49
49
  message: string | null;
50
50
  opRecords?: undefined;
51
51
  }>;
@@ -81,8 +81,7 @@ class SimpleConnector {
81
81
  throw new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
82
82
  }
83
83
  const message = response.headers.get('oak-message');
84
- const responseType = response.headers.get('Content-Type') ||
85
- response.headers.get('content-type');
84
+ const responseType = response.headers.get('Content-Type') || response.headers.get('content-type');
86
85
  if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
87
86
  const { exception, result, opRecords } = await response.json();
88
87
  if (exception) {
@@ -94,18 +93,24 @@ class SimpleConnector {
94
93
  message,
95
94
  };
96
95
  }
97
- else if (responseType
98
- ?.toLocaleLowerCase()
99
- .match(/application\/octet-stream/i)) {
100
- const result = await response.arrayBuffer();
96
+ // else if (
97
+ // responseType
98
+ // ?.toLocaleLowerCase()
99
+ // .match(/application\/octet-stream/i)
100
+ // ) {
101
+ // const result = await response.arrayBuffer();
102
+ // return {
103
+ // result,
104
+ // message,
105
+ // };
106
+ // }
107
+ else {
108
+ const result = response.body;
101
109
  return {
102
110
  result,
103
111
  message,
104
112
  };
105
113
  }
106
- else {
107
- throw new Error(`尚不支持的content-type类型${responseType}`);
108
- }
109
114
  }
110
115
  async callAspect(name, params, context) {
111
116
  const { headers, body } = await this.makeHeadersAndBody(name, params, context);
@@ -153,8 +158,7 @@ class SimpleConnector {
153
158
  throw new types_1.OakServerProxyException(`网络请求返回status是${response.status}`);
154
159
  }
155
160
  const message = response.headers.get('oak-message');
156
- const responseType = response.headers.get('Content-Type') ||
157
- response.headers.get('content-type');
161
+ const responseType = response.headers.get('Content-Type') || response.headers.get('content-type');
158
162
  if (responseType?.toLocaleLowerCase().match(/application\/json/i)) {
159
163
  const { socketUrl, subscribeUrl, path } = await response.json();
160
164
  return {
@@ -185,7 +189,7 @@ class SimpleConnector {
185
189
  };
186
190
  }
187
191
  async serializeResult(result, opRecords, headers, body, message) {
188
- if (result instanceof stream_1.Stream || result instanceof Buffer) {
192
+ if (result instanceof stream_1.Stream || result instanceof Buffer || result instanceof ReadableStream) {
189
193
  return {
190
194
  body: result,
191
195
  headers: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oak-domain",
3
- "version": "5.1.22",
3
+ "version": "5.1.24",
4
4
  "author": {
5
5
  "name": "XuChang"
6
6
  },