# 系统

# 导入

通过如下方式导入系统api

import sys from "svr-api/sys";

# 方法

/**
 * 系统相关API,包括产品的、jvm的和操作系统的
 */

import type {
	File
} from './fs';

/**
 * 获取第三方系统在本系统所在的局域网中的访问地址或者代理地址。
 *
 * 根据访问本系统的 URL,对被访问到的第三方外网地址进行映射转换。
 *
 * 主要用于以下典型场景:oauth2 单点登录,本系统作为子系统跳转主系统授权页面;gis 地图中配置高德等外
 * 网代理 API;门户页面调转外网;或在子系统中注销带动主系统同步注销等。
 *
 * 以一个实际配置为例,假设访问本系统的地址为 `http://192.168.10.179:8080/login`,系统设置记录内容
 * 为:
 * ```json
 * {
 *     "http://192.168.10.179:8080": {
 *       "https://api.amap.com": "http://192.168.23.43:8081"
 *     }
 * }
 * ```
 * 那么 `getIntranetUrlMapping("http://192.168.10.179:8080", "https://api.amap.com/api1")` 会返回
 * `http://192.168.23.43:8081/api1`。
 *
 * @param extranet 将要被访问到的第三方外网地址。
 * @param url 访问本系统的 URL。若不设置使用系统默认的。
 * @returns 映射后的内网代理地址。如果没有找到访问本系统 URL 的映射记录,或没有第三方代理地址配置,
 * 则直接返回 `extranet` 参数的值。
 */
export function getIntranetUrlMapping(extranet: string, url?: string): string;

/**
 * 获取系统的系统设置中的配置信息。
 *
 * 系统设置文件通常位于 `/sysdata/settings/settings.json`。
 *
 * @param propertyName 属性名。
 * @returns 配置项的值。
 */
export function getSysSetting(propertyName: string): any;

/**
 * 修改系统设置中的某个属性。
 *
 * 调用该方法后,指定的属性值会被序列化并保存到 `settings.json` 中。由于修改是持久化的,会影响全局配
 * 置。
 *
 * 例如:
 * ```typescript
 * sys.setSysSetting("sys.basic.name", "test");
 * ```
 * 调用之后 `settings.json` 变成:
 * ```json
 * {
 *     "sys.basic.name": "test"
 * }
 * ```
 *
 * @param propertyName 属性名。
 * @param propertyValue 属性值。支持字符串、数字或布尔值,JSON对象,数组。
 */
export function setSysSetting(propertyName: string | keyof SysSettingsJson, propertyValue: any): void;

/**
 * 判断当前服务器是否为集群。
 *
 * @returns 是否为集群环境。
 */
export function isCluster(): boolean;

/**
 * 判断当前服务器是否为集群主节点。
 *
 * 边界说明:如果当前系统不是集群配置,那么总是返回 `true`。
 *
 * @returns 是否为主节点(单机默认返回 `true`)。
 */
export function isMasterClusterNode(): boolean;

/**
 * 返回当前集群节点的名称。
 *
 * @returns 节点名称。
 */
export function getClusterNodeName(): string;

/**
 * 存储一个自定义配置信息到系统。
 *
 * 用于方便二次开发者在系统中存储一些自定义的配置项,并在服务器重启后仍然有效。
 *
 * 需注意的是配置项会被存储到系统数据库的 `CUSTOM_CONFS.tbl` 中。由于配置项会持久化到一个 varChar 字
 * 段内,因此存储的内容必须是能被序列化为文本的,且长度被严格限制在 32K 以内。
 *
 * @see {@link getCustomConf}
 * @param args.userId 用户 ID。如果为空,则表示系统级配置。
 * @param args.key 配置项的 key,长度最多 512。
 * @param args.value 配置项的值。支持字符串、数字、布尔值、JSON 对象、数组。当传入 `null` 时表示删除
 * 配置项。
 */
export function saveCustomConf<T>(args: {
	userId?: string,
	key: string,
	value: T,
}): void;

/**
 * 获取一个自定义配置信息。
 *
 * 获取之前通过 {@link saveCustomConf} 保存的配置信息。
 *
 * 由于调用此函数时可能每次都会发生数据库查询,故调用者应该自己考虑在局部作用域中复用获取到的配置
 * 项,避免频繁查询带来性能开销。
 *
 * @see {@link saveCustomConf}
 * @param args 配置项的 key 字符串(长度限制 512),或者查询参数对象。
 * @param args.key 配置项的 key,长度最多 512。
 * @param args.userId 用户 ID。如果为空,则表示查询系统级配置。
 * @param args.default 配置项不存在时返回的默认值。
 * @returns 配置项的值。如果配置不存在,则对应返回 `default` 默认值。
 */
export function getCustomConf<T>(args: string | {
	userId?: string,
	key: string,
	default?: T;
}): T;

/**
 * 获取一个驻留内存的数据项。
 *
 * 此函数获取并提取已注册的内存缓存数据项。在调用前需要确保该数据已经被
 * {@link registerMemoCacheValue} 提前注册。
 *
 * @param key 数据项的 key,即注册时设置的 key,长度最多 512。
 * @returns 返回之前注册的数据项的值。如果数据项已注册但未初始化,则会按需初始化创建一个;如果数据项
 * 并未注册则抛出异常。
 */
export function getMemoCacheValue<T>(key: string): T;

/**
 * 删除一个驻留内存的数据项。
 *
 * @param key 数据项的 key,即注册时设置的 key,长度最多 512。
 */
export function removeMemoCacheValue(key: string): void;

/**
 * 注册一个驻留内存的数据项。
 *
 * 此函数是为了方便脚本开发者能在内存按需创建一些常驻内存的数据项,注册时数据项并不会马上产生,而是
 * 第一次调用函数{@link getMemoCacheValue()}时才会产生,并支持跨集群共享,支持过期或被gc后自动重新获
 * 取,此函数会确保同一时刻不会重复创建多个数据项。
 *
 * @param args.key 数据项的key,长度最多512
 * @param args.generatorScript 生成数据的脚本,可以是文件路径,默认是当前调用此函数所在的脚本文件。
 * @param args.generatorMethod 生成数据的方法,此方法只有一个参数,即`key`,其返回的结果会作为数据项
 *        返回,当支持集群共享时,此函数返回的数据项必须是可持久化的,比如字符串、JSON等,不集群共享
 *        时可以返回任意对象。
 * @param args.crossCluster 是否跨集群共享,默认为false
 * @param args.expireIn 数据项的过期时间,单位秒,默认为0,表示不过期,如果设置,则数据项会在指定时
 *        间后自动过期,下次获取时会重新产生新的。
 * @param args.gc gc类型,默认为"no",可选值:"soft"表示会在内存紧张时gc掉、"weak"表示会在下次gc时gc
 *        掉、"no"表示不会被gc。
 * @return 数据项的值,如果配置项不存在,则会按需创建一个。
 */
export function registerMemoCacheValue<T>(args: {
	key: string,
	generatorScript?: string;
	generatorMethod: string;
	crossCluster?: boolean,
	expireIn?: number;
	gc?: "soft" | "weak" | "no",
}): T;

/**
 * 发送消息。
 *
 * 系统会使用消息队列的方式来发送消息,此方法仅仅是将消息提交到消息队列中。什么时候开始真正发送,需
 * 要等待消息消费者从消息队列取到这条消息。
 *
 * @param message 消息内容。
 * @returns 异步任务对象。异步对象执行结果为 `null` 或者异常对象,因为 `null` 代表执行成功,异常为发
 * 送失败抛出的异常。
 */
export function sendMessage(message: succ.sys.Message): Future;

/**
 * 定时任务参数。
 */
export interface ScheduleArgs {
	/**
	 * 定时任务的 ID。
	 *
	 * 传递此参数后,可以通过此 key 唯一标识该任务。当连续多次设置同一个 key 的定时任务时只会保留最
	 * 后一个。同时,在设置定时任务后,调用者可以通过函数 {@link cancelSchedule} 取消该定时任务。
	 *
	 * 边界说明:如果不传递此参数,则定时任务一旦加入就会一直存在。如果是一个多次连续执行的任务,那
	 * 么此任务会一直存在到服务器关闭为止;如果是只执行一次的任务,那么会在执行完毕后退出。
	 */
	key?: string;
	/**
	 * 要执行的脚本所在的路径。
	 *
	 * 支持传入 `/` 开头的绝对路径,也支持 `./` 或 `../` 开头的相对路径(相对于当前脚本)。
	 */
	path: string;
	/**
	 * 执行脚本中的具体函数名称。
	 *
	 * @defaultValue `"main"`
	 */
	method?: string;
	/**
	 * 传递给脚本函数的入参,不传表示无参。以调用 `main` 为例:传递 `1` 则执行 `main(1)`;传递
	 * `[1,2]` 则执行 `main(1,2)`;传递 `[[1,2]]` 则执行 `main([1,2])`。
	 */
	args?: any;
	/**
	 * 延迟执行的时间(毫秒)。
	 *
	 * 注意事项:如果传递参数 {@link key},那么系统会只留下最后一次调用的任务。如果此时恰好上一个任
	 * 务正在执行,那么会等待上一个任务执行完毕后,再开始新的计时器。
	 *
	 * 边界说明:`delay`、`date` 和 `period` 必须设置其中一个。
	 */
	delay?: number;
	/**
	 * 在指定的日期和时间执行脚本,可传递日期对象或时间戳毫秒。
	 *
	 * 边界说明:`delay`、`date` 和 `period` 必须设置其中一个。
	 */
	date?: Date | number;
	/**
	 * 循环执行脚本的间隔(毫秒)。
	 *
	 * 每次间隔 period 毫秒,如果没有传递 period,那么只执行一次脚本。此时建议同时传递参数
	 * {@link key},以便后续按需取消定时器。
	 *
	 * 边界说明:`delay`、`date` 和 `period` 必须设置其中一个。
	 */
	period?: number;
}

