@cloudcome/utils-uni 1.34.0 → 1.35.1
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.
- package/README.md +71 -71
- package/dist/_helpers.cjs.map +1 -1
- package/dist/_helpers.mjs.map +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.mjs.map +1 -1
- package/dist/cloud/types.d.ts +2 -2
- package/dist/cloud.cjs.map +1 -1
- package/dist/cloud.mjs.map +1 -1
- package/dist/database/_db.class.d.ts +5 -4
- package/dist/database/types.d.ts +1 -1
- package/dist/database.cjs +40 -30
- package/dist/database.cjs.map +1 -1
- package/dist/database.mjs +40 -30
- package/dist/database.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +1 -1
- package/dist/weixin/notice.d.ts +79 -0
- package/dist/weixin/token.d.ts +49 -0
- package/dist/weixin.cjs +132 -0
- package/dist/weixin.cjs.map +1 -0
- package/dist/weixin.d.ts +2 -0
- package/dist/weixin.mjs +130 -0
- package/dist/weixin.mjs.map +1 -0
- package/package.json +15 -7
package/dist/cloud.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.cjs","names":[],"sources":["../src/cloud/error.ts","../src/cloud/module.ts","../src/cloud/respond.ts","../src/cloud/method.ts","../src/cloud/request.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport function createCloudObjectError(\n message: string,\n code?: number | string,\n) {\n return errorAssign(new Error(message), {\n errCode: code,\n errMsg: message,\n });\n}\n","import { objectOmit } from '@cloudcome/utils-core/object';\nimport { createCloudObjectError } from './error';\nimport type { CloudModuleOutput } from './types';\n\n/**\n * 解析云模块输出结果\n *\n * 该函数用于处理云模块的输出,如果输出中包含错误码,则抛出相应的错误;\n * 否则返回去除错误码和错误信息后的数据部分。\n *\n * @template O - 输出数据的类型\n * @param output - 云模块的输出结果,包含errCode、errMsg和数据部分\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 返回去除errCode和errMsg字段后的数据对象\n * @throws {CloudObjectError} 当output中存在errCode时抛出包含错误码和错误信息的异常\n *\n * @example\n * // 成功情况\n * const result = parseCloudModuleOutput({ value: 'success', errCode: 0, errMsg: '' });\n * // 返回: { value: 'success' }\n *\n * @example\n * // 错误情况\n * try {\n * parseCloudModuleOutput({ errCode: 404, errMsg: 'Not Found' });\n * } catch (error) {\n * // 抛出错误: CloudObjectError('Not Found', 404)\n * }\n */\nexport function parseCloudModuleOutput<O>(\n output: CloudModuleOutput<O>,\n fallbackErrorMessage = '',\n): Omit<O, 'errCode' | 'errMsg'> {\n if (output.errCode) {\n throw createCloudObjectError(\n output.errMsg || fallbackErrorMessage,\n output.errCode,\n );\n }\n return objectOmit(output, ['errCode', 'errMsg']);\n}\n","import { errorNormalize } from '@cloudcome/utils-core/error';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport type { UniError } from '@/_types';\nimport type { CloudMethodOutput } from './types';\n\n/**\n * 执行云对象方法并标准化响应格式\n *\n * @template O - 函数返回值的类型\n * @param fn - 要执行的异步函数\n * @param append - 要附加到响应中的额外数据\n * @returns 标准化的云对象响应对象\n *\n * @example\n * ```typescript\n * const result = await respondCloudMethod(async () => {\n * return await getData();\n * }, { extra: 'data' });\n * ```\n */\nexport async function respondCloudMethod<O>(\n fn: () => MaybePromise<O>,\n append?: AnyObject,\n): Promise<CloudMethodOutput<O>> {\n try {\n const data = await fn();\n\n return {\n errCode: 0,\n errMsg: '',\n data,\n ...append,\n };\n } catch (err) {\n console.error('respondCloudObject error');\n console.error(err);\n\n const err2 = errorNormalize(err as UniError);\n\n return {\n errCode: err2.errCode || -1,\n errMsg: err2.errMsg || err2.message || '',\n // @ts-expect-error\n data: null,\n ...append,\n };\n }\n}\n","import { objectDefaults } from '@cloudcome/utils-core/object';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport { versionCompare } from '@cloudcome/utils-core/version';\nimport type z from 'zod';\nimport type { ZodObject } from 'zod';\nimport { createCloudObjectError } from './error';\nimport { parseCloudModuleOutput } from './module';\nimport { respondCloudMethod } from './respond';\nimport type { CloudMethod, CloudObjectThis } from './types';\nimport type { UniIdCommonModule } from './uni-id';\n\ntype _CloudObjectThisAppendUser = {\n id: string;\n role: string[];\n permission: string[];\n isAdmin: boolean;\n};\n\ntype _CloudObjectThisAppend = {\n options: Required<CreateCloudObjectOptions>;\n user: _CloudObjectThisAppendUser;\n};\n\nexport type CloudObjectContext = CloudObjectThis & _CloudObjectThisAppend;\n\nexport type BuildCloudMethodCreatorOptions = {\n /**\n * UniId 通用模块\n * 用于处理用户身份验证和权限管理\n * 如果提供,将在云对象执行前验证用户身份\n */\n uniIdCommonModule?: UniIdCommonModule;\n\n /**\n * 需要用户登录态的错误码\n * @default 'uni-id-check-token-failed'\n */\n requiredUserErrCode?: number | string;\n\n /**\n * 需要用户登录态的错误消息\n * @default '需要登录后才能进行此操作'\n */\n requiredUserErrMsg?: string;\n\n /**\n * 仅允许本地环境运行的错误消息\n * @default '运行环境不匹配'\n */\n onlyLocalEnvErrMsg?: string;\n\n /**\n * 版本不匹配错误消息\n * @default '应用版本过低'\n */\n appVersionTooLowErrMsg?: string;\n\n /**\n * 应用版本过高错误消息\n * @default '应用版本过高'\n */\n appVersionTooHighErrMsg?: string;\n\n /**\n * 响应附加数据函数\n * 用于在云对象响应中添加额外的上下文信息\n * @param objectThis 云对象上下文\n * @returns 返回要附加到响应中的数据对象\n */\n respondAppend?: (objectThis: CloudObjectThis) => AnyObject;\n\n /**\n * 所有云对象执行前钩子函数\n * @param context 云对象上下文,包含用户信息、选项等\n */\n onBefore?: (context: CloudObjectContext) => MaybePromise<unknown>;\n};\n\nexport type CreateCloudObjectOptions = {\n /**\n * 是否需要用户登录态\n * @default false\n */\n requiredUser?: boolean;\n\n /**\n * 是否仅在本地环境运行\n * @default false\n */\n onlyLocalEnv?: boolean;\n\n /**\n * 最小支持版本\n */\n minVersion?: string;\n\n /**\n * 最大支持版本\n */\n maxVersion?: string;\n\n /**\n * 非响应模式,常用于钩子函数中,如 _before, _after 等,\n * 文档:https://doc.dcloud.net.cn/uniCloud/cloud-obj.html#before-and-after\n */\n noRespond?: boolean;\n};\n\n/**\n * 云对象方法创建器类型定义\n *\n * 用于定义云对象方法的创建函数类型,支持两种重载形式:\n * 1. 带输入验证的版本:接收schema、处理函数和选项\n * 2. 无输入参数的版本:仅接收处理函数和选项\n */\nexport type CreateCloudMethod = {\n /**\n * 带输入验证的云对象方法创建器\n * @template S - Zod验证模式类型\n * @template O - 返回值类型\n * @param schema - Zod验证模式,用于验证输入数据\n * @param fn - 业务逻辑处理函数,接收上下文和验证后的输入数据\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <S extends ZodObject, O>(\n schema: S,\n fn: (context: CloudObjectContext, input: z.infer<S>) => MaybePromise<O>,\n options?: CreateCloudObjectOptions,\n ): CloudMethod<z.infer<S>, O>;\n\n /**\n * 无输入参数的云对象方法创建器\n * @template O - 返回值类型\n * @param fn - 业务逻辑处理函数,仅接收上下文\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <O>(\n fn: (context: CloudObjectContext) => MaybePromise<O>,\n options?: CreateCloudObjectOptions,\n ): CloudMethod<void, O>;\n};\n\n/**\n * 构建云对象方法创建器\n *\n * 该函数用于创建云对象方法的工厂函数,支持输入验证、用户身份验证、环境检查等功能。\n * 返回的创建器函数可以根据不同的配置创建云对象方法。\n *\n * @param options 构建选项,用于配置云对象方法创建器的行为\n * @returns 返回一个云对象方法创建器函数\n *\n * @example\n * // 创建一个需要用户登录的云对象方法\n * const createMethod = buildCloudMethodCreator({ uniIdCommonModule });\n * const myMethod = createMethod(async (context) => {\n * return { message: 'Hello ' + context.user.id };\n * }, { requiredUser: true });\n */\nexport function buildCloudMethodCreator(\n options?: BuildCloudMethodCreatorOptions,\n) {\n const buildOptions = objectDefaults(options || {}, {\n requiredUserErrCode: 'uni-id-check-token-failed',\n requiredUserErrMsg: '需要登录后才能进行此操作',\n onlyLocalEnvErrMsg: '运行环境不匹配',\n appVersionTooLowErrMsg: '应用版本过低',\n appVersionTooHighErrMsg: '应用版本过高',\n respondAppend: () => ({}),\n onBefore: () => {},\n }) as Required<BuildCloudMethodCreatorOptions>;\n\n // @ts-expect-error\n const createCloudMethod: CreateCloudMethod = (arg0, arg1, arg2) => {\n // 确定选项来源:如果arg0是函数,则选项在arg1;否则在arg2\n const optionsSource = (isFunction(arg0) ? arg1 : arg2) as\n | CreateCloudObjectOptions\n | undefined;\n\n // 设置默认选项值\n const createOptions = objectDefaults(optionsSource || {}, {\n requiredUser: false,\n onlyLocalEnv: false,\n }) as Required<CreateCloudObjectOptions>;\n\n return async function (input) {\n const cloudMethod = async () => {\n const { runtimeEnv } = this.getCloudInfo();\n\n if (createOptions.onlyLocalEnv && runtimeEnv !== 'local') {\n throw createCloudObjectError(buildOptions.onlyLocalEnvErrMsg);\n }\n\n const { appVersion } = this.getClientInfo();\n\n if (\n createOptions.minVersion &&\n versionCompare(appVersion, createOptions.minVersion) < 0\n ) {\n throw createCloudObjectError(buildOptions.appVersionTooLowErrMsg);\n }\n\n if (\n createOptions.maxVersion &&\n versionCompare(appVersion, createOptions.maxVersion) > 0\n ) {\n throw createCloudObjectError(buildOptions.appVersionTooHighErrMsg);\n }\n\n // 构建附加的上下文信息,包括用户身份和权限信息\n const user = await _parseAppendUser(this, options?.uniIdCommonModule);\n const append: _CloudObjectThisAppend = {\n options: createOptions,\n user: user,\n };\n const context = Object.assign(this, append) as CloudObjectContext;\n\n // 如果需要用户登录态但用户未登录,则抛出错误\n if (createOptions.requiredUser && !user.id) {\n throw createCloudObjectError(\n buildOptions.requiredUserErrMsg,\n buildOptions.requiredUserErrCode,\n );\n }\n\n // 执行前钩子函数\n await buildOptions.onBefore(context);\n\n // 无入参函数调用\n if (isFunction(arg0)) {\n return await arg0(context);\n }\n\n // 有入参函数调用 - 验证输入数据\n const parsed = arg0.safeParse(input);\n\n // 输入验证失败处理\n if (!parsed.success) {\n console.log(parsed.error.issues);\n\n const issue0 = parsed.error?.issues?.[0];\n\n // 处理自定义验证错误\n if (issue0?.code === 'custom') throw issue0.message;\n throw new Error('请求数据不正确');\n }\n\n // 执行业务逻辑函数,传入上下文和验证后的数据\n return await arg1(context, parsed.data);\n };\n\n // 如果设置了非响应模式,则直接执行方法,不返回响应\n if (createOptions.noRespond) {\n return await cloudMethod();\n }\n\n // 处理云对象方法响应逻辑,包括错误捕获和统一响应格式\n return await respondCloudMethod(\n cloudMethod,\n buildOptions.respondAppend(this),\n );\n };\n };\n\n return createCloudMethod;\n}\n\n/**\n * 解析并附加用户信息到云对象上下文\n *\n * 该函数用于验证用户身份并获取用户权限信息,将结果附加到云对象上下文中的user字段\n * 如果未提供uniIdCommonModule或验证失败,则返回默认的空用户信息\n *\n * @param objectThis 云对象上下文,包含客户端信息和token等\n * @param uniIdCommonModule 可选的UniId通用模块实例,用于验证用户token\n * @returns 返回包含用户ID、角色、权限等信息的对象\n *\n * @example\n * // 成功验证用户身份\n * const user = await _parseAppendUser(this, uniIdModule);\n * // 返回: { id: 'user123', role: ['user'], permission: ['read'], isAdmin: false }\n *\n * @example\n * // 验证失败或未提供模块\n * const user = await _parseAppendUser(this);\n * // 返回: { id: '', role: [], permission: [], isAdmin: false }\n */\nasync function _parseAppendUser(\n objectThis: CloudObjectThis,\n uniIdCommonModule?: UniIdCommonModule,\n): Promise<_CloudObjectThisAppendUser> {\n const appendUser: _CloudObjectThisAppendUser = {\n id: '',\n role: [],\n permission: [],\n isAdmin: false,\n };\n\n if (!uniIdCommonModule) return appendUser;\n\n const uic = uniIdCommonModule.createInstance({\n clientInfo: objectThis.getClientInfo(),\n });\n\n // 验证用户token,忽略验证过程中的错误\n const [_err1, user] = await tryFlatten(\n uic.checkToken(objectThis.getUniIdToken() || ''),\n );\n if (!user) return appendUser;\n\n // 解析验证结果,忽略解析过程中的错误\n const [_err2, userData] = tryFlatten(() => parseCloudModuleOutput(user));\n if (!userData) return appendUser;\n\n appendUser.id = userData.uid || '';\n appendUser.role = userData.role || [];\n appendUser.permission = userData.permission || [];\n appendUser.isAdmin =\n appendUser.role.includes('admin') && appendUser.permission.length === 0;\n\n return appendUser;\n}\n","import { qsStringify } from '@cloudcome/utils-core/qs';\nimport type { AnyObject } from '@cloudcome/utils-core/types';\n\n/**\n * HTTP 请求配置选项\n */\nexport type RequestOptions = {\n /**\n * 请求 URL 地址\n */\n url: string;\n\n /**\n * URL 查询参数,会自动拼接到 url 后面\n */\n query?: Record<string, string>;\n\n /**\n * HTTP 请求方法\n * @default 'GET'\n */\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS';\n\n /**\n * 请求头\n */\n headers?: Record<string, string>;\n\n /**\n * 请求体数据\n */\n data?: AnyObject;\n\n /**\n * 返回数据格式\n * @default 'json'\n */\n dataType?: string;\n\n /**\n * 请求内容类型\n * - 'json': application/json\n * - 'form': application/x-www-form-urlencoded\n * @default 'json'\n */\n contentType?: string;\n\n /**\n * 请求超时时间,单位毫秒\n * @default 10000\n */\n timeout?: number;\n};\n\n/**\n * 发起 HTTP 请求\n *\n * 基于 uniCloud.httpclient 发起 HTTP 请求,支持 GET、POST、PUT、DELETE 等方法。\n * 查询参数会自动通过 qsStringify 拼接到 URL 上。\n *\n * @template T - 响应数据的类型\n * @param options 请求配置选项\n * @returns 包含 data、status、headers 的响应对象\n *\n * @example\n * ```ts\n * // GET 请求\n * const res = await request<{ name: string }>({\n * url: 'https://api.example.com/users/1',\n * })\n * console.log(res.data) // { name: 'Alice' }\n * console.log(res.status) // 200\n *\n * // POST 请求\n * const res = await request<{ id: string }>({\n * url: 'https://api.example.com/users',\n * method: 'POST',\n * data: { name: 'Alice', age: 25 },\n * })\n *\n * // 带查询参数\n * const res = await request<{ list: any[] }>({\n * url: 'https://api.example.com/users',\n * query: { page: '1', size: '10' },\n * })\n * ```\n */\nexport async function request<T>(options: RequestOptions) {\n const {\n url,\n query = {},\n method = 'GET',\n headers = {},\n data,\n dataType = 'json',\n contentType = 'json',\n timeout = 10000,\n } = options;\n\n const fullUrl = `${url}?${qsStringify(query)}`;\n\n // 使用uniCloud.httpclient发起请求\n // @ts-expect-error: uniCloud类型定义中可能缺少httpclient属性\n const res = await uniCloud.httpclient.request(fullUrl, {\n method,\n headers,\n data,\n dataType,\n contentType,\n timeout,\n });\n\n return res as { data: T; status: number; headers: Record<string, string> };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cloud.cjs","names":[],"sources":["../src/cloud/error.ts","../src/cloud/module.ts","../src/cloud/respond.ts","../src/cloud/method.ts","../src/cloud/request.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport function createCloudObjectError(message: string, code?: number | string) {\n return errorAssign(new Error(message), {\n errCode: code,\n errMsg: message,\n });\n}\n","import { objectOmit } from '@cloudcome/utils-core/object';\nimport { createCloudObjectError } from './error';\nimport type { CloudModuleOutput } from './types';\n\n/**\n * 解析云模块输出结果\n *\n * 该函数用于处理云模块的输出,如果输出中包含错误码,则抛出相应的错误;\n * 否则返回去除错误码和错误信息后的数据部分。\n *\n * @template O - 输出数据的类型\n * @param output - 云模块的输出结果,包含errCode、errMsg和数据部分\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 返回去除errCode和errMsg字段后的数据对象\n * @throws {CloudObjectError} 当output中存在errCode时抛出包含错误码和错误信息的异常\n *\n * @example\n * // 成功情况\n * const result = parseCloudModuleOutput({ value: 'success', errCode: 0, errMsg: '' });\n * // 返回: { value: 'success' }\n *\n * @example\n * // 错误情况\n * try {\n * parseCloudModuleOutput({ errCode: 404, errMsg: 'Not Found' });\n * } catch (error) {\n * // 抛出错误: CloudObjectError('Not Found', 404)\n * }\n */\nexport function parseCloudModuleOutput<O>(\n output: CloudModuleOutput<O>,\n fallbackErrorMessage = '',\n): Omit<O, 'errCode' | 'errMsg'> {\n if (output.errCode) {\n throw createCloudObjectError(output.errMsg || fallbackErrorMessage, output.errCode);\n }\n return objectOmit(output, ['errCode', 'errMsg']);\n}\n","import { errorNormalize } from '@cloudcome/utils-core/error';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport type { UniError } from '@/_types';\nimport type { CloudMethodOutput } from './types';\n\n/**\n * 执行云对象方法并标准化响应格式\n *\n * @template O - 函数返回值的类型\n * @param fn - 要执行的异步函数\n * @param append - 要附加到响应中的额外数据\n * @returns 标准化的云对象响应对象\n *\n * @example\n * ```typescript\n * const result = await respondCloudMethod(async () => {\n * return await getData();\n * }, { extra: 'data' });\n * ```\n */\nexport async function respondCloudMethod<O>(\n fn: () => MaybePromise<O>,\n append?: AnyObject,\n): Promise<CloudMethodOutput<O>> {\n try {\n const data = await fn();\n\n return {\n errCode: 0,\n errMsg: '',\n data,\n ...append,\n };\n } catch (err) {\n console.error('respondCloudObject error');\n console.error(err);\n\n const err2 = errorNormalize(err as UniError);\n\n return {\n errCode: err2.errCode || -1,\n errMsg: err2.errMsg || err2.message || '',\n // @ts-expect-error\n data: null,\n ...append,\n };\n }\n}\n","import { objectDefaults } from '@cloudcome/utils-core/object';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport { versionCompare } from '@cloudcome/utils-core/version';\nimport type z from 'zod';\nimport type { ZodObject } from 'zod';\nimport { createCloudObjectError } from './error';\nimport { parseCloudModuleOutput } from './module';\nimport { respondCloudMethod } from './respond';\nimport type { CloudMethod, CloudObjectThis } from './types';\nimport type { UniIdCommonModule } from './uni-id';\n\ntype _CloudObjectThisAppendUser = {\n id: string;\n role: string[];\n permission: string[];\n isAdmin: boolean;\n};\n\ntype _CloudObjectThisAppend = {\n options: Required<CreateCloudObjectOptions>;\n user: _CloudObjectThisAppendUser;\n};\n\nexport type CloudObjectContext = CloudObjectThis & _CloudObjectThisAppend;\n\nexport type BuildCloudMethodCreatorOptions = {\n /**\n * UniId 通用模块\n * 用于处理用户身份验证和权限管理\n * 如果提供,将在云对象执行前验证用户身份\n */\n uniIdCommonModule?: UniIdCommonModule;\n\n /**\n * 需要用户登录态的错误码\n * @default 'uni-id-check-token-failed'\n */\n requiredUserErrCode?: number | string;\n\n /**\n * 需要用户登录态的错误消息\n * @default '需要登录后才能进行此操作'\n */\n requiredUserErrMsg?: string;\n\n /**\n * 仅允许本地环境运行的错误消息\n * @default '运行环境不匹配'\n */\n onlyLocalEnvErrMsg?: string;\n\n /**\n * 版本不匹配错误消息\n * @default '应用版本过低'\n */\n appVersionTooLowErrMsg?: string;\n\n /**\n * 应用版本过高错误消息\n * @default '应用版本过高'\n */\n appVersionTooHighErrMsg?: string;\n\n /**\n * 响应附加数据函数\n * 用于在云对象响应中添加额外的上下文信息\n * @param objectThis 云对象上下文\n * @returns 返回要附加到响应中的数据对象\n */\n respondAppend?: (objectThis: CloudObjectThis) => AnyObject;\n\n /**\n * 所有云对象执行前钩子函数\n * @param context 云对象上下文,包含用户信息、选项等\n */\n onBefore?: (context: CloudObjectContext) => MaybePromise<unknown>;\n};\n\nexport type CreateCloudObjectOptions = {\n /**\n * 是否需要用户登录态\n * @default false\n */\n requiredUser?: boolean;\n\n /**\n * 是否仅在本地环境运行\n * @default false\n */\n onlyLocalEnv?: boolean;\n\n /**\n * 最小支持版本\n */\n minVersion?: string;\n\n /**\n * 最大支持版本\n */\n maxVersion?: string;\n\n /**\n * 非响应模式,常用于钩子函数中,如 _before, _after 等,\n * 文档:https://doc.dcloud.net.cn/uniCloud/cloud-obj.html#before-and-after\n */\n noRespond?: boolean;\n};\n\n/**\n * 云对象方法创建器类型定义\n *\n * 用于定义云对象方法的创建函数类型,支持两种重载形式:\n * 1. 带输入验证的版本:接收schema、处理函数和选项\n * 2. 无输入参数的版本:仅接收处理函数和选项\n */\nexport type CreateCloudMethod = {\n /**\n * 带输入验证的云对象方法创建器\n * @template S - Zod验证模式类型\n * @template O - 返回值类型\n * @param schema - Zod验证模式,用于验证输入数据\n * @param fn - 业务逻辑处理函数,接收上下文和验证后的输入数据\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <S extends ZodObject, O>(\n schema: S,\n fn: (context: CloudObjectContext, input: z.infer<S>) => MaybePromise<O>,\n options?: CreateCloudObjectOptions,\n ): CloudMethod<z.infer<S>, O>;\n\n /**\n * 无输入参数的云对象方法创建器\n * @template O - 返回值类型\n * @param fn - 业务逻辑处理函数,仅接收上下文\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <O>(fn: (context: CloudObjectContext) => MaybePromise<O>, options?: CreateCloudObjectOptions): CloudMethod<void, O>;\n};\n\n/**\n * 构建云对象方法创建器\n *\n * 该函数用于创建云对象方法的工厂函数,支持输入验证、用户身份验证、环境检查等功能。\n * 返回的创建器函数可以根据不同的配置创建云对象方法。\n *\n * @param options 构建选项,用于配置云对象方法创建器的行为\n * @returns 返回一个云对象方法创建器函数\n *\n * @example\n * // 创建一个需要用户登录的云对象方法\n * const createMethod = buildCloudMethodCreator({ uniIdCommonModule });\n * const myMethod = createMethod(async (context) => {\n * return { message: 'Hello ' + context.user.id };\n * }, { requiredUser: true });\n */\nexport function buildCloudMethodCreator(options?: BuildCloudMethodCreatorOptions) {\n const buildOptions = objectDefaults(options || {}, {\n requiredUserErrCode: 'uni-id-check-token-failed',\n requiredUserErrMsg: '需要登录后才能进行此操作',\n onlyLocalEnvErrMsg: '运行环境不匹配',\n appVersionTooLowErrMsg: '应用版本过低',\n appVersionTooHighErrMsg: '应用版本过高',\n respondAppend: () => ({}),\n onBefore: () => {},\n }) as Required<BuildCloudMethodCreatorOptions>;\n\n // @ts-expect-error\n const createCloudMethod: CreateCloudMethod = (arg0, arg1, arg2) => {\n // 确定选项来源:如果arg0是函数,则选项在arg1;否则在arg2\n const optionsSource = (isFunction(arg0) ? arg1 : arg2) as CreateCloudObjectOptions | undefined;\n\n // 设置默认选项值\n const createOptions = objectDefaults(optionsSource || {}, {\n requiredUser: false,\n onlyLocalEnv: false,\n }) as Required<CreateCloudObjectOptions>;\n\n return async function (input) {\n const cloudMethod = async () => {\n const { runtimeEnv } = this.getCloudInfo();\n\n if (createOptions.onlyLocalEnv && runtimeEnv !== 'local') {\n throw createCloudObjectError(buildOptions.onlyLocalEnvErrMsg);\n }\n\n const { appVersion } = this.getClientInfo();\n\n if (createOptions.minVersion && versionCompare(appVersion, createOptions.minVersion) < 0) {\n throw createCloudObjectError(buildOptions.appVersionTooLowErrMsg);\n }\n\n if (createOptions.maxVersion && versionCompare(appVersion, createOptions.maxVersion) > 0) {\n throw createCloudObjectError(buildOptions.appVersionTooHighErrMsg);\n }\n\n // 构建附加的上下文信息,包括用户身份和权限信息\n const user = await _parseAppendUser(this, options?.uniIdCommonModule);\n const append: _CloudObjectThisAppend = {\n options: createOptions,\n user: user,\n };\n const context = Object.assign(this, append) as CloudObjectContext;\n\n // 如果需要用户登录态但用户未登录,则抛出错误\n if (createOptions.requiredUser && !user.id) {\n throw createCloudObjectError(buildOptions.requiredUserErrMsg, buildOptions.requiredUserErrCode);\n }\n\n // 执行前钩子函数\n await buildOptions.onBefore(context);\n\n // 无入参函数调用\n if (isFunction(arg0)) {\n return await arg0(context);\n }\n\n // 有入参函数调用 - 验证输入数据\n const parsed = arg0.safeParse(input);\n\n // 输入验证失败处理\n if (!parsed.success) {\n console.log(parsed.error.issues);\n\n const issue0 = parsed.error?.issues?.[0];\n\n // 处理自定义验证错误\n if (issue0?.code === 'custom') throw issue0.message;\n throw new Error('请求数据不正确');\n }\n\n // 执行业务逻辑函数,传入上下文和验证后的数据\n return await arg1(context, parsed.data);\n };\n\n // 如果设置了非响应模式,则直接执行方法,不返回响应\n if (createOptions.noRespond) {\n return await cloudMethod();\n }\n\n // 处理云对象方法响应逻辑,包括错误捕获和统一响应格式\n return await respondCloudMethod(cloudMethod, buildOptions.respondAppend(this));\n };\n };\n\n return createCloudMethod;\n}\n\n/**\n * 解析并附加用户信息到云对象上下文\n *\n * 该函数用于验证用户身份并获取用户权限信息,将结果附加到云对象上下文中的user字段\n * 如果未提供uniIdCommonModule或验证失败,则返回默认的空用户信息\n *\n * @param objectThis 云对象上下文,包含客户端信息和token等\n * @param uniIdCommonModule 可选的UniId通用模块实例,用于验证用户token\n * @returns 返回包含用户ID、角色、权限等信息的对象\n *\n * @example\n * // 成功验证用户身份\n * const user = await _parseAppendUser(this, uniIdModule);\n * // 返回: { id: 'user123', role: ['user'], permission: ['read'], isAdmin: false }\n *\n * @example\n * // 验证失败或未提供模块\n * const user = await _parseAppendUser(this);\n * // 返回: { id: '', role: [], permission: [], isAdmin: false }\n */\nasync function _parseAppendUser(\n objectThis: CloudObjectThis,\n uniIdCommonModule?: UniIdCommonModule,\n): Promise<_CloudObjectThisAppendUser> {\n const appendUser: _CloudObjectThisAppendUser = {\n id: '',\n role: [],\n permission: [],\n isAdmin: false,\n };\n\n if (!uniIdCommonModule) return appendUser;\n\n const uic = uniIdCommonModule.createInstance({\n clientInfo: objectThis.getClientInfo(),\n });\n\n // 验证用户token,忽略验证过程中的错误\n const [_err1, user] = await tryFlatten(uic.checkToken(objectThis.getUniIdToken() || ''));\n if (!user) return appendUser;\n\n // 解析验证结果,忽略解析过程中的错误\n const [_err2, userData] = tryFlatten(() => parseCloudModuleOutput(user));\n if (!userData) return appendUser;\n\n appendUser.id = userData.uid || '';\n appendUser.role = userData.role || [];\n appendUser.permission = userData.permission || [];\n appendUser.isAdmin = appendUser.role.includes('admin') && appendUser.permission.length === 0;\n\n return appendUser;\n}\n","import { qsStringify } from '@cloudcome/utils-core/qs';\nimport type { AnyObject } from '@cloudcome/utils-core/types';\n\n/**\n * HTTP 请求配置选项\n */\nexport type RequestOptions = {\n /**\n * 请求 URL 地址\n */\n url: string;\n\n /**\n * URL 查询参数,会自动拼接到 url 后面\n */\n query?: Record<string, string>;\n\n /**\n * HTTP 请求方法\n * @default 'GET'\n */\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS';\n\n /**\n * 请求头\n */\n headers?: Record<string, string>;\n\n /**\n * 请求体数据\n */\n data?: AnyObject;\n\n /**\n * 返回数据格式\n * @default 'json'\n */\n dataType?: string;\n\n /**\n * 请求内容类型\n * - 'json': application/json\n * - 'form': application/x-www-form-urlencoded\n * @default 'json'\n */\n contentType?: string;\n\n /**\n * 请求超时时间,单位毫秒\n * @default 10000\n */\n timeout?: number;\n};\n\n/**\n * 发起 HTTP 请求\n *\n * 基于 uniCloud.httpclient 发起 HTTP 请求,支持 GET、POST、PUT、DELETE 等方法。\n * 查询参数会自动通过 qsStringify 拼接到 URL 上。\n *\n * @template T - 响应数据的类型\n * @param options 请求配置选项\n * @returns 包含 data、status、headers 的响应对象\n *\n * @example\n * ```ts\n * // GET 请求\n * const res = await request<{ name: string }>({\n * url: 'https://api.example.com/users/1',\n * })\n * console.log(res.data) // { name: 'Alice' }\n * console.log(res.status) // 200\n *\n * // POST 请求\n * const res = await request<{ id: string }>({\n * url: 'https://api.example.com/users',\n * method: 'POST',\n * data: { name: 'Alice', age: 25 },\n * })\n *\n * // 带查询参数\n * const res = await request<{ list: any[] }>({\n * url: 'https://api.example.com/users',\n * query: { page: '1', size: '10' },\n * })\n * ```\n */\nexport async function request<T>(options: RequestOptions) {\n const {\n url,\n query = {},\n method = 'GET',\n headers = {},\n data,\n dataType = 'json',\n contentType = 'json',\n timeout = 10000,\n } = options;\n\n const fullUrl = `${url}?${qsStringify(query)}`;\n\n // 使用uniCloud.httpclient发起请求\n // @ts-expect-error: uniCloud类型定义中可能缺少httpclient属性\n const res = await uniCloud.httpclient.request(fullUrl, {\n method,\n headers,\n data,\n dataType,\n contentType,\n timeout,\n });\n\n return res as { data: T; status: number; headers: Record<string, string> };\n}\n"],"mappings":"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"}
|
package/dist/cloud.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cloud.mjs","names":[],"sources":["../src/cloud/error.ts","../src/cloud/module.ts","../src/cloud/respond.ts","../src/cloud/method.ts","../src/cloud/request.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport function createCloudObjectError(\n message: string,\n code?: number | string,\n) {\n return errorAssign(new Error(message), {\n errCode: code,\n errMsg: message,\n });\n}\n","import { objectOmit } from '@cloudcome/utils-core/object';\nimport { createCloudObjectError } from './error';\nimport type { CloudModuleOutput } from './types';\n\n/**\n * 解析云模块输出结果\n *\n * 该函数用于处理云模块的输出,如果输出中包含错误码,则抛出相应的错误;\n * 否则返回去除错误码和错误信息后的数据部分。\n *\n * @template O - 输出数据的类型\n * @param output - 云模块的输出结果,包含errCode、errMsg和数据部分\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 返回去除errCode和errMsg字段后的数据对象\n * @throws {CloudObjectError} 当output中存在errCode时抛出包含错误码和错误信息的异常\n *\n * @example\n * // 成功情况\n * const result = parseCloudModuleOutput({ value: 'success', errCode: 0, errMsg: '' });\n * // 返回: { value: 'success' }\n *\n * @example\n * // 错误情况\n * try {\n * parseCloudModuleOutput({ errCode: 404, errMsg: 'Not Found' });\n * } catch (error) {\n * // 抛出错误: CloudObjectError('Not Found', 404)\n * }\n */\nexport function parseCloudModuleOutput<O>(\n output: CloudModuleOutput<O>,\n fallbackErrorMessage = '',\n): Omit<O, 'errCode' | 'errMsg'> {\n if (output.errCode) {\n throw createCloudObjectError(\n output.errMsg || fallbackErrorMessage,\n output.errCode,\n );\n }\n return objectOmit(output, ['errCode', 'errMsg']);\n}\n","import { errorNormalize } from '@cloudcome/utils-core/error';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport type { UniError } from '@/_types';\nimport type { CloudMethodOutput } from './types';\n\n/**\n * 执行云对象方法并标准化响应格式\n *\n * @template O - 函数返回值的类型\n * @param fn - 要执行的异步函数\n * @param append - 要附加到响应中的额外数据\n * @returns 标准化的云对象响应对象\n *\n * @example\n * ```typescript\n * const result = await respondCloudMethod(async () => {\n * return await getData();\n * }, { extra: 'data' });\n * ```\n */\nexport async function respondCloudMethod<O>(\n fn: () => MaybePromise<O>,\n append?: AnyObject,\n): Promise<CloudMethodOutput<O>> {\n try {\n const data = await fn();\n\n return {\n errCode: 0,\n errMsg: '',\n data,\n ...append,\n };\n } catch (err) {\n console.error('respondCloudObject error');\n console.error(err);\n\n const err2 = errorNormalize(err as UniError);\n\n return {\n errCode: err2.errCode || -1,\n errMsg: err2.errMsg || err2.message || '',\n // @ts-expect-error\n data: null,\n ...append,\n };\n }\n}\n","import { objectDefaults } from '@cloudcome/utils-core/object';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport { versionCompare } from '@cloudcome/utils-core/version';\nimport type z from 'zod';\nimport type { ZodObject } from 'zod';\nimport { createCloudObjectError } from './error';\nimport { parseCloudModuleOutput } from './module';\nimport { respondCloudMethod } from './respond';\nimport type { CloudMethod, CloudObjectThis } from './types';\nimport type { UniIdCommonModule } from './uni-id';\n\ntype _CloudObjectThisAppendUser = {\n id: string;\n role: string[];\n permission: string[];\n isAdmin: boolean;\n};\n\ntype _CloudObjectThisAppend = {\n options: Required<CreateCloudObjectOptions>;\n user: _CloudObjectThisAppendUser;\n};\n\nexport type CloudObjectContext = CloudObjectThis & _CloudObjectThisAppend;\n\nexport type BuildCloudMethodCreatorOptions = {\n /**\n * UniId 通用模块\n * 用于处理用户身份验证和权限管理\n * 如果提供,将在云对象执行前验证用户身份\n */\n uniIdCommonModule?: UniIdCommonModule;\n\n /**\n * 需要用户登录态的错误码\n * @default 'uni-id-check-token-failed'\n */\n requiredUserErrCode?: number | string;\n\n /**\n * 需要用户登录态的错误消息\n * @default '需要登录后才能进行此操作'\n */\n requiredUserErrMsg?: string;\n\n /**\n * 仅允许本地环境运行的错误消息\n * @default '运行环境不匹配'\n */\n onlyLocalEnvErrMsg?: string;\n\n /**\n * 版本不匹配错误消息\n * @default '应用版本过低'\n */\n appVersionTooLowErrMsg?: string;\n\n /**\n * 应用版本过高错误消息\n * @default '应用版本过高'\n */\n appVersionTooHighErrMsg?: string;\n\n /**\n * 响应附加数据函数\n * 用于在云对象响应中添加额外的上下文信息\n * @param objectThis 云对象上下文\n * @returns 返回要附加到响应中的数据对象\n */\n respondAppend?: (objectThis: CloudObjectThis) => AnyObject;\n\n /**\n * 所有云对象执行前钩子函数\n * @param context 云对象上下文,包含用户信息、选项等\n */\n onBefore?: (context: CloudObjectContext) => MaybePromise<unknown>;\n};\n\nexport type CreateCloudObjectOptions = {\n /**\n * 是否需要用户登录态\n * @default false\n */\n requiredUser?: boolean;\n\n /**\n * 是否仅在本地环境运行\n * @default false\n */\n onlyLocalEnv?: boolean;\n\n /**\n * 最小支持版本\n */\n minVersion?: string;\n\n /**\n * 最大支持版本\n */\n maxVersion?: string;\n\n /**\n * 非响应模式,常用于钩子函数中,如 _before, _after 等,\n * 文档:https://doc.dcloud.net.cn/uniCloud/cloud-obj.html#before-and-after\n */\n noRespond?: boolean;\n};\n\n/**\n * 云对象方法创建器类型定义\n *\n * 用于定义云对象方法的创建函数类型,支持两种重载形式:\n * 1. 带输入验证的版本:接收schema、处理函数和选项\n * 2. 无输入参数的版本:仅接收处理函数和选项\n */\nexport type CreateCloudMethod = {\n /**\n * 带输入验证的云对象方法创建器\n * @template S - Zod验证模式类型\n * @template O - 返回值类型\n * @param schema - Zod验证模式,用于验证输入数据\n * @param fn - 业务逻辑处理函数,接收上下文和验证后的输入数据\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <S extends ZodObject, O>(\n schema: S,\n fn: (context: CloudObjectContext, input: z.infer<S>) => MaybePromise<O>,\n options?: CreateCloudObjectOptions,\n ): CloudMethod<z.infer<S>, O>;\n\n /**\n * 无输入参数的云对象方法创建器\n * @template O - 返回值类型\n * @param fn - 业务逻辑处理函数,仅接收上下文\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <O>(\n fn: (context: CloudObjectContext) => MaybePromise<O>,\n options?: CreateCloudObjectOptions,\n ): CloudMethod<void, O>;\n};\n\n/**\n * 构建云对象方法创建器\n *\n * 该函数用于创建云对象方法的工厂函数,支持输入验证、用户身份验证、环境检查等功能。\n * 返回的创建器函数可以根据不同的配置创建云对象方法。\n *\n * @param options 构建选项,用于配置云对象方法创建器的行为\n * @returns 返回一个云对象方法创建器函数\n *\n * @example\n * // 创建一个需要用户登录的云对象方法\n * const createMethod = buildCloudMethodCreator({ uniIdCommonModule });\n * const myMethod = createMethod(async (context) => {\n * return { message: 'Hello ' + context.user.id };\n * }, { requiredUser: true });\n */\nexport function buildCloudMethodCreator(\n options?: BuildCloudMethodCreatorOptions,\n) {\n const buildOptions = objectDefaults(options || {}, {\n requiredUserErrCode: 'uni-id-check-token-failed',\n requiredUserErrMsg: '需要登录后才能进行此操作',\n onlyLocalEnvErrMsg: '运行环境不匹配',\n appVersionTooLowErrMsg: '应用版本过低',\n appVersionTooHighErrMsg: '应用版本过高',\n respondAppend: () => ({}),\n onBefore: () => {},\n }) as Required<BuildCloudMethodCreatorOptions>;\n\n // @ts-expect-error\n const createCloudMethod: CreateCloudMethod = (arg0, arg1, arg2) => {\n // 确定选项来源:如果arg0是函数,则选项在arg1;否则在arg2\n const optionsSource = (isFunction(arg0) ? arg1 : arg2) as\n | CreateCloudObjectOptions\n | undefined;\n\n // 设置默认选项值\n const createOptions = objectDefaults(optionsSource || {}, {\n requiredUser: false,\n onlyLocalEnv: false,\n }) as Required<CreateCloudObjectOptions>;\n\n return async function (input) {\n const cloudMethod = async () => {\n const { runtimeEnv } = this.getCloudInfo();\n\n if (createOptions.onlyLocalEnv && runtimeEnv !== 'local') {\n throw createCloudObjectError(buildOptions.onlyLocalEnvErrMsg);\n }\n\n const { appVersion } = this.getClientInfo();\n\n if (\n createOptions.minVersion &&\n versionCompare(appVersion, createOptions.minVersion) < 0\n ) {\n throw createCloudObjectError(buildOptions.appVersionTooLowErrMsg);\n }\n\n if (\n createOptions.maxVersion &&\n versionCompare(appVersion, createOptions.maxVersion) > 0\n ) {\n throw createCloudObjectError(buildOptions.appVersionTooHighErrMsg);\n }\n\n // 构建附加的上下文信息,包括用户身份和权限信息\n const user = await _parseAppendUser(this, options?.uniIdCommonModule);\n const append: _CloudObjectThisAppend = {\n options: createOptions,\n user: user,\n };\n const context = Object.assign(this, append) as CloudObjectContext;\n\n // 如果需要用户登录态但用户未登录,则抛出错误\n if (createOptions.requiredUser && !user.id) {\n throw createCloudObjectError(\n buildOptions.requiredUserErrMsg,\n buildOptions.requiredUserErrCode,\n );\n }\n\n // 执行前钩子函数\n await buildOptions.onBefore(context);\n\n // 无入参函数调用\n if (isFunction(arg0)) {\n return await arg0(context);\n }\n\n // 有入参函数调用 - 验证输入数据\n const parsed = arg0.safeParse(input);\n\n // 输入验证失败处理\n if (!parsed.success) {\n console.log(parsed.error.issues);\n\n const issue0 = parsed.error?.issues?.[0];\n\n // 处理自定义验证错误\n if (issue0?.code === 'custom') throw issue0.message;\n throw new Error('请求数据不正确');\n }\n\n // 执行业务逻辑函数,传入上下文和验证后的数据\n return await arg1(context, parsed.data);\n };\n\n // 如果设置了非响应模式,则直接执行方法,不返回响应\n if (createOptions.noRespond) {\n return await cloudMethod();\n }\n\n // 处理云对象方法响应逻辑,包括错误捕获和统一响应格式\n return await respondCloudMethod(\n cloudMethod,\n buildOptions.respondAppend(this),\n );\n };\n };\n\n return createCloudMethod;\n}\n\n/**\n * 解析并附加用户信息到云对象上下文\n *\n * 该函数用于验证用户身份并获取用户权限信息,将结果附加到云对象上下文中的user字段\n * 如果未提供uniIdCommonModule或验证失败,则返回默认的空用户信息\n *\n * @param objectThis 云对象上下文,包含客户端信息和token等\n * @param uniIdCommonModule 可选的UniId通用模块实例,用于验证用户token\n * @returns 返回包含用户ID、角色、权限等信息的对象\n *\n * @example\n * // 成功验证用户身份\n * const user = await _parseAppendUser(this, uniIdModule);\n * // 返回: { id: 'user123', role: ['user'], permission: ['read'], isAdmin: false }\n *\n * @example\n * // 验证失败或未提供模块\n * const user = await _parseAppendUser(this);\n * // 返回: { id: '', role: [], permission: [], isAdmin: false }\n */\nasync function _parseAppendUser(\n objectThis: CloudObjectThis,\n uniIdCommonModule?: UniIdCommonModule,\n): Promise<_CloudObjectThisAppendUser> {\n const appendUser: _CloudObjectThisAppendUser = {\n id: '',\n role: [],\n permission: [],\n isAdmin: false,\n };\n\n if (!uniIdCommonModule) return appendUser;\n\n const uic = uniIdCommonModule.createInstance({\n clientInfo: objectThis.getClientInfo(),\n });\n\n // 验证用户token,忽略验证过程中的错误\n const [_err1, user] = await tryFlatten(\n uic.checkToken(objectThis.getUniIdToken() || ''),\n );\n if (!user) return appendUser;\n\n // 解析验证结果,忽略解析过程中的错误\n const [_err2, userData] = tryFlatten(() => parseCloudModuleOutput(user));\n if (!userData) return appendUser;\n\n appendUser.id = userData.uid || '';\n appendUser.role = userData.role || [];\n appendUser.permission = userData.permission || [];\n appendUser.isAdmin =\n appendUser.role.includes('admin') && appendUser.permission.length === 0;\n\n return appendUser;\n}\n","import { qsStringify } from '@cloudcome/utils-core/qs';\nimport type { AnyObject } from '@cloudcome/utils-core/types';\n\n/**\n * HTTP 请求配置选项\n */\nexport type RequestOptions = {\n /**\n * 请求 URL 地址\n */\n url: string;\n\n /**\n * URL 查询参数,会自动拼接到 url 后面\n */\n query?: Record<string, string>;\n\n /**\n * HTTP 请求方法\n * @default 'GET'\n */\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS';\n\n /**\n * 请求头\n */\n headers?: Record<string, string>;\n\n /**\n * 请求体数据\n */\n data?: AnyObject;\n\n /**\n * 返回数据格式\n * @default 'json'\n */\n dataType?: string;\n\n /**\n * 请求内容类型\n * - 'json': application/json\n * - 'form': application/x-www-form-urlencoded\n * @default 'json'\n */\n contentType?: string;\n\n /**\n * 请求超时时间,单位毫秒\n * @default 10000\n */\n timeout?: number;\n};\n\n/**\n * 发起 HTTP 请求\n *\n * 基于 uniCloud.httpclient 发起 HTTP 请求,支持 GET、POST、PUT、DELETE 等方法。\n * 查询参数会自动通过 qsStringify 拼接到 URL 上。\n *\n * @template T - 响应数据的类型\n * @param options 请求配置选项\n * @returns 包含 data、status、headers 的响应对象\n *\n * @example\n * ```ts\n * // GET 请求\n * const res = await request<{ name: string }>({\n * url: 'https://api.example.com/users/1',\n * })\n * console.log(res.data) // { name: 'Alice' }\n * console.log(res.status) // 200\n *\n * // POST 请求\n * const res = await request<{ id: string }>({\n * url: 'https://api.example.com/users',\n * method: 'POST',\n * data: { name: 'Alice', age: 25 },\n * })\n *\n * // 带查询参数\n * const res = await request<{ list: any[] }>({\n * url: 'https://api.example.com/users',\n * query: { page: '1', size: '10' },\n * })\n * ```\n */\nexport async function request<T>(options: RequestOptions) {\n const {\n url,\n query = {},\n method = 'GET',\n headers = {},\n data,\n dataType = 'json',\n contentType = 'json',\n timeout = 10000,\n } = options;\n\n const fullUrl = `${url}?${qsStringify(query)}`;\n\n // 使用uniCloud.httpclient发起请求\n // @ts-expect-error: uniCloud类型定义中可能缺少httpclient属性\n const res = await uniCloud.httpclient.request(fullUrl, {\n method,\n headers,\n data,\n dataType,\n contentType,\n timeout,\n });\n\n return res as { data: T; status: number; headers: Record<string, string> };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"cloud.mjs","names":[],"sources":["../src/cloud/error.ts","../src/cloud/module.ts","../src/cloud/respond.ts","../src/cloud/method.ts","../src/cloud/request.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport function createCloudObjectError(message: string, code?: number | string) {\n return errorAssign(new Error(message), {\n errCode: code,\n errMsg: message,\n });\n}\n","import { objectOmit } from '@cloudcome/utils-core/object';\nimport { createCloudObjectError } from './error';\nimport type { CloudModuleOutput } from './types';\n\n/**\n * 解析云模块输出结果\n *\n * 该函数用于处理云模块的输出,如果输出中包含错误码,则抛出相应的错误;\n * 否则返回去除错误码和错误信息后的数据部分。\n *\n * @template O - 输出数据的类型\n * @param output - 云模块的输出结果,包含errCode、errMsg和数据部分\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 返回去除errCode和errMsg字段后的数据对象\n * @throws {CloudObjectError} 当output中存在errCode时抛出包含错误码和错误信息的异常\n *\n * @example\n * // 成功情况\n * const result = parseCloudModuleOutput({ value: 'success', errCode: 0, errMsg: '' });\n * // 返回: { value: 'success' }\n *\n * @example\n * // 错误情况\n * try {\n * parseCloudModuleOutput({ errCode: 404, errMsg: 'Not Found' });\n * } catch (error) {\n * // 抛出错误: CloudObjectError('Not Found', 404)\n * }\n */\nexport function parseCloudModuleOutput<O>(\n output: CloudModuleOutput<O>,\n fallbackErrorMessage = '',\n): Omit<O, 'errCode' | 'errMsg'> {\n if (output.errCode) {\n throw createCloudObjectError(output.errMsg || fallbackErrorMessage, output.errCode);\n }\n return objectOmit(output, ['errCode', 'errMsg']);\n}\n","import { errorNormalize } from '@cloudcome/utils-core/error';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport type { UniError } from '@/_types';\nimport type { CloudMethodOutput } from './types';\n\n/**\n * 执行云对象方法并标准化响应格式\n *\n * @template O - 函数返回值的类型\n * @param fn - 要执行的异步函数\n * @param append - 要附加到响应中的额外数据\n * @returns 标准化的云对象响应对象\n *\n * @example\n * ```typescript\n * const result = await respondCloudMethod(async () => {\n * return await getData();\n * }, { extra: 'data' });\n * ```\n */\nexport async function respondCloudMethod<O>(\n fn: () => MaybePromise<O>,\n append?: AnyObject,\n): Promise<CloudMethodOutput<O>> {\n try {\n const data = await fn();\n\n return {\n errCode: 0,\n errMsg: '',\n data,\n ...append,\n };\n } catch (err) {\n console.error('respondCloudObject error');\n console.error(err);\n\n const err2 = errorNormalize(err as UniError);\n\n return {\n errCode: err2.errCode || -1,\n errMsg: err2.errMsg || err2.message || '',\n // @ts-expect-error\n data: null,\n ...append,\n };\n }\n}\n","import { objectDefaults } from '@cloudcome/utils-core/object';\nimport { tryFlatten } from '@cloudcome/utils-core/try';\nimport { isFunction } from '@cloudcome/utils-core/type';\nimport type { MaybePromise } from '@cloudcome/utils-core/types';\nimport { versionCompare } from '@cloudcome/utils-core/version';\nimport type z from 'zod';\nimport type { ZodObject } from 'zod';\nimport { createCloudObjectError } from './error';\nimport { parseCloudModuleOutput } from './module';\nimport { respondCloudMethod } from './respond';\nimport type { CloudMethod, CloudObjectThis } from './types';\nimport type { UniIdCommonModule } from './uni-id';\n\ntype _CloudObjectThisAppendUser = {\n id: string;\n role: string[];\n permission: string[];\n isAdmin: boolean;\n};\n\ntype _CloudObjectThisAppend = {\n options: Required<CreateCloudObjectOptions>;\n user: _CloudObjectThisAppendUser;\n};\n\nexport type CloudObjectContext = CloudObjectThis & _CloudObjectThisAppend;\n\nexport type BuildCloudMethodCreatorOptions = {\n /**\n * UniId 通用模块\n * 用于处理用户身份验证和权限管理\n * 如果提供,将在云对象执行前验证用户身份\n */\n uniIdCommonModule?: UniIdCommonModule;\n\n /**\n * 需要用户登录态的错误码\n * @default 'uni-id-check-token-failed'\n */\n requiredUserErrCode?: number | string;\n\n /**\n * 需要用户登录态的错误消息\n * @default '需要登录后才能进行此操作'\n */\n requiredUserErrMsg?: string;\n\n /**\n * 仅允许本地环境运行的错误消息\n * @default '运行环境不匹配'\n */\n onlyLocalEnvErrMsg?: string;\n\n /**\n * 版本不匹配错误消息\n * @default '应用版本过低'\n */\n appVersionTooLowErrMsg?: string;\n\n /**\n * 应用版本过高错误消息\n * @default '应用版本过高'\n */\n appVersionTooHighErrMsg?: string;\n\n /**\n * 响应附加数据函数\n * 用于在云对象响应中添加额外的上下文信息\n * @param objectThis 云对象上下文\n * @returns 返回要附加到响应中的数据对象\n */\n respondAppend?: (objectThis: CloudObjectThis) => AnyObject;\n\n /**\n * 所有云对象执行前钩子函数\n * @param context 云对象上下文,包含用户信息、选项等\n */\n onBefore?: (context: CloudObjectContext) => MaybePromise<unknown>;\n};\n\nexport type CreateCloudObjectOptions = {\n /**\n * 是否需要用户登录态\n * @default false\n */\n requiredUser?: boolean;\n\n /**\n * 是否仅在本地环境运行\n * @default false\n */\n onlyLocalEnv?: boolean;\n\n /**\n * 最小支持版本\n */\n minVersion?: string;\n\n /**\n * 最大支持版本\n */\n maxVersion?: string;\n\n /**\n * 非响应模式,常用于钩子函数中,如 _before, _after 等,\n * 文档:https://doc.dcloud.net.cn/uniCloud/cloud-obj.html#before-and-after\n */\n noRespond?: boolean;\n};\n\n/**\n * 云对象方法创建器类型定义\n *\n * 用于定义云对象方法的创建函数类型,支持两种重载形式:\n * 1. 带输入验证的版本:接收schema、处理函数和选项\n * 2. 无输入参数的版本:仅接收处理函数和选项\n */\nexport type CreateCloudMethod = {\n /**\n * 带输入验证的云对象方法创建器\n * @template S - Zod验证模式类型\n * @template O - 返回值类型\n * @param schema - Zod验证模式,用于验证输入数据\n * @param fn - 业务逻辑处理函数,接收上下文和验证后的输入数据\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <S extends ZodObject, O>(\n schema: S,\n fn: (context: CloudObjectContext, input: z.infer<S>) => MaybePromise<O>,\n options?: CreateCloudObjectOptions,\n ): CloudMethod<z.infer<S>, O>;\n\n /**\n * 无输入参数的云对象方法创建器\n * @template O - 返回值类型\n * @param fn - 业务逻辑处理函数,仅接收上下文\n * @param options - 云对象创建选项\n * @returns 云对象方法函数\n */\n <O>(fn: (context: CloudObjectContext) => MaybePromise<O>, options?: CreateCloudObjectOptions): CloudMethod<void, O>;\n};\n\n/**\n * 构建云对象方法创建器\n *\n * 该函数用于创建云对象方法的工厂函数,支持输入验证、用户身份验证、环境检查等功能。\n * 返回的创建器函数可以根据不同的配置创建云对象方法。\n *\n * @param options 构建选项,用于配置云对象方法创建器的行为\n * @returns 返回一个云对象方法创建器函数\n *\n * @example\n * // 创建一个需要用户登录的云对象方法\n * const createMethod = buildCloudMethodCreator({ uniIdCommonModule });\n * const myMethod = createMethod(async (context) => {\n * return { message: 'Hello ' + context.user.id };\n * }, { requiredUser: true });\n */\nexport function buildCloudMethodCreator(options?: BuildCloudMethodCreatorOptions) {\n const buildOptions = objectDefaults(options || {}, {\n requiredUserErrCode: 'uni-id-check-token-failed',\n requiredUserErrMsg: '需要登录后才能进行此操作',\n onlyLocalEnvErrMsg: '运行环境不匹配',\n appVersionTooLowErrMsg: '应用版本过低',\n appVersionTooHighErrMsg: '应用版本过高',\n respondAppend: () => ({}),\n onBefore: () => {},\n }) as Required<BuildCloudMethodCreatorOptions>;\n\n // @ts-expect-error\n const createCloudMethod: CreateCloudMethod = (arg0, arg1, arg2) => {\n // 确定选项来源:如果arg0是函数,则选项在arg1;否则在arg2\n const optionsSource = (isFunction(arg0) ? arg1 : arg2) as CreateCloudObjectOptions | undefined;\n\n // 设置默认选项值\n const createOptions = objectDefaults(optionsSource || {}, {\n requiredUser: false,\n onlyLocalEnv: false,\n }) as Required<CreateCloudObjectOptions>;\n\n return async function (input) {\n const cloudMethod = async () => {\n const { runtimeEnv } = this.getCloudInfo();\n\n if (createOptions.onlyLocalEnv && runtimeEnv !== 'local') {\n throw createCloudObjectError(buildOptions.onlyLocalEnvErrMsg);\n }\n\n const { appVersion } = this.getClientInfo();\n\n if (createOptions.minVersion && versionCompare(appVersion, createOptions.minVersion) < 0) {\n throw createCloudObjectError(buildOptions.appVersionTooLowErrMsg);\n }\n\n if (createOptions.maxVersion && versionCompare(appVersion, createOptions.maxVersion) > 0) {\n throw createCloudObjectError(buildOptions.appVersionTooHighErrMsg);\n }\n\n // 构建附加的上下文信息,包括用户身份和权限信息\n const user = await _parseAppendUser(this, options?.uniIdCommonModule);\n const append: _CloudObjectThisAppend = {\n options: createOptions,\n user: user,\n };\n const context = Object.assign(this, append) as CloudObjectContext;\n\n // 如果需要用户登录态但用户未登录,则抛出错误\n if (createOptions.requiredUser && !user.id) {\n throw createCloudObjectError(buildOptions.requiredUserErrMsg, buildOptions.requiredUserErrCode);\n }\n\n // 执行前钩子函数\n await buildOptions.onBefore(context);\n\n // 无入参函数调用\n if (isFunction(arg0)) {\n return await arg0(context);\n }\n\n // 有入参函数调用 - 验证输入数据\n const parsed = arg0.safeParse(input);\n\n // 输入验证失败处理\n if (!parsed.success) {\n console.log(parsed.error.issues);\n\n const issue0 = parsed.error?.issues?.[0];\n\n // 处理自定义验证错误\n if (issue0?.code === 'custom') throw issue0.message;\n throw new Error('请求数据不正确');\n }\n\n // 执行业务逻辑函数,传入上下文和验证后的数据\n return await arg1(context, parsed.data);\n };\n\n // 如果设置了非响应模式,则直接执行方法,不返回响应\n if (createOptions.noRespond) {\n return await cloudMethod();\n }\n\n // 处理云对象方法响应逻辑,包括错误捕获和统一响应格式\n return await respondCloudMethod(cloudMethod, buildOptions.respondAppend(this));\n };\n };\n\n return createCloudMethod;\n}\n\n/**\n * 解析并附加用户信息到云对象上下文\n *\n * 该函数用于验证用户身份并获取用户权限信息,将结果附加到云对象上下文中的user字段\n * 如果未提供uniIdCommonModule或验证失败,则返回默认的空用户信息\n *\n * @param objectThis 云对象上下文,包含客户端信息和token等\n * @param uniIdCommonModule 可选的UniId通用模块实例,用于验证用户token\n * @returns 返回包含用户ID、角色、权限等信息的对象\n *\n * @example\n * // 成功验证用户身份\n * const user = await _parseAppendUser(this, uniIdModule);\n * // 返回: { id: 'user123', role: ['user'], permission: ['read'], isAdmin: false }\n *\n * @example\n * // 验证失败或未提供模块\n * const user = await _parseAppendUser(this);\n * // 返回: { id: '', role: [], permission: [], isAdmin: false }\n */\nasync function _parseAppendUser(\n objectThis: CloudObjectThis,\n uniIdCommonModule?: UniIdCommonModule,\n): Promise<_CloudObjectThisAppendUser> {\n const appendUser: _CloudObjectThisAppendUser = {\n id: '',\n role: [],\n permission: [],\n isAdmin: false,\n };\n\n if (!uniIdCommonModule) return appendUser;\n\n const uic = uniIdCommonModule.createInstance({\n clientInfo: objectThis.getClientInfo(),\n });\n\n // 验证用户token,忽略验证过程中的错误\n const [_err1, user] = await tryFlatten(uic.checkToken(objectThis.getUniIdToken() || ''));\n if (!user) return appendUser;\n\n // 解析验证结果,忽略解析过程中的错误\n const [_err2, userData] = tryFlatten(() => parseCloudModuleOutput(user));\n if (!userData) return appendUser;\n\n appendUser.id = userData.uid || '';\n appendUser.role = userData.role || [];\n appendUser.permission = userData.permission || [];\n appendUser.isAdmin = appendUser.role.includes('admin') && appendUser.permission.length === 0;\n\n return appendUser;\n}\n","import { qsStringify } from '@cloudcome/utils-core/qs';\nimport type { AnyObject } from '@cloudcome/utils-core/types';\n\n/**\n * HTTP 请求配置选项\n */\nexport type RequestOptions = {\n /**\n * 请求 URL 地址\n */\n url: string;\n\n /**\n * URL 查询参数,会自动拼接到 url 后面\n */\n query?: Record<string, string>;\n\n /**\n * HTTP 请求方法\n * @default 'GET'\n */\n method?: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'HEAD' | 'OPTIONS';\n\n /**\n * 请求头\n */\n headers?: Record<string, string>;\n\n /**\n * 请求体数据\n */\n data?: AnyObject;\n\n /**\n * 返回数据格式\n * @default 'json'\n */\n dataType?: string;\n\n /**\n * 请求内容类型\n * - 'json': application/json\n * - 'form': application/x-www-form-urlencoded\n * @default 'json'\n */\n contentType?: string;\n\n /**\n * 请求超时时间,单位毫秒\n * @default 10000\n */\n timeout?: number;\n};\n\n/**\n * 发起 HTTP 请求\n *\n * 基于 uniCloud.httpclient 发起 HTTP 请求,支持 GET、POST、PUT、DELETE 等方法。\n * 查询参数会自动通过 qsStringify 拼接到 URL 上。\n *\n * @template T - 响应数据的类型\n * @param options 请求配置选项\n * @returns 包含 data、status、headers 的响应对象\n *\n * @example\n * ```ts\n * // GET 请求\n * const res = await request<{ name: string }>({\n * url: 'https://api.example.com/users/1',\n * })\n * console.log(res.data) // { name: 'Alice' }\n * console.log(res.status) // 200\n *\n * // POST 请求\n * const res = await request<{ id: string }>({\n * url: 'https://api.example.com/users',\n * method: 'POST',\n * data: { name: 'Alice', age: 25 },\n * })\n *\n * // 带查询参数\n * const res = await request<{ list: any[] }>({\n * url: 'https://api.example.com/users',\n * query: { page: '1', size: '10' },\n * })\n * ```\n */\nexport async function request<T>(options: RequestOptions) {\n const {\n url,\n query = {},\n method = 'GET',\n headers = {},\n data,\n dataType = 'json',\n contentType = 'json',\n timeout = 10000,\n } = options;\n\n const fullUrl = `${url}?${qsStringify(query)}`;\n\n // 使用uniCloud.httpclient发起请求\n // @ts-expect-error: uniCloud类型定义中可能缺少httpclient属性\n const res = await uniCloud.httpclient.request(fullUrl, {\n method,\n headers,\n data,\n dataType,\n contentType,\n timeout,\n });\n\n return res as { data: T; status: number; headers: Record<string, string> };\n}\n"],"mappings":"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"}
|
|
@@ -58,11 +58,10 @@ export type DbLookup = DbLookupOptions<any, unknown, unknown, string, boolean> &
|
|
|
58
58
|
* @template W2 - 副表查询
|
|
59
59
|
*/
|
|
60
60
|
export declare class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject = {}, W2 extends AnyObject = {}> {
|
|
61
|
-
private _host;
|
|
62
61
|
/**
|
|
63
62
|
* 是否为事务环境
|
|
64
|
-
* -
|
|
65
|
-
* -
|
|
63
|
+
* - 更新条件只能是 id
|
|
64
|
+
* - 删除条件只能是 id
|
|
66
65
|
*/
|
|
67
66
|
private _isTransaction;
|
|
68
67
|
private _options;
|
|
@@ -81,11 +80,12 @@ export declare class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject =
|
|
|
81
80
|
get table(): string;
|
|
82
81
|
get options(): DbOptions;
|
|
83
82
|
get isTransaction(): boolean;
|
|
83
|
+
_createHost(withoutTransaction?: boolean): any;
|
|
84
84
|
/**
|
|
85
85
|
* 获取聚合操作实例
|
|
86
86
|
* @returns 聚合操作实例
|
|
87
87
|
*/
|
|
88
|
-
|
|
88
|
+
_createAggregate(): any;
|
|
89
89
|
private _hasWhere;
|
|
90
90
|
private _hasWhereId;
|
|
91
91
|
private _where;
|
|
@@ -144,6 +144,7 @@ export declare class Db<D1, S1 extends DbSelect<D1> = {}, D2 extends AnyObject =
|
|
|
144
144
|
get hasLookup(): boolean;
|
|
145
145
|
private _lookups;
|
|
146
146
|
lookup<FD1, FS1 extends DbSelect<FD1>, FD2 extends AnyObject, FW2 extends AnyObject, RL extends DbRelation, AS extends string, US extends boolean | undefined | void = undefined>(table: Db<FD1, FS1, FD2, FW2>, lookup: DbLookupOptions<RL, D1, FD1, AS, US>): Db<D1, S1, US extends true ? D2 : MergeIntersection<D2 & DbForeign<FD1, FS1, FD2, RL, AS>>, MergeIntersection<W2 & Partial<Record<AS, DbQueryCommand>>>>;
|
|
147
|
+
private _ending;
|
|
147
148
|
private _aggregated;
|
|
148
149
|
private _lookupAs;
|
|
149
150
|
private _endAggregate;
|
package/dist/database/types.d.ts
CHANGED
|
@@ -40,7 +40,7 @@ export type DbFieldsDefault<T> = {
|
|
|
40
40
|
* @template D - 字段选择类型
|
|
41
41
|
* @template V - 值类型
|
|
42
42
|
*/
|
|
43
|
-
type _OnlyFieldId<D, V> = IsOnlyProperty<D, '_id'> extends true ? '_id' extends keyof D ? D['_id'] extends V ? true : false : false : false;
|
|
43
|
+
type _OnlyFieldId<D, V> = IsOnlyProperty<D, '_id'> extends true ? ('_id' extends keyof D ? (D['_id'] extends V ? true : false) : false) : false;
|
|
44
44
|
/**
|
|
45
45
|
* 数据库字段处理类型
|
|
46
46
|
* @template D - 数据模型类型
|
package/dist/database.cjs
CHANGED
|
@@ -232,11 +232,10 @@ var gid = 0;
|
|
|
232
232
|
* @template W2 - 副表查询
|
|
233
233
|
*/
|
|
234
234
|
var Db = class Db {
|
|
235
|
-
_host;
|
|
236
235
|
/**
|
|
237
236
|
* 是否为事务环境
|
|
238
|
-
* -
|
|
239
|
-
* -
|
|
237
|
+
* - 更新条件只能是 id
|
|
238
|
+
* - 删除条件只能是 id
|
|
240
239
|
*/
|
|
241
240
|
_isTransaction = false;
|
|
242
241
|
_options;
|
|
@@ -247,7 +246,6 @@ var Db = class Db {
|
|
|
247
246
|
*/
|
|
248
247
|
constructor(options) {
|
|
249
248
|
this._options = options;
|
|
250
|
-
this._host = options._mockDatabase || options.transaction?.collection(options.table) || db0.collection(options.table);
|
|
251
249
|
this._isTransaction = !!options.transaction;
|
|
252
250
|
}
|
|
253
251
|
/**
|
|
@@ -270,12 +268,16 @@ var Db = class Db {
|
|
|
270
268
|
get isTransaction() {
|
|
271
269
|
return this._isTransaction;
|
|
272
270
|
}
|
|
271
|
+
_createHost(withoutTransaction) {
|
|
272
|
+
const options = this._options;
|
|
273
|
+
return options._mockDatabase || (withoutTransaction ? null : options.transaction?.collection(options.table) || db0.collection(options.table));
|
|
274
|
+
}
|
|
273
275
|
/**
|
|
274
276
|
* 获取聚合操作实例
|
|
275
277
|
* @returns 聚合操作实例
|
|
276
278
|
*/
|
|
277
|
-
|
|
278
|
-
return this.
|
|
279
|
+
_createAggregate() {
|
|
280
|
+
return this._createHost().aggregate();
|
|
279
281
|
}
|
|
280
282
|
_hasWhere = void 0;
|
|
281
283
|
_hasWhereId = void 0;
|
|
@@ -380,10 +382,13 @@ var Db = class Db {
|
|
|
380
382
|
});
|
|
381
383
|
return this;
|
|
382
384
|
}
|
|
385
|
+
_ending = false;
|
|
383
386
|
_aggregated = false;
|
|
384
387
|
_lookupAs = {};
|
|
385
388
|
_endAggregate(aggRef) {
|
|
386
389
|
if (this._aggregated) throw new Error(`相同的数据表实例(${this.table})不能重复使用`);
|
|
390
|
+
if (this._ending) throw new Error(`相同的数据表实例(${this.table})不能重复使用`);
|
|
391
|
+
this._ending = true;
|
|
387
392
|
this._aggregated = true;
|
|
388
393
|
let returnAggRef = aggRef;
|
|
389
394
|
let _hasAggSelect = 0;
|
|
@@ -426,16 +431,20 @@ var Db = class Db {
|
|
|
426
431
|
else if (hasAggUnselect) returnAggRef = returnAggRef.project(aggUnselect);
|
|
427
432
|
return returnAggRef;
|
|
428
433
|
}
|
|
429
|
-
_endHost(action) {
|
|
430
|
-
if (this.
|
|
431
|
-
|
|
432
|
-
|
|
434
|
+
_endHost(host, action) {
|
|
435
|
+
if (this._ending) throw new Error(`相同的数据表实例(${this.table})不能重复使用`);
|
|
436
|
+
this._ending = true;
|
|
437
|
+
let hostRef = host;
|
|
438
|
+
if (this._hasWhere) if ((action === "update" || action === "remove") && this._isTransaction) hostRef = hostRef.doc(this._where._id);
|
|
439
|
+
else hostRef = hostRef.where(_mapCommandRaw(this._where));
|
|
440
|
+
if (this._hasSelect) hostRef = hostRef.field(_mergeSelect(this._select, this._order));
|
|
433
441
|
if (this._hasOrder) (0, _cloudcome_utils_core_object.objectEach)(this._order, (val, key) => {
|
|
434
|
-
|
|
442
|
+
hostRef = hostRef.orderBy(key, val);
|
|
435
443
|
});
|
|
436
|
-
if (this._hasSkip)
|
|
437
|
-
if (this._hasLimit && action === "query")
|
|
438
|
-
else if (this._hasWhereId && action === "query")
|
|
444
|
+
if (this._hasSkip) hostRef = hostRef.skip(this._skip);
|
|
445
|
+
if (this._hasLimit && action === "query") hostRef = hostRef.limit(this._limit);
|
|
446
|
+
else if (this._hasWhereId && action === "query") hostRef = hostRef.limit(1);
|
|
447
|
+
return hostRef;
|
|
439
448
|
}
|
|
440
449
|
/**
|
|
441
450
|
* 执行查询操作
|
|
@@ -443,15 +452,15 @@ var Db = class Db {
|
|
|
443
452
|
*/
|
|
444
453
|
async many() {
|
|
445
454
|
try {
|
|
446
|
-
if (this._isTransaction) throw new Error("db.many() 方法不支持事务模式");
|
|
447
455
|
let res;
|
|
448
456
|
if (this._hasLookup) {
|
|
449
|
-
|
|
450
|
-
this._endAggregate(aggRef);
|
|
457
|
+
let aggRef = this._createAggregate();
|
|
458
|
+
aggRef = this._endAggregate(aggRef);
|
|
451
459
|
res = await aggRef.end();
|
|
452
460
|
} else {
|
|
453
|
-
this.
|
|
454
|
-
|
|
461
|
+
let hostRef = this._createHost();
|
|
462
|
+
hostRef = this._endHost(hostRef, "query");
|
|
463
|
+
res = await hostRef.get();
|
|
455
464
|
}
|
|
456
465
|
const { data } = require__helpers.parseDatabaseOutput(res);
|
|
457
466
|
return data;
|
|
@@ -466,7 +475,6 @@ var Db = class Db {
|
|
|
466
475
|
* @returns 查询结果
|
|
467
476
|
*/
|
|
468
477
|
async firstOrThrow() {
|
|
469
|
-
if (this._isTransaction) throw new Error("db.firstOrThrow() 方法不支持事务模式");
|
|
470
478
|
if (this._hasLimit) throw new Error("db.firstOrThrow() 方法不支持 limit 条件");
|
|
471
479
|
if (!this._hasWhereId) this.limit(1);
|
|
472
480
|
const res = (await this.many()).at(0);
|
|
@@ -479,7 +487,6 @@ var Db = class Db {
|
|
|
479
487
|
* @returns 查询结果或 null
|
|
480
488
|
*/
|
|
481
489
|
async firstOrNull() {
|
|
482
|
-
if (this._isTransaction) throw new Error("db.firstOrNull() 方法不支持事务模式");
|
|
483
490
|
if (this._hasLimit) throw new Error("db.firstOrNull() 方法不支持 limit 条件");
|
|
484
491
|
if (!this._hasWhereId) this.limit(1);
|
|
485
492
|
return (await this.many()).at(0) || null;
|
|
@@ -489,15 +496,15 @@ var Db = class Db {
|
|
|
489
496
|
* @returns 记录总数
|
|
490
497
|
*/
|
|
491
498
|
async count() {
|
|
492
|
-
if (this._isTransaction) throw new Error("db.count() 方法不支持事务模式");
|
|
493
499
|
if (this._hasLookup) throw new Error("db.count() 方法不支持 lookup 聚合");
|
|
494
500
|
if (this._hasSelect) throw new Error("db.count() 方法不支持 select 条件");
|
|
495
501
|
if (this._hasOrder) throw new Error("db.count() 方法不支持 order 条件");
|
|
496
502
|
if (this._hasSkip) throw new Error("db.count() 方法不支持 skip 条件");
|
|
497
503
|
if (this._hasLimit) throw new Error("db.count() 方法不支持 limit 条件");
|
|
498
504
|
try {
|
|
499
|
-
this.
|
|
500
|
-
|
|
505
|
+
let hostRef = this._createHost();
|
|
506
|
+
hostRef = this._endHost(hostRef, "count");
|
|
507
|
+
const { total } = require__helpers.parseDatabaseOutput(await hostRef.count());
|
|
501
508
|
return total;
|
|
502
509
|
} catch (err) {
|
|
503
510
|
const dbErr = err;
|
|
@@ -517,8 +524,9 @@ var Db = class Db {
|
|
|
517
524
|
if (this._hasSkip) throw new Error("db.create() 方法不支持 skip 条件");
|
|
518
525
|
if (this._hasLimit) throw new Error("db.create() 方法不支持 limit 条件");
|
|
519
526
|
try {
|
|
520
|
-
this.
|
|
521
|
-
|
|
527
|
+
let hostRef = this._createHost();
|
|
528
|
+
hostRef = this._endHost(hostRef, "create");
|
|
529
|
+
const { id } = require__helpers.parseDatabaseOutput(await hostRef.add(data));
|
|
522
530
|
return id;
|
|
523
531
|
} catch (err) {
|
|
524
532
|
const dbErr = err;
|
|
@@ -539,8 +547,9 @@ var Db = class Db {
|
|
|
539
547
|
if (this._hasLimit) throw new Error("db.update() 方法不支持 limit 条件");
|
|
540
548
|
if (this._isTransaction && !this._hasWhereId) throw new Error("事务模式下 db.update() 的 where 条件必须是 _id");
|
|
541
549
|
try {
|
|
542
|
-
this.
|
|
543
|
-
|
|
550
|
+
let hostRef = this._createHost();
|
|
551
|
+
hostRef = this._endHost(hostRef, "update");
|
|
552
|
+
const { updated } = require__helpers.parseDatabaseOutput(await hostRef.update((0, _cloudcome_utils_core_object.objectOmit)(_mapCommandRaw(data), ["_id"])));
|
|
544
553
|
return updated;
|
|
545
554
|
} catch (err) {
|
|
546
555
|
const dbErr = err;
|
|
@@ -560,8 +569,9 @@ var Db = class Db {
|
|
|
560
569
|
if (this._hasLimit) throw new Error("db.remove() 方法不支持 limit 条件");
|
|
561
570
|
if (this._isTransaction && !this._hasWhereId) throw new Error("事务模式下 db.remove() 的 where 条件必须是 _id");
|
|
562
571
|
try {
|
|
563
|
-
this.
|
|
564
|
-
|
|
572
|
+
let hostRef = this._createHost();
|
|
573
|
+
hostRef = this._endHost(hostRef, "remove");
|
|
574
|
+
const { deleted } = require__helpers.parseDatabaseOutput(await hostRef.remove());
|
|
565
575
|
return deleted;
|
|
566
576
|
} catch (err) {
|
|
567
577
|
const dbErr = err;
|