@zhin.js/adapter-juejin 0.1.2 → 0.1.4

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,4 +1,5 @@
1
1
  import type { ResolvedJuejinNotifyTarget } from './protocol.js';
2
2
  /** 返回 false 表示当前没有可用的出站通道(只记日志)。 */
3
3
  export type JuejinNotifier = (target: ResolvedJuejinNotifyTarget, text: string) => Promise<boolean>;
4
- export declare const juejinNotifierToken: import("zhin.js").Token<JuejinNotifier>;
4
+ export declare const juejinNotifierStore: import("zhin.js").PluginStore<JuejinNotifier, unknown>;
5
+ export declare const juejinNotifierToken: import("zhin.js").PluginStore<JuejinNotifier, unknown>;
@@ -1,3 +1,4 @@
1
1
  /** Domain notifier only; account ownership and review directory are projected from the Adapter. */
2
- import { createToken } from 'zhin.js';
3
- export const juejinNotifierToken = createToken('zhin.juejin-comment.notifier', 'Pushes Juejin draft / login notices to a configured chat conversation via OutboundHost');
2
+ import { definePluginStore } from 'zhin.js';
3
+ export const juejinNotifierStore = definePluginStore('zhin.juejin-comment.notifier', 'Pushes Juejin draft / login notices to a configured chat conversation via OutboundHost');
4
+ export const juejinNotifierToken = juejinNotifierStore;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-juejin",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Zhin.js Juejin (掘金) comment adapter for Plugin Runtime (Experimental; whitelisted article comments, review-then-send with a Console approval page)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -32,23 +32,20 @@
32
32
  "directory": "plugins/adapters/juejin"
33
33
  },
34
34
  "dependencies": {
35
- "react": "^19.2.8",
36
- "@zhin.js/adapter": "1.1.29",
37
- "@zhin.js/client": "1.1.25",
38
- "@zhin.js/console-contract": "1.1.3",
39
- "@zhin.js/core": "1.1.57",
40
- "@zhin.js/feature-kit": "1.1.13",
41
- "@zhin.js/im-contract": "1.1.12",
35
+ "@zhin.js/adapter": "1.1.31",
36
+ "@zhin.js/console-contract": "1.1.5",
37
+ "@zhin.js/core": "1.1.59",
38
+ "@zhin.js/feature-kit": "1.1.15",
39
+ "@zhin.js/im-contract": "1.1.13",
42
40
  "@zhin.js/logger": "1.1.2",
43
- "@zhin.js/page": "1.1.15"
41
+ "@zhin.js/page": "1.1.17"
44
42
  },
45
43
  "peerDependencies": {
46
- "react": "^19.0.0",
47
- "@zhin.js/adapter": "^1.1.29",
48
- "@zhin.js/core": "^1.1.57",
49
- "zhin.js": "^1.1.22",
50
- "@zhin.js/command": "^1.1.15",
51
- "@zhin.js/page": "^1.1.15"
44
+ "@zhin.js/adapter": "^1.1.31",
45
+ "@zhin.js/core": "^1.1.59",
46
+ "zhin.js": "^1.1.24",
47
+ "@zhin.js/command": "^1.1.17",
48
+ "@zhin.js/page": "^1.1.17"
52
49
  },
53
50
  "peerDependenciesMeta": {
54
51
  "zhin.js": {
@@ -56,18 +53,14 @@
56
53
  },
57
54
  "@zhin.js/command": {
58
55
  "optional": true
59
- },
60
- "react": {
61
- "optional": true
62
56
  }
63
57
  },
64
58
  "devDependencies": {
65
59
  "@types/node": "^26.1.2",
66
- "@types/react": "^19.2.18",
67
60
  "typescript": "^6.0.3",
68
61
  "vitest": "^4.1.10",
69
- "@zhin.js/pagemanager": "1.1.22",
70
- "zhin.js": "1.1.22"
62
+ "@zhin.js/pagemanager": "1.1.24",
63
+ "zhin.js": "1.1.24"
71
64
  },
