@plolink/sdk 0.0.5 → 0.0.8

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.
Files changed (56) hide show
  1. package/README.md +40 -26
  2. package/dist/{chunk-4H4RACSE.js → chunk-LHNCGCWW.js} +137 -3
  3. package/dist/chunk-LHNCGCWW.js.map +1 -0
  4. package/dist/{chunk-NS3DJP2O.cjs → chunk-WFBN23AH.cjs} +141 -2
  5. package/dist/chunk-WFBN23AH.cjs.map +1 -0
  6. package/dist/client-DXKAtLg1.d.ts +848 -0
  7. package/dist/client-l6cekf09.d.cts +848 -0
  8. package/dist/common/index.cjs +18 -14
  9. package/dist/common/index.d.cts +126 -1
  10. package/dist/common/index.d.ts +126 -1
  11. package/dist/common/index.js +1 -1
  12. package/dist/index.cjs +751 -13
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.d.cts +410 -3
  15. package/dist/index.d.ts +410 -3
  16. package/dist/index.js +735 -3
  17. package/dist/index.js.map +1 -1
  18. package/dist/modules/billing/index.cjs +1 -1
  19. package/dist/modules/billing/index.d.cts +1 -1
  20. package/dist/modules/billing/index.d.ts +1 -1
  21. package/dist/modules/billing/index.js +1 -1
  22. package/dist/modules/rbac/index.d.cts +1 -1
  23. package/dist/modules/rbac/index.d.ts +1 -1
  24. package/dist/modules/team/index.d.cts +1 -1
  25. package/dist/modules/team/index.d.ts +1 -1
  26. package/dist/modules/video-psych-analysis/index.cjs +123 -4
  27. package/dist/modules/video-psych-analysis/index.cjs.map +1 -1
  28. package/dist/modules/video-psych-analysis/index.d.cts +231 -93
  29. package/dist/modules/video-psych-analysis/index.d.ts +231 -93
  30. package/dist/modules/video-psych-analysis/index.js +123 -4
  31. package/dist/modules/video-psych-analysis/index.js.map +1 -1
  32. package/dist/modules/virtual-account/index.d.cts +1 -1
  33. package/dist/modules/virtual-account/index.d.ts +1 -1
  34. package/package.json +1 -16
  35. package/dist/chunk-4H4RACSE.js.map +0 -1
  36. package/dist/chunk-NS3DJP2O.cjs.map +0 -1
  37. package/dist/client-CAjIQKPm.d.cts +0 -193
  38. package/dist/client-CwNikk7i.d.ts +0 -193
  39. package/dist/modules/agent/index.cjs +0 -21
  40. package/dist/modules/agent/index.cjs.map +0 -1
  41. package/dist/modules/agent/index.d.cts +0 -71
  42. package/dist/modules/agent/index.d.ts +0 -71
  43. package/dist/modules/agent/index.js +0 -19
  44. package/dist/modules/agent/index.js.map +0 -1
  45. package/dist/modules/chat/index.cjs +0 -20
  46. package/dist/modules/chat/index.cjs.map +0 -1
  47. package/dist/modules/chat/index.d.cts +0 -68
  48. package/dist/modules/chat/index.d.ts +0 -68
  49. package/dist/modules/chat/index.js +0 -18
  50. package/dist/modules/chat/index.js.map +0 -1
  51. package/dist/modules/psych/index.cjs +0 -20
  52. package/dist/modules/psych/index.cjs.map +0 -1
  53. package/dist/modules/psych/index.d.cts +0 -69
  54. package/dist/modules/psych/index.d.ts +0 -69
  55. package/dist/modules/psych/index.js +0 -18
  56. package/dist/modules/psych/index.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/modules/video-psych-analysis/index.ts"],"names":[],"mappings":";;;;AAwFO,IAAM,qBAAN,MAAyB;AAAA,EAG9B,YAAY,MAAA,EAAuB;AACjC,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuBA,MAAa,KAAK,MAAA,EAAgF;AAChG,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,IAAI,8BAAA,EAAgC,EAAE,QAAQ,CAAA;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAa,OAAO,MAAA,EAAmF;AACrG,IAAA,MAAM,EAAE,YAAA,EAAc,oBAAA,EAAsB,QAAQ,QAAA,EAAU,QAAA,EAAU,MAAK,GAAI,MAAA;AAGjF,IAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AAC9C,MAAA,MAAM,IAAI,YAAA,CAAa,gDAAA,EAAkD,gBAAgB,CAAA;AAAA,IAC3F;AAEA,IAAA,IAAI,CAAC,oBAAA,EAAsB;AACzB,MAAA,MAAM,IAAI,YAAA,CAAa,kCAAA,EAAoC,gBAAgB,CAAA;AAAA,IAC7E;AAEA,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,IAAI,YAAA,CAAa,oBAAA,EAAsB,gBAAgB,CAAA;AAAA,IAC/D;AAEA,IAAA,IAAI,QAAA,KAAa,MAAA,KAAc,QAAA,GAAW,CAAA,IAAK,WAAW,EAAA,CAAA,EAAK;AAC7D,MAAA,MAAM,IAAI,YAAA,CAAa,mCAAA,EAAqC,gBAAgB,CAAA;AAAA,IAC9E;AAEA,IAAA,OAAO,IAAA,CAAK,MAAA,CAAO,aAAA,CAAc,IAAA,CAAK,8BAAA,EAAgC;AAAA,MACpE,IAAA;AAAA,MACA,YAAA;AAAA,MACA,oBAAA;AAAA,MACA,MAAA;AAAA,MACA,QAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAa,UAAU,EAAA,EAA+C;AACpE,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,YAAA,CAAa,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,GAAA,CAAI,CAAA,6BAAA,EAAgC,EAAE,CAAA,CAAE,CAAA;AAAA,EAC3E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAa,MAAA,CAAO,EAAA,EAAY,MAAA,EAAmF;AACjH,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,YAAA,CAAa,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,IAAI,CAAC,MAAA,CAAO,IAAA,IAAQ,CAAC,OAAO,MAAA,EAAQ;AAClC,MAAA,MAAM,IAAI,YAAA,CAAa,sDAAA,EAAwD,gBAAgB,CAAA;AAAA,IACjG;AAEA,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,MAAM,CAAA,6BAAA,EAAgC,EAAE,IAAI,MAAM,CAAA;AAAA,EACrF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAiBA,MAAa,OAAO,EAAA,EAA0C;AAC5D,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,YAAA,CAAa,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,MAAA,CAAO,CAAA,6BAAA,EAAgC,EAAE,CAAA,CAAE,CAAA;AAAA,EAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBA,MAAa,WAAW,EAAA,EAAyC;AAC/D,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,YAAA,CAAa,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,GAAA,CAAI,CAAA,6BAAA,EAAgC,EAAE,CAAA,OAAA,CAAS,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkCO,mBAAA,CACL,IACA,cAAA,EACkC;AAClC,IAAA,MAAM,MAAA,GAAS,IAAI,MAAA,CAAiC;AAAA,MAClD,MAAM,YAAY;AAEhB,QAAA,MAAM,IAAA,CAAK,WAAW,EAAE,CAAA;AACxB,QAAA,OAAO,IAAA,CAAK,UAAU,EAAE,CAAA;AAAA,MAC1B,CAAA;AAAA,MACA,QAAA,EAAU,cAAA;AAAA,MACV,UAAA,EAAY,CAAC,MAAA,KAAW;AACtB,QAAA,OAAO,CAAC,WAAA,EAAa,QAAQ,CAAA,CAAE,QAAA,CAAS,OAAO,MAAM,CAAA;AAAA,MACvD,CAAA;AAAA,MACA,eAAA,EAAiB,GAAA;AAAA;AAAA,MACjB,WAAA,EAAa,GAAA;AAAA;AAAA,MACb,aAAA,EAAe,GAAA;AAAA,MACf,OAAA,EAAS,CAAC,KAAA,KAAU;AAClB,QAAA,IAAA,CAAK,OAAO,MAAA,CAAO,KAAA,CAAM,0BAA0B,EAAE,KAAA,EAAO,IAAI,CAAA;AAAA,MAClE;AAAA,KACD,CAAA;AAGD,IAAA,KAAK,OAAO,KAAA,EAAM;AAElB,IAAA,OAAO,MAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAa,SAAS,EAAA,EAAgC;AACpD,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,YAAA,CAAa,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,GAAA,CAAI,CAAA,6BAAA,EAAgC,EAAE,CAAA,MAAA,CAAQ,CAAA;AAAA,EACjF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAsBA,MAAa,UAAU,EAAA,EAAiC;AACtD,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,YAAA,CAAa,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,GAAA,CAAI,CAAA,6BAAA,EAAgC,EAAE,CAAA,OAAA,CAAS,CAAA;AAAA,EAClF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAyBA,MAAa,cAAc,EAAA,EAAqC;AAC9D,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,MAAM,IAAI,YAAA,CAAa,gBAAA,EAAkB,gBAAgB,CAAA;AAAA,IAC3D;AAEA,IAAA,OAAO,KAAK,MAAA,CAAO,aAAA,CAAc,GAAA,CAAI,CAAA,6BAAA,EAAgC,EAAE,CAAA,WAAA,CAAa,CAAA;AAAA,EACtF;AACF","file":"index.js","sourcesContent":["/**\n * 视频人物心理分析模块\n * \n * @description\n * 提供视频人物心理分析相关功能,包括:\n * - 创建分析任务\n * - 查询任务详情和状态\n * - 同步任务状态(轮询)\n * - 获取分析结果(文本/帧/段落维度)\n * - 生成心理分析报告\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * import { VideoPsychAnalysis } from '@plolink/sdk/video-psych-analysis';\n * \n * const client = new PlolinkClient({\n * mode: 'apiKey',\n * apiKey: 'your-api-key'\n * });\n * \n * const videoPsych = new VideoPsychAnalysis(client);\n * \n * // 创建分析任务\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2'],\n * referenceImageFileId: 'refImage1',\n * prompt: '请以专业心理分析师的视角进行分析',\n * frameFps: 3,\n * language: 'zh'\n * });\n * console.log(`任务已创建: ${result.id}`);\n * \n * // 轮询任务状态\n * const poller = videoPsych.watchAnalysisStatus(result.id, (detail) => {\n * console.log(`分析进度: ${detail.progress.done}/${detail.progress.total}`);\n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * }\n * });\n * ```\n * \n * @module video-psych-analysis\n */\n\nimport { PlolinkClient } from '../../core/client';\nimport { Poller } from '../../common/poller';\nimport { PlolinkError } from '../../core/error';\nimport type {\n CreateVideoPsychAnalysisParams,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextsData,\n FramesData,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n} from '../../types/video-psych-analysis';\n\nexport type {\n VideoPsychAnalysisStatus,\n CreateVideoPsychAnalysisParams,\n VideoInfo,\n AnalysisProgress,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextAnalysisItem,\n TextsData,\n FrameAnalysisItem,\n FramesData,\n ParagraphAnalysisItem,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n VideoPsychAnalysisSummary,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n} from '../../types/video-psych-analysis';\n\n/**\n * 视频人物心理分析模块\n */\nexport class VideoPsychAnalysis {\n private client: PlolinkClient;\n\n constructor(client: PlolinkClient) {\n this.client = client;\n }\n\n /**\n * 查询分析任务列表\n * \n * @param params - 查询参数(可选)\n * @returns 任务列表\n * @throws {PlolinkError} 当查询失败时抛出\n * \n * @example\n * ```typescript\n * // 查询所有已完成的任务\n * const result = await videoPsych.list({\n * status: 'COMPLETED',\n * page: 1,\n * pageSize: 20\n * });\n * console.log(`共 ${result.total} 个任务`);\n * result.list.forEach(item => {\n * console.log(`${item.name}: ${item.status}`);\n * });\n * ```\n */\n public async list(params?: ListVideoPsychAnalysesParams): Promise<ListVideoPsychAnalysesResponse> {\n return this.client.axiosInstance.get('/api/v1/video-psych-analysis', { params });\n }\n\n /**\n * 创建视频心理分析任务\n * \n * @param params - 创建参数\n * @returns 创建结果,包含任务ID和初始状态\n * @throws {PlolinkError} 当参数验证失败或创建失败时抛出\n * \n * @example\n * ```typescript\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2', 'file3'],\n * referenceImageFileId: 'refImage1',\n * prompt: '请以专业心理分析师的视角,分析候选人的情绪、态度和心理状态',\n * frameFps: 3,\n * language: 'zh'\n * });\n * console.log(`任务ID: ${result.id}, 状态: ${result.status}`);\n * ```\n */\n public async create(params: CreateVideoPsychAnalysisParams): Promise<CreateVideoPsychAnalysisResponse> {\n const { videoFileIds, referenceImageFileId, prompt, frameFps, language, name } = params;\n\n // 参数验证\n if (!videoFileIds || videoFileIds.length === 0) {\n throw new PlolinkError('videoFileIds is required and must not be empty', 'INVALID_PARAMS');\n }\n\n if (!referenceImageFileId) {\n throw new PlolinkError('referenceImageFileId is required', 'INVALID_PARAMS');\n }\n\n if (!prompt) {\n throw new PlolinkError('prompt is required', 'INVALID_PARAMS');\n }\n\n if (frameFps !== undefined && (frameFps < 1 || frameFps > 30)) {\n throw new PlolinkError('frameFps must be between 1 and 30', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.post('/api/v1/video-psych-analysis', {\n name,\n videoFileIds,\n referenceImageFileId,\n prompt,\n frameFps,\n language,\n });\n }\n\n /**\n * 获取分析任务详情\n * \n * @param id - 任务ID\n * @returns 任务详情信息\n * @throws {PlolinkError} 当任务不存在或无权访问时抛出\n * \n * @example\n * ```typescript\n * const detail = await videoPsych.getDetail('analysis_123');\n * console.log(`任务: ${detail.name}`);\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total}`);\n * \n * if (detail.reportContent) {\n * console.log('报告已生成');\n * }\n * ```\n */\n public async getDetail(id: string): Promise<VideoPsychAnalysisDetail> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 更新分析任务\n * \n * @description\n * 更新分析任务的基本信息(仅限 PENDING 和 FAILED 状态的任务)。\n * \n * @param id - 任务ID\n * @param params - 更新参数\n * @returns 更新后的任务信息\n * @throws {PlolinkError} 当任务不存在、状态不允许更新或更新失败时抛出\n * \n * @example\n * ```typescript\n * const updated = await videoPsych.update('analysis_123', {\n * name: '李四的心理分析',\n * prompt: '请以临床心理学专家的视角进行分析'\n * });\n * console.log(`已更新: ${updated.name}`);\n * ```\n */\n public async update(id: string, params: UpdateVideoPsychAnalysisParams): Promise<UpdateVideoPsychAnalysisResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n if (!params.name && !params.prompt) {\n throw new PlolinkError('At least one field (name or prompt) must be provided', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.patch(`/api/v1/video-psych-analysis/${id}`, params);\n }\n\n /**\n * 删除分析任务\n * \n * @description\n * 删除分析任务(软删除)。\n * \n * @param id - 任务ID\n * @throws {PlolinkError} 当任务不存在或删除失败时抛出\n * \n * @example\n * ```typescript\n * await videoPsych.delete('analysis_123');\n * console.log('任务已删除');\n * ```\n */\n public async delete(id: string): Promise<{ message: string }> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.delete(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 同步任务状态\n * \n * @description\n * 主动触发后端从 AI TOOLS API 同步最新状态和中间结果。\n * \n * **注意**:通常不需要手动调用此方法,系统会每30秒自动轮询同步所有非完成态的任务。\n * \n * @param id - 任务ID\n * @returns 同步后的状态信息\n * @throws {PlolinkError} 当任务不存在或同步失败时抛出\n * \n * @example\n * ```typescript\n * const status = await videoPsych.syncStatus('analysis_123');\n * console.log(`当前状态: ${status.status}`);\n * console.log(`进度: ${status.progress.done}/${status.progress.total}`);\n * ```\n */\n public async syncStatus(id: string): Promise<SyncStatusResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/status`);\n }\n\n /**\n * 轮询分析任务状态\n * \n * @description\n * 创建一个轮询器持续监听任务状态变化,直到任务达到终态(COMPLETED/FAILED)。\n * 使用指数退避策略,初始间隔5秒,最大间隔30秒。\n * \n * @param id - 任务ID\n * @param onStatusChange - 状态变化回调函数\n * @returns Poller实例,可用于手动停止轮询\n * \n * @example\n * ```typescript\n * const poller = videoPsych.watchAnalysisStatus('analysis_123', (detail) => {\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total} (${detail.progress.stage})`);\n * \n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * } else if (detail.status === 'FAILED') {\n * console.error(`分析失败: ${detail.errorMessage}`);\n * }\n * });\n * \n * // 开始轮询\n * poller.start();\n * \n * // 需要时可以手动停止\n * // poller.stop();\n * ```\n */\n public watchAnalysisStatus(\n id: string,\n onStatusChange: (detail: VideoPsychAnalysisDetail) => void\n ): Poller<VideoPsychAnalysisDetail> {\n const poller = new Poller<VideoPsychAnalysisDetail>({\n task: async () => {\n // 先同步状态,再获取详情\n await this.syncStatus(id);\n return this.getDetail(id);\n },\n onResult: onStatusChange,\n shouldStop: (detail) => {\n return ['COMPLETED', 'FAILED'].includes(detail.status);\n },\n initialInterval: 5000, // 5秒\n maxInterval: 30000, // 30秒\n backoffFactor: 1.5,\n onError: (error) => {\n this.client.logger.error('Analysis polling error', { error, id });\n },\n });\n\n // 自动启动\n void poller.start();\n\n return poller;\n }\n\n /**\n * 获取文本维度分析结果\n * \n * @param id - 任务ID\n * @returns 文本维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const texts = await videoPsych.getTexts('analysis_123');\n * console.log(`共 ${texts.total} 条文本`);\n * texts.items.forEach(item => {\n * console.log(`${item.start_time}s: ${item.text}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getTexts(id: string): Promise<TextsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/texts`);\n }\n\n /**\n * 获取帧维度分析结果\n * \n * @param id - 任务ID\n * @returns 帧维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const frames = await videoPsych.getFrames('analysis_123');\n * console.log(`共 ${frames.total} 帧`);\n * frames.items.forEach(item => {\n * console.log(`${item.timestamp}s: ${item.image_url}`);\n * if (item.vision_result) {\n * console.log(` 表情: ${item.vision_result.expression}`);\n * console.log(` 动作: ${item.vision_result.action}`);\n * }\n * });\n * ```\n */\n public async getFrames(id: string): Promise<FramesData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/frames`);\n }\n\n /**\n * 获取段落分析结果\n * \n * @param id - 任务ID\n * @returns 段落分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const paragraphs = await videoPsych.getParagraphs('analysis_123');\n * console.log(`共 ${paragraphs.total} 段`);\n * paragraphs.items.forEach(item => {\n * console.log(`段落 ${item.id}:`);\n * console.log(` 时间: ${item.start_time}s - ${item.end_time}s`);\n * console.log(` 内容: ${item.text}`);\n * console.log(` 摘要: ${item.summary}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getParagraphs(id: string): Promise<ParagraphsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/paragraphs`);\n }\n}\n"]}
1
+ {"version":3,"sources":["../../../src/modules/video-psych-analysis/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * 视频人物心理分析模块\n * \n * @description\n * 提供视频人物心理分析相关功能,包括:\n * - 创建分析任务\n * - 查询任务详情和状态\n * - 同步任务状态(轮询)\n * - 获取分析结果(文本/帧/段落维度)\n * - 生成心理分析报告\n * \n * @example\n * ```typescript\n * import { PlolinkClient } from '@plolink/sdk';\n * import { VideoPsychAnalysis } from '@plolink/sdk/video-psych-analysis';\n * \n * const client = new PlolinkClient({\n * mode: 'apiKey',\n * apiKey: 'your-api-key'\n * });\n * \n * const videoPsych = new VideoPsychAnalysis(client);\n * \n * // 创建分析任务\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2'],\n * referenceImageFileId: 'refImage1',\n * prompt: '视频是某公司 CEO 的公开演讲,请分析他对某话题的真实态度',\n * frameFps: 3,\n * language: 'zh-CN'\n * });\n * console.log(`任务已创建: ${result.id}`);\n * \n * // 轮询任务状态\n * const poller = videoPsych.watchAnalysisStatus(result.id, (detail) => {\n * console.log(`分析进度: ${detail.progress.done}/${detail.progress.total}`);\n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * }\n * });\n * ```\n * \n * @module video-psych-analysis\n */\n\nimport { PlolinkClient } from '../../core/client';\nimport { Poller } from '../../common/poller';\nimport { PlolinkError } from '../../core/error';\nimport type {\n CreateVideoPsychAnalysisParams,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextsData,\n FramesData,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n VideoPsychAnalysisConfig,\n} from '../../types/video-psych-analysis';\n\nexport type {\n VideoPsychAnalysisStatus,\n CreateVideoPsychAnalysisParams,\n VideoInfo,\n AnalysisProgress,\n FileInfo,\n CreateVideoPsychAnalysisResponse,\n VideoPsychAnalysisDetail,\n SyncStatusResponse,\n TextAnalysisItem,\n TextsData,\n FrameAnalysisItem,\n FramesData,\n ParagraphAnalysisItem,\n ParagraphsData,\n ListVideoPsychAnalysesParams,\n VideoPsychAnalysisSummary,\n ListVideoPsychAnalysesResponse,\n UpdateVideoPsychAnalysisParams,\n UpdateVideoPsychAnalysisResponse,\n LanguageOption,\n VideoPsychAnalysisConfig,\n} from '../../types/video-psych-analysis';\n\n/**\n * 视频人物心理分析模块\n */\nexport class VideoPsychAnalysis {\n private client: PlolinkClient;\n\n constructor(client: PlolinkClient) {\n this.client = client;\n }\n\n /**\n * 获取视频心理分析配置\n * \n * @returns 配置信息(包括语言选项等)\n * \n * @example\n * ```typescript\n * const config = await videoPsych.getConfig();\n * console.log('语言选项:', config.languageOptions);\n * console.log('默认语言:', config.defaultLanguage);\n * ```\n */\n public async getConfig(): Promise<VideoPsychAnalysisConfig> {\n return this.client.axiosInstance.get('/api/v1/video-psych-analysis/config');\n }\n\n /**\n * 查询分析任务列表\n * \n * @param params - 查询参数(可选)\n * @returns 任务列表\n * @throws {PlolinkError} 当查询失败时抛出\n * \n * @example\n * ```typescript\n * // 查询所有已完成的任务\n * const result = await videoPsych.list({\n * status: 'COMPLETED',\n * page: 1,\n * pageSize: 20\n * });\n * console.log(`共 ${result.total} 个任务`);\n * result.list.forEach(item => {\n * console.log(`${item.name}: ${item.status}`);\n * });\n * ```\n */\n public async list(params?: ListVideoPsychAnalysesParams): Promise<ListVideoPsychAnalysesResponse> {\n return this.client.axiosInstance.get('/api/v1/video-psych-analysis', { params });\n }\n\n /**\n * 创建视频心理分析任务\n * \n * @param params - 创建参数\n * @returns 创建结果,包含任务ID和初始状态\n * @throws {PlolinkError} 当参数验证失败或创建失败时抛出\n * \n * @example\n * ```typescript\n * const result = await videoPsych.create({\n * name: '候选人A面试分析',\n * videoFileIds: ['file1', 'file2', 'file3'],\n * referenceImageFileId: 'refImage1',\n * prompt: '请以专业心理分析师的视角,分析候选人的情绪、态度和心理状态',\n * frameFps: 3,\n * language: 'zh'\n * });\n * console.log(`任务ID: ${result.id}, 状态: ${result.status}`);\n * ```\n */\n public async create(params: CreateVideoPsychAnalysisParams): Promise<CreateVideoPsychAnalysisResponse> {\n const { videoFileIds, referenceImageFileId, prompt, familyBackground, frameFps, language, name } = params;\n\n // 参数验证\n if (!videoFileIds || videoFileIds.length === 0) {\n throw new PlolinkError('videoFileIds is required and must not be empty', 'INVALID_PARAMS');\n }\n\n if (!referenceImageFileId) {\n throw new PlolinkError('referenceImageFileId is required', 'INVALID_PARAMS');\n }\n\n if (!prompt) {\n throw new PlolinkError('prompt is required', 'INVALID_PARAMS');\n }\n\n if (frameFps !== undefined && (frameFps < 1 || frameFps > 30)) {\n throw new PlolinkError('frameFps must be between 1 and 30', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.post('/api/v1/video-psych-analysis', {\n name,\n videoFileIds,\n referenceImageFileId,\n prompt,\n familyBackground,\n frameFps,\n language,\n });\n }\n\n /**\n * 获取分析任务详情\n * \n * @param id - 任务ID\n * @returns 任务详情信息\n * @throws {PlolinkError} 当任务不存在或无权访问时抛出\n * \n * @example\n * ```typescript\n * const detail = await videoPsych.getDetail('analysis_123');\n * console.log(`任务: ${detail.name}`);\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total}`);\n * \n * if (detail.reportContent) {\n * console.log('报告已生成');\n * }\n * ```\n */\n public async getDetail(id: string): Promise<VideoPsychAnalysisDetail> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 获取视频元数据信息\n * \n * @description\n * 获取任务的视频元数据信息(videoInfo)。在异步模式下,任务创建时 videoInfo 为空,\n * 需要等待任务进入 PROCESSING 状态后由定时任务自动同步。\n * \n * **使用场景**:\n * - 获取视频的宽高、时长、编码等信息用于界面展示\n * - 在任务创建后轮询此接口直到获取到 videoInfo\n * \n * **注意**:\n * - 如果视频信息尚未生成,返回 null\n * - 建议配合任务状态查询使用,等待状态变为 PROCESSING 后再查询\n * \n * @param id - 任务ID\n * @returns 视频元数据信息,如果尚未生成则返回 null\n * @throws {PlolinkError} 当任务不存在时抛出\n * \n * @example\n * ```typescript\n * // 轮询获取 videoInfo\n * const checkVideoInfo = async (analysisId: string) => {\n * const maxAttempts = 60;\n * let attempt = 0;\n * \n * while (attempt < maxAttempts) {\n * const videoInfo = await videoPsych.getVideoInfo(analysisId);\n * \n * if (videoInfo) {\n * console.log(`视频信息: ${videoInfo.width}x${videoInfo.height}`);\n * console.log(`时长: ${videoInfo.duration}s`);\n * console.log(`文件大小: ${(videoInfo.file_size / 1024 / 1024).toFixed(2)}MB`);\n * return videoInfo;\n * }\n * \n * console.log('视频信息还在处理中...');\n * await new Promise(resolve => setTimeout(resolve, 5000)); // 等待5秒\n * attempt++;\n * }\n * \n * throw new Error('获取视频信息超时');\n * };\n * \n * const info = await checkVideoInfo('analysis_123');\n * ```\n */\n public async getVideoInfo(id: string): Promise<import('../../types/video-psych-analysis').VideoInfo | null> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n try {\n const response: { taskId: string; videoInfo: import('../../types/video-psych-analysis').VideoInfo | null } = await this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/video-info`);\n return response.videoInfo || null;\n } catch (error: unknown) {\n // 如果是 PlolinkError 且 HTTP 状态码为 404(视频信息尚未生成),返回 null\n // 注意:axios interceptor 会将 HTTP 状态码作为 PlolinkError.code\n if (error instanceof PlolinkError && error.code === 404) {\n return null;\n }\n // 其他错误继续抛出\n throw error;\n }\n }\n\n /**\n * 更新分析任务\n * \n * @description\n * 更新分析任务的基本信息(仅限 PENDING 和 FAILED 状态的任务)。\n * \n * @param id - 任务ID\n * @param params - 更新参数\n * @returns 更新后的任务信息\n * @throws {PlolinkError} 当任务不存在、状态不允许更新或更新失败时抛出\n * \n * @example\n * ```typescript\n * const updated = await videoPsych.update('analysis_123', {\n * name: '李四的心理分析',\n * prompt: '请以临床心理学专家的视角进行分析'\n * });\n * console.log(`已更新: ${updated.name}`);\n * ```\n */\n public async update(id: string, params: UpdateVideoPsychAnalysisParams): Promise<UpdateVideoPsychAnalysisResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n if (!params.name && !params.prompt && !params.familyBackground) {\n throw new PlolinkError('At least one field (name, prompt, or familyBackground) must be provided', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.patch(`/api/v1/video-psych-analysis/${id}`, params);\n }\n\n /**\n * 删除分析任务\n * \n * @description\n * 删除分析任务(软删除)。\n * \n * @param id - 任务ID\n * @throws {PlolinkError} 当任务不存在或删除失败时抛出\n * \n * @example\n * ```typescript\n * await videoPsych.delete('analysis_123');\n * console.log('任务已删除');\n * ```\n */\n public async delete(id: string): Promise<{ message: string }> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.delete(`/api/v1/video-psych-analysis/${id}`);\n }\n\n /**\n * 重试失败的分析任务\n * \n * @description\n * 对失败(FAILED)状态的任务进行重试,使用原有参数重新提交到AI引擎进行分析。\n * 重试会清空之前的错误信息和分析结果,重新开始完整的分析流程。\n * \n * **注意**:\n * - 只能重试状态为 FAILED 的任务\n * - 重试后任务状态会重置为 PENDING\n * - 会清空之前的分析结果和报告内容\n * - 建议配合 `watchAnalysisStatus()` 方法监听重试后的任务状态\n * \n * @param id - 任务ID\n * @returns 更新后的任务信息\n * @throws {PlolinkError} 当任务不存在、状态不是FAILED或重试失败时抛出\n * \n * @example\n * ```typescript\n * // 重试失败的任务\n * const result = await videoPsych.retry('analysis_123');\n * console.log(`任务已重新提交: ${result.id}`);\n * console.log(`当前状态: ${result.status}`);\n * \n * // 监听重试后的任务状态\n * const poller = videoPsych.watchAnalysisStatus(result.id, (detail) => {\n * console.log(`重试进度: ${detail.progress.done}/${detail.progress.total}`);\n * if (detail.status === 'COMPLETED') {\n * console.log('重试成功,分析完成!');\n * } else if (detail.status === 'FAILED') {\n * console.error('重试后仍失败');\n * }\n * });\n * poller.start();\n * ```\n */\n public async retry(id: string): Promise<VideoPsychAnalysisDetail> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.post(`/api/v1/video-psych-analysis/${id}/retry`);\n }\n\n /**\n * 同步任务状态\n * \n * @description\n * 主动触发后端从 AI TOOLS API 同步最新状态和中间结果。\n * \n * **注意**:通常不需要手动调用此方法,系统会每30秒自动轮询同步所有非完成态的任务。\n * \n * @param id - 任务ID\n * @returns 同步后的状态信息\n * @throws {PlolinkError} 当任务不存在或同步失败时抛出\n * \n * @example\n * ```typescript\n * const status = await videoPsych.syncStatus('analysis_123');\n * console.log(`当前状态: ${status.status}`);\n * console.log(`进度: ${status.progress.done}/${status.progress.total}`);\n * ```\n */\n public async syncStatus(id: string): Promise<SyncStatusResponse> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/status`);\n }\n\n /**\n * 轮询分析任务状态\n * \n * @description\n * 创建一个轮询器持续监听任务状态变化,直到任务达到终态(COMPLETED/FAILED)。\n * 使用指数退避策略,初始间隔5秒,最大间隔30秒。\n * \n * @param id - 任务ID\n * @param onStatusChange - 状态变化回调函数\n * @returns Poller实例,可用于手动停止轮询\n * \n * @example\n * ```typescript\n * const poller = videoPsych.watchAnalysisStatus('analysis_123', (detail) => {\n * console.log(`状态: ${detail.status}`);\n * console.log(`进度: ${detail.progress.done}/${detail.progress.total} (${detail.progress.stage})`);\n * \n * if (detail.status === 'COMPLETED') {\n * console.log('分析完成,报告已生成!');\n * console.log(detail.reportContent);\n * } else if (detail.status === 'FAILED') {\n * console.error(`分析失败: ${detail.errorMessage}`);\n * }\n * });\n * \n * // 开始轮询\n * poller.start();\n * \n * // 需要时可以手动停止\n * // poller.stop();\n * ```\n */\n public watchAnalysisStatus(\n id: string,\n onStatusChange: (detail: VideoPsychAnalysisDetail) => void\n ): Poller<VideoPsychAnalysisDetail> {\n const poller = new Poller<VideoPsychAnalysisDetail>({\n task: async () => {\n // 先同步状态,再获取详情\n await this.syncStatus(id);\n return this.getDetail(id);\n },\n onResult: onStatusChange,\n shouldStop: (detail) => {\n return ['COMPLETED', 'FAILED'].includes(detail.status);\n },\n initialInterval: 5000, // 5秒\n maxInterval: 30000, // 30秒\n backoffFactor: 1.5,\n onError: (error) => {\n this.client.logger.error('Analysis polling error', { error, id });\n },\n });\n\n // 自动启动\n void poller.start();\n\n return poller;\n }\n\n /**\n * 获取文本维度分析结果\n * \n * @param id - 任务ID\n * @returns 文本维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const texts = await videoPsych.getTexts('analysis_123');\n * console.log(`共 ${texts.total} 条文本`);\n * texts.items.forEach(item => {\n * console.log(`${item.start_time}s: ${item.text}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getTexts(id: string): Promise<TextsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/texts`);\n }\n\n /**\n * 获取帧维度分析结果\n * \n * @param id - 任务ID\n * @returns 帧维度分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const frames = await videoPsych.getFrames('analysis_123');\n * console.log(`共 ${frames.total} 帧`);\n * frames.items.forEach(item => {\n * console.log(`${item.timestamp}s: ${item.image_url}`);\n * if (item.vision_result) {\n * console.log(` 表情: ${item.vision_result.expression}`);\n * console.log(` 动作: ${item.vision_result.action}`);\n * }\n * });\n * ```\n */\n public async getFrames(id: string): Promise<FramesData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/frames`);\n }\n\n /**\n * 获取段落分析结果\n * \n * @param id - 任务ID\n * @returns 段落分析数据\n * @throws {PlolinkError} 当任务不存在或分析未完成时抛出\n * \n * @example\n * ```typescript\n * const paragraphs = await videoPsych.getParagraphs('analysis_123');\n * console.log(`共 ${paragraphs.total} 段`);\n * paragraphs.items.forEach(item => {\n * console.log(`段落 ${item.id}:`);\n * console.log(` 时间: ${item.start_time}s - ${item.end_time}s`);\n * console.log(` 内容: ${item.text}`);\n * console.log(` 摘要: ${item.summary}`);\n * if (item.nlp_result) {\n * console.log(` 情绪: ${item.nlp_result.speaker_emotion}`);\n * console.log(` 态度: ${item.nlp_result.real_attitude}`);\n * }\n * });\n * ```\n */\n public async getParagraphs(id: string): Promise<ParagraphsData> {\n if (!id) {\n throw new PlolinkError('id is required', 'INVALID_PARAMS');\n }\n\n return this.client.axiosInstance.get(`/api/v1/video-psych-analysis/${id}/paragraphs`);\n }\n}\n"]}
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CAjIQKPm.cjs';
1
+ import { P as PlolinkClient } from '../../client-l6cekf09.cjs';
2
2
  import { A as AssignRoleParams } from '../../shared-6ZepUSPW.cjs';
3
3
  import '../../core-77EbLgbp.cjs';
4
4
  import 'axios';
@@ -1,4 +1,4 @@
1
- import { P as PlolinkClient } from '../../client-CwNikk7i.js';
1
+ import { P as PlolinkClient } from '../../client-DXKAtLg1.js';
2
2
  import { A as AssignRoleParams } from '../../shared-6ZepUSPW.js';
3
3
  import '../../core-77EbLgbp.js';
4
4
  import 'axios';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plolink/sdk",
3
- "version": "0.0.5",
3
+ "version": "0.0.8",
4
4
  "description": "Plolink 开放平台官方 SDK",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -21,21 +21,6 @@
21
21
  "import": "./dist/modules/billing/index.js",
22
22
  "require": "./dist/modules/billing/index.cjs"
23
23
  },
24
- "./agent": {
25
- "types": "./dist/modules/agent/index.d.ts",
26
- "import": "./dist/modules/agent/index.js",
27
- "require": "./dist/modules/agent/index.cjs"
28
- },
29
- "./psych": {
30
- "types": "./dist/modules/psych/index.d.ts",
31
- "import": "./dist/modules/psych/index.js",
32
- "require": "./dist/modules/psych/index.cjs"
33
- },
34
- "./chat": {
35
- "types": "./dist/modules/chat/index.d.ts",
36
- "import": "./dist/modules/chat/index.js",
37
- "require": "./dist/modules/chat/index.cjs"
38
- },
39
24
  "./virtual-account": {
40
25
  "types": "./dist/modules/virtual-account/index.d.ts",
41
26
  "import": "./dist/modules/virtual-account/index.js",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/common/hooks.ts","../src/common/adapter.ts"],"names":[],"mappings":"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","file":"chunk-4H4RACSE.js","sourcesContent":["/**\n * 事件处理函数类型\n */\ntype EventHandler<T = unknown> = (data: T) => void;\n\n/**\n * 事件处理器映射类型\n */\ntype EventHandlerMap = Map<string, Set<EventHandler>>;\n\n/**\n * 事件发射器基础类\n * \n * @description\n * 提供简单的事件订阅/发布机制,用于业务模块的状态变化通知。\n * 支持类型安全的事件处理,适用于状态变化、进度更新等场景。\n * \n * @example\n * ```typescript\n * // 创建事件发射器\n * const emitter = new EventEmitter();\n * \n * // 订阅事件\n * const unsubscribe = emitter.on('status-change', (data) => {\n * console.log('Status changed:', data);\n * });\n * \n * // 触发事件\n * emitter.emit('status-change', { status: 'completed' });\n * \n * // 取消订阅\n * unsubscribe();\n * \n * // 一次性事件\n * emitter.once('complete', (data) => {\n * console.log('Completed:', data);\n * });\n * ```\n */\nexport class EventEmitter {\n /**\n * 事件处理器映射表\n */\n private handlers: EventHandlerMap = new Map();\n\n /**\n * 一次性事件处理器集合\n */\n private onceHandlers: EventHandlerMap = new Map();\n\n /**\n * 订阅事件\n * \n * @param event - 事件名称\n * @param handler - 事件处理函数\n * @returns 取消订阅的函数\n * \n * @example\n * ```typescript\n * const unsubscribe = emitter.on('data', (payload) => {\n * console.log('Received:', payload);\n * });\n * \n * // 不再需要时取消订阅\n * unsubscribe();\n * ```\n */\n public on<T = unknown>(event: string, handler: EventHandler<T>): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n\n const handlers = this.handlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // 返回取消订阅函数\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n /**\n * 订阅一次性事件\n * \n * @description\n * 事件处理函数只会执行一次,执行后自动取消订阅。\n * \n * @param event - 事件名称\n * @param handler - 事件处理函数\n * @returns 取消订阅的函数\n * \n * @example\n * ```typescript\n * emitter.once('complete', (result) => {\n * console.log('Task completed:', result);\n * });\n * ```\n */\n public once<T = unknown>(event: string, handler: EventHandler<T>): () => void {\n if (!this.onceHandlers.has(event)) {\n this.onceHandlers.set(event, new Set());\n }\n\n const handlers = this.onceHandlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // 返回取消订阅函数\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.onceHandlers.delete(event);\n }\n };\n }\n\n /**\n * 触发事件\n * \n * @param event - 事件名称\n * @param data - 传递给处理函数的数据\n * \n * @example\n * ```typescript\n * emitter.emit('status-change', { \n * from: 'pending', \n * to: 'completed' \n * });\n * ```\n */\n public emit<T = unknown>(event: string, data: T): void {\n // 执行常规事件处理器\n const handlers = this.handlers.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`Error in event handler for \"${event}\":`, error);\n }\n });\n }\n\n // 执行一次性事件处理器\n const onceHandlers = this.onceHandlers.get(event);\n if (onceHandlers) {\n const handlersToExecute = Array.from(onceHandlers);\n // 清空一次性处理器\n this.onceHandlers.delete(event);\n\n handlersToExecute.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`Error in once event handler for \"${event}\":`, error);\n }\n });\n }\n }\n\n /**\n * 取消订阅指定事件的处理器\n * \n * @param event - 事件名称\n * @param handler - 可选,要取消的事件处理函数。如果不提供,则取消所有处理器\n * \n * @example\n * ```typescript\n * // 取消所有处理器\n * emitter.off('status-change');\n * \n * // 取消特定处理器\n * const handler = (data) => console.log(data);\n * emitter.on('data', handler);\n * emitter.off('data', handler);\n * ```\n */\n public off<T = unknown>(event: string, handler?: EventHandler<T>): void {\n if (!handler) {\n // 取消所有处理器\n this.handlers.delete(event);\n this.onceHandlers.delete(event);\n return;\n }\n\n // 取消特定处理器\n const handlers = this.handlers.get(event);\n if (handlers) {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n const onceHandlers = this.onceHandlers.get(event);\n if (onceHandlers) {\n onceHandlers.delete(handler as EventHandler);\n if (onceHandlers.size === 0) {\n this.onceHandlers.delete(event);\n }\n }\n }\n\n /**\n * 清除所有事件处理器\n * \n * @example\n * ```typescript\n * emitter.clear();\n * ```\n */\n public clear(): void {\n this.handlers.clear();\n this.onceHandlers.clear();\n }\n\n /**\n * 获取指定事件的处理器数量\n * \n * @param event - 事件名称\n * @returns 处理器数量\n * \n * @example\n * ```typescript\n * const count = emitter.listenerCount('status-change');\n * console.log(`${count} listeners registered`);\n * ```\n */\n public listenerCount(event: string): number {\n const regularCount = this.handlers.get(event)?.size || 0;\n const onceCount = this.onceHandlers.get(event)?.size || 0;\n return regularCount + onceCount;\n }\n\n /**\n * 获取所有已注册的事件名称\n * \n * @returns 事件名称数组\n * \n * @example\n * ```typescript\n * const events = emitter.eventNames();\n * console.log('Registered events:', events);\n * ```\n */\n public eventNames(): string[] {\n const regularEvents = Array.from(this.handlers.keys());\n const onceEvents = Array.from(this.onceHandlers.keys());\n return Array.from(new Set([...regularEvents, ...onceEvents]));\n }\n}\n\n/**\n * 类型安全的事件发射器\n * \n * @description\n * 提供类型约束的事件发射器,确保事件名称和数据类型的正确性。\n * \n * @template TEvents - 事件映射类型\n * \n * @example\n * ```typescript\n * // 定义事件类型\n * interface TaskEvents {\n * 'status-change': { status: string };\n * 'progress': { percent: number };\n * 'error': { message: string };\n * }\n * \n * // 创建类型安全的发射器\n * const emitter = new TypedEventEmitter<TaskEvents>();\n * \n * // TypeScript 会检查事件名称和数据类型\n * emitter.on('status-change', (data) => {\n * console.log(data.status); // TypeScript 知道 data 有 status 属性\n * });\n * \n * emitter.emit('status-change', { status: 'completed' }); // OK\n * emitter.emit('status-change', { wrong: 'data' }); // TypeScript 报错\n * ```\n */\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private emitter = new EventEmitter();\n\n /**\n * 订阅事件(类型安全)\n */\n public on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n return this.emitter.on(event as string, handler);\n }\n\n /**\n * 订阅一次性事件(类型安全)\n */\n public once<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n return this.emitter.once(event as string, handler);\n }\n\n /**\n * 触发事件(类型安全)\n */\n public emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n this.emitter.emit(event as string, data);\n }\n\n /**\n * 取消订阅(类型安全)\n */\n public off<K extends keyof TEvents>(event: K, handler?: EventHandler<TEvents[K]>): void {\n if (handler) {\n this.emitter.off(event as string, handler);\n } else {\n this.emitter.off(event as string);\n }\n }\n\n /**\n * 清除所有事件处理器\n */\n public clear(): void {\n this.emitter.clear();\n }\n\n /**\n * 获取指定事件的处理器数量\n */\n public listenerCount<K extends keyof TEvents>(event: K): number {\n return this.emitter.listenerCount(event as string);\n }\n\n /**\n * 获取所有已注册的事件名称\n */\n public eventNames(): Array<keyof TEvents> {\n return this.emitter.eventNames() as Array<keyof TEvents>;\n }\n}\n\n","/**\n * 环境适配工具\n * \n * @description\n * 提供跨环境(Node.js / 浏览器)的工具函数和类型检测。\n * 用于处理文件上传、网络请求等在不同环境下有差异的功能。\n */\n\n/**\n * 检测当前是否运行在 Node.js 环境\n * \n * @returns 如果在 Node.js 环境返回 true,否则返回 false\n * \n * @example\n * ```typescript\n * if (isNode) {\n * // 使用 Node.js 特有的 API\n * const fs = require('fs');\n * }\n * ```\n */\nexport const isNode: boolean =\n typeof process !== 'undefined' &&\n process.versions !== null &&\n process.versions.node !== null;\n\n/**\n * 检测当前是否运行在浏览器环境\n * \n * @returns 如果在浏览器环境返回 true,否则返回 false\n * \n * @example\n * ```typescript\n * if (isBrowser) {\n * // 使用浏览器 API\n * const file = new File(['content'], 'file.txt');\n * }\n * ```\n */\nexport const isBrowser: boolean =\n typeof window !== 'undefined' && typeof window.document !== 'undefined';\n\n/**\n * 检测当前是否支持 Web Worker\n * \n * @returns 如果支持 Web Worker 返回 true,否则返回 false\n */\nexport const isWebWorker: boolean =\n typeof self === 'object' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n typeof (self as any).importScripts === 'function';\n\n/**\n * 获取运行环境类型\n * \n * @returns 环境类型字符串\n * \n * @example\n * ```typescript\n * const env = getEnvironment();\n * console.log(`Running in ${env}`); // \"node\" 或 \"browser\" 或 \"worker\"\n * ```\n */\nexport function getEnvironment(): 'node' | 'browser' | 'worker' | 'unknown' {\n if (isNode) return 'node';\n if (isWebWorker) return 'worker';\n if (isBrowser) return 'browser';\n return 'unknown';\n}\n\n/**\n * 文件类型联合类型\n * 在 Node.js 中是 Buffer,在浏览器中是 Blob 或 File\n */\nexport type FileInput = Buffer | Blob | File;\n\n/**\n * 检测是否为有效的文件输入\n * \n * @param input - 待检测的输入\n * @returns 如果是有效的文件输入返回 true\n * \n * @example\n * ```typescript\n * const file = new File(['content'], 'test.txt');\n * if (isValidFileInput(file)) {\n * // 处理文件\n * }\n * ```\n */\nexport function isValidFileInput(input: unknown): input is FileInput {\n if (isNode) {\n // Node.js 环境:检查是否为 Buffer\n return Buffer.isBuffer(input);\n }\n\n if (isBrowser) {\n // 浏览器环境:检查是否为 Blob 或 File\n return input instanceof Blob || input instanceof File;\n }\n\n return false;\n}\n\n/**\n * 获取文件输入的大小(字节)\n * \n * @param input - 文件输入\n * @returns 文件大小(字节)\n * @throws {Error} 如果输入类型不支持\n * \n * @example\n * ```typescript\n * const file = new File(['content'], 'test.txt');\n * const size = getFileSize(file);\n * console.log(`File size: ${size} bytes`);\n * ```\n */\nexport function getFileSize(input: FileInput): number {\n if (isNode && Buffer.isBuffer(input)) {\n return input.length;\n }\n\n if ((isBrowser || isWebWorker) && (input instanceof Blob || input instanceof File)) {\n return input.size;\n }\n\n throw new Error('Unsupported file input type');\n}\n\n/**\n * 获取文件名(仅适用于 File 对象)\n * \n * @param input - 文件输入\n * @returns 文件名,如果无法获取则返回 undefined\n * \n * @example\n * ```typescript\n * const file = new File(['content'], 'test.txt');\n * const name = getFileName(file);\n * console.log(name); // \"test.txt\"\n * ```\n */\nexport function getFileName(input: FileInput): string | undefined {\n if (input instanceof File) {\n return input.name;\n }\n return undefined;\n}\n\n/**\n * 环境特定功能检测\n */\nexport const features = {\n /**\n * 是否支持 FormData\n */\n hasFormData: typeof FormData !== 'undefined',\n\n /**\n * 是否支持 Blob\n */\n hasBlob: typeof Blob !== 'undefined',\n\n /**\n * 是否支持 File\n */\n hasFile: typeof File !== 'undefined',\n\n /**\n * 是否支持 FileReader\n */\n hasFileReader: typeof FileReader !== 'undefined',\n\n /**\n * 是否支持 fetch API\n */\n hasFetch: typeof fetch !== 'undefined',\n\n /**\n * 是否支持 Stream API\n */\n hasStream: typeof ReadableStream !== 'undefined',\n} as const;\n\n/**\n * 环境信息对象\n * \n * @example\n * ```typescript\n * console.log(environmentInfo);\n * // {\n * // type: 'browser',\n * // isNode: false,\n * // isBrowser: true,\n * // features: { ... }\n * // }\n * ```\n */\nexport const environmentInfo = {\n type: getEnvironment(),\n isNode,\n isBrowser,\n isWebWorker,\n features,\n} as const;\n\n/**\n * 断言当前环境\n * \n * @param expectedEnv - 期望的环境类型\n * @param message - 自定义错误消息\n * @throws {Error} 如果当前环境不符合预期\n * \n * @example\n * ```typescript\n * // 确保在 Node.js 环境中运行\n * assertEnvironment('node', 'This feature requires Node.js');\n * ```\n */\nexport function assertEnvironment(\n expectedEnv: 'node' | 'browser' | 'worker',\n message?: string\n): void {\n const currentEnv = getEnvironment();\n if (currentEnv !== expectedEnv) {\n throw new Error(\n message ||\n `This feature requires ${expectedEnv} environment, but running in ${currentEnv}`\n );\n }\n}\n\n/**\n * 安全地动态导入模块(仅 Node.js)\n * \n * @description\n * 在 Node.js 环境中动态导入模块,避免在浏览器环境中引起错误。\n * \n * @param moduleName - 模块名称\n * @returns Promise,resolve 为模块对象\n * @throws {Error} 如果不在 Node.js 环境或模块加载失败\n * \n * @example\n * ```typescript\n * if (isNode) {\n * const fs = await safeDynamicImport('fs');\n * const content = fs.readFileSync('file.txt', 'utf-8');\n * }\n * ```\n */\nexport async function safeDynamicImport<T = unknown>(moduleName: string): Promise<T> {\n assertEnvironment('node', `Cannot import module \"${moduleName}\" in non-Node.js environment`);\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return await import(moduleName);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to import module \"${moduleName}\": ${errorMessage}`);\n }\n}\n\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/common/hooks.ts","../src/common/adapter.ts"],"names":[],"mappings":"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","file":"chunk-NS3DJP2O.cjs","sourcesContent":["/**\n * 事件处理函数类型\n */\ntype EventHandler<T = unknown> = (data: T) => void;\n\n/**\n * 事件处理器映射类型\n */\ntype EventHandlerMap = Map<string, Set<EventHandler>>;\n\n/**\n * 事件发射器基础类\n * \n * @description\n * 提供简单的事件订阅/发布机制,用于业务模块的状态变化通知。\n * 支持类型安全的事件处理,适用于状态变化、进度更新等场景。\n * \n * @example\n * ```typescript\n * // 创建事件发射器\n * const emitter = new EventEmitter();\n * \n * // 订阅事件\n * const unsubscribe = emitter.on('status-change', (data) => {\n * console.log('Status changed:', data);\n * });\n * \n * // 触发事件\n * emitter.emit('status-change', { status: 'completed' });\n * \n * // 取消订阅\n * unsubscribe();\n * \n * // 一次性事件\n * emitter.once('complete', (data) => {\n * console.log('Completed:', data);\n * });\n * ```\n */\nexport class EventEmitter {\n /**\n * 事件处理器映射表\n */\n private handlers: EventHandlerMap = new Map();\n\n /**\n * 一次性事件处理器集合\n */\n private onceHandlers: EventHandlerMap = new Map();\n\n /**\n * 订阅事件\n * \n * @param event - 事件名称\n * @param handler - 事件处理函数\n * @returns 取消订阅的函数\n * \n * @example\n * ```typescript\n * const unsubscribe = emitter.on('data', (payload) => {\n * console.log('Received:', payload);\n * });\n * \n * // 不再需要时取消订阅\n * unsubscribe();\n * ```\n */\n public on<T = unknown>(event: string, handler: EventHandler<T>): () => void {\n if (!this.handlers.has(event)) {\n this.handlers.set(event, new Set());\n }\n\n const handlers = this.handlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // 返回取消订阅函数\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n };\n }\n\n /**\n * 订阅一次性事件\n * \n * @description\n * 事件处理函数只会执行一次,执行后自动取消订阅。\n * \n * @param event - 事件名称\n * @param handler - 事件处理函数\n * @returns 取消订阅的函数\n * \n * @example\n * ```typescript\n * emitter.once('complete', (result) => {\n * console.log('Task completed:', result);\n * });\n * ```\n */\n public once<T = unknown>(event: string, handler: EventHandler<T>): () => void {\n if (!this.onceHandlers.has(event)) {\n this.onceHandlers.set(event, new Set());\n }\n\n const handlers = this.onceHandlers.get(event)!;\n handlers.add(handler as EventHandler);\n\n // 返回取消订阅函数\n return () => {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.onceHandlers.delete(event);\n }\n };\n }\n\n /**\n * 触发事件\n * \n * @param event - 事件名称\n * @param data - 传递给处理函数的数据\n * \n * @example\n * ```typescript\n * emitter.emit('status-change', { \n * from: 'pending', \n * to: 'completed' \n * });\n * ```\n */\n public emit<T = unknown>(event: string, data: T): void {\n // 执行常规事件处理器\n const handlers = this.handlers.get(event);\n if (handlers) {\n handlers.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`Error in event handler for \"${event}\":`, error);\n }\n });\n }\n\n // 执行一次性事件处理器\n const onceHandlers = this.onceHandlers.get(event);\n if (onceHandlers) {\n const handlersToExecute = Array.from(onceHandlers);\n // 清空一次性处理器\n this.onceHandlers.delete(event);\n\n handlersToExecute.forEach((handler) => {\n try {\n handler(data);\n } catch (error) {\n console.error(`Error in once event handler for \"${event}\":`, error);\n }\n });\n }\n }\n\n /**\n * 取消订阅指定事件的处理器\n * \n * @param event - 事件名称\n * @param handler - 可选,要取消的事件处理函数。如果不提供,则取消所有处理器\n * \n * @example\n * ```typescript\n * // 取消所有处理器\n * emitter.off('status-change');\n * \n * // 取消特定处理器\n * const handler = (data) => console.log(data);\n * emitter.on('data', handler);\n * emitter.off('data', handler);\n * ```\n */\n public off<T = unknown>(event: string, handler?: EventHandler<T>): void {\n if (!handler) {\n // 取消所有处理器\n this.handlers.delete(event);\n this.onceHandlers.delete(event);\n return;\n }\n\n // 取消特定处理器\n const handlers = this.handlers.get(event);\n if (handlers) {\n handlers.delete(handler as EventHandler);\n if (handlers.size === 0) {\n this.handlers.delete(event);\n }\n }\n\n const onceHandlers = this.onceHandlers.get(event);\n if (onceHandlers) {\n onceHandlers.delete(handler as EventHandler);\n if (onceHandlers.size === 0) {\n this.onceHandlers.delete(event);\n }\n }\n }\n\n /**\n * 清除所有事件处理器\n * \n * @example\n * ```typescript\n * emitter.clear();\n * ```\n */\n public clear(): void {\n this.handlers.clear();\n this.onceHandlers.clear();\n }\n\n /**\n * 获取指定事件的处理器数量\n * \n * @param event - 事件名称\n * @returns 处理器数量\n * \n * @example\n * ```typescript\n * const count = emitter.listenerCount('status-change');\n * console.log(`${count} listeners registered`);\n * ```\n */\n public listenerCount(event: string): number {\n const regularCount = this.handlers.get(event)?.size || 0;\n const onceCount = this.onceHandlers.get(event)?.size || 0;\n return regularCount + onceCount;\n }\n\n /**\n * 获取所有已注册的事件名称\n * \n * @returns 事件名称数组\n * \n * @example\n * ```typescript\n * const events = emitter.eventNames();\n * console.log('Registered events:', events);\n * ```\n */\n public eventNames(): string[] {\n const regularEvents = Array.from(this.handlers.keys());\n const onceEvents = Array.from(this.onceHandlers.keys());\n return Array.from(new Set([...regularEvents, ...onceEvents]));\n }\n}\n\n/**\n * 类型安全的事件发射器\n * \n * @description\n * 提供类型约束的事件发射器,确保事件名称和数据类型的正确性。\n * \n * @template TEvents - 事件映射类型\n * \n * @example\n * ```typescript\n * // 定义事件类型\n * interface TaskEvents {\n * 'status-change': { status: string };\n * 'progress': { percent: number };\n * 'error': { message: string };\n * }\n * \n * // 创建类型安全的发射器\n * const emitter = new TypedEventEmitter<TaskEvents>();\n * \n * // TypeScript 会检查事件名称和数据类型\n * emitter.on('status-change', (data) => {\n * console.log(data.status); // TypeScript 知道 data 有 status 属性\n * });\n * \n * emitter.emit('status-change', { status: 'completed' }); // OK\n * emitter.emit('status-change', { wrong: 'data' }); // TypeScript 报错\n * ```\n */\nexport class TypedEventEmitter<TEvents extends Record<string, unknown>> {\n private emitter = new EventEmitter();\n\n /**\n * 订阅事件(类型安全)\n */\n public on<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n return this.emitter.on(event as string, handler);\n }\n\n /**\n * 订阅一次性事件(类型安全)\n */\n public once<K extends keyof TEvents>(\n event: K,\n handler: EventHandler<TEvents[K]>\n ): () => void {\n return this.emitter.once(event as string, handler);\n }\n\n /**\n * 触发事件(类型安全)\n */\n public emit<K extends keyof TEvents>(event: K, data: TEvents[K]): void {\n this.emitter.emit(event as string, data);\n }\n\n /**\n * 取消订阅(类型安全)\n */\n public off<K extends keyof TEvents>(event: K, handler?: EventHandler<TEvents[K]>): void {\n if (handler) {\n this.emitter.off(event as string, handler);\n } else {\n this.emitter.off(event as string);\n }\n }\n\n /**\n * 清除所有事件处理器\n */\n public clear(): void {\n this.emitter.clear();\n }\n\n /**\n * 获取指定事件的处理器数量\n */\n public listenerCount<K extends keyof TEvents>(event: K): number {\n return this.emitter.listenerCount(event as string);\n }\n\n /**\n * 获取所有已注册的事件名称\n */\n public eventNames(): Array<keyof TEvents> {\n return this.emitter.eventNames() as Array<keyof TEvents>;\n }\n}\n\n","/**\n * 环境适配工具\n * \n * @description\n * 提供跨环境(Node.js / 浏览器)的工具函数和类型检测。\n * 用于处理文件上传、网络请求等在不同环境下有差异的功能。\n */\n\n/**\n * 检测当前是否运行在 Node.js 环境\n * \n * @returns 如果在 Node.js 环境返回 true,否则返回 false\n * \n * @example\n * ```typescript\n * if (isNode) {\n * // 使用 Node.js 特有的 API\n * const fs = require('fs');\n * }\n * ```\n */\nexport const isNode: boolean =\n typeof process !== 'undefined' &&\n process.versions !== null &&\n process.versions.node !== null;\n\n/**\n * 检测当前是否运行在浏览器环境\n * \n * @returns 如果在浏览器环境返回 true,否则返回 false\n * \n * @example\n * ```typescript\n * if (isBrowser) {\n * // 使用浏览器 API\n * const file = new File(['content'], 'file.txt');\n * }\n * ```\n */\nexport const isBrowser: boolean =\n typeof window !== 'undefined' && typeof window.document !== 'undefined';\n\n/**\n * 检测当前是否支持 Web Worker\n * \n * @returns 如果支持 Web Worker 返回 true,否则返回 false\n */\nexport const isWebWorker: boolean =\n typeof self === 'object' &&\n // eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access\n typeof (self as any).importScripts === 'function';\n\n/**\n * 获取运行环境类型\n * \n * @returns 环境类型字符串\n * \n * @example\n * ```typescript\n * const env = getEnvironment();\n * console.log(`Running in ${env}`); // \"node\" 或 \"browser\" 或 \"worker\"\n * ```\n */\nexport function getEnvironment(): 'node' | 'browser' | 'worker' | 'unknown' {\n if (isNode) return 'node';\n if (isWebWorker) return 'worker';\n if (isBrowser) return 'browser';\n return 'unknown';\n}\n\n/**\n * 文件类型联合类型\n * 在 Node.js 中是 Buffer,在浏览器中是 Blob 或 File\n */\nexport type FileInput = Buffer | Blob | File;\n\n/**\n * 检测是否为有效的文件输入\n * \n * @param input - 待检测的输入\n * @returns 如果是有效的文件输入返回 true\n * \n * @example\n * ```typescript\n * const file = new File(['content'], 'test.txt');\n * if (isValidFileInput(file)) {\n * // 处理文件\n * }\n * ```\n */\nexport function isValidFileInput(input: unknown): input is FileInput {\n if (isNode) {\n // Node.js 环境:检查是否为 Buffer\n return Buffer.isBuffer(input);\n }\n\n if (isBrowser) {\n // 浏览器环境:检查是否为 Blob 或 File\n return input instanceof Blob || input instanceof File;\n }\n\n return false;\n}\n\n/**\n * 获取文件输入的大小(字节)\n * \n * @param input - 文件输入\n * @returns 文件大小(字节)\n * @throws {Error} 如果输入类型不支持\n * \n * @example\n * ```typescript\n * const file = new File(['content'], 'test.txt');\n * const size = getFileSize(file);\n * console.log(`File size: ${size} bytes`);\n * ```\n */\nexport function getFileSize(input: FileInput): number {\n if (isNode && Buffer.isBuffer(input)) {\n return input.length;\n }\n\n if ((isBrowser || isWebWorker) && (input instanceof Blob || input instanceof File)) {\n return input.size;\n }\n\n throw new Error('Unsupported file input type');\n}\n\n/**\n * 获取文件名(仅适用于 File 对象)\n * \n * @param input - 文件输入\n * @returns 文件名,如果无法获取则返回 undefined\n * \n * @example\n * ```typescript\n * const file = new File(['content'], 'test.txt');\n * const name = getFileName(file);\n * console.log(name); // \"test.txt\"\n * ```\n */\nexport function getFileName(input: FileInput): string | undefined {\n if (input instanceof File) {\n return input.name;\n }\n return undefined;\n}\n\n/**\n * 环境特定功能检测\n */\nexport const features = {\n /**\n * 是否支持 FormData\n */\n hasFormData: typeof FormData !== 'undefined',\n\n /**\n * 是否支持 Blob\n */\n hasBlob: typeof Blob !== 'undefined',\n\n /**\n * 是否支持 File\n */\n hasFile: typeof File !== 'undefined',\n\n /**\n * 是否支持 FileReader\n */\n hasFileReader: typeof FileReader !== 'undefined',\n\n /**\n * 是否支持 fetch API\n */\n hasFetch: typeof fetch !== 'undefined',\n\n /**\n * 是否支持 Stream API\n */\n hasStream: typeof ReadableStream !== 'undefined',\n} as const;\n\n/**\n * 环境信息对象\n * \n * @example\n * ```typescript\n * console.log(environmentInfo);\n * // {\n * // type: 'browser',\n * // isNode: false,\n * // isBrowser: true,\n * // features: { ... }\n * // }\n * ```\n */\nexport const environmentInfo = {\n type: getEnvironment(),\n isNode,\n isBrowser,\n isWebWorker,\n features,\n} as const;\n\n/**\n * 断言当前环境\n * \n * @param expectedEnv - 期望的环境类型\n * @param message - 自定义错误消息\n * @throws {Error} 如果当前环境不符合预期\n * \n * @example\n * ```typescript\n * // 确保在 Node.js 环境中运行\n * assertEnvironment('node', 'This feature requires Node.js');\n * ```\n */\nexport function assertEnvironment(\n expectedEnv: 'node' | 'browser' | 'worker',\n message?: string\n): void {\n const currentEnv = getEnvironment();\n if (currentEnv !== expectedEnv) {\n throw new Error(\n message ||\n `This feature requires ${expectedEnv} environment, but running in ${currentEnv}`\n );\n }\n}\n\n/**\n * 安全地动态导入模块(仅 Node.js)\n * \n * @description\n * 在 Node.js 环境中动态导入模块,避免在浏览器环境中引起错误。\n * \n * @param moduleName - 模块名称\n * @returns Promise,resolve 为模块对象\n * @throws {Error} 如果不在 Node.js 环境或模块加载失败\n * \n * @example\n * ```typescript\n * if (isNode) {\n * const fs = await safeDynamicImport('fs');\n * const content = fs.readFileSync('file.txt', 'utf-8');\n * }\n * ```\n */\nexport async function safeDynamicImport<T = unknown>(moduleName: string): Promise<T> {\n assertEnvironment('node', `Cannot import module \"${moduleName}\" in non-Node.js environment`);\n \n try {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-return\n return await import(moduleName);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(`Failed to import module \"${moduleName}\": ${errorMessage}`);\n }\n}\n\n"]}
@@ -1,193 +0,0 @@
1
- import { b as LoggerFunction, S as SDKConfig } from './core-77EbLgbp.cjs';
2
- import { AxiosInstance, AxiosRequestConfig } from 'axios';
3
-
4
- /**
5
- * SDK 内部日志器
6
- *
7
- * @description
8
- * 提供统一的日志接口,支持用户自定义日志钩子。
9
- * 默认使用 console 输出,用户可以通过配置自定义 logger 函数来集成 Sentry 等监控系统。
10
- *
11
- * @example
12
- * ```typescript
13
- * const logger = new InternalLogger((level, message, data) => {
14
- * // 自定义日志处理,例如发送到 Sentry
15
- * console.log(`[${level}] ${message}`, data);
16
- * });
17
- *
18
- * logger.info('Operation started', { userId: '123' });
19
- * logger.error('Operation failed', { error: 'Network timeout' });
20
- * ```
21
- */
22
- declare class InternalLogger {
23
- /**
24
- * 用户自定义的日志钩子函数
25
- */
26
- private readonly userLogger?;
27
- /**
28
- * 是否启用日志输出
29
- * 可以通过环境变量 PLOLINK_SDK_DEBUG 控制
30
- */
31
- private readonly isDebugEnabled;
32
- /**
33
- * 创建一个 InternalLogger 实例
34
- *
35
- * @param userLogger - 用户自定义的日志钩子函数
36
- */
37
- constructor(userLogger?: LoggerFunction);
38
- /**
39
- * 记录信息级别日志
40
- *
41
- * @param message - 日志消息
42
- * @param context - 附加上下文数据
43
- */
44
- info(message: string, context?: unknown): void;
45
- /**
46
- * 记录警告级别日志
47
- *
48
- * @param message - 日志消息
49
- * @param context - 附加上下文数据
50
- */
51
- warn(message: string, context?: unknown): void;
52
- /**
53
- * 记录错误级别日志
54
- *
55
- * @param message - 日志消息
56
- * @param context - 附加上下文数据
57
- */
58
- error(message: string, context?: unknown): void;
59
- /**
60
- * 记录调试级别日志
61
- * 只有在 debug 模式下才会输出
62
- *
63
- * @param message - 日志消息
64
- * @param context - 附加上下文数据
65
- */
66
- debug(message: string, context?: unknown): void;
67
- /**
68
- * 内部日志记录方法
69
- *
70
- * @param level - 日志级别
71
- * @param message - 日志消息
72
- * @param context - 附加上下文数据
73
- */
74
- private log;
75
- /**
76
- * 创建一个带有固定上下文的子 logger
77
- *
78
- * @param context - 固定的上下文数据
79
- * @returns 新的 logger 实例
80
- *
81
- * @example
82
- * ```typescript
83
- * const logger = new InternalLogger();
84
- * const moduleLogger = logger.withContext({ module: 'billing' });
85
- * moduleLogger.info('Payment processed'); // 日志会自动带上 module: 'billing'
86
- * ```
87
- */
88
- withContext(context: Record<string, unknown>): InternalLogger;
89
- }
90
-
91
- /**
92
- * 为 Axios 实例添加类型安全的请求方法
93
- *
94
- * @description
95
- * 这些方法封装了 Axios 的原始方法,提供更好的类型推断。
96
- */
97
- interface TypedAxiosInstance extends AxiosInstance {
98
- get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
99
- post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
100
- put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
101
- patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
102
- delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
103
- }
104
-
105
- /**
106
- * Plolink SDK 客户端主类
107
- *
108
- * @description
109
- * PlolinkClient 是 SDK 的核心类,负责:
110
- * - 管理 SDK 配置(认证 Token、API 地址等)
111
- * - 初始化 Axios 实例并配置拦截器
112
- * - 提供统一的日志接口
113
- * - 作为所有业务模块的基础依赖
114
- *
115
- * @example
116
- * ```typescript
117
- * // 使用 ApiKey
118
- * const client = new PlolinkClient({
119
- * token: 'sk-123456789',
120
- * logger: (level, msg, data) => {
121
- * console.log(`[${level}] ${msg}`, data);
122
- * }
123
- * });
124
- *
125
- * // 使用 SessionId (登录后获取)
126
- * const client = new PlolinkClient({
127
- * token: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
128
- * baseUrl: 'https://api.plolink.com'
129
- * });
130
- * ```
131
- */
132
- declare class PlolinkClient {
133
- /**
134
- * SDK 配置对象(已填充默认值)
135
- */
136
- readonly config: Required<SDKConfig>;
137
- /**
138
- * Axios 实例,用于发起 HTTP 请求
139
- */
140
- readonly axiosInstance: TypedAxiosInstance;
141
- /**
142
- * 内部日志记录器
143
- */
144
- readonly logger: InternalLogger;
145
- /**
146
- * 创建一个 PlolinkClient 实例
147
- *
148
- * @param config - SDK 配置对象
149
- * @throws {PlolinkError} 当配置验证失败时抛出
150
- *
151
- * @example
152
- * ```typescript
153
- * const client = new PlolinkClient({
154
- * token: 'sk-your-api-key'
155
- * });
156
- * ```
157
- */
158
- constructor(config: SDKConfig);
159
- /**
160
- * 验证 SDK 配置
161
- *
162
- * @param config - SDK 配置对象
163
- * @throws {PlolinkError} 当配置不合法时抛出
164
- * @private
165
- */
166
- private validateConfig;
167
- /**
168
- * 获取当前 SDK 版本
169
- *
170
- * @returns SDK 版本号
171
- */
172
- getVersion(): string;
173
- /**
174
- * 检查客户端健康状态
175
- *
176
- * @returns 健康状态信息
177
- *
178
- * @example
179
- * ```typescript
180
- * const health = client.healthCheck();
181
- * console.log(health);
182
- * // { status: 'ok', baseUrl: '...', version: '...' }
183
- * ```
184
- */
185
- healthCheck(): {
186
- status: 'ok';
187
- baseUrl: string;
188
- version: string;
189
- hasToken: boolean;
190
- };
191
- }
192
-
193
- export { InternalLogger as I, PlolinkClient as P };
@@ -1,193 +0,0 @@
1
- import { b as LoggerFunction, S as SDKConfig } from './core-77EbLgbp.js';
2
- import { AxiosInstance, AxiosRequestConfig } from 'axios';
3
-
4
- /**
5
- * SDK 内部日志器
6
- *
7
- * @description
8
- * 提供统一的日志接口,支持用户自定义日志钩子。
9
- * 默认使用 console 输出,用户可以通过配置自定义 logger 函数来集成 Sentry 等监控系统。
10
- *
11
- * @example
12
- * ```typescript
13
- * const logger = new InternalLogger((level, message, data) => {
14
- * // 自定义日志处理,例如发送到 Sentry
15
- * console.log(`[${level}] ${message}`, data);
16
- * });
17
- *
18
- * logger.info('Operation started', { userId: '123' });
19
- * logger.error('Operation failed', { error: 'Network timeout' });
20
- * ```
21
- */
22
- declare class InternalLogger {
23
- /**
24
- * 用户自定义的日志钩子函数
25
- */
26
- private readonly userLogger?;
27
- /**
28
- * 是否启用日志输出
29
- * 可以通过环境变量 PLOLINK_SDK_DEBUG 控制
30
- */
31
- private readonly isDebugEnabled;
32
- /**
33
- * 创建一个 InternalLogger 实例
34
- *
35
- * @param userLogger - 用户自定义的日志钩子函数
36
- */
37
- constructor(userLogger?: LoggerFunction);
38
- /**
39
- * 记录信息级别日志
40
- *
41
- * @param message - 日志消息
42
- * @param context - 附加上下文数据
43
- */
44
- info(message: string, context?: unknown): void;
45
- /**
46
- * 记录警告级别日志
47
- *
48
- * @param message - 日志消息
49
- * @param context - 附加上下文数据
50
- */
51
- warn(message: string, context?: unknown): void;
52
- /**
53
- * 记录错误级别日志
54
- *
55
- * @param message - 日志消息
56
- * @param context - 附加上下文数据
57
- */
58
- error(message: string, context?: unknown): void;
59
- /**
60
- * 记录调试级别日志
61
- * 只有在 debug 模式下才会输出
62
- *
63
- * @param message - 日志消息
64
- * @param context - 附加上下文数据
65
- */
66
- debug(message: string, context?: unknown): void;
67
- /**
68
- * 内部日志记录方法
69
- *
70
- * @param level - 日志级别
71
- * @param message - 日志消息
72
- * @param context - 附加上下文数据
73
- */
74
- private log;
75
- /**
76
- * 创建一个带有固定上下文的子 logger
77
- *
78
- * @param context - 固定的上下文数据
79
- * @returns 新的 logger 实例
80
- *
81
- * @example
82
- * ```typescript
83
- * const logger = new InternalLogger();
84
- * const moduleLogger = logger.withContext({ module: 'billing' });
85
- * moduleLogger.info('Payment processed'); // 日志会自动带上 module: 'billing'
86
- * ```
87
- */
88
- withContext(context: Record<string, unknown>): InternalLogger;
89
- }
90
-
91
- /**
92
- * 为 Axios 实例添加类型安全的请求方法
93
- *
94
- * @description
95
- * 这些方法封装了 Axios 的原始方法,提供更好的类型推断。
96
- */
97
- interface TypedAxiosInstance extends AxiosInstance {
98
- get<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
99
- post<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
100
- put<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
101
- patch<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
102
- delete<T = unknown>(url: string, config?: AxiosRequestConfig): Promise<T>;
103
- }
104
-
105
- /**
106
- * Plolink SDK 客户端主类
107
- *
108
- * @description
109
- * PlolinkClient 是 SDK 的核心类,负责:
110
- * - 管理 SDK 配置(认证 Token、API 地址等)
111
- * - 初始化 Axios 实例并配置拦截器
112
- * - 提供统一的日志接口
113
- * - 作为所有业务模块的基础依赖
114
- *
115
- * @example
116
- * ```typescript
117
- * // 使用 ApiKey
118
- * const client = new PlolinkClient({
119
- * token: 'sk-123456789',
120
- * logger: (level, msg, data) => {
121
- * console.log(`[${level}] ${msg}`, data);
122
- * }
123
- * });
124
- *
125
- * // 使用 SessionId (登录后获取)
126
- * const client = new PlolinkClient({
127
- * token: 'a1b2c3d4-e5f6-7890-abcd-ef1234567890',
128
- * baseUrl: 'https://api.plolink.com'
129
- * });
130
- * ```
131
- */
132
- declare class PlolinkClient {
133
- /**
134
- * SDK 配置对象(已填充默认值)
135
- */
136
- readonly config: Required<SDKConfig>;
137
- /**
138
- * Axios 实例,用于发起 HTTP 请求
139
- */
140
- readonly axiosInstance: TypedAxiosInstance;
141
- /**
142
- * 内部日志记录器
143
- */
144
- readonly logger: InternalLogger;
145
- /**
146
- * 创建一个 PlolinkClient 实例
147
- *
148
- * @param config - SDK 配置对象
149
- * @throws {PlolinkError} 当配置验证失败时抛出
150
- *
151
- * @example
152
- * ```typescript
153
- * const client = new PlolinkClient({
154
- * token: 'sk-your-api-key'
155
- * });
156
- * ```
157
- */
158
- constructor(config: SDKConfig);
159
- /**
160
- * 验证 SDK 配置
161
- *
162
- * @param config - SDK 配置对象
163
- * @throws {PlolinkError} 当配置不合法时抛出
164
- * @private
165
- */
166
- private validateConfig;
167
- /**
168
- * 获取当前 SDK 版本
169
- *
170
- * @returns SDK 版本号
171
- */
172
- getVersion(): string;
173
- /**
174
- * 检查客户端健康状态
175
- *
176
- * @returns 健康状态信息
177
- *
178
- * @example
179
- * ```typescript
180
- * const health = client.healthCheck();
181
- * console.log(health);
182
- * // { status: 'ok', baseUrl: '...', version: '...' }
183
- * ```
184
- */
185
- healthCheck(): {
186
- status: 'ok';
187
- baseUrl: string;
188
- version: string;
189
- hasToken: boolean;
190
- };
191
- }
192
-
193
- export { InternalLogger as I, PlolinkClient as P };