@byted-apaas/server-sdk-node 1.1.18-beta.2 → 1.1.18-beta.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.
@@ -60,6 +60,58 @@ export interface IDB<T, mt> {
60
60
  */
61
61
  oql(oql: string, nameArgs: Record<string, any>): IOql;
62
62
  }
63
+ /**
64
+ * IDB3 经由 IDBGetter 返回,是 DBV3 的基础接口结构
65
+ */
66
+ export interface IDBV3<T, mt> {
67
+ /**
68
+ * 操作指定对象的记录数据
69
+ * @param objectApiName 指定对象的 ApiName
70
+ * @example
71
+ * ```
72
+ * application.data.object('_user').where({
73
+ * gender: 'male'
74
+ * }).find()
75
+ * ```
76
+ */
77
+ object<T extends keyof mt>(objectApiName: T): _IKAllEndpoint<mt[T]> & _IKQuery<mt[T]>;
78
+ /**
79
+ * 创建一个新的空事务
80
+ * @example
81
+ * ```
82
+ * let tx = application.data.newTransaction();
83
+ * let user = tx.object('_user').registerCreate({
84
+ * _name: new application.constants.type.Multilingual({ zh: '用户1', en: 'user1' }),
85
+ * });
86
+ * let contract = tx.object('contract').registerCreate({
87
+ * _name: new application.constants.type.Multilingual({ zh: '用户1的合同', en: 'user1's contract' }),
88
+ * user: {id: user._id}
89
+ * });
90
+ * await tx.commit();
91
+ * ```
92
+ */
93
+ /**
94
+ * OQL 操作
95
+ * @param oql OQL 语句
96
+ * @example
97
+ * ```
98
+ * let users = await application.data.oql('select _email from _user').execute();
99
+ * ```
100
+ */
101
+ oql(oql: string): IOql;
102
+ /**
103
+ * OQL 操作
104
+ * @param oql OQL 语句
105
+ * @param nameArgs 用于替换 OQL 语句中的占位符
106
+ * @example
107
+ * ```
108
+ * let employees = await application.data.oql('select _email from _user where _type = $user_type',{
109
+ * 'user_type': '_employee',
110
+ * }).execute();
111
+ * ```
112
+ */
113
+ oql(oql: string, nameArgs: Record<string, any>): IOql;
114
+ }
63
115
  /**
64
116
  * IDBWithCurrentObject 经由 IDBGetter 返回,是 DB 的动态增加的接口结构
65
117
  */
@@ -17,7 +17,7 @@ export interface _IKSyncEndpoint<T> {
17
17
  * ```
18
18
  */
19
19
  create(recordMap: _Cond<T>): Promise<{
20
- _id: number;
20
+ _id: number | string;
21
21
  }>;
22
22
  /**
23
23
  * 删除记录
@@ -27,7 +27,7 @@ export interface _IKSyncEndpoint<T> {
27
27
  * application.data.object('_user').delete(123456789123)
28
28
  * ```
29
29
  */
30
- delete(recordID: number): Promise<void>;
30
+ delete(recordID: number | string): Promise<void>;
31
31
  /**
32
32
  * 删除记录
33
33
  * @param record 用于删除的一条完整记录
@@ -49,7 +49,7 @@ export interface _IKSyncEndpoint<T> {
49
49
  * })
50
50
  * ```
51
51
  */
52
- update(_id: number, recordMap: _Cond<T>): Promise<void>;
52
+ update(_id: number | string, recordMap: _Cond<T>): Promise<void>;
53
53
  /**
54
54
  * 指定 _id 后,更新对应记录
55
55
  * @param recordMap 用于更新的一条记录,需对 _id 赋值
@@ -1,9 +1,8 @@
1
1
  import { _IKAllEndpoint, _IKQuery } from './IObject';
2
- import { ITransactionGetter } from './transaction';
3
- import { IDB } from '../db';
2
+ import { IDBV3 } from '../db';
4
3
  import { metadataMap } from '../../../data/index';
5
4
  import { IOql } from './oql/ioql';
6
- export declare class DBV3<T, mt = metadataMap> implements IDB<T, mt> {
5
+ export declare class DBV3<T, mt = metadataMap> implements IDBV3<T, mt> {
7
6
  objectApiName: string;
8
7
  constructor(objectApiName?: string);
9
8
  /**
@@ -32,7 +31,6 @@ export declare class DBV3<T, mt = metadataMap> implements IDB<T, mt> {
32
31
  * await tx.commit();
33
32
  * ```
34
33
  */
35
- newTransaction(): ITransactionGetter<T, mt>;
36
34
  /**
37
35
  * OQL 操作
38
36
  * @param oql 指定 OQL 语句
@@ -43,5 +41,4 @@ export declare class DBV3<T, mt = metadataMap> implements IDB<T, mt> {
43
41
  */
44
42
  oql(oql: string): IOql;
45
43
  oql(oql: string, nameArgs: Record<string, any>): IOql;
46
- toDataParam(): any;
47
44
  }
@@ -2,7 +2,6 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.DBV3 = void 0;
4
4
  const object_1 = require("./object");
5
- const index_1 = require("./transaction/index");
6
5
  const oql_1 = require("./oql/oql");