72
65
  "files": [
73
66
  "adapters",
@@ -1,6 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { definePage } from '@zhin.js/console-contract';
3
- import { createCommentReviewPage } from '@zhin.js/client';
2
+ import { defineCommentReviewPage, definePage } from '@zhin.js/console-contract';
4
3
  import { spec } from './spec.js';
5
4
  export const meta = definePage({
6
5
  title: '掘金评论审批',
@@ -10,8 +9,8 @@ export const meta = definePage({
10
9
  requiredPermissions: ['juejin:read'],
11
10
  });
12
11
  /**
13
- * Convention page entry: `pages/index/index.tsx` → `/<插件路径>`(如 `/juejin`)。
14
- * 看登录态和白名单文章、审批 AI 写好的掘金评论回复;页面本体是 `@zhin.js/client` 的 `createCommentReviewPage`,
12
+ * Convention page entry: `pages/index/index.ts` → `/<插件路径>`(如 `/juejin`)。
13
+ * 看登录态和白名单文章、审批 AI 写好的掘金评论回复;采用纯服务端声明式 Blueprint,
15
14
  * 数据走插件 RPC(plugin.<pluginId>.status / 动作)。
16
15
  */
17
- export default createCommentReviewPage(spec);
16
+ export default defineCommentReviewPage(spec);
@@ -1,5 +1,4 @@
1
- import { definePage } from '@zhin.js/console-contract';
2
- import { createCommentReviewPage } from '@zhin.js/client';
1
+ import { defineCommentReviewPage, definePage } from '@zhin.js/console-contract';
3
2
  import { spec } from './spec.js';
4
3
 
5
4
  export const meta = definePage({
@@ -11,8 +10,8 @@ export const meta = definePage({
11
10
  });
12
11
 
13
12
  /**
14
- * Convention page entry: `pages/index/index.tsx` → `/<插件路径>`(如 `/juejin`)。
15
- * 看登录态和白名单文章、审批 AI 写好的掘金评论回复;页面本体是 `@zhin.js/client` 的 `createCommentReviewPage`,
13
+ * Convention page entry: `pages/index/index.ts` → `/<插件路径>`(如 `/juejin`)。
14
+ * 看登录态和白名单文章、审批 AI 写好的掘金评论回复;采用纯服务端声明式 Blueprint,
16
15
  * 数据走插件 RPC(plugin.<pluginId>.status / 动作)。
17
16
  */
18
- export default createCommentReviewPage(spec);
17
+ export default defineCommentReviewPage(spec);
@@ -1,21 +1,19 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import React from 'react';
4
- import { ReviewResourceList } from '@zhin.js/client';
5
- import { Button } from '@zhin.js/client/ui';
6
2
  export const spec = {
7
3
  adapter: 'juejin',
8
4
  platform: { zh: '掘金', en: 'Juejin' },
9
5
  mark: '掘',
10
6
  resource: { zh: '文章', en: 'articles' },
7
+ loginMode: 'cookie-check',
8
+ resourcesKey: 'articles',
11
9
  openLabel: '打开文章',
12
- account: endpoint => ({ id: endpoint.login.userId, name: endpoint.login.userName }),
10
+ account: (endpoint) => ({ id: endpoint.login.userId, name: endpoint.login.userName }),
13
11
  draftResource: (draft, t) => t('文章 {0}', draft.articleId),
14
- loginHint: ({ login }, t) => login.state === 'none' ? t('未登录时只能读取公开评论,不能发送回复。请用 JUEJIN_COOKIE 环境变量注入 Cookie。')
15
- : login.state === 'expired' ? t('Cookie 已失效,草稿都保留着。更新 JUEJIN_COOKIE 后重启就能继续发送。')
12
+ loginHint: ({ login }, t) => login.state === 'none'
13
+ ? t('未登录时只能读取公开评论,不能发送回复。请用 JUEJIN_COOKIE 环境变量注入 Cookie。')
14
+ : login.state === 'expired'
15
+ ? t('Cookie 已失效,草稿都保留着。更新 JUEJIN_COOKIE 后重启就能继续发送。')
16
16
  : t('Cookie 只来自配置 / 环境变量,不会经过这个页面,也不会写进数据目录。'),
17
- renderLoginExtras: (_endpoint, { t, pending, act }) => (_jsx("div", { className: "zk-row", children: _jsx(Button, { busy: pending === 'login-check', disabled: pending !== undefined, onClick: () => act('login-check'), children: t('重新检查登录') }) })),
18
- renderResources: (endpoint, { t, noun }) => (_jsx(ReviewResourceList, { title: t('管理的{0}', noun), items: endpoint.articles.map(article => ({ key: article.id, label: article.id, url: article.url })), empty: t('还没有配置文章。要管理哪些文章请在配置的 articles 里填写文章 id 或链接。'), footnote: t('{0}列表来自配置,要增删请改配置文件。', noun) })),
19
17
  dictionary: {
20
18
  '打开文章': 'Open article',
21
19
  '文章 {0}': 'Article {0}',
@@ -0,0 +1,50 @@
1
+ import type {
2
+ CommentReviewBlueprintSpec,
3
+ CommentReviewDraftBase,
4
+ CommentReviewEndpointBase,
5
+ } from '@zhin.js/console-contract';
6
+
7
+ /** 与插件 `src/console.ts` 返回的结构保持一致(只读视图)。 */
8
+ export interface JuejinDraft extends CommentReviewDraftBase {
9
+ readonly articleId: string;
10
+ }
11
+
12
+ export interface JuejinEndpoint extends CommentReviewEndpointBase<JuejinDraft> {
13
+ readonly login: {
14
+ readonly state: 'none' | 'ok' | 'expired';
15
+ readonly userId?: string;
16
+ readonly userName?: string;
17
+ };
18
+ readonly articles: readonly { readonly id: string; readonly url: string }[];
19
+ }
20
+
21
+ export const spec: CommentReviewBlueprintSpec<JuejinEndpoint, JuejinDraft> = {
22
+ adapter: 'juejin',
23
+ platform: { zh: '掘金', en: 'Juejin' },
24
+ mark: '掘',
25
+ resource: { zh: '文章', en: 'articles' },
26
+ loginMode: 'cookie-check',
27
+ resourcesKey: 'articles',
28
+ openLabel: '打开文章',
29
+ account: (endpoint) => ({ id: endpoint.login.userId, name: endpoint.login.userName }),
30
+ draftResource: (draft, t) => t('文章 {0}', draft.articleId),
31
+ loginHint: ({ login }, t) =>
32
+ login.state === 'none'
33
+ ? t('未登录时只能读取公开评论,不能发送回复。请用 JUEJIN_COOKIE 环境变量注入 Cookie。')
34
+ : login.state === 'expired'
35
+ ? t('Cookie 已失效,草稿都保留着。更新 JUEJIN_COOKIE 后重启就能继续发送。')
36
+ : t('Cookie 只来自配置 / 环境变量,不会经过这个页面,也不会写进数据目录。'),
37
+ dictionary: {
38
+ '打开文章': 'Open article',
39
+ '文章 {0}': 'Article {0}',
40
+ '未登录时只能读取公开评论,不能发送回复。请用 JUEJIN_COOKIE 环境变量注入 Cookie。':
41
+ 'Without signing in, only public comments are read and replies cannot be posted. Inject the cookie with the JUEJIN_COOKIE environment variable.',
42
+ 'Cookie 已失效,草稿都保留着。更新 JUEJIN_COOKIE 后重启就能继续发送。':
43
+ 'The cookie has expired. Drafts are kept; update JUEJIN_COOKIE and restart to keep sending.',
44
+ 'Cookie 只来自配置 / 环境变量,不会经过这个页面,也不会写进数据目录。':
45
+ 'The cookie only comes from config or environment; it never passes through this page or the data directory.',
46
+ '重新检查登录': 'Check login again',
47
+ '还没有配置文章。要管理哪些文章请在配置的 articles 里填写文章 id 或链接。':
48
+ 'No articles configured. Add article IDs or links under articles in the config.',
49
+ },
50
+ };
package/plugin.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { definePlugin, outboundHostToken, pluginConsoleRpcToken } from 'zhin.js';
3
- import { juejinNotifierToken } from "./lib/juejin-runtime-state.js";
2
+ import { definePlugin, outboundHostToken } from 'zhin.js';
3
+ import { juejinNotifierStore } from "./lib/juejin-runtime-state.js";
4
4
  import { createJuejinConsoleRpc } from "./lib/console.js";
5
5
  /**
6
6
  * Plugin Runtime:
@@ -27,7 +27,9 @@ export default definePlugin({
27
27
  });
28
28
  return true;
29
29
  };
30
- context.resources.provide(juejinNotifierToken, notifier);
31
- context.resources.provide(pluginConsoleRpcToken, createJuejinConsoleRpc());
30
+ juejinNotifierStore.provide(context, () => notifier);
31
+ return {
32
+ consoleRpc: createJuejinConsoleRpc(),
33
+ };
32
34
  },
33
35
  });
@@ -1,11 +1,12 @@
1
1
  /** Domain notifier only; account ownership and review directory are projected from the Adapter. */
2
- import { createToken } from 'zhin.js';
2
+ import { definePluginStore } from 'zhin.js';
3
3
  import type { ResolvedJuejinNotifyTarget } from './protocol.js';
4
4
 
5
5
  /** 返回 false 表示当前没有可用的出站通道(只记日志)。 */
6
6
  export type JuejinNotifier = (target: ResolvedJuejinNotifyTarget, text: string) => Promise<boolean>;
7
7
 
8
- export const juejinNotifierToken = createToken<JuejinNotifier>(
8
+ export const juejinNotifierStore = definePluginStore<JuejinNotifier>(
9
9
  'zhin.juejin-comment.notifier',
10
10
  'Pushes Juejin draft / login notices to a configured chat conversation via OutboundHost',
11
11
  );
12
+ export const juejinNotifierToken = juejinNotifierStore;
@@ -1,39 +0,0 @@
1
- import React from 'react';
2
- import { ReviewResourceList, type CommentReviewSpec, type ReviewDraftBase, type ReviewEndpointBase } from '@zhin.js/client';
3
- import { Button } from '@zhin.js/client/ui';
4
-
5
- /** 与插件 `src/console.ts` 返回的结构保持一致(只读视图)。 */
6
- interface JuejinDraft extends ReviewDraftBase { readonly articleId: string }
7
- interface JuejinEndpoint extends ReviewEndpointBase<JuejinDraft> {
8
- readonly login: { readonly state: 'none' | 'ok' | 'expired'; readonly userId?: string; readonly userName?: string };
9
- readonly articles: readonly { readonly id: string; readonly url: string }[];
10
- }
11
-
12
- export const spec: CommentReviewSpec<JuejinEndpoint, JuejinDraft> = {
13
- adapter: 'juejin',
14
- platform: { zh: '掘金', en: 'Juejin' },
15
- mark: '掘',
16
- resource: { zh: '文章', en: 'articles' },
17
- openLabel: '打开文章',
18
- account: endpoint => ({ id: endpoint.login.userId, name: endpoint.login.userName }),
19
- draftResource: (draft, t) => t('文章 {0}', draft.articleId),
20
- loginHint: ({ login }, t) => login.state === 'none' ? t('未登录时只能读取公开评论,不能发送回复。请用 JUEJIN_COOKIE 环境变量注入 Cookie。')
21
- : login.state === 'expired' ? t('Cookie 已失效,草稿都保留着。更新 JUEJIN_COOKIE 后重启就能继续发送。')
22
- : t('Cookie 只来自配置 / 环境变量,不会经过这个页面,也不会写进数据目录。'),
23
- renderLoginExtras: (_endpoint, { t, pending, act }) => (
24
- <div className="zk-row"><Button busy={pending === 'login-check'} disabled={pending !== undefined} onClick={() => act('login-check')}>{t('重新检查登录')}</Button></div>
25
- ),
26
- renderResources: (endpoint, { t, noun }) => (
27
- <ReviewResourceList title={t('管理的{0}', noun)} items={endpoint.articles.map(article => ({ key: article.id, label: article.id, url: article.url }))}
28
- empty={t('还没有配置文章。要管理哪些文章请在配置的 articles 里填写文章 id 或链接。')} footnote={t('{0}列表来自配置,要增删请改配置文件。', noun)} />
29
- ),
30
- dictionary: {
31
- '打开文章': 'Open article',
32
- '文章 {0}': 'Article {0}',
33
- '未登录时只能读取公开评论,不能发送回复。请用 JUEJIN_COOKIE 环境变量注入 Cookie。': 'Without signing in, only public comments are read and replies cannot be posted. Inject the cookie with the JUEJIN_COOKIE environment variable.',
34
- 'Cookie 已失效,草稿都保留着。更新 JUEJIN_COOKIE 后重启就能继续发送。': 'The cookie has expired. Drafts are kept; update JUEJIN_COOKIE and restart to keep sending.',
35
- 'Cookie 只来自配置 / 环境变量,不会经过这个页面,也不会写进数据目录。': 'The cookie only comes from config or environment; it never passes through this page or the data directory.',
36
- '重新检查登录': 'Check login again',
37
- '还没有配置文章。要管理哪些文章请在配置的 articles 里填写文章 id 或链接。': 'No articles configured. Add article IDs or links under articles in the config.',
38
- },
39
- };