/**
 * 设置一个脚本定时执行。
 *
 * @param args 定时任务配置参数。
 */
export function schedule(args: ScheduleArgs): void;

/**
 * 取消掉一个定时任务。
 *
 * 边界说明:如果任务不存在则什么都不做。
 *
 * @param key 定时任务的 ID,该 ID 由调用 {@link schedule} 函数时通过参数指定。
 * @param mayInterruptIfRunning 如果任务正在运行,是否允许强行中断并取消任务。 @defaultValue false
 */
export function cancelSchedule(key: string, mayInterruptIfRunning?: boolean): void;

/**
 * 异步执行一个脚本函数。
 *
 * @param args 配置参数。
 * @param args.path 要执行的脚本所在的路径。支持传入 `/` 开头的绝对路径,也支持 `./` 或 `../` 开头的
 * 相对路径。
 * @param args.method 执行脚本中的方法名称。如果不传递则执行 `main`。 @defaultValue "main"
 * @param args.group 并发控制分组名称。当指定分组时,组内的脚本将共享一个并发量;否则将以
 * `path+method` 控制并发量。
 * @param args.maxConcurrency 并发量限制。传入明确的并发量时将限定同时最多可执行的线程数。需要注意的
 * 是,异步脚本线程是在系统的异步任务线程池中进行的,最终受制于系统异步任务的总线程池容量。
 * @param args.args 传递给脚本函数的入参。不传递表示无参数。
 */
export function exeScriptAsync(args: {
	path?: string;
	method?: string;
	group?: string;
	maxConcurrency?: number;
	args?: any;
}): void;



/**
 * 同步执行一个脚本函数,并返回它的结果。
 *
 * @param args 配置参数。
 * @param args.path 要执行的脚本所在的路径。支持绝对路径或相对路径。
 * @param args.method 执行脚本中的方法名称。 @defaultValue "main"
 * @param args.args 传递给脚本函数的入参。
 * @returns 目标脚本函数返回的结果。
 */
export function exeScript(args: {
	path?: string;
	method?: string;
	args?: any;
}): any;

/**
 * 记录服务器端事件日志。
 *
 * 当 `event` 为字符串时,事件名由“模块标记 + 事件简称”构成(如 `fapp.submitData` 表示提交表单数
 * 据)。必须符合产品《事件和日志规范.md》。系统通过事件名可以自动设置事件的描述、安全级别和日志记录
 * 级别。
 *
 * @param event 传递一个事件名称字符串,或者是事件的详细信息对象。
 * @param log 当第一个参数传递的是字符串时,可传递此参数附加一条事件的日志内容。
 */
export function fireEvent(event: string | ServerEvent, log?: string): void;


/**
 * 返回系统工作目录或者是其子目录的绝对路径。
 *
 * 边界说明:返回的路径均不带最后的 `/` 或 `\`。
 *
 * 例如:
 * 1. `getWorkDir()` 返回 `/path/to/workdir`
 * 2. `getWorkDir('abc/def')` 返回 `/path/to/workdir/abc/def`
 *
 * @param subPath 相对于系统工作目录的子路径。
 * @returns 对应工作目录的绝对路径字符串。
 */
export function getWorkDir(subPath?: string): string;

/**返回用于存放临时文件的目录,不带最后的`/`或`\` */
export function getTempDir(): string;

/**返回用于存放缓存文件的目录,不带最后的`/`或`\` */
export function getCacheDir(): string;

/**返回在集群上每个节点都可以访问的一个跨集群共享的目录,不带最后的`/`或`\` */
export function getClusterShareDir(): string;

/**获取系统环境变量JAVA_HOME的值 */
export function getJavaHome(): string;

/**获取用户文件夹的路径,即Java环境变量user.home的值 */
export function getUserHome(): string;

/**获取tomcat的web根目录,以/结尾,如`/Users/xxxxx/workspace5.0/bi/com.succez.bi/web/` */
export function getWebRootDir(): string;


/**
 * 返回系统的 contextpath。
 *
 * 注意事项:在系统启动时应该设置 contextpath,如果没有设置调用本方法会出异常。
 *
 * @returns 符合 servlet 规范的 contextPath 字符串。如果没有 context 返回 `""`;如果有,返回 `/` 开
 * 头(没有 `/` 结尾)的字符串,如 `/bi`。
 */
export function getWebContextPath(): string;

/**
 * 获得当前 web 服务器的端口号。
 *
 * 注意事项:此函数会确保获得一个合法的端口号,实在获取不到会抛出异常。
 *
 * @returns HTTP 端口号。
 */
export function getWebHttpPort(): number;

/**
 * 获取 Java 虚拟机的版本号。
 *
 * @returns 版本号字符串。
 */
export function getJavaVersion(): string;

/**
 * 返回 jvm 的空闲内存,单位字节。
 *
 * @returns 内存大小。
 */
export function getJvmFreeMemory(): number;

/**
 * 返回 jvm 已分配的内存,单位字节。
 *
 * @returns 内存大小。
 */
export function getJvmTotalMemory(): number;

/**
 * 返回 jvm 最大可用内存,单位字节。
 *
 * @returns 内存大小。
 */
export function getJvmMaxMemory(): number;

/**
 * 返回 jvm 的进程 ID。
 *
 * @returns 进程 ID。
 */
export function getJvmProcessID(): number;

/**
 * 返回逻辑 CPU 数目,多核的每核算一个 CPU。
 *
 * @returns CPU 数目。
 */
export function getAvailableProcessors(): number;

/**
 * 返回当前时间的毫秒数。
 *
 * 对应 `System.currentTimeMillis()` 方法。
 *
 * @returns 时间戳。
 */
export function getTimeMills(): number;

/**
 * 返回操作系统的名称。
 *
 * 返回的名称可能包括 Linux, Mac OS, Mac OS X, Windows 2000, Windows XP, Windows 2003, Windows CE,
 * OS/2, Solaris, SunOS, MPE/iX, HP-UX, AIX, OS/390, FreeBSD, Irix, Digital Unix, NetWare 4.11,
 * OSF1, OpenVMS 等等。
 *
 * 更多信息参考:[OS Names](http://lopica.sourceforge.net/os.html)
 *
 * @returns 操作系统名称。
 */
export function getOSName(): string;

/**
 * 返回操作系统的版本号。
 *
 * 例如:`10.2.6`, `6.3`。
 *
 * @returns 操作系统版本号。
 */
export function getOSVersion(): string;

/**
 * 返回操作系统的架构信息。
 *
 * 例如:`x86_64`, `x86`, `Power`, `ppc`。
 *
 * @returns 系统架构。
 */
export function getOSArch(): string;

/**
 * 返回所有的 OS 环境变量。
 *
 * @returns 环境变量字典。
 */
export function getOSEnvironments(): { [envName: string]: string };

/**
 * 执行指定的外部程序。
 *
 * 行为说明:等待其执行完毕后返回标准输出信息、错误信息等。
 *
 * @param file 外部程序的绝对路径。如果是 `\` 分隔符,需要写成 `'\\'`。
 * @param args 传递给外部程序的执行参数数组。
 * @returns 包含输出、错误和错误码的对象。
 */
export function exe(file: string, args?: Array<string>): {
	/** 标准输出内容 */
	stdout: string;
	/** 标准错误输出内容 */
	stderr: string;
	/** 进程退出码,0 表示正常退出 */
	exitcode: number;
};

/**
 * 异步执行指定的外部程序。
 *
 * 行为说明:不等待其执行完毕,直接返回。
 *
 * @param file 外部程序的绝对路径。如果是 `\` 分隔符,需要写成 `'\\'`。
 * @param args 传递给外部程序的执行参数数组。
 */
export function exea(file: string, args?: Array<string>): void;

