@zhin.js/adapter-satori 1.1.18 → 1.1.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zhin.js/adapter-satori",
3
- "version": "1.1.18",
3
+ "version": "1.1.20",
4
4
  "description": "Zhin.js Satori adapter for Plugin Runtime (WebSocket client)",
5
5
  "type": "module",
6
6
  "main": "./lib/index.js",
@@ -41,30 +41,30 @@
41
41
  "@imhelper/satori-v1": "1.0.7",
42
42
  "imhelper": "1.0.7",
43
43
  "ws": "^8.21.1",
44
- "@zhin.js/adapter": "1.1.25",
45
- "@zhin.js/client": "1.1.21",
44
+ "@zhin.js/adapter": "1.1.26",
45
+ "@zhin.js/client": "1.1.22",
46
46
  "@zhin.js/console-contract": "1.1.3",
47
- "@zhin.js/core": "1.1.53",
48
- "@zhin.js/feature-kit": "1.1.9",
49
- "@zhin.js/host-http": "1.1.11",
47
+ "@zhin.js/core": "1.1.54",
48
+ "@zhin.js/feature-kit": "1.1.10",
49
+ "@zhin.js/host-http": "1.1.12",
50
50
  "@zhin.js/im-contract": "1.1.9",
51
51
  "@zhin.js/logger": "1.1.2",
52
- "@zhin.js/page": "1.1.10",
53
- "@zhin.js/skill": "1.1.10"
52
+ "@zhin.js/page": "1.1.12",
53
+ "@zhin.js/skill": "1.1.11"
54
54
  },
55
55
  "devDependencies": {
56
56
  "@types/node": "^26.1.2",
57
57
  "@types/ws": "^8.18.1",
58
58
  "typescript": "^6.0.3",
59
59
  "vitest": "^4.1.10",
60
- "@zhin.js/host-http": "1.1.11",
61
- "zhin.js": "1.1.18"
60
+ "@zhin.js/host-http": "1.1.12",
61
+ "zhin.js": "1.1.19"
62
62
  },
63
63
  "peerDependencies": {
64
- "@zhin.js/adapter": "^1.1.25",
65
- "@zhin.js/command": "^1.1.11",
66
- "@zhin.js/core": "^1.1.53",
67
- "zhin.js": "^1.1.18"
64
+ "@zhin.js/adapter": "^1.1.26",
65
+ "@zhin.js/command": "^1.1.12",
66
+ "@zhin.js/core": "^1.1.54",
67
+ "zhin.js": "^1.1.19"
68
68
  },
