import AV from 'leanengine'; import Joi from 'joi'; import { SDKVersion } from './cloudHandler'; import { Platform, getCacheKey } from './base'; export { Platform, getCacheKey }; import { SetCache } from './redis'; export { SetCache }; import { VerifyType, SetVerifyParams, VerifyParams } from './verify'; export interface CloudInvokeParams { functionName: string; request: AV.Cloud.CloudFunctionRequest & { noUser?: true; internal?: true; } & { internalData?: T; } & { params: { _api?: SDKVersion; }; }; data?: any; cloudOptions?: CloudOptions; } export type CloudInvoke = (params: CloudInvokeParams) => Promise; export type SemverCloudInvoke = { /** * 平台 */ platform: Platform; /** * 可执行的版本 */ semver: string; /** * 符合条件时的回调 */ callback: CloudInvoke; }; export type CloudInvokeBefore = CloudInvoke; export declare function SetInvokeCallback(params: { beforeInvoke?: CloudInvokeBefore; afterInvoke?: CloudInvoke; }): void; export declare function SetAfterVerify(params: { afterVerify: (params: VerifyParams & { user?: AV.User; }) => Promise; }): void; type Environment = 'production' | 'staging' | string; interface CacheOptions { /** * 需要缓存的参数条件,请求参数完全符合其中某个数组中的参数组合时,才调用缓存. _开头为内部参数,不会被判断 */ params: Array>; /** * 存储的时间长度单位 */ timeUnit?: 'day' | 'hour' | 'minute' | 'month' | 'second'; /** * 缓存时长,单位为timeUnit,默认为1 */ count?: number; /** * 是否每个用户分别使用一个缓存 */ currentUser?: boolean; /** * 过期时间基于时间单位还是请求时间. 默认request. timeUnit为某个时间单位的整点开始即时,request为请求的时候开始计时 */ expireBy?: 'timeUnit' | 'request'; /** * redis 地址, 不填则使用默认redis */ redisUrl?: string; /** * 过期时间的随机偏移量,单位为秒 */ offset?: { min: number; max: number; }; } interface RateLimitOptions { /** * 时间数量 */ limit: number; /** * 时间单位 */ timeUnit: 'day' | 'hour' | 'minute' | 'second' | 'month'; } export interface VerifyOptions { /** * 验证类型 */ type: VerifyType; /** * 多少次调用需要走一次验证 */ count?: number; /** * 时间单位 */ timeUnit: 'day' | 'hour' | 'minute' | 'second' | 'month'; /** * 过期时间,单位为秒. 默认为30天 */ expire?: number; } type Omit = Pick>; type TypedSchemaLike = T extends string ? Joi.StringSchema : T extends Array ? Joi.ArraySchema : T extends number ? Joi.NumberSchema : T extends Date ? Joi.DateSchema : T extends boolean ? Joi.BooleanSchema : T extends Buffer ? Joi.BinarySchema : T extends Object ? Joi.ObjectSchema : Joi.AnySchema; export type IClientCacheMode = 'remote' | 'local' | 'localFirst' | 'remoteFirst'; /** * T为云函数的参数类型 */ interface CloudOptions { /** * 自动生成SDK的平台 */ platforms?: Array; /** * 是否为RPC调用 */ rpc?: boolean; /** * 运行环境,生产环境还是预备环境 */ environment?: Environment | Environment[]; /** * 缓存配置 */ cache?: CacheOptions; /** * 防抖配置 */ debounce?: boolean | Array>; /** * 备选名,用于让新的云函数,兼容旧的云函数调用 */ optionalName?: string; /** * 参数的schema, 必填参数记得加上 .required() . _开头为内部参数,不会被判断 */ schema: { [key in keyof Omit]-?: TypedSchemaLike; }; /** * schema的回调,提供更多配置选项用 */ schemaCb?: (schema: Joi.ObjectSchema) => Joi.ObjectSchema; /** * 可以无用户调用此云函数 */ noUser?: true; /** * 调用此云函数需要的权限 */ roles?: string[][]; /** * 每个用户调用此云函数的频率设置, 没有用户情况下, 使用ip限流 */ rateLimit?: RateLimitOptions[]; /** * 内部函数,不注册云函数,但是会应用缓存的功能,以供内部调用 */ internal?: true; /** * noUser为true的时, 默认不fetch User数据, 加上此设置,强制fetch User数据 */ fetchUser?: true; /** * 云函数调用前的回调, 可用于修改数据. 在全局beforeInvoke之后执行 */ beforeInvoke?: CloudInvoke; /** * @deprecated * 云函数调用后的回调, 可用于修改数据, 在全局afterInvoke之前执行 */ afterInvoke?: CloudInvoke; /** * 云函数调用后的回调, 可用于修改数据, 在全局afterInvoke之前执行 */ afterInvokes?: SemverCloudInvoke[]; /** * 额外自定义配置信息 */ customOptions?: any; /** * 模块id,可以自动生成,也可以指定 */ moduleId?: number; /** * 云函数id,可以自动生成,也可以指定 */ functionId?: number; /** * 是否需要验证后才能执行 */ verify?: VerifyOptions; /** * 服务端 标记哪些云函数可以进行客户端缓存,并把该标记发布到sdk */ clientCache?: { /** * 缓存没有数据时的默认返回内容 */ offlineDefaultCache?: R; /** * 配置存储的key, 以及符合配置条件的请求才会被缓存 */ keyPath: (keyof T)[][]; /** * 版本标记。当前端升级api模块之后,调用接口时生成的clientCacheVersion也不同。会把返回的version加入到缓存的key path里。 */ versionCb?: (params: any) => number | string; /** * - 远程模式 remote:完全不使用任何客户端缓存。每次调用都访问远程云函数。如果在离线模式下调用的话,就会直接报错 `new Error('App is offline, cannot call remote func: ' + 云函数名称)` * * 在线模式: 访问远程→返回远程结果 * * 离线模式: 报错 * * - 本地模式 local:如果有本地缓存,则返回本地缓存,否则访问远程云函数,并将结果缓存。如果在离线模式下,有本地缓存则返回缓存,没有本地缓存则看是否设置了offlineDefaultCache,有则返回,无则报错`new Error('App is offline and no local cache is found for local func: ' + 云函数名称)` * * 在线模式: 返回本地缓存 / 访问远程→缓存结果→返回远程结果 * * 离线模式: 返回本地缓存 / 返回offlineDefaultCache / 报错 * * - 本地优先模式 localFirst:如果有本地缓存,则先返回本地缓存,如果没有则等待远程结果返回。每次调用先返回本地数据,如果远程拿到了结果,在用onData回调进行更新。进入离线模式之后,有本地缓存则返回缓存,没有本地缓存则看是否设置了offlineDefaultCache,有则返回,无则报错`new Error('App is offline and no local cache is found for localFirst func: ' + 云函数名称)` * * 在线模式: 返回本地缓存→访问远程→缓存结果 * * 离线模式: 返回本地缓存 / 返回offlineDefaultCache / 报错 * * - 远程优先模式 remoteFirst:先返回远程数据,然后每次都把远程数据缓存,一旦进入离线模式,直接返回本地数据,如果没有本地数据,看是否有offlineDefaultCache,有则返回,无则像上面那样报错`new Error('App is offline and no local cache is found for remoteFirst func: ' + 云函数名称)` * * 在线模式: 访问远程→缓存结果→返回远程结果 * * 离线模式: 返回本地缓存 / 返回offlineDefaultCache / 报错 * * 默认是remote */ mode?: IClientCacheMode; }; } export interface Listener { /** * 限流被触发的回调 */ onRateLimited?: CloudInvoke; } export declare function SetListener(p: Listener): void; /** * 客户端版本错误 */ export declare class ClientApiVersionError extends Error { constructor(message?: string); } export declare class SchemaError extends Error { validationError: Joi.ValidationError; constructor(error: Joi.ValidationError); } export declare class DebounceError extends Error { constructor(message?: string); } export declare class MissingVerify extends Error { constructor(message?: string); } export declare class VerifyError extends Error { constructor(message?: string); } export declare class RateLimitError extends AV.Cloud.Error { functionName: string; user: string; count: number; limit: number; timeUnit: string; code: number; constructor(params: { functionName: string; user: string; count: number; limit: number; timeUnit: string; code: number; }); } /** * 将函数加入云函数中,云函数名为 ``类名.函数名`` */ export declare function Cloud(params?: CloudOptions): (target: any, propertyKey: string, descriptor: PropertyDescriptor) => void; export interface Lock { /** * 尝试锁住某个key,成功返回true,失败返回false, 会在云函数结束后自动解锁 */ tryLock(key: string): Promise; /** * 主动解锁某个key */ unlock(key: string): Promise; } /** * 云函数参数的内置字段 */ export interface CloudParams { /** * 当前用户 */ currentUser?: AV.User; /** * 操作锁,用于避免不同请求中,同时对某个数据进行操作 */ lock?: Lock; /** * 原始的leancloud 的request内容 */ request?: AV.Cloud.CloudFunctionRequest; /** * 此请求强制不使用缓存 */ noCache?: boolean; /** * 调用云函数的管理员id,用于特殊操作,比如noCache操作 */ adminId?: string; /** * 调用云函数的sdk信息 */ _api?: SDKVersion; /** * 验证参数 */ cloudVerify?: SetVerifyParams; }