@lcap/nasl
Version:
NetEase Application Specific Language
860 lines (846 loc) • 216 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.NaslServer = exports.getDisplayString2Type = void 0;
const config_1 = require("../config");
const Messager_1 = __importDefault(require("../common/Messager"));
const oql_cache_1 = require("./OQL/oql-cache");
const initial_1 = require("../service/initial");
const set_1 = require("mnemonist/set");
const sqlFunctions_json_1 = __importDefault(require("./OQL/sqlFunctions.json"));
const sqlCategory_json_1 = __importDefault(require("./OQL/sqlCategory.json"));
/// #if process.env.BUILD_TARGET === 'node'
const fs = __importStar(require("fs-extra"));
const path = __importStar(require("path"));
const worker_threads_1 = require("worker_threads");
/// #endif
const concepts_1 = require("../concepts");
// import { validator, VusionValidator } from '@lcap/nasl-concepts';
const asserts_1 = require("@lcap/nasl-concepts/asserts");
const service_1 = require("@lcap/nasl-concepts/service");
const utils = __importStar(require("../utils"));
const memory_optimization_1 = require("../generator/release-body/memory-optimization");
const createUiTs_1 = __importStar(require("./createUiTs"));
const translator_1 = require("../translator");
const translator_2 = require("./translator");
const common_1 = require("../common");
const diagnostic_1 = require("../manager/diagnostic");
const naslStdlibMap_1 = __importDefault(require("./naslStdlibMap"));
const decorators_1 = require("../decorators");
const nasl_concepts_1 = require("@lcap/nasl-concepts");
const nasl_language_server_core_1 = require("@lcap/nasl-language-server-core");
const findReference_1 = require("./findReference");
const nasl_server_client_1 = require("./client/nasl-server-client");
// naslStdlib文件缓存;作为全局变量给多实例用复用
const __naslStdlibFileCacheMap = new Map();
function transformDiagnosticMapToRecords(diagnosticMap) {
const records = [];
diagnosticMap.forEach((diagnostics, fileNode) => {
records.push(...nasl_language_server_core_1.checker.transformDiagnosticsToRecords(fileNode, diagnostics));
});
return records;
}
// 联合类型切割取出类型
function getDisplayString2Type(displayString) {
const targetString = displayString.match(/value:\s(\S+)\)/)?.[1];
let targetType = null;
if (targetString?.startsWith('nasl.core.')) {
targetType = targetString.slice(10);
}
// 取出匹配的内容
const reg = /<([^()]+)>/g;
// 解决extends 导致类型缺失的问题
displayString = displayString?.replace('T extends ', '') || '';
const types = reg.exec(displayString);
// 取出提示的类型,组成是数组
const typeList = (types?.[1].split(' | ') ?? []).map((item) => {
if (/<([^()]+)>/g.exec(item)) {
return item;
}
if (item.includes(' ')) {
const strs = item.split(' ');
const type = strs[strs.length - 1];
return type;
}
if (item.includes('.')) {
const strs = item.split('.');
const type = strs[strs.length - 1];
return type;
}
return item;
});
if (targetType) {
return typeList.filter((item) => item !== targetType);
}
return typeList;
}
exports.getDisplayString2Type = getDisplayString2Type;
function isCoreDateTimeType(n) {
return n?.expression?.__TypeAnnotation?.typeName === 'DateTime' &&
n?.expression?.__TypeAnnotation?.typeNamespace === 'nasl.core';
}
function isFunctionWithFixedTimeZoneParam(calleeName) {
const fns = ['CurrDateTime', 'CurrDate', 'CurrTime', 'FormatDateTime'];
return fns.includes(calleeName);
}
const createWorker = async (link, options) => {
const blob = await fetch(link).then((res) => res.blob());
const instance = globalThis.window;
const electron = instance.electron;
if (electron?.createWorker) {
return electron?.createWorker?.(await blob.arrayBuffer(), options);
}
const url = URL.createObjectURL(blob);
const worker = new worker_threads_1.Worker(url, options);
URL.revokeObjectURL(url);
return worker;
};
// FIXME wudengke 移动位置,放到nasl-language-server-core中
const oqlDefsStr = `
declare namespace nasl.oql {
// 一次平铺的查询视为一次Query,FROM查询的依据为实体Entity
// RecordList需要形如 any[]。而目前extends约束会参与求解;因此加上这个约束,会将 RecordList 解成 any[],导致单测挂掉
function checkUniqueKeys<RecordList>(...args: RecordList): CheckUniqueKeys<RecordList>;
export class Query<Record extends Array<any>> {
FROM_0<R>(): Query<[R]>;
FROM_1<JoinRecord extends Array<any>>(query: Query<JoinRecord>): Query<[...Record, ...JoinRecord]>;
FROM_SUBQUERY<JoinRecord extends Array<any>>(query: Query<JoinRecord>): Query<[...JoinRecord]>;
PARTITION(expr: (...record: Record) => any): Query<Record>;
INDEXHIT(expr: (...record: Record) => any): Query<Record>;
JOIN_0<Record>(): Query<[Record]>;
JOIN_1<JoinRecord extends Array<any>>(query: Query<JoinRecord>): Query<[...Record, ...JoinRecord]>;
USING(...expr: Array<(...record: Record) => any>): Query<Record>;
ON(expr: (...record: Record) => nasl.core.Boolean): Query<Record>;
// UNION<T2 extends Array<any>>(union: Query<T2> & IfEquals<Record, T2>): Query<Record>;
UNION<UnionRecord extends Array<any>>(union: Query<UnionRecord>): Query<Record>;
WHERE(...expr: Array<(...record: Record) => nasl.core.Boolean>): Query<Record>;
GROUP_BY(...expr: Array<(...record: Record) => any>): Query<Record>;
HAVING(...expr: Array<(...record: Record) => nasl.core.Boolean>): Query<Record>;
SELECT<SelectRecord>(expr: (...record: Record) => SelectRecord, check?: (...record: Record) => true, check2?: void): Query<[SelectRecord]>;
// 内存临时表
SELECT_WITH_TEMP_TABLE<SelectRecord>(expr: (...record: Record) => SelectRecord): Query<[SelectRecord, ...Record]>;
SELECT_SUBQUERY_EXPR<SelectRecord>(expr: (...record: Record) => SelectRecord): SelectRecord;
ORDER_BY(...expr: Array<(...record: Record) => any>): Query<Record>;
LIMIT_OFFSET(limit: nasl.core.Long, offset?: nasl.core.Long): Query<Record>;
PAGINATE(page: nasl.core.Long, size: nasl.core.Long): Query<Record>;
DynamicIfJoinExpr<JoinRecord extends Array<any>>(testExpr: nasl.core.Boolean, sqlExpr: Query<JoinRecord>): Query<[...Record, ...JoinRecord]>;
GET_NO_LIST(_: nasl.core.Boolean): nasl.oql.InternalGetQueryNoListResult<Record>;
GET_LIST(_: nasl.core.Boolean): nasl.oql.InternalGetQueryListResult<Record>;
}
// String functions
export function ASCII(str: nasl.core.String ): nasl.core.String;
export function BIN(expr: nasl.core.Long ): nasl.core.String;
export function BIT_LENGTH(str: nasl.core.String ): nasl.core.Long;
export function CHAR(charset?: nasl.core.String , ...exprs: Array<any>): nasl.core.String;
export function CHAR_LENGTH(str: nasl.core.String ): nasl.core.Long;
export function CONCAT(...strs: Array<any>): nasl.core.String;
export function CONCAT_WS(seperator: nasl.core.String , ...strs: Array<nasl.core.String >): nasl.core.String;
export function ELT(expr: nasl.core.Long, ...strs: Array<nasl.core.String >): nasl.core.String;
export function EXPORT_SET(bits: nasl.core.Long, on: nasl.core.String , off: nasl.core.String , separator?: nasl.core.String , number_of_bits?: nasl.core.Long): nasl.core.String;
export function FIELD(str: nasl.core.String , ...strs: Array<nasl.core.String >): nasl.core.Long;
export function FIND_IN_SET(str: nasl.core.String , strs: nasl.core.String ): nasl.core.Long;
export function FORMAT(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Long, locale?: nasl.core.String ): nasl.core.String;
export function FROM_BASE64(str: nasl.core.String ): nasl.core.String;
export function HEX(expr: nasl.core.String ): nasl.core.String;
export function INSERT(str: nasl.core.String , pos: nasl.core.Long, len: nasl.core.Long, newStr: nasl.core.String ): nasl.core.String;
export function INSTR(str: nasl.core.String , newStr: nasl.core.String ): nasl.core.Long;
export function LCASE(str: nasl.core.String ): nasl.core.String;
export function LEFT(str: nasl.core.String | nasl.core.Date, len: nasl.core.Long): nasl.core.String;
export function LENGTH(str: nasl.core.String ): nasl.core.Long;
export function LOAD_FILE(fileName: nasl.core.String ): nasl.core.String;
export function LOCATE(subStr: nasl.core.String , str: nasl.core.String, pos?: nasl.core.Long): nasl.core.Long;
export function LOWER(str: nasl.core.String ): nasl.core.String;
export function LPAD(str: nasl.core.String , len: nasl.core.Long, padStr: nasl.core.String ): nasl.core.String;
export function LTRIM(str: nasl.core.String ): nasl.core.String;
export function MAKE_SET(bits: nasl.core.Long, ...strs: Array<nasl.core.String >): nasl.core.String;
export function MID(str: nasl.core.String , pos: nasl.core.Long, len: nasl.core.Long): nasl.core.String;
export function OCT(expr: nasl.core.Long ): nasl.core.String;
export function OCTET_LENGTH(str: nasl.core.String ): nasl.core.Long;
export function ORD(str: nasl.core.String ): nasl.core.Long;
export function POSITION(subStr: nasl.core.String , str: nasl.core.String ): nasl.core.Long;
export function QUOTE(str: nasl.core.String ): nasl.core.String;
export function REPEAT(str: nasl.core.String , count: nasl.core.Long): nasl.core.String;
export function REPLACE(str: nasl.core.String , fromStr: nasl.core.String , toStr: nasl.core.String ): nasl.core.String;
export function REVERSE(str: nasl.core.String ): nasl.core.String;
export function RIGHT(str: nasl.core.String , len: nasl.core.Long): nasl.core.String;
export function RPAD(str: nasl.core.String , len: nasl.core.Long, padStr: nasl.core.String ): nasl.core.String;
export function RTRIM(str: nasl.core.String ): nasl.core.String;
export function SOUNDEX(str: nasl.core.String ): nasl.core.String;
export function SOUNDES_LIKE(str1: nasl.core.String , str2: nasl.core.String ): nasl.core.Boolean;
export function SPACE(expr: nasl.core.Long): nasl.core.Long;
export function SUBSTR(str: nasl.core.String , pos: nasl.core.Long, len?: nasl.core.Long): nasl.core.String;
export function SUBSTRING(str: nasl.core.String , pos: nasl.core.Long, len?: nasl.core.Long): nasl.core.String;
export function SUBSTRING_INDEX(str: nasl.core.String , delim: nasl.core.String, count: nasl.core.Long): nasl.core.String;
export function TO_BASE64(str: nasl.core.String ): nasl.core.String;
export function TRIM(remStr: nasl.core.String , str: nasl.core.String ): nasl.core.String;
export function UCASE(str: nasl.core.String ): nasl.core.String;
export function UNHEX(str: nasl.core.String ): nasl.core.String;
export function UPPER(str: nasl.core.String ): nasl.core.String;
export function WEIGHT_STRING(str: nasl.core.String , as: 'CHAR' | 'BINARY', ...level: Array<nasl.core.Long>): nasl.core.String;
// String comparison functions
export function LIKE(str1: nasl.core.String , str2: nasl.core.String , escape?: nasl.core.String ): nasl.core.Boolean;
export function NOT_LIKE(str1: nasl.core.String , str2: nasl.core.String , escape?: nasl.core.String ): nasl.core.Boolean;
export function STRCMP(str1: nasl.core.String , str2: nasl.core.String ): nasl.core.Boolean;
// Regular Expressions
export function REGEXP(str1: nasl.core.String , str2: nasl.core.String ): nasl.core.Boolean;
export function NOT_REGEXP(str1: nasl.core.String , str2: nasl.core.String ): nasl.core.Boolean;
export function RLIKE(str1: nasl.core.String , str2: nasl.core.String ): nasl.core.Boolean;
// Character Set and Collation of Function Results
// Mathematical Functions
export function ABS(expr: nasl.core.Long): nasl.core.Long;
export function ABS(expr: nasl.core.Long): nasl.core.Long;
export function ABS(expr: nasl.core.Decimal): nasl.core.Decimal;
export function ABS(expr: nasl.core.Decimal): nasl.core.Decimal;
export function ACOS(expr: nasl.core.Long ): nasl.core.Decimal;
export function ACOS(expr: nasl.core.Decimal): nasl.core.Decimal;
export function ASIN(expr: nasl.core.Long ): nasl.core.Decimal;
export function ASIN(expr: nasl.core.Decimal): nasl.core.Decimal;
export function ATAN(expr: nasl.core.Long ): nasl.core.Decimal;
export function ATAN(expr: nasl.core.Decimal): nasl.core.Decimal;
export function ATAN(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function ATAN(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Decimal): nasl.core.Decimal;
export function ATAN(expr1: nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function ATAN2(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function ATAN2(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Decimal): nasl.core.Decimal;
export function ATAN2(expr1: nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function CEIL(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Long;
export function CEILING(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Long;
export function CONV(expr1: nasl.core.Long | nasl.core.String, expr2: nasl.core.Long, expr3: nasl.core.Long): nasl.core.String;
export function COS(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function COS(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function COT(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function COT(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function CRC32(expr1: nasl.core.String): nasl.core.Long;
export function DEGREES(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function DEGREES(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function EXP(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function EXP(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function FLOOR(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Long;
export function LN(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function LN(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function LOG(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function LOG(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function LOG(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function LOG(expr1: nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function LOG(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Decimal): nasl.core.Decimal;
export function LOG2(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function LOG2(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function LOG10(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function LOG10(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function MOD(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function MOD(expr1: nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function MOD(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Decimal): nasl.core.Decimal;
export function PI(): nasl.core.Decimal;
export function POW(expr1: nasl.core.Long , expr2: nasl.core.Long ): nasl.core.Long;
export function POW(expr1: nasl.core.Long , expr2: nasl.core.Decimal): nasl.core.Decimal;
export function POW(expr1: nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function POWER(expr1: nasl.core.Long , expr2: nasl.core.Long ): nasl.core.Long;
export function POWER(expr1: nasl.core.Long , expr2: nasl.core.Decimal): nasl.core.Decimal;
export function POWER(expr1: nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function RADIANS(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function RAND(expr1?: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function RAND(expr1: nasl.core.Decimal): nasl.core.Decimal;
export function ROUND(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Long;
export function ROUND(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function SIGN(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Long;
export function SIN(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function SQRT(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function TAN(expr1: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function TRUNCATE(expr1: nasl.core.Long | nasl.core.Decimal, expr2: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
// Date and Time Functions
type TIME_UNIT = 'MICROSECOND' | 'SECOND' | 'MINUTE' | 'HOUR' | 'DAY' | 'WEEK' | 'MONTH' | 'QUARTER' | 'YEAR' | 'SECOND_MICROSECOND' | 'MINUTE_MICROSECOND' | 'MINUTE_SECOND' | 'HOUR_MICROSECOND' | 'HOUR_SECOND' | 'HOUR_MINUTE' | 'DAY_MICROSECOND' | 'DAY_SECOND' | 'DAY_MINUTE' | 'DAY_HOUR' | 'YEAR_MONTH';
type fsp = 0 | 1 | 2 | 3 | 4 | 5 | 6; // fractional seconds precision
export function DATE_ADD(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.Long, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function DATE_ADD(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.Long, unit: TIME_UNIT): nasl.core.DateTime;
export function DATE_ADD(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.String, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function DATE_ADD(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.String, unit: TIME_UNIT): nasl.core.DateTime;
export function DATE_SUB(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.Long, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function DATE_SUB(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.Long, unit: TIME_UNIT): nasl.core.DateTime;
export function DATE_SUB(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.String, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function DATE_SUB(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.String, unit: TIME_UNIT): nasl.core.DateTime;
export function ADDDATE(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.Long, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function ADDDATE(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.Long, unit: TIME_UNIT): nasl.core.DateTime;
export function ADDDATE(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.String, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function ADDDATE(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.String, unit: TIME_UNIT): nasl.core.DateTime;
export function ADDDATE(date: nasl.core.Date, expr: nasl.core.Long): nasl.core.Date;
export function ADDDATE(date: nasl.core.DateTime, expr: nasl.core.Long): nasl.core.DateTime;
export function ADDTIME(expr1: nasl.core.DateTime, expr: nasl.core.Time): nasl.core.DateTime;
export function ADDTIME(expr1: nasl.core.Time, expr: nasl.core.Time): nasl.core.Time;
export function CONVERT_TZ(expr1: nasl.core.DateTime, fromTz: nasl.core.String, toTz: nasl.core.String): nasl.core.DateTime;
export function CURDATE(): nasl.core.Date;
export function CURRENT_DATE(): nasl.core.Date;
export function CURTIME(): nasl.core.Time;
export function CURTIME(fsp: fsp): nasl.core.Decimal;
export function CURRENT_TIME(): nasl.core.Time;
export function CURRENT_TIME(fsp: fsp): nasl.core.Decimal;
export function DATE(expr: nasl.core.Date | nasl.core.DateTime): nasl.core.Date;
export function DATEDIFF(expr1: nasl.core.Date | nasl.core.DateTime, expr2: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function DATE_FORMAT(expr1: nasl.core.Date | nasl.core.DateTime | nasl.core.Time, format: nasl.core.String): nasl.core.String;
export function DAY(expr1: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function DAYNAME(expr1: nasl.core.Date | nasl.core.DateTime): nasl.core.String;
export function DAYOFMONTH(expr1: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function DAYOFWEEK(expr1: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function EXTRACT(unit: TIME_UNIT, expr1: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function FROM_DAYS(days: nasl.core.Long): nasl.core.Date;
export function FROM_UNIXTIME(timestamp: nasl.core.Long, format?: nasl.core.String): nasl.core.DateTime;
export function GET_FORMAT(str1: 'DATE' | 'TIME' | 'DATETIME', str2: 'EUR' | 'USA' | 'JIS' | 'ISO' | 'INTERNAL'): nasl.core.String;
export function LAST_DAY(date: nasl.core.Date | nasl.core.DateTime): nasl.core.Date;
export function LOCALTIME(): nasl.core.DateTime;
export function LOCALTIMESTAMP(): nasl.core.DateTime;
export function MAKEDATE(year: nasl.core.Long, dayOfYear: nasl.core.Long): nasl.core.Date;
export function MAKETIME(hour: nasl.core.Long, minute: nasl.core.Long, second: nasl.core.Long): nasl.core.Time;
export function MICROSECOND(expr: nasl.core.Time | nasl.core.DateTime): nasl.core.Long;
export function MINUTE(expr: nasl.core.Time | nasl.core.DateTime): nasl.core.Long;
export function MONTH(expr: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function MONTHNAME(expr: nasl.core.Date | nasl.core.DateTime): nasl.core.String;
export function PERIOD_ADD(expr1: nasl.core.Long, expr2: nasl.core.Long): nasl.core.Long;
export function PERIOD_DIFF(expr1: nasl.core.Long, expr2: nasl.core.Long): nasl.core.Long;
export function QUARTER(expr1: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function SECOND(expr1: nasl.core.Time | nasl.core.DateTime): nasl.core.Long;
export function SEC_TO_TIME(expr1: nasl.core.Long): nasl.core.Time;
export function STR_TO_DATE(str: nasl.core.String, format: nasl.core.String): nasl.core.DateTime;
export function SUBDATE(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.Long, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function SUBDATE(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.Long, unit: TIME_UNIT): nasl.core.DateTime;
export function SUBDATE(date: nasl.core.Date, interval: "INTERVAL", expr: nasl.core.String, unit: 'YEAR' | 'MONTH' | 'DAY'): nasl.core.Date;
export function SUBDATE(date: nasl.core.DateTime, interval: "INTERVAL", expr: nasl.core.String, unit: TIME_UNIT): nasl.core.DateTime;
export function SUBDATE(date: nasl.core.Date, expr: nasl.core.Long): nasl.core.Date;
export function SUBDATE(date: nasl.core.DateTime, expr: nasl.core.Long): nasl.core.DateTime;
export function SUBTIME(expr1: nasl.core.DateTime, expr2: nasl.core.Time): nasl.core.DateTime;
export function SUBTIME(expr1: nasl.core.Time, expr2: nasl.core.Time): nasl.core.Time;
export function TIME(expr: nasl.core.Time | nasl.core.DateTime): nasl.core.Time;
export function TIMEDIFF(expr1: nasl.core.Time | nasl.core.DateTime, expr2: nasl.core.Time | nasl.core.DateTime): nasl.core.Time;
export function TO_DAYS(expr: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function TO_SECONDS(expr: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function UNIX_TIMESTAMP(date?: nasl.core.DateTime): nasl.core.Long;
export function UTC_DATE(): nasl.core.Date;
export function UTC_TIME(): nasl.core.Time;
export function UTC_TIMESTAMP(): nasl.core.DateTime;
export function WEEK(date: nasl.core.Date | nasl.core.DateTime, mode?: nasl.core.Long): nasl.core.Long;
export function WEEKDAY(date: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function DAYOFYEAR(date: nasl.core.Date | nasl.core.DateTime): nasl.core.Long
export function WEEKOFYEAR(date: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function YEAR(date: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function YEARWEEK(date: nasl.core.Date, mode?: nasl.core.Long): nasl.core.Long;
export function HOUR(date: nasl.core.Date | nasl.core.DateTime): nasl.core.Long;
export function NOW(): nasl.core.DateTime;
// Comparison Functions
export function INTERVAL(...value: Array<nasl.core.Long>): nasl.core.Long;
export function GREATEST(...value: Array<nasl.core.Long>): nasl.core.Long;
export function GREATEST(...value: Array<nasl.core.Long>): nasl.core.Long;
export function GREATEST(...value: Array<nasl.core.Decimal>): nasl.core.Decimal;
export function GREATEST(...value: Array<nasl.core.Decimal>): nasl.core.Decimal;
export function GREATEST(...value: Array<nasl.core.String>): nasl.core.String;
export function LEAST(...value: Array<nasl.core.Long>): nasl.core.Long;
export function LEAST(...value: Array<nasl.core.Long>): nasl.core.Long;
export function LEAST(...value: Array<nasl.core.Decimal>): nasl.core.Decimal;
export function LEAST(...value: Array<nasl.core.Decimal>): nasl.core.Decimal;
export function LEAST(...value: Array<nasl.core.String>): nasl.core.String;
// Miscellaneous Functions
export function ANY_VALUE<T>(arg: T): T;
// nonAggregateWindowedFunction
export function CUME_DIST(): nasl.core.Decimal;
export function DENSE_RANK(): nasl.core.Long;
export function PERCENT_RANK(): nasl.core.Decimal;
export function RANK(): nasl.core.Long;
export function ROW_NUMBER(): nasl.core.Long;
// aggregateWindowedFunction
export function COUNT(...value: Array<any>): nasl.core.Long;
export function SUM(value: nasl.core.Long): nasl.core.Long;
export function SUM(value: nasl.core.Decimal): nasl.core.Decimal;
export function SUM(value: nasl.core.Boolean): nasl.core.Long;
export function AVG(value: nasl.core.Long | nasl.core.Decimal): nasl.core.Decimal;
export function MAX(value: nasl.core.Long): nasl.core.Long;
export function MAX(value: nasl.core.Decimal): nasl.core.Decimal;
export function MAX(value: nasl.core.Date): nasl.core.Date;
export function MAX(value: nasl.core.DateTime): nasl.core.DateTime;
export function MAX(value: nasl.core.Time): nasl.core.Time;
export function MAX(value: nasl.core.Boolean): nasl.core.Boolean;
export function MIN(value: nasl.core.Long): nasl.core.Long;
export function MIN(value: nasl.core.Decimal): nasl.core.Decimal;
export function MIN(value: nasl.core.Date): nasl.core.Date;
export function MIN(value: nasl.core.DateTime): nasl.core.DateTime;
export function MIN(value: nasl.core.Time): nasl.core.Time;
export function MIN(value: nasl.core.Boolean): nasl.core.Boolean;
// self
export function STARTWITH(str1: nasl.core.String, str2: nasl.core.String): nasl.core.Boolean;
export function ENDWITH(str1: nasl.core.String, str2: nasl.core.String): nasl.core.Boolean;
export function IN<T>(value: T, list: nasl.collection.List<T>): nasl.core.Boolean;
export function IN<T>(value: T, ...array: Array<T>): nasl.core.Boolean;
export function IN_SUBQUERY<SelectRecord, T>(value: T, expr: Query<[SelectRecord]>): nasl.core.Boolean;
export function COMPARE_SUBQUERY<SelectRecord, T extends SelectRecord>(value: T, expr: Query<[SelectRecord]>): nasl.core.Boolean;
export function ISNULL(value: any): nasl.core.Boolean;
export function IFNULL<T extends nasl.core.Long | nasl.core.Decimal>(expr1: T, expr2: nasl.core.Decimal): nasl.core.Decimal;
export function IFNULL<T extends nasl.core.Decimal | nasl.core.Long>(expr1: nasl.core.Decimal, expr2: T): nasl.core.Decimal;
export function IFNULL<T1, T2>(expr1: T1, expr2: T2): T1 | T2;
export function CASE_WHEN<THEN>(caseCase: any, ...caseWhen: Array<[() => any, () => THEN]>): THEN;
export function CASE_WHEN<THEN>(caseCase: any, caseElse: THEN, ...caseWhen: Array<[() => any, () => THEN]>): THEN;
export function BETWEEN_AND<T>(value: T, between: T, and: T): nasl.core.Boolean;
export function GROUP_CONCAT(...value: Array<any>): nasl.core.String;
export function IF<THEN, ELSE>(expr1: nasl.core.Boolean, expr2: THEN, expr3: ELSE): THEN | ELSE;
export function ISBOOLEAN(value: nasl.core.Boolean): nasl.core.Boolean;
export function COMPARE<T>(left: T, right: T): nasl.core.Boolean;
export function CAST<T>(value: any, dataType: T): T;
export function CONVERT<T>(value: any, dataType: T): T;
export function CONVERT<T>(value: T): T;
export function EXISTS_EXPR<Record extends Array<any>>(value: Query<Record>): nasl.core.Boolean;
export function COALESCE<T>(...args: Array<T>): T
// others
export let NULL: never
export function DynamicIfExpr<Record>(testExpr: nasl.core.Boolean, sqlExpr: Record): Record;
export function checkDynamicReference(...expr1: Array<any>): void;
// 单项查询
export function SINGLE_SELECT_ELEMENT<Record>(query: Record): Record;
}
`;
const allComponent = {};
class NaslServer {
constructor(opt) {
/** naslStdlib文件缓存 */
this.naslStdlibFileCacheMap = __naslStdlibFileCacheMap;
/**
* 按道理 fileSourceMap: new Map<string, SourceMap>() 比较合理,
* 但是要多维护一层 vertex 增删 -> file 增删的关系问题,
* 先用挂在点上面,简单的方法实现,后期再考虑解耦
*/
this.file2NodeMap = new Map();
/** TS 翻译的源码 */
this.tsFiles = new Map();
/// #if process.env.NODE_ENV === 'development'
/**
* 调试时是否储存 ts 文件
*/
this.openDebugEmbedded = true;
/// #endif
this.elementsLogic = {};
// 待处理的变化事件
this.changeStackList = [];
// 需要检查的文件节点
this.typerCheckFiles = new Set();
// 删除的精确节点,这个不一定是文件级别的节点
this.typerRemoveNodes = new Set();
// 创建的节点
this.typerCreateNodes = new Set();
// 临时 hack:OQL 需要删除的节点(NASL 节点重命名,老名字对应的 TS 节点需删除
this.oqlRemoveNodesTsPath = new Set();
// 临时 hack:删除的连接器中的文件级别的节点
this.removedConnectors = new Set();
// 变动的原始目标节点,带有 proxy,用于触发响应式更新:事件树,子逻辑树等
this.originProxyTargetNodes = new Set();
this.typerErrRecords = [];
// 确保首屏检查没有"传统艺能"、"时序问题"
this.cachedEventPayloadValues = [];
// 当前重命名模式:rename-only: 只重命名,update: 更新引用
this.currentRenameMode = null;
this.oqlDisaster = false;
this.isFirstScreen = true; // 优化首屏 getAncestor 热点代码
/**
* 语言服务运行完毕
*
* @description 初始化以及每次修改内容时都会重置
*/
this.lsRunEnd = Promise.resolve();
/**
* 语言服务运行完毕标记
*
* @description `lsRunEnd`属性的内部状态
*/
this._lsRunEndSwitch = () => void 0;
this.flags = {
/**
* 是否启用性能分析模式
*/
profileMode: false,
/**
* 是否启用 TypeScript 语言服务
* 默认启用,可以通过在 url 中添加 oql-check=true 来关闭 tss,使用 NASL 的OQL类型检查器
*/
tssEnabled: true,
/**
* 是否为智能应用生成开发模式。如果是,那么有一些特殊的类型检查规则。
*/
creatorDevMode: false,
};
this.uiTsInitedResolve = null;
// 检查共享数据是否有更新
this._latestVersionsOfSharedApp = [];
this.firstScreenEndWork = undefined;
// 用户点击"查找引用"
this.findReferenceAndRender = (nd) => (0, findReference_1.findReferenceAndRender)(this.semEnv, nd);
/**
* 根据入参准备并往 TS Server 写入需要校验的 ts 文件
* @param chkFiles 需要校验的文件
* @param removedNodes 需要删除的文件
* @param oqlRemoveNodesTsPath 需要删除的文件路径
* @returns 需要校验的文件名
*/
this.prepareAndWriteTsFilesToCheck = async (oqlFiles, removedNodes, oqlRemoveNodesTsPath) => {
if (!this.flags.tssEnabled) {
const self = this;
try {
await Promise.all([...oqlFiles].map(x => {
return self.waitOqlQueryComponentChildrenFinish(x);
}));
}
catch (error) {
console.error(error);
}
return { tsFilePathsToCheck: new Set() };
}
function getETSFilePath(fileNode) {
try {
return fileNode.getEmbeddedFilePath();
}
catch (err) {
return null;
}
}
async function removeETSFile(filePath) {
if (!filePath) {
return;
}
await self.writeFiles([
{
file: filePath,
fileContent: '',
},
]);
}
const self = this;
for (const nd of removedNodes) {
await removeETSFile(getETSFilePath(nd));
}
for (const filePath of oqlRemoveNodesTsPath) {
await removeETSFile(filePath);
}
const tsFilePathsToCheck = new Set();
for (const fileNode of oqlFiles) {
let tsFilePath;
try {
tsFilePath = fileNode.getEmbeddedFilePath();
}
catch (err) {
this.logger.error(err);
// TODO wudengke 或许需要 continue
}
let tsFile;
// 3.14 需要改成后端大逻辑涉及 OQL 改动时则收集一下(可能要跑 OQL 的 toTS)
// TODO: 可能可以用 fileNodeRaw 当输入,提速 5x,现在的 typer 已经有不触发 vue 渲染更新的情况了,可以考虑统一解决
await utils.timeSlicingWithGenerator(this.semData.updateSemanticCtxAsPer(fileNode));
// 用 raw 的话,很多响应式更新都失效了。几个,几十个的单子,实在是修补过来,慢慢修或者等 nasl worker 吧。
tsFile = await utils.timeSlicingWithGenerator(fileNode.toEmbeddedTSFile());
await this.writeFiles([{
file: tsFile.filePath,
fileContent: tsFile.code,
}]);
tsFilePathsToCheck.add(tsFilePath);
// 如果当前没有生成tsFile
if (!tsFile?.sourceMap) {
continue;
}
// 修改触发修改文件
this._debugInFileStorage(fileNode, [{
file: tsFile.filePath,
fileContent: tsFile.code,
}]);
// @ts-ignore
fileNode.sourceMap = tsFile.sourceMap;
// 麻了,查了半天是没 set 这里
this.file2NodeMap.set(tsFile.filePath, fileNode);
}
if (utils.isDebugMode) {
console.info('TS 校验以下文件', Array.from(oqlFiles).map((item) => item.getEmbeddedFilePath()));
}
utils.isDebugMode && console.timeEnd('TS 文件变更');
return { tsFilePathsToCheck };
};
this.getProxyNode = (nd) => {
return this.getProxyApp()?.findNodeByPath(nd.nodePath);
};
// 初始化 uiTsInited Promise 并保存 resolve 函数
this.uiTsInited = new Promise((resolve) => {
this.uiTsInitedResolve = resolve;
});
this.promise = this.launch(opt);
}
async start() {
await this.promise;
if (this.flags.tssEnabled) {
return this.messager.requestCommand('start');
}
}
terminate() {
if (this.worker) {
this.worker.terminate();
this.worker = null;
}
}
loadFlags(flags) {
if (flags) {
Object.keys(flags).forEach((k) => {
const v = flags[k];
if (v !== undefined) {
this.flags[k] = v;
}
});
}
}
synthesisFlagsFromUrl() {
if (utils.isBrowser) {
function isOQLCheckEnabled() {
if (/[?&]oql-check=false/.test(location.search)) {
return false;
}
else if (/[?&]oql-check=true/.test(location.search)) {
return true;
}
else {
// 测试环境默认打开。
return /lcap\.codewave-test\.163yun\.com/.test(location.host);
}
}
function isCreatorDevModeEnabled() {
return !!/[?&]creator-dev-mode=true/.test(location.search);
}
return {
tssEnabled: !isOQLCheckEnabled(),
creatorDevMode: isCreatorDevModeEnabled(),
};
}
return undefined;
}
async launch(opt) {
const flags = opt.flags ?? this.synthesisFlagsFromUrl();
if (flags) {
this.loadFlags(flags);
}
// 根据特性开关控制是否创建TypeScript Worker
if (this.flags.tssEnabled) {
/// #if process.env.BUILD_TARGET === 'node'
if (globalThis.process)
// For TS build
// this.worker = new Worker(require.resolve('@lcap/nasl-typescript-worker/src/index.js'));
this.worker = new worker_threads_1.Worker(require.resolve('../../ts-worker/src/index.js'));
/// #endif
/// #if process.env.BUILD_TARGET !== 'node'
if (globalThis.window) {
// const source = require('!!raw-loader!@lcap/nasl-typescript-worker/dist/index.js').default;
this.worker = await (async () => {
if (process.env.NODE_ENV === 'development') {
const source = require('!!raw-loader!../../ts-worker/bundle.js').default;
const url = URL.createObjectURL(new Blob([source]));
const worker = new window.Worker(url);
URL.revokeObjectURL(url);
return worker;
}
const instance = globalThis.window;
const baseIdePath = instance?.baseIdePath;
const hash = process.env.COMMIT_HASH || '';
const filename = instance?.electron?.createWorker
? 'tsserver.electron.js'
: 'tsserver.js';
// @ts-ignore
const link = `${baseIdePath}/js/${filename}?${hash}`;
const options = { name: 'typescript-server' };
return createWorker(link, options);
})();
}
/// #endif
}
this.http = opt.http;
this.isAnnotationMode = opt?.isAnnotationMode ?? false;
this.logger = opt.logger ?? utils.internalLogger;
this.diagnosticManager = new diagnostic_1.DiagnosticManager();
this.handlePublishDiagnostics =
async ({ data }) => {
console.timeEnd('wait-tss');
console.time('ls-typecheck');
if (!data || data.event !== 'publishDiagnostics') {
return;
}
console.debug(`[NaslServer] flags: ${JSON.stringify(this.flags ?? {})}`);
// getDiagnosticRecordsAndPushAll 最终通过 ts 回调走到这里
const tsDiagnostics = this.flags.tssEnabled ? (await this._resolveDiagnosticRecords(data.records, data.versions) ?? []) : [];
if (!this.isAnnotationMode) {
// 让出CPU,让浏览器关闭骨架屏
await utils.delay(500);
if (this.flags.tssEnabled) {
await utils.timeSlicingWithGenerator(this._incrementalAnnotationJSONWithGenerator(data.records));
}
if (this.isFirstScreen) {
// 首屏时,语言服务初始化
await this.languageServerInitiate();
}
console.time("等待uiTsInited");
(await this.uiTsInited)?.();
console.timeEnd("等待uiTsInited");
// 已经和 NASL 节点配对的诊断信息
const isProfileMode = this.flags.profileMode;
if (this.isFirstScreen) {
utils.isDebugMode && console.time('\x1b[44m\x1b[97m 用户体感首屏检查耗时 \x1b[0m');
// 对OQL节点加载来自TS的错误
tsDiagnostics.forEach(({ node, message }) => {
if (node.errorsFromTSServer) {
node.errorsFromTSServer.push({ message });
}
else {
node.errorsFromTSServer = [{ message }];
}
});
if (isProfileMode) {
console.profile('check');
}
let fixAllUseBeforeAssignTasks = [];
const rawApp = NaslServer.toRaw(this.getProxyApp());
// 让事件逻辑显示出来
this._getAllElementLogicRoots();
try {
// 目前里面包含所有定义、逻辑、业务组件、前端全局变量等
fixAllUseBeforeAssignTasks = await (0, nasl_language_server_core_1.firstScreenCheckAndCompare)(this.semEnv, rawApp);
// 类型检查完才能收集引用
this.semEnv.refMgr.buildSymbolRefsForApp(this.semEnv, rawApp);
}
catch (err) {
this.semEnv.logger.fatal('\x1b[44m\x1b[97m 类型检查出错了,估计没标完 \x1b[0m');
this.semEnv.logger.fatal(err);
}
if (isProfileMode) {
console.profileEnd('check');
}
if (isProfileMode) {
console.profile('diag');
}
// Use performance measurement to accurately track time in time-sliced execution
const diagAppStartTime = performance.now();
await utils.runGeneratorAsync(this.semEnv.errorDiagnoser.diagnosticApp());
const diagAppEndTime = performance.now();
console.info(`\x1b[44m\x1b[97m Diagnostic App \x1b[0m: ${((diagAppEndTime - diagAppStartTime) / 1000).toFixed(3)}s`);
const diagnosticMap = this.semEnv.errorDiagnoser.getAllDiagnostics();
const transformStartTime = performance.now();
const records = transformDiagnosticMapToRecords(diagnosticMap);
await this.diagnosticManager.setInitialDiagData(records);
const transformEndTime = performance.now();
console.info(`\x1b[44m\x1b[97m Transform Diagnostic Map To Records \x1b[0m: ${((transformEndTime - transformStartTime) / 1000).toFixed(3)}s`);
// 首屏和增量通路不同,首屏时需要手动调用lsRunEndSwitch;增量时则在增量代码中调用
this._lsRunEndSwitch();
this.isFirstScreen = false;
rawApp.emit('collect:start', {
actionMsg: 'v3.14 v4.0 新 LS 修复变量先使用后赋值的场景'
});
// 🪝,放在前面的话有时序问题,容易多很多重复报错
fixAllUseBeforeAssignTasks.forEach(task => task());
rawApp.emit('collect:end');
this.semData.isFirstScreen = false;
this.semEnv.allocatedVEQNames.forEach(n => {
this.semEnv.refMgr.gQNameDefs.delete(n);
});
this.semEnv.allocatedVEQNames.length = 0;
for (const value of this.cachedEventPayloadValues) {
this.embeddedTSEmitter.emit('change', { value });
}
this.cachedEventPayloadValues.length = 0;
if (isProfileMode) {
console.profileEnd('diag');
}
utils.isDebugMode && console.timeEnd('\x1b[44m\x1b[97m 用户体感首屏检查耗时 \x1b[0m');
}
/**
* @warning 不放在这里无法起到加速效果,且读到的 cache 为空,抛出 undefined 值
* 放在这里的话好像是有些“时序”问题?
*/
this.semData.recoverSlowGetters();
this.semData.clearSemanticData();
(0, nasl_language_server_core_1.clearFileNodeCache)();
}
this.notifyPublishDiagnosticsEnd(tsDiagnostics);
console.timeEnd("ls-typecheck");
if (this.firstScreenEndWork) {
this.firstScreenEndWork();
this.firstScreenEndWork = undefined;
}
};
// 只有在tssEnabled时才创建messager
if (this.flags.tssEnabled) {
this.messager = new Messager_1.default({
protocol: 'ts-worker',
sender: 'ide',
context: this,
timeout: 420000,
getReceiver: () => this.worker,
getSender: () => this.worker,
// @ts-expect-error FIXME 看不懂,等高人修复
handleMessage: this.handlePublishDiagnostics
});
}
// 监听所有改变操作
this.embeddedTSEmitter = new concepts_1.EventEmitter();
if (!this.isAnnotationMode) {
this.embeddedTSEmitter.on('change', ({ value: eventValue }) => {
if (this.isFirstScreen) {
this.cachedEventPayloadValues.push(eventValue);
return;
}
const itemEventPtr = new Array();
eventValue.forEach((item) => {
if (concepts_1.asserts.isDirectory(item.originEvent?.currentTarget)
|| concepts_1.asserts.isReferredDefinition(item.originEvent?.currentTarget))
return;
// 查找引用无法处理合并后的请求,需要拦截后缓存数据
item.originEvent && itemEventPtr.push({
action: item.originEvent.action,
objNasl: item.originEvent.objNasl,
oldObjNasl: item.originEvent.oldObjNasl,
field: item.originEvent.field, // 判断是否是 rename
target: item.originEvent.target, // rename 专用
ctxProcess: item.originEvent.ctxProcess // 流程特殊情况:更新流程关联的 view
});
/**
* 多个行为进行合并
* 合并规则是
* 1.[a,b,c,c] 在cc的时候,在已有一个c,又来一个c的时候,file级别的节点
* 就可以前面的内容去掉,只保留最后一个, 但是如果前面那个有携带file
* 2.[a,b,c,b,c] 在bc已存在,又来了bc 这就都要保留,因为可能顺序有相关性,不能去掉
* 理论上只处理同时几个操作 合并,
* 3.有field的也直接保留
*/
try {
const changeEvent = item.originEvent;
// 设置国际化相关内容传标识过来,不需要进入语言服务
if (changeEvent?.field === 'setI18n')
return;
const changeNode = changeEvent.target;
// FIXME: 验证完成后需要移除
const { fileNode: fileNode2 } = NaslServer.getCurrentSource(changeNode);
const fileNode = (0, service_1.getFileNode)(changeNode);
if (NaslServer.toRaw(fileNode) !== NaslServer.toRaw(fileNode2)) {
this.logger.error('\x1b[41m