69
69
  "peerDependenciesMeta": {
70
70
  "@zhin.js/command": {
@@ -95,7 +95,7 @@
95
95
  "features": [
96
96
  {
97
97
  "package": "@zhin.js/adapter",
98
- "api": "^1.0.0"
98
+ "api": "^2.0.0"
99
99
  },
100
100
  {
101
101
  "package": "@zhin.js/command",
package/plugin.js CHANGED
@@ -1,7 +1,5 @@
1
1
  // Generated by build-plugin-runtime-entries.mjs. Do not edit.
2
- import { createEndpointRuntimeState } from 'zhin.js/adapter';
3
2
  import { definePlugin, pluginConsoleRpcToken } from 'zhin.js';
4
- import { satoriRuntimeStateToken } from "./lib/satori-runtime-state.js";
5
3
  import { createSatoriConsoleRpc } from "./lib/console.js";
6
4
  export default definePlugin({
7
5
  name: 'satori',
@@ -9,8 +7,6 @@ export default definePlugin({
9
7
  displayName: 'Satori Adapter',
10
8
  },
11
9
  setup(context) {
12
- // 运行中 endpoint 注册表(satori endpoint list 的"运行中"数据源)
13
- context.resources.provide(satoriRuntimeStateToken, createEndpointRuntimeState());
14
10
  context.resources.provide(pluginConsoleRpcToken, createSatoriConsoleRpc(context.resources, () => context.config.get()));
15
11
  },
16
12
  });
package/schema.json CHANGED
@@ -48,7 +48,7 @@
48
48
  "endpoints": {
49
49
  "type": "array",
50
50
  "minItems": 1,
51
- "description": "多账号:每项定义一个 endpoint,id/baseUrl 必填,其余字段覆盖实例默认值",
51
+ "description": "多账号:每项明确选择 platform/userId,id/baseUrl 必填,其余字段覆盖实例默认值",
52
52
  "items": {
53
53
  "type": "object",
54
54
  "additionalProperties": false,
@@ -109,16 +109,28 @@
109
109
  "id": {
110
110
  "type": "string",
111
111
  "description": "Satori bot name"
112
+ },
113
+ "platform": {
114
+ "type": "string",
115
+ "minLength": 1,
116
+ "description": "Selected Satori login platform"
117
+ },
118
+ "userId": {
119
+ "type": "string",
120
+ "minLength": 1,
121
+ "description": "Selected Satori login user ID"
112
122
  }
113
123
  },
114
124
  "required": [
115
125
  "id",
116
- "baseUrl"
126
+ "baseUrl",
127
+ "platform",
128
+ "userId"
117
129
  ]
118
130
  },
119
131
  "x-i18n": {
120
132
  "en": {
121
- "description": "Multiple accounts: each entry defines an endpoint. id and baseUrl are required; other fields override instance defaults."
133
+ "description": "Multiple accounts: each entry selects an explicit platform and userId. id and baseUrl are required; remaining fields override instance defaults."
122
134
  }
123
135
  }
124
136
  },
package/src/adapter.ts ADDED
@@ -0,0 +1,32 @@
1
+ import { Adapter, type AdapterContext, type EndpointCreationContext } from 'zhin.js/adapter';
2
+ import { httpHostToken } from '@zhin.js/host-http';
3
+ import { callSatoriApi, resolveSatoriConfig, type SatoriEndpointConfig, type SatoriLogin } from './protocol.js';
4
+ import { SatoriWsEndpoint, SatoriWebhookEndpoint } from './endpoint.js';
5
+ import type { SatoriClientEventMap } from './client.js';
6
+
7
+ export class SatoriAdapter extends Adapter<SatoriWsEndpoint | SatoriWebhookEndpoint, SatoriEndpointConfig, SatoriClientEventMap> {
8
+ readonly #context: AdapterContext<SatoriEndpointConfig>;
9
+ constructor(context: AdapterContext<SatoriEndpointConfig>) { super(); this.#context = context; }
10
+ override get configurationIdentityFields(): readonly string[] { return ['id', 'platform', 'userId']; }
11
+ override get configurationIdentityProbeFields(): readonly string[] { return ['token', 'baseUrl']; }
12
+ override get configurationUpdateFields(): readonly string[] { return ['connection', 'baseUrl', 'token', 'path', 'heartbeat_interval']; }
13
+ protected override validateConfiguration(config: SatoriEndpointConfig): void { resolveSatoriConfig(config); }
14
+ protected override async identifyConfiguration(input: SatoriEndpointConfig, signal: AbortSignal): Promise<string> {
15
+ const config = resolveSatoriConfig(input);
16
+ signal.throwIfAborted();
17
+ const login = await callSatoriApi<SatoriLogin>({ ...config, signal, resource: 'login', method: 'get' });
18
+ signal.throwIfAborted();
19
+ if (!login?.platform || !login.user?.id) throw new Error('Satori login identity is unavailable');
20
+ if (login.platform !== config.platform || login.user.id !== config.userId) throw new Error('Satori returned another login identity');
21
+ return `satori:${JSON.stringify([login.platform, login.user.id])}`;
22
+ }
23
+ protected createEndpoint(input: SatoriEndpointConfig, execution: EndpointCreationContext): SatoriWsEndpoint | SatoriWebhookEndpoint {
24
+ const config = resolveSatoriConfig(input), id = execution.canonicalId, signal = execution.signal;
25
+ return config.connection === 'webhook'
26
+ ? new SatoriWebhookEndpoint({ id, config, signal, http: this.#context.use(httpHostToken) })
27
+ : new SatoriWsEndpoint({ id, config, signal });
28
+ }
29
+ }
30
+ declare module '@zhin.js/feature-kit' {
31
+ interface AdapterRegistry { readonly satori: SatoriAdapter; }
32
+ }
package/src/client.ts CHANGED
@@ -1,16 +1,15 @@
1
+ import { EndpointDeliveryError } from '@zhin.js/im-contract';
1
2
  import {
2
3
  SatoriV1Client,
3
4
  type SatoriV1Event,
4
5
  } from '@imhelper/satori-v1';
5
6
  import { EventFactory, type EventMap, type ImHelperEventMap } from 'imhelper';
6
7
  import {
7
- defineEndpointClient,
8
8
  forwardEndpointClientEvents,
9
9
  type ClientEventPayloads,
10
10
  } from 'zhin.js/adapter';
11
11
  import type {
12
12
  ResolvedSatoriConfig,
13
- SatoriApiOptions,
14
13
  callSatoriApi,
15
14
  } from './protocol.js';
16
15
 
@@ -19,18 +18,35 @@ export { SatoriV1Client as SatoriClient } from '@imhelper/satori-v1';
19
18
  type SatoriClientEvents = ImHelperEventMap<string, SatoriV1Event, EventMap<string>>;
20
19
  export type SatoriClientEventMap = ClientEventPayloads<SatoriClientEvents>;
21
20
 
22
- export function createSatoriEndpointClient(
23
- config: ResolvedSatoriConfig,
24
- request: typeof callSatoriApi,
25
- apiOptions: () => SatoriApiOptions,
26
- ): SatoriV1Client {
27
- return new SatoriV1Client({
28
- baseUrl: config.baseUrl,
29
- selfId: config.id,
30
- accessToken: config.token,
31
- receiveMode: 'manual',
32
- call: (resource, method, params) => request(apiOptions(), resource, method, params ?? {}),
33
- });
21
+ /** One account-bound caller is shared by native SDK and semantic ports. */
22
+ export interface SatoriActionRequest {
23
+ readonly resource: string;
24
+ readonly method: string;
25
+ readonly params?: Record<string, unknown>;
26
+ readonly signal?: AbortSignal;
27
+ }
28
+ export interface SatoriClientBinding {
29
+ readonly config: ResolvedSatoriConfig;
30
+ readonly request: typeof callSatoriApi;
31
+ readonly signal?: AbortSignal;
32
+ }
33
+ export type SatoriActionCaller = (request: SatoriActionRequest) => Promise<unknown>;
34
+ export function createSatoriActionCaller({ config, request, signal }: SatoriClientBinding): SatoriActionCaller {
35
+ return action => {
36
+ const operationSignal = signal && action.signal ? AbortSignal.any([signal, action.signal]) : signal ?? action.signal;
37
+ if (operationSignal?.aborted) throw new EndpointDeliveryError('endpoint_inactive', 'Endpoint request ended before submission', 'not_sent', { cause: operationSignal.reason });
38
+ return request({ baseUrl: config.baseUrl, platform: config.platform, userId: config.userId,
39
+ token: config.token, ...action, signal: operationSignal });
40
+ };
41
+ }
42
+ export function satoriClientOptions({ config, call }: {
43
+ readonly config: ResolvedSatoriConfig;
44
+ readonly call: SatoriActionCaller;
45
+ }): ConstructorParameters<typeof SatoriV1Client>[0] {
46
+ return { baseUrl: config.baseUrl, selfId: config.userId, platform: config.platform,
47
+ accessToken: config.token, receiveMode: 'manual',
48
+ call: (resource, method, params) => call({ resource, method, params: params ?? {} }),
49
+ };
34
50
  }
35
51
 
36
52
  const satoriClientEventNames = Object.freeze([
@@ -44,14 +60,3 @@ export function forwardSatoriClientEvents(
44
60
  ): () => void {
45
61
  return forwardEndpointClientEvents(client, satoriClientEventNames, receive);
46
62
  }
47
-
48
- declare module '@zhin.js/feature-kit' {
49
- interface AdapterClientRegistry {
50
- readonly satori: {
51
- readonly client: SatoriV1Client;
52
- readonly events: SatoriClientEventMap;
53
- };
54
- }
55
- }
56
-
57
- export const satoriClient = defineEndpointClient<SatoriV1Client, SatoriClientEventMap>('satori');
@@ -7,6 +7,8 @@ export const satoriConsoleSpec = {
7
7
  adapterKey: 'satori',
8
8
  adapterDisplayName: 'Satori',
9
9
  fields: [
10
+ { key: 'platform', required: true, description: 'Selected Satori login platform' },
11
+ { key: 'userId', required: true, description: 'Selected Satori login user ID' },
10
12
  { key: 'baseUrl', required: true, description: 'Satori 服务 base URL', descriptionI18n: { en: 'Satori service base URL' } },
11
13
  { key: 'path', description: 'webhook 路径(connection: webhook)', descriptionI18n: { en: 'Webhook path (connection: webhook)' } },
12
14
  { key: 'token', env: true, description: 'Satori access token' },
package/src/console.ts CHANGED
@@ -5,17 +5,14 @@
5
5
  */
6
6
  import { createAdapterConsoleRpc, type AdapterConsoleResources } from 'zhin.js/adapter';
7
7
  import type { PluginConsoleRpc } from 'zhin.js';
8
- import { satoriRuntimeStateToken } from './satori-runtime-state.js';
9
8
  import { satoriConsoleSpec } from './console-spec.js';
10
9
 
11
10
  export function createSatoriConsoleRpc(
12
- resources: AdapterConsoleResources,
11
+ _resources: AdapterConsoleResources,
13
12
  getConfig: () => unknown,
14
13
  ): PluginConsoleRpc {
15
- const state = resources.use(satoriRuntimeStateToken);
16
14
  return createAdapterConsoleRpc({
17
15
  ...satoriConsoleSpec,
18
- running: () => state.endpoints.values(),
19
16
  getConfig,
20
- }, resources);
17
+ });
21
18
  }