@double-coding/dsh-connectors 0.0.0-stage → 0.1.0-test.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (125) hide show
  1. package/CONTRIBUTING.md +173 -0
  2. package/LICENSE +21 -0
  3. package/README.en.md +156 -0
  4. package/README.md +153 -2
  5. package/assets/readme/architecture.webp +0 -0
  6. package/assets/readme/hero-en.svg +62 -0
  7. package/assets/readme/hero.svg +62 -0
  8. package/assets/readme/panel.webp +0 -0
  9. package/cordis.patch.yml +8 -0
  10. package/dist/client.js +5385 -0
  11. package/dist/client.js.map +7 -0
  12. package/dist/host/catalog.d.ts +7 -0
  13. package/dist/host/catalog.js +15 -0
  14. package/dist/host/catalog.js.map +1 -0
  15. package/dist/host/cli/adapters.d.ts +69 -0
  16. package/dist/host/cli/adapters.js +577 -0
  17. package/dist/host/cli/adapters.js.map +1 -0
  18. package/dist/host/cli/exec.d.ts +34 -0
  19. package/dist/host/cli/exec.js +186 -0
  20. package/dist/host/cli/exec.js.map +1 -0
  21. package/dist/host/cli/service.d.ts +44 -0
  22. package/dist/host/cli/service.js +711 -0
  23. package/dist/host/cli/service.js.map +1 -0
  24. package/dist/host/cli/version.d.ts +1 -0
  25. package/dist/host/cli/version.js +16 -0
  26. package/dist/host/cli/version.js.map +1 -0
  27. package/dist/host/connections.d.ts +106 -0
  28. package/dist/host/connections.js +1207 -0
  29. package/dist/host/connections.js.map +1 -0
  30. package/dist/host/errors.d.ts +4 -0
  31. package/dist/host/errors.js +8 -0
  32. package/dist/host/errors.js.map +1 -0
  33. package/dist/host/instanceUrl.d.ts +1 -0
  34. package/dist/host/instanceUrl.js +27 -0
  35. package/dist/host/instanceUrl.js.map +1 -0
  36. package/dist/host/mcpServers.d.ts +19 -0
  37. package/dist/host/mcpServers.js +243 -0
  38. package/dist/host/mcpServers.js.map +1 -0
  39. package/dist/host/oauth.d.ts +49 -0
  40. package/dist/host/oauth.js +215 -0
  41. package/dist/host/oauth.js.map +1 -0
  42. package/dist/host/openExternal.d.ts +1 -0
  43. package/dist/host/openExternal.js +45 -0
  44. package/dist/host/openExternal.js.map +1 -0
  45. package/dist/host/providers.d.ts +105 -0
  46. package/dist/host/providers.js +199 -0
  47. package/dist/host/providers.js.map +1 -0
  48. package/dist/host/routes.d.ts +18 -0
  49. package/dist/host/routes.js +514 -0
  50. package/dist/host/routes.js.map +1 -0
  51. package/dist/host/sse-bridge.d.ts +1 -0
  52. package/dist/host/sse-bridge.js +168 -0
  53. package/dist/host/sse-bridge.js.map +1 -0
  54. package/dist/host/store.d.ts +184 -0
  55. package/dist/host/store.js +98 -0
  56. package/dist/host/store.js.map +1 -0
  57. package/dist/index.d.ts +5 -0
  58. package/dist/index.js +35 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/shared/categories.d.ts +12 -0
  61. package/dist/shared/categories.js +59 -0
  62. package/dist/shared/categories.js.map +1 -0
  63. package/dist/shared/customConfig.d.ts +1 -0
  64. package/dist/shared/customConfig.js +2 -0
  65. package/dist/shared/customConfig.js.map +1 -0
  66. package/dist/shared/types.d.ts +222 -0
  67. package/dist/shared/types.js +2 -0
  68. package/dist/shared/types.js.map +1 -0
  69. package/package.json +96 -4
  70. package/providers/README.md +44 -0
  71. package/providers/amap/icon.png +0 -0
  72. package/providers/amap/provider.json +34 -0
  73. package/providers/baidu-netdisk/icon.png +0 -0
  74. package/providers/baidu-netdisk/provider.json +36 -0
  75. package/providers/circleci/icon.svg +1 -0
  76. package/providers/circleci/provider.json +29 -0
  77. package/providers/cloudflare-docs/icon.svg +1 -0
  78. package/providers/cloudflare-docs/provider.json +26 -0
  79. package/providers/context7/icon.png +0 -0
  80. package/providers/context7/provider.json +25 -0
  81. package/providers/deepwiki/icon.svg +5 -0
  82. package/providers/deepwiki/provider.json +26 -0
  83. package/providers/firecrawl/icon.png +0 -0
  84. package/providers/firecrawl/provider.json +40 -0
  85. package/providers/gitee/icon.svg +1 -0
  86. package/providers/gitee/provider.json +32 -0
  87. package/providers/github/icon.svg +1 -0
  88. package/providers/github/provider.json +33 -0
  89. package/providers/gitlab/icon.svg +1 -0
  90. package/providers/gitlab/provider.json +31 -0
  91. package/providers/gitlab-self-hosted/icon.svg +1 -0
  92. package/providers/gitlab-self-hosted/provider.json +39 -0
  93. package/providers/grafana/icon.svg +1 -0
  94. package/providers/grafana/provider.json +32 -0
  95. package/providers/linear/icon.svg +1 -0
  96. package/providers/linear/provider.json +41 -0
  97. package/providers/microsoft-learn/icon.svg +6 -0
  98. package/providers/microsoft-learn/provider.json +26 -0
  99. package/providers/neon/icon.svg +1 -0
  100. package/providers/neon/provider.json +41 -0
  101. package/providers/notion/icon.svg +1 -0
  102. package/providers/notion/provider.json +29 -0
  103. package/providers/posthog/icon.svg +1 -0
  104. package/providers/posthog/provider.json +38 -0
  105. package/providers/postman/icon.svg +1 -0
  106. package/providers/postman/provider.json +29 -0
  107. package/providers/qcc/icon.png +0 -0
  108. package/providers/qcc/provider.json +50 -0
  109. package/providers/sentry/icon.svg +1 -0
  110. package/providers/sentry/provider.json +30 -0
  111. package/providers/sourcegraph/icon.png +0 -0
  112. package/providers/sourcegraph/provider.json +32 -0
  113. package/providers/supabase/icon.svg +1 -0
  114. package/providers/supabase/provider.json +52 -0
  115. package/providers/tavily/icon.svg +4 -0
  116. package/providers/tavily/provider.json +41 -0
  117. package/providers/tencent-docs/icon.png +0 -0
  118. package/providers/tencent-docs/provider.json +34 -0
  119. package/providers/tencent-yuanbao-search/icon.png +0 -0
  120. package/providers/tencent-yuanbao-search/provider.json +32 -0
  121. package/providers/tianyancha/icon.png +0 -0
  122. package/providers/tianyancha/provider.json +34 -0
  123. package/providers/yunxiao/icon.svg +1 -0
  124. package/providers/yunxiao/provider.json +30 -0
  125. package/schema/provider.schema.json +325 -0