/**
 * 通过 Node.js 执行指定 JS 模块中的导出函数,并返回其标准输出内容。
 *
 * 行为说明:启动一个 Node.js 子进程来执行目标模块中的指定函数,等待执行完毕后返回结果。
 * 若函数执行过程中抛出异常,此方法也会抛出异常。
 *
 * 注意事项:参数通过命令行传递给 Node.js 进程,总长度受操作系统限制。
 *
 * @example
 * // 调用内置模块
 * sys.runNodeJs({ module: "sys/sys", func: "relativePath", args: ["/a/b", "/a/c"] });
 * // → "../c"
 *
 * @example
 * // 调用元数据脚本模块
 * sys.runNodeJs({ module: "/项目/app/应用.app/scripts/my_script", func: "run", args: ["arg1"] });
 *
 * @param args 执行参数对象。
 * @returns Node.js 进程的标准输出内容(即函数返回值的字符串形式)。
 */
export function runNodeJs(args: {
	/**
	 * JS 模块路径。
	 *
	 * - **内置模块**:使用相对路径,如 `"sys/sys"`、`"metadata/metadata"`
	 * - **元数据脚本模块**:使用元数据绝对路径(不含 ctx 和扩展名),
	 *   如 `"/项目/app/应用.app/scripts/my_module"`
	 */
	module: string,
	/** 要执行的导出函数名称 */
	func: string,
	/** 传递给函数的参数数组,每个元素为字符串(受命令行长度限制) */
	args?: Array<string>,
	/** 是否允许前端代码中发起 AJAX 请求,默认 `true` */
	allowAjax?: boolean,
	/**
	 * 执行模块的用户身份(用户 ID)。
	 *
	 * 为空时使用当前登录用户。需要编辑权限的场景(如报表、仪表板编译)
	 * 应指定有权限的用户,否则可能出现权限异常。
	 */
	userId?: string,
}): string;

/**
 * 查找满足条件的进程信息。
 *
 * @param assign Windows 系统是进程名关键字,其他系统是进程命令行的关键字。
 * @returns 匹配的进程列表。
 */
export function findProcess(assign: string): Array<{
	/** 进程 ID */
	pid: number;
	/** 父进程 ID */
	ppid?: number;
	/** 文件名 */
	name: string;
	/** 命令行内容 */
	cmd: string;
}>;


/**
 * 线程休眠。
 *
 * 对应 `Thread.sleep()` 方法。
 *
 * @param sleepTime 休眠时间(毫秒)。
 */
export function sleep(sleepTime: number): void;


/**
 * 判断一个应用是否有权限访问某一项 API。
 *
 * @param appId 应用 ID。若为 `null` 或不正确,或 enabled 为 `false`,或 type 不为 oauth, code, auto
 * 此三种类型,则会返回类似由于应用不存在的错误信息。
 * @param appSecret 应用密钥。若不正确,则返回密钥不正确的错误信息。
 * @param apiPath API 路径,如 `api/oauth2/verifyUser`。若该 API 不在当前 app 的白名单中,则返回没有
 * 权限的错误信息。
 * @returns 验证结果及可能的错误信息。
 */
export function checkAppPermission(appId: string, appSecret: string, apiPath: string): { result: boolean, errorCode?: string, message?: string };

/**
 * 根据 appId 获取 app 的信息。
 *
 * 边界说明:不存在时返回 `null` 或抛出异常。
 *
 * @param appId 应用 ID。
 * @param throwException 不存在对应 appId 的信息是否抛出异常。 @defaultValue false
 * @returns 应用信息。
 */
export function getAppInfo(appId: string, throwException?: boolean): TrustedAppInfo;

/**
 * 获取当前脚本所在线程绑定的进度条对象。
 *
 * 该方法常用于需要在脚本中输出自带上下文的日志,并最终呈现给具体终端用户查看的场景:
 * 1. 数据加工中的脚本节点输出自己的日志,日志会最终和加工本身的日志在一起输出给用户。
 * 2. 脚本中通过多线程池提交的脚本可以通过此对象输出相关日志。
 *
 * 注意事项:这里输出的日志和通过 `print` 函数输出的不同。`print` 函数常用于开发者自己调试脚本使用,
 * 而使用 `ProgressMonitor` 输出的日志是给具体终端用户查看日志用的。
 *
 * @returns 若当前线程没有绑定的进度条对象,则会创建一个新的返回并设置给当前线程。
 */
export function getThreadProcessMonitor(): ProgressMonitor;

/**
 * 设置当前脚本的最大执行超时时间。
 *
 * 此设置为脚本级别,仅影响当前脚本执行线程,不会影响其他正在运行的脚本
 * 或系统全局配置。每次脚本执行时独立生效,脚本结束后自动失效。
 * 脚本引擎会在执行过程中周期性检查是否超时,超时后自动终止脚本执行,
 * 可防止死循环或长时间运行的逻辑占用服务器资源。
 *
 * ```typescript
 * // 将当前脚本的超时时间延长到 60 秒(适用于复杂查询或批量处理场景)
 * sys.setScriptTimeout(60000);
 *
 * // 取消超时限制(仅在确实需要长时间运行时使用,避免资源泄漏)
 * sys.setScriptTimeout(0);
 * ```
 *
 * @param timeoutMs 超时毫秒数。默认 10000(10 秒),设为 0 表示不限制。
 */
export function setScriptTimeout(timeoutMs: number): void;

/**
 * 获得一个线程池,不存在则创建。
 *
 * @param options 配置参数。
 * @param options.name 线程池名称。
 * @param options.corePoolSize 核心线程数。 @defaultValue 3
 * @param options.maximumPoolSize 最大线程数。 @defaultValue 5
 * @param options.keepAliveTime 线程空闲时间。当线程空闲时间达到它时会退出。单位秒。 @defaultValue
 * 30
 * @returns 返回一个线程池对象,用于提交线程任务。
 */
export function getThreadPool(options: {
	name: string,
	corePoolSize?: number,
	maximumPoolSize?: number,
	keepAliveTime?: number
}): ThreadPool;

/**
 * 移除并关闭一个指定的线程池。
 *
 * 如果线程池存在,则将其关闭并从系统中移除。
 *
 * @param name 要移除的线程池名称。
 */
export function removeThreadPool(name: string): void;

/**
 * 尝试获取一个分布式锁。
 *
 * 并等待获取成功或超时。如果获取失败或超时会触发异常。获取成功后必须在特定时间内释放锁,否则将自动
 * 释放锁。
 *
 * @param key 必须传递一个合法的 key,长度小于 256。调用者自己确保 key 之间的冲突问题。
 * @param timeout 等待超时时间,单位毫秒。
 * @param maxKeepTime 持有锁超过这个时间将自动释放锁,通常用于防止应用系统宕机导致的死锁。
 * @returns 返回一个 Closeable 对象。关闭该对象后锁即释放。
 */
export function distLock(key: string, timeout?: number, maxKeepTime?: number): Closeable;

/**
 * 释放锁。
 *
 * 通过 {@link distLock} 函数获取锁后可以通过 close 其返回的锁来释放,也可以调用此函数根据 key 来释
 * 放。
 *
 * @param key 必须传递一个合法的 key,长度小于 256。
 */
export function distUnlock(key: string): void;


/**
 * 扩展对象。
 */
export interface SysExtension {
	/**
	 * 获取扩展的名字。
	 *
	 * @returns 扩展名,例如 `succ-portalTemplate-darkblue`。
	 */
	getName(): string;

	/**
	 * 获得 `package.json` 的内容。
	 *
	 * @returns JSON 对象。
	 */
	getPackageJSON(): JSONObject;

	/**
	 * 获取扩展自带的 Java 对象。
	 *
	 * 关于扩展自带第三方 Java 类库的详细说明,见 [开发文
	 * 档](https://docs.succbi.com/v5/dev/extension/faq/051be50)。
	 *
	 * @param clazz 类路径,如 `com.xxx.yyy.Class1`。
	 * @param errorIfNotExists 不存在时是否抛出异常。 @defaultValue false
	 * @returns 对应的 Java 对象实例或类。
	 */
	getJavaType(clazz: string, errorIfNotExists?: boolean): any;

	/**
	 * 返回扩展内的文件。
	 *
	 * @param file 要获取的文件路径。不可直接以 `/` 开头。
	 * @param errorIfNotExists 不存在时是否抛出异常。 @defaultValue false
	 * @returns 对应的文件对象。
	 */
	getFile(file: string, errorIfNotExists?: boolean): import("./fs").File;
}

/**
 * 获取系统扩展对象。
 *
 * 扩展是一种插件,安装一个扩展可以提供 SuccBI 默认不具备的功能,能够改变产品的默认功能和行为。
 *
 * @param extensionName 扩展名称,如 `succ-portalTemplate-darkblue`。
 * @param errorIfNotExists 不存在时是否抛出异常。 @defaultValue false
 * @returns 扩展对象。
 */
