@zhin.js/plugin-music 1.0.26 → 1.1.2

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 (111) hide show
  1. package/README.md +28 -27
  2. package/commands/cookie/delete/[source]/index.js +23 -0
  3. package/commands/cookie/delete/[source]/index.ts +27 -0
  4. package/commands/cookie/get/[source]/index.js +29 -0
  5. package/commands/cookie/get/[source]/index.ts +33 -0
  6. package/commands/cookie/set/[source]/index.js +23 -0
  7. package/commands/cookie/set/[source]/index.ts +27 -0
  8. package/commands/cookie/status/index.js +25 -0
  9. package/commands/cookie/status/index.ts +25 -0
  10. package/commands/login/[platform]/index.js +66 -0
  11. package/commands/login/[platform]/index.ts +74 -0
  12. package/commands//347/202/271/346/255/214/[keyword]/index.js +63 -0
  13. package/commands//347/202/271/346/255/214/[keyword]/index.ts +75 -0
  14. package/components/share-music/index.js +24 -0
  15. package/components/share-music/index.ts +29 -0
  16. package/lib/config.d.ts +3 -3
  17. package/lib/config.d.ts.map +1 -1
  18. package/lib/config.js +36 -7
  19. package/lib/config.js.map +1 -1
  20. package/lib/credential-store.d.ts +37 -0
  21. package/lib/credential-store.d.ts.map +1 -0
  22. package/lib/credential-store.js +85 -0
  23. package/lib/credential-store.js.map +1 -0
  24. package/lib/index.d.ts +8 -1
  25. package/lib/index.d.ts.map +1 -1
  26. package/lib/index.js +7 -112
  27. package/lib/index.js.map +1 -1
  28. package/lib/login/index.d.ts +27 -0
  29. package/lib/login/index.d.ts.map +1 -0
  30. package/lib/login/index.js +124 -0
  31. package/lib/login/index.js.map +1 -0
  32. package/lib/login/netease.d.ts +6 -0
  33. package/lib/login/netease.d.ts.map +1 -0
  34. package/lib/login/netease.js +58 -0
  35. package/lib/login/netease.js.map +1 -0
  36. package/lib/login/qq.d.ts +7 -0
  37. package/lib/login/qq.d.ts.map +1 -0
  38. package/lib/login/qq.js +139 -0
  39. package/lib/login/qq.js.map +1 -0
  40. package/lib/login/types.d.ts +19 -0
  41. package/lib/login/types.d.ts.map +1 -0
  42. package/lib/login/types.js +11 -0
  43. package/lib/login/types.js.map +1 -0
  44. package/lib/music-lib.d.ts +32 -0
  45. package/lib/music-lib.d.ts.map +1 -0
  46. package/lib/music-lib.js +58 -0
  47. package/lib/music-lib.js.map +1 -0
  48. package/lib/runtime.d.ts +12 -0
  49. package/lib/runtime.d.ts.map +1 -0
  50. package/lib/runtime.js +3 -0
  51. package/lib/runtime.js.map +1 -0
  52. package/lib/session.d.ts +35 -0
  53. package/lib/session.d.ts.map +1 -0
  54. package/lib/session.js +51 -0
  55. package/lib/session.js.map +1 -0
  56. package/lib/sources/index.d.ts +4 -2
  57. package/lib/sources/index.d.ts.map +1 -1
  58. package/lib/sources/index.js +12 -6
  59. package/lib/sources/index.js.map +1 -1
  60. package/lib/sources/kugou.d.ts +6 -0
  61. package/lib/sources/kugou.d.ts.map +1 -0
  62. package/lib/sources/kugou.js +69 -0
  63. package/lib/sources/kugou.js.map +1 -0
  64. package/lib/sources/kuwo.d.ts +7 -0
  65. package/lib/sources/kuwo.d.ts.map +1 -0
  66. package/lib/sources/kuwo.js +69 -0
  67. package/lib/sources/kuwo.js.map +1 -0
  68. package/lib/sources/netease.d.ts +4 -1
  69. package/lib/sources/netease.d.ts.map +1 -1
  70. package/lib/sources/netease.js +25 -6
  71. package/lib/sources/netease.js.map +1 -1
  72. package/lib/sources/qq.d.ts +4 -14
  73. package/lib/sources/qq.d.ts.map +1 -1
  74. package/lib/sources/qq.js +117 -82
  75. package/lib/sources/qq.js.map +1 -1
  76. package/lib/types.d.ts +4 -24
  77. package/lib/types.d.ts.map +1 -1
  78. package/lib/types.js +0 -1
  79. package/lib/types.js.map +1 -1
  80. package/middlewares/music-selection/index.js +48 -0
  81. package/middlewares/music-selection/index.ts +62 -0
  82. package/package.json +66 -12
  83. package/plugin.js +45 -0
  84. package/schema.json +6 -0
  85. package/skills/music/SKILL.md +2 -2
  86. package/skills/music/tools/music-search/index.js +22 -0
  87. package/skills/music/tools/music-search/index.ts +33 -0
  88. package/skills/music/tools/music-share/index.js +21 -0
  89. package/skills/music/tools/music-share/index.ts +26 -0
  90. package/src/config.ts +54 -30
  91. package/src/credential-store.ts +125 -0
  92. package/src/index.ts +37 -0
  93. package/src/login/index.ts +154 -0
  94. package/src/login/netease.ts +69 -0
  95. package/src/login/qq.ts +154 -0
  96. package/src/login/types.ts +27 -0
  97. package/src/music-lib.ts +71 -0
  98. package/src/runtime.ts +17 -0
  99. package/src/session.ts +77 -0
  100. package/src/sources/index.ts +17 -10
  101. package/src/sources/kugou.ts +92 -0
  102. package/src/sources/kuwo.ts +94 -0
  103. package/src/sources/netease.ts +35 -11
  104. package/src/sources/qq.ts +164 -126
  105. package/src/types.ts +6 -28
  106. package/lib/async-jsx.d.ts +0 -19
  107. package/lib/async-jsx.d.ts.map +0 -1
  108. package/lib/async-jsx.js +0 -48
  109. package/lib/async-jsx.js.map +0 -1
  110. package/src/async-jsx.ts +0 -54
  111. package/src/index.tsx +0 -130
