@lcap/nasl 3.8.3-beta.5 → 3.8.3-beta.7

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.
@@ -5,5 +5,14 @@ declare namespace _default {
5
5
  const method: string;
6
6
  }
7
7
  }
8
+ namespace queryDebugTypescriptBatch {
9
+ export namespace url_1 {
10
+ const path_1: string;
11
+ export { path_1 as path };
12
+ const method_1: string;
13
+ export { method_1 as method };
14
+ }
15
+ export { url_1 as url };
16
+ }
8
17
  }
9
18
  export default _default;
@@ -7,5 +7,11 @@ exports.default = {
7
7
  method: 'post',
8
8
  },
9
9
  },
10
+ queryDebugTypescriptBatch: {
11
+ url: {
12
+ path: '/api/v1/querydebug/generate/typescriptBatch',
13
+ method: 'post',
14
+ },
15
+ },
10
16
  };
11
17
  //# sourceMappingURL=api.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/service/logic/api.js"],"names":[],"mappings":";;AAAA,kBAAe;IACX,oBAAoB,EAAE;QAClB,GAAG,EAAE;YACD,IAAI,EAAE,wCAAwC;YAC9C,MAAM,EAAE,MAAM;SACjB;KACJ;CACJ,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/service/logic/api.js"],"names":[],"mappings":";;AAAA,kBAAe;IACX,oBAAoB,EAAE;QAClB,GAAG,EAAE;YACD,IAAI,EAAE,wCAAwC;YAC9C,MAAM,EAAE,MAAM;SACjB;KACJ;IACD,yBAAyB,EAAE;QACvB,GAAG,EAAE;YACD,IAAI,EAAE,6CAA6C;YACnD,MAAM,EAAE,MAAM;SACjB;KACJ;CACJ,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@lcap/nasl",
3
3
  "description": "NetEase Application Specific Language",
4
- "version": "3.8.3-beta.5",
4
+ "version": "3.8.3-beta.7",
5
5
  "author": "Forrest <rainforest92@126.com>",
6
6
  "main": "./out",
7
7
  "license": "MIT",