export function getExtension(extensionName: string, errorIfNotExists?: boolean): SysExtension;

/**
 * 编译、加载java代码返回对应的class对象。
 *
 * 用于在脚本中动态构建java二进制代码。
 *
 * ```ts
 * let source =
 *    `package a.b.c;
 *    import java.util.function.Supplier;
 *    public class Test1 implements Supplier<Object>{
 *        public Object get(){
 *            return 2;
 *        }
 *    }
 *    `;
 * let Test1 = sys.compileInlineClass(source, null);
 * let instance = new Test1();
 * ```
 *
 * @param source java代码的文件,包括`package ... import ... public class ...` 等部分。
 * @param extraClasspath 编译时可能会引用到的一些类所在的classpath,此函数会自动将当前jvm运行时的
 *        classpath加上,如果脚本所在的扩展有javalib,那么也会自动加上,所以这里只需要指定额外的
 *        classpath即可,没有时可传递null。
 */
export function compileInlineClass<T = any>(source: string, extraClasspath?: string): T;

/**
 * 获取一个文件存储服务
 *
 * 这个文件存储服务可能不支持创建目录
 *
 * @param name 文件服务的名称,不传递默认取系统默认使用的存储服务
 * @returns 文件存储服务对象,不存在时根据 `throwIfNotExists` 参数决定返回 `null` 或抛出异常
 */
export function getVfsBucket(name?: string, throwIfNotExists?: boolean): VfsBucket;

/**
 * 获取系统模块使用的文件存储空间
 *
 * @param module 模块名称,为系统设置中{@link SysSettingsJson["sys.file.storages"]} 配置中的key
 * @returns 文件存储空间对象
 */
export function getSysFileStorage(module: string): VfsBucket;


/**
 * 根据文件路径创建一个下载链接。将这个链接提供给前端用户,用户点击后可以下载此文件。
 *
 * @param fileInfo 可以是文件路径、文件对象{@link File}或者是一个json对象。
 * @param fileName 可选,指定用户下载到本地后的默认文件名, 当{@code fileInfo}是JSON的时候不能传这个
 * 参数。
 * @return 返回一个下载链接。
 */
export function createDownloadURL(fileInfo: string | File | {
	/** 
	 * 要下载的文件
	 */
	file: string | File;
	/**
	 * 指定用户下载到本地后的默认文件名 
	 */
	fileName?: string;
	/**
	 * 文件内容类型,如`application/octet-stream`。如果不指定,则通过文件的后缀自动获取 
	 */
	contentType?: string;
	/**
	 * 下载链接最长保留时间,单位毫秒,默认为2天。当`temp`传递false时,下载链接可以重复下载文件。
	 */
	maxAge?: number;
	/**
	 * 若为true,则会在响应头上加上`Content-Encoding`: `gzip`,浏览器会按照gzip解压文件。文件内容需
	 * 要调用者自己先压缩好 
	 */
	gzip?: boolean;
	/**
	 * 是否临时文件,若为临时文件,则下载一次之后删除。
	 *
	 * 默认为true。
	 */
	temp?: boolean;
	/**
	 * 是否为安全文件
	 *
	 * 若为安全文件则只能生成下载连接的用户可以下载,不是则下载连接可以匿名访问。默认false
	 */
	secure?: boolean
}, fileName?: string): string;

/**
 * 根据用户上传的文件id获取文件
 *
 * 系统中大多数据的上传文件服务,都是先调用`/api/fileupload/services/upload`来上传文件,这个api在完
 * 成上传文件后,会返回给前端一个文件id,业务系统再根据使用这个文件id来调用其他的服务来实现对文件的
 * 处理
 *
 * 如果没有登录,会抛出没有错误码为`err.login.notlogin`的异常
 *
 * @param uploadFileId 上传文件的ID
 * @returns 上传文件信息,不存在时返回 `null`
 */
export function getUserUploadFile(uploadFileId: succ.types.TempUploadFileId): UploadFileInfo | null;

/**
 * 上传用户文件
 *
 * 脚本中上传一个文件到用户上传文件服务中,等价于直接在界面上使用`/api/fileupload/services/upload`上
 * 传文件,和接口一样会返回一个文件id。使用id可以通过{@link #getUserUploadFile}获取对应的文件。
 *
 * @param file 文件内容
 * @param fileName 文件名, 为null时使用file的文件名 
 * @returns 返回文件id,可以通过{@link getUserUploadFile}获取文件对象
 */
export function uploadUserFile(file: File, fileName: string): succ.types.TempUploadFileId;

/**
 * 获取一个与第三方系统进行验证登录后所产出的`认证服务凭证信息`
 *
 * 供依赖了`第三方系统认证服务`的`扩展`获取认证信息调用第三方系统接口
 *
 * 虽然系统会按照获取器返回的时效性来生成和缓存信息,但是是否有效还是有第三方系统决定,如果使用认证
 * 信息时发现无效,一般来说应该再次调用此方法并给参数`forceUpdate`传递true来更新缓存并重新获取
 *
 * 调用者尽量不要长时间持有当前返回的对象,需要认证信息就应该调用当前方法,避免其他服务同时使用同一
 * 个认证信息时执行了强制刷新
 *
 * @see succ.ExtendPoint.serviceCredential
 * @see succ.servicecredential.CredentialConf
 * @param id 认证信息服务的ID,来源于系统设置中存储配置信息
 *        {@link succ.servicecredential.CredentialConf.id}
 * @param forceRefresh 是否需要强制刷新并获取一个新的服务凭证信息,默认false
 * @returns 返回认证信息,不会返回null;如果`id`对应的配置信息不存在,会抛出异常
 */
export function getServiceCredential(id: string, forceRefresh?: boolean): Credential;

/**
 * 根据`第三方系统认证服务`的`扩展类型`来获取用于与第三方系统验证登录后产出的`认证服务凭证信息`
 *
 * 本方法用于获取一个系统有且仅有一个配置的认证信息,比如高德地图服务,提供的地图服务都是固定的,调
 * 用高德的API所需要一个`API Key`只是用于高德服务校验用户身份,不同的`API Key`享受到的服务都是一样
 * 的,没有必要配置多个服务
 *
 * 借助这个方法,应用服务的扩展者可以不需要考虑使用时扩展依赖了哪个认证服务配置,只需要在系统中不存
 * 对应的`认证服务`配置时提示需要添加一个配置
 *
 * 如果系统中配置了多个`type`指定类型的`认证服务`,会返回第一个找到的认证服务(按照添加配置时的顺序进
 * 行排序,请在`系统设置`-> `服务` -> `服务凭证`设置界面查看具体顺序)
 *
 * 其它调用说明请参考{@link getServiceCredential}
 *
 * @see succ.ExtendPoint.serviceCredential
 * @see succ.servicecredential.CredentialConf
 * @param type 为一个`认证服务扩展`的名称{@link succ.servicecredential.ExtensionContributeInfo.name}
 * @param forceRefresh 是否需要强制刷新并获取一个新的服务凭证信息,默认false
 * @returns 返回认证信息,不会返回null;如果系统中不存在对应的认证服务配置,会抛出异常
 */
export function getServiceCredentialByType(type: string, forceRefresh?: boolean): Credential;

/**
 * 认证服务凭证信息。
 *
 * 凭证信息本身是一个 JSON 结构,其中包含了用于访问特定平台服务时所需的必要验证数据(如
 * `appid`、`access_token` 等)。由于面对众多的外部平台,具体的内容和 key 的名称完全取决于所对应平台
 * 的官方规范,本接口采用索引签名以兼容所有不同服务的凭证字段集。例:对于微信小程序,通常包括
 * `appid` 和 `access_token`;而对于钉钉微应用,则可能包含 `clientId` 和 `auth_code` 等等。
 */
export interface Credential {
	/**
	 * 服务端接口调用凭证。
	 *
	 * 对应诸如微信小程序、微信公众号服务号、企业微信等平台提供的服务端能力全局鉴权 Token。
	 */
	access_token?: string;

	/**
	 * 应用 ID。
	 *
	 * 对应应用所在对应平台(如微信公众平台)中下发分配的唯一独立标识。
	 */
	appid?: string;

	/**
	 * 其他消息属性。
	 *
	 * 兼容由不同平台颁发的各式属性字段。
	 */
	[k: string]: any;
}

# 对象

/**定义系统核心的类型 */


declare interface OutputStream extends Closeable {

	/** 写出字节码 */
	write(bytes: number[]): void;

	/**
	 * 写出字节码
	 * @param bytes 
	 * @param off  开始写出的起始位置the start offset in the data.
	 * @param len  写出字节长度长度
	 */
	write(bytes: number[], off: number, len: number): void;

	/** 写出一个字节 */
	write(byte: number): void