package/lib/async-jsx.js DELETED
@@ -1,48 +0,0 @@
1
- // async-jsx.ts - 异步 JSX 增强工具
2
- /**
3
- * 异步组件包装器
4
- * 类似 Next.js 的异步组件支持
5
- */
6
- export function AsyncComponent(Component) {
7
- // 返回一个同步函数,但内部处理是异步的
8
- return (props) => {
9
- // 创建一个特殊的标记对象
10
- const asyncMarker = {
11
- __async: true,
12
- component: Component,
13
- props,
14
- execute: () => Component(props)
15
- };
16
- // TypeScript 类型断言
17
- return asyncMarker;
18
- };
19
- }
20
- /**
21
- * 渲染异步内容
22
- * 检查是否是异步标记,如果是则执行
23
- */
24
- export async function renderAsync(content) {
25
- if (content && typeof content === 'object' && content.__async) {
26
- return await content.execute();
27
- }
28
- if (content && typeof content.then === 'function') {
29
- return await content;
30
- }
31
- return content;
32
- }
33
- /**
34
- * Suspense 组件工厂
35
- * 用于包装异步组件并提供 fallback
36
- */
37
- export function createSuspense(fallback = '加载中...') {
38
- return async function Suspense(props) {
39
- try {
40
- return await renderAsync(props.children);
41
- }
42
- catch (error) {
43
- console.error('Suspense error:', error);
44
- return fallback;
45
- }
46
- };
47
- }
48
- //# sourceMappingURL=async-jsx.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"async-jsx.js","sourceRoot":"","sources":["../src/async-jsx.ts"],"names":[],"mappings":"AAAA,6BAA6B;AAI7B;;;GAGG;AACH,MAAM,UAAU,cAAc,CAC5B,SAA6C;IAE7C,qBAAqB;IACrB,OAAO,CAAC,KAAQ,EAAE,EAAE;QAClB,cAAc;QACd,MAAM,WAAW,GAAG;YAClB,OAAO,EAAE,IAAI;YACb,SAAS,EAAE,SAAS;YACpB,KAAK;YACL,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,KAAK,CAAC;SAChC,CAAC;QAEF,kBAAkB;QAClB,OAAO,WAAiC,CAAC;IAC3C,CAAC,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAY;IAC5C,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAC9D,OAAO,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACjC,CAAC;IACD,IAAI,OAAO,IAAI,OAAO,OAAO,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QAClD,OAAO,MAAM,OAAO,CAAC;IACvB,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,QAAQ;IACxD,OAAO,KAAK,UAAU,QAAQ,CAAC,KAAwB;QACrD,IAAI,CAAC;YACH,OAAO,MAAM,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC;YACxC,OAAO,QAAQ,CAAC;QAClB,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
package/src/async-jsx.ts DELETED
@@ -1,54 +0,0 @@
1
- // async-jsx.ts - 异步 JSX 增强工具
2
-
3
- import { SendContent } from "zhin.js";
4
-
5
- /**
6
- * 异步组件包装器
7
- * 类似 Next.js 的异步组件支持
8
- */
9
- export function AsyncComponent<P = any>(
10
- Component: (props: P) => Promise<SendContent>
11
- ): (props: P) => SendContent {
12
- // 返回一个同步函数,但内部处理是异步的
13
- return (props: P) => {
14
- // 创建一个特殊的标记对象
15
- const asyncMarker = {
16
- __async: true,
17
- component: Component,
18
- props,
19
- execute: () => Component(props)
20
- };
21
-
22
- // TypeScript 类型断言
23
- return asyncMarker as any as SendContent;
24
- };
25
- }
26
-
27
- /**
28
- * 渲染异步内容
29
- * 检查是否是异步标记,如果是则执行
30
- */
31
- export async function renderAsync(content: any): Promise<SendContent> {
32
- if (content && typeof content === 'object' && content.__async) {
33
- return await content.execute();
34
- }
35
- if (content && typeof content.then === 'function') {
36
- return await content;
37
- }
38
- return content;
39
- }
40
-
41
- /**
42
- * Suspense 组件工厂
43
- * 用于包装异步组件并提供 fallback
44
- */
45
- export function createSuspense(fallback: string = '加载中...') {
46
- return async function Suspense(props: { children: any }): Promise<SendContent> {
47
- try {
48
- return await renderAsync(props.children);
49
- } catch (error) {
50
- console.error('Suspense error:', error);
51
- return fallback;
52
- }
53
- };
54
- }
package/src/index.tsx DELETED
@@ -1,130 +0,0 @@
1
- import { usePlugin, defineComponent, ZhinTool } from "zhin.js";
2
- import { musicServices } from "./sources/index.js";
3
- import { sourceConfigMap } from "./config.js";
4
- import type { MusicSource } from "./types.js";
5
-
6
- const plugin = usePlugin();
7
- const { logger, useContext, addComponent } = plugin;
8
-
9
- // 异步组件:分享音乐
10
- const ShareMusic = defineComponent(async function ShareMusic({ platform, musicId }: { platform: MusicSource, musicId: string }) {
11
- const service = musicServices[platform];
12
- if (!service) return 'unsupported music source';
13
- const { id, source, ...detail } = await service.getDetail(musicId);
14
- return <share {...detail} config={sourceConfigMap[platform]} />
15
- }, 'ShareMusic')
16
- addComponent(ShareMusic)
17
-
18
- // Suspense 组件 - 用于包装异步组件
19
- const Suspense = defineComponent(async function Suspense(
20
- props: { fallback?: string; children?: any },
21
- context
22
- ) {
23
- try {
24
- // 如果 children 是一个 Promise(异步组件),等待它
25
- if (props.children && typeof props.children === 'object' && 'then' in props.children) {
26
- return await props.children;
27
- }
28
- // 否则直接返回
29
- return props.children || '';
30
- } catch (error) {
31
- logger.error('Suspense error:', error);
32
- return props.fallback || '加载失败';
33
- }
34
- }, 'Suspense');
35
-
36
- addComponent(Suspense);
37
-
38
- // ============================================================================
39
- // 点歌工具 (使用 ZhinTool)
40
- // ============================================================================
41
-
42
- const searchMusicTool = new ZhinTool('music_search')
43
- .desc('搜索音乐并返回结果列表')
44
- .tag('music', 'entertainment')
45
- .param('keyword', { type: 'string', description: '搜索关键词' }, true)
46
- .param('source', {
47
- type: 'string',
48
- description: '音乐源: qq, netease(默认两者都搜索)',
49
- enum: ['qq', 'netease']
50
- })
51
- .param('limit', { type: 'number', description: '返回结果数量(默认 5)' })
52
- .execute(async ({ keyword, source, limit = 5 }) => {
53
- const keywordStr = keyword as string;
54
- const limitNum = limit as number;
55
-
56
- // 确定搜索源
57
- const searchSources: MusicSource[] = source
58
- ? [source as MusicSource]
59
- : ['qq', 'netease'];
60
-
61
- logger.info(`AI 搜索音乐: ${keywordStr}, 来源: ${searchSources.join(', ')}`);
62
-
63
- // 并行搜索
64
- const searchPromises = searchSources.map(s =>
65
- musicServices[s].search(keywordStr, limitNum)
66
- );
67
-
68
- const searchResults = await Promise.all(searchPromises);
69
- const allMusic = searchResults.flat().filter(Boolean);
70
-
71
- return {
72
- success: true,
73
- keyword: keywordStr,
74
- results: allMusic.map(m => ({
75
- id: m.id,
76
- title: m.title,
77
- source: m.source,
78
- url: m.url,
79
- })),
80
- total: allMusic.length,
81
- };
82
- })
83
- .platform('icqq'); // 限制为 icqq 平台
84
-
85
- // 分享音乐工具(直接分享指定音乐)
86
- const shareMusicTool = new ZhinTool('music_share')
87
- .desc('分享指定的音乐')
88
- .tag('music', 'entertainment')
89
- .param('id', { type: 'string', description: '音乐 ID' }, true)
90
- .param('source', {
91
- type: 'string',
92
- description: '音乐源: qq 或 netease',
93
- enum: ['qq', 'netease']
94
- }, true)
95
- .platform('icqq')
96
- .execute(async ({ id, source }) => {
97
- const service = musicServices[source as MusicSource];
98
- if (!service) {
99
- return { success: false, error: `不支持的音乐源: ${source}` };
100
- }
101
-
102
- try {
103
- const detail = await service.getDetail(id as string);
104
- return {
105
- success: true,
106
- music: {
107
- id: detail.id,
108
- title: detail.title,
109
- source: detail.source,
110
- url: detail.url,
111
- }
112
- };
113
- } catch (error) {
114
- return { success: false, error: error instanceof Error ? error.message : String(error) };
115
- }
116
- });
117
-
118
- // 注册工具
119
- useContext('tool', (toolService) => {
120
- if (!toolService) return;
121
-
122
- const disposers = [
123
- toolService.addTool(searchMusicTool, 'music'),
124
- toolService.addTool(shareMusicTool, 'music'),
125
- ];
126
-
127
- logger.debug('音乐工具已注册');
128
-
129
- return () => disposers.forEach(d => d());
130
- });