@harrylabsj/kiwi 0.6.1 → 0.7.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 +28 -0
- package/contracts/candidate-agent-dto-1.0.README.md +12 -8
- package/contracts/conformance/python-service/README.md +19 -0
- package/contracts/conformance/python-service/run.py +134 -0
- package/contracts/kiwi-catalog/1.0/listing-record.schema.json +11 -1
- package/contracts/kiwi-contracts.lock.json +7 -0
- package/contracts/manifest.json +61 -0
- package/contracts/vectors/candidate-agent.invalid-private-field.json +7 -0
- package/contracts/vectors/candidate-agent.valid.json +26 -0
- package/dist/a2a/client/client.js +39 -34
- package/dist/a2a/client/client.js.map +1 -1
- package/dist/a2a/client/url-policy.d.ts +8 -1
- package/dist/a2a/client/url-policy.js +18 -2
- package/dist/a2a/client/url-policy.js.map +1 -1
- package/dist/a2a/clock.d.ts +30 -0
- package/dist/a2a/clock.js +39 -0
- package/dist/a2a/clock.js.map +1 -0
- package/dist/a2a/negotiate.d.ts +6 -0
- package/dist/a2a/negotiate.js +10 -12
- package/dist/a2a/negotiate.js.map +1 -1
- package/dist/a2a/node.d.ts +20 -2
- package/dist/a2a/node.js +165 -19
- package/dist/a2a/node.js.map +1 -1
- package/dist/a2a/server/auth.js +11 -2
- package/dist/a2a/server/auth.js.map +1 -1
- package/dist/a2a/server/merchant-handler.d.ts +4 -0
- package/dist/a2a/server/merchant-handler.js +283 -27
- package/dist/a2a/server/merchant-handler.js.map +1 -1
- package/dist/a2a/server/pipeline.d.ts +17 -0
- package/dist/a2a/server/pipeline.js +89 -1
- package/dist/a2a/server/pipeline.js.map +1 -1
- package/dist/a2a/server/ucp.d.ts +30 -2
- package/dist/a2a/server/ucp.js +23 -14
- package/dist/a2a/server/ucp.js.map +1 -1
- package/dist/agent/agent-db.js +5 -0
- package/dist/agent/agent-db.js.map +1 -1
- package/dist/agent/buyer/buyer-tools.d.ts +5 -0
- package/dist/agent/buyer/buyer-tools.js +75 -7
- package/dist/agent/buyer/buyer-tools.js.map +1 -1
- package/dist/agent/buyer/search-loop.d.ts +3 -0
- package/dist/agent/buyer/search-loop.js +129 -0
- package/dist/agent/buyer/search-loop.js.map +1 -1
- package/dist/agent/buyer/task-store.d.ts +2 -0
- package/dist/agent/buyer/task-store.js +11 -7
- package/dist/agent/buyer/task-store.js.map +1 -1
- package/dist/agent/kernel.d.ts +6 -0
- package/dist/agent/kernel.js +100 -10
- package/dist/agent/kernel.js.map +1 -1
- package/dist/agent/memory/schema.d.ts +1 -1
- package/dist/agent/memory/schema.js +7 -1
- package/dist/agent/memory/schema.js.map +1 -1
- package/dist/agent/memory/store.d.ts +5 -0
- package/dist/agent/memory/store.js +29 -1
- package/dist/agent/memory/store.js.map +1 -1
- package/dist/agent/merchant/action-candidate.js +15 -1
- package/dist/agent/merchant/action-candidate.js.map +1 -1
- package/dist/agent/merchant/merchant-client.js +22 -4
- package/dist/agent/merchant/merchant-client.js.map +1 -1
- package/dist/agent/merchant/types.d.ts +5 -2
- package/dist/agent/merchant/types.js +6 -2
- package/dist/agent/merchant/types.js.map +1 -1
- package/dist/agent/negotiation-chat.js +34 -14
- package/dist/agent/negotiation-chat.js.map +1 -1
- package/dist/cli.d.ts +56 -0
- package/dist/cli.js +51 -3
- package/dist/cli.js.map +1 -1
- package/dist/commerce/data-source.d.ts +3 -0
- package/dist/commerce/data-source.js.map +1 -1
- package/dist/commerce/http-client.js +35 -31
- package/dist/commerce/http-client.js.map +1 -1
- package/dist/commerce/shopping-cli-source.js +63 -46
- package/dist/commerce/shopping-cli-source.js.map +1 -1
- package/dist/counterparty/a2a-direct/index.d.ts +5 -0
- package/dist/counterparty/a2a-direct/index.js +24 -0
- package/dist/counterparty/a2a-direct/index.js.map +1 -1
- package/dist/counterparty/shopping-cli-hosted/index.js +52 -19
- package/dist/counterparty/shopping-cli-hosted/index.js.map +1 -1
- package/dist/discovery/catalog-source/kiwi-record.d.ts +2 -0
- package/dist/discovery/catalog-source/kiwi-record.js.map +1 -1
- package/dist/discovery/catalog-source/kiwi-source.js +39 -35
- package/dist/discovery/catalog-source/kiwi-source.js.map +1 -1
- package/dist/discovery/catalog-source/register.js +12 -1
- package/dist/discovery/catalog-source/register.js.map +1 -1
- package/dist/discovery/catalog-source/source.js +39 -35
- package/dist/discovery/catalog-source/source.js.map +1 -1
- package/dist/discovery/resolve.d.ts +15 -0
- package/dist/discovery/resolve.js +59 -35
- package/dist/discovery/resolve.js.map +1 -1
- package/dist/discovery/ucp/index.d.ts +1 -1
- package/dist/discovery/ucp/index.js +1 -1
- package/dist/discovery/ucp/index.js.map +1 -1
- package/dist/discovery/ucp/resolver.d.ts +5 -0
- package/dist/discovery/ucp/resolver.js +65 -38
- package/dist/discovery/ucp/resolver.js.map +1 -1
- package/dist/discovery/ucp/vendor.d.ts +1 -1
- package/dist/discovery/ucp/vendor.js +1 -1
- package/dist/handoff/delivery.d.ts +4 -2
- package/dist/handoff/delivery.js +6 -1
- package/dist/handoff/delivery.js.map +1 -1
- package/dist/handoff/index.d.ts +1 -1
- package/dist/handoff/index.js +1 -1
- package/dist/handoff/index.js.map +1 -1
- package/dist/handoff/ledger.d.ts +9 -0
- package/dist/handoff/ledger.js +66 -0
- package/dist/handoff/ledger.js.map +1 -1
- package/dist/handoff/transaction.d.ts +21 -3
- package/dist/handoff/transaction.js +37 -5
- package/dist/handoff/transaction.js.map +1 -1
- package/dist/handoff/ucp-checkout/channel.js +15 -10
- package/dist/handoff/ucp-checkout/channel.js.map +1 -1
- package/dist/negotiation/jcs.js +11 -8
- package/dist/negotiation/jcs.js.map +1 -1
- package/dist/negotiation/lease/store.d.ts +25 -0
- package/dist/negotiation/lease/store.js +101 -0
- package/dist/negotiation/lease/store.js.map +1 -0
- package/dist/negotiation/recovery/recover.js +25 -1
- package/dist/negotiation/recovery/recover.js.map +1 -1
- package/dist/operator/runner.d.ts +11 -0
- package/dist/operator/runner.js +20 -1
- package/dist/operator/runner.js.map +1 -1
- package/dist/product-catalog.d.ts +1 -1
- package/dist/product-catalog.js +3 -3
- package/dist/product-catalog.js.map +1 -1
- package/dist/product-cli.d.ts +1 -1
- package/dist/product-cli.js +1 -1
- package/dist/product-publish.d.ts +5 -0
- package/dist/product-publish.js +112 -7
- package/dist/product-publish.js.map +1 -1
- package/dist/supervisor/stack-config.d.ts +6 -1
- package/dist/supervisor/stack-config.js +11 -3
- package/dist/supervisor/stack-config.js.map +1 -1
- package/dist/trust/identity/message-signature.js +17 -0
- package/dist/trust/identity/message-signature.js.map +1 -1
- package/dist/weixin/channel.d.ts +2 -0
- package/dist/weixin/channel.js +17 -3
- package/dist/weixin/channel.js.map +1 -1
- package/dist/weixin/cli-weixin.js +2 -0
- package/dist/weixin/cli-weixin.js.map +1 -1
- package/dist/weixin/ilink-client.d.ts +1 -1
- package/dist/weixin/ilink-client.js +26 -1
- package/dist/weixin/ilink-client.js.map +1 -1
- package/dist/weixin/login.d.ts +3 -0
- package/dist/weixin/login.js +1 -1
- package/dist/weixin/login.js.map +1 -1
- package/package.json +9 -2
- package/dist/commerce/erp-source.d.ts +0 -51
- package/dist/commerce/erp-source.js +0 -184
- package/dist/commerce/erp-source.js.map +0 -1
- package/dist/commerce/local-db-source.d.ts +0 -50
- package/dist/commerce/local-db-source.js +0 -162
- package/dist/commerce/local-db-source.js.map +0 -1
|
@@ -103,6 +103,24 @@ export class IlinkClient {
|
|
|
103
103
|
if (redirectHost === "") {
|
|
104
104
|
throw new WeixinError("validation", "scaned_but_redirect 缺少 redirect_host");
|
|
105
105
|
}
|
|
106
|
+
// 审查 P3:redirect_host 是后续 bot_token 直送目标(经 base_info)——
|
|
107
|
+
// 此前零校验直接拼 https://${redirectHost}。至少校验是纯 hostname
|
|
108
|
+
// (无 scheme/path/port/userinfo),防 iLink 被攻破时把凭证流量导到
|
|
109
|
+
// 任意主机(协议内信任模型可接受,但语法边界必须 fail-closed)。
|
|
110
|
+
let parsed;
|
|
111
|
+
try {
|
|
112
|
+
parsed = new URL(`https://${redirectHost}`);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
throw new WeixinError("validation", `scaned_but_redirect 非法 redirect_host: ${redirectHost}`);
|
|
116
|
+
}
|
|
117
|
+
if (parsed.hostname !== redirectHost.toLowerCase() ||
|
|
118
|
+
parsed.pathname !== "/" ||
|
|
119
|
+
parsed.port !== "" ||
|
|
120
|
+
parsed.username !== "" ||
|
|
121
|
+
parsed.password !== "") {
|
|
122
|
+
throw new WeixinError("validation", `scaned_but_redirect redirect_host 必须是无 scheme/path/port 的纯 hostname`);
|
|
123
|
+
}
|
|
106
124
|
return { state: "scaned_but_redirect", baseUrl: `https://${redirectHost}` };
|
|
107
125
|
}
|
|
108
126
|
if (status === "wait" || status === "scaned" || status === "expired") {
|
|
@@ -111,13 +129,14 @@ export class IlinkClient {
|
|
|
111
129
|
throw new WeixinError("validation", `get_qrcode_status 未知状态 "${status}"`);
|
|
112
130
|
}
|
|
113
131
|
/** POST ilink/bot/getupdates(长轮询)→ 消息 + 新游标。 */
|
|
114
|
-
async getUpdates(syncBuf, credentials) {
|
|
132
|
+
async getUpdates(syncBuf, credentials, signal) {
|
|
115
133
|
const body = (await this.request("POST", EP_GET_UPDATES, {
|
|
116
134
|
timeoutMs: LONG_POLL_DEFAULT_MS + 20_000, // 长轮询需覆盖服务端 longpoll
|
|
117
135
|
payload: {
|
|
118
136
|
get_updates_buf: syncBuf,
|
|
119
137
|
base_info: baseInfoOf(credentials),
|
|
120
138
|
},
|
|
139
|
+
...(signal !== undefined ? { signal } : {}),
|
|
121
140
|
}));
|
|
122
141
|
assertOk(body, "getupdates");
|
|
123
142
|
const messages = [];
|
|
@@ -165,6 +184,11 @@ export class IlinkClient {
|
|
|
165
184
|
async request(method, path, options) {
|
|
166
185
|
const controller = new AbortController();
|
|
167
186
|
const timer = setTimeout(() => controller.abort(), options.timeoutMs);
|
|
187
|
+
// 审查 P2-M:外部 abort(通道 stop())转发到内部 controller——长轮询
|
|
188
|
+
// 在飞时 Ctrl+C 不再等满轮询超时(此前 pollAbort 声明后从未赋值,
|
|
189
|
+
// stop() 的 abort 是空操作,进程退出卡 ~55s)。
|
|
190
|
+
const onExternalAbort = () => controller.abort();
|
|
191
|
+
options.signal?.addEventListener("abort", onExternalAbort, { once: true });
|
|
168
192
|
try {
|
|
169
193
|
const headers = {
|
|
170
194
|
"iLink-App-Id": ILINK_APP_ID,
|
|
@@ -210,6 +234,7 @@ export class IlinkClient {
|
|
|
210
234
|
}
|
|
211
235
|
finally {
|
|
212
236
|
clearTimeout(timer);
|
|
237
|
+
options.signal?.removeEventListener("abort", onExternalAbort);
|
|
213
238
|
}
|
|
214
239
|
}
|
|
215
240
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ilink-client.js","sourceRoot":"","sources":["../../src/weixin/ilink-client.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"ilink-client.js","sourceRoot":"","sources":["../../src/weixin/ilink-client.ts"],"names":[],"mappings":"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"}
|
package/dist/weixin/login.d.ts
CHANGED
|
@@ -24,6 +24,9 @@ export interface LoginOptions {
|
|
|
24
24
|
qrPollMs?: number;
|
|
25
25
|
/** 过期刷新上限(缺省 DEFAULT_WEIXIN_TIMINGS.qrRefreshCap)。 */
|
|
26
26
|
qrRefreshCap?: number;
|
|
27
|
+
/** 二维码每模块列数(审查 P3:此前 CLI --qr-scale 传到这里就断了,
|
|
28
|
+
* renderQr 恒用默认 scale=1,文档承诺的 --qr-scale 2 静默无效)。 */
|
|
29
|
+
qrScale?: number;
|
|
27
30
|
/** 时间源(测试注入)。 */
|
|
28
31
|
now?: () => string;
|
|
29
32
|
}
|
package/dist/weixin/login.js
CHANGED
|
@@ -37,7 +37,7 @@ export async function loginWithQrcode(client, options = {}) {
|
|
|
37
37
|
let refreshCount = 0;
|
|
38
38
|
for (;;) {
|
|
39
39
|
const qrcode = await client.getBotQrcode();
|
|
40
|
-
render(renderQr(qrcode.qrcode_img_content));
|
|
40
|
+
render(renderQr(qrcode.qrcode_img_content, options.qrScale ?? 1));
|
|
41
41
|
notice("请使用微信扫一扫登录 kiwi 微信通道(8 分钟内有效,过期自动刷新)");
|
|
42
42
|
// 轮询状态直到 confirmed / expired(自动刷新)
|
|
43
43
|
const credentials = await pollUntilConfirmed(client, qrcode.qrcode, {
|
package/dist/weixin/login.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/weixin/login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AACnC,OAAO,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"login.js","sourceRoot":"","sources":["../../src/weixin/login.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@harrylabsj/kiwi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Kiwi: standalone A2A commerce negotiation agent runtime (Pi Agent Core + shopping-cli Commerce API)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -27,8 +27,11 @@
|
|
|
27
27
|
"format": "prettier --write .",
|
|
28
28
|
"format:check": "prettier --check .",
|
|
29
29
|
"test": "vitest run",
|
|
30
|
+
"verify:vectors": "node scripts/verify-contract-vectors.mjs",
|
|
31
|
+
"verify:contracts": "node scripts/verify-contracts.mjs",
|
|
30
32
|
"verify:package": "bash scripts/verify-package.sh",
|
|
31
|
-
"verify": "
|
|
33
|
+
"verify:portfolio-lock": "node scripts/verify-portfolio-lock-candidate.mjs",
|
|
34
|
+
"verify": "npm run lint && npm run typecheck && npm run build && npm run test && npm run verify:contracts && npm run verify:vectors && npm run verify:package",
|
|
32
35
|
"prepublishOnly": "npm run build"
|
|
33
36
|
},
|
|
34
37
|
"dependencies": {
|
|
@@ -54,5 +57,9 @@
|
|
|
54
57
|
},
|
|
55
58
|
"publishConfig": {
|
|
56
59
|
"access": "public"
|
|
60
|
+
},
|
|
61
|
+
"repository": {
|
|
62
|
+
"type": "git",
|
|
63
|
+
"url": "git+https://github.com/harrylabsj/kiwi.git"
|
|
57
64
|
}
|
|
58
65
|
}
|
|
@@ -1,51 +0,0 @@
|
|
|
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
|
-
* ErpCommerceDataSource —— HTTP ERP adapter(shopping-cli data hub
|
|
18
|
-
* v0.2.1 §3/#7「至少一种 ERP / external business data adapter」)。
|
|
19
|
-
*
|
|
20
|
-
* 上游代理语义(UPSTREAM_PROXY):字段权威在外部 ERP;Kiwi 只做
|
|
21
|
-
* 读取与超时/HTTP 失败映射(fail-closed,不静默容错)。任何非 2xx /
|
|
22
|
-
* 网络 / 超时 / 结构错误抛 CommerceError。
|
|
23
|
-
*/
|
|
24
|
-
import { type CommerceDataSource, type CommerceField, type ProductFact, type ProductSearchQuery } from "./data-source.js";
|
|
25
|
-
import type { CommerceHealth } from "./types.js";
|
|
26
|
-
export interface ErpCommerceDataSourceDeps {
|
|
27
|
-
/** ERP 服务根 URL(http/https,无 userinfo/query/fragment)。 */
|
|
28
|
-
baseUrl: string;
|
|
29
|
-
/** 可选的 bearer 凭证。 */
|
|
30
|
-
authToken?: string;
|
|
31
|
-
/** 拉取超时 ms(默认 15000)。 */
|
|
32
|
-
timeoutMs?: number;
|
|
33
|
-
/** 注入 fetch(测试)。 */
|
|
34
|
-
fetchImpl?: typeof fetch;
|
|
35
|
-
}
|
|
36
|
-
/** ERP 上游数据源(UPSTREAM_PROXY)。 */
|
|
37
|
-
export declare class ErpCommerceDataSource implements CommerceDataSource {
|
|
38
|
-
private readonly baseUrl;
|
|
39
|
-
private readonly deps;
|
|
40
|
-
constructor(deps: ErpCommerceDataSourceDeps);
|
|
41
|
-
private getJson;
|
|
42
|
-
getProduct(sku: string): Promise<ProductFact | undefined>;
|
|
43
|
-
getProducts(query?: ProductSearchQuery): Promise<ProductFact[]>;
|
|
44
|
-
getInventory(sku: string): Promise<CommerceField<number> | undefined>;
|
|
45
|
-
getPrice(sku: string): Promise<CommerceField<{
|
|
46
|
-
currency: string;
|
|
47
|
-
amount_minor: number;
|
|
48
|
-
}> | undefined>;
|
|
49
|
-
getPublicListing(): Promise<Record<string, unknown>>;
|
|
50
|
-
health(): Promise<CommerceHealth>;
|
|
51
|
-
}
|
|
@@ -1,184 +0,0 @@
|
|
|
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
|
-
* ErpCommerceDataSource —— HTTP ERP adapter(shopping-cli data hub
|
|
18
|
-
* v0.2.1 §3/#7「至少一种 ERP / external business data adapter」)。
|
|
19
|
-
*
|
|
20
|
-
* 上游代理语义(UPSTREAM_PROXY):字段权威在外部 ERP;Kiwi 只做
|
|
21
|
-
* 读取与超时/HTTP 失败映射(fail-closed,不静默容错)。任何非 2xx /
|
|
22
|
-
* 网络 / 超时 / 结构错误抛 CommerceError。
|
|
23
|
-
*/
|
|
24
|
-
import { CommerceError } from "./data-source.js";
|
|
25
|
-
const DEFAULT_TIMEOUT_MS = 15_000;
|
|
26
|
-
function validateBaseUrl(value) {
|
|
27
|
-
let url;
|
|
28
|
-
try {
|
|
29
|
-
url = new URL(value);
|
|
30
|
-
}
|
|
31
|
-
catch {
|
|
32
|
-
throw new CommerceError("invalid_input", `erp baseUrl is not a valid URL: "${value}"`);
|
|
33
|
-
}
|
|
34
|
-
if (url.protocol !== "https:" && url.protocol !== "http:") {
|
|
35
|
-
throw new CommerceError("invalid_input", `erp baseUrl must use http or https (got ${url.protocol})`);
|
|
36
|
-
}
|
|
37
|
-
if (url.username !== "" || url.password !== "") {
|
|
38
|
-
throw new CommerceError("invalid_input", "erp baseUrl must not embed credentials (userinfo)");
|
|
39
|
-
}
|
|
40
|
-
if (url.search !== "" || url.hash !== "") {
|
|
41
|
-
throw new CommerceError("invalid_input", "erp baseUrl must not contain query or fragment (paths are appended to it)");
|
|
42
|
-
}
|
|
43
|
-
return value.replace(/\/+$/, "");
|
|
44
|
-
}
|
|
45
|
-
function parseProduct(raw, path) {
|
|
46
|
-
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
47
|
-
throw new CommerceError("request_failed", `erp product at ${path} is not an object`);
|
|
48
|
-
}
|
|
49
|
-
const obj = raw;
|
|
50
|
-
const sku = obj.sku;
|
|
51
|
-
if (typeof sku !== "string" || sku.length === 0) {
|
|
52
|
-
throw new CommerceError("request_failed", `erp product at ${path} is missing sku`);
|
|
53
|
-
}
|
|
54
|
-
const fact = {
|
|
55
|
-
sku,
|
|
56
|
-
...(typeof obj.title === "string" && obj.title !== "" ? { title: obj.title } : {}),
|
|
57
|
-
...(typeof obj.price_minor === "number" && Number.isInteger(obj.price_minor)
|
|
58
|
-
? { price_minor: obj.price_minor }
|
|
59
|
-
: {}),
|
|
60
|
-
...(typeof obj.currency === "string" && obj.currency !== "" ? { currency: obj.currency } : {}),
|
|
61
|
-
...(typeof obj.stock === "number" && Number.isInteger(obj.stock) ? { stock: obj.stock } : {}),
|
|
62
|
-
...(typeof obj.delivery_lead_days === "number" && Number.isInteger(obj.delivery_lead_days)
|
|
63
|
-
? { delivery_lead_days: obj.delivery_lead_days }
|
|
64
|
-
: {}),
|
|
65
|
-
};
|
|
66
|
-
return fact;
|
|
67
|
-
}
|
|
68
|
-
/** ERP 上游数据源(UPSTREAM_PROXY)。 */
|
|
69
|
-
export class ErpCommerceDataSource {
|
|
70
|
-
baseUrl;
|
|
71
|
-
deps;
|
|
72
|
-
constructor(deps) {
|
|
73
|
-
this.baseUrl = validateBaseUrl(deps.baseUrl);
|
|
74
|
-
this.deps = deps;
|
|
75
|
-
}
|
|
76
|
-
async getJson(requestPath) {
|
|
77
|
-
const fetchImpl = this.deps.fetchImpl ?? globalThis.fetch;
|
|
78
|
-
const timeoutMs = this.deps.timeoutMs ?? DEFAULT_TIMEOUT_MS;
|
|
79
|
-
const url = `${this.baseUrl}${requestPath}`;
|
|
80
|
-
const controller = new AbortController();
|
|
81
|
-
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
82
|
-
let response;
|
|
83
|
-
try {
|
|
84
|
-
response = await fetchImpl(url, {
|
|
85
|
-
signal: controller.signal,
|
|
86
|
-
headers: {
|
|
87
|
-
accept: "application/json",
|
|
88
|
-
...(this.deps.authToken !== undefined
|
|
89
|
-
? { authorization: `Bearer ${this.deps.authToken}` }
|
|
90
|
-
: {}),
|
|
91
|
-
},
|
|
92
|
-
});
|
|
93
|
-
}
|
|
94
|
-
catch (err) {
|
|
95
|
-
const name = err?.name;
|
|
96
|
-
const detail = err instanceof Error ? err.message : String(err);
|
|
97
|
-
throw new CommerceError("request_failed", name === "AbortError"
|
|
98
|
-
? `erp request timed out after ${timeoutMs}ms: ${url}`
|
|
99
|
-
: `erp request failed: ${url} (${detail})`);
|
|
100
|
-
}
|
|
101
|
-
finally {
|
|
102
|
-
clearTimeout(timer);
|
|
103
|
-
}
|
|
104
|
-
if (response.status === 404) {
|
|
105
|
-
// 404 = 资源不存在:getProduct 的"未知 SKU → undefined"接口承诺
|
|
106
|
-
//(composite 次要源靠它跳过自身不收录的 SKU,而不是整体抛错)。
|
|
107
|
-
return null;
|
|
108
|
-
}
|
|
109
|
-
if (!response.ok) {
|
|
110
|
-
throw new CommerceError("request_failed", `erp request returned HTTP ${response.status} from ${url}`);
|
|
111
|
-
}
|
|
112
|
-
let raw;
|
|
113
|
-
try {
|
|
114
|
-
raw = await response.json();
|
|
115
|
-
}
|
|
116
|
-
catch {
|
|
117
|
-
throw new CommerceError("request_failed", `erp response from ${url} is not valid JSON`);
|
|
118
|
-
}
|
|
119
|
-
return raw;
|
|
120
|
-
}
|
|
121
|
-
async getProduct(sku) {
|
|
122
|
-
if (typeof sku !== "string" || sku.length === 0) {
|
|
123
|
-
throw new CommerceError("invalid_input", "sku must be a non-empty string");
|
|
124
|
-
}
|
|
125
|
-
const raw = await this.getJson(`/products/${encodeURIComponent(sku)}`);
|
|
126
|
-
if (raw === null)
|
|
127
|
-
return undefined;
|
|
128
|
-
return parseProduct(raw, `/products/${sku}`);
|
|
129
|
-
}
|
|
130
|
-
async getProducts(query = {}) {
|
|
131
|
-
const limit = Math.max(1, Math.min(Number(query.limit ?? 20) || 20, 100));
|
|
132
|
-
const params = new URLSearchParams();
|
|
133
|
-
if (query.q !== undefined && query.q !== "")
|
|
134
|
-
params.set("q", query.q);
|
|
135
|
-
params.set("limit", String(limit));
|
|
136
|
-
const raw = await this.getJson(`/products?${params.toString()}`);
|
|
137
|
-
if (raw === null || typeof raw !== "object" || Array.isArray(raw)) {
|
|
138
|
-
throw new CommerceError("request_failed", "erp product list response must be an object");
|
|
139
|
-
}
|
|
140
|
-
const body = raw;
|
|
141
|
-
if (!Array.isArray(body.results)) {
|
|
142
|
-
throw new CommerceError("request_failed", 'erp product list response is missing array field "results"');
|
|
143
|
-
}
|
|
144
|
-
return body.results.map((element, i) => parseProduct(element, `/products/${i}`));
|
|
145
|
-
}
|
|
146
|
-
async getInventory(sku) {
|
|
147
|
-
const product = await this.getProduct(sku);
|
|
148
|
-
if (product?.stock === undefined)
|
|
149
|
-
return undefined;
|
|
150
|
-
return {
|
|
151
|
-
value: product.stock,
|
|
152
|
-
authority: "UPSTREAM_PROXY",
|
|
153
|
-
source: "erp",
|
|
154
|
-
};
|
|
155
|
-
}
|
|
156
|
-
async getPrice(sku) {
|
|
157
|
-
const product = await this.getProduct(sku);
|
|
158
|
-
if (product?.price_minor === undefined || product.currency === undefined)
|
|
159
|
-
return undefined;
|
|
160
|
-
return {
|
|
161
|
-
value: { currency: product.currency, amount_minor: product.price_minor },
|
|
162
|
-
authority: "UPSTREAM_PROXY",
|
|
163
|
-
source: "erp",
|
|
164
|
-
};
|
|
165
|
-
}
|
|
166
|
-
async getPublicListing() {
|
|
167
|
-
const products = await this.getProducts({ limit: 100 });
|
|
168
|
-
return { source: "erp", count: products.length, products };
|
|
169
|
-
}
|
|
170
|
-
async health() {
|
|
171
|
-
try {
|
|
172
|
-
await this.getJson("/health");
|
|
173
|
-
return { ok: true, service: "erp-commerce-data-source", version: "1" };
|
|
174
|
-
}
|
|
175
|
-
catch (err) {
|
|
176
|
-
return {
|
|
177
|
-
ok: false,
|
|
178
|
-
service: "erp-commerce-data-source",
|
|
179
|
-
details: { error: err instanceof Error ? err.message : String(err) },
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
//# sourceMappingURL=erp-source.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"erp-source.js","sourceRoot":"","sources":["../../src/commerce/erp-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,50 +0,0 @@
|
|
|
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 { DatabaseSync } from "node:sqlite";
|
|
17
|
-
import type { CommerceHealth } from "./types.js";
|
|
18
|
-
import { type CommerceDataSource, type CommerceField, type ProductFact, type ProductSearchQuery } from "./data-source.js";
|
|
19
|
-
declare const CTOR: unique symbol;
|
|
20
|
-
/** 本地商品库 CommerceDataSource(LOCAL_AUTHORITATIVE)。 */
|
|
21
|
-
export declare class LocalDatabaseCommerceDataSource implements CommerceDataSource {
|
|
22
|
-
private readonly db;
|
|
23
|
-
constructor(db: DatabaseSync, _token: typeof CTOR);
|
|
24
|
-
getProduct(sku: string): Promise<ProductFact | undefined>;
|
|
25
|
-
getProducts(query?: ProductSearchQuery): Promise<ProductFact[]>;
|
|
26
|
-
getInventory(sku: string): Promise<CommerceField<number> | undefined>;
|
|
27
|
-
getPrice(sku: string): Promise<CommerceField<{
|
|
28
|
-
currency: string;
|
|
29
|
-
amount_minor: number;
|
|
30
|
-
}> | undefined>;
|
|
31
|
-
getPublicListing(): Promise<Record<string, unknown>>;
|
|
32
|
-
health(): Promise<CommerceHealth>;
|
|
33
|
-
/** 写入商品事实(本地权威:录入即事实)。 */
|
|
34
|
-
upsertProduct(input: {
|
|
35
|
-
sku: string;
|
|
36
|
-
title?: string;
|
|
37
|
-
price_minor: number;
|
|
38
|
-
currency?: string;
|
|
39
|
-
stock?: number;
|
|
40
|
-
delivery_lead_days?: number;
|
|
41
|
-
updated_at?: string;
|
|
42
|
-
}): ProductFact;
|
|
43
|
-
close(): void;
|
|
44
|
-
private rowToFact;
|
|
45
|
-
}
|
|
46
|
-
/** 打开(必要时创建)本地商品库;目录 0700 / 文件 0600。 */
|
|
47
|
-
export declare function openLocalDatabaseCommerceDataSource(options: {
|
|
48
|
-
dbPath: string;
|
|
49
|
-
}): LocalDatabaseCommerceDataSource;
|
|
50
|
-
export {};
|
|
@@ -1,162 +0,0 @@
|
|
|
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
|
-
* LocalDatabaseCommerceDataSource —— 本地商品库(node:sqlite,
|
|
18
|
-
* shopping-cli data hub v0.2.1 §4/#6「至少一种本地数据库源」)。
|
|
19
|
-
*
|
|
20
|
-
* 全部字段 LOCAL_AUTHORITATIVE(本地规则/录入即权威);存储惯例对齐
|
|
21
|
-
* src/handoff/order-record.ts(目录 0700 / 文件 0600 / DatabaseSync)。
|
|
22
|
-
* public-only:成本/底价等私有字段不在本表。
|
|
23
|
-
*/
|
|
24
|
-
import { chmodSync, existsSync, mkdirSync } from "node:fs";
|
|
25
|
-
import path from "node:path";
|
|
26
|
-
import { DatabaseSync } from "node:sqlite";
|
|
27
|
-
import { CommerceError, } from "./data-source.js";
|
|
28
|
-
const PRODUCT_SCHEMA = `
|
|
29
|
-
CREATE TABLE IF NOT EXISTS product_facts (
|
|
30
|
-
sku TEXT PRIMARY KEY,
|
|
31
|
-
title TEXT NOT NULL DEFAULT '',
|
|
32
|
-
price_minor INTEGER NOT NULL,
|
|
33
|
-
currency TEXT NOT NULL DEFAULT 'CNY',
|
|
34
|
-
stock INTEGER,
|
|
35
|
-
delivery_lead_days INTEGER,
|
|
36
|
-
updated_at TEXT NOT NULL
|
|
37
|
-
);
|
|
38
|
-
CREATE INDEX IF NOT EXISTS idx_product_title ON product_facts(title);
|
|
39
|
-
`;
|
|
40
|
-
const CTOR = Symbol("local-db-source.ctor");
|
|
41
|
-
/** LIKE 通配符转义(`%`/`_` 在用户输入里是字面量,不是通配符)。 */
|
|
42
|
-
function escapeLike(value) {
|
|
43
|
-
return value.replace(/[\\%_]/g, (ch) => `\\${ch}`);
|
|
44
|
-
}
|
|
45
|
-
/** 本地商品库 CommerceDataSource(LOCAL_AUTHORITATIVE)。 */
|
|
46
|
-
export class LocalDatabaseCommerceDataSource {
|
|
47
|
-
db;
|
|
48
|
-
constructor(db, _token) {
|
|
49
|
-
this.db = db;
|
|
50
|
-
}
|
|
51
|
-
async getProduct(sku) {
|
|
52
|
-
if (typeof sku !== "string" || sku.length === 0) {
|
|
53
|
-
throw new CommerceError("invalid_input", "sku must be a non-empty string");
|
|
54
|
-
}
|
|
55
|
-
const row = this.db
|
|
56
|
-
.prepare("SELECT * FROM product_facts WHERE sku = ?")
|
|
57
|
-
.get(sku);
|
|
58
|
-
return row === undefined ? undefined : this.rowToFact(row);
|
|
59
|
-
}
|
|
60
|
-
async getProducts(query = {}) {
|
|
61
|
-
const limit = Math.max(1, Math.min(Number(query.limit ?? 20) || 20, 100));
|
|
62
|
-
const q = (query.q ?? "").trim();
|
|
63
|
-
const rows = q
|
|
64
|
-
? this.db
|
|
65
|
-
.prepare("SELECT * FROM product_facts WHERE sku LIKE ? ESCAPE '\\' OR title LIKE ? ESCAPE '\\' ORDER BY sku LIMIT ?")
|
|
66
|
-
.all(`%${escapeLike(q)}%`, `%${escapeLike(q)}%`, limit)
|
|
67
|
-
: this.db
|
|
68
|
-
.prepare("SELECT * FROM product_facts ORDER BY sku LIMIT ?")
|
|
69
|
-
.all(limit);
|
|
70
|
-
return rows.map((r) => this.rowToFact(r));
|
|
71
|
-
}
|
|
72
|
-
async getInventory(sku) {
|
|
73
|
-
const product = await this.getProduct(sku);
|
|
74
|
-
if (product?.stock === undefined)
|
|
75
|
-
return undefined;
|
|
76
|
-
return {
|
|
77
|
-
value: product.stock,
|
|
78
|
-
authority: "LOCAL_AUTHORITATIVE",
|
|
79
|
-
source: "local-db",
|
|
80
|
-
};
|
|
81
|
-
}
|
|
82
|
-
async getPrice(sku) {
|
|
83
|
-
const product = await this.getProduct(sku);
|
|
84
|
-
if (product?.price_minor === undefined || product.currency === undefined)
|
|
85
|
-
return undefined;
|
|
86
|
-
return {
|
|
87
|
-
value: { currency: product.currency, amount_minor: product.price_minor },
|
|
88
|
-
authority: "LOCAL_AUTHORITATIVE",
|
|
89
|
-
source: "local-db",
|
|
90
|
-
};
|
|
91
|
-
}
|
|
92
|
-
async getPublicListing() {
|
|
93
|
-
const rows = this.db
|
|
94
|
-
.prepare("SELECT sku, title, price_minor, currency FROM product_facts ORDER BY sku LIMIT 500")
|
|
95
|
-
.all();
|
|
96
|
-
return { source: "local-db", count: rows.length, products: rows.map((r) => this.rowToFact(r)) };
|
|
97
|
-
}
|
|
98
|
-
async health() {
|
|
99
|
-
try {
|
|
100
|
-
this.db.prepare("SELECT COUNT(*) AS n FROM product_facts").get();
|
|
101
|
-
return { ok: true, service: "local-db-commerce-data-source", version: "1" };
|
|
102
|
-
}
|
|
103
|
-
catch (err) {
|
|
104
|
-
return {
|
|
105
|
-
ok: false,
|
|
106
|
-
service: "local-db-commerce-data-source",
|
|
107
|
-
details: { error: err instanceof Error ? err.message : String(err) },
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
/** 写入商品事实(本地权威:录入即事实)。 */
|
|
112
|
-
upsertProduct(input) {
|
|
113
|
-
if (typeof input.sku !== "string" || input.sku.length === 0) {
|
|
114
|
-
throw new CommerceError("invalid_input", "sku must be a non-empty string");
|
|
115
|
-
}
|
|
116
|
-
if (!Number.isInteger(input.price_minor) || input.price_minor < 0) {
|
|
117
|
-
throw new CommerceError("invalid_input", "price_minor must be a non-negative integer");
|
|
118
|
-
}
|
|
119
|
-
const updatedAt = input.updated_at ?? new Date().toISOString();
|
|
120
|
-
this.db
|
|
121
|
-
.prepare(`INSERT INTO product_facts (sku, title, price_minor, currency, stock, delivery_lead_days, updated_at)
|
|
122
|
-
VALUES (?, ?, ?, ?, ?, ?, ?)
|
|
123
|
-
ON CONFLICT(sku) DO UPDATE SET
|
|
124
|
-
title=excluded.title, price_minor=excluded.price_minor, currency=excluded.currency,
|
|
125
|
-
stock=excluded.stock, delivery_lead_days=excluded.delivery_lead_days, updated_at=excluded.updated_at`)
|
|
126
|
-
.run(input.sku, input.title ?? "", input.price_minor, input.currency ?? "CNY", input.stock ?? null, input.delivery_lead_days ?? null, updatedAt);
|
|
127
|
-
const row = this.db.prepare("SELECT * FROM product_facts WHERE sku = ?").get(input.sku);
|
|
128
|
-
if (row === undefined)
|
|
129
|
-
throw new CommerceError("request_failed", "upsert did not persist");
|
|
130
|
-
return this.rowToFact(row);
|
|
131
|
-
}
|
|
132
|
-
close() {
|
|
133
|
-
this.db.close();
|
|
134
|
-
}
|
|
135
|
-
rowToFact(row) {
|
|
136
|
-
return {
|
|
137
|
-
sku: row.sku,
|
|
138
|
-
...(row.title !== "" ? { title: row.title } : {}),
|
|
139
|
-
price_minor: row.price_minor,
|
|
140
|
-
currency: row.currency,
|
|
141
|
-
...(row.stock !== null ? { stock: row.stock } : {}),
|
|
142
|
-
...(row.delivery_lead_days !== null ? { delivery_lead_days: row.delivery_lead_days } : {}),
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
/** 打开(必要时创建)本地商品库;目录 0700 / 文件 0600。 */
|
|
147
|
-
export function openLocalDatabaseCommerceDataSource(options) {
|
|
148
|
-
if (options.dbPath === ":memory:") {
|
|
149
|
-
const db = new DatabaseSync(":memory:");
|
|
150
|
-
db.exec(PRODUCT_SCHEMA);
|
|
151
|
-
return new LocalDatabaseCommerceDataSource(db, CTOR);
|
|
152
|
-
}
|
|
153
|
-
const dir = path.dirname(options.dbPath);
|
|
154
|
-
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
155
|
-
chmodSync(dir, 0o700);
|
|
156
|
-
const db = new DatabaseSync(options.dbPath);
|
|
157
|
-
if (existsSync(options.dbPath))
|
|
158
|
-
chmodSync(options.dbPath, 0o600);
|
|
159
|
-
db.exec(PRODUCT_SCHEMA);
|
|
160
|
-
return new LocalDatabaseCommerceDataSource(db, CTOR);
|
|
161
|
-
}
|
|
162
|
-
//# sourceMappingURL=local-db-source.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-db-source.js","sourceRoot":"","sources":["../../src/commerce/local-db-source.ts"],"names":[],"mappings":"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"}
|