	/**
	 * 刷新输出流,强制将所有缓存区的数据写出
	 */
	flush(): void;

}

declare interface InputStream extends Closeable {
	/** 
	 * 读取一个字节
	 * @returns 如果流已经读取结束,则返回-1
	 */
	read(): number;

	/**
	 * 从流中特定长度的字节数存入bytes 数组中,流中的数据不够bytes数组长度时,也不会补足数据
	 * @param bytes 
	 * @returns 从流中读取出来的字节数,如果已经读取完成,返回-1
	 */
	read(bytes: number[]): number;

	/**
	 * 从流中特定长度的字节数存入bytes 数组中,流中的数据不够bytes数组长度时,也不会补足数据
	 * @param bytes 
	 * @param off bytes数组中的第一个被写入字节的偏移位置
	 * @param len 最大读取长度
	 * @returns 从流中读取出来的字节数,如果已经读取完成,返回-1
	 */
	read(bytes: number[], off: number, len: number): number;

}

declare interface Writer extends Closeable {

	/** write a string or number */
	write(c: string): Writer;

	/** Appends the specified string to this writer. */
	append(c: string): Writer;

	/** 
	 * Flushes the stream.  If the stream has saved any characters from the
	 * various write() methods in a buffer, write them immediately to their
	 * intended destination.  Then, if that destination is another character or
	 * byte stream, flush it.  Thus one flush() invocation will flush all the
	 * buffers in a chain of Writers and OutputStreams. 
	 */
	flush(): void;

}

/**
 * 对应的是{@link java.io.BufferedReader}
 */
declare interface Reader extends InputStream {
	/**
	 *  从输入流中读取一行作为字符串
	 * @param ignoreLF 默认false, 是否忽略下一个 `\n` 
	 */
	readLine(ignoreLF?: boolean): string;
}

/**
 * 一个高性能的CSV文件的读取工具类。
 * 
 * 支持标准的CSV规范,支持双引号引起来的字段,双引号内部的所有字符都认为是字段的值。
 */
declare interface CSVReader extends Closeable {

	/**
	 * 读取一行。
	 * 
	 * 调用此函数并返回true之后才能继续调用{@link #getColumnCount()}判断此行有多少列,调用
	 * {@link CsvReader.getObject}获取指定列的值。
	 */
	next(): boolean;

	/**
	 * 返回当前行有多少列。
	 *
	 * 只有当调用{@link CsvReader.next}且返回true后才能调用此函数。
	 */
	getColumnCount(): number;

	/**
	 * 获取当前行的所有值。
	 * 
	 * 1. 只有当调用{@link CsvReader.next()}且返回true后才能调用此函数,否则可能出现空指针异常。
	 * 2. 返回的数组是内部复用的,调用者不要长期持有或修改这个数组,在下次调用{@link CsvReader.next()}时数组
	 *    对象中的内容会被修改。
	 * 3. 返回的数组的长度就是当前行实际的有效列数的。
	 */
	getRowValues(): any[];

	/**
	 * 将当前行的所有值,复制到指定的数组。
	 * 
	 * @param values 
	 * @param offset 
	 * @param len 
	 */
	getRowValues(values: any[], offset: number, len: number): void;

	/**
	 * 获取当前行的指定列的值。
	 * 
	 * 只有当调用{@link CsvReader.next}且返回true后才能调用此函数。
	 * 
	 * @param i 第i列,从0开始。
	 * @returns i大于总列数时返回null。
	 */
	getObject(i: number): any;
}

/**
 * 一个高性能CSV写入器。
 */
declare interface CSVWriter extends Writer {

	/**
	 * 输出一行数据并自动换行。
	 * 
	 * @param values 
	 */
	writeRow(values: any[]): void;

	/** 设置空值是否使用引号包裹。 */
	setQuoteEmptyValue(quoteEmptyValue: boolean): void;

}

/**
 * 让后端的数组对象好用点,js原生的比较晦涩。
 * 
 * Copy from global.d.ts 
 */
interface Array<T> {
	/**
	 * 将`arr`中的元素挨个push到自己内部。
	 * 
	 * @returns 返回自己
	 */
	pushAll(arr: T[]): T[];

	/**
	 * 添加其不存在的条目
	 * @param arr 准备加入的数组
	 * @returns 返回自己
	 */
	distinctPushAll(arr: T[]): T[];

	/**
	 * 添加其不存在的元素
	 * @param obj 准备加入的元素
	 * @returns 返回自己
	 */
	distinctPush(obj: T): T[];

	/**
	 * 比较本数组和另外一个数组arr是否内容相同
	 */
	equals(arr: T[]): boolean;

	/**
	 * 返回去掉重复项的一个新数组
	 */
	distinct(): T[];

	/**
	 * 从数组中删除一个元素
	 */
	remove(obj: number | T): T;

	/**
	 * 从数组中删除多个元素
	 */
	removeAll(objs: number[] | T[]): T;
}

/**
 * 消息队列的消息结构
 */
declare interface MQMessage {
	/**消息的主题,用于订阅消息的时候区分消息 */
	topic: string,
	/**消息的标签,用于订阅消息的时候区分消息*/
	tag: string,
	/**消息体,可以是一个数组 */
	message: any
}

/**
 * 输出一个日志信息。
 *
 * 1. 日志可以输出到控制台,见<https://docs.succbi.com/dev/script-debug/#debug-with-log>
 * 2. 日志也可以输出到进度对话框中,这一点与{@link console.log()}不同。
 *
 * @param log 可以是字符串、Error、Json或其他对象,如果是字符串,内部可以包含参数占位符,会依次取
 * {@link args}中的参数替换,如:
 *  1. `%s` 替换为字符串
 *  2. `%d`或`%i` 替换为整形数字
 *  3. `%f` 替换为浮点数字
 *  4. `%o` 替换为对象
 * @param args 附加参数,可选,args中的参数会依次替换并输出到第一个参数中的动态占位符中,剩下的参数
 * 将自动输出到日志后面,最后一个参数如果是Error对象,那么将输出堆栈信息。
 */
declare function print(log: any, ...args: any[]): void

/**
 * `Java.type("java.util.Locale")` 等价于 `java.util.Locale`
 * @see https://docs.oracle.com/javase/8/docs/technotes/guides/scripting/nashorn/api.html
 */
declare const Java: {
	/**
	 * 返回一个java的class对象。
	 *
	 * 关于扩展自带第三方java类库,见<https://docs.succbi.com/v5/dev/extension/faq/051be50>。
	 *
	 * @param fullClassName 类名,如`java.util.ArrayList`
	 * @throws 找不到类时会抛出异常
	 */
	type(fullClassName: string): any;

	/**
	 * 构造一个java的ArrayList对象并返回。
	 * 
	 * @param initialCapacity 初始化长度,不传递时,将使用java默认的构造长度。
	 */
	newArrayList(initialCapacity?: number): Array<any> | any;

	/**
	 * 构造一个java的HashMap对象并返回。
	 * 
	 * @param initialCapacity 初始化长度,不传递时,将使用java默认的构造长度。
	 */
	newHashMap(initialCapacity?: number): JSONObject;

	/**
	 * 构造一个java的ConcurrentHashMap对象(支持多线程操作)并返回。
	 *
	 * 在action脚本模块中初始化一个ConcurrentHashMap对象,后续的action函数调用可以并发的(多线程)读
	 * 取和设置这个map中的信息。
	 *
	 * @param initialCapacity 初始化长度,不传递时,将使用java默认的构造长度。
	 */
	newConcurrentHashMap(initialCapacity?: number): JSONObject;
};

/** 通过java可以引用java开头的类,如`java.util.Locale`  */
declare const java: any;
/** 通过com可以引用com开头的类,如`com.succsoft.bi.Xxxxx` */
declare const com: any;
/**
 * 通过`new JavaAdapter(...)`语法,动态生成字节码的方式创建一个满足java接口的java匿名类,并实例化这个匿名类的对象。
 * 
 * @see https://web.archive.org/web/20200704031304/https://developer.mozilla.org/en-US/docs/Mozilla/Projects/Rhino/Scripting_Java The JavaAdapter Constructor
 */
declare const JavaAdapter: any;

/**
 * getThreadPool()创建的线程池对象
 */
declare interface ThreadPool {

	/**
	 * 提交一个任务到线程池执行,该任务是某段脚本的export的方法
	 * @param args 
	 */
	submit(args: {
		/**指定任务的uuid,可以根据id轮训任务,在浏览器上显示等待信息 */
		uuid?: string;
		/**任务的一段描述文字,方便在线程管理界面理解这个线程 */
		desc?: string;
		/**
		 * 要执行的脚本的路径。
		 * 可以是绝对路径或者相对路径,不传递默认为当前文件路径
		 */
		path?: string,

		/**执行的脚本的方法 */
		method: string,

		/**方法执行的参数 */
		params?: Array<any>,

		/**
		 * 给线程设置进度条对象,可以使线程池中线程共享一个进度条对象这个方法一般是通过主线程创建
		 * createSubProgress,
		 */
		progress?: ProgressMonitor
	}): Future;

