@cloudcome/utils-uni 1.37.0 → 1.39.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"_helpers.cjs","names":[],"sources":["../src/_helpers.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\nimport { objectOmit } from '@cloudcome/utils-core/object';\nimport type { CloudMethodOutput } from './cloud';\nimport type { ClientDatabaseOutput, CloudDatabaseOutput } from './database';\n\n/**\n * 解析云对象方法调用的输出结果\n *\n * @template O - 云对象方法返回数据的类型\n * @param output - 云对象方法调用的输出结果\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 云对象方法返回成功时的数据部分\n * @throws 当云对象方法调用失败时,抛出包含错误信息的异常\n */\nexport function parseCloudMethodOutput<O>(output: CloudMethodOutput<O>, fallbackErrorMessage = ''): O {\n if (output.errCode) {\n throw errorAssign(new Error(output.errMsg || fallbackErrorMessage), output);\n }\n\n return output.data;\n}\n\n/**\n * 解析数据库执行结果\n * @param res 客户端、云端响应结果\n * @returns 处理后的结果\n */\nexport function parseDatabaseOutput<T>(res: ClientDatabaseOutput<T> | CloudDatabaseOutput<T>) {\n const keys = Object.keys(res as AnyObject);\n // 客户端 { result: {errCode: 0, errMsg: 'ok'} & 数据 }\n const isClient = keys.length === 1 && keys[0] === 'result';\n\n if (isClient) {\n const { result } = res as ClientDatabaseOutput<T>;\n if (!result.errCode) return objectOmit(result, ['errCode', 'errMsg']);\n throw errorAssign(new Error(result.errMsg), result);\n }\n\n // 云端 数据\n return res as T;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,uBAA0B,QAA8B,uBAAuB,IAAO;CACpG,IAAI,OAAO,SACT,OAAA,GAAA,4BAAA,aAAkB,IAAI,MAAM,OAAO,UAAU,qBAAqB,EAAE,OAAO;CAG7E,OAAO,OAAO;;;;;;;AAQhB,SAAgB,oBAAuB,KAAuD;CAC5F,MAAM,OAAO,OAAO,KAAK,IAAiB;CAI1C,IAFiB,KAAK,WAAW,KAAK,KAAK,OAAO,UAEpC;EACZ,MAAM,EAAE,WAAW;EACnB,IAAI,CAAC,OAAO,SAAS,QAAA,GAAA,6BAAA,YAAkB,QAAQ,CAAC,WAAW,SAAS,CAAC;EACrE,OAAA,GAAA,4BAAA,aAAkB,IAAI,MAAM,OAAO,OAAO,EAAE,OAAO;;CAIrD,OAAO"}
1
+ {"version":3,"file":"_helpers.cjs","names":[],"sources":["../src/_helpers.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\nimport { objectOmit } from '@cloudcome/utils-core/object';\nimport type { CloudMethodOutput } from './cloud';\nimport type { ClientDatabaseOutput, CloudDatabaseOutput } from './database';\n\n/**\n * 解析云对象方法调用的输出结果\n *\n * @template O - 云对象方法返回数据的类型\n * @param output - 云对象方法调用的输出结果\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 云对象方法返回成功时的数据部分\n * @throws 当云对象方法调用失败时,抛出包含错误信息的异常\n */\nexport function parseCloudMethodOutput<O>(output: CloudMethodOutput<O>, fallbackErrorMessage = ''): O {\n if (output.errCode) {\n throw errorAssign(new Error(output.errMsg || fallbackErrorMessage), output);\n }\n\n return output.data;\n}\n\n/**\n * 解析数据库执行结果\n * @param res 客户端、云端响应结果\n * @returns 处理后的结果\n */\nexport function parseDatabaseOutput<T>(res: ClientDatabaseOutput<T> | CloudDatabaseOutput<T>) {\n const keys = Object.keys(res as AnyObject);\n // 客户端 { result: {errCode: 0, errMsg: 'ok'} & 数据 }\n const isClient = keys.length === 1 && keys[0] === 'result';\n\n if (isClient) {\n const { result } = res as ClientDatabaseOutput<T>;\n if (!result.errCode) return objectOmit(result, ['errCode', 'errMsg']);\n throw errorAssign(new Error(result.errMsg), result);\n }\n\n // 云端 数据\n return res as T;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,uBAA0B,QAA8B,uBAAuB,IAAO;CACpG,IAAI,OAAO,SACT,OAAA,GAAA,4BAAA,aAAkB,IAAI,MAAM,OAAO,UAAU,oBAAoB,GAAG,MAAM;CAG5E,OAAO,OAAO;AAChB;;;;;;AAOA,SAAgB,oBAAuB,KAAuD;CAC5F,MAAM,OAAO,OAAO,KAAK,GAAgB;CAIzC,IAFiB,KAAK,WAAW,KAAK,KAAK,OAAO,UAEpC;EACZ,MAAM,EAAE,WAAW;EACnB,IAAI,CAAC,OAAO,SAAS,QAAA,GAAA,6BAAA,YAAkB,QAAQ,CAAC,WAAW,QAAQ,CAAC;EACpE,OAAA,GAAA,4BAAA,aAAkB,IAAI,MAAM,OAAO,MAAM,GAAG,MAAM;CACpD;CAGA,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"_helpers.mjs","names":[],"sources":["../src/_helpers.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\nimport { objectOmit } from '@cloudcome/utils-core/object';\nimport type { CloudMethodOutput } from './cloud';\nimport type { ClientDatabaseOutput, CloudDatabaseOutput } from './database';\n\n/**\n * 解析云对象方法调用的输出结果\n *\n * @template O - 云对象方法返回数据的类型\n * @param output - 云对象方法调用的输出结果\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 云对象方法返回成功时的数据部分\n * @throws 当云对象方法调用失败时,抛出包含错误信息的异常\n */\nexport function parseCloudMethodOutput<O>(output: CloudMethodOutput<O>, fallbackErrorMessage = ''): O {\n if (output.errCode) {\n throw errorAssign(new Error(output.errMsg || fallbackErrorMessage), output);\n }\n\n return output.data;\n}\n\n/**\n * 解析数据库执行结果\n * @param res 客户端、云端响应结果\n * @returns 处理后的结果\n */\nexport function parseDatabaseOutput<T>(res: ClientDatabaseOutput<T> | CloudDatabaseOutput<T>) {\n const keys = Object.keys(res as AnyObject);\n // 客户端 { result: {errCode: 0, errMsg: 'ok'} & 数据 }\n const isClient = keys.length === 1 && keys[0] === 'result';\n\n if (isClient) {\n const { result } = res as ClientDatabaseOutput<T>;\n if (!result.errCode) return objectOmit(result, ['errCode', 'errMsg']);\n throw errorAssign(new Error(result.errMsg), result);\n }\n\n // 云端 数据\n return res as T;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,uBAA0B,QAA8B,uBAAuB,IAAO;CACpG,IAAI,OAAO,SACT,MAAM,YAAY,IAAI,MAAM,OAAO,UAAU,qBAAqB,EAAE,OAAO;CAG7E,OAAO,OAAO;;;;;;;AAQhB,SAAgB,oBAAuB,KAAuD;CAC5F,MAAM,OAAO,OAAO,KAAK,IAAiB;CAI1C,IAFiB,KAAK,WAAW,KAAK,KAAK,OAAO,UAEpC;EACZ,MAAM,EAAE,WAAW;EACnB,IAAI,CAAC,OAAO,SAAS,OAAO,WAAW,QAAQ,CAAC,WAAW,SAAS,CAAC;EACrE,MAAM,YAAY,IAAI,MAAM,OAAO,OAAO,EAAE,OAAO;;CAIrD,OAAO"}
1
+ {"version":3,"file":"_helpers.mjs","names":[],"sources":["../src/_helpers.ts"],"sourcesContent":["import { errorAssign } from '@cloudcome/utils-core/error';\nimport { objectOmit } from '@cloudcome/utils-core/object';\nimport type { CloudMethodOutput } from './cloud';\nimport type { ClientDatabaseOutput, CloudDatabaseOutput } from './database';\n\n/**\n * 解析云对象方法调用的输出结果\n *\n * @template O - 云对象方法返回数据的类型\n * @param output - 云对象方法调用的输出结果\n * @param fallbackErrorMessage - 当输出中没有错误信息时使用的默认错误消息\n * @returns 云对象方法返回成功时的数据部分\n * @throws 当云对象方法调用失败时,抛出包含错误信息的异常\n */\nexport function parseCloudMethodOutput<O>(output: CloudMethodOutput<O>, fallbackErrorMessage = ''): O {\n if (output.errCode) {\n throw errorAssign(new Error(output.errMsg || fallbackErrorMessage), output);\n }\n\n return output.data;\n}\n\n/**\n * 解析数据库执行结果\n * @param res 客户端、云端响应结果\n * @returns 处理后的结果\n */\nexport function parseDatabaseOutput<T>(res: ClientDatabaseOutput<T> | CloudDatabaseOutput<T>) {\n const keys = Object.keys(res as AnyObject);\n // 客户端 { result: {errCode: 0, errMsg: 'ok'} & 数据 }\n const isClient = keys.length === 1 && keys[0] === 'result';\n\n if (isClient) {\n const { result } = res as ClientDatabaseOutput<T>;\n if (!result.errCode) return objectOmit(result, ['errCode', 'errMsg']);\n throw errorAssign(new Error(result.errMsg), result);\n }\n\n // 云端 数据\n return res as T;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,SAAgB,uBAA0B,QAA8B,uBAAuB,IAAO;CACpG,IAAI,OAAO,SACT,MAAM,YAAY,IAAI,MAAM,OAAO,UAAU,oBAAoB,GAAG,MAAM;CAG5E,OAAO,OAAO;AAChB;;;;;;AAOA,SAAgB,oBAAuB,KAAuD;CAC5F,MAAM,OAAO,OAAO,KAAK,GAAgB;CAIzC,IAFiB,KAAK,WAAW,KAAK,KAAK,OAAO,UAEpC;EACZ,MAAM,EAAE,WAAW;EACnB,IAAI,CAAC,OAAO,SAAS,OAAO,WAAW,QAAQ,CAAC,WAAW,QAAQ,CAAC;EACpE,MAAM,YAAY,IAAI,MAAM,OAAO,MAAM,GAAG,MAAM;CACpD;CAGA,OAAO;AACT"}
@@ -1,5 +1,5 @@
1
1
  import { AnyArray, AnyFunction } from '@cloudcome/utils-core/types';
2
- import { UseRequestOptions, UseRequestOutput, UseRequestOutputFilled } from '@cloudcome/utils-vue/request';
2
+ import { UseRequestOptions, UseRequestOutput } from '@cloudcome/utils-vue/request';
3
3
  import { CloudMethodOutput, UniError } from '../cloud';
4
4
  import { ClientDatabaseOutput } from '../database';
5
5
  export type CreateUseCloudObjectOptions = {
@@ -80,23 +80,6 @@ export type UseCloudMethodOptions<I extends AnyArray, O> = Omit<UseRequestOption
80
80
  * @template O 输出结果类型
81
81
  */
82
82
  export type UseCloudMethod<Api extends Record<string, AnyFunction>> = {
83
- /**
84
- * 重载签名:当提供 placeholder 选项时,返回包含初始值的输出类型
85
- * @param method 云对象方法名
86
- * @param caller 调用云对象方法的函数
87
- * @param options 包含 placeholder 的请求配置选项
88
- * @returns 返回包含初始值的请求输出
89
- */
90
- <K extends keyof Api, I extends AnyArray, O>(method: K, caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>, options: Omit<UseCloudMethodOptions<I, O>, 'placeholder'> & {
91
- placeholder: () => O;
92
- }): UseRequestOutputFilled<I, O>;
93
- /**
94
- * 重载签名:当不提供 placeholder 选项时,返回普通输出类型
95
- * @param method 云对象方法名
96
- * @param caller 调用云对象方法的函数
97
- * @param options 可选的请求配置选项
98
- * @returns 返回普通的请求输出
99
- */
100
83
  <K extends keyof Api, I extends AnyArray, O>(method: K, caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>, options?: UseCloudMethodOptions<I, O>): UseRequestOutput<I, O>;
101
84
  };
102
85
  /**
@@ -118,7 +101,4 @@ export type UseDatabaseOptions<I extends AnyArray, O> = UseRequestOptions<I, O>
118
101
  * @param options 配置选项
119
102
  * @returns 返回一个请求hook,用于处理云数据库调用
120
103
  */
121
- export declare function useDatabase<I extends AnyArray, O>(caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>, options: Omit<UseDatabaseOptions<I, O>, 'placeholder'> & {
122
- placeholder: () => O;
123
- }): UseRequestOutputFilled<I, O>;
124
104
  export declare function useDatabase<I extends AnyArray, O>(caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>, options?: UseDatabaseOptions<I, O>): UseRequestOutput<I, O>;
@@ -1 +1 @@
1
- {"version":3,"file":"client.cjs","names":[],"sources":["../src/client/message.ts","../src/client/app.ts","../src/client/async.ts","../src/client/page.ts","../src/client/request.ts","../src/client/ui.ts"],"sourcesContent":["import { promiseDelay } from '@cloudcome/utils-core/promise';\nimport { isString } from '@cloudcome/utils-core/type';\n\n/**\n * 显示 confirm 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniConfirm(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<boolean>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请确认',\n content: text,\n showCancel: true,\n confirmText,\n cancelText,\n ...options,\n success(result) {\n resolve(result.confirm);\n },\n });\n });\n });\n}\n\n/**\n * 显示 prompt 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniPrompt(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<string>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请输入',\n content: '',\n placeholderText: text,\n showCancel: true,\n confirmText,\n cancelText,\n editable: true,\n ...options,\n success(result) {\n resolve(result.content || '');\n },\n });\n });\n });\n}\n\n/**\n * 显示 alert 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniAlert(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'cancelText' | 'showCancel' | 'success' | 'content'>,\n) {\n const confirmText = options?.confirmText || '好';\n\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '提示',\n confirmText,\n cancelText: '',\n ...options,\n content: text,\n showCancel: false,\n success() {\n resolve();\n },\n });\n });\n });\n}\n\n/**\n * 显示 toast 提示\n * @param text 提示文本\n * @param icon 图标\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniToast(text: string, icon?: UniNamespace.ShowToastOptions['icon']): Promise<void>;\nexport function uniToast(text: string, options?: UniNamespace.ShowToastOptions): Promise<void>;\nexport function uniToast(\n text: string,\n iconOrOptions?: UniNamespace.ShowToastOptions['icon'] | UniNamespace.ShowToastOptions,\n): Promise<void> {\n const options = {} as UniNamespace.ShowToastOptions;\n\n if (isString(iconOrOptions)) {\n options.icon = iconOrOptions;\n } else {\n Object.assign(options, iconOrOptions);\n }\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(async () => {\n uni.showToast({\n title: text,\n duration: 2900,\n icon: options.icon || 'none',\n mask: false,\n });\n promiseDelay(3000).then(resolve);\n });\n });\n}\n\n/**\n * 显示 loading 提示\n * @param title 提示文本\n */\nexport function uniLoading(title = '') {\n uni.showLoading({\n title,\n mask: true,\n });\n}\n","import type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onHide, onShow } from '@dcloudio/uni-app';\nimport { ref } from 'vue';\nimport { uniConfirm } from './message';\n\n/**\n * 应用显示状态生命周期钩子函数\n *\n * 该函数用于监听应用从后台进入前台的生命周期事件。\n * 当应用从后台切换到前台时触发 onShow 回调,\n * 当应用从前台切换到后台时触发 onHide 回调。\n *\n * @param appShow - 应用显示状态变化时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * useAppShow(() => {\n * console.log('应用进入前台');\n *\n * // 可选:返回一个清理函数,在应用进入后台时执行\n * return () => {\n * console.log('应用进入后台');\n * };\n * });\n *\n * @example\n * // 带有异步操作的用法\n * useAppShow(async () => {\n * // 应用进入前台时刷新数据\n * await refreshUserData();\n *\n * // 返回清理函数\n * return () => {\n * // 应用进入后台时保存数据\n * saveUserData();\n * };\n * });\n */\nexport function useAppShow(appShow: HookListenerWithDispose) {\n _runLifeHook(onShow, onHide, appShow);\n}\n\n/**\n * 订阅模板消息\n * @param templateId 模板消息 ID 或 ID 列表\n * @returns Promise<boolean>\n */\nexport async function uniSubscribeNotice(templateId: string | string[]) {\n if (!uni.requestSubscribeMessage) return false;\n\n return new Promise<boolean>((resolve) => {\n const tmplIds = Array.isArray(templateId) ? templateId : [templateId];\n uni.requestSubscribeMessage({\n tmplIds,\n success(_res) {\n // 'accept'表示用户同意订阅该条id对应的模板消息,\n // 'reject'表示用户拒绝订阅该条id对应的模板消息,\n // 'ban'表示已被后台封禁,\n // 'filter'表示该模板因为模板标题同名被后台过滤\n const res = _res as unknown as Record<string, 'accept' | 'reject' | 'ban' | 'filter'>;\n let subscribed = false;\n\n for (const templateId of tmplIds) {\n if (res[templateId] === 'accept') {\n subscribed = true;\n break;\n }\n }\n\n resolve(subscribed);\n },\n fail() {\n resolve(false);\n },\n });\n });\n}\n\n/**\n * 监听应用更新状态\n */\nexport function useAppUpdate() {\n const hasUpdate = ref(false);\n const updateReady = ref(false);\n const updateManager = uni.getUpdateManager?.();\n\n updateManager?.onCheckForUpdate((res) => {\n // 请求完新版本信息的回调\n hasUpdate.value = Boolean(res.hasUpdate);\n });\n\n updateManager?.onUpdateReady(async () => {\n updateReady.value = true;\n\n const confirm = await uniConfirm('新版本已经准备好,是否重启应用?', {\n title: '更新提示',\n confirmText: '重启',\n });\n if (!confirm) return;\n\n updateManager.applyUpdate();\n });\n\n updateManager?.onUpdateFailed(() => {\n // 新的版本下载失败\n });\n\n return { hasUpdate, updateReady };\n}\n","import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport type UniFailErr = UniNamespace.GeneralCallbackResult & {\n errCode?: number;\n errno?: number;\n};\n\nexport type UniPromiseError = Error & {\n errCode: number;\n errNo: number;\n};\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param promise uni 异步函数的 Promise\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniPromise<T>(promise: Promise<T>): Promise<T> {\n try {\n const result = await promise;\n return result;\n } catch (err) {\n const res = err as unknown as UniFailErr;\n throw errorAssign(new Error(res.errMsg || '未知错误'), {\n errCode: res.errCode || -1,\n errNo: res.errno || -1,\n });\n }\n}\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param runner uni 异步函数的回调\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniCallback<T>(\n runner: (options: { success: (res: T) => void; fail: (err: UniFailErr) => void }) => unknown,\n) {\n return new Promise<T>((resolve, reject) => {\n runner({\n success(res) {\n resolve(res);\n },\n fail(err) {\n reject(\n errorAssign(new Error(err.errMsg || '未知错误'), {\n errCode: err.errCode || -1,\n errNo: err.errno || -1,\n }),\n );\n },\n });\n });\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onLoad, onPageHide, onPageShow, onUnload } from '@dcloudio/uni-app';\nimport { type Reactive, reactive } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n\n/**\n * 用于处理页面加载生命周期的 hook 函数\n *\n * 该函数会在页面加载时执行传入的回调函数,并在页面卸载时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onLoad 和 onUnload 生命周期的封装。\n *\n * @param {HookListenerWithDispose} load - 页面加载时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n *\n * // 返回一个清理函数,在页面卸载时执行\n * return () => {\n * console.log('页面将要卸载');\n * };\n * });\n *\n * @example\n * // 异步用法\n * usePageLoad(async () => {\n * const data = await fetchData();\n * console.log('获取到数据:', data);\n *\n * return () => {\n * console.log('清理资源');\n * };\n * });\n */\nexport function usePageLoad(load: HookListenerWithDispose) {\n _runLifeHook(onLoad, onUnload, load);\n}\n\n/**\n * 用于处理页面显示生命周期的 hook 函数\n *\n * 该函数会在页面显示时执行传入的回调函数,并在页面隐藏时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onPageShow 和 onPageHide 生命周期的封装。\n *\n * @param {HookListenerWithDispose} pageShow - 页面显示时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageShow(() => {\n * console.log('页面已显示');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageShow(() => {\n * console.log('页面已显示');\n *\n * // 返回一个清理函数,在页面隐藏时执行\n * return () => {\n * console.log('页面将要隐藏');\n * };\n * });\n */\nexport function usePageShow(pageShow: HookListenerWithDispose) {\n _runLifeHook(onPageShow, onPageHide, pageShow);\n}\n","import type { AnyArray, AnyFunction } from '@cloudcome/utils-core/types';\nimport {\n type UseRequestOptions,\n type UseRequestOutput,\n type UseRequestOutputFilled,\n useRequest,\n} from '@cloudcome/utils-vue/request';\nimport type { CloudMethodOutput, UniError } from '@/cloud';\nimport type { ClientDatabaseOutput } from '@/database';\nimport { parseCloudMethodOutput } from '../_helpers';\nimport { uniLoading, uniToast } from './message';\n\nexport type CreateUseCloudObjectOptions = {\n /**\n * 模拟云对象,用于单元测试\n * @private\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockServer?: any;\n\n /**\n * 回退错误信息\n * @default '请求失败'\n */\n fallbackErrorMessage?: string;\n\n /**\n * 请求开始前的回调函数\n */\n onBefore?: () => unknown;\n\n /**\n * 请求成功后的回调函数\n */\n onSuccess?: () => unknown;\n\n /**\n * 请求失败时的回调函数\n * @param err 错误信息\n */\n onError?: (err: UniError) => unknown;\n\n /**\n * 请求完成后的回调函数(无论成功或失败都会执行)\n */\n onAfter?: () => unknown;\n\n /**\n * 显示加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onShowLoading?: () => unknown;\n\n /**\n * 隐藏加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onHideLoading?: () => unknown;\n\n /**\n * 显示错误信息的回调函数,当配置了 showError 为 true 时会调用\n * @param err 错误信息\n */\n onShowError?: (err: UniError) => unknown;\n};\n\n/**\n * 云对象请求函数类型定义\n * @template F 云对象方法函数类型\n * @param input 云对象方法的参数数组\n * @returns 返回云对象方法执行结果的Promise\n */\nexport type CloudObjectRequest = <F extends AnyFunction>(\n ...input: Parameters<F>\n) => Promise<CloudMethodOutput<ReturnType<F>>>;\n\n/**\n * 用于调用云对象方法的配置选项类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethodOptions<I extends AnyArray, O> = Omit<UseRequestOptions<I, O>, 'onError'> & {\n /**\n * 请求发生错误时的回调函数\n * @param err 错误信息\n * @param inputs 请求输入参数\n */\n onError?: (err: UniError, ...inputs: I) => unknown;\n\n /**\n * 是否显示加载状态\n * @default false\n */\n showLoading?: boolean;\n\n /**\n * 是否显示错误信息\n * @default false\n */\n showError?: boolean;\n};\n\n/**\n * 用于调用云对象方法的hook函数类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethod<Api extends Record<string, AnyFunction>> = {\n /**\n * 重载签名:当提供 placeholder 选项时,返回包含初始值的输出类型\n * @param method 云对象方法名\n * @param caller 调用云对象方法的函数\n * @param options 包含 placeholder 的请求配置选项\n * @returns 返回包含初始值的请求输出\n */\n <K extends keyof Api, I extends AnyArray, O>(\n method: K,\n caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>,\n options: Omit<UseCloudMethodOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n ): UseRequestOutputFilled<I, O>;\n\n /**\n * 重载签名:当不提供 placeholder 选项时,返回普通输出类型\n * @param method 云对象方法名\n * @param caller 调用云对象方法的函数\n * @param options 可选的请求配置选项\n * @returns 返回普通的请求输出\n */\n <K extends keyof Api, I extends AnyArray, O>(\n method: K,\n caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>,\n options?: UseCloudMethodOptions<I, O>,\n ): UseRequestOutput<I, O>;\n};\n\n/**\n * 导入云对象并创建一个用于调用云对象的hook\n * @param objectName 云对象名称\n * @param importOptions 配置选项,包含模拟服务器、回退错误信息等\n * @returns 返回一个可用于调用云对象方法的hook函数\n */\nexport function importCloudObject<Api extends Record<string, AnyFunction>>(\n objectName: string,\n importOptions?: CreateUseCloudObjectOptions,\n) {\n const fallbackErrorMessage = importOptions?.fallbackErrorMessage || '请求失败';\n const server =\n importOptions?._mockServer ||\n uniCloud.importObject(objectName, {\n customUI: true,\n });\n const onShowLoading = importOptions?.onShowLoading || (() => uniLoading());\n const onHideLoading = importOptions?.onHideLoading || (() => uni.hideLoading());\n const onShowError = importOptions?.onShowError || ((err) => uniToast(err.message));\n\n /**\n * 用于调用云对象方法的hook函数\n * @template I 输入参数类型\n * @template O 输出结果类型\n * @param method 云对象方法名\n * @param caller 调用云对象的函数\n * @param options 配置选项,包含请求相关的配置\n * @returns 返回一个请求hook,用于处理云对象调用\n */\n const useCloudMethod: UseCloudMethod<Api> = (method, caller, options) => {\n // 使用请求hook处理云对象调用\n return useRequest(\n async (...inputs) => {\n const request = server[method];\n const output = await caller(request, ...inputs);\n return parseCloudMethodOutput(output, fallbackErrorMessage);\n },\n {\n ...options,\n async onBefore(...inputs) {\n if (options?.showLoading) onShowLoading();\n\n await importOptions?.onBefore?.();\n await options?.onBefore?.(...inputs);\n },\n async onSuccess(data, ...inputs) {\n await importOptions?.onSuccess?.();\n await options?.onSuccess?.(data, ...inputs);\n },\n async onError(err, ...inputs) {\n await importOptions?.onError?.(err as UniError);\n await options?.onError?.(err as UniError, ...inputs);\n\n if (options?.showError) {\n // 加延迟是尽量保证在 loading 隐藏后再显示错误信息\n setTimeout(() => {\n onShowError(err as UniError);\n });\n }\n },\n async onAfter(...inputs) {\n if (options?.showLoading) onHideLoading();\n\n await importOptions?.onAfter?.();\n await options?.onAfter?.(...inputs);\n },\n },\n );\n };\n\n return useCloudMethod;\n}\n\nexport type UseDatabaseOptions<I extends AnyArray, O> = UseRequestOptions<I, O> & {\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockDatabase?: any;\n};\n\n/**\n * 创建一个用于调用云数据库的hook\n * @param caller 调用云数据库的函数,接收数据库实例和输入参数,返回Promise\n * @param options 配置选项\n * @returns 返回一个请求hook,用于处理云数据库调用\n */\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options: Omit<UseDatabaseOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseRequestOutputFilled<I, O>;\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O> {\n // 获取数据库实例,优先使用模拟数据库(用于测试),否则使用uniCloud数据库\n const db = options?._mockDatabase || uniCloud.database();\n return useRequest(async (...inputs: I) => {\n const { result } = await caller(db, ...inputs);\n if (!result.errCode) return result;\n throw new Error(result.errMsg || '请求失败');\n }, options);\n}\n","import type { ComponentInternalInstance } from 'vue';\n\nexport type Rect = {\n /**\n * 元素距离屏幕的左坐标,单位:px\n */\n left: number;\n /**\n * 元素距离屏幕的上坐标,单位:px\n */\n top: number;\n /**\n * 元素距离屏幕的宽度,单位:px\n */\n width: number;\n /**\n * 元素距离屏幕的高度,单位:px\n */\n height: number;\n};\n\n/**\n * 查询元素距离屏幕的矩形信息\n * @param instance 组件实例\n * @param selector 选择器\n * @returns 元素距离屏幕的矩形信息\n */\nexport async function querySelectorRects(instance: ComponentInternalInstance, selector: string) {\n return new Promise<Rect[]>((resolve) => {\n uni\n .createSelectorQuery()\n .in(instance.proxy)\n .selectAll(selector)\n .boundingClientRect((_rects) => {\n const rects = _rects as UniApp.NodeInfo[];\n resolve(\n rects.map((rect) => ({\n left: rect.left || 0,\n top: rect.top || 0,\n width: rect.width || 0,\n height: rect.height || 0,\n })),\n );\n })\n .exec();\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.cjs","names":[],"sources":["../src/client/message.ts","../src/client/app.ts","../src/client/async.ts","../src/client/page.ts","../src/client/request.ts","../src/client/ui.ts"],"sourcesContent":["import { promiseDelay } from '@cloudcome/utils-core/promise';\nimport { isString } from '@cloudcome/utils-core/type';\n\n/**\n * 显示 confirm 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniConfirm(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<boolean>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请确认',\n content: text,\n showCancel: true,\n confirmText,\n cancelText,\n ...options,\n success(result) {\n resolve(result.confirm);\n },\n });\n });\n });\n}\n\n/**\n * 显示 prompt 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniPrompt(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<string>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请输入',\n content: '',\n placeholderText: text,\n showCancel: true,\n confirmText,\n cancelText,\n editable: true,\n ...options,\n success(result) {\n resolve(result.content || '');\n },\n });\n });\n });\n}\n\n/**\n * 显示 alert 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniAlert(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'cancelText' | 'showCancel' | 'success' | 'content'>,\n) {\n const confirmText = options?.confirmText || '好';\n\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '提示',\n confirmText,\n cancelText: '',\n ...options,\n content: text,\n showCancel: false,\n success() {\n resolve();\n },\n });\n });\n });\n}\n\n/**\n * 显示 toast 提示\n * @param text 提示文本\n * @param icon 图标\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniToast(text: string, icon?: UniNamespace.ShowToastOptions['icon']): Promise<void>;\nexport function uniToast(text: string, options?: UniNamespace.ShowToastOptions): Promise<void>;\nexport function uniToast(\n text: string,\n iconOrOptions?: UniNamespace.ShowToastOptions['icon'] | UniNamespace.ShowToastOptions,\n): Promise<void> {\n const options = {} as UniNamespace.ShowToastOptions;\n\n if (isString(iconOrOptions)) {\n options.icon = iconOrOptions;\n } else {\n Object.assign(options, iconOrOptions);\n }\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(async () => {\n uni.showToast({\n title: text,\n duration: 2900,\n icon: options.icon || 'none',\n mask: false,\n });\n promiseDelay(3000).then(resolve);\n });\n });\n}\n\n/**\n * 显示 loading 提示\n * @param title 提示文本\n */\nexport function uniLoading(title = '') {\n uni.showLoading({\n title,\n mask: true,\n });\n}\n","import type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onHide, onShow } from '@dcloudio/uni-app';\nimport { ref } from 'vue';\nimport { uniConfirm } from './message';\n\n/**\n * 应用显示状态生命周期钩子函数\n *\n * 该函数用于监听应用从后台进入前台的生命周期事件。\n * 当应用从后台切换到前台时触发 onShow 回调,\n * 当应用从前台切换到后台时触发 onHide 回调。\n *\n * @param appShow - 应用显示状态变化时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * useAppShow(() => {\n * console.log('应用进入前台');\n *\n * // 可选:返回一个清理函数,在应用进入后台时执行\n * return () => {\n * console.log('应用进入后台');\n * };\n * });\n *\n * @example\n * // 带有异步操作的用法\n * useAppShow(async () => {\n * // 应用进入前台时刷新数据\n * await refreshUserData();\n *\n * // 返回清理函数\n * return () => {\n * // 应用进入后台时保存数据\n * saveUserData();\n * };\n * });\n */\nexport function useAppShow(appShow: HookListenerWithDispose) {\n _runLifeHook(onShow, onHide, appShow);\n}\n\n/**\n * 订阅模板消息\n * @param templateId 模板消息 ID 或 ID 列表\n * @returns Promise<boolean>\n */\nexport async function uniSubscribeNotice(templateId: string | string[]) {\n if (!uni.requestSubscribeMessage) return false;\n\n return new Promise<boolean>((resolve) => {\n const tmplIds = Array.isArray(templateId) ? templateId : [templateId];\n uni.requestSubscribeMessage({\n tmplIds,\n success(_res) {\n // 'accept'表示用户同意订阅该条id对应的模板消息,\n // 'reject'表示用户拒绝订阅该条id对应的模板消息,\n // 'ban'表示已被后台封禁,\n // 'filter'表示该模板因为模板标题同名被后台过滤\n const res = _res as unknown as Record<string, 'accept' | 'reject' | 'ban' | 'filter'>;\n let subscribed = false;\n\n for (const templateId of tmplIds) {\n if (res[templateId] === 'accept') {\n subscribed = true;\n break;\n }\n }\n\n resolve(subscribed);\n },\n fail() {\n resolve(false);\n },\n });\n });\n}\n\n/**\n * 监听应用更新状态\n */\nexport function useAppUpdate() {\n const hasUpdate = ref(false);\n const updateReady = ref(false);\n const updateManager = uni.getUpdateManager?.();\n\n updateManager?.onCheckForUpdate((res) => {\n // 请求完新版本信息的回调\n hasUpdate.value = Boolean(res.hasUpdate);\n });\n\n updateManager?.onUpdateReady(async () => {\n updateReady.value = true;\n\n const confirm = await uniConfirm('新版本已经准备好,是否重启应用?', {\n title: '更新提示',\n confirmText: '重启',\n });\n if (!confirm) return;\n\n updateManager.applyUpdate();\n });\n\n updateManager?.onUpdateFailed(() => {\n // 新的版本下载失败\n });\n\n return { hasUpdate, updateReady };\n}\n","import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport type UniFailErr = UniNamespace.GeneralCallbackResult & {\n errCode?: number;\n errno?: number;\n};\n\nexport type UniPromiseError = Error & {\n errCode: number;\n errNo: number;\n};\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param promise uni 异步函数的 Promise\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniPromise<T>(promise: Promise<T>): Promise<T> {\n try {\n const result = await promise;\n return result;\n } catch (err) {\n const res = err as unknown as UniFailErr;\n throw errorAssign(new Error(res.errMsg || '未知错误'), {\n errCode: res.errCode || -1,\n errNo: res.errno || -1,\n });\n }\n}\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param runner uni 异步函数的回调\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniCallback<T>(\n runner: (options: { success: (res: T) => void; fail: (err: UniFailErr) => void }) => unknown,\n) {\n return new Promise<T>((resolve, reject) => {\n runner({\n success(res) {\n resolve(res);\n },\n fail(err) {\n reject(\n errorAssign(new Error(err.errMsg || '未知错误'), {\n errCode: err.errCode || -1,\n errNo: err.errno || -1,\n }),\n );\n },\n });\n });\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onLoad, onPageHide, onPageShow, onUnload } from '@dcloudio/uni-app';\nimport { type Reactive, reactive } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n\n/**\n * 用于处理页面加载生命周期的 hook 函数\n *\n * 该函数会在页面加载时执行传入的回调函数,并在页面卸载时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onLoad 和 onUnload 生命周期的封装。\n *\n * @param {HookListenerWithDispose} load - 页面加载时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n *\n * // 返回一个清理函数,在页面卸载时执行\n * return () => {\n * console.log('页面将要卸载');\n * };\n * });\n *\n * @example\n * // 异步用法\n * usePageLoad(async () => {\n * const data = await fetchData();\n * console.log('获取到数据:', data);\n *\n * return () => {\n * console.log('清理资源');\n * };\n * });\n */\nexport function usePageLoad(load: HookListenerWithDispose) {\n _runLifeHook(onLoad, onUnload, load);\n}\n\n/**\n * 用于处理页面显示生命周期的 hook 函数\n *\n * 该函数会在页面显示时执行传入的回调函数,并在页面隐藏时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onPageShow 和 onPageHide 生命周期的封装。\n *\n * @param {HookListenerWithDispose} pageShow - 页面显示时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageShow(() => {\n * console.log('页面已显示');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageShow(() => {\n * console.log('页面已显示');\n *\n * // 返回一个清理函数,在页面隐藏时执行\n * return () => {\n * console.log('页面将要隐藏');\n * };\n * });\n */\nexport function usePageShow(pageShow: HookListenerWithDispose) {\n _runLifeHook(onPageShow, onPageHide, pageShow);\n}\n","import type { AnyArray, AnyFunction } from '@cloudcome/utils-core/types';\nimport { type UseRequestOptions, type UseRequestOutput, useRequest } from '@cloudcome/utils-vue/request';\nimport type { CloudMethodOutput, UniError } from '@/cloud';\nimport type { ClientDatabaseOutput } from '@/database';\nimport { parseCloudMethodOutput } from '../_helpers';\nimport { uniLoading, uniToast } from './message';\n\nexport type CreateUseCloudObjectOptions = {\n /**\n * 模拟云对象,用于单元测试\n * @private\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockServer?: any;\n\n /**\n * 回退错误信息\n * @default '请求失败'\n */\n fallbackErrorMessage?: string;\n\n /**\n * 请求开始前的回调函数\n */\n onBefore?: () => unknown;\n\n /**\n * 请求成功后的回调函数\n */\n onSuccess?: () => unknown;\n\n /**\n * 请求失败时的回调函数\n * @param err 错误信息\n */\n onError?: (err: UniError) => unknown;\n\n /**\n * 请求完成后的回调函数(无论成功或失败都会执行)\n */\n onAfter?: () => unknown;\n\n /**\n * 显示加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onShowLoading?: () => unknown;\n\n /**\n * 隐藏加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onHideLoading?: () => unknown;\n\n /**\n * 显示错误信息的回调函数,当配置了 showError 为 true 时会调用\n * @param err 错误信息\n */\n onShowError?: (err: UniError) => unknown;\n};\n\n/**\n * 云对象请求函数类型定义\n * @template F 云对象方法函数类型\n * @param input 云对象方法的参数数组\n * @returns 返回云对象方法执行结果的Promise\n */\nexport type CloudObjectRequest = <F extends AnyFunction>(\n ...input: Parameters<F>\n) => Promise<CloudMethodOutput<ReturnType<F>>>;\n\n/**\n * 用于调用云对象方法的配置选项类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethodOptions<I extends AnyArray, O> = Omit<UseRequestOptions<I, O>, 'onError'> & {\n /**\n * 请求发生错误时的回调函数\n * @param err 错误信息\n * @param inputs 请求输入参数\n */\n onError?: (err: UniError, ...inputs: I) => unknown;\n\n /**\n * 是否显示加载状态\n * @default false\n */\n showLoading?: boolean;\n\n /**\n * 是否显示错误信息\n * @default false\n */\n showError?: boolean;\n};\n\n/**\n * 用于调用云对象方法的hook函数类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethod<Api extends Record<string, AnyFunction>> = {\n <K extends keyof Api, I extends AnyArray, O>(\n method: K,\n caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>,\n options?: UseCloudMethodOptions<I, O>,\n ): UseRequestOutput<I, O>;\n};\n\n/**\n * 导入云对象并创建一个用于调用云对象的hook\n * @param objectName 云对象名称\n * @param importOptions 配置选项,包含模拟服务器、回退错误信息等\n * @returns 返回一个可用于调用云对象方法的hook函数\n */\nexport function importCloudObject<Api extends Record<string, AnyFunction>>(\n objectName: string,\n importOptions?: CreateUseCloudObjectOptions,\n) {\n const fallbackErrorMessage = importOptions?.fallbackErrorMessage || '请求失败';\n const server =\n importOptions?._mockServer ||\n uniCloud.importObject(objectName, {\n customUI: true,\n });\n const onShowLoading = importOptions?.onShowLoading || (() => uniLoading());\n const onHideLoading = importOptions?.onHideLoading || (() => uni.hideLoading());\n const onShowError = importOptions?.onShowError || ((err) => uniToast(err.message));\n\n /**\n * 用于调用云对象方法的hook函数\n * @template I 输入参数类型\n * @template O 输出结果类型\n * @param method 云对象方法名\n * @param caller 调用云对象的函数\n * @param options 配置选项,包含请求相关的配置\n * @returns 返回一个请求hook,用于处理云对象调用\n */\n const useCloudMethod: UseCloudMethod<Api> = (method, caller, options) => {\n // 使用请求hook处理云对象调用\n return useRequest(\n async (...inputs) => {\n const request = server[method];\n const output = await caller(request, ...inputs);\n return parseCloudMethodOutput(output, fallbackErrorMessage);\n },\n {\n ...options,\n async onBefore(...inputs) {\n if (options?.showLoading) onShowLoading();\n\n await importOptions?.onBefore?.();\n await options?.onBefore?.(...inputs);\n },\n async onSuccess(data, ...inputs) {\n await importOptions?.onSuccess?.();\n await options?.onSuccess?.(data, ...inputs);\n },\n async onError(err, ...inputs) {\n await importOptions?.onError?.(err as UniError);\n await options?.onError?.(err as UniError, ...inputs);\n\n if (options?.showError) {\n // 加延迟是尽量保证在 loading 隐藏后再显示错误信息\n setTimeout(() => {\n onShowError(err as UniError);\n });\n }\n },\n async onAfter(...inputs) {\n if (options?.showLoading) onHideLoading();\n\n await importOptions?.onAfter?.();\n await options?.onAfter?.(...inputs);\n },\n },\n );\n };\n\n return useCloudMethod;\n}\n\nexport type UseDatabaseOptions<I extends AnyArray, O> = UseRequestOptions<I, O> & {\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockDatabase?: any;\n};\n\n/**\n * 创建一个用于调用云数据库的hook\n * @param caller 调用云数据库的函数,接收数据库实例和输入参数,返回Promise\n * @param options 配置选项\n * @returns 返回一个请求hook,用于处理云数据库调用\n */\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O> {\n // 获取数据库实例,优先使用模拟数据库(用于测试),否则使用uniCloud数据库\n const db = options?._mockDatabase || uniCloud.database();\n return useRequest(async (...inputs: I) => {\n const { result } = await caller(db, ...inputs);\n if (!result.errCode) return result;\n throw new Error(result.errMsg || '请求失败');\n }, options);\n}\n","import type { ComponentInternalInstance } from 'vue';\n\nexport type Rect = {\n /**\n * 元素距离屏幕的左坐标,单位:px\n */\n left: number;\n /**\n * 元素距离屏幕的上坐标,单位:px\n */\n top: number;\n /**\n * 元素距离屏幕的宽度,单位:px\n */\n width: number;\n /**\n * 元素距离屏幕的高度,单位:px\n */\n height: number;\n};\n\n/**\n * 查询元素距离屏幕的矩形信息\n * @param instance 组件实例\n * @param selector 选择器\n * @returns 元素距离屏幕的矩形信息\n */\nexport async function querySelectorRects(instance: ComponentInternalInstance, selector: string) {\n return new Promise<Rect[]>((resolve) => {\n uni\n .createSelectorQuery()\n .in(instance.proxy)\n .selectAll(selector)\n .boundingClientRect((_rects) => {\n const rects = _rects as UniApp.NodeInfo[];\n resolve(\n rects.map((rect) => ({\n left: rect.left || 0,\n top: rect.top || 0,\n width: rect.width || 0,\n height: rect.height || 0,\n })),\n );\n })\n .exec();\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;AASA,SAAgB,WACd,MACA,SACA;CACA,MAAM,aAAa,SAAS,cAAc;CAC1C,MAAM,cAAc,SAAS,eAAe;CAE5C,IAAI,WAAW,SAAS,GAAG,QAAQ,KAAK,iCAAiC;CACzE,IAAI,YAAY,SAAS,GAAG,QAAQ,KAAK,kCAAkC;CAE3E,OAAO,IAAI,SAAkB,YAAY;EAEvC,iBAAiB;GACf,IAAI,UAAU;IACZ,OAAO;IACP,SAAS;IACT,YAAY;IACZ;IACA;IACA,GAAG;IACH,QAAQ,QAAQ;KACd,QAAQ,OAAO,OAAO;IACxB;GACF,CAAC;EACH,CAAC;CACH,CAAC;AACH;;;;;;;AAQA,SAAgB,UACd,MACA,SACA;CACA,MAAM,aAAa,SAAS,cAAc;CAC1C,MAAM,cAAc,SAAS,eAAe;CAE5C,IAAI,WAAW,SAAS,GAAG,QAAQ,KAAK,iCAAiC;CACzE,IAAI,YAAY,SAAS,GAAG,QAAQ,KAAK,kCAAkC;CAE3E,OAAO,IAAI,SAAiB,YAAY;EAEtC,iBAAiB;GACf,IAAI,UAAU;IACZ,OAAO;IACP,SAAS;IACT,iBAAiB;IACjB,YAAY;IACZ;IACA;IACA,UAAU;IACV,GAAG;IACH,QAAQ,QAAQ;KACd,QAAQ,OAAO,WAAW,EAAE;IAC9B;GACF,CAAC;EACH,CAAC;CACH,CAAC;AACH;;;;;;;AAQA,SAAgB,SACd,MACA,SACA;CACA,MAAM,cAAc,SAAS,eAAe;CAE5C,IAAI,YAAY,SAAS,GAAG,QAAQ,KAAK,kCAAkC;CAE3E,OAAO,IAAI,SAAe,YAAY;EAEpC,iBAAiB;GACf,IAAI,UAAU;IACZ,OAAO;IACP;IACA,YAAY;IACZ,GAAG;IACH,SAAS;IACT,YAAY;IACZ,UAAU;KACR,QAAQ;IACV;GACF,CAAC;EACH,CAAC;CACH,CAAC;AACH;AAWA,SAAgB,SACd,MACA,eACe;CACf,MAAM,UAAU,CAAC;CAEjB,KAAA,GAAA,2BAAA,UAAa,aAAa,GACxB,QAAQ,OAAO;MAEf,OAAO,OAAO,SAAS,aAAa;CAGtC,OAAO,IAAI,SAAe,YAAY;EAEpC,WAAW,YAAY;GACrB,IAAI,UAAU;IACZ,OAAO;IACP,UAAU;IACV,MAAM,QAAQ,QAAQ;IACtB,MAAM;GACR,CAAC;GACD,CAAA,GAAA,8BAAA,cAAa,GAAI,EAAE,KAAK,OAAO;EACjC,CAAC;CACH,CAAC;AACH;;;;;AAMA,SAAgB,WAAW,QAAQ,IAAI;CACrC,IAAI,YAAY;EACd;EACA,MAAM;CACR,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC9GA,SAAgB,WAAW,SAAkC;CAC3D,CAAA,GAAA,4BAAA,cAAa,kBAAA,QAAQ,kBAAA,QAAQ,OAAO;AACtC;;;;;;AAOA,eAAsB,mBAAmB,YAA+B;CACtE,IAAI,CAAC,IAAI,yBAAyB,OAAO;CAEzC,OAAO,IAAI,SAAkB,YAAY;EACvC,MAAM,UAAU,MAAM,QAAQ,UAAU,IAAI,aAAa,CAAC,UAAU;EACpE,IAAI,wBAAwB;GAC1B;GACA,QAAQ,MAAM;IAKZ,MAAM,MAAM;IACZ,IAAI,aAAa;IAEjB,KAAK,MAAM,cAAc,SACvB,IAAI,IAAI,gBAAgB,UAAU;KAChC,aAAa;KACb;IACF;IAGF,QAAQ,UAAU;GACpB;GACA,OAAO;IACL,QAAQ,KAAK;GACf;EACF,CAAC;CACH,CAAC;AACH;;;;AAKA,SAAgB,eAAe;CAC7B,MAAM,aAAA,GAAA,IAAA,KAAgB,KAAK;CAC3B,MAAM,eAAA,GAAA,IAAA,KAAkB,KAAK;CAC7B,MAAM,gBAAgB,IAAI,mBAAmB;CAE7C,eAAe,kBAAkB,QAAQ;EAEvC,UAAU,QAAQ,QAAQ,IAAI,SAAS;CACzC,CAAC;CAED,eAAe,cAAc,YAAY;EACvC,YAAY,QAAQ;EAMpB,IAAI,CAAC,MAJiB,WAAW,oBAAoB;GACnD,OAAO;GACP,aAAa;EACf,CAAC,GACa;EAEd,cAAc,YAAY;CAC5B,CAAC;CAED,eAAe,qBAAqB,CAEpC,CAAC;CAED,OAAO;EAAE;EAAW;CAAY;AAClC;;;;;;;;;AC3FA,eAAsB,WAAc,SAAiC;CACnE,IAAI;EAEF,OAAO,MADc;CAEvB,SAAS,KAAK;EACZ,MAAM,MAAM;EACZ,OAAA,GAAA,4BAAA,aAAkB,IAAI,MAAM,IAAI,UAAU,MAAM,GAAG;GACjD,SAAS,IAAI,WAAW;GACxB,OAAO,IAAI,SAAS;EACtB,CAAC;CACH;AACF;;;;;;;AAQA,eAAsB,YACpB,QACA;CACA,OAAO,IAAI,SAAY,SAAS,WAAW;EACzC,OAAO;GACL,QAAQ,KAAK;IACX,QAAQ,GAAG;GACb;GACA,KAAK,KAAK;IACR,QAAA,GAAA,4BAAA,aACc,IAAI,MAAM,IAAI,UAAU,MAAM,GAAG;KAC3C,SAAS,IAAI,WAAW;KACxB,OAAO,IAAI,SAAS;IACtB,CAAC,CACH;GACF;EACF,CAAC;CACH,CAAC;AACH;;;;;;;;;;;;;;;;;;;;;;;;;AC3BA,SAAgB,aAAkC,YAA2C;CAC3F,MAAM,SAAA,GAAA,IAAA,UAAoB,CAAC,CAAM;CAEjC,CAAA,GAAA,kBAAA,SAAQ,WAAW;EACjB,OAAO,OAAO,OAAO,MAAM;EAC3B,aAAa,KAAK;CACpB,CAAC;CAED,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA,SAAgB,YAAY,MAA+B;CACzD,CAAA,GAAA,4BAAA,cAAa,kBAAA,QAAQ,kBAAA,UAAU,IAAI;AACrC;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,YAAY,UAAmC;CAC7D,CAAA,GAAA,4BAAA,cAAa,kBAAA,YAAY,kBAAA,YAAY,QAAQ;AAC/C;;;;;;;;;ACQA,SAAgB,kBACd,YACA,eACA;CACA,MAAM,uBAAuB,eAAe,wBAAwB;CACpE,MAAM,SACJ,eAAe,eACf,SAAS,aAAa,YAAY,EAChC,UAAU,KACZ,CAAC;CACH,MAAM,gBAAgB,eAAe,wBAAwB,WAAW;CACxE,MAAM,gBAAgB,eAAe,wBAAwB,IAAI,YAAY;CAC7E,MAAM,cAAc,eAAe,iBAAiB,QAAQ,SAAS,IAAI,OAAO;;;;;;;;;;CAWhF,MAAM,kBAAuC,QAAQ,QAAQ,YAAY;EAEvE,QAAA,GAAA,6BAAA,YACE,OAAO,GAAG,WAAW;GACnB,MAAM,UAAU,OAAO;GAEvB,OAAO,iBAAA,uBAAuB,MADT,OAAO,SAAS,GAAG,MAAM,GACR,oBAAoB;EAC5D,GACA;GACE,GAAG;GACH,MAAM,SAAS,GAAG,QAAQ;IACxB,IAAI,SAAS,aAAa,cAAc;IAExC,MAAM,eAAe,WAAW;IAChC,MAAM,SAAS,WAAW,GAAG,MAAM;GACrC;GACA,MAAM,UAAU,MAAM,GAAG,QAAQ;IAC/B,MAAM,eAAe,YAAY;IACjC,MAAM,SAAS,YAAY,MAAM,GAAG,MAAM;GAC5C;GACA,MAAM,QAAQ,KAAK,GAAG,QAAQ;IAC5B,MAAM,eAAe,UAAU,GAAe;IAC9C,MAAM,SAAS,UAAU,KAAiB,GAAG,MAAM;IAEnD,IAAI,SAAS,WAEX,iBAAiB;KACf,YAAY,GAAe;IAC7B,CAAC;GAEL;GACA,MAAM,QAAQ,GAAG,QAAQ;IACvB,IAAI,SAAS,aAAa,cAAc;IAExC,MAAM,eAAe,UAAU;IAC/B,MAAM,SAAS,UAAU,GAAG,MAAM;GACpC;EACF,CACF;CACF;CAEA,OAAO;AACT;AAoBA,SAAgB,YACd,QACA,SACwB;CAExB,MAAM,KAAK,SAAS,iBAAiB,SAAS,SAAS;CACvD,QAAA,GAAA,6BAAA,YAAkB,OAAO,GAAG,WAAc;EACxC,MAAM,EAAE,WAAW,MAAM,OAAO,IAAI,GAAG,MAAM;EAC7C,IAAI,CAAC,OAAO,SAAS,OAAO;EAC5B,MAAM,IAAI,MAAM,OAAO,UAAU,MAAM;CACzC,GAAG,OAAO;AACZ;;;;;;;;;ACvLA,eAAsB,mBAAmB,UAAqC,UAAkB;CAC9F,OAAO,IAAI,SAAiB,YAAY;EACtC,IACG,oBAAoB,EACpB,GAAG,SAAS,KAAK,EACjB,UAAU,QAAQ,EAClB,oBAAoB,WAAW;GAE9B,QACE,OAAM,KAAK,UAAU;IACnB,MAAM,KAAK,QAAQ;IACnB,KAAK,KAAK,OAAO;IACjB,OAAO,KAAK,SAAS;IACrB,QAAQ,KAAK,UAAU;GACzB,EAAE,CACJ;EACF,CAAC,EACA,KAAK;CACV,CAAC;AACH"}
@@ -1 +1 @@
1
- {"version":3,"file":"client.mjs","names":[],"sources":["../src/client/message.ts","../src/client/app.ts","../src/client/async.ts","../src/client/page.ts","../src/client/request.ts","../src/client/ui.ts"],"sourcesContent":["import { promiseDelay } from '@cloudcome/utils-core/promise';\nimport { isString } from '@cloudcome/utils-core/type';\n\n/**\n * 显示 confirm 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniConfirm(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<boolean>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请确认',\n content: text,\n showCancel: true,\n confirmText,\n cancelText,\n ...options,\n success(result) {\n resolve(result.confirm);\n },\n });\n });\n });\n}\n\n/**\n * 显示 prompt 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniPrompt(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<string>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请输入',\n content: '',\n placeholderText: text,\n showCancel: true,\n confirmText,\n cancelText,\n editable: true,\n ...options,\n success(result) {\n resolve(result.content || '');\n },\n });\n });\n });\n}\n\n/**\n * 显示 alert 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniAlert(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'cancelText' | 'showCancel' | 'success' | 'content'>,\n) {\n const confirmText = options?.confirmText || '好';\n\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '提示',\n confirmText,\n cancelText: '',\n ...options,\n content: text,\n showCancel: false,\n success() {\n resolve();\n },\n });\n });\n });\n}\n\n/**\n * 显示 toast 提示\n * @param text 提示文本\n * @param icon 图标\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniToast(text: string, icon?: UniNamespace.ShowToastOptions['icon']): Promise<void>;\nexport function uniToast(text: string, options?: UniNamespace.ShowToastOptions): Promise<void>;\nexport function uniToast(\n text: string,\n iconOrOptions?: UniNamespace.ShowToastOptions['icon'] | UniNamespace.ShowToastOptions,\n): Promise<void> {\n const options = {} as UniNamespace.ShowToastOptions;\n\n if (isString(iconOrOptions)) {\n options.icon = iconOrOptions;\n } else {\n Object.assign(options, iconOrOptions);\n }\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(async () => {\n uni.showToast({\n title: text,\n duration: 2900,\n icon: options.icon || 'none',\n mask: false,\n });\n promiseDelay(3000).then(resolve);\n });\n });\n}\n\n/**\n * 显示 loading 提示\n * @param title 提示文本\n */\nexport function uniLoading(title = '') {\n uni.showLoading({\n title,\n mask: true,\n });\n}\n","import type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onHide, onShow } from '@dcloudio/uni-app';\nimport { ref } from 'vue';\nimport { uniConfirm } from './message';\n\n/**\n * 应用显示状态生命周期钩子函数\n *\n * 该函数用于监听应用从后台进入前台的生命周期事件。\n * 当应用从后台切换到前台时触发 onShow 回调,\n * 当应用从前台切换到后台时触发 onHide 回调。\n *\n * @param appShow - 应用显示状态变化时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * useAppShow(() => {\n * console.log('应用进入前台');\n *\n * // 可选:返回一个清理函数,在应用进入后台时执行\n * return () => {\n * console.log('应用进入后台');\n * };\n * });\n *\n * @example\n * // 带有异步操作的用法\n * useAppShow(async () => {\n * // 应用进入前台时刷新数据\n * await refreshUserData();\n *\n * // 返回清理函数\n * return () => {\n * // 应用进入后台时保存数据\n * saveUserData();\n * };\n * });\n */\nexport function useAppShow(appShow: HookListenerWithDispose) {\n _runLifeHook(onShow, onHide, appShow);\n}\n\n/**\n * 订阅模板消息\n * @param templateId 模板消息 ID 或 ID 列表\n * @returns Promise<boolean>\n */\nexport async function uniSubscribeNotice(templateId: string | string[]) {\n if (!uni.requestSubscribeMessage) return false;\n\n return new Promise<boolean>((resolve) => {\n const tmplIds = Array.isArray(templateId) ? templateId : [templateId];\n uni.requestSubscribeMessage({\n tmplIds,\n success(_res) {\n // 'accept'表示用户同意订阅该条id对应的模板消息,\n // 'reject'表示用户拒绝订阅该条id对应的模板消息,\n // 'ban'表示已被后台封禁,\n // 'filter'表示该模板因为模板标题同名被后台过滤\n const res = _res as unknown as Record<string, 'accept' | 'reject' | 'ban' | 'filter'>;\n let subscribed = false;\n\n for (const templateId of tmplIds) {\n if (res[templateId] === 'accept') {\n subscribed = true;\n break;\n }\n }\n\n resolve(subscribed);\n },\n fail() {\n resolve(false);\n },\n });\n });\n}\n\n/**\n * 监听应用更新状态\n */\nexport function useAppUpdate() {\n const hasUpdate = ref(false);\n const updateReady = ref(false);\n const updateManager = uni.getUpdateManager?.();\n\n updateManager?.onCheckForUpdate((res) => {\n // 请求完新版本信息的回调\n hasUpdate.value = Boolean(res.hasUpdate);\n });\n\n updateManager?.onUpdateReady(async () => {\n updateReady.value = true;\n\n const confirm = await uniConfirm('新版本已经准备好,是否重启应用?', {\n title: '更新提示',\n confirmText: '重启',\n });\n if (!confirm) return;\n\n updateManager.applyUpdate();\n });\n\n updateManager?.onUpdateFailed(() => {\n // 新的版本下载失败\n });\n\n return { hasUpdate, updateReady };\n}\n","import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport type UniFailErr = UniNamespace.GeneralCallbackResult & {\n errCode?: number;\n errno?: number;\n};\n\nexport type UniPromiseError = Error & {\n errCode: number;\n errNo: number;\n};\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param promise uni 异步函数的 Promise\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniPromise<T>(promise: Promise<T>): Promise<T> {\n try {\n const result = await promise;\n return result;\n } catch (err) {\n const res = err as unknown as UniFailErr;\n throw errorAssign(new Error(res.errMsg || '未知错误'), {\n errCode: res.errCode || -1,\n errNo: res.errno || -1,\n });\n }\n}\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param runner uni 异步函数的回调\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniCallback<T>(\n runner: (options: { success: (res: T) => void; fail: (err: UniFailErr) => void }) => unknown,\n) {\n return new Promise<T>((resolve, reject) => {\n runner({\n success(res) {\n resolve(res);\n },\n fail(err) {\n reject(\n errorAssign(new Error(err.errMsg || '未知错误'), {\n errCode: err.errCode || -1,\n errNo: err.errno || -1,\n }),\n );\n },\n });\n });\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onLoad, onPageHide, onPageShow, onUnload } from '@dcloudio/uni-app';\nimport { type Reactive, reactive } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n\n/**\n * 用于处理页面加载生命周期的 hook 函数\n *\n * 该函数会在页面加载时执行传入的回调函数,并在页面卸载时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onLoad 和 onUnload 生命周期的封装。\n *\n * @param {HookListenerWithDispose} load - 页面加载时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n *\n * // 返回一个清理函数,在页面卸载时执行\n * return () => {\n * console.log('页面将要卸载');\n * };\n * });\n *\n * @example\n * // 异步用法\n * usePageLoad(async () => {\n * const data = await fetchData();\n * console.log('获取到数据:', data);\n *\n * return () => {\n * console.log('清理资源');\n * };\n * });\n */\nexport function usePageLoad(load: HookListenerWithDispose) {\n _runLifeHook(onLoad, onUnload, load);\n}\n\n/**\n * 用于处理页面显示生命周期的 hook 函数\n *\n * 该函数会在页面显示时执行传入的回调函数,并在页面隐藏时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onPageShow 和 onPageHide 生命周期的封装。\n *\n * @param {HookListenerWithDispose} pageShow - 页面显示时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageShow(() => {\n * console.log('页面已显示');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageShow(() => {\n * console.log('页面已显示');\n *\n * // 返回一个清理函数,在页面隐藏时执行\n * return () => {\n * console.log('页面将要隐藏');\n * };\n * });\n */\nexport function usePageShow(pageShow: HookListenerWithDispose) {\n _runLifeHook(onPageShow, onPageHide, pageShow);\n}\n","import type { AnyArray, AnyFunction } from '@cloudcome/utils-core/types';\nimport {\n type UseRequestOptions,\n type UseRequestOutput,\n type UseRequestOutputFilled,\n useRequest,\n} from '@cloudcome/utils-vue/request';\nimport type { CloudMethodOutput, UniError } from '@/cloud';\nimport type { ClientDatabaseOutput } from '@/database';\nimport { parseCloudMethodOutput } from '../_helpers';\nimport { uniLoading, uniToast } from './message';\n\nexport type CreateUseCloudObjectOptions = {\n /**\n * 模拟云对象,用于单元测试\n * @private\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockServer?: any;\n\n /**\n * 回退错误信息\n * @default '请求失败'\n */\n fallbackErrorMessage?: string;\n\n /**\n * 请求开始前的回调函数\n */\n onBefore?: () => unknown;\n\n /**\n * 请求成功后的回调函数\n */\n onSuccess?: () => unknown;\n\n /**\n * 请求失败时的回调函数\n * @param err 错误信息\n */\n onError?: (err: UniError) => unknown;\n\n /**\n * 请求完成后的回调函数(无论成功或失败都会执行)\n */\n onAfter?: () => unknown;\n\n /**\n * 显示加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onShowLoading?: () => unknown;\n\n /**\n * 隐藏加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onHideLoading?: () => unknown;\n\n /**\n * 显示错误信息的回调函数,当配置了 showError 为 true 时会调用\n * @param err 错误信息\n */\n onShowError?: (err: UniError) => unknown;\n};\n\n/**\n * 云对象请求函数类型定义\n * @template F 云对象方法函数类型\n * @param input 云对象方法的参数数组\n * @returns 返回云对象方法执行结果的Promise\n */\nexport type CloudObjectRequest = <F extends AnyFunction>(\n ...input: Parameters<F>\n) => Promise<CloudMethodOutput<ReturnType<F>>>;\n\n/**\n * 用于调用云对象方法的配置选项类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethodOptions<I extends AnyArray, O> = Omit<UseRequestOptions<I, O>, 'onError'> & {\n /**\n * 请求发生错误时的回调函数\n * @param err 错误信息\n * @param inputs 请求输入参数\n */\n onError?: (err: UniError, ...inputs: I) => unknown;\n\n /**\n * 是否显示加载状态\n * @default false\n */\n showLoading?: boolean;\n\n /**\n * 是否显示错误信息\n * @default false\n */\n showError?: boolean;\n};\n\n/**\n * 用于调用云对象方法的hook函数类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethod<Api extends Record<string, AnyFunction>> = {\n /**\n * 重载签名:当提供 placeholder 选项时,返回包含初始值的输出类型\n * @param method 云对象方法名\n * @param caller 调用云对象方法的函数\n * @param options 包含 placeholder 的请求配置选项\n * @returns 返回包含初始值的请求输出\n */\n <K extends keyof Api, I extends AnyArray, O>(\n method: K,\n caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>,\n options: Omit<UseCloudMethodOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n ): UseRequestOutputFilled<I, O>;\n\n /**\n * 重载签名:当不提供 placeholder 选项时,返回普通输出类型\n * @param method 云对象方法名\n * @param caller 调用云对象方法的函数\n * @param options 可选的请求配置选项\n * @returns 返回普通的请求输出\n */\n <K extends keyof Api, I extends AnyArray, O>(\n method: K,\n caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>,\n options?: UseCloudMethodOptions<I, O>,\n ): UseRequestOutput<I, O>;\n};\n\n/**\n * 导入云对象并创建一个用于调用云对象的hook\n * @param objectName 云对象名称\n * @param importOptions 配置选项,包含模拟服务器、回退错误信息等\n * @returns 返回一个可用于调用云对象方法的hook函数\n */\nexport function importCloudObject<Api extends Record<string, AnyFunction>>(\n objectName: string,\n importOptions?: CreateUseCloudObjectOptions,\n) {\n const fallbackErrorMessage = importOptions?.fallbackErrorMessage || '请求失败';\n const server =\n importOptions?._mockServer ||\n uniCloud.importObject(objectName, {\n customUI: true,\n });\n const onShowLoading = importOptions?.onShowLoading || (() => uniLoading());\n const onHideLoading = importOptions?.onHideLoading || (() => uni.hideLoading());\n const onShowError = importOptions?.onShowError || ((err) => uniToast(err.message));\n\n /**\n * 用于调用云对象方法的hook函数\n * @template I 输入参数类型\n * @template O 输出结果类型\n * @param method 云对象方法名\n * @param caller 调用云对象的函数\n * @param options 配置选项,包含请求相关的配置\n * @returns 返回一个请求hook,用于处理云对象调用\n */\n const useCloudMethod: UseCloudMethod<Api> = (method, caller, options) => {\n // 使用请求hook处理云对象调用\n return useRequest(\n async (...inputs) => {\n const request = server[method];\n const output = await caller(request, ...inputs);\n return parseCloudMethodOutput(output, fallbackErrorMessage);\n },\n {\n ...options,\n async onBefore(...inputs) {\n if (options?.showLoading) onShowLoading();\n\n await importOptions?.onBefore?.();\n await options?.onBefore?.(...inputs);\n },\n async onSuccess(data, ...inputs) {\n await importOptions?.onSuccess?.();\n await options?.onSuccess?.(data, ...inputs);\n },\n async onError(err, ...inputs) {\n await importOptions?.onError?.(err as UniError);\n await options?.onError?.(err as UniError, ...inputs);\n\n if (options?.showError) {\n // 加延迟是尽量保证在 loading 隐藏后再显示错误信息\n setTimeout(() => {\n onShowError(err as UniError);\n });\n }\n },\n async onAfter(...inputs) {\n if (options?.showLoading) onHideLoading();\n\n await importOptions?.onAfter?.();\n await options?.onAfter?.(...inputs);\n },\n },\n );\n };\n\n return useCloudMethod;\n}\n\nexport type UseDatabaseOptions<I extends AnyArray, O> = UseRequestOptions<I, O> & {\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockDatabase?: any;\n};\n\n/**\n * 创建一个用于调用云数据库的hook\n * @param caller 调用云数据库的函数,接收数据库实例和输入参数,返回Promise\n * @param options 配置选项\n * @returns 返回一个请求hook,用于处理云数据库调用\n */\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options: Omit<UseDatabaseOptions<I, O>, 'placeholder'> & {\n placeholder: () => O;\n },\n): UseRequestOutputFilled<I, O>;\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O> {\n // 获取数据库实例,优先使用模拟数据库(用于测试),否则使用uniCloud数据库\n const db = options?._mockDatabase || uniCloud.database();\n return useRequest(async (...inputs: I) => {\n const { result } = await caller(db, ...inputs);\n if (!result.errCode) return result;\n throw new Error(result.errMsg || '请求失败');\n }, options);\n}\n","import type { ComponentInternalInstance } from 'vue';\n\nexport type Rect = {\n /**\n * 元素距离屏幕的左坐标,单位:px\n */\n left: number;\n /**\n * 元素距离屏幕的上坐标,单位:px\n */\n top: number;\n /**\n * 元素距离屏幕的宽度,单位:px\n */\n width: number;\n /**\n * 元素距离屏幕的高度,单位:px\n */\n height: number;\n};\n\n/**\n * 查询元素距离屏幕的矩形信息\n * @param instance 组件实例\n * @param selector 选择器\n * @returns 元素距离屏幕的矩形信息\n */\nexport async function querySelectorRects(instance: ComponentInternalInstance, selector: string) {\n return new Promise<Rect[]>((resolve) => {\n uni\n .createSelectorQuery()\n .in(instance.proxy)\n .selectAll(selector)\n .boundingClientRect((_rects) => {\n const rects = _rects as UniApp.NodeInfo[];\n resolve(\n rects.map((rect) => ({\n left: rect.left || 0,\n top: rect.top || 0,\n width: rect.width || 0,\n height: rect.height || 0,\n })),\n );\n })\n .exec();\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"client.mjs","names":[],"sources":["../src/client/message.ts","../src/client/app.ts","../src/client/async.ts","../src/client/page.ts","../src/client/request.ts","../src/client/ui.ts"],"sourcesContent":["import { promiseDelay } from '@cloudcome/utils-core/promise';\nimport { isString } from '@cloudcome/utils-core/type';\n\n/**\n * 显示 confirm 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniConfirm(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<boolean>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请确认',\n content: text,\n showCancel: true,\n confirmText,\n cancelText,\n ...options,\n success(result) {\n resolve(result.confirm);\n },\n });\n });\n });\n}\n\n/**\n * 显示 prompt 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniPrompt(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'showCancel' | 'success' | 'content' | 'editable'>,\n) {\n const cancelText = options?.cancelText || '取消';\n const confirmText = options?.confirmText || '确认';\n\n if (cancelText.length > 4) console.warn('微信小程序内不支持 cancelText 长度超过 4 个字符');\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<string>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '请输入',\n content: '',\n placeholderText: text,\n showCancel: true,\n confirmText,\n cancelText,\n editable: true,\n ...options,\n success(result) {\n resolve(result.content || '');\n },\n });\n });\n });\n}\n\n/**\n * 显示 alert 提示\n * @param text 提示文本\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniAlert(\n text: string,\n options?: Omit<UniNamespace.ShowModalOptions, 'cancelText' | 'showCancel' | 'success' | 'content'>,\n) {\n const confirmText = options?.confirmText || '好';\n\n if (confirmText.length > 4) console.warn('微信小程序内不支持 confirmText 长度超过 4 个字符');\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(() => {\n uni.showModal({\n title: '提示',\n confirmText,\n cancelText: '',\n ...options,\n content: text,\n showCancel: false,\n success() {\n resolve();\n },\n });\n });\n });\n}\n\n/**\n * 显示 toast 提示\n * @param text 提示文本\n * @param icon 图标\n * @param options 其他选项\n * @returns 提示完成后的 Promise\n */\nexport function uniToast(text: string, icon?: UniNamespace.ShowToastOptions['icon']): Promise<void>;\nexport function uniToast(text: string, options?: UniNamespace.ShowToastOptions): Promise<void>;\nexport function uniToast(\n text: string,\n iconOrOptions?: UniNamespace.ShowToastOptions['icon'] | UniNamespace.ShowToastOptions,\n): Promise<void> {\n const options = {} as UniNamespace.ShowToastOptions;\n\n if (isString(iconOrOptions)) {\n options.icon = iconOrOptions;\n } else {\n Object.assign(options, iconOrOptions);\n }\n\n return new Promise<void>((resolve) => {\n // 避免和 hideLoading 同时出现影响弹窗\n setTimeout(async () => {\n uni.showToast({\n title: text,\n duration: 2900,\n icon: options.icon || 'none',\n mask: false,\n });\n promiseDelay(3000).then(resolve);\n });\n });\n}\n\n/**\n * 显示 loading 提示\n * @param title 提示文本\n */\nexport function uniLoading(title = '') {\n uni.showLoading({\n title,\n mask: true,\n });\n}\n","import type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onHide, onShow } from '@dcloudio/uni-app';\nimport { ref } from 'vue';\nimport { uniConfirm } from './message';\n\n/**\n * 应用显示状态生命周期钩子函数\n *\n * 该函数用于监听应用从后台进入前台的生命周期事件。\n * 当应用从后台切换到前台时触发 onShow 回调,\n * 当应用从前台切换到后台时触发 onHide 回调。\n *\n * @param appShow - 应用显示状态变化时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * useAppShow(() => {\n * console.log('应用进入前台');\n *\n * // 可选:返回一个清理函数,在应用进入后台时执行\n * return () => {\n * console.log('应用进入后台');\n * };\n * });\n *\n * @example\n * // 带有异步操作的用法\n * useAppShow(async () => {\n * // 应用进入前台时刷新数据\n * await refreshUserData();\n *\n * // 返回清理函数\n * return () => {\n * // 应用进入后台时保存数据\n * saveUserData();\n * };\n * });\n */\nexport function useAppShow(appShow: HookListenerWithDispose) {\n _runLifeHook(onShow, onHide, appShow);\n}\n\n/**\n * 订阅模板消息\n * @param templateId 模板消息 ID 或 ID 列表\n * @returns Promise<boolean>\n */\nexport async function uniSubscribeNotice(templateId: string | string[]) {\n if (!uni.requestSubscribeMessage) return false;\n\n return new Promise<boolean>((resolve) => {\n const tmplIds = Array.isArray(templateId) ? templateId : [templateId];\n uni.requestSubscribeMessage({\n tmplIds,\n success(_res) {\n // 'accept'表示用户同意订阅该条id对应的模板消息,\n // 'reject'表示用户拒绝订阅该条id对应的模板消息,\n // 'ban'表示已被后台封禁,\n // 'filter'表示该模板因为模板标题同名被后台过滤\n const res = _res as unknown as Record<string, 'accept' | 'reject' | 'ban' | 'filter'>;\n let subscribed = false;\n\n for (const templateId of tmplIds) {\n if (res[templateId] === 'accept') {\n subscribed = true;\n break;\n }\n }\n\n resolve(subscribed);\n },\n fail() {\n resolve(false);\n },\n });\n });\n}\n\n/**\n * 监听应用更新状态\n */\nexport function useAppUpdate() {\n const hasUpdate = ref(false);\n const updateReady = ref(false);\n const updateManager = uni.getUpdateManager?.();\n\n updateManager?.onCheckForUpdate((res) => {\n // 请求完新版本信息的回调\n hasUpdate.value = Boolean(res.hasUpdate);\n });\n\n updateManager?.onUpdateReady(async () => {\n updateReady.value = true;\n\n const confirm = await uniConfirm('新版本已经准备好,是否重启应用?', {\n title: '更新提示',\n confirmText: '重启',\n });\n if (!confirm) return;\n\n updateManager.applyUpdate();\n });\n\n updateManager?.onUpdateFailed(() => {\n // 新的版本下载失败\n });\n\n return { hasUpdate, updateReady };\n}\n","import { errorAssign } from '@cloudcome/utils-core/error';\n\nexport type UniFailErr = UniNamespace.GeneralCallbackResult & {\n errCode?: number;\n errno?: number;\n};\n\nexport type UniPromiseError = Error & {\n errCode: number;\n errNo: number;\n};\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param promise uni 异步函数的 Promise\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniPromise<T>(promise: Promise<T>): Promise<T> {\n try {\n const result = await promise;\n return result;\n } catch (err) {\n const res = err as unknown as UniFailErr;\n throw errorAssign(new Error(res.errMsg || '未知错误'), {\n errCode: res.errCode || -1,\n errNo: res.errno || -1,\n });\n }\n}\n\n/**\n * 包装 uni 异步函数,返回 Promise 并处理错误\n * @param runner uni 异步函数的回调\n * @returns Promise<T>\n * @throws UniPromiseError\n */\nexport async function uniCallback<T>(\n runner: (options: { success: (res: T) => void; fail: (err: UniFailErr) => void }) => unknown,\n) {\n return new Promise<T>((resolve, reject) => {\n runner({\n success(res) {\n resolve(res);\n },\n fail(err) {\n reject(\n errorAssign(new Error(err.errMsg || '未知错误'), {\n errCode: err.errCode || -1,\n errNo: err.errno || -1,\n }),\n );\n },\n });\n });\n}\n","import type { AnyObject } from '@cloudcome/utils-core/types';\nimport type { HookListenerWithDispose } from '@cloudcome/utils-vue/component';\nimport { _runLifeHook } from '@cloudcome/utils-vue/shared';\nimport { onLoad, onPageHide, onPageShow, onUnload } from '@dcloudio/uni-app';\nimport { type Reactive, reactive } from 'vue';\n\n/**\n * 用于获取页面参数的 hook 函数\n * @template T - 页面参数对象的类型,继承自 AnyObject\n * @param {function} [onPageLoad] - 页面加载时的回调函数\n * @param {T} onLoad.query - 页面参数对象\n * @returns {T} 响应式的页面参数对象\n * @example\n * // 基本用法\n * const query = usePageQuery();\n *\n * // 带回调的用法\n * const query = usePageQuery((query) => {\n * console.log('页面参数:', query);\n * });\n *\n * // 指定参数类型\n * interface PageParams {\n * id: string;\n * name?: string;\n * }\n * const query = usePageQuery<PageParams>();\n */\nexport function usePageQuery<T extends AnyObject>(onPageLoad?: (query: Reactive<T>) => void) {\n const query = reactive<T>({} as T);\n\n onLoad((_query) => {\n Object.assign(query, _query);\n onPageLoad?.(query);\n });\n\n return query;\n}\n\n/**\n * 用于处理页面加载生命周期的 hook 函数\n *\n * 该函数会在页面加载时执行传入的回调函数,并在页面卸载时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onLoad 和 onUnload 生命周期的封装。\n *\n * @param {HookListenerWithDispose} load - 页面加载时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageLoad(() => {\n * console.log('页面已加载');\n *\n * // 返回一个清理函数,在页面卸载时执行\n * return () => {\n * console.log('页面将要卸载');\n * };\n * });\n *\n * @example\n * // 异步用法\n * usePageLoad(async () => {\n * const data = await fetchData();\n * console.log('获取到数据:', data);\n *\n * return () => {\n * console.log('清理资源');\n * };\n * });\n */\nexport function usePageLoad(load: HookListenerWithDispose) {\n _runLifeHook(onLoad, onUnload, load);\n}\n\n/**\n * 用于处理页面显示生命周期的 hook 函数\n *\n * 该函数会在页面显示时执行传入的回调函数,并在页面隐藏时执行清理操作(如果提供了清理函数)。\n * 它是 uni-app 中 onPageShow 和 onPageHide 生命周期的封装。\n *\n * @param {HookListenerWithDispose} pageShow - 页面显示时的回调函数,可以返回一个清理函数\n *\n * @example\n * // 基本用法\n * usePageShow(() => {\n * console.log('页面已显示');\n * });\n *\n * @example\n * // 带清理函数的用法\n * usePageShow(() => {\n * console.log('页面已显示');\n *\n * // 返回一个清理函数,在页面隐藏时执行\n * return () => {\n * console.log('页面将要隐藏');\n * };\n * });\n */\nexport function usePageShow(pageShow: HookListenerWithDispose) {\n _runLifeHook(onPageShow, onPageHide, pageShow);\n}\n","import type { AnyArray, AnyFunction } from '@cloudcome/utils-core/types';\nimport { type UseRequestOptions, type UseRequestOutput, useRequest } from '@cloudcome/utils-vue/request';\nimport type { CloudMethodOutput, UniError } from '@/cloud';\nimport type { ClientDatabaseOutput } from '@/database';\nimport { parseCloudMethodOutput } from '../_helpers';\nimport { uniLoading, uniToast } from './message';\n\nexport type CreateUseCloudObjectOptions = {\n /**\n * 模拟云对象,用于单元测试\n * @private\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockServer?: any;\n\n /**\n * 回退错误信息\n * @default '请求失败'\n */\n fallbackErrorMessage?: string;\n\n /**\n * 请求开始前的回调函数\n */\n onBefore?: () => unknown;\n\n /**\n * 请求成功后的回调函数\n */\n onSuccess?: () => unknown;\n\n /**\n * 请求失败时的回调函数\n * @param err 错误信息\n */\n onError?: (err: UniError) => unknown;\n\n /**\n * 请求完成后的回调函数(无论成功或失败都会执行)\n */\n onAfter?: () => unknown;\n\n /**\n * 显示加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onShowLoading?: () => unknown;\n\n /**\n * 隐藏加载状态的回调函数,当配置了 showLoading 为 true 时会调用\n */\n onHideLoading?: () => unknown;\n\n /**\n * 显示错误信息的回调函数,当配置了 showError 为 true 时会调用\n * @param err 错误信息\n */\n onShowError?: (err: UniError) => unknown;\n};\n\n/**\n * 云对象请求函数类型定义\n * @template F 云对象方法函数类型\n * @param input 云对象方法的参数数组\n * @returns 返回云对象方法执行结果的Promise\n */\nexport type CloudObjectRequest = <F extends AnyFunction>(\n ...input: Parameters<F>\n) => Promise<CloudMethodOutput<ReturnType<F>>>;\n\n/**\n * 用于调用云对象方法的配置选项类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethodOptions<I extends AnyArray, O> = Omit<UseRequestOptions<I, O>, 'onError'> & {\n /**\n * 请求发生错误时的回调函数\n * @param err 错误信息\n * @param inputs 请求输入参数\n */\n onError?: (err: UniError, ...inputs: I) => unknown;\n\n /**\n * 是否显示加载状态\n * @default false\n */\n showLoading?: boolean;\n\n /**\n * 是否显示错误信息\n * @default false\n */\n showError?: boolean;\n};\n\n/**\n * 用于调用云对象方法的hook函数类型定义\n * @template I 输入参数类型数组\n * @template O 输出结果类型\n */\nexport type UseCloudMethod<Api extends Record<string, AnyFunction>> = {\n <K extends keyof Api, I extends AnyArray, O>(\n method: K,\n caller: (request: Api[K], ...inputs: I) => Promise<CloudMethodOutput<O>>,\n options?: UseCloudMethodOptions<I, O>,\n ): UseRequestOutput<I, O>;\n};\n\n/**\n * 导入云对象并创建一个用于调用云对象的hook\n * @param objectName 云对象名称\n * @param importOptions 配置选项,包含模拟服务器、回退错误信息等\n * @returns 返回一个可用于调用云对象方法的hook函数\n */\nexport function importCloudObject<Api extends Record<string, AnyFunction>>(\n objectName: string,\n importOptions?: CreateUseCloudObjectOptions,\n) {\n const fallbackErrorMessage = importOptions?.fallbackErrorMessage || '请求失败';\n const server =\n importOptions?._mockServer ||\n uniCloud.importObject(objectName, {\n customUI: true,\n });\n const onShowLoading = importOptions?.onShowLoading || (() => uniLoading());\n const onHideLoading = importOptions?.onHideLoading || (() => uni.hideLoading());\n const onShowError = importOptions?.onShowError || ((err) => uniToast(err.message));\n\n /**\n * 用于调用云对象方法的hook函数\n * @template I 输入参数类型\n * @template O 输出结果类型\n * @param method 云对象方法名\n * @param caller 调用云对象的函数\n * @param options 配置选项,包含请求相关的配置\n * @returns 返回一个请求hook,用于处理云对象调用\n */\n const useCloudMethod: UseCloudMethod<Api> = (method, caller, options) => {\n // 使用请求hook处理云对象调用\n return useRequest(\n async (...inputs) => {\n const request = server[method];\n const output = await caller(request, ...inputs);\n return parseCloudMethodOutput(output, fallbackErrorMessage);\n },\n {\n ...options,\n async onBefore(...inputs) {\n if (options?.showLoading) onShowLoading();\n\n await importOptions?.onBefore?.();\n await options?.onBefore?.(...inputs);\n },\n async onSuccess(data, ...inputs) {\n await importOptions?.onSuccess?.();\n await options?.onSuccess?.(data, ...inputs);\n },\n async onError(err, ...inputs) {\n await importOptions?.onError?.(err as UniError);\n await options?.onError?.(err as UniError, ...inputs);\n\n if (options?.showError) {\n // 加延迟是尽量保证在 loading 隐藏后再显示错误信息\n setTimeout(() => {\n onShowError(err as UniError);\n });\n }\n },\n async onAfter(...inputs) {\n if (options?.showLoading) onHideLoading();\n\n await importOptions?.onAfter?.();\n await options?.onAfter?.(...inputs);\n },\n },\n );\n };\n\n return useCloudMethod;\n}\n\nexport type UseDatabaseOptions<I extends AnyArray, O> = UseRequestOptions<I, O> & {\n /**\n * 模拟数据库,用于单元测试\n */\n // biome-ignore lint/suspicious/noExplicitAny: 单测使用 any\n _mockDatabase?: any;\n};\n\n/**\n * 创建一个用于调用云数据库的hook\n * @param caller 调用云数据库的函数,接收数据库实例和输入参数,返回Promise\n * @param options 配置选项\n * @returns 返回一个请求hook,用于处理云数据库调用\n */\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O>;\nexport function useDatabase<I extends AnyArray, O>(\n caller: (db: UniCloud.Database, ...inputs: I) => Promise<ClientDatabaseOutput<O>>,\n options?: UseDatabaseOptions<I, O>,\n): UseRequestOutput<I, O> {\n // 获取数据库实例,优先使用模拟数据库(用于测试),否则使用uniCloud数据库\n const db = options?._mockDatabase || uniCloud.database();\n return useRequest(async (...inputs: I) => {\n const { result } = await caller(db, ...inputs);\n if (!result.errCode) return result;\n throw new Error(result.errMsg || '请求失败');\n }, options);\n}\n","import type { ComponentInternalInstance } from 'vue';\n\nexport type Rect = {\n /**\n * 元素距离屏幕的左坐标,单位:px\n */\n left: number;\n /**\n * 元素距离屏幕的上坐标,单位:px\n */\n top: number;\n /**\n * 元素距离屏幕的宽度,单位:px\n */\n width: number;\n /**\n * 元素距离屏幕的高度,单位:px\n */\n height: number;\n};\n\n/**\n * 查询元素距离屏幕的矩形信息\n * @param instance 组件实例\n * @param selector 选择器\n * @returns 元素距离屏幕的矩形信息\n */\nexport async function querySelectorRects(instance: ComponentInternalInstance, selector: string) {\n return new Promise<Rect[]>((resolve) => {\n uni\n .createSelectorQuery()\n .in(instance.proxy)\n .selectAll(selector)\n .boundingClientRect((_rects) => {\n const rects = _rects as UniApp.NodeInfo[];\n resolve(\n rects.map((rect) => ({\n left: rect.left || 0,\n top: rect.top || 0,\n width: rect.width || 0,\n height: rect.height || 0,\n })),\n );\n })\n .exec();\n });\n}\n"],"mappings":"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"}
@@ -152,11 +152,7 @@ export type CloudModuleOutput<T> = UniErrorData & T;
152
152
  * @param input 输入参数
153
153
  * @returns 返回包含输出数据的Promise
154
154
  */
155
- export type CloudMethod<I, O> = (
156
- /** 云对象上下文 */
157
- this: CloudObjectThis,
158
- /** 输入参数 */
159
- input: I) => Promise<CloudMethodOutput<O>>;
155
+ export type CloudMethod<I, O> = (input: I) => Promise<CloudMethodOutput<O>>;
160
156
  /**
161
157
  * 提取云对象方法输入参数类型
162
158
  * 用于从 UniCloudExpose<I, O> 中提取输入参数类型 I
@@ -167,8 +163,3 @@ export type ExtractCloudMethodInput<T> = T extends CloudMethod<infer I, infer _O
167
163
  * 用于从 UniCloudExpose<I, O> 中提取输出数据类型 O
168
164
  */
169
165
  export type ExtractCloudMethodData<T> = T extends CloudMethod<infer _I, infer O> ? O : never;
170
- /**
171
- * 提取云对象方法请求签名类型
172
- * 用于从 UniCloudExpose<I, O> 中提取函数签名 (input: I) => O
173
- */
174
- export type ExtractCloudMethodRequest<T> = T extends CloudMethod<infer I, infer O> ? (input: I) => Promise<CloudMethodOutput<O>> : never;
@@ -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(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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"}
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 (this: CloudObjectThis, 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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"}
@@ -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(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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"}
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 (this: CloudObjectThis, 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/database.cjs CHANGED
@@ -6,6 +6,9 @@ let _cloudcome_utils_core_type = require("@cloudcome/utils-core/type");
6
6
  let _cloudcome_utils_core_try = require("@cloudcome/utils-core/try");
7
7
  //#region src/database/_command.class.ts
8
8
  var DbBaseCommand = class {
9
+ _command;
10
+ _parameter;
11
+ _options;
9
12
  _isQuery = false;
10
13
  _isMutate = false;
11
14
  constructor(_command, _parameter, _options) {