@@ -0,0 +1,215 @@
1
+ import { createHash, randomBytes } from 'node:crypto';
2
+ import { ConnectError } from './errors.js';
3
+ const REQUEST_TIMEOUT_MS = 12_000;
4
+ async function getJson(url, init) {
5
+ let response;
6
+ try {
7
+ response = await fetch(url, {
8
+ ...init,
9
+ headers: { accept: 'application/json', ...init?.headers },
10
+ signal: AbortSignal.timeout(REQUEST_TIMEOUT_MS),
11
+ });
12
+ }
13
+ catch (error) {
14
+ throw new ConnectError('oauth_unreachable', `无法访问 OAuth 服务:${error instanceof Error ? error.message : String(error)}`);
15
+ }
16
+ const text = await response.text();
17
+ let body = {};
18
+ try {
19
+ body = JSON.parse(text);
20
+ }
21
+ catch {
22
+ // 非 JSON 响应按状态码报错
23
+ }
24
+ if (!response.ok) {
25
+ const detail = typeof body.error_description === 'string'
26
+ ? body.error_description
27
+ : typeof body.error === 'string'
28
+ ? body.error
29
+ : `HTTP ${response.status}`;
30
+ throw new ConnectError('oauth_failed', `OAuth 请求失败:${detail}`);
31
+ }
32
+ return body;
33
+ }
34
+ function asString(value) {
35
+ return typeof value === 'string' && value !== '' ? value : undefined;
36
+ }
37
+ function asStringList(value) {
38
+ return Array.isArray(value) ? value.filter((item) => typeof item === 'string') : [];
39
+ }
40
+ // 401 的 WWW-Authenticate 里可能直接给出 resource_metadata 地址(RFC 9728),优先用它
41
+ async function advertisedResourceMetadata(resource) {
42
+ try {
43
+ const response = await fetch(resource, {
44
+ method: 'POST',
45
+ headers: { 'content-type': 'application/json', accept: 'application/json, text/event-stream' },
46
+ body: JSON.stringify({
47
+ jsonrpc: '2.0',
48
+ id: 0,
49
+ method: 'initialize',
50
+ params: {
51
+ protocolVersion: '2025-06-18',
52
+ capabilities: {},
53
+ clientInfo: { name: 'dsh-connectors', version: '0.1.0' },
54
+ },
55
+ }),
56
+ signal: AbortSignal.timeout(5_000),
57
+ });
58
+ const header = response.headers.get('www-authenticate') ?? '';
59
+ return /resource_metadata="([^"]+)"/i.exec(header)?.[1];
60
+ }
61
+ catch {
62
+ return undefined;
63
+ }
64
+ }
65
+ // 两种 well-known 拼法都要兼容:{origin}/.well-known/...{path} 与 {resource}/.well-known/...
66
+ async function fetchResourceMetadata(resource) {
67
+ const resourceUrl = new URL(resource);
68
+ const candidates = [];
69
+ const advertised = await advertisedResourceMetadata(resource);
70
+ if (advertised !== undefined)
71
+ candidates.push(advertised);
72
+ const suffix = `${resourceUrl.origin}/.well-known/oauth-protected-resource${resourceUrl.pathname}`;
73
+ candidates.push(suffix.replace(/\/$/, ''));
74
+ candidates.push(`${resource.replace(/\/+$/, '')}/.well-known/oauth-protected-resource`);
75
+ let firstError;
76
+ for (const candidate of [...new Set(candidates)]) {
77
+ try {
78
+ return await getJson(candidate);
79
+ }
80
+ catch (error) {
81
+ firstError ??= error;
82
+ }
83
+ }
84
+ throw firstError;
85
+ }
86
+ export async function fetchOAuthMetadata(resource) {
87
+ const resourceUrl = new URL(resource);
88
+ const resourceMetadata = await fetchResourceMetadata(resource);
89
+ const issuer = asStringList(resourceMetadata.authorization_servers)[0] ?? resourceUrl.origin;
90
+ const serverMetadata = await getJson(`${issuer.replace(/\/+$/, '')}/.well-known/oauth-authorization-server`);
91
+ const authorizationEndpoint = asString(serverMetadata.authorization_endpoint);
92
+ const tokenEndpoint = asString(serverMetadata.token_endpoint);
93
+ if (authorizationEndpoint === undefined || tokenEndpoint === undefined) {
94
+ throw new ConnectError('oauth_failed', 'OAuth 元数据缺少授权端点或令牌端点');
95
+ }
96
+ const scope = asStringList(resourceMetadata.scopes_supported)[0]
97
+ ?? (asStringList(serverMetadata.scopes_supported).includes('mcp')
98
+ ? 'mcp'
99
+ : asStringList(serverMetadata.scopes_supported)[0])
100
+ ?? 'mcp';
101
+ return {
102
+ authorizationEndpoint,
103
+ tokenEndpoint,
104
+ ...(asString(serverMetadata.registration_endpoint) === undefined
105
+ ? {}
106
+ : { registrationEndpoint: asString(serverMetadata.registration_endpoint) }),
107
+ scope,
108
+ resource: asString(resourceMetadata.resource) ?? resource,
109
+ };
110
+ }
111
+ export async function registerOAuthClient(metadata, redirectUri, clientName) {
112
+ if (metadata.registrationEndpoint === undefined) {
113
+ throw new ConnectError('oauth_failed', 'OAuth 服务未提供动态客户端注册端点');
114
+ }
115
+ const body = await getJson(metadata.registrationEndpoint, {
116
+ method: 'POST',
117
+ headers: { 'content-type': 'application/json' },
118
+ body: JSON.stringify({
119
+ client_name: clientName,
120
+ redirect_uris: [redirectUri],
121
+ grant_types: ['authorization_code', 'refresh_token'],
122
+ response_types: ['code'],
123
+ token_endpoint_auth_method: 'none',
124
+ ...(metadata.scope === '' ? {} : { scope: metadata.scope }),
125
+ }),
126
+ });
127
+ const clientId = asString(body.client_id);
128
+ if (clientId === undefined)
129
+ throw new ConnectError('oauth_failed', 'OAuth 动态注册未返回 client_id');
130
+ return {
131
+ clientId,
132
+ ...(asString(body.client_secret) === undefined ? {} : { clientSecret: asString(body.client_secret) }),
133
+ };
134
+ }
135
+ export function createPkce() {
136
+ const verifier = randomBytes(32).toString('base64url');
137
+ const challenge = createHash('sha256').update(verifier).digest('base64url');
138
+ return { verifier, challenge };
139
+ }
140
+ export function createState() {
141
+ return randomBytes(24).toString('base64url');
142
+ }
143
+ export function buildAuthorizeUrl(metadata, options) {
144
+ const url = new URL(metadata.authorizationEndpoint);
145
+ url.searchParams.set('client_id', options.clientId);
146
+ url.searchParams.set('redirect_uri', options.redirectUri);
147
+ url.searchParams.set('response_type', 'code');
148
+ url.searchParams.set('state', options.state);
149
+ if (metadata.scope !== '')
150
+ url.searchParams.set('scope', metadata.scope);
151
+ if (options.challenge !== undefined) {
152
+ url.searchParams.set('code_challenge', options.challenge);
153
+ url.searchParams.set('code_challenge_method', 'S256');
154
+ }
155
+ if (metadata.resource !== undefined)
156
+ url.searchParams.set('resource', metadata.resource);
157
+ for (const [key, value] of Object.entries(metadata.authorizeParams ?? {})) {
158
+ url.searchParams.set(key, value);
159
+ }
160
+ return url.toString();
161
+ }
162
+ function parseTokens(body) {
163
+ const accessToken = asString(body.access_token);
164
+ if (accessToken === undefined)
165
+ throw new ConnectError('oauth_failed', 'OAuth 未返回访问令牌');
166
+ const expiresIn = typeof body.expires_in === 'number' ? body.expires_in : undefined;
167
+ return {
168
+ accessToken,
169
+ ...(asString(body.refresh_token) === undefined ? {} : { refreshToken: asString(body.refresh_token) }),
170
+ ...(expiresIn === undefined ? {} : { expiresAt: Date.now() + expiresIn * 1000 }),
171
+ ...(asString(body.scope) === undefined ? {} : { scope: asString(body.scope) }),
172
+ };
173
+ }
174
+ export async function exchangeCode(tokenEndpoint, options) {
175
+ const params = new URLSearchParams({
176
+ grant_type: 'authorization_code',
177
+ code: options.code,
178
+ redirect_uri: options.redirectUri,
179
+ client_id: options.clientId,
180
+ });
181
+ if (options.verifier !== undefined)
182
+ params.set('code_verifier', options.verifier);
183
+ if (options.clientSecret !== undefined)
184
+ params.set('client_secret', options.clientSecret);
185
+ if (options.resource !== undefined)
186
+ params.set('resource', options.resource);
187
+ const body = options.tokenMethod === 'GET'
188
+ ? await getJson(`${tokenEndpoint}${tokenEndpoint.includes('?') ? '&' : '?'}${params.toString()}`)
189
+ : await getJson(tokenEndpoint, {
190
+ method: 'POST',
191
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
192
+ body: params.toString(),
193
+ });
194
+ return parseTokens(body);
195
+ }
196
+ export async function refreshAccessToken(tokenEndpoint, options) {
197
+ const params = new URLSearchParams({
198
+ grant_type: 'refresh_token',
199
+ refresh_token: options.refreshToken,
200
+ client_id: options.clientId,
201
+ });
202
+ if (options.clientSecret !== undefined)
203
+ params.set('client_secret', options.clientSecret);
204
+ if (options.resource !== undefined)
205
+ params.set('resource', options.resource);
206
+ const body = options.tokenMethod === 'GET'
207
+ ? await getJson(`${tokenEndpoint}${tokenEndpoint.includes('?') ? '&' : '?'}${params.toString()}`)
208
+ : await getJson(tokenEndpoint, {
209
+ method: 'POST',
210
+ headers: { 'content-type': 'application/x-www-form-urlencoded' },
211
+ body: params.toString(),
212
+ });
213
+ return parseTokens(body);
214
+ }
215
+ //# sourceMappingURL=oauth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/host/oauth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export declare function openExternal(url: string): Promise<boolean>;
@@ -0,0 +1,45 @@
1
+ import { execFile } from 'node:child_process';
2
+ export function openExternal(url) {
3
+ let target;
4
+ try {
5
+ target = new URL(url);
6
+ }
7
+ catch {
8
+ return Promise.resolve(false);
9
+ }
10
+ if (target.protocol !== 'https:' && target.protocol !== 'http:')
11
+ return Promise.resolve(false);
12
+ let command;
13
+ let args;
14
+ if (process.platform === 'win32') {
15
+ command = 'rundll32.exe';
16
+ args = ['url.dll,FileProtocolHandler', url];
17
+ }
18
+ else if (process.platform === 'darwin') {
19
+ command = 'open';
20
+ args = [url];
21
+ }
22
+ else {
23
+ command = 'xdg-open';
24
+ args = [url];
25
+ }
26
+ return new Promise(resolve => {
27
+ let settled = false;
28
+ const finish = (value) => {
29
+ if (settled)
30
+ return;
31
+ settled = true;
32
+ resolve(value);
33
+ };
34
+ try {
35
+ const child = execFile(command, args, { windowsHide: true }, () => undefined);
36
+ child.once('spawn', () => finish(true));
37
+ child.once('error', () => finish(false));
38
+ }
39
+ catch {
40
+ finish(false);
41
+ }
42
+ setTimeout(() => finish(false), 3000).unref();
43
+ });
44
+ }
45
+ //# sourceMappingURL=openExternal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openExternal.js","sourceRoot":"","sources":["../../src/host/openExternal.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE7C,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,IAAI,MAAW,CAAA;IACf,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAC/B,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IAE9F,IAAI,OAAe,CAAA;IACnB,IAAI,IAAc,CAAA;IAClB,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,GAAG,cAAc,CAAA;QACxB,IAAI,GAAG,CAAC,6BAA6B,EAAE,GAAG,CAAC,CAAA;IAC7C,CAAC;SAAM,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QACzC,OAAO,GAAG,MAAM,CAAA;QAChB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;SAAM,CAAC;QACN,OAAO,GAAG,UAAU,CAAA;QACpB,IAAI,GAAG,CAAC,GAAG,CAAC,CAAA;IACd,CAAC;IAED,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,IAAI,OAAO,GAAG,KAAK,CAAA;QACnB,MAAM,MAAM,GAAG,CAAC,KAAc,EAAQ,EAAE;YACtC,IAAI,OAAO;gBAAE,OAAM;YACnB,OAAO,GAAG,IAAI,CAAA;YACd,OAAO,CAAC,KAAK,CAAC,CAAA;QAChB,CAAC,CAAA;QACD,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,QAAQ,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAA;YAC7E,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;YACvC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;QAC1C,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,CAAC,KAAK,CAAC,CAAA;QACf,CAAC;QACD,UAAU,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,IAAI,CAAC,CAAC,KAAK,EAAE,CAAA;IAC/C,CAAC,CAAC,CAAA;AACJ,CAAC"}
@@ -0,0 +1,105 @@
1
+ import { z } from 'zod';
2
+ import type { ConnectorCard } from '../shared/types.js';
3
+ export declare const PROVIDER_CATEGORIES: readonly ["开发工具", "项目管理", "数据库", "知识检索", "办公协作", "安全运维", "数据分析", "其他"];
4
+ export declare function isHttpsUrl(value: string): boolean;
5
+ export declare const providerDefinitionSchema: z.ZodObject<{
6
+ $schema: z.ZodOptional<z.ZodString>;
7
+ schemaVersion: z.ZodLiteral<1>;
8
+ id: z.ZodString;
9
+ name: z.ZodString;
10
+ vendor: z.ZodOptional<z.ZodString>;
11
+ category: z.ZodEnum<{
12
+ 开发工具: "开发工具";
13
+ 项目管理: "项目管理";
14
+ 数据库: "数据库";
15
+ 知识检索: "知识检索";
16
+ 办公协作: "办公协作";
17
+ 安全运维: "安全运维";
18
+ 数据分析: "数据分析";
19
+ 其他: "其他";
20
+ }>;
21
+ summary: z.ZodString;
22
+ description: z.ZodOptional<z.ZodString>;
23
+ examples: z.ZodOptional<z.ZodArray<z.ZodString>>;
24
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
25
+ featured: z.ZodOptional<z.ZodBoolean>;
26
+ order: z.ZodOptional<z.ZodNumber>;
27
+ instance: z.ZodOptional<z.ZodObject<{
28
+ label: z.ZodString;
29
+ noun: z.ZodOptional<z.ZodString>;
30
+ placeholder: z.ZodOptional<z.ZodString>;
31
+ hint: z.ZodOptional<z.ZodString>;
32
+ help: z.ZodOptional<z.ZodObject<{
33
+ url: z.ZodString;
34
+ label: z.ZodString;
35
+ hint: z.ZodOptional<z.ZodString>;
36
+ }, z.core.$strict>>;
37
+ presets: z.ZodOptional<z.ZodArray<z.ZodObject<{
38
+ label: z.ZodString;
39
+ url: z.ZodString;
40
+ hint: z.ZodOptional<z.ZodString>;
41
+ }, z.core.$strict>>>;
42
+ }, z.core.$strict>>;
43
+ server: z.ZodObject<{
44
+ serverName: z.ZodOptional<z.ZodString>;
45
+ transport: z.ZodEnum<{
46
+ "streamable-http": "streamable-http";
47
+ sse: "sse";
48
+ }>;
49
+ url: z.ZodOptional<z.ZodString>;
50
+ }, z.core.$strict>;
51
+ auth: z.ZodDiscriminatedUnion<[z.ZodObject<{
52
+ type: z.ZodLiteral<"none">;
53
+ }, z.core.$strict>, z.ZodObject<{
54
+ type: z.ZodLiteral<"bearer">;
55
+ label: z.ZodString;
56
+ help: z.ZodOptional<z.ZodObject<{
57
+ url: z.ZodString;
58
+ label: z.ZodString;
59
+ hint: z.ZodOptional<z.ZodString>;
60
+ }, z.core.$strict>>;
61
+ }, z.core.$strict>, z.ZodObject<{
62
+ type: z.ZodLiteral<"header">;
63
+ header: z.ZodString;
64
+ prefix: z.ZodOptional<z.ZodString>;
65
+ label: z.ZodString;
66
+ help: z.ZodOptional<z.ZodObject<{
67
+ url: z.ZodString;
68
+ label: z.ZodString;
69
+ hint: z.ZodOptional<z.ZodString>;
70
+ }, z.core.$strict>>;
71
+ }, z.core.$strict>, z.ZodObject<{
72
+ type: z.ZodLiteral<"oauth2">;
73
+ flow: z.ZodLiteral<"pkce">;
74
+ registration: z.ZodUnion<readonly [z.ZodLiteral<"dcr">, z.ZodLiteral<"user">, z.ZodObject<{
75
+ clientId: z.ZodString;
76
+ }, z.core.$strict>]>;
77
+ scopes: z.ZodOptional<z.ZodArray<z.ZodString>>;
78
+ clientName: z.ZodOptional<z.ZodString>;
79
+ endpoints: z.ZodOptional<z.ZodObject<{
80
+ authorization: z.ZodString;
81
+ token: z.ZodString;
82
+ }, z.core.$strict>>;
83
+ authorizeParams: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
84
+ tokenMethod: z.ZodOptional<z.ZodEnum<{
85
+ POST: "POST";
86
+ GET: "GET";
87
+ }>>;
88
+ pkce: z.ZodOptional<z.ZodBoolean>;
89
+ help: z.ZodOptional<z.ZodObject<{
90
+ url: z.ZodString;
91
+ label: z.ZodString;
92
+ hint: z.ZodOptional<z.ZodString>;
93
+ }, z.core.$strict>>;
94
+ }, z.core.$strict>], "type">;
95
+ }, z.core.$strict>;
96
+ export type ProviderDefinition = z.infer<typeof providerDefinitionSchema>;
97
+ export interface ProviderIssue {
98
+ file: string;
99
+ message: string;
100
+ }
101
+ export interface ProviderLoadResult {
102
+ cards: ConnectorCard[];
103
+ issues: ProviderIssue[];
104
+ }
105
+ export declare function loadProviders(directory: string): ProviderLoadResult;
@@ -0,0 +1,199 @@
1
+ import { existsSync, readFileSync, readdirSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { z } from 'zod';
4
+ import { BUILTIN_CATEGORIES } from '../shared/categories.js';
5
+ export const PROVIDER_CATEGORIES = BUILTIN_CATEGORIES;
6
+ const httpsUrl = z.string().url().refine(value => value.startsWith('https://'), '必须使用 https 地址');
7
+ const helpSchema = z.object({
8
+ url: httpsUrl,
9
+ label: z.string().min(1),
10
+ hint: z.string().min(1).optional(),
11
+ }).strict();
12
+ const instanceSchema = z.object({
13
+ label: z.string().min(1),
14
+ noun: z.string().min(1).optional(),
15
+ placeholder: z.string().min(1).optional(),
16
+ hint: z.string().min(1).optional(),
17
+ help: helpSchema.optional(),
18
+ presets: z.array(z.object({
19
+ label: z.string().min(1),
20
+ url: httpsUrl,
21
+ hint: z.string().min(1).optional(),
22
+ }).strict()).min(1).optional(),
23
+ }).strict();
24
+ export function isHttpsUrl(value) {
25
+ try {
26
+ return new URL(value).protocol === 'https:';
27
+ }
28
+ catch {
29
+ return false;
30
+ }
31
+ }
32
+ const authHelpSchema = helpSchema;
33
+ const authSchema = z.discriminatedUnion('type', [
34
+ z.object({ type: z.literal('none') }).strict(),
35
+ z.object({
36
+ type: z.literal('bearer'),
37
+ label: z.string().min(1),
38
+ help: authHelpSchema.optional(),
39
+ }).strict(),
40
+ z.object({
41
+ type: z.literal('header'),
42
+ header: z.string().min(1),
43
+ prefix: z.string().optional(),
44
+ label: z.string().min(1),
45
+ help: authHelpSchema.optional(),
46
+ }).strict(),
47
+ z.object({
48
+ type: z.literal('oauth2'),
49
+ flow: z.literal('pkce'),
50
+ registration: z.union([
51
+ z.literal('dcr'),
52
+ z.literal('user'),
53
+ z.object({ clientId: z.string().min(1) }).strict(),
54
+ ]),
55
+ scopes: z.array(z.string().min(1)).optional(),
56
+ clientName: z.string().min(1).optional(),
57
+ endpoints: z.object({
58
+ authorization: z.string().url(),
59
+ token: z.string().url(),
60
+ }).strict().optional(),
61
+ authorizeParams: z.record(z.string(), z.string()).optional(),
62
+ tokenMethod: z.enum(['POST', 'GET']).optional(),
63
+ pkce: z.boolean().optional(),
64
+ help: authHelpSchema.optional(),
65
+ }).strict(),
66
+ ]);
67
+ export const providerDefinitionSchema = z.object({
68
+ $schema: z.string().min(1).optional(),
69
+ schemaVersion: z.literal(1),
70
+ id: z.string().regex(/^[a-z0-9][a-z0-9-]*$/, 'id 只能包含小写字母、数字和连字符'),
71
+ name: z.string().min(1),
72
+ vendor: z.string().min(1).optional(),
73
+ category: z.enum(PROVIDER_CATEGORIES),
74
+ summary: z.string().min(1),
75
+ description: z.string().min(1).optional(),
76
+ examples: z.array(z.string().min(1)).max(6).optional(),
77
+ tags: z.array(z.string().min(1)).optional(),
78
+ featured: z.boolean().optional(),
79
+ order: z.number().int().nonnegative().optional(),
80
+ instance: instanceSchema.optional(),
81
+ server: z.object({
82
+ serverName: z.string().regex(/^[a-z0-9][a-z0-9_-]*$/, 'serverName 只能包含小写字母、数字、下划线和连字符').optional(),
83
+ transport: z.enum(['streamable-http', 'sse']),
84
+ url: z.string().min(1).optional(),
85
+ }).strict(),
86
+ auth: authSchema,
87
+ }).strict().superRefine((provider, ctx) => {
88
+ if (provider.instance !== undefined) {
89
+ if (provider.server.url !== undefined) {
90
+ ctx.addIssue({
91
+ code: 'custom',
92
+ path: ['server', 'url'],
93
+ message: '带 instance 时不要设置 server.url,完整地址由用户填写',
94
+ });
95
+ }
96
+ return;
97
+ }
98
+ if (provider.server.url === undefined || !isHttpsUrl(provider.server.url)) {
99
+ ctx.addIssue({
100
+ code: 'custom',
101
+ path: ['server', 'url'],
102
+ message: '不带 instance 时必须使用 https 地址',
103
+ });
104
+ }
105
+ if (provider.auth.type === 'oauth2' && provider.auth.registration === 'user' && provider.auth.endpoints === undefined) {
106
+ ctx.addIssue({
107
+ code: 'custom',
108
+ path: ['auth', 'endpoints'],
109
+ message: 'registration 为 user 时必须显式提供 authorization 与 token 端点',
110
+ });
111
+ }
112
+ });
113
+ function formatIssues(error) {
114
+ return error.issues
115
+ .map(issue => `${issue.path.length === 0 ? '(root)' : issue.path.join('.')}: ${issue.message}`)
116
+ .join('; ');
117
+ }
118
+ function toCard(provider, serverName) {
119
+ const server = {
120
+ serverName,
121
+ transport: provider.server.transport,
122
+ url: provider.server.url,
123
+ };
124
+ return {
125
+ id: provider.id,
126
+ name: provider.name,
127
+ vendor: provider.vendor,
128
+ category: provider.category,
129
+ summary: provider.summary,
130
+ description: provider.description,
131
+ examples: provider.examples,
132
+ tags: provider.tags,
133
+ published: true,
134
+ featured: provider.featured,
135
+ source: 'builtin',
136
+ auth: provider.auth,
137
+ ...(provider.instance === undefined ? {} : { instance: provider.instance }),
138
+ server,
139
+ };
140
+ }
141
+ export function loadProviders(directory) {
142
+ const issues = [];
143
+ if (!existsSync(directory)) {
144
+ return { cards: [], issues: [{ file: directory, message: 'providers 目录不存在' }] };
145
+ }
146
+ const folders = readdirSync(directory, { withFileTypes: true })
147
+ .filter(entry => entry.isDirectory())
148
+ .map(entry => entry.name)
149
+ .sort();
150
+ const loaded = [];
151
+ const ids = new Map();
152
+ const serverNames = new Map();
153
+ for (const folder of folders) {
154
+ const file = join(directory, folder, 'provider.json');
155
+ if (!existsSync(file))
156
+ continue;
157
+ let raw;
158
+ try {
159
+ raw = JSON.parse(readFileSync(file, 'utf8'));
160
+ }
161
+ catch (error) {
162
+ issues.push({ file, message: `JSON 解析失败:${error instanceof Error ? error.message : String(error)}` });
163
+ continue;
164
+ }
165
+ const parsed = providerDefinitionSchema.safeParse(raw);
166
+ if (!parsed.success) {
167
+ issues.push({ file, message: formatIssues(parsed.error) });
168
+ continue;
169
+ }
170
+ const provider = parsed.data;
171
+ if (provider.id !== folder) {
172
+ issues.push({ file, message: `id "${provider.id}" 必须与目录名 "${folder}" 一致` });
173
+ continue;
174
+ }
175
+ const duplicateId = ids.get(provider.id);
176
+ if (duplicateId !== undefined) {
177
+ issues.push({ file, message: `id "${provider.id}" 与 ${duplicateId} 重复` });
178
+ continue;
179
+ }
180
+ const serverName = provider.server.serverName ?? provider.id;
181
+ const duplicateName = serverNames.get(serverName);
182
+ if (duplicateName !== undefined) {
183
+ issues.push({ file, message: `serverName "${serverName}" 与 ${duplicateName} 重复` });
184
+ continue;
185
+ }
186
+ ids.set(provider.id, file);
187
+ serverNames.set(serverName, file);
188
+ loaded.push({ provider, serverName });
189
+ }
190
+ loaded.sort((left, right) => {
191
+ const order = (left.provider.order ?? 100) - (right.provider.order ?? 100);
192
+ return order !== 0 ? order : left.provider.name.localeCompare(right.provider.name);
193
+ });
194
+ return {
195
+ cards: loaded.map(({ provider, serverName }) => toCard(provider, serverName)),
196
+ issues,
197
+ };
198
+ }
199
+ //# sourceMappingURL=providers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/host/providers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { IncomingMessage, ServerResponse } from 'node:http';
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import type { CliConnectorService } from './cli/service.js';
4
+ import type { ConnectionService } from './connections.js';
5
+ export interface RouterFace {
6
+ register: (options: {
7
+ kind: 'prefix' | 'exact';
8
+ path: string;
9
+ handler: (req: IncomingMessage, res: ServerResponse) => void | Promise<void>;
10
+ }) => () => void;
11
+ }
12
+ export interface RouteOptions {
13
+ version: string;
14
+ capabilities: () => Record<string, boolean>;
15
+ connections: ConnectionService;
16
+ cli: CliConnectorService;
17
+ }
18
+ export declare function registerRoutes(ctx: Context, options: RouteOptions): () => void;