	/**
	 * 等待异步任务执行完成
	 *
	 * 内部实现每隔100ms确认一次任务是否执行完成
	 *
	 * @param tasks 异步任务或者异步任务列表
	 * @param waitTime 等待时间,单位为毫秒
	 * @param throwErrorIfTimeout 在等待时间到期后任务如果没有执行完,是否抛出异常,默认false
	 * @return true代表任务执行完成了
	 */
	waitFutures(tasks: Future | Future[], waitTime: number, throwErrorIfTimeout?: boolean): boolean;

	/**获取线程池中正在执行的任务数量 */
	getActiveCount(): number;

	/**获取线程池中执行过的任务数量 */
	getTaskCount(): number;

	/**
	 * 关闭线程池。
	 * 
	 * @param waitTime 默认等待关闭的时间为10秒,超过该时间会强行终止正在执行的线程
	 */
	shutDown(waitTime?: number): void;
}

/**
 * 异步任务对象
 *
 * 对应一个`java.util.concurrent.Future`
 */
declare interface Future {

	/**
	 * 尝试取消任务执行
	 *
	 * @param mayInterruptIfRunning 是否可以对正在执行的任务执行中断,false代表允许正在执行的任务持
	 *        续执行结束
	 * @returns false代表任务不能被取消,常规情况下代表任务已经执行结束了
	 */
	cancel(mayInterruptIfRunning: boolean): boolean;

	/**
	 * 是否任务已经被取消了
	 *
	 * @returns true代表任务被取消
	 */
	isCancelled(): boolean;

	/**
	 * 是否任务已经执行结束了
	 *
	 * @returns true代表执行结束
	 */
	isDone(): boolean;

	/**
	 * 等待执行结束并获取任务执行结果
	 *
	 * 如果任务没执行完成会一直等待任务执行结束,如果期望指定等待时间,请使用`utils`模块中的
	 * {@link getFutureResult}
	 *
	 * 可能因为中断、任务执行异常等问题抛出异常,请按需 catch异常
	 *
	 * @returns 根据任务返回内容
	 */
	get(): any;
}

/**
 * 线程的进度对象
 */
declare interface ProgressMonitor {
	/**设置进度的最小值,不设置默认为0 */
	setMinimum(value: number): void,

	/**设置进度条的最大值,一般情况需要进行设置 */
	setMaximum(value: number): void,

	/**设置进度条的位置 */
	setProgress(value: number): void,

	/**获取进度条的位置 */
	getProgress(): number,

	/**
	 * 进度条增加value的值
	 * @param value 不传递默认加1
	 */
	step(value?: number): void,

	/**
	 * 创建子进度对象,可以将主进度的一部分切分给子对象。
	 * 
	 * 一个复杂的业务流程(以系统的启动初始化过程为例)往往内部会执行很多子业务逻辑(如创建系统表、还原demo数据……),父业务流程需要有一个完整的进度信息呈现给用户,
	 * 父业务流程调用内部的子业务逻辑时也需要传递一个`ProgressMonitor`给它(比如系统初始化业务逻辑调用创建系统表的子业务逻辑),此时子业务逻辑只能走总的进度条的
	 * 一部分,为了让子业务逻辑好开发,就还是给它一个完整的进度条信息,让他可以“以为”它能走到100%,这样好开发些。
	 * 
	 * @param totalProgress 子进度条站总的任务条的多少进度
	 * @param acceptSubMessage 子进度条的{@link #setMessage(String)}是否反应给父进度条
	 * @param acceptSubLogs 子进度条的{@link #addLog(String)}是否反应给父进度条
	 * @return
	 */
	createSubProgress(totalProgress: number, acceptSubMessage: boolean, acceptSubLogs: boolean): ProgressMonitor

	/**
	 * 添加一条普通的表示详细信息的log
	 * @param log 
	 */
	addLog(log: string): void;

	/**
	 * 前台界面显示sql日志的规则:如果是SQL的日志,该日志应该以<sql>xxx</sql>包裹起来的,需要对SQL日志进行格式化并高亮显示。
	 * 后台在生成sql日志时,需要满足以上规则。本方法用于当日志为sql语句时,为该语句提供格式化包装,然后再添加到日志中。
	 * 例如sql描述信息为"开始查询:",sql语句为select * from ajxx,则sql日志为    开始查询:<sql>select * from ajxx</sql>
	 * @param sqlInfo sql描述信息
	 * @param sql sql语句
	 */
	addSql(sqlInfo: string, sql: string): void;

	/**
	 * 修改最后一条添加的日志,如果没有一条日志,那么添加一条<br />
	 * 此方法一个比较常见的应用场景就是,一行日志中显示百分比,可以看到数字不停地闪动,而不是数字变化一次就生成新的日志行
	 */
	setLastLog(log: string): void;

	/**
	 * 获取包含所有日志的字符串,通常用于刷新日志显示界面
	 */
	getLogs(): string;

	/**
	 * 获取日志的json结构,便于解析日志。
	 */
	getJsonLogs(): string;

	/**
	 * 获取已经存在的日志条数
	 */
	getLogCount(): number;
	/**
	 * 判断进程是否已经取消了
	 *
	 * @return
	 */
	isCanceled(): boolean;

	/**
	 * 设置是否要取消进度条,并给出取消的原因
	 *
	 * @param cancel 是否取消进度
	 * @param msg 取消进度的原因
	 */
	setCancel(cancel: boolean, msg: string): void;

	/**
	 * 检查是否已经取消了,如果取消了则触发异常CancelException
	 *
	 * @return
	 */
	checkCancel(): void;
}

/**
 * 脚本所在的文件的元数据路径。
 *
 * 通常以.action结尾(会自动去掉.ts后缀),如`/sysdata/public/test.action`。当使用require函数引入另
 * 一个脚本时,如在`/path/to/a.action`中引入了`/path/to/b.action`,此时此属性表示所在文件的名称,即
 * 如果在a.action中访问__filename,得到的是`/path/to/a.action`,在b.action中访问__filename,得到的是
 * `/path/to/b.action`。
 */
declare const __filename: string;

/**
 * 最初启动时的脚本。
 *
 * 在脚本互相引用时,此属性可以表示最初启动脚本运行环境时的那个脚本文件,如在`/path/to/a.action`中引
 * 入了`/path/to/b.action`,此时此属性总是表示`/path/to/a.action`,即便在b.action中访问__filename,
 * 得到的依然是`/path/to/a.action`。
 */
declare const __filename_root: string;

/**
 * 脚本所在文件夹元数据路径,如`/sysdata/public`。
 * 
 * 和{@link __filename}类似,当脚本文件require另一个脚本文件时,此属性代表所在脚本文件的所在目录。
 */
declare const __dirname: string;

/**
 * 脚本所在模块的`exports`对象。
 *
 * 通常情况下,用`export xxx`语法就可以在后端脚本模块中导出变量、函数、类等。
 *
 * 将`exports`提供出去可以在脚本中动态构造导出的对象,如在测试用例脚本文件中动态构建测试函数等。
 */
declare const exports: any;

/**
 * 脚本执行器对象。
 */
declare const _script_runner: any;

declare namespace Dom4j {

	/**
	 * 定义XML文档。
	 */
	interface Document extends Branch {

		/**
		 * 获取根元素。
		 *
		 * @return 
		 */
		getRootElement(): Element;
	}

	/**
	 * 定义能包含子节点的节点。
	 */
	interface Branch extends Node {

		/**
		 * 返回指定索引位置的节点。
		 *
		 * @param index 
		 * @return 索引超出范围抛异常IndexOutOfBoundsException。
		 */
		node(index: number): Node;

		/**
		 * 返回此分支包含的节点实例数。
		 *
		 * @return 
		 */
		nodeCount(): number;
	}

	/**
	 * 节点定义dom4j树中所有XML节点的行为。
	 */
	interface Node {

		/**
		 * 返回此节点的名称。
		 * 
		 * @return 对于CDATA和Text nodes返回null。
		 */
		getName(): string;

		/**
		 * 返回此节点的文本。如果内容为空则返回一个空字符串而不是null。
		 * 
		 * @return 
		 */
		getText(): string;

		/**
		 * 返回此节点的XML文本字符串。
		 * 
		 * @return 
		 */
		asXML(): string;