7
6
  class DBV3 {
8
7
  constructor(objectApiName) {
@@ -25,28 +24,6 @@ class DBV3 {
25
24
  return new object_1._KObject(objectApiName, appCtx);
26
25
  }
27
26
  ;
28
- /**
29
- * 创建一个新的空事务
30
- * @example
31
- * ```
32
- * let tx = context.db.newTransaction();
33
- * let user = tx.object('_user').registerCreate({
34
- * _name: new kunlun.type.Multilingual({ zh: '用户1', en: 'user1' }),
35
- * });
36
- * let contract = tx.object('contract').registerCreate({
37
- * _name: new kunlun.type.Multilingual({ zh: '用户1的合同', en: 'user1's contract' }),
38
- * user: {id: user._id}
39
- * });
40
- * await tx.commit();
41
- * ```
42
- */
43
- newTransaction() {
44
- const appCtx = {
45
- dataVersion: "v3",
46
- };
47
- return new index_1.Transaction(this.objectApiName, appCtx);
48
- }
49
- ;
50
27
  oql(oql, nameArgs) {
51
28
  const appCtx = {
52
29
  dataVersion: "v3",
@@ -56,8 +33,5 @@ class DBV3 {
56
33
  }
57
34
  return new oql_1.Oql(oql, undefined, appCtx);
58
35
  }
59
- toDataParam() {
60
- console.log("================= toDataParam");
61
- }
62
36
  }
63
37
  exports.DBV3 = DBV3;
@@ -26,12 +26,14 @@ declare class _KObjectSync<T> implements _IKSyncEndpoint<T> {
26
26
  appCtx: AppCtx;
27
27
  authType: string;
28
28
  create(recordMap: _Cond<T>): Promise<{
29
- _id: number;
29
+ _id: number | string;
30
30
  }>;
31
- delete(recordID: number): Promise<void>;
31
+ delete(recordID: number | string): Promise<void>;
32
32
  delete(record: _Cond<T>): Promise<void>;
33
- update(_id: number, recordMap: _Cond<T>): Promise<void>;
33
+ private deleteV3;
34
+ update(_id: number | string, recordMap: _Cond<T>): Promise<void>;
34
35
  update(recordMap: _Cond<T>): Promise<void>;
36
+ private updateV3;
35
37
  batchCreate(recordMapList: _Cond<T>[]): Promise<number[]>;
36
38
  batchDelete(recordIdList: number[]): Promise<BatchResult>;
37
39
  batchDelete(recordList: _Cond<T>[]): Promise<BatchResult>;
@@ -108,6 +110,7 @@ declare class _KQuery<T> implements _IKQuery<T> {
108
110
  limit(limit: number): this;
109
111
  offset(offset: number): this;
110
112
  count(): Promise<number>;
113
+ private findV3;
111
114
  private findPreCheck;
112
115
  useSystemAuth(): this;
113
116
  useUserAuth(): this;
@@ -57,11 +57,18 @@ class _KObjectSync {
57
57
  return await Request.GetInstance().openSDKCreateRecordBySync(this.apiName, recordMap);
58
58
  });
59
59
  }
60
+ else if (this.appCtx && this.appCtx.dataVersion === 'v3') {
61
+ console.log("dataV3");
62
+ return await Request.GetInstance().createRecordV3BySync(this.apiName, recordMap, this.authType);
63
+ }
60
64
  return await Request.GetInstance().createRecordBySync(this.apiName, recordMap, this.authType);
61
65
  }
62
66
  ;
63
67
  async delete(recordOrRecordID) {
64
- let recordID = 0;
68
+ if (this.appCtx && this.appCtx.dataVersion === "v3") {
69
+ return this.deleteV3(recordOrRecordID);
70
+ }
71
+ let recordID;
65
72
  // 用户直接传入 record id 来进行删除的情况
66
73
  if (typeof recordOrRecordID === 'number') {
67
74
  recordID = recordOrRecordID;
@@ -74,7 +81,12 @@ class _KObjectSync {
74
81
  if (!record._id) {
75
82
  throw new server_common_node_1.exceptions.InvalidParamError('record._id is empty');
76
83
  }
77
- recordID = record._id;
84
+ if (typeof record._id === 'number') {
85
+ recordID = record._id;
86
+ }
87
+ else if (typeof record._id === 'string') {
88
+ recordID = parseInt(record._id);
89
+ }
78
90
  }
79
91
  }
80
92
  if (recordID > 0) {
@@ -89,7 +101,38 @@ class _KObjectSync {
89
101
  throw new server_common_node_1.exceptions.InvalidParamError('record must be number or object');
90
102
  }
91
103
  ;
104
+ async deleteV3(recordOrRecordID) {
105
+ let recordIDStr;
106
+ if (typeof recordOrRecordID === 'number') {
107
+ recordIDStr = recordOrRecordID.toString();
108
+ }
109
+ else if (typeof recordOrRecordID === 'string') {
110
+ recordIDStr = recordOrRecordID;
111
+ }
112
+ else {
113
+ let record = recordOrRecordID;
114
+ if (server_common_node_1.checkUtils.isObject(record)) {
115
+ // 如果用户没有传入包含 id 的 record,则报错
116
+ if (!record._id) {
117
+ throw new server_common_node_1.exceptions.InvalidParamError('record._id is empty');
118
+ }
119
+ if (typeof record._id === 'number') {
120
+ recordIDStr = record._id.toString();
121
+ }
122
+ else if (typeof record._id === 'string') {
123
+ recordIDStr = record._id;
124
+ }
125
+ }
126
+ }
127
+ if (recordIDStr.length <= 0) {
128
+ throw new server_common_node_1.exceptions.InvalidParamError('record._id must greater than 0');
129
+ }
130
+ return await Request.GetInstance().deleteRecordV3BySync(this.apiName, recordIDStr, this.authType);
131
+ }
92
132
  async update(_idOrRecordMap, recordMap) {
133
+ if (this.appCtx && this.appCtx.dataVersion === "v3") {
134
+ return this.updateV3(_idOrRecordMap, recordMap);
135
+ }
93
136
  // record 必须包含 _id
94
137
  let record;
95
138
  // 用户显式传入 id 的情况
@@ -124,6 +167,37 @@ class _KObjectSync {
124
167
  return await Request.GetInstance().updateRecordBySync(this.apiName, recordID, record, this.authType);
125
168
  }
126
169
  ;
170
+ async updateV3(_idOrRecordMap, recordMap) {
171
+ // record 必须包含 _id
172
+ let record;
173
+ // 用户显式传入 id 的情况
174
+ if (recordMap && (typeof _idOrRecordMap === 'string' || typeof _idOrRecordMap === 'number')) {
175
+ record = recordMap;
176
+ if (typeof _idOrRecordMap === 'number')
177
+ record._id = _idOrRecordMap.toString();
178
+ else if (typeof _idOrRecordMap === 'string')
179
+ record._id = _idOrRecordMap;
180
+ }
181
+ else {
182
+ // 用户隐式传入 id 的情况
183
+ record = _idOrRecordMap;
184
+ if (!record._id) {
185
+ throw new server_common_node_1.exceptions.InvalidParamError('record._id is empty');
186
+ }
187
+ if (typeof record._id === 'number') {
188
+ record._id = record._id.toString();
189
+ }
190
+ }
191
+ if (!record) {
192
+ throw new server_common_node_1.exceptions.InvalidParamError('param is empty');
193
+ }
194
+ record = permissionUtils.delUnauthField(record).newRecord;
195
+ let recordIDStr = record._id;
196
+ if (recordIDStr.length <= 0) {
197
+ throw new server_common_node_1.exceptions.InvalidParamError('record._id must greater than 0');
198
+ }
199
+ return await Request.GetInstance().updateRecordV3BySync(this.apiName, recordIDStr, record, this.authType);
200
+ }
127
201
  // batch sync
128
202
  async batchCreate(recordMapList) {
129
203
  // 参数校验
@@ -190,7 +264,13 @@ class _KObjectSync {
190
264
  const recordIDs = [];
191
265
  let recordMap = {};
192
266
  for (let record of recordMapList) {
193
- let recordID = record['_id'];
267
+ let recordID;
268
+ if (typeof record._id === 'number') {
269
+ recordID = record._id;
270
+ }
271
+ else if (typeof record._id === 'string') {
272
+ recordID = parseInt(record._id);
273
+ }
194
274
  if ((typeof recordID !== 'number') || recordID <= 0) {
195
275
  throw new server_common_node_1.exceptions.InvalidParamError('record._id is empty');
196
276
  }
@@ -286,7 +366,13 @@ class _KObjectAsync {
286
366
  recordMapList = permissionUtils.batchDelUnauthField(recordMapList).newRecords;
287
367
  let recordMap = {};
288
368
  for (let record of recordMapList) {
289
- let recordID = record['_id'];
369
+ let recordID;
370
+ if (typeof record._id === 'number') {
371
+ recordID = record._id;
372
+ }
373
+ else if (typeof record._id === 'string') {
374
+ recordID = parseInt(record._id);
375
+ }
290
376
  if (recordID === undefined || recordID === null) {
291
377
  throw new server_common_node_1.exceptions.InvalidParamError('record._id is empty');
292
378
  }
@@ -397,6 +483,9 @@ class _KQuery {
397
483
  async find() {
398
484
  this.findPreCheck();
399
485
  const { apiName, appCtx, queryBuilder, queryV2 } = queryPropertiesStore.get(this);
486
+ if (appCtx && appCtx.dataVersion === "v3") {
487
+ return await this.findV3(false);
488
+ }
400
489
  if (queryV2) {
401
490
  const param = {
402
491
  limit: queryV2._limit,
@@ -514,6 +603,13 @@ class _KQuery {
514
603
  return await Request.GetInstance().openSDKGetRecords(apiName, param);
515
604
  });
516
605
  }
606
+ else if (appCtx && appCtx.dataVersion === "v3") {
607
+ // 更新 maxId
608
+ criterion.conditions[criterion.conditions.length - 1].right.settings.data = maxId;
609
+ // 转换成 V3 的 criterion
610
+ const criterionV3 = (0, logic_1.convertCriterionToCriterionV3)(criterion);
611
+ rs = await Request.GetInstance().getRecordsV3OrCounByCriterion(apiName, criterionV3, queryBuilder.fuzzySearch, [new order_1.Order('_id', 'asc')], queryBuilder.getSelect(), 0, newLimit, false, this.authType);
612
+ }
517
613
  else {
518
614
  // 更新 maxId
519
615
  criterion.conditions[criterion.conditions.length - 1].right.settings.data = maxId;
@@ -604,6 +700,13 @@ class _KQuery {
604
700
  return await Request.GetInstance().openSDKGetRecords(apiName, param);
605
701
  });
606
702
  }
703
+ else if (appCtx && appCtx.dataVersion === "v3") {
704
+ // 更新 maxId
705
+ criterion.conditions[criterion.conditions.length - 1].right.settings.data = maxId;
706
+ // 转换成 V3 的 criterion
707
+ const criterionV3 = (0, logic_1.convertCriterionToCriterionV3)(criterion);
708
+ rs = await Request.GetInstance().getRecordsV3OrCounByCriterion(apiName, criterionV3, queryBuilder.fuzzySearch, orders, selectFields, curOffset, newLimit, false, this.authType);
709
+ }
607
710
  else {
608
711
  // 更新 maxId
609
712
  criterion.conditions[criterion.conditions.length - 1].right.settings.data = maxId;
@@ -690,9 +793,6 @@ class _KQuery {
690
793
  }
691
794
  select(fieldApiNames, ...restFieldApiNames) {
692
795
  const { appCtx } = queryPropertiesStore.get(this);
693
- if (appCtx && appCtx.dataVersion == "v3") {
694
- console.log("=======================wby test: ", appCtx.dataVersion);
695
- }
696
796
  fieldApiNames = !fieldApiNames ? [] : fieldApiNames;
697
797
  let fields = server_common_node_1.utils.argsToList(fieldApiNames, restFieldApiNames);
698
798
  const { queryBuilder, queryV2 } = queryPropertiesStore.get(this);
@@ -772,6 +872,9 @@ class _KQuery {
772
872
  ;
773
873
  async count() {
774
874
  const { apiName, appCtx, queryBuilder, queryV2 } = queryPropertiesStore.get(this);
875
+ if (appCtx && appCtx.dataVersion == "v3") {
876
+ return await this.findV3(true);
877
+ }
775
878
  if (queryV2) {
776
879
  const param = {
777
880
  limit: 1,
@@ -795,6 +898,20 @@ class _KQuery {
795
898
  }
796
899
  }
797
900
  ;
901
+ async findV3(needCount) {
902
+ const { apiName, appCtx, queryBuilder, queryV2 } = queryPropertiesStore.get(this);
903
+ let criterion = (0, logic_1.buildCriterion)(queryBuilder.getLogic(), apiName);
904
+ if (queryBuilder.getLogic().logics.length > 0) {
905
+ // console.log("test-----------------------", queryBuilder.getLogic().logics)
906
+ criterion = await (0, logic_1.handleCriterion)(criterion);
907
+ }
908
+ const criterionV3 = (0, logic_1.convertCriterionToCriterionV3)(criterion);
909
+ const res = await Request.GetInstance().getRecordsV3OrCounByCriterion(apiName, criterionV3, queryBuilder.fuzzySearch, queryBuilder.getOrder(), queryBuilder.getSelect(), queryBuilder.getOffset(), queryBuilder.getLimit(), needCount, this.authType);
910
+ if (needCount) {
911
+ return res;
912
+ }
913
+ return res;
914
+ }
798
915
  findPreCheck() {
799
916
  const { queryBuilder, queryV2 } = queryPropertiesStore.get(this);
800
917
  let limit = queryBuilder_1.defaultLimit;
@@ -74,7 +74,14 @@ class Transaction {
74
74
  throw new server_common_node_1.exceptions.InvalidParamError('record is empty');
75
75
  }
76
76
  recordMap = permissionUtils.delUnauthField(recordMap).newRecord;
77
- const recordID = recordMap._id;
77
+ // const recordID: number = recordMap._id;
78
+ let recordID;
79
+ if (typeof recordMap._id === 'number') {
80
+ recordID = recordMap._id;
81
+ }
82
+ else if (typeof recordMap._id === 'string') {
83
+ recordID = parseInt(recordMap._id);
84
+ }
78
85
  if (!recordID) {
79
86
  throw new server_common_node_1.exceptions.InvalidParamError('record._id is empty');
80
87
  }
@@ -37,6 +37,12 @@ declare class MetaData<mt> implements IMetaData<mt> {
37
37
  page(apiName: string, objectApiName: string, type: string): Page;
38
38
  }
39
39
  declare function metadata<mt>(ctx: any): IMetaData<mt>;
40
+ declare class MetaDataV2<mt> implements IMetaData<mt> {
41
+ constructor(ctx: any);
42
+ object<T>(objectApiName: keyof mt): IKObject<T>;
43
+ page(apiName: string, objectApiName: string, type: string): Page;
44
+ }
45
+ declare function metadataV2<mt>(ctx: any): IMetaData<mt>;
40
46
  declare class Page implements IPage {
41
47
  pageApiName: string;
42
48
  objectApiName: string;
@@ -55,4 +61,4 @@ declare class Page implements IPage {
55
61
  updateMobileList(componentName: string, params: any): Promise<void>;
56
62
  }
57
63
  declare function metaType(): any;
58
- export { IMetaData, IKObject, IPage, MetaData, metadata, metaType, };
64
+ export { IMetaData, IKObject, IPage, MetaData, metadata, metaType, MetaDataV2, metadataV2, };
@@ -2,7 +2,7 @@
2
2
  // Copyright 2022 ByteDance Ltd. and/or its affiliates
3
3
  // SPDX-License-Identifier: MIT
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.metaType = exports.metadata = exports.MetaData = void 0;
5
+ exports.metadataV2 = exports.MetaDataV2 = exports.metaType = exports.metadata = exports.MetaData = void 0;
6
6
  const components = require("./components/components");
7
7
  const common = require("@byted-apaas/server-common-node");
8
8
  const fields = require("./objects/fields");
@@ -36,6 +36,33 @@ function metadata(ctx) {
36
36
  return new MetaData(ctx);
37
37
  }
38
38
  exports.metadata = metadata;
39
+ class MetaDataV2 {
40
+ constructor(ctx) {
41
+ }
42
+ object(objectApiName) {
43
+ if (!objectApiName) {
44
+ throw new commonExceptions.InvalidParamError('objectApiName is empty');
45
+ }
46
+ return new KObject(objectApiName);
47
+ }
48
+ page(apiName, objectApiName, type) {
49
+ if (!apiName) {
50
+ throw new commonExceptions.InvalidParamError('apiName is empty');
51
+ }
52
+ if (!objectApiName) {
53
+ throw new commonExceptions.InvalidParamError('objectApiName is empty');
54
+ }
55
+ if (!type) {
56
+ throw new commonExceptions.InvalidParamError('type is empty');
57
+ }
58
+ return new Page(apiName, objectApiName, type);
59
+ }
60
+ }
61
+ exports.MetaDataV2 = MetaDataV2;
62
+ function metadataV2(ctx) {
63
+ return new MetaData(ctx);
64
+ }
65
+ exports.metadataV2 = metadataV2;
39
66
  class KObject {
40
67
  constructor(objectApiName) {
41
68
  this.objectApiName = objectApiName;
@@ -7,6 +7,7 @@ import { _Resources } from '../context/resources/impl/resources';
7
7
  import { Message } from '../context/msg/msg';
8
8
  import { _IIntegration } from '../context/integration/IIntegration';
9
9
  import { DBV3 } from '../context/db/impl/dbV3';
10
+ import { MetaDataV2 } from '../context/metadata/metadata';
10
11
  declare global {
11
12
  export namespace application {
12
13
  /**
@@ -26,9 +27,13 @@ declare global {
26
27
  */
27
28
  let operator: IOperator;
28
29
  /**
29
- * data 接口
30
+ * dataV2 接口
30
31
  */
31
32
  let dataV2: DBV3<{}>;
33
+ /**
34
+ * metadataV2 接口
35
+ */
36
+ let metadataV2: MetaDataV2<{}>;
32
37
  /**
33
38
  * 常量
34
39
  */
package/hooks/hooks.js CHANGED
@@ -86,6 +86,7 @@ function mountApplication(context) {
86
86
  global.application.msg = new msg_1.Message();
87
87
  global.application.resources = new resources_1._Resources();
88
88
  global.application.metadata = metadataApi.metadata(context);
89
+ global.application.metadataV2 = metadataApi.metadataV2(context);
89
90
  // globalVar
90
91
  if (!global.application.globalVar) {
91
92
  global.application.globalVar = {};
@@ -44,4 +44,32 @@ export declare class ConstantExpressionField extends ExpressionField {
44
44
  export declare class MetadataExpressionField extends ExpressionField {
45
45
  constructor(objectApiName: string, fieldApiName: string);
46
46
  }
47
+ export declare class ExpressionV3 {
48
+ index: number;
49
+ left: ExpressionFieldV3;
50
+ operator: string;
51
+ right: ExpressionFieldV3;
52
+ constructor(left: ExpressionFieldV3, operator: string, right: ExpressionFieldV3, index: number);
53
+ }
54
+ declare class ExpressionFieldV3 {
55
+ type: string;
56
+ settings: string;
57
+ constructor(type: string, settings: string);
58
+ }
59
+ /**
60
+ * 常量表达式字段
61
+ *
62
+ * 比如在 condition: user.name equal 'bob' 中,'bob' 将被构建为 ConstantExpressionField
63
+ */
64
+ export declare class ConstantExpressionFieldV3 extends ExpressionFieldV3 {
65
+ constructor(data?: UserDataType);
66
+ }
67
+ /**
68
+ * 元数据表达式字段
69
+ *
70
+ * 比如在 condition: user.name equal 'bob' 中,'user.name' 将被构建为 MetadataExpressionField
71
+ */
72
+ export declare class MetadataExpressionFieldV3 extends ExpressionFieldV3 {
73
+ constructor(filedPath?: PathType[]);
74
+ }
47
75
  export {};
@@ -2,7 +2,7 @@
2
2
  // Copyright 2022 ByteDance Ltd. and/or its affiliates
3
3
  // SPDX-License-Identifier: MIT
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.MetadataExpressionField = exports.ConstantExpressionField = exports.Expression = void 0;
5
+ exports.MetadataExpressionFieldV3 = exports.ConstantExpressionFieldV3 = exports.ExpressionV3 = exports.MetadataExpressionField = exports.ConstantExpressionField = exports.Expression = void 0;
6
6
  class Expression {
7
7
  constructor(left, operator, right, index) {
8
8
  this.index = index;
@@ -54,3 +54,43 @@ class MetadataExpressionField extends ExpressionField {
54
54
  }
55
55
  }
56
56
  exports.MetadataExpressionField = MetadataExpressionField;
57
+ class ExpressionV3 {
58
+ constructor(left, operator, right, index) {
59
+ this.index = index;
60
+ this.left = left;
61
+ this.operator = operator;
62
+ this.right = right;
63
+ }
64
+ }
65
+ exports.ExpressionV3 = ExpressionV3;
66
+ class ExpressionFieldV3 {
67
+ constructor(type, settings) {
68
+ this.type = type;
69
+ this.settings = settings;
70
+ }
71
+ }
72
+ /**
73
+ * 常量表达式字段
74
+ *
75
+ * 比如在 condition: user.name equal 'bob' 中,'bob' 将被构建为 ConstantExpressionField
76
+ */
77
+ class ConstantExpressionFieldV3 extends ExpressionFieldV3 {
78
+ constructor(data) {
79
+ const d = { 'data': data };
80
+ super('constant', JSON.stringify(d));
81
+ }
82
+ }
83
+ exports.ConstantExpressionFieldV3 = ConstantExpressionFieldV3;
84
+ /**
85
+ * 元数据表达式字段
86
+ *
87
+ * 比如在 condition: user.name equal 'bob' 中,'user.name' 将被构建为 MetadataExpressionField
88
+ */
89
+ class MetadataExpressionFieldV3 extends ExpressionFieldV3 {
90
+ constructor(filedPath) {
91
+ const filedPathV3 = filedPath.map(({ extendLogicTags, ...item }) => item);
92
+ const fp = { 'fieldPath': filedPathV3 };
93
+ super('metadataVariable', JSON.stringify(fp));
94
+ }
95
+ }
96
+ exports.MetadataExpressionFieldV3 = MetadataExpressionFieldV3;
@@ -1,4 +1,4 @@
1
- import { Expression, UserDataType } from './expression';
1
+ import { Expression, UserDataType, ExpressionV3 } from './expression';
2
2
  export declare class Condition {
3
3
  left: string;
4
4
  right: Condition | UserDataType;
@@ -17,6 +17,10 @@ export type Criterion = {
17
17
  conditions: Expression[];
18
18
  logic: string;
19
19
  };
20
+ export type CriterionV3 = {
21
+ conditions: ExpressionV3[];
22
+ expression: string;
23
+ };
20
24
  /**
21
25
  * 构造 criterion
22
26
  *
@@ -34,6 +38,12 @@ export declare function buildExpression(objectApiName: string, left: string, rig
34
38
  * @param maxId 添加 _id>maxId 条件
35
39
  */
36
40
  export declare function addIDCriterion(criterion: Criterion, apiName: string, maxId: number): Criterion;
41
+ /**
42
+ * 构造 convertCriterionToCriterionV3
43
+ *
44
+ * @param criterion v1 版本的条件
45
+ */
46
+ export declare function convertCriterionToCriterionV3(criterion: Criterion): CriterionV3;
37
47
  export declare class Logic {
38
48
  value: string;
39
49
  expressions: {
@@ -2,7 +2,7 @@
2
2
  // Copyright 2022 ByteDance Ltd. and/or its affiliates
3
3
  // SPDX-License-Identifier: MIT
4
4
  Object.defineProperty(exports, "__esModule", { value: true });
5
- exports.handleCriterion = exports.buildLogic = exports.Logic = exports.addIDCriterion = exports.buildExpression = exports.buildCriterion = exports.Condition = void 0;
5
+ exports.handleCriterion = exports.buildLogic = exports.Logic = exports.convertCriterionToCriterionV3 = exports.addIDCriterion = exports.buildExpression = exports.buildCriterion = exports.Condition = void 0;
6
6
  const expression_1 = require("./expression");
7
7
  const operator_1 = require("./operator");
8
8
  const server_common_node_1 = require("@byted-apaas/server-common-node");
@@ -186,6 +186,26 @@ function addIDCriterion(criterion, apiName, maxId) {
186
186
  return criterion;
187
187
  }
188
188
  exports.addIDCriterion = addIDCriterion;
189
+ /**
190
+ * 构造 convertCriterionToCriterionV3
191
+ *
192
+ * @param criterion v1 版本的条件
193
+ */
194
+ function convertCriterionToCriterionV3(criterion) {
195
+ let criterionV3 = {
196
+ conditions: [],
197
+ expression: criterion.logic
198
+ };
199
+ // const criterionCopy = {...criterion}; // 创造一个v1Data的拷贝
200
+ criterionV3.conditions = criterion.conditions.map(condition => {
201
+ const rightField = new expression_1.ConstantExpressionFieldV3(condition.right.settings.data);
202
+ const leftField = new expression_1.MetadataExpressionFieldV3(condition.left.settings.fieldPath);
203
+ let conditionV3 = new expression_1.ExpressionV3(leftField, condition.operator, rightField, condition.index);
204
+ return conditionV3;
205
+ });
206
+ return criterionV3;
207
+ }
208
+ exports.convertCriterionToCriterionV3 = convertCriterionToCriterionV3;
189
209
  // 逻辑操作:and 和 or
190
210
  class Logic {
191
211
  constructor(expressions = null, logicValue = 'and') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@byted-apaas/server-sdk-node",
3
- "version": "1.1.18-beta.2",
3
+ "version": "1.1.18-beta.3",
4
4
  "description": "aPaaS Server SDK",
5
5
  "author": "zhouwexin <zhouwexin@bytedance.com>",
6
6
  "homepage": "",
@@ -13,7 +13,7 @@
13
13
  "clean": "tsc --build --clean && rm -rf **/*.js.map"
14
14
  },
15
15
  "dependencies": {
16
- "@byted-apaas/server-common-node": "^2.0.9",
16
+ "@byted-apaas/server-common-node": "2.0.12-beta.3",
17
17
  "@jorgeferrero/stream-to-buffer": "^2.0.6",
18
18
  "dayjs": "^1.9.6",
19
19
  "form-data": "^3.0.0",
@@ -1,6 +1,6 @@
1
1
  /// <reference types="node" />
2
2
  /// <reference types="node" />
3
- import { Criterion } from '../kunlun/operator/impl/logic';
3
+ import { Criterion, CriterionV3 } from '../kunlun/operator/impl/logic';
4
4
  import { Stream } from 'stream';
5
5
  import { ExecutionInfo, ExecutionResult, RevokeExecutionOptions } from '@byted-apaas/server-common-node/context/workflow/workflow';
6
6
  import { AppCtx } from '../application/application';
@@ -44,8 +44,11 @@ export interface IInnerAPIRequest extends IInnerAPIBaseRequest, IInnerAPIOpenSDK
44
44
  }
45
45
  export interface IInnerAPIBaseRequest {
46
46
  createRecordBySync: (objectApiName: string, record: object, authType: string) => any;
47
+ createRecordV3BySync: (objectApiName: string, record: object, authType: string) => any;
47
48
  updateRecordBySync: (objectApiName: string, recordID: number, record: object, authType: string) => any;
49
+ updateRecordV3BySync: (objectApiName: string, recordID: string, record: object, authType: string) => any;
48
50
  deleteRecordBySync: (objectApiName: string, recordID: number, authType: string) => any;
51
+ deleteRecordV3BySync: (objectApiName: string, recordID: string, authType: string) => any;
49
52
  createRecordsByAsync: (objectApiName: string, records: object[], authType: string) => any;
50
53
  updateRecordsByAsync: (objectApiName: string, recordMap: Record<number, object>, authType: string) => any;
51
54
  deleteRecordsByAsync: (objectApiName: string, recordIDs: number[], authType: string) => any;
@@ -53,6 +56,7 @@ export interface IInnerAPIBaseRequest {
53
56
  updateRecordsBySync: (objectApiName: string, recordMap: Record<number, object>, authType: string) => Promise<Record<number, string>>;
54
57
  deleteRecordsBySync: (objectApiName: string, recordIDs: number[], authType: string) => Promise<Record<number, string>>;
55
58
  getRecordsOrCountByCriterion: (objectApiName: string, criterion: string | Criterion, fuzzySearch: any, order: Order[], ignoreBackLookupField: boolean, fieldApiNames: string[], offset: number, limit: number, needCount: boolean, authType: string) => any;
59
+ getRecordsV3OrCounByCriterion: (objectApiName: string, criterion: string | CriterionV3, fuzzySearch: any, order: Order[], fieldApiNames: string[], offset: number, limit: number, needCount: boolean, authType: string) => any;
56
60
  updateWorkflowVariables: (ctx: any, instanceId: number, variables: object, variableTypes: object) => Promise<void>;
57
61
  uploadFile: (data: Stream, expire: number, fileName?: string) => Promise<UploadFileResp>;
58
62
  downloadFileByID: (fileID: string, filePath?: string) => Promise<Buffer | undefined>;
@@ -2,7 +2,7 @@
2
2
  /// <reference types="node" />
3
3
  import { Stream } from 'stream';
4
4
  import { Order } from '../context/db/impl/order';
5
- import { Criterion } from '../kunlun/operator/impl/logic';
5
+ import { Criterion, CriterionV3 } from '../kunlun/operator/impl/logic';
6
6
  import { IInnerAPIRequest, OpenSDKGetRecordsReq, UploadFileResp } from './interface';
7
7
  import { ExecutionInfo, ExecutionResult, RevokeExecutionOptions } from '@byted-apaas/server-common-node/context/workflow/workflow';
8
8
  import { AppCtx } from '../application/application';
@@ -12,8 +12,11 @@ export declare class RequestHttp implements IInnerAPIRequest {
12
12
  constructor();
13
13
  updateWorkflowVariables(ctx: any, instanceId: number, variables: object, variableTypes: object): any;
14
14
  createRecordBySync(objectApiName: string, record: object, authType: string): any;
15
+ createRecordV3BySync(objectApiName: string, record: object, authType: string): any;
15
16
  updateRecordBySync(objectApiName: string, recordID: number, record: object, authType: string): any;
17
+ updateRecordV3BySync(objectApiName: string, recordID: string, record: object, authType: string): any;
16
18
  deleteRecordBySync(objectApiName: string, recordID: number, authType: string): any;
19
+ deleteRecordV3BySync(objectApiName: string, recordID: string, authType: string): any;
17
20
  createRecordsByAsync(objectApiName: string, records: object[], authType: string): any;
18
21
  updateRecordsByAsync(objectApiName: string, recordMap: Record<number, object>, authType: string): any;
19
22
  deleteRecordsByAsync(objectApiName: string, recordIDs: number[], authType: string): any;
@@ -21,6 +24,7 @@ export declare class RequestHttp implements IInnerAPIRequest {
21
24
  updateRecordsBySync(objectApiName: string, recordMap: Record<number, object>, authType: string): Promise<Record<number, string>>;
22
25
  deleteRecordsBySync(objectApiName: string, recordIDs: number[], authType: string): Promise<Record<number, string>>;
23
26
  getRecordsOrCountByCriterion(objectApiName: string, criterion: string | Criterion, order: Order[], fuzzySearch: any, ignoreBackLookupField: boolean, fieldApiNames: string[], offset: number, limit: number, needCount: boolean, authType: string): any;
27
+ getRecordsV3OrCounByCriterion(objectApiName: string, criterion: string | CriterionV3, order: Order[], fuzzySearch: any, fieldApiNames: string[], offset: number, limit: number, needCount: boolean, authType: string): any;
24
28
  uploadFile(data: Stream, expire: number, fileName?: string): Promise<UploadFileResp>;
25
29
  downloadFileByID(fileID: string, filePath?: string): Promise<undefined | Buffer>;
26
30
  downloadFileByToken(fileToken: string, filePath?: string): Promise<Buffer | undefined>;
@@ -69,6 +69,39 @@ async function createRecordBySync(objectApiName, record, authType) {
69
69
  }
70
70
  return data;
71
71
  }
72
+ // todo wby
73
+ async function createRecordV3BySync(objectApiName, record, authType) {
74
+ // 1.check
75
+ if (!objectApiName) {
76
+ throw new exceptions.InvalidParamError('objectApiName is empty');
77
+ }
78
+ // 2.获取 options
79
+ let options = commonHttp.getOptions(null, openapiHttpPath.createRecordV3BySync);
80
+ let urlPath = options._reqPath.replace(replaceKeys.namespace, await (0, common_1.getNamespaceForOpenAndFaaSSDK)());
81
+ urlPath = urlPath.replace(replaceKeys.objectApiName, objectApiName);
82
+ // 3.请求
83
+ options.json = {
84
+ 'data_version': "v3",
85
+ 'record': record,
86
+ };
87
+ authType = (0, utils_1.formatAuthType)(authType);
88
+ options.headers.User = String(utils.getUserIDFromCtx());
89
+ if (authType) {
90
+ options.headers[constants_3.AuthTypeHttpHeader] = authType;
91
+ }
92
+ let task_id = utils.getTriggerTaskID();
93
+ if (task_id) {
94
+ options.json.task_id = task_id;
95
+ }
96
+ let data = await openapi.doRequest(null, urlPath, options);
97
+ if (data && data.record_id) {
98
+ return { _id: data.record_id };
99
+ }
100
+ if (data && data.recordID) {
101
+ return { _id: data.recordID };
102
+ }
103
+ return data;
104
+ }
72
105
  async function updateRecordBySync(objectApiName, recordID, record, authType) {
73
106
  // 1.check
74
107
  if (!objectApiName) {
@@ -95,6 +128,33 @@ async function updateRecordBySync(objectApiName, recordID, record, authType) {
95
128
  }
96
129
  return openapi.doRequest(null, urlPath, options);
97
130
  }
131
+ // todo wby
132
+ async function updateRecordV3BySync(objectApiName, recordID, record, authType) {
133
+ // 1.check
134
+ if (!objectApiName) {
135
+ throw new exceptions.InvalidParamError('objectApiName is empty');
136
+ }
137
+ // 2.获取 options
138
+ let options = commonHttp.getOptions(null, openapiHttpPath.updateRecordV3BySync);
139
+ let urlPath = options._reqPath.replace(replaceKeys.namespace, await (0, common_1.getNamespaceForOpenAndFaaSSDK)());
140
+ urlPath = urlPath.replace(replaceKeys.objectApiName, objectApiName);
141
+ urlPath = urlPath.replace(replaceKeys.recordID, recordID);
142
+ // 3.请求
143
+ options.json = {
144
+ "record": record,
145
+ "data_version": "v3"
146
+ };
147
+ authType = (0, utils_1.formatAuthType)(authType);
148
+ options.headers.User = String(utils.getUserIDFromCtx());
149
+ if (authType) {
150
+ options.headers[constants_3.AuthTypeHttpHeader] = authType;
151
+ }
152
+ let task_id = utils.getTriggerTaskID();
153
+ if (task_id) {
154
+ options.json.task_id = task_id;
155
+ }
156
+ return openapi.doRequest(null, urlPath, options);
157
+ }
98
158
  async function deleteRecordBySync(objectApiName, recordID, authType) {
99
159
  // 1.check
100
160
  if (!objectApiName) {
@@ -120,6 +180,9 @@ async function deleteRecordBySync(objectApiName, recordID, authType) {
120
180
  }
121
181
  return openapi.doRequest(null, urlPath, options);
122
182
  }
183
+ // todo wby
184
+ async function deleteRecordV3BySync(objectApiName, recordID, authType) {
185
+ }
123
186
  async function createRecordsByAsync(objectApiName, records, authType) {
124
187
  // 1.获取 options
125
188
  let options = commonHttp.getOptions(null, openapiHttpPath.createRecordsByAsyncV2);
@@ -274,8 +337,11 @@ function handleResponse(objectAPIName, data, needCount) {
274
337
  return 0;
275
338
  }
276
339
  else {
277
- if (checkUtils.isObject(data) && data.data_list) {
278
- const records = data.data_list;
340
+ if (checkUtils.isObject(data) && (data.data_list || data.items)) {
341
+ let records = data.data_list;
342
+ if (data.items) {
343
+ records = data.items;
344
+ }
279
345
  if (data.unauthPermissionInfo && data.unauthPermissionInfo.UnauthFieldSlice) {
280
346
  permissionUtils.appendUnauthFieldRecordList(objectAPIName, records, data.unauthPermissionInfo.UnauthFieldSlice, true);
281
347
  }
@@ -324,6 +390,46 @@ async function getRecordsOrCountByCriterion(objectApiName, criterion, fuzzySearc
324
390
  let data = await openapi.doRequest(null, urlPath, options);
325
391
  return handleResponse(objectApiName, data, needCount);
326
392
  }
393
+ async function getRecordsV3OrCountByCriterion(objectApiName, criterion, order, fuzzySearch, fieldApiNames, offset, limit, needCount, authType) {
394
+ // 1.check
395
+ if (!objectApiName) {
396
+ throw new exceptions.InternalError('objectApiName is empty');
397
+ }
398
+ // 2.获取 options
399
+ let options = commonHttp.getOptions(null, openapiHttpPath.mGetRecordsV3OrCounByCriterion);
400
+ let urlPath = options._reqPath.replace(replaceKeys.namespace, await (0, common_1.getNamespaceForOpenAndFaaSSDK)());
401
+ urlPath = urlPath.replace(replaceKeys.objectApiName, objectApiName);
402
+ if (needCount) {
403
+ fieldApiNames = ['_id'];
404
+ }
405
+ if (typeof criterion === 'string') {
406
+ criterion = JSON.parse(criterion);
407
+ }
408
+ console.log('criterion', JSON.stringify(criterion));
409
+ // 3.请求
410
+ options.json = {
411
+ 'page_size': limit,
412
+ 'offset': offset,
413
+ 'select': fieldApiNames,
414
+ 'order_by': order,
415
+ 'need_total_count': needCount,
416
+ 'filter': criterion,
417
+ // fuzzySearch, // todo wby
418
+ // 只返回 slice 结果,使用 SliceResult
419
+ // 只返回 map 结果,使用 MapResult
420
+ // 分不清场景可以用 BothResult,性能较差,建议区分场景
421
+ // 0 表示不返回 unauth field 任何数据; 1 表示两者都返回;2 表示仅返回 slice;3 表示仅返回 map
422
+ 'process_auth_field_type': 2,
423
+ 'date_version': 'v3',
424
+ };
425
+ authType = (0, utils_1.formatAuthType)(authType);
426
+ options.headers.User = String(utils.getUserIDFromCtx());
427
+ if (authType) {
428
+ options.headers[constants_3.AuthTypeHttpHeader] = authType;
429
+ }
430
+ let data = await openapi.doRequest(null, urlPath, options);
431
+ return handleResponse(objectApiName, data, needCount);
432
+ }
327
433
  /**
328
434
  * 上传文件
329
435
  *
@@ -782,8 +888,11 @@ class RequestHttp {
782
888
  constructor() {
783
889
  this.updateWorkflowVariables = updateWorkflowVariables;
784
890
  this.createRecordBySync = createRecordBySync;
891
+ this.createRecordV3BySync = createRecordV3BySync;
785
892
  this.updateRecordBySync = updateRecordBySync;
893
+ this.updateRecordV3BySync = updateRecordV3BySync;
786
894
  this.deleteRecordBySync = deleteRecordBySync;
895
+ this.deleteRecordV3BySync = deleteRecordV3BySync;
787
896
  this.createRecordsByAsync = createRecordsByAsync;
788
897
  this.updateRecordsByAsync = updateRecordsByAsync;
789
898
  this.deleteRecordsByAsync = deleteRecordsByAsync;
@@ -791,6 +900,7 @@ class RequestHttp {
791
900
  this.updateRecordsBySync = updateRecordsBySync;
792
901
  this.deleteRecordsBySync = deleteRecordsBySync;
793
902
  this.getRecordsOrCountByCriterion = getRecordsOrCountByCriterion;
903
+ this.getRecordsV3OrCounByCriterion = getRecordsV3OrCountByCriterion;
794
904
  this.uploadFile = uploadFile;
795
905
  this.downloadFileByID = downloadFileByID;
796
906
  this.downloadFileByToken = downloadFileByToken;
@@ -823,10 +933,16 @@ class RequestHttp {
823
933
  }
824
934
  createRecordBySync(objectApiName, record, authType) {
825
935
  }
936
+ createRecordV3BySync(objectApiName, record, authType) {
937
+ }
826
938
  updateRecordBySync(objectApiName, recordID, record, authType) {
827
939
  }
940
+ updateRecordV3BySync(objectApiName, recordID, record, authType) {
941
+ }
828
942
  deleteRecordBySync(objectApiName, recordID, authType) {
829
943
  }
944
+ deleteRecordV3BySync(objectApiName, recordID, authType) {
945
+ }
830
946
  createRecordsByAsync(objectApiName, records, authType) {
831
947
  }
832
948
  updateRecordsByAsync(objectApiName, recordMap, authType) {
@@ -843,6 +959,8 @@ class RequestHttp {
843
959
  }
844
960
  getRecordsOrCountByCriterion(objectApiName, criterion, order, fuzzySearch, ignoreBackLookupField, fieldApiNames, offset, limit, needCount, authType) {
845
961
  }
962
+ getRecordsV3OrCounByCriterion(objectApiName, criterion, order, fuzzySearch, fieldApiNames, offset, limit, needCount, authType) {
963
+ }
846
964
  uploadFile(data, expire, fileName) {
847
965
  return null;
848
966
  }
package/types/types.d.ts CHANGED
@@ -23,7 +23,7 @@ export type _Record<T> = {
23
23
  [K in keyof T]: T[K] extends _LookupField ? _LookupFieldRet : T[K];
24
24
  };
25
25
  export type _CondRequireID<T> = _Cond<T> & {
26
- _id: number;
26
+ _id: number | string;
27
27
  };
28
28
  interface _LookupFieldRet {
29
29
  /**