@@ -1,11 +1,11 @@
1
1
  declare namespace nasl.collection {
2
- export class List<in out T> {
2
+ export class List<T> {
3
3
  length: nasl.core.Long;
4
4
  __slice: (start?: nasl.core.Long, end?: nasl.core.Long) => List<T>;
5
5
  __forEach: (callbackfn: (value: T, index: nasl.core.Long) => void) => void;
6
6
  __get: (index?: any) => T;
7
7
  }
8
- export class PageOf<in out T> {
8
+ export class PageOf<T> {
9
9
  content: nasl.collection.List<T>;
10
10
  number: nasl.core.Long;
11
11
  size: nasl.core.Long;
@@ -16,7 +16,7 @@ declare namespace nasl.collection {
16
16
  empty: nasl.core.Boolean;
17
17
  totalElements: nasl.core.Long;
18
18
  }
19
- export class Map<in out K, in out V> {
19
+ export class Map<K, V> {
20
20
  __set: (key?: K, value?: V) => any;
21
21
  length: nasl.core.Long;
22
22
  accept: 'Map';
@@ -1,17 +1,239 @@
1
+ import type { AxiosInstance } from 'axios';
1
2
  import type { types } from '../concepts';
3
+ import EntityProperty from '../concepts/EntityProperty__';
4
+ import Entity from '../concepts/Entity__';
5
+ import OqlQueryComponent from '../concepts/OqlQueryComponent__';
6
+ import api from '../service/logic/api';
7
+ import { naslOQLCacheStore } from '../utils/language-cache/nasl';
2
8
 
3
- export function waitOqlQueryComponentChildrenFinish(node: types.SyntaxNode) {
4
- const needGetSourceMapOqlList: Promise<any>[] = [];
9
+ type OQLEmbeddedTSRequestPayload = {
10
+ appId: 'myAppId';
11
+ oqlIdentifier: 'myoqlIdentifier';
12
+ dataSourceName: string;
13
+ oql: string;
14
+ ideVersion: string;
15
+ dataSourceNasl: any[];
16
+ typeScriptStartLine: 1;
17
+ typeScriptStartLineColumn: 1;
18
+ };
19
+
20
+ type PayloadWithCacheKey = {
21
+ payload: OQLEmbeddedTSRequestPayload | null;
22
+ cacheKey: string;
23
+ };
24
+
25
+ function preparePayloadAndCacheKey(oql: OqlQueryComponent): PayloadWithCacheKey {
26
+ if (oql.code) {
27
+ let dataSourceNasl = oql.app.findNodeByCompleteName(oql.dataSource)?.toJSON();
28
+ if (dataSourceNasl) {
29
+ dataSourceNasl = {
30
+ concept: 'DataSource',
31
+ entities: (dataSourceNasl.entities = dataSourceNasl.entities?.map((entity: Entity) => {
32
+ return {
33
+ name: entity.name,
34
+ concept: entity.concept,
35
+ tableName: entity.tableName,
36
+ properties: entity.properties?.map((prop: EntityProperty) => {
37
+ return {
38
+ name: prop.name,
39
+ concept: prop.concept,
40
+ columnName: prop.columnName,
41
+ };
42
+ }),
43
+ };
44
+ })),
45
+ };
46
+ }
47
+ const payload: OQLEmbeddedTSRequestPayload = {
48
+ appId: 'myAppId',
49
+ oqlIdentifier: 'myoqlIdentifier',
50
+ dataSourceName: oql.dataSource,
51
+ oql: oql.code,
52
+ ideVersion: oql.app.ideVersion,
53
+ dataSourceNasl,
54
+ typeScriptStartLine: 1,
55
+ typeScriptStartLineColumn: 1,
56
+ };
57
+ return {
58
+ cacheKey: JSON.stringify(payload),
59
+ payload: payload,
60
+ };
61
+ }
62
+ return {
63
+ cacheKey: '',
64
+ payload: null,
65
+ };
66
+ }
67
+
68
+ type RequestedEmbeddedTS = {
69
+ typescript: string;
70
+ lexicalErrorCode: number;
71
+ };
72
+
73
+ // 从服务端获取 SQL -> TS 的翻译和 sourceMap
74
+ export async function requestEmbeddedTS(this: OqlQueryComponent): Promise<void> {
75
+ const { http, logger } = this.rootNode.naslServer;
76
+
77
+ if (this.code) {
78
+ let dataSourceNasl = this.app.findNodeByCompleteName(this.dataSource)?.toJSON();
79
+ if (dataSourceNasl) {
80
+ dataSourceNasl = {
81
+ concept: 'DataSource',
82
+ entities: (dataSourceNasl.entities = dataSourceNasl.entities?.map((entity: Entity) => {
83
+ return {
84
+ name: entity.name,
85
+ concept: entity.concept,
86
+ tableName: entity.tableName,
87
+ properties: entity.properties?.map((prop: EntityProperty) => {
88
+ return {
89
+ name: prop.name,
90
+ concept: prop.concept,
91
+ columnName: prop.columnName,
92
+ };
93
+ }),
94
+ };
95
+ })),
96
+ };
97
+ }
98
+
99
+ const queryWithCache = async () => {
100
+ const params = {
101
+ appId: 'myAppId',
102
+ oqlIdentifier: 'myoqlIdentifier',
103
+ dataSourceName: this.dataSource,
104
+ oql: this.code,
105
+ ideVersion: this.app.ideVersion,
106
+ dataSourceNasl,
107
+ typeScriptStartLine: 1,
108
+ typeScriptStartLineColumn: 1,
109
+ };
110
+ const key = JSON.stringify(params);
111
+ let res = null;
112
+ let canUseCache = false;
113
+ try {
114
+ res = await naslOQLCacheStore.getItem(key);
115
+ canUseCache = true;
116
+ } catch (error) {}
117
+ if (res !== null) {
118
+ return res;
119
+ }
120
+ return http.post(api.queryDebugTypescript.url.path, params).then(async ({ data }) => {
121
+ if (canUseCache) {
122
+ try {
123
+ await naslOQLCacheStore.setItem(key, data);
124
+ } catch (error) {}
125
+ }
126
+ return data;
127
+ });
128
+ };
129
+
130
+ return queryWithCache()
131
+ .then((data: any) => {
132
+ this.codeSourceMap = data.result ?? { typescript: '', lexicalErrorCode: 1001 };
133
+ })
134
+ .catch((err) => {
135
+ logger.error('Oql 请求失败', err.toString());
136
+ this.codeSourceMap = { typescript: '', lexicalErrorCode: 1001 };
137
+ });
138
+ }
139
+ this.codeSourceMap = { typescript: '', lexicalErrorCode: 1001 };
140
+ }
141
+
142
+ async function makeCachedBatchRequest(
143
+ http: AxiosInstance,
144
+ payloadWithCacheKeyList: PayloadWithCacheKey[]
145
+ ): Promise<(RequestedEmbeddedTS | null)[]> {
146
+ const itemsWithIndex = payloadWithCacheKeyList.map((item, index) => {
147
+ return { item, index };
148
+ });
149
+
150
+ const cacheTest = await Promise.all(
151
+ itemsWithIndex.map(async ({ item, index }) => {
152
+ const cached: RequestedEmbeddedTS | null = await naslOQLCacheStore.getItem(item.cacheKey);
153
+ return { item, index, cached };
154
+ })
155
+ );
156
+
157
+ const notCachedList = cacheTest.filter((x) => !x.cached);
158
+ const cachedList = cacheTest.filter((x) => x.cached);
159
+
160
+ const resultContainer = Array.from<RequestedEmbeddedTS | null>({
161
+ length: payloadWithCacheKeyList.length,
162
+ }).fill(null);
163
+
164
+ for (const { cached, index } of cachedList) {
165
+ resultContainer[index] = cached;
166
+ }
167
+ const paramList = notCachedList.map((x) => x.item.payload);
168
+ const tempResultList: (RequestedEmbeddedTS | null)[] = paramList.length
169
+ ? await http
170
+ .post(api.queryDebugTypescriptBatch.url.path, paramList)
171
+ .then((x) => x.data.result)
172
+ .then(async (resultList: (RequestedEmbeddedTS | null)[]) => {
173
+ await Promise.all(
174
+ resultList.map((res, index) => {
175
+ const payload = notCachedList[index];
176
+ resultContainer[payload.index] = res;
177
+ return naslOQLCacheStore.setItem(payload.item.cacheKey, res);
178
+ })
179
+ );
180
+ return resultList;
181
+ })
182
+ : [];
183
+ if (tempResultList.length !== paramList.length) {
184
+ throw new Error('返回的数据长度不一致');
185
+ }
186
+ return resultContainer;
187
+ }
188
+
189
+ // 从服务端获取 SQL -> TS 的翻译和 sourceMap
190
+ export async function requestEmbeddedTSBatch(
191
+ http: AxiosInstance,
192
+ oqlList: OqlQueryComponent[]
193
+ ): Promise<void> {
194
+ const paramList = oqlList.map((oql) => {
195
+ const { cacheKey, payload } = preparePayloadAndCacheKey(oql);
196
+ return { oql, cacheKey, payload };
197
+ });
198
+
199
+ return makeCachedBatchRequest(http, paramList)
200
+ .then((data) => {
201
+ if (data.length !== oqlList.length) {
202
+ throw new Error('返回的数据长度不一致');
203
+ }
204
+ data.forEach((item, index) => {
205
+ const targetOql = oqlList[index];
206
+ targetOql.codeSourceMap = item ?? { typescript: '', lexicalErrorCode: 1001 };
207
+ });
208
+ })
209
+ .catch((err) => {
210
+ // TODO wudengke logger
211
+ console.error('Oql 请求失败', err.toString());
212
+ console.error(err);
213
+ });
214
+ }
215
+
216
+ export async function waitOqlQueryComponentChildrenFinish(node: types.SyntaxNode) {
217
+ const oqlList: OqlQueryComponent[] = [];
5
218
 
6
219
  node.traverseStrictChildren((el) => {
7
220
  if (el.concept === 'OqlQueryComponent') {
8
221
  if (!el.codeSourceMap) {
9
- needGetSourceMapOqlList.push(el.requestEmbeddedTS());
222
+ oqlList.push(el);
10
223
  }
11
224
  }
12
225
  });
13
226
 
14
- if (needGetSourceMapOqlList.length > 0) {
15
- return Promise.all(needGetSourceMapOqlList);
227
+ if (oqlList.length > 0) {
228
+ const http =
229
+ node.rootNode?.naslServer.http ??
230
+ // @ts-expect-error
231
+ // 若是App节点
232
+ node?.naslServer.http;
233
+ if (http) {
234
+ return requestEmbeddedTSBatch(http, oqlList);
235
+ } else {
236
+ throw new Error('http client 不存在');
237
+ }
16
238
  }
17
239
  }
@@ -14,9 +14,6 @@ import type StructureProperty from './StructureProperty__';
14
14
  import type Structure from './Structure__';
15
15
  import type Identifier from './Identifier__';
16
16
  import type MemberExpression from './MemberExpression__';
17
- import type { Entity } from './Entity__';
18
- import type { EntityProperty } from './EntityProperty__';
19
- import { naslOQLCacheStore } from '../utils/language-cache/nasl';
20
17
 
21
18
  //================================================================================
22
19
  // 从这里开始到结尾注释之间的代码由 NASL Workbench 自动生成,请不手动修改!
@@ -32,6 +29,7 @@ import * as asserts from './utils/asserts';
32
29
 
33
30
  import TypeAnnotation from './TypeAnnotation__';
34
31
  import LogicItem from './LogicItem__';
32
+ import api from '../service/logic/api';
35
33
 
36
34
  /**
37
35
  * SQL 查询
@@ -278,77 +276,6 @@ export class OqlQueryComponent extends LogicItem {
278
276
  return `sql"${code}"`;
279
277
  }
280
278
 
281
- // 从服务端获取 SQL -> TS 的翻译和 sourceMap
282
- async requestEmbeddedTS(): Promise<any> {
283
- const { http, logger } = this.rootNode.naslServer;
284
-
285
- if (this.code) {
286
- let dataSourceNasl = this.app.findNodeByCompleteName(this.dataSource)?.toJSON();
287
- if (dataSourceNasl) {
288
- dataSourceNasl = {
289
- concept: 'DataSource',
290
- entities: (dataSourceNasl.entities = dataSourceNasl.entities?.map((entity: Entity) => {
291
- return {
292
- name: entity.name,
293
- concept: entity.concept,
294
- tableName: entity.tableName,
295
- properties: entity.properties?.map((prop: EntityProperty) => {
296
- return {
297
- name: prop.name,
298
- concept: prop.concept,
299
- columnName: prop.columnName,
300
- };
301
- }),
302
- };
303
- })),
304
- };
305
- }
306
-
307
- const query = async () => {
308
- const params = {
309
- appId: 'myAppId',
310
- oqlIdentifier: 'myoqlIdentifier',
311
- dataSourceName: this.dataSource,
312
- oql: this.code,
313
- ideVersion: this.app.ideVersion,
314
- dataSourceNasl,
315
- typeScriptStartLine: 1,
316
- typeScriptStartLineColumn: 1,
317
- };
318
- const key = JSON.stringify(params);
319
- let res = null;
320
- let canUseCache = false;
321
- try {
322
- res = await naslOQLCacheStore.getItem(key);
323
- canUseCache = true;
324
- } catch (error) {}
325
- if (res !== null) {
326
- return res;
327
- }
328
- return http
329
- .post('/api/v1/querydebug/generate/typescript', params)
330
- .then(async ({ data }) => {
331
- if (canUseCache) {
332
- try {
333
- await naslOQLCacheStore.setItem(key, data);
334
- } catch (error) {}
335
- }
336
- return data;
337
- });
338
- };
339
-
340
- return query()
341
- .then((data: any) => {
342
- this.codeSourceMap = data.result ?? { typescript: '', lexicalErrorCode: 1001 };
343
- })
344
- .catch((err) => {
345
- logger.error('Oql 请求失败', err.toString());
346
- this.codeSourceMap = { typescript: '', lexicalErrorCode: 1001 };
347
- });
348
- }
349
- this.codeSourceMap = { typescript: '', lexicalErrorCode: 1001 };
350
- }
351
-
352
279
  /**
353
280
  * 获取添加时的默认选项
354
281
  * @returns
@@ -1001,7 +1001,7 @@ function transformNode2Logic(node: babelTypes.FunctionDeclaration, name: string,
1001
1001
  let logicItem = transformNode2Expression(item, 'logic');
1002
1002
  if (logicItem) {
1003
1003
  if ((logicItem as any).concept === 'Variable') {
1004
- if (!curLogic.variables.find((_: any) => _.name === logicItem.name)) curLogic.addVariable(logicItem);
1004
+ if (!curLogic.variables.find((_: any) => _.name === logicItem.name)) curLogic.addVariable({ ...logicItem, defaultValue: undefined });
1005
1005
  logicItem = new naslTypes.Assignment({
1006
1006
  left: new naslTypes.Identifier({ name: logicItem?.name }),
1007
1007
  right: (logicItem as any).defaultValue?.expression || '',
@@ -1320,7 +1320,7 @@ export function transform2LogicItem(node: babelTypes.Node, options: TransformOpt
1320
1320
  transformManager.registerCallExpression('alert', transformAlert2ShowMessage);
1321
1321
  transformManager.registerCallExpression((node, calleeName) => /^app.dataSources|app.logics/.test(calleeName), transformCall2CallDataSourceLogic);
1322
1322
  transformManager.registerCallExpression((node, calleeName) => /interfaces\./.test(calleeName), transformCall2Interface);
1323
- transformManager.registerCallExpression((node, calleeName) => /connectors\./.test(calleeName), transformCall2Connector);
1323
+ transformManager.registerCallExpression((node, calleeName) => /connector\./.test(calleeName), transformCall2Connector);
1324
1324
  transformManager.registerCallExpression((node, calleeName) => /extensions\./.test(calleeName), transformCall2Extension);
1325
1325
  transformManager.registerCallExpression((node) => node.callee.type === 'ArrowFunctionExpression', transformArrowFunction2Match);
1326
1326
  transformManager.registerCallExpression((node, calleeName) => ['plus', 'minus', 'multiply', 'divide', 'remainder', 'STARTWITH', 'ENDWITH', 'LIKE', 'IN'].includes(calleeName), transformCallExpressionToBinaryExpression);
@@ -123,6 +123,7 @@ import { traverse, FileNode } from '../utils';
123
123
  import { withQueueExecute } from '../decorators';
124
124
  import { getNodeByNodeCallee } from '../automate/engine/utils';
125
125
  import { isApp, isConnection, isConnector, isMsgTriggerEvent, isProcess, isProcessV2, isStrictLogic } from '../concepts/utils/asserts';
126
+ import { waitOqlQueryComponentChildrenFinish } from '../common/utils';
126
127
 
127
128
  import { collectAllSemanticCtx, clearSemanticData, printSemanticDataInfo } from './semanticData';
128
129
 
@@ -587,6 +588,8 @@ class NaslServer {
587
588
  frontends = []
588
589
  } = module as Module;
589
590
 
591
+ const oqlFinished = waitOqlQueryComponentChildrenFinish(module);
592
+
590
593
  yield* getTsFiles(structures, 'structure');
591
594
  yield* getTsFiles(metadataTypes, 'metadataType');
592
595
 
@@ -621,6 +624,7 @@ class NaslServer {
621
624
  yield* getTsFiles(concat(dataSources, 'entities'), 'dataSource_entity');
622
625
  yield* getTsFiles(interfaces as FileNode[], 'interface');
623
626
  yield* getTsFiles(enums, 'enum');
627
+ yield oqlFinished;
624
628
  yield* getTsFiles(logics, 'logic');
625
629
  yield* getTsFiles(authLogics, 'authLogic', Logic);
626
630
  yield* getTsFiles(authLogicsForCallInterface, 'authLogicForCallInterface', Logic);
@@ -5,4 +5,10 @@ export default {
5
5
  method: 'post',
6
6
  },
7
7
  },
8
+ queryDebugTypescriptBatch: {
9
+ url: {
10
+ path: '/api/v1/querydebug/generate/typescriptBatch',
11
+ method: 'post',
12
+ },
13
+ },
8
14
  };