		/**
		 * 获取多个节点。
		 *
		 * @param xpathExpression 传入符合[XPath](https://www.w3school.com.cn/xpath/index.asp)的节点路径。
		 * 
		 * 以如下xml为例:
		 *```xml
		 *<?xml version="1.0" encoding="ISO-8859-1"?>
		 *<bookstore>
		 *<book category="COOKING">
		 *  <title lang="en">Everyday Italian</title>
		 *  <author>Giada De Laurentiis</author>
		 *  <year>2005</year>
		 *  <price>30.00</price>
		 *</book>
		 *
		 *<book category="CHILDREN">
		 *  <title lang=" en">Harry Potter</title>
		 *  <author>J K. Rowling</author>
		 *  <year>2005</year>
		 *  <price>29.99</price>
		 *</book>
		 *</bookstore>
		 *```
		 * 
		 * 参考示例:
		 * 1. selectNodes("/bookstore/book/title") ----->> 选取路径在/bookstore/book所有title节点
		 * 2. selectNodes("//book/title")----->>选择所有父元素是book的title元素
		 * 3. selectNodes("/bookstore/book/*")----->>选择所有路径依附于/bookstore/book的元素
		 * 4. selectNodes("/bookstore/book[1]/title")----->>选取bookstore 元素下面的第一个 book 节点的 title
		 * 5. selectNodes("/bookstore/book/title[@lang]")----->>选择有lang属性的title元素
		 * 6. selectNodes("/bookstore/book/title[normalize-space(@lang)='en']")----->>选择含有属性lang且其值(在用normalize-space函数去掉前后空格后)为'en'的title元素
		 * 7. selectNodes("//title|//price")----->>选择所有title和price元素
		 * @return 
		 */
		selectNodes(xpathExpression: string): Array<Node>;

		/**
		 * 查找满足XPath表达式的第一个子节点。
		 *
		 * @param xpathExpression 传入符合[XPath](https://www.w3school.com.cn/xpath/index.asp)语法的节点路径,具体规则说明详见{@link selectNodes(xpathExpression: string)}。
		 * @return 
		 */
		selectSingleNode(xpathExpression: string): Node;

		/**
		 * 查找满足XPath表达式的第一个子节点的文本内容。
		 * 
		 * @param xpathExpression 传入符合[XPath](https://www.w3school.com.cn/xpath/index.asp)语法的节点路径。具体规则说明详见{@link selectNodes(xpathExpression: string)}。
		 * @return 
		 */
		valueOf(xpathExpression: string): string;

	}

	/**
	 * 定义XML元素。
	 */
	interface Element extends Branch {

		/**
		 * 返回所含有的text内容,其中连续的空格被转化为单个空格,该方法不会返回null。
		 *
		 * @return 
		 */
		getTextTrim(): string;

		/**
		 * 返回属性列表。
		 *
		 * @return 
		 */
		attributes(): Array<Attribute>;

		/**
		 * 返回一个属性。
		 *
		 * @param indexOrName 指定索引或者给定name。
		 * @return 
		 * 1. 指定索引处的属性,若索引超出范围则抛IndexOutOfBoundsException异常。
		 * 2. 如果有多个符合的name的属性,则返回第一个。
		 * 3. 若没有符合name的属性,则返回null。
		 */
		attribute(indexOrName: number | string): Attribute;

		/**
		 * 返回具有给定name的属性的属性值。
		 *
		 * @param name 
		 * @return 如果没有此类属性,则返回null,如果属性值为空,则返回空字符串。
		 */
		attributeValue(name: string): string;

		/**
		 * 返回具有给定name的属性的属性值,如果没有此类属性值,则返回默认值。
		 *
		 * @param name 
		 * @param defaultValue 
		 * @return 
		 */
		attributeValue(name: string, defaultValue: string): string;

		/**
		 * 返回元素具有指定name的第一个子元素。若没有找到对应的元素,则返回null。
		 *
		 * @param name 
		 * @return 
		 */
		element(name: string): Element;

		/**
		 * 返回该元素中具有指定name的子元素数组,如果没有找到对应的元素,则返回空数组。
		 *
		 * @param name 
		 * @return 
		 */
		elements(name?: string): Array<Element>;

	}

	/**
	 * 定义XML的属性。
	 */
	interface Attribute extends Node {

		/**
		 * 返回属性值。
		 *
		 * @return 
		 */
		getValue(): string;
	}
}

/**
 * 服务器事件对象。对应服务器端的`com.succez.metadata.service.event.Event`接口。
 */
declare interface ServerEvent {
	/**
	 * 事件名称。
	 */
	name: string,

	/**
	 * 事件级别
	 *
	 * 默认是{@link LogLevel.INFO}
	 */
	logLevel?: succ.LogLevel,

	/**
	 * 元数据文件信息,应该是一个绝对路径,/开头的包含项目名的。
	 */
	resPath?: string,

	/**
	 * 操作结果,默认是成功的,如果是成功的操作,可以不用设置。
	 *
	 * 说明:
	 *
	 * 1. `exception`不为空时会自动设置为`EventOperationState#EXCPT`。
	 */
	operationState?: EventOperationState,

	/**
	 * 操作开始时间,如果不指定则为调用时的时间。
	 */
	startTime?: number,

	/*
	 * 操作结束时间,如果不指定则默认为该方法结束的时间。
	 */
	endTime?: number,

	/**
	 * 异常。如果有异常,那么`operationState`会自动设置为`EventOperationState#EXCPT`。
	 */
	exception?: Error,

	/**
	 * 日志的详细信息,例如报表计算的计算参数等,是一个json对象,会直接当作json序列化到系统日志表的
	 * clob字段中。
	 */
	detailInfo?: JSONObject,

	/**
	 * 一系列的进度日志条目。系统中有些操作是会产生一些进度日志的,比如用到了{@link ProgressMonitor},
	 * 如果需要记录进度日志可以指定本参数。
	 */
	logs?: Array<any>,

	/**
	 * 提供2个VARCHAR类型的附加字段,用于记录日志的一些个性化信息。
	 */
	option1?: string,
	option2?: string,

	/**
	 * 触发事件的用户ID。
	 */
	userId?: string,

	/**
	 * 用户登录的sessionId。
	 */
	sessionId?: string

	/**
	 * 数据完整性验证。
	 *
	 * 允许传入一个hash值,用于查询时判断数据是否篡改。
	 *
	 * 提供给`server.action.ts`中的`onPersistEvents`拓展点使用,默认为null,设置值后产品会自动写入模型对应的
	 * 数据完整性校验字段上。
	 */
	consistencyInfo?: string;
}

/**
 * 事件的状态:0成功,1失败,2异常,3错误。
 */
declare const enum EventOperationState {
	/**
	 * "成功完成"状态,如计划任务成功执行完毕,用户登录成功等。
	 */
	OK = 0,

	/**
	 * "失败状态"状态,如用户登录失败等。
	 */
	FAIL = 1,

	/**
	 * "异常状态"状态,如执行计算时表不存在。
	 */
	EXCPT = 2,

	/**
	 * "错误状态"状态,服务器级别的比较严重的错误结果,这个很少遇到,但是遇到后会对服务器运行产生影响。
	 */
	ERROR = 3
}

/**
 * 一个文件存储空间
 */
declare interface VfsBucket {
	/**
	 * 存储空间的名称。
	 *
	 * 唯一标识一个存储空间,由用户在新建存储空间时指定当系统内存在多个存储空间时,用于标识具体使用
	 * 哪一个,如元数据项目可以设置项目默认使用的文件存储空间。
	 *
	 * 此属性不同于{@link succ.vfs.VfsConfig.name},此属性标识的是空间在当前系统内的标识,而
	 * {@link succ.vfs.VfsConfig.name}标识的是连接器在连接第三方云平台存储时指定的`bucketName`,它是具体的云
	 * 平台oss服务需要的设置。
	 *
	 * @return 当前空间的名字。
	 */
	getBucketName(): string;

	/**
	 * 是否只读
	 *
	 * @return
	 */
	isReadonly(): boolean;

	/**
	 * 是否支持目录结构。
	 *
	 * 云平台的oss服务和多数分布式文件系统都是支持目录结构的,通常都是通过使用path当作存储文件的key
	 * 来模拟的,但也有些分布式文件系统如FastDFS不支持。
	 *
	 * @return
	 */
	supportsFolder(): boolean;

	/**
	 * 是否可支持自定义文件的唯一标识
	 *
	 * 有些文件存储,如FastDFS就不支持调用者自己设置文件名,它只能自己产生,这类服务可以用于存储用户
	 * 上传的临时文件,也可以用于存储模型附件(此时不能自定义存储路径),但就不能直接用于存储其他需
	 * 要指定名称的场景了。
	 *
	 * @return
	 */
	supportsArbitraryName(): boolean;

	/**
	 * 返回具体的连接配置。
	 *
	 * @return
	 */
	getConfig(): succ.vfs.VfsConfig;

	/**
	 * 获取文件的元数据信息。
	 * 
	 * @param name 文件标识
	 * @param throwIfNotExists 不存在时是否抛出异常,其他异常总是抛出,比如服务器连接失败。
	 * @return 不存在时抛出异常或返回null
	 */
	getMetaInfo(name: string, throwIfNotExists?: boolean): succ.vfs.VfsMetaInfo;

