@harrylabsj/kiwi 0.8.0 → 0.10.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.
- package/README.md +1 -1
- package/dist/a2a/negotiate.d.ts +6 -2
- package/dist/a2a/negotiate.js +10 -3
- package/dist/a2a/negotiate.js.map +1 -1
- package/dist/a2a/node.d.ts +4 -1
- package/dist/a2a/node.js +56 -3
- package/dist/a2a/node.js.map +1 -1
- package/dist/a2a/server/merchant-handler.d.ts +11 -3
- package/dist/a2a/server/merchant-handler.js +84 -26
- package/dist/a2a/server/merchant-handler.js.map +1 -1
- package/dist/agent/buyer/buyer-tools.js +2 -2
- package/dist/agent/buyer/buyer-tools.js.map +1 -1
- package/dist/agent/kernel.js +5 -1
- package/dist/agent/kernel.js.map +1 -1
- package/dist/agent/memory/schema.d.ts +1 -1
- package/dist/agent/memory/schema.js +9 -1
- package/dist/agent/memory/schema.js.map +1 -1
- package/dist/agent/merchant/action-candidate.d.ts +18 -0
- package/dist/agent/merchant/action-candidate.js +51 -0
- package/dist/agent/merchant/action-candidate.js.map +1 -1
- package/dist/agent/merchant/fake-merchant-client.js +6 -1
- package/dist/agent/merchant/fake-merchant-client.js.map +1 -1
- package/dist/agent/merchant/intelligence/default-backend.js +25 -2
- package/dist/agent/merchant/intelligence/default-backend.js.map +1 -1
- package/dist/agent/merchant/merchant-client.d.ts +50 -1
- package/dist/agent/merchant/merchant-client.js +157 -8
- package/dist/agent/merchant/merchant-client.js.map +1 -1
- package/dist/agent/merchant/merchant-presentations.js +25 -2
- package/dist/agent/merchant/merchant-presentations.js.map +1 -1
- package/dist/agent/merchant/merchant-tools.js +102 -188
- package/dist/agent/merchant/merchant-tools.js.map +1 -1
- package/dist/agent/merchant/types.d.ts +6 -2
- package/dist/agent/merchant/types.js +45 -0
- package/dist/agent/merchant/types.js.map +1 -1
- package/dist/auth/merchant-authorization.d.ts +49 -0
- package/dist/auth/merchant-authorization.js +61 -0
- package/dist/auth/merchant-authorization.js.map +1 -0
- package/dist/auth/merchant-oauth.d.ts +255 -0
- package/dist/auth/merchant-oauth.js +764 -0
- package/dist/auth/merchant-oauth.js.map +1 -0
- package/dist/auth/merchant-pairing.d.ts +62 -0
- package/dist/auth/merchant-pairing.js +199 -0
- package/dist/auth/merchant-pairing.js.map +1 -0
- package/dist/auth/merchant-sessions.d.ts +71 -0
- package/dist/auth/merchant-sessions.js +168 -0
- package/dist/auth/merchant-sessions.js.map +1 -0
- package/dist/buyer-core/build-service.d.ts +5 -0
- package/dist/buyer-core/build-service.js +12 -0
- package/dist/buyer-core/build-service.js.map +1 -1
- package/dist/buyer-core/errors.d.ts +1 -1
- package/dist/buyer-core/errors.js +2 -0
- package/dist/buyer-core/errors.js.map +1 -1
- package/dist/buyer-core/merchant-index.d.ts +19 -4
- package/dist/buyer-core/merchant-index.js +137 -16
- package/dist/buyer-core/merchant-index.js.map +1 -1
- package/dist/buyer-core/negotiator.d.ts +0 -10
- package/dist/buyer-core/negotiator.js +12 -1
- package/dist/buyer-core/negotiator.js.map +1 -1
- package/dist/buyer-core/quote-fetcher.js +2 -1
- package/dist/buyer-core/quote-fetcher.js.map +1 -1
- package/dist/buyer-core/service.d.ts +104 -0
- package/dist/buyer-core/service.js +105 -1
- package/dist/buyer-core/service.js.map +1 -1
- package/dist/cli.d.ts +4 -2
- package/dist/cli.js +612 -20
- package/dist/cli.js.map +1 -1
- package/dist/config/profile.d.ts +30 -0
- package/dist/config/profile.js +126 -61
- package/dist/config/profile.js.map +1 -1
- package/dist/demo/demo-runner.js +12 -9
- package/dist/demo/demo-runner.js.map +1 -1
- package/dist/discovery/catalog-source/buyer-follows.d.ts +82 -0
- package/dist/discovery/catalog-source/buyer-follows.js +228 -0
- package/dist/discovery/catalog-source/buyer-follows.js.map +1 -0
- package/dist/discovery/catalog-source/connector-identity.d.ts +75 -0
- package/dist/discovery/catalog-source/connector-identity.js +175 -0
- package/dist/discovery/catalog-source/connector-identity.js.map +1 -0
- package/dist/discovery/catalog-source/errors.d.ts +1 -1
- package/dist/discovery/catalog-source/errors.js +2 -0
- package/dist/discovery/catalog-source/errors.js.map +1 -1
- package/dist/discovery/catalog-source/merchant-publications.d.ts +65 -0
- package/dist/discovery/catalog-source/merchant-publications.js +207 -0
- package/dist/discovery/catalog-source/merchant-publications.js.map +1 -0
- package/dist/discovery/catalog-source/register.d.ts +24 -0
- package/dist/discovery/catalog-source/register.js +46 -0
- package/dist/discovery/catalog-source/register.js.map +1 -1
- package/dist/discovery/catalog-source/source.js +2 -1
- package/dist/discovery/catalog-source/source.js.map +1 -1
- package/dist/fs/atomic-write.d.ts +18 -0
- package/dist/fs/atomic-write.js +29 -0
- package/dist/fs/atomic-write.js.map +1 -0
- package/dist/http/server.js +4 -1
- package/dist/http/server.js.map +1 -1
- package/dist/mcp/cli.d.ts +2 -0
- package/dist/mcp/cli.js +7 -6
- package/dist/mcp/cli.js.map +1 -1
- package/dist/mcp/merchant-auth.d.ts +78 -0
- package/dist/mcp/merchant-auth.js +146 -0
- package/dist/mcp/merchant-auth.js.map +1 -0
- package/dist/mcp/merchant-dirs.d.ts +26 -0
- package/dist/mcp/merchant-dirs.js +44 -0
- package/dist/mcp/merchant-dirs.js.map +1 -0
- package/dist/mcp/merchant-resources.d.ts +38 -0
- package/dist/mcp/merchant-resources.js +146 -0
- package/dist/mcp/merchant-resources.js.map +1 -0
- package/dist/mcp/merchant-server.d.ts +106 -0
- package/dist/mcp/merchant-server.js +615 -0
- package/dist/mcp/merchant-server.js.map +1 -0
- package/dist/mcp/merchant-tools.d.ts +103 -0
- package/dist/mcp/merchant-tools.js +517 -0
- package/dist/mcp/merchant-tools.js.map +1 -0
- package/dist/mcp/server.js +4 -3
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +5 -3
- package/dist/mcp/tools.js +102 -5
- package/dist/mcp/tools.js.map +1 -1
- package/dist/mcp/types.d.ts +1 -1
- package/dist/mcp/types.js +4 -0
- package/dist/mcp/types.js.map +1 -1
- package/dist/merchant/ops.d.ts +0 -11
- package/dist/merchant/ops.js +13 -1
- package/dist/merchant/ops.js.map +1 -1
- package/dist/merchant/workbench-service.d.ts +189 -0
- package/dist/merchant/workbench-service.js +417 -0
- package/dist/merchant/workbench-service.js.map +1 -0
- package/dist/merchant-admin/pending-page.d.ts +35 -0
- package/dist/merchant-admin/pending-page.js +69 -0
- package/dist/merchant-admin/pending-page.js.map +1 -0
- package/dist/merchant-core/commands.d.ts +99 -0
- package/dist/merchant-core/commands.js +179 -0
- package/dist/merchant-core/commands.js.map +1 -0
- package/dist/merchant-core/executor.d.ts +69 -0
- package/dist/merchant-core/executor.js +218 -0
- package/dist/merchant-core/executor.js.map +1 -0
- package/dist/merchant-core/negotiation-adapters.d.ts +55 -0
- package/dist/merchant-core/negotiation-adapters.js +55 -0
- package/dist/merchant-core/negotiation-adapters.js.map +1 -0
- package/dist/merchant-core/network-checks.d.ts +65 -0
- package/dist/merchant-core/network-checks.js +111 -0
- package/dist/merchant-core/network-checks.js.map +1 -0
- package/dist/merchant-core/operations.d.ts +64 -0
- package/dist/merchant-core/operations.js +136 -0
- package/dist/merchant-core/operations.js.map +1 -0
- package/dist/merchant-core/policy-runtime.d.ts +70 -0
- package/dist/merchant-core/policy-runtime.js +181 -0
- package/dist/merchant-core/policy-runtime.js.map +1 -0
- package/dist/merchant-core/product-import.d.ts +67 -0
- package/dist/merchant-core/product-import.js +160 -0
- package/dist/merchant-core/product-import.js.map +1 -0
- package/dist/merchant-core/service.d.ts +203 -0
- package/dist/merchant-core/service.js +402 -0
- package/dist/merchant-core/service.js.map +1 -0
- package/dist/merchant-gateway/catalog-publications.d.ts +96 -0
- package/dist/merchant-gateway/catalog-publications.js +212 -0
- package/dist/merchant-gateway/catalog-publications.js.map +1 -0
- package/dist/merchant-gateway/catalog-tools.d.ts +46 -0
- package/dist/merchant-gateway/catalog-tools.js +315 -0
- package/dist/merchant-gateway/catalog-tools.js.map +1 -0
- package/dist/merchant-gateway/cli.d.ts +75 -0
- package/dist/merchant-gateway/cli.js +461 -0
- package/dist/merchant-gateway/cli.js.map +1 -0
- package/dist/merchant-gateway/credential-vault.d.ts +44 -0
- package/dist/merchant-gateway/credential-vault.js +111 -0
- package/dist/merchant-gateway/credential-vault.js.map +1 -0
- package/dist/merchant-gateway/entry-server.d.ts +117 -0
- package/dist/merchant-gateway/entry-server.js +747 -0
- package/dist/merchant-gateway/entry-server.js.map +1 -0
- package/dist/merchant-gateway/instance-registration.d.ts +144 -0
- package/dist/merchant-gateway/instance-registration.js +391 -0
- package/dist/merchant-gateway/instance-registration.js.map +1 -0
- package/dist/merchant-gateway/instance-tools.d.ts +58 -0
- package/dist/merchant-gateway/instance-tools.js +186 -0
- package/dist/merchant-gateway/instance-tools.js.map +1 -0
- package/dist/merchant-gateway/mcp-proxy.d.ts +25 -0
- package/dist/merchant-gateway/mcp-proxy.js +192 -0
- package/dist/merchant-gateway/mcp-proxy.js.map +1 -0
- package/dist/merchant-gateway/pinned-fetch.d.ts +54 -0
- package/dist/merchant-gateway/pinned-fetch.js +231 -0
- package/dist/merchant-gateway/pinned-fetch.js.map +1 -0
- package/dist/merchant-gateway/tenant-registry.d.ts +82 -0
- package/dist/merchant-gateway/tenant-registry.js +190 -0
- package/dist/merchant-gateway/tenant-registry.js.map +1 -0
- package/dist/merchant-gateway/tool-bundle.d.ts +26 -0
- package/dist/merchant-gateway/tool-bundle.js +56 -0
- package/dist/merchant-gateway/tool-bundle.js.map +1 -0
- package/dist/merchant-runtime/backup.d.ts +48 -0
- package/dist/merchant-runtime/backup.js +226 -0
- package/dist/merchant-runtime/backup.js.map +1 -0
- package/dist/merchant-runtime/health.d.ts +99 -0
- package/dist/merchant-runtime/health.js +206 -0
- package/dist/merchant-runtime/health.js.map +1 -0
- package/dist/merchant-runtime/jobs.d.ts +64 -0
- package/dist/merchant-runtime/jobs.js +107 -0
- package/dist/merchant-runtime/jobs.js.map +1 -0
- package/dist/merchant-runtime/manager.d.ts +94 -0
- package/dist/merchant-runtime/manager.js +305 -0
- package/dist/merchant-runtime/manager.js.map +1 -0
- package/dist/merchant-runtime/services.d.ts +30 -0
- package/dist/merchant-runtime/services.js +51 -0
- package/dist/merchant-runtime/services.js.map +1 -0
- package/dist/net/url.d.ts +26 -0
- package/dist/net/url.js +32 -0
- package/dist/net/url.js.map +1 -0
- package/dist/product-cli.js +22 -3
- package/dist/product-cli.js.map +1 -1
- package/dist/product-compat.d.ts +9 -1
- package/dist/product-compat.js +12 -1
- package/dist/product-compat.js.map +1 -1
- package/dist/product-init.js +17 -5
- package/dist/product-init.js.map +1 -1
- package/dist/product-publish.js +2 -1
- package/dist/product-publish.js.map +1 -1
- package/package.json +3 -2
- package/skills/kiwi-buyer/SKILL.md +2 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 商家连接器入口 → kiwi-catalog 商家公开资料客户端(写侧,凭据为 `cmt_…`)。
|
|
18
|
+
*
|
|
19
|
+
* POST {base}/v1/merchant-publications (action=draft|publish)
|
|
20
|
+
* GET {base}/v1/merchant-publications/{id}
|
|
21
|
+
* POST {base}/v1/merchant-publications/{id}/withdraw
|
|
22
|
+
*
|
|
23
|
+
* 契约来源:kiwi-catalog 仓 kiwi_catalog/services/merchant_publications.py 的
|
|
24
|
+
* validate_payload / public_projection(schema v29+,M0 工作包 A)。
|
|
25
|
+
*
|
|
26
|
+
* 硬边界:
|
|
27
|
+
* - merchant_id 由目录按凭据绑定决定,**客户端永远不传**;
|
|
28
|
+
* - 本客户端只把 `action=draft` 用于常规保存;`publish` 只应由商家在门户
|
|
29
|
+
* 确认页触发(入口不替商家确认,见第 1 版设计 §3.3 / §4 执行控制);
|
|
30
|
+
* - 出站加固与既有 catalog 客户端一致:不跟随重定向、超时、响应字段校验。
|
|
31
|
+
*/
|
|
32
|
+
import { PRODUCT_VERSION } from "../product-cli.js";
|
|
33
|
+
import { isRedirectResponse, readJsonBody } from "../net/safe-http.js";
|
|
34
|
+
import { CatalogSourceError } from "../discovery/catalog-source/errors.js";
|
|
35
|
+
import { validateBaseUrl } from "../discovery/catalog-source/source.js";
|
|
36
|
+
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
37
|
+
function asRecord(value, field) {
|
|
38
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
39
|
+
throw new CatalogSourceError("response_invalid", `merchant-publications response is missing object field "${field}"`);
|
|
40
|
+
}
|
|
41
|
+
return value;
|
|
42
|
+
}
|
|
43
|
+
function asString(record, field) {
|
|
44
|
+
return typeof record[field] === "string" ? record[field] : "";
|
|
45
|
+
}
|
|
46
|
+
function toPublication(value) {
|
|
47
|
+
const record = asRecord(value, "publication");
|
|
48
|
+
const faq = Array.isArray(record.faq)
|
|
49
|
+
? record.faq.map((item) => {
|
|
50
|
+
const entry = asRecord(item, "publication.faq[]");
|
|
51
|
+
return { question: asString(entry, "question"), answer: asString(entry, "answer") };
|
|
52
|
+
})
|
|
53
|
+
: [];
|
|
54
|
+
const publicationId = asString(record, "publication_id");
|
|
55
|
+
const merchantId = asString(record, "merchant_id");
|
|
56
|
+
if (publicationId === "" || merchantId === "") {
|
|
57
|
+
throw new CatalogSourceError("response_invalid", "merchant-publications response is missing publication_id or merchant_id");
|
|
58
|
+
}
|
|
59
|
+
if (record.inquiry_available !== false) {
|
|
60
|
+
// 第 0 版公开资料恒不可实时询价;为 true 视为协议级违规(不得向上传播)。
|
|
61
|
+
throw new CatalogSourceError("contract_violation", "merchant-publications projected inquiry_available must be false");
|
|
62
|
+
}
|
|
63
|
+
return {
|
|
64
|
+
publication_id: publicationId,
|
|
65
|
+
merchant_id: merchantId,
|
|
66
|
+
merchant_display_name: asString(record, "merchant_display_name"),
|
|
67
|
+
title: asString(record, "title"),
|
|
68
|
+
category: asString(record, "category"),
|
|
69
|
+
summary: asString(record, "summary"),
|
|
70
|
+
shop_platform: asString(record, "shop_platform"),
|
|
71
|
+
shop_url: asString(record, "shop_url"),
|
|
72
|
+
faq,
|
|
73
|
+
source_kind: asString(record, "source_kind"),
|
|
74
|
+
status: asString(record, "status"),
|
|
75
|
+
version: typeof record.version === "number" ? record.version : 0,
|
|
76
|
+
published_at: asString(record, "published_at"),
|
|
77
|
+
expires_at: asString(record, "expires_at"),
|
|
78
|
+
updated_at: asString(record, "updated_at"),
|
|
79
|
+
inquiry_available: false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
export class MerchantPublicationClient {
|
|
83
|
+
baseUrl;
|
|
84
|
+
deps;
|
|
85
|
+
constructor(deps) {
|
|
86
|
+
this.baseUrl = validateBaseUrl(deps.baseUrl);
|
|
87
|
+
this.deps = deps;
|
|
88
|
+
}
|
|
89
|
+
/** 保存草稿(action=draft;发布不由入口执行)。 */
|
|
90
|
+
async saveDraft(token, input) {
|
|
91
|
+
const body = await this.request(token, "POST", "/v1/merchant-publications", {
|
|
92
|
+
action: "draft",
|
|
93
|
+
merchant_display_name: input.merchantDisplayName,
|
|
94
|
+
title: input.title,
|
|
95
|
+
...(input.category !== undefined ? { category: input.category } : {}),
|
|
96
|
+
...(input.summary !== undefined ? { summary: input.summary } : {}),
|
|
97
|
+
...(input.shopPlatform !== undefined ? { shop_platform: input.shopPlatform } : {}),
|
|
98
|
+
...(input.shopUrl !== undefined ? { shop_url: input.shopUrl } : {}),
|
|
99
|
+
...(input.faq !== undefined ? { faq: input.faq } : {}),
|
|
100
|
+
...(input.expiresAt !== undefined ? { expires_at: input.expiresAt } : {}),
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
publication: toPublication(body.publication),
|
|
104
|
+
created: body.created === true,
|
|
105
|
+
idempotent: body.idempotent === true,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
async getPublication(token, publicationId) {
|
|
109
|
+
const body = await this.request(token, "GET", `/v1/merchant-publications/${encodeURIComponent(publicationId)}`);
|
|
110
|
+
return toPublication(body.publication);
|
|
111
|
+
}
|
|
112
|
+
async withdraw(token, publicationId) {
|
|
113
|
+
const body = await this.request(token, "POST", `/v1/merchant-publications/${encodeURIComponent(publicationId)}/withdraw`, {});
|
|
114
|
+
return toPublication(body.publication);
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* 商家本人的匿名经营汇总(只读):关注者总数 + 公开资料浏览量明细。
|
|
118
|
+
*
|
|
119
|
+
* 目录侧该接口的设计是**只回聚合数字**——不返回买家身份、不返回关注列表、也
|
|
120
|
+
* 不提供向关注者发消息的通道(kiwi-catalog `publication_stats` 的契约)。
|
|
121
|
+
* 本方法只透出聚合数与资料本身的可公开字段,响应里的其它内容不进入返回值,
|
|
122
|
+
* 也就不会进模型上下文。
|
|
123
|
+
*/
|
|
124
|
+
async fetchStats(token) {
|
|
125
|
+
const body = await this.request(token, "GET", "/v1/merchant-publications/stats");
|
|
126
|
+
const stats = asRecord(body.stats, "stats");
|
|
127
|
+
const followersTotal = stats.followers_total;
|
|
128
|
+
const viewsTotal = stats.views_total;
|
|
129
|
+
if (typeof followersTotal !== "number" || !Number.isFinite(followersTotal) || followersTotal < 0) {
|
|
130
|
+
throw new CatalogSourceError("response_invalid", "merchant-publications stats response is missing a non-negative numeric followers_total");
|
|
131
|
+
}
|
|
132
|
+
if (typeof viewsTotal !== "number" || !Number.isFinite(viewsTotal) || viewsTotal < 0) {
|
|
133
|
+
throw new CatalogSourceError("response_invalid", "merchant-publications stats response is missing a non-negative numeric views_total");
|
|
134
|
+
}
|
|
135
|
+
const rawPublications = stats.publications;
|
|
136
|
+
const publications = [];
|
|
137
|
+
if (Array.isArray(rawPublications)) {
|
|
138
|
+
for (const item of rawPublications) {
|
|
139
|
+
const record = asRecord(item, "stats.publications[]");
|
|
140
|
+
publications.push({
|
|
141
|
+
publicationId: asString(record, "publication_id"),
|
|
142
|
+
title: asString(record, "title"),
|
|
143
|
+
status: asString(record, "status"),
|
|
144
|
+
viewCount: typeof record.view_count === "number" && Number.isFinite(record.view_count)
|
|
145
|
+
? record.view_count
|
|
146
|
+
: 0,
|
|
147
|
+
publishedAt: asString(record, "published_at"),
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return { followersTotal, viewsTotal, publications };
|
|
152
|
+
}
|
|
153
|
+
async request(token, method, path, body) {
|
|
154
|
+
if (typeof token !== "string" || token.trim() === "") {
|
|
155
|
+
throw new CatalogSourceError("invalid_input", "merchant publication request requires a merchant credential");
|
|
156
|
+
}
|
|
157
|
+
const fetchImpl = this.deps.fetchImpl ?? globalThis.fetch;
|
|
158
|
+
const timeoutMs = this.deps.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
159
|
+
const url = `${this.baseUrl}${path}`;
|
|
160
|
+
const controller = new AbortController();
|
|
161
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
162
|
+
let response;
|
|
163
|
+
let raw;
|
|
164
|
+
try {
|
|
165
|
+
try {
|
|
166
|
+
response = await fetchImpl(url, {
|
|
167
|
+
method,
|
|
168
|
+
redirect: "manual",
|
|
169
|
+
signal: controller.signal,
|
|
170
|
+
headers: {
|
|
171
|
+
accept: "application/json",
|
|
172
|
+
...(body !== undefined ? { "content-type": "application/json" } : {}),
|
|
173
|
+
authorization: `Bearer ${token}`,
|
|
174
|
+
"user-agent": `kiwi-merchant-entry/${PRODUCT_VERSION}`,
|
|
175
|
+
},
|
|
176
|
+
...(body !== undefined ? { body: JSON.stringify(body) } : {}),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
catch (err) {
|
|
180
|
+
const name = err?.name;
|
|
181
|
+
const detail = err instanceof Error ? err.message : String(err);
|
|
182
|
+
throw new CatalogSourceError("request_failed", name === "AbortError"
|
|
183
|
+
? `kiwi-catalog merchant request timed out after ${timeoutMs}ms: ${url}`
|
|
184
|
+
: `kiwi-catalog merchant request failed: ${url} (${detail})`);
|
|
185
|
+
}
|
|
186
|
+
if (isRedirectResponse(response)) {
|
|
187
|
+
throw new CatalogSourceError("request_failed", `kiwi-catalog merchant request must not follow redirects (HTTP ${response.status} from ${url})`);
|
|
188
|
+
}
|
|
189
|
+
if (response.status === 401 || response.status === 403) {
|
|
190
|
+
throw new CatalogSourceError("session_rejected", `kiwi-catalog rejected the merchant credential (HTTP ${response.status} from ${url})`);
|
|
191
|
+
}
|
|
192
|
+
if (!response.ok) {
|
|
193
|
+
throw new CatalogSourceError("request_failed", `kiwi-catalog merchant request returned HTTP ${response.status} from ${url}`);
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
raw = await readJsonBody(response, { signal: controller.signal });
|
|
197
|
+
}
|
|
198
|
+
catch {
|
|
199
|
+
throw new CatalogSourceError("response_invalid", `kiwi-catalog merchant response from ${url} is not valid JSON`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
finally {
|
|
203
|
+
clearTimeout(timer);
|
|
204
|
+
}
|
|
205
|
+
const envelope = asRecord(raw, "envelope");
|
|
206
|
+
if (envelope.ok !== true) {
|
|
207
|
+
throw new CatalogSourceError("response_invalid", `merchant-publications response is not ok: ${typeof envelope.error === "string" ? envelope.error : "unknown error"}`);
|
|
208
|
+
}
|
|
209
|
+
return envelope;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
//# sourceMappingURL=catalog-publications.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-publications.js","sourceRoot":"","sources":["../../src/merchant-gateway/catalog-publications.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* 商家连接器第 0 版目录工具(`kiwi_catalog_*`)。
|
|
18
|
+
*
|
|
19
|
+
* merchant-buddy 第 1 版设计 §3.3 / §4 执行控制与商家连接器发布计划 §3.2:
|
|
20
|
+
* - 商家身份来自**已验证的 OAuth 主体**(`merchantId` 由入口从访问令牌解析,
|
|
21
|
+
* 绝不来自工具参数);目录凭据按该 merchant_id 从保管库取;
|
|
22
|
+
* - 草稿是私有状态;`request_publish` **不写入 published**,只保存草稿并给出
|
|
23
|
+
* 目录门户的确认入口——发布必须由商家本人在门户确认页批准;
|
|
24
|
+
* - 无凭据/凭据失效时工具明确报「需要重新连接」,不返回过期数据。
|
|
25
|
+
*/
|
|
26
|
+
import type { ScopedMcpTools } from "../mcp/merchant-server.js";
|
|
27
|
+
import type { MerchantPublicationClient } from "./catalog-publications.js";
|
|
28
|
+
import type { MerchantCredentialStore } from "./credential-vault.js";
|
|
29
|
+
/** 工具所需 scope(读/写两类;与目录凭据 scope 同名)。 */
|
|
30
|
+
export declare function catalogToolScope(name: string): "catalog:read" | "catalog:write";
|
|
31
|
+
export interface CatalogToolDeps {
|
|
32
|
+
client: MerchantPublicationClient;
|
|
33
|
+
credentials: MerchantCredentialStore;
|
|
34
|
+
/** 目录门户地址(发布确认入口)。 */
|
|
35
|
+
portalBaseUrl: string;
|
|
36
|
+
toolOptions?: {
|
|
37
|
+
maxChars?: number;
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* 构建绑定到某个已验证商家的目录工具束。
|
|
42
|
+
*
|
|
43
|
+
* `merchantId` 必须来自 OAuth 访问令牌(入口解析),不能来自工具入参——
|
|
44
|
+
* 这是第 0 版商家之间隔离的唯一依据。
|
|
45
|
+
*/
|
|
46
|
+
export declare function buildCatalogTools(merchantId: string, deps: CatalogToolDeps): ScopedMcpTools;
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright 2026 harrylabsj
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
import { CatalogSourceError } from "../discovery/catalog-source/errors.js";
|
|
17
|
+
import { trimTrailingSlashes } from "../net/url.js";
|
|
18
|
+
const READ_TOOLS = new Set([
|
|
19
|
+
"kiwi_catalog_get_merchant_profile",
|
|
20
|
+
"kiwi_catalog_get_merchant_stats",
|
|
21
|
+
"kiwi_catalog_get_publication",
|
|
22
|
+
]);
|
|
23
|
+
const WRITE_TOOLS = new Set([
|
|
24
|
+
"kiwi_catalog_save_publication_draft",
|
|
25
|
+
"kiwi_catalog_request_publish",
|
|
26
|
+
"kiwi_catalog_withdraw_publication",
|
|
27
|
+
]);
|
|
28
|
+
/** 工具所需 scope(读/写两类;与目录凭据 scope 同名)。 */
|
|
29
|
+
export function catalogToolScope(name) {
|
|
30
|
+
return WRITE_TOOLS.has(name) ? "catalog:write" : "catalog:read";
|
|
31
|
+
}
|
|
32
|
+
const DISPLAY_NAME_PARAM = { type: "string", description: "公开商家名称(买家可见)" };
|
|
33
|
+
const TITLE_PARAM = { type: "string", description: "商品名(买家通过它搜索到你)" };
|
|
34
|
+
const PUBLICATION_INPUT_SCHEMA = {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
merchant_display_name: DISPLAY_NAME_PARAM,
|
|
38
|
+
title: TITLE_PARAM,
|
|
39
|
+
category: { type: "string", description: "类目(选填)" },
|
|
40
|
+
summary: { type: "string", description: "公开简介(选填,买家可见)" },
|
|
41
|
+
shop_platform: { type: "string", description: "店铺平台(选填,如 淘宝/京东)" },
|
|
42
|
+
shop_url: { type: "string", description: "公开店铺链接(选填,http/https)" },
|
|
43
|
+
faq: {
|
|
44
|
+
type: "array",
|
|
45
|
+
description: "公开 FAQ(选填;每项 question/answer,不得含电话或邮箱)",
|
|
46
|
+
items: {
|
|
47
|
+
type: "object",
|
|
48
|
+
properties: {
|
|
49
|
+
question: { type: "string" },
|
|
50
|
+
answer: { type: "string" },
|
|
51
|
+
},
|
|
52
|
+
required: ["question", "answer"],
|
|
53
|
+
additionalProperties: false,
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
expires_at: {
|
|
57
|
+
type: "string",
|
|
58
|
+
description: "资料有效期(选填,ISO 时间;到期后不再出现在搜索中)",
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
required: ["merchant_display_name", "title"],
|
|
62
|
+
additionalProperties: false,
|
|
63
|
+
};
|
|
64
|
+
const PUBLICATION_ID_SCHEMA = {
|
|
65
|
+
type: "object",
|
|
66
|
+
properties: {
|
|
67
|
+
publication_id: { type: "string", description: "公开资料 id(发布回执中的 publication_id)" },
|
|
68
|
+
},
|
|
69
|
+
required: ["publication_id"],
|
|
70
|
+
additionalProperties: false,
|
|
71
|
+
};
|
|
72
|
+
const DEFAULT_MAX_CHARS = 8_000;
|
|
73
|
+
function ok(payload, maxChars) {
|
|
74
|
+
const text = JSON.stringify(payload);
|
|
75
|
+
return {
|
|
76
|
+
content: [
|
|
77
|
+
{
|
|
78
|
+
type: "text",
|
|
79
|
+
text: text.length > maxChars ? `${text.slice(0, maxChars)}…(结果已截断)` : text,
|
|
80
|
+
},
|
|
81
|
+
],
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
function fail(message) {
|
|
85
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
86
|
+
}
|
|
87
|
+
function readString(args, field) {
|
|
88
|
+
const value = args[field];
|
|
89
|
+
return typeof value === "string" ? value.trim() : "";
|
|
90
|
+
}
|
|
91
|
+
function readFaq(args) {
|
|
92
|
+
const raw = args.faq;
|
|
93
|
+
if (!Array.isArray(raw))
|
|
94
|
+
return [];
|
|
95
|
+
const items = [];
|
|
96
|
+
for (const element of raw) {
|
|
97
|
+
if (element === null || typeof element !== "object")
|
|
98
|
+
continue;
|
|
99
|
+
const question = readString(element, "question");
|
|
100
|
+
const answer = readString(element, "answer");
|
|
101
|
+
if (question !== "" && answer !== "")
|
|
102
|
+
items.push({ question, answer });
|
|
103
|
+
}
|
|
104
|
+
return items;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* 构建绑定到某个已验证商家的目录工具束。
|
|
108
|
+
*
|
|
109
|
+
* `merchantId` 必须来自 OAuth 访问令牌(入口解析),不能来自工具入参——
|
|
110
|
+
* 这是第 0 版商家之间隔离的唯一依据。
|
|
111
|
+
*/
|
|
112
|
+
export function buildCatalogTools(merchantId, deps) {
|
|
113
|
+
const maxChars = deps.toolOptions?.maxChars ?? DEFAULT_MAX_CHARS;
|
|
114
|
+
const portalUrl = `${trimTrailingSlashes(deps.portalBaseUrl)}/portal/publications`;
|
|
115
|
+
const credential = () => {
|
|
116
|
+
const stored = deps.credentials.get(merchantId);
|
|
117
|
+
if (stored === undefined) {
|
|
118
|
+
throw new CatalogSourceError("session_rejected", "目录凭据不可用(未连接或已过期):请重新连接「Kiwi 商家运营」,然后在 Buddy 中重试");
|
|
119
|
+
}
|
|
120
|
+
return stored.token;
|
|
121
|
+
};
|
|
122
|
+
const credentialExpiry = () => {
|
|
123
|
+
const stored = deps.credentials.get(merchantId);
|
|
124
|
+
return stored?.expiresAt ?? "";
|
|
125
|
+
};
|
|
126
|
+
const draftInput = (args) => {
|
|
127
|
+
const merchantDisplayName = readString(args, "merchant_display_name");
|
|
128
|
+
const title = readString(args, "title");
|
|
129
|
+
const category = readString(args, "category");
|
|
130
|
+
const summary = readString(args, "summary");
|
|
131
|
+
const shopPlatform = readString(args, "shop_platform");
|
|
132
|
+
const shopUrl = readString(args, "shop_url");
|
|
133
|
+
const expiresAt = readString(args, "expires_at");
|
|
134
|
+
const faq = readFaq(args);
|
|
135
|
+
return {
|
|
136
|
+
merchantDisplayName,
|
|
137
|
+
title,
|
|
138
|
+
...(category !== "" ? { category } : {}),
|
|
139
|
+
...(summary !== "" ? { summary } : {}),
|
|
140
|
+
...(shopPlatform !== "" ? { shopPlatform } : {}),
|
|
141
|
+
...(shopUrl !== "" ? { shopUrl } : {}),
|
|
142
|
+
...(faq.length > 0 ? { faq } : {}),
|
|
143
|
+
...(expiresAt !== "" ? { expiresAt } : {}),
|
|
144
|
+
};
|
|
145
|
+
};
|
|
146
|
+
const handlers = {
|
|
147
|
+
kiwi_catalog_get_merchant_profile: async () => {
|
|
148
|
+
const stored = deps.credentials.get(merchantId);
|
|
149
|
+
return ok({
|
|
150
|
+
merchant_id: merchantId,
|
|
151
|
+
connected: stored !== undefined,
|
|
152
|
+
credential_expires_at: credentialExpiry(),
|
|
153
|
+
portal_url: portalUrl,
|
|
154
|
+
note: stored === undefined
|
|
155
|
+
? "尚未连接或凭据已过期:请重新连接「Kiwi 商家运营」后再管理公开资料。"
|
|
156
|
+
: "公开资料为商家声明快照(买家看到「资料可查」,不可实时询价);发布须在目录门户确认页批准。",
|
|
157
|
+
}, maxChars);
|
|
158
|
+
},
|
|
159
|
+
kiwi_catalog_get_merchant_stats: async () => {
|
|
160
|
+
const stats = await deps.client.fetchStats(credential());
|
|
161
|
+
return ok({
|
|
162
|
+
merchant_id: merchantId,
|
|
163
|
+
followers_total: stats.followersTotal,
|
|
164
|
+
views_total: stats.viewsTotal,
|
|
165
|
+
publications: stats.publications.map((item) => ({
|
|
166
|
+
publication_id: item.publicationId,
|
|
167
|
+
title: item.title,
|
|
168
|
+
status: item.status,
|
|
169
|
+
view_count: item.viewCount,
|
|
170
|
+
published_at: item.publishedAt,
|
|
171
|
+
})),
|
|
172
|
+
note: "关注与浏览均为**匿名汇总**:目录只提供数字,不提供买家身份、名单或联系方式," +
|
|
173
|
+
"也没有向关注者群发消息的通道。浏览量统计的是公开资料被查看的次数。",
|
|
174
|
+
}, maxChars);
|
|
175
|
+
},
|
|
176
|
+
kiwi_catalog_save_publication_draft: async (args) => {
|
|
177
|
+
const input = draftInput(args);
|
|
178
|
+
if (input.merchantDisplayName === "" || input.title === "") {
|
|
179
|
+
return fail("缺少必填字段:merchant_display_name 与 title 都是必填");
|
|
180
|
+
}
|
|
181
|
+
const result = await deps.client.saveDraft(credential(), input);
|
|
182
|
+
return ok({
|
|
183
|
+
publication_id: result.publication.publication_id,
|
|
184
|
+
merchant_id: result.publication.merchant_id,
|
|
185
|
+
title: result.publication.title,
|
|
186
|
+
status: result.publication.status,
|
|
187
|
+
version: result.publication.version,
|
|
188
|
+
created: result.created,
|
|
189
|
+
updated: result.idempotent,
|
|
190
|
+
confirm_url: portalUrl,
|
|
191
|
+
note: "已保存为私有草稿(未公开,采购专家搜索不到)。发布需你在目录门户的公开资料页确认。",
|
|
192
|
+
}, maxChars);
|
|
193
|
+
},
|
|
194
|
+
kiwi_catalog_request_publish: async (args) => {
|
|
195
|
+
const input = draftInput(args);
|
|
196
|
+
if (input.merchantDisplayName === "" || input.title === "") {
|
|
197
|
+
return fail("缺少必填字段:merchant_display_name 与 title 都是必填");
|
|
198
|
+
}
|
|
199
|
+
const result = await deps.client.saveDraft(credential(), input);
|
|
200
|
+
return ok({
|
|
201
|
+
publication_id: result.publication.publication_id,
|
|
202
|
+
status: result.publication.status,
|
|
203
|
+
version: result.publication.version,
|
|
204
|
+
confirm_url: portalUrl,
|
|
205
|
+
note: "草稿已保存,但**尚未发布**:请在目录门户的公开资料页核对公开预览并点击确认发布。" +
|
|
206
|
+
"确认前采购专家搜索不到该商品。",
|
|
207
|
+
}, maxChars);
|
|
208
|
+
},
|
|
209
|
+
kiwi_catalog_get_publication: async (args) => {
|
|
210
|
+
const publicationId = readString(args, "publication_id");
|
|
211
|
+
if (publicationId === "")
|
|
212
|
+
return fail("缺少 publication_id");
|
|
213
|
+
const publication = await deps.client.getPublication(credential(), publicationId);
|
|
214
|
+
return ok({
|
|
215
|
+
publication_id: publication.publication_id,
|
|
216
|
+
merchant_id: publication.merchant_id,
|
|
217
|
+
title: publication.title,
|
|
218
|
+
status: publication.status,
|
|
219
|
+
version: publication.version,
|
|
220
|
+
published_at: publication.published_at,
|
|
221
|
+
updated_at: publication.updated_at,
|
|
222
|
+
expires_at: publication.expires_at,
|
|
223
|
+
inquiry_available: publication.inquiry_available,
|
|
224
|
+
// 当前可编辑内容:改写文案前先看原文,避免凭记忆重写(会丢字段或编造)。
|
|
225
|
+
content: {
|
|
226
|
+
merchant_display_name: publication.merchant_display_name,
|
|
227
|
+
title: publication.title,
|
|
228
|
+
category: publication.category,
|
|
229
|
+
summary: publication.summary,
|
|
230
|
+
shop_platform: publication.shop_platform,
|
|
231
|
+
shop_url: publication.shop_url,
|
|
232
|
+
faq: publication.faq.map((item) => ({ question: item.question, answer: item.answer })),
|
|
233
|
+
},
|
|
234
|
+
}, maxChars);
|
|
235
|
+
},
|
|
236
|
+
kiwi_catalog_withdraw_publication: async (args) => {
|
|
237
|
+
const publicationId = readString(args, "publication_id");
|
|
238
|
+
if (publicationId === "")
|
|
239
|
+
return fail("缺少 publication_id");
|
|
240
|
+
const publication = await deps.client.withdraw(credential(), publicationId);
|
|
241
|
+
return ok({
|
|
242
|
+
publication_id: publication.publication_id,
|
|
243
|
+
status: publication.status,
|
|
244
|
+
version: publication.version,
|
|
245
|
+
note: "已撤回:该资料不再出现在采购专家的正常搜索中。",
|
|
246
|
+
}, maxChars);
|
|
247
|
+
},
|
|
248
|
+
};
|
|
249
|
+
const tools = [
|
|
250
|
+
{
|
|
251
|
+
name: "kiwi_catalog_get_merchant_profile",
|
|
252
|
+
description: "读取当前已连接商家的目录身份与连接状态(只读)。返回 merchant_id、目录凭据是否可用,以及公开资料管理入口地址。",
|
|
253
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
name: "kiwi_catalog_get_merchant_stats",
|
|
257
|
+
description: "读取本商家在 Kiwi 目录的经营汇总(只读,匿名枚举):活跃关注者总数、公开资料总浏览量、" +
|
|
258
|
+
"以及每条公开资料的状态与浏览量。用于回答「有多少买家在关注我」「我的公开资料有没有人看」" +
|
|
259
|
+
"「哪条资料被看得多」。目录**只提供数字**:不提供关注者身份、名单或联系方式,也没有向" +
|
|
260
|
+
"关注者群发消息的通道——不要向商家承诺任何群发、触达或导出名单的能力。",
|
|
261
|
+
inputSchema: { type: "object", properties: {}, additionalProperties: false },
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
name: "kiwi_catalog_save_publication_draft",
|
|
265
|
+
description: "保存商家公开资料草稿(私有,不公开)。必填 merchant_display_name 与 title;类目/简介/店铺链接/FAQ/有效期选填。" +
|
|
266
|
+
"草稿不会出现在采购专家搜索结果中;公开前置请用 kiwi_catalog_request_publish。不得填写电话、邮箱等联系方式(会被目录拒绝)。",
|
|
267
|
+
inputSchema: PUBLICATION_INPUT_SCHEMA,
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
name: "kiwi_catalog_request_publish",
|
|
271
|
+
description: "准备发布公开资料:保存草稿并返回目录门户的确认入口。**本工具不会把资料变成已发布**——必须由商家本人在门户核对公开预览并确认发布后才生效。",
|
|
272
|
+
inputSchema: PUBLICATION_INPUT_SCHEMA,
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
name: "kiwi_catalog_get_publication",
|
|
276
|
+
description: "按 publication_id 读取一条公开资料的**当前内容**(商家名/商品名/类目/简介/店铺平台与链接/FAQ)" +
|
|
277
|
+
"与状态(draft/published/withdrawn)、版本、时间戳。改写文案前先用它看原文——不要凭记忆重写," +
|
|
278
|
+
"否则会丢字段或编造内容。第 0 版资料恒为不可实时询价(inquiry_available=false)。",
|
|
279
|
+
inputSchema: PUBLICATION_ID_SCHEMA,
|
|
280
|
+
},
|
|
281
|
+
{
|
|
282
|
+
name: "kiwi_catalog_withdraw_publication",
|
|
283
|
+
description: "撤回已发布的公开资料(终态):撤回后不再出现在采购专家搜索结果中。撤回不会删除账号或历史版本。",
|
|
284
|
+
inputSchema: PUBLICATION_ID_SCHEMA,
|
|
285
|
+
},
|
|
286
|
+
];
|
|
287
|
+
return {
|
|
288
|
+
listTools: (scopes) => tools.filter((tool) => {
|
|
289
|
+
if (scopes === undefined)
|
|
290
|
+
return true;
|
|
291
|
+
return scopes.includes(catalogToolScope(tool.name));
|
|
292
|
+
}),
|
|
293
|
+
call: async (name, args, scopes) => {
|
|
294
|
+
const handler = handlers[name];
|
|
295
|
+
if (handler === undefined) {
|
|
296
|
+
return fail(`未知工具:${name}`);
|
|
297
|
+
}
|
|
298
|
+
const required = catalogToolScope(name);
|
|
299
|
+
if (scopes !== undefined && !scopes.includes(required)) {
|
|
300
|
+
return fail(`scope 不足:${name} 需要 ${required},请重新连接并授予该权限`);
|
|
301
|
+
}
|
|
302
|
+
if (!READ_TOOLS.has(name) && !WRITE_TOOLS.has(name)) {
|
|
303
|
+
return fail(`工具未注册:${name}`);
|
|
304
|
+
}
|
|
305
|
+
try {
|
|
306
|
+
return await handler(args);
|
|
307
|
+
}
|
|
308
|
+
catch (err) {
|
|
309
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
310
|
+
return fail(`目录操作失败:${message}`);
|
|
311
|
+
}
|
|
312
|
+
},
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
//# sourceMappingURL=catalog-tools.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"catalog-tools.js","sourceRoot":"","sources":["../../src/merchant-gateway/catalog-tools.ts"],"names":[],"mappings":"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"}
|