	/**
	 * 列出某个前缀或父目录的下级文件或子目录。
	 *
	 * 对于云平台OSS服务,通常key如果是`/`结尾,那么表示是目录,在oss中,目录对象不一定总是存在,此
	 * 时此函数会自动补齐缺失的目录对象。
	 *
	 * 当{@link supportsFolder()}返回true时可以调用当前方法,但是当{@link #supportsFolder()}返回
	 * false,此方法可能会抛出错误码为“err.vfs.unsupportedFeature”的异常,即即使
	 * {@link #supportsArbitraryName()}也可能不支持前缀遍历
	 *
	 * @param namePrefix 前缀或父目录路径,如果是目录,是/开头,以/结尾
	 * @param recur 是否递归
	 * @return 父目录不存在时返回null,存在但没有内容时返回空列表
	 */
	listFiles?(namePrefix: string, recur: boolean): succ.vfs.VfsMetaInfo[];

	/**
	 * 移动文件或文件夹。
	 *
	 * 当`name`以'/'结尾时认为是文件夹,此时会移动整个文件夹下的所有文件,包括子文件夹。
	 *
	 * 当原文件不存在或目标文件存在时抛出异常。目标目录或者目标文件的父级目录中不能存在同名的目录和
	 * 文件。
	 *
	 * 当{@link #supportsArbitraryName()}返回false或者{@link isReadOnly()}返回true时,通常不应调用此
	 * 方法,否则此方法会抛出错误码为“err.vfs.unsupportedFeature”的异常
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param originalName 原文件标识
	 * @param targetName 新文件标识
	 */
	moveFile?(originalName: string, targetName: string): void;

	/**
	 * 创建文件夹。
	 *
	 * 当{@link supportsArbitraryName()}或者{@link supportsFolder()}返回false时,通常不应调用此方
	 * 法,否则此方法会抛出错误码为“err.vfs.unsupportedFeature”的异常
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param name 文件标识
	 */
	createFolder?(name: string): void;


	/**
	 * 创建文件夹。包括文件夹的所有父文件夹。
	 *
	 * 当{@link #supportsArbitraryName()}或者{@link #supportsFolder()}返回false时,通常不应调用此方
	 * 法,否则此方法会抛出错误码为{@link succ.err.vfs.unsupportedFeature}的异常
	 * {@link VfsException}
	 *
	 * 当{@link #isReadonly()}为true时,通常不应调用此方法,否则此方法会抛出错误码为
	 * {@link succ.err.vfs.readonly}的异常{@link VfsException}
	 *
	 * @param name 文件标识,关于文件标识见此类注释。
	 */
	mkdir?(name: string): void;

	/**
	 * 复制文件。
	 *
	 * 不支持复制目录。当原文件不存在或目标文件存在时抛出异常。
	 *
	 * 当{@link #supportsArbitraryName()}返回false时,通常不应调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.unsupportedFeature”的异常
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param originalName 原文件标识
	 * @param targetName 新文件标识
	 */
	copyFile?(originalName: string, targetName: string): void;

	/**
	 * 删除文件或文件夹。
	 *
	 * 当name以'/'结尾时认为是文件夹,此时会删除文件夹下的所有文件,包括子文件夹。
	 *
	 * 当文件不存在时什么都不做。如果删除失败了,会抛出异常。
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param name 文件标识
	 */
	deleteFile(name: string): void;

	/**
	 * 批量删除文件。
	 *
	 * 此方法默认实现是循环调用{@link #deleteFile(String)},对于文件存储如果有批处理的接口,可以重写
	 * 此方法来减少网络通信的次数。
	 *
	 * 当name以'/'结尾时认为是文件夹,此时会删除文件夹下的所有文件,包括子文件夹。
	 *
	 * 当文件不存在时什么都不做。如果删除失败了,会抛出异常。
	 *
	 * @param names 文件标识集合,关于文件标识见此类注释。
	 */
	deleteFiles?(name: string[]): void

	/**
	 * 下载文件。
	 *
	 * @param name 文件标识
	 * @param target_file 读取的文件内容写到指定文件中,由调用者创建。
	 */
	downloadFile(name: string, target_file: any): void;

	/**
	 * 不指定文件标识上传文件。
	 *
	 * 当文件服务不支持自定义文件名称或者使用者不关心文件存储到哪时(临时文件),新建文件对应的文件
	 * 标识将会被存储到传入参数`metaInfo`的`name`属性中
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param metaInfo 元数据信息,不能为null,可以是一个空对象
	 * @param content 文件内容, 不会是null,不应该存在修改元数据信息不修改内容的情况
	 * @return 返回新的文件标识
	 */
	uploadFile(metaInfo: succ.vfs.VfsMetaInfo, content: any): void;

	/**
	 * 指定文件标识上传文件。
	 *
	 * 文件存在时会覆盖老文件
	 *
	 * 文件不存在情况则根据文件标识创建文件,如果文件服务不支持自定义文件标识应该选择调用
	 * {@link uploadFile(succ.vfs.VfsMetaInfo, any)}
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param name 文件标识,关于文件标识见此类注释,不能为null
	 * @param metaInfo 元数据信息,不能为null,可以是一个空对象
	 * @param content 文件内容, 不能为null,不应该存在修改元数据信息不修改内容的情况
	 * @param options 参数,支持{@link succ.vfs.VfsOptions#append}、{@link succ.vfs.VfsOptions#mkpdir}
	 */
	uploadFile(name: string, content: any, metaInfo?: succ.vfs.VfsMetaInfo, options?: succ.vfs.VfsOptions): void;

	/**
	 * 获取文件内容。
	 *
	 * 对于外部文件存储,如云服务oss,此函数有缓存,当文件内容没有修改时,可能会返回上一次已经下载的
	 * 文件对象。而有些实现可能就直接是基于本地磁盘的,此时可以直接返回其内部的文件对象。故调用者不
	 * 要修改返回的文件对象,应该只读的使用。
	 *
	 * @param name 文件标识
	 * @param throwIfNotExists 不存在时是否抛出异常,其他异常总是抛出,比如服务器连接失败。
	 * @return 不存在时返回null或者抛出异常,调用者不要修改返回的文件对象,应该只读的使用。
	 */
	getAsFile?(name: string, throwIfNotExists?: boolean): any;

	/**
	 * 获取一个读取文件内容的流。
	 *
	 * 此函数会尽量调用底层服务的能力,打开一个实时数据流,对于大文件,使用流读取文件内容,可以尽量
	 * 做到边下载边读取,节省IO等待时间。此函数无缓存支持,对一个文件多次打开流读取内容,可能每次都
	 * 会下载文件内容,如果需要多次读取文件内容,可以使用{@link getAsFile()}函数,有缓存。
	 *
	 * @param name 文件标识
	 * @return 如果文件不存在返回null,调用者需要自己关闭返回的流。
	 */
	openInputStream?(name: string): InputStream;

	/**
	 * 指定文件标识打开一个写入文件内容的流。
	 * 
	 * 对于大文件,使用流写入文件内容,可以尽量做到边写入边上传,节省IO等待时间。
	 * 
	 * 文件标识指定文件存在时会覆盖老文件
	 *
	 * 文件不存在情况则根据文件标识创建文件,如果{@link supportsArbitraryName()}返回false时应该选择
	 * 调用{@link openOutputStream(succ.vfs.VfsMetaInfo)}
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param name 文件标识,关于文件标识见此类注释。
	 * @param append true表示继续追加文件内容而不是覆盖文件。如果`name`指定的文件不存在,会被忽略掉
	 * @param metaInfo 元数据信息,可以为null,为null时根据文件标识符创建一个
	 * @param options 参数,支持{@link succ.vfs.VfsOptions#append}、{@link succ.vfs.VfsOptions#mkpdir}
	 * @return 不会返回null,调用者需要自己关闭返回的流。
	 */
	openOutputStream?(name: string, metaInfo?: succ.vfs.VfsMetaInfo, options?: succ.vfs.VfsOptions): OutputStream;

	/**
	 * 以新建文件的方式打开一个文件写入流。
	 *
	 * 对于大文件,使用流写入文件内容,可以尽量做到边写入边上传,节省IO等待时间。
	 *
	 * 新建的文件的文件标识将被存储到传递参数 `metaInfo`的 `name`属性中
	 *
	 * 当{@link isReadOnly()}返回true时,通常也不应该调用此方法,否则此方法会抛出错误码为
	 * “err.vfs.readonly”的异常
	 *
	 * @param metaInfo 元数据信息,不能为null,可以是一个空对象
	 * @return 不会返回null,调用者需要自己关闭返回的流。
	 */
	openOutputStream?(metaInfo: succ.vfs.VfsMetaInfo): OutputStream;
}
是否有帮助?
0条评论
评论