@tier0/sdk-v2 0.9.10 → 0.10.1
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/CHANGELOG.md +102 -0
- package/LICENSE +21 -21
- package/README.md +162 -24
- package/dist/cjs/client.d.ts +83 -3
- package/dist/cjs/client.js +4 -6
- package/dist/cjs/client.js.map +1 -1
- package/dist/cjs/cloud-server.d.ts +33 -26
- package/dist/cjs/cloud-server.js +102 -100
- package/dist/cjs/cloud-server.js.map +1 -1
- package/dist/cjs/cloud-transport.d.ts +15 -20
- package/dist/cjs/cloud-transport.js +87 -68
- package/dist/cjs/cloud-transport.js.map +1 -1
- package/dist/cjs/data/bootstrap.js +3 -4
- package/dist/cjs/data/bootstrap.js.map +1 -1
- package/dist/cjs/data/call.d.ts +1 -3
- package/dist/cjs/data/call.js +8 -12
- package/dist/cjs/data/call.js.map +1 -1
- package/dist/cjs/data/client.d.ts +8 -7
- package/dist/cjs/data/client.js +24 -11
- package/dist/cjs/data/client.js.map +1 -1
- package/dist/cjs/data/collection.d.ts +3 -5
- package/dist/cjs/data/collection.js +3 -4
- package/dist/cjs/data/collection.js.map +1 -1
- package/dist/cjs/data/context.d.ts +5 -11
- package/dist/cjs/data/context.js +21 -36
- package/dist/cjs/data/context.js.map +1 -1
- package/dist/cjs/data/error.js +1 -1
- package/dist/cjs/data/error.js.map +1 -1
- package/dist/cjs/data/index.d.ts +5 -3
- package/dist/cjs/data/index.js +5 -5
- package/dist/cjs/data/index.js.map +1 -1
- package/dist/cjs/data/relay.d.ts +51 -0
- package/dist/cjs/data/relay.js +371 -0
- package/dist/cjs/data/relay.js.map +1 -0
- package/dist/cjs/data/subscribe.d.ts +22 -38
- package/dist/cjs/data/subscribe.js +22 -28
- package/dist/cjs/data/subscribe.js.map +1 -1
- package/dist/cjs/event-stream.d.ts +28 -0
- package/dist/cjs/event-stream.js +222 -0
- package/dist/cjs/event-stream.js.map +1 -0
- package/dist/cjs/mq/client.d.ts +32 -1
- package/dist/cjs/mq/client.js +404 -69
- package/dist/cjs/mq/client.js.map +1 -1
- package/dist/cjs/mq/index.d.ts +1 -0
- package/dist/cjs/mq/index.js +3 -1
- package/dist/cjs/mq/index.js.map +1 -1
- package/dist/cjs/mq/topic.d.ts +29 -0
- package/dist/cjs/mq/topic.js +48 -0
- package/dist/cjs/mq/topic.js.map +1 -0
- package/dist/cjs/mq/types.d.ts +21 -1
- package/dist/cjs/mq/types.js.map +1 -1
- package/dist/cjs/openapi/api.generated.d.ts +21 -0
- package/dist/cjs/openapi/api.generated.js +11 -0
- package/dist/cjs/openapi/api.generated.js.map +1 -1
- package/dist/cjs/openapi/client.d.ts +46 -0
- package/dist/cjs/openapi/client.js +158 -10
- package/dist/cjs/openapi/client.js.map +1 -1
- package/dist/cjs/openapi/codecs.generated.d.ts +75 -0
- package/dist/cjs/openapi/codecs.generated.js +1 -1
- package/dist/cjs/openapi/codecs.generated.js.map +1 -1
- package/dist/cjs/openapi/types.generated.d.ts +206 -1
- package/dist/cjs/openapi/types.generated.js.map +1 -1
- package/dist/cjs/page-runtime.d.ts +48 -0
- package/dist/cjs/page-runtime.js +74 -0
- package/dist/cjs/page-runtime.js.map +1 -0
- package/dist/cjs/platform-proxy.d.ts +17 -0
- package/dist/cjs/platform-proxy.js +52 -0
- package/dist/cjs/platform-proxy.js.map +1 -0
- package/dist/cjs/runtime-context.d.ts +2 -1
- package/dist/cjs/runtime-context.js +6 -2
- package/dist/cjs/runtime-context.js.map +1 -1
- package/dist/cjs/runtime-env.js.map +1 -1
- package/dist/cjs/source.d.ts +19 -1
- package/dist/cjs/source.js +9 -3
- package/dist/cjs/source.js.map +1 -1
- package/dist/cjs/stream.js +3 -2
- package/dist/cjs/stream.js.map +1 -1
- package/dist/cjs/streams/contract.generated.d.ts +7 -1
- package/dist/cjs/streams/contract.generated.js.map +1 -1
- package/dist/cjs/streams/messages.js +1 -10
- package/dist/cjs/streams/messages.js.map +1 -1
- package/dist/cjs/streams/requests.d.ts +3 -0
- package/dist/cjs/streams/requests.js +5 -2
- package/dist/cjs/streams/requests.js.map +1 -1
- package/dist/cjs/streams/transport.d.ts +1 -13
- package/dist/cjs/streams/transport.js +2 -18
- package/dist/cjs/streams/transport.js.map +1 -1
- package/dist/cjs/uns-v2/client.d.ts +1 -6
- package/dist/cjs/uns-v2/client.js +30 -6
- package/dist/cjs/uns-v2/client.js.map +1 -1
- package/dist/cjs/uns-v2/data-client.d.ts +5 -2
- package/dist/cjs/uns-v2/data-client.js +7 -4
- package/dist/cjs/uns-v2/data-client.js.map +1 -1
- package/dist/cjs/uns-v2/generated.d.ts +6783 -4655
- package/dist/cjs/uns-v2/generated.js +221 -65
- package/dist/cjs/uns-v2/generated.js.map +1 -1
- package/dist/cjs/uns-v2/sse.d.ts +7 -1
- package/dist/cjs/uns-v2/sse.js +12 -2
- package/dist/cjs/uns-v2/sse.js.map +1 -1
- package/dist/esm/client.d.ts +83 -3
- package/dist/esm/client.js +5 -7
- package/dist/esm/client.js.map +1 -1
- package/dist/esm/cloud-server.d.ts +33 -26
- package/dist/esm/cloud-server.js +99 -97
- package/dist/esm/cloud-server.js.map +1 -1
- package/dist/esm/cloud-transport.d.ts +15 -20
- package/dist/esm/cloud-transport.js +86 -67
- package/dist/esm/cloud-transport.js.map +1 -1
- package/dist/esm/data/bootstrap.js +3 -4
- package/dist/esm/data/bootstrap.js.map +1 -1
- package/dist/esm/data/call.d.ts +1 -3
- package/dist/esm/data/call.js +9 -13
- package/dist/esm/data/call.js.map +1 -1
- package/dist/esm/data/client.d.ts +8 -7
- package/dist/esm/data/client.js +22 -9
- package/dist/esm/data/client.js.map +1 -1
- package/dist/esm/data/collection.d.ts +3 -5
- package/dist/esm/data/collection.js +3 -4
- package/dist/esm/data/collection.js.map +1 -1
- package/dist/esm/data/context.d.ts +5 -11
- package/dist/esm/data/context.js +19 -33
- package/dist/esm/data/context.js.map +1 -1
- package/dist/esm/data/error.js +1 -1
- package/dist/esm/data/error.js.map +1 -1
- package/dist/esm/data/index.d.ts +5 -3
- package/dist/esm/data/index.js +3 -2
- package/dist/esm/data/index.js.map +1 -1
- package/dist/esm/data/relay.d.ts +51 -0
- package/dist/esm/data/relay.js +368 -0
- package/dist/esm/data/relay.js.map +1 -0
- package/dist/esm/data/subscribe.d.ts +22 -38
- package/dist/esm/data/subscribe.js +22 -27
- package/dist/esm/data/subscribe.js.map +1 -1
- package/dist/esm/event-stream.d.ts +28 -0
- package/dist/esm/event-stream.js +217 -0
- package/dist/esm/event-stream.js.map +1 -0
- package/dist/esm/mq/client.d.ts +32 -1
- package/dist/esm/mq/client.js +404 -69
- package/dist/esm/mq/client.js.map +1 -1
- package/dist/esm/mq/index.d.ts +1 -0
- package/dist/esm/mq/index.js +1 -0
- package/dist/esm/mq/index.js.map +1 -1
- package/dist/esm/mq/topic.d.ts +29 -0
- package/dist/esm/mq/topic.js +44 -0
- package/dist/esm/mq/topic.js.map +1 -0
- package/dist/esm/mq/types.d.ts +21 -1
- package/dist/esm/mq/types.js.map +1 -1
- package/dist/esm/openapi/api.generated.d.ts +21 -0
- package/dist/esm/openapi/api.generated.js +11 -0
- package/dist/esm/openapi/api.generated.js.map +1 -1
- package/dist/esm/openapi/client.d.ts +46 -0
- package/dist/esm/openapi/client.js +157 -10
- package/dist/esm/openapi/client.js.map +1 -1
- package/dist/esm/openapi/codecs.generated.d.ts +75 -0
- package/dist/esm/openapi/codecs.generated.js +1 -1
- package/dist/esm/openapi/codecs.generated.js.map +1 -1
- package/dist/esm/openapi/types.generated.d.ts +206 -1
- package/dist/esm/openapi/types.generated.js.map +1 -1
- package/dist/esm/page-runtime.d.ts +48 -0
- package/dist/esm/page-runtime.js +65 -0
- package/dist/esm/page-runtime.js.map +1 -0
- package/dist/esm/platform-proxy.d.ts +17 -0
- package/dist/esm/platform-proxy.js +47 -0
- package/dist/esm/platform-proxy.js.map +1 -0
- package/dist/esm/runtime-context.d.ts +2 -1
- package/dist/esm/runtime-context.js +6 -2
- package/dist/esm/runtime-context.js.map +1 -1
- package/dist/esm/runtime-env.js.map +1 -1
- package/dist/esm/source.d.ts +19 -1
- package/dist/esm/source.js +10 -4
- package/dist/esm/source.js.map +1 -1
- package/dist/esm/stream.js +4 -3
- package/dist/esm/stream.js.map +1 -1
- package/dist/esm/streams/contract.generated.d.ts +7 -1
- package/dist/esm/streams/contract.generated.js.map +1 -1
- package/dist/esm/streams/messages.js +1 -10
- package/dist/esm/streams/messages.js.map +1 -1
- package/dist/esm/streams/requests.d.ts +3 -0
- package/dist/esm/streams/requests.js +5 -2
- package/dist/esm/streams/requests.js.map +1 -1
- package/dist/esm/streams/transport.d.ts +1 -13
- package/dist/esm/streams/transport.js +1 -17
- package/dist/esm/streams/transport.js.map +1 -1
- package/dist/esm/uns-v2/client.d.ts +1 -6
- package/dist/esm/uns-v2/client.js +30 -6
- package/dist/esm/uns-v2/client.js.map +1 -1
- package/dist/esm/uns-v2/data-client.d.ts +5 -2
- package/dist/esm/uns-v2/data-client.js +8 -5
- package/dist/esm/uns-v2/data-client.js.map +1 -1
- package/dist/esm/uns-v2/generated.d.ts +6783 -4655
- package/dist/esm/uns-v2/generated.js +221 -65
- package/dist/esm/uns-v2/generated.js.map +1 -1
- package/dist/esm/uns-v2/sse.d.ts +7 -1
- package/dist/esm/uns-v2/sse.js +12 -2
- package/dist/esm/uns-v2/sse.js.map +1 -1
- package/package.json +25 -12
- package/skills/tier0-sdk-v2/SKILL.md +11 -5
- package/skills/tier0-sdk-v2/references/integration.md +14 -24
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +11 -5
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +6 -10
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +20 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +46 -13
- package/skills/tier0-sdk-v2/tier0-sdk-v2-members/SKILL.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +5 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +25 -0
- package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +1 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/SKILL.md +3 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +6 -6
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +4 -4
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +26 -36
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +9 -23
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +12 -29
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +4 -5
- package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +5 -5
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +3 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +23 -9
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +14 -12
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/http-server.md +4 -4
- package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +4 -3
- package/skills/tier0-sdk-v2/tier0-sdk-v2-streams/SKILL.md +14 -12
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +3 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +2 -2
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +22 -1
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +5 -6
- package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/update.md +11 -0
- package/dist/cjs/app-identity-contract.generated.d.ts +0 -22
- package/dist/cjs/app-identity-contract.generated.js +0 -51
- package/dist/cjs/app-identity-contract.generated.js.map +0 -1
- package/dist/cjs/runtime.d.ts +0 -13
- package/dist/cjs/runtime.js +0 -51
- package/dist/cjs/runtime.js.map +0 -1
- package/dist/esm/app-identity-contract.generated.d.ts +0 -22
- package/dist/esm/app-identity-contract.generated.js +0 -48
- package/dist/esm/app-identity-contract.generated.js.map +0 -1
- package/dist/esm/runtime.d.ts +0 -13
- package/dist/esm/runtime.js +0 -46
- package/dist/esm/runtime.js.map +0 -1
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
| title | string | 是 | 1–50 字符 |
|
|
10
10
|
| content | string | 是 | 1–800 字符 |
|
|
11
11
|
| idempotencyKey | string | 是 | 最多 128 字符;同一次业务事件固定 |
|
|
12
|
-
| mode | test/live | 否 |
|
|
12
|
+
| mode | test/live | 否 | 已废弃,不传;平台按来源判定 |
|
|
13
13
|
| channels | array | 否 | SDK 省略补 web+mobile;[] 仅站内信 |
|
|
14
14
|
| sender | object | 否 | app/other;system 仅平台内部服务 Key |
|
|
15
15
|
| link | string | 否 | https:// 或单斜杠开头,最多 500 字符 |
|
|
@@ -22,19 +22,19 @@
|
|
|
22
22
|
import { createClient, getCurrentAppId, type Tier0Client } from '@tier0/sdk-v2';
|
|
23
23
|
|
|
24
24
|
export async function sendCompletedOrder(
|
|
25
|
-
recipientUserId: string, orderId: string, intentKey: string,
|
|
25
|
+
recipientUserId: string, orderId: string, intentKey: string,
|
|
26
26
|
client: Tier0Client = createClient(),
|
|
27
27
|
) {
|
|
28
28
|
return client.notifications.send({
|
|
29
29
|
recipientUserId, type: 'inbox', title: '工单已完成',
|
|
30
30
|
content: '工单 ' + orderId + ' 已完成,请查看处理结果。',
|
|
31
|
-
idempotencyKey: intentKey,
|
|
31
|
+
idempotencyKey: intentKey, channels: ['web', 'mobile'],
|
|
32
32
|
sender: { type: 'app', id: getCurrentAppId() },
|
|
33
33
|
});
|
|
34
34
|
}
|
|
35
35
|
```
|
|
36
36
|
|
|
37
|
-
sender.id
|
|
37
|
+
sender.id 来自 getCurrentAppId()(平台设置的 TIER0_APP_ID)。需带链接时传已验证可访问的业务 https 地址,或确认目标前端支持的相对路由。
|
|
38
38
|
|
|
39
39
|
other 发送者应给人读名称,如 `{type:'other',name:'库存同步服务'}`。app 不重复硬编码名称。sender/meta/link 都是展示导航提示,不是授权证明。meta 值为字符串,序列化最多 500 字节;sender.name 最多100字符。source 是废弃别名,不用于新代码。
|
|
40
40
|
|
|
@@ -48,7 +48,7 @@ other 发送者应给人读名称,如 `{type:'other',name:'库存同步服务'
|
|
|
48
48
|
| [] | 只建站内信 |
|
|
49
49
|
| 重复项 | SDK 去重 |
|
|
50
50
|
|
|
51
|
-
没有 desktop 渠道。不要将 SDK 默认值与裸后端省略渠道的静默语义混淆。
|
|
51
|
+
没有 desktop 渠道。不要将 SDK 默认值与裸后端省略渠道的静默语义混淆。mode 由平台判定:预览和沙箱发出的是 test,只进该 App 的预览铃铛;线上 App 发出的是 live。test 也是真实消息,不是 dryRun。
|
|
52
52
|
|
|
53
53
|
同键同内容用于重放原意图;同键改内容产生冲突。新事件/不同收件人使用不同键。SDK 不自动重试,结果未知先对账;已有 messageId 用 get,没有按意图键查询的 SDK 方法。
|
|
54
54
|
|
|
@@ -69,4 +69,4 @@ other 发送者应给人读名称,如 `{type:'other',name:'库存同步服务'
|
|
|
69
69
|
| 422 CONTENT_LIMIT_EXCEEDED | 缩短内容 |
|
|
70
70
|
| 429 NOTIFICATION_RATE_LIMITED | 有界退避;保留原键,不自动广播重发 |
|
|
71
71
|
|
|
72
|
-
link 拒绝 //host、反斜杠、Unicode 空白/控制/不可见格式字符。省略 link
|
|
72
|
+
link 拒绝 //host、反斜杠、Unicode 空白/控制/不可见格式字符。省略 link 时点开消息不跳转;是否另有打开发送 App 的按钮取决于发送者与目标前端。
|
|
@@ -5,7 +5,7 @@ description: 使用 @tier0/sdk-v2 的 client.source 查询、创建、修改和
|
|
|
5
5
|
|
|
6
6
|
# Source 数据接入
|
|
7
7
|
|
|
8
|
-
Source 维护连接配置、认证引用与源状态。脚本处理用 [Stream](../tier0-sdk-v2-stream/SKILL.md),数据存储用 [UNS](../tier0-sdk-v2-uns/SKILL.md)。服务端使用 `createClient({apiHost,apiKey})`,或注入 TIER0_API_HOST / TIER0_API_KEY 后 `createClient()`;密钥不进入浏览器。
|
|
8
|
+
Source 维护连接配置、认证引用与源状态。脚本处理用 [Stream](../tier0-sdk-v2-stream/SKILL.md),数据存储用 [UNS](../tier0-sdk-v2-uns/SKILL.md)。服务端使用 `createClient({apiHost,apiKey})`,或注入 TIER0_API_HOST / TIER0_API_KEY 后 `createClient()`;密钥不进入浏览器。Tier0 App 的 Key 无权调 Source 管理接口,Backend 拒绝(403)。
|
|
9
9
|
|
|
10
10
|
## 按任务加载参考
|
|
11
11
|
|
|
@@ -16,16 +16,16 @@ Source 维护连接配置、认证引用与源状态。脚本处理用 [Stream](
|
|
|
16
16
|
| 列表、详情、运行状态 | [查询](references/read.md) | documents.list/get、observations.get、runtime.get |
|
|
17
17
|
| 修改名称、端点或配置 | [修改](references/update.md) | documents.update |
|
|
18
18
|
| 查看修改/删除影响 | [影响分析](references/changes.md) | impact |
|
|
19
|
-
|
|
|
19
|
+
| 禁用后删除并核验 | [删除](references/delete.md) | documents.state.update、documents.delete |
|
|
20
20
|
|
|
21
21
|
先加载对应操作文档,使用其中的参数表、完整请求及返回判断。只执行用户任务所需步骤;示例函数调用才会执行写入,导入不执行。新建→查询→修改→删除可组成生命周期,但查询任务不触发其他操作。
|
|
22
22
|
|
|
23
23
|
## 核心约束
|
|
24
24
|
|
|
25
|
-
1. Source
|
|
25
|
+
1. Source 配置使用 documents.*,原生文档为 SourceDefinition,连接字段 endpoint/role/http/sql/mqtt/modbus 等位于顶层,与 Enterprise 一致。HTTP API 使用 http-api;OAuth 为 oauth2;SQL 为 edge-sql;Modbus TCP 为 modbus-tcp。Server 托管入口的路由和响应时机由 Stream 定义。
|
|
26
26
|
2. 已有 ID 和 revision 时优先用 documents.update 的 patch,避免额外 get;完整替换 document 前读取完整文档,安全列表摘要不能无损回写。原生 ID 是十进制字符串,revision 原样传递,不转 Number。
|
|
27
27
|
3. 现有 Source 修改、删除都要 expectedRevision。仅修改名称、描述可直接提交;修改连接配置或删除时,没有任何 Stream 引用可直接提交,有草稿、活动、历史或不可见引用则需 confirmedImpactRevision。先形成精确意图,再读取全部影响分页;回执不可合成、跨意图复用或静默刷新。提供的回执始终严格校验,不自动获取并同意影响。
|
|
28
|
-
4.
|
|
28
|
+
4. 配置中保留 credentialRef,不写秘密。创建专用 credentials 与 documents.credentials.update 使用原生 kind 和 username/secret/values;OAuth 非秘密配置在 http.oauth。删除使用 documents.delete;不再调用 source.delete 或 credentials.create。远端 Edge 凭据在本地预配,云端只使用批准的 target 绑定。
|
|
29
29
|
5. Source 创建后即可供 Stream 使用,不提供启停开关。删除 Source 后停止后续使用;runtimeState 和 health 是运行观测,不是用户开关。保存配置不代表 Stream 已切换至新 configRevision。
|
|
30
30
|
|
|
31
31
|
## 返回值与异常
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
| --- | --- | --- | --- |
|
|
7
7
|
| id / expectedRevision | string / integer | 是 | 当前 ID 和最近写回执或读取取得的修订 |
|
|
8
8
|
| action | update/delete | 是 | 精确变更类型 |
|
|
9
|
-
| patch / document |
|
|
9
|
+
| patch / document | SourceDefinitionPatch / SourceDefinition | 更新时二选一 | 与随后提交完全相同的补丁或完整文档;其他 action 不传 |
|
|
10
10
|
| offset / size | integer | 否 | 首次 0;size 1–200 |
|
|
11
11
|
| impactRevision | string | 翻页时 | 沿用首次返回的确认值 |
|
|
12
12
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
|
|
15
15
|
|
|
16
16
|
export async function collectSourceImpact(
|
|
17
|
-
intent:
|
|
17
|
+
intent: UnsV2Request<'sourceImpact'>,
|
|
18
18
|
client: Tier0Client = createClient(),
|
|
19
19
|
) {
|
|
20
20
|
const first = await client.source.impact({ ...intent, offset: 0, size: 200 });
|
|
@@ -6,26 +6,27 @@
|
|
|
6
6
|
| --- | --- | --- | --- |
|
|
7
7
|
| dryRun | boolean | 否 | 默认 false 提交;true 仅预检 |
|
|
8
8
|
| document.name | string | 是 | 1–63 个 Unicode 字符 |
|
|
9
|
-
| document.protocol | string | 是 | 原生协议,如 http-api、mqtt、modbus |
|
|
10
|
-
| document.
|
|
11
|
-
| document.
|
|
9
|
+
| document.protocol | string | 是 | 原生协议,如 http-api、oauth2、mqtt、modbus-tcp、edge-sql |
|
|
10
|
+
| document.role | client / server | HTTP API 显式指定 | client 主动请求;server 接收入站请求 |
|
|
11
|
+
| document.endpoint | string | 是 | 无凭据的协议地址 |
|
|
12
|
+
| document.http/sql/mqtt/modbus | object | 按协议 | 见[协议配置](protocols.md) |
|
|
12
13
|
| document.description | string | 否 | 最多 512 字符 |
|
|
13
|
-
| credentials | object | 否 | HTTP Client 或 SQL 的只写新凭据;与已有
|
|
14
|
+
| credentials | object | 否 | HTTP Client 或 SQL 的只写新凭据;与已有 credentialRef 引用互斥 |
|
|
14
15
|
| idempotencyKey | string | 否 | 建议提供,最多 128 字符,同一业务意图保持不变 |
|
|
15
16
|
|
|
16
17
|
## 完整示例:HTTP Client 数据源
|
|
17
18
|
|
|
18
|
-
传入实际端点、名称和意图键。此函数创建 `http-api` + `
|
|
19
|
+
传入实际端点、名称和意图键。此函数创建 `http-api` + `role: client` 配置,创建后即可供 Stream 使用。client 从服务端环境读取 API Host/Key,也可显式注入。
|
|
19
20
|
|
|
20
21
|
```ts
|
|
21
|
-
import { createClient, type Tier0Client, type
|
|
22
|
+
import { createClient, type Tier0Client, type SourceDefinition } from '@tier0/sdk-v2';
|
|
22
23
|
|
|
23
24
|
export async function createHttpSource(
|
|
24
25
|
endpoint: string, name: string, intentKey: string, client: Tier0Client = createClient(),
|
|
25
26
|
) {
|
|
26
|
-
const document:
|
|
27
|
+
const document: SourceDefinition = {
|
|
27
28
|
name, protocol: 'http-api', description: '订单系统 HTTP 接入',
|
|
28
|
-
|
|
29
|
+
role: 'client', endpoint, http: { anonymous: true },
|
|
29
30
|
};
|
|
30
31
|
const saved = await client.source.documents.create({
|
|
31
32
|
dryRun: false, document, idempotencyKey: intentKey,
|
|
@@ -37,13 +38,13 @@ export async function createHttpSource(
|
|
|
37
38
|
|
|
38
39
|
一次提交即可返回完整 data:id、revision、document、runtimeState、health、createdAt、updatedAt,无需另行 get。需要单独预检时可先传 `dryRun: true`,返回 `{ validated: true, sideEffects: false }`,没有 ID。预检不保留提交条件;实际保存仍会校验。ID 原样保留十进制字符串。
|
|
39
40
|
|
|
40
|
-
HTTP Server 同样使用 `protocol: http-api`,角色为 `
|
|
41
|
+
HTTP Server 同样使用 `protocol: http-api`,角色为 `role: server`;其配置以 `source.protocols.list({})` 返回的正式合同为准,不能复用下方 Client 的主动请求示例。入站业务统一绑定 HTTPServer Source,路由和响应时机在 Stream 定义;202 状态不能据此报告 Stream 执行完成。
|
|
41
42
|
|
|
42
43
|
## HTTP Client Bearer 凭据
|
|
43
44
|
|
|
44
45
|
Source 保存 API 基址和认证;实际请求的 method/path/query 由 Stream 设置。例如 endpoint 使用 `https://inventory.example.com/api/v1`,再由 [Stream 示例](../../tier0-sdk-v2-stream/references/create.md)请求 `GET inventory`。token 从服务端密钥提供者取得,不写入脚本、文档、日志或仓库。
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
凭据使用 `{kind:"bearer",secret:token}`;不再使用 material 或 method。认证类型在 document.http.authentication 声明,实际 HTTP method/path/query 仍在 Stream 中设置。
|
|
47
48
|
|
|
48
49
|
```ts
|
|
49
50
|
import { createClient, type Tier0Client } from '@tier0/sdk-v2';
|
|
@@ -54,8 +55,8 @@ export async function createAuthenticatedHttpSource(
|
|
|
54
55
|
) {
|
|
55
56
|
const saved = await client.source.documents.create({
|
|
56
57
|
dryRun: false, idempotencyKey: intentKey,
|
|
57
|
-
document: { name, protocol: 'http-api',
|
|
58
|
-
credentials: { kind: 'bearer',
|
|
58
|
+
document: { name, protocol: 'http-api', role: 'client', endpoint, http: { authentication: 'bearer' } },
|
|
59
|
+
credentials: { kind: 'bearer', secret: token },
|
|
59
60
|
});
|
|
60
61
|
if (!('id' in saved.data)) throw new Error('未返回 Source ID');
|
|
61
62
|
return { receipt: saved, current: saved.data };
|
|
@@ -66,17 +67,17 @@ export async function createAuthenticatedHttpSource(
|
|
|
66
67
|
|
|
67
68
|
## HTTP Server:管理配置
|
|
68
69
|
|
|
69
|
-
正式协议目录规定 Server 的 `
|
|
70
|
+
正式协议目录规定 Server 的 `endpoint` 为 `http://managed`,不携带 Client 认证 或创建专用 `credentials`。该函数只保存 Source,不创建 Stream,也不发起入站请求。
|
|
70
71
|
|
|
71
72
|
```ts
|
|
72
|
-
import { createClient, type Tier0Client, type
|
|
73
|
+
import { createClient, type Tier0Client, type SourceDefinition } from '@tier0/sdk-v2';
|
|
73
74
|
|
|
74
75
|
export async function createHttpServerSource(
|
|
75
76
|
name: string, intentKey: string, client: Tier0Client = createClient(),
|
|
76
77
|
) {
|
|
77
|
-
const document:
|
|
78
|
+
const document: SourceDefinition = {
|
|
78
79
|
name, protocol: 'http-api',
|
|
79
|
-
|
|
80
|
+
role: 'server', endpoint: 'http://managed',
|
|
80
81
|
};
|
|
81
82
|
const saved = await client.source.documents.create({
|
|
82
83
|
dryRun: false, document, idempotencyKey: intentKey,
|
|
@@ -88,33 +89,20 @@ export async function createHttpServerSource(
|
|
|
88
89
|
|
|
89
90
|
Server 的固定前缀 `/ingest/v1/{workspaceId}/{sourceId}` 和 Bearer 要求由协议目录的 `x-tier0-http-in` 描述。Source 不接受业务路径配置;在 [Stream HTTPServer 示例](../../tier0-sdk-v2-stream/references/http-server.md)中注册 `onRequest` 的 method/path。响应时机属于 Stream。
|
|
90
91
|
|
|
91
|
-
##
|
|
92
|
+
## 原生只写凭据
|
|
92
93
|
|
|
93
|
-
HTTP
|
|
94
|
-
|
|
95
|
-
| kind | material | method |
|
|
96
|
-
| --- | --- | --- |
|
|
97
|
-
| basic | username、password | 省略时 REQUEST;显式方法绑定精确 URL 和该方法 |
|
|
98
|
-
| bearer | token | 省略时 REQUEST;显式方法绑定精确 URL 和该方法 |
|
|
99
|
-
| apiKey | headerName、value | 省略或 REQUEST |
|
|
100
|
-
| oauth2ClientCredentials | tokenUrl、clientId、clientSecret;可选 scope、clientAuthentication | 普通创建省略;旧 GET 保留既有兼容语义 |
|
|
101
|
-
|
|
102
|
-
Basic/Bearer 显式 `credentials.method: 'GET'` 表示凭据只用于所绑定精确 URL 的 GET,不表示该基址下所有 GET 都可使用:绑定 `/api/v1` 不授权 `/api/v1/inventory?limit=5000`。仅在任务明确需要该限制时传入;已有绑定保持原限制,不自动迁移或在拒绝后回退 REQUEST。
|
|
103
|
-
|
|
104
|
-
OAuth 的 `clientAuthentication` 支持 `client_secret_post`(默认)和 `client_secret_basic`;method 接受省略、REQUEST 或旧 GET,旧 GET 保留现有兼容语义,不能把 Basic/Bearer 的精确 URL 规则跨认证类型套用。普通创建仍省略 method。vendor SESSION 合同独立保留,不是此 inline 创建的 method,也不新增独立公开凭据 API。
|
|
94
|
+
Cloud 与 Enterprise 使用相同 SourceDefinition / SourceCredentials。HTTP Basic 为 `{kind:'basic',username,secret}`,Bearer 为 `{kind:'bearer',secret}`,OAuth 为 `{kind:'oauth2',secret}`;OAuth 的 tokenUrl/clientId/grantType/clientAuthentication 留在 document.http.oauth,Source protocol 使用 oauth2。custom 使用 values 字符串映射,键名按目标协议目录声明,不凭空推测。创建凭据需要 idempotencyKey 与凭据管理权限,不能把秘密写入 endpoint、脚本或日志。
|
|
105
95
|
|
|
106
96
|
```ts
|
|
107
|
-
import { createClient, type Tier0Client, type
|
|
97
|
+
import { createClient, type Tier0Client, type SourceCredentials, type SourceDefinition } from '@tier0/sdk-v2';
|
|
108
98
|
|
|
109
99
|
export async function createHttpSourceWithCredentials(
|
|
110
|
-
|
|
100
|
+
document: SourceDefinition, credentials: SourceCredentials, intentKey: string,
|
|
111
101
|
client: Tier0Client = createClient(),
|
|
112
102
|
) {
|
|
113
103
|
const saved = await client.source.documents.create({
|
|
114
104
|
dryRun: false, idempotencyKey: intentKey,
|
|
115
|
-
document
|
|
116
|
-
config: { role: 'client', endpoint, options: {} } },
|
|
117
|
-
credentials,
|
|
105
|
+
document, credentials,
|
|
118
106
|
});
|
|
119
107
|
if (!('id' in saved.data)) throw new Error('未返回已保存的 Source');
|
|
120
108
|
return { receipt: saved, current: saved.data };
|
|
@@ -123,6 +111,8 @@ export async function createHttpSourceWithCredentials(
|
|
|
123
111
|
|
|
124
112
|
## SQL 用户名和密码
|
|
125
113
|
|
|
126
|
-
SQL
|
|
114
|
+
SQL 使用 protocol=edge-sql、顶层 endpoint 和 sql(固定命名查询)。凭据为 `{kind:'basic',username,secret}`,不传 method/material。查询和 TLS 选项以目标协议目录为准,不允许脚本传任意 SQL。
|
|
115
|
+
|
|
116
|
+
已有 Source 换证使用 `source.documents.credentials.update({id,expectedRevision,credentials,dryRun:false,idempotencyKey})`,路由 `/openapi/v2/uns/sources/documents/credentials/update`,不再调用独立 credentials.create。远端 Edge 秘密须在目标 Edge 本地预配;云绑定只使用已批准的 target,不经云转发 Edge 秘密。
|
|
127
117
|
|
|
128
|
-
|
|
118
|
+
dryRun 省略时直接提交。创建或换证成功不等于采集成功;仍须检查 Stream 运行与 Collection 数据。
|
|
@@ -1,19 +1,10 @@
|
|
|
1
1
|
# 删除 Source
|
|
2
2
|
|
|
3
|
-
方法:`source.delete`;POST `/openapi/v2/uns/sources/delete`。
|
|
3
|
+
方法:`source.documents.delete`;POST `/openapi/v2/uns/sources/documents/delete`。
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
| --- | --- | --- | --- |
|
|
7
|
-
| dryRun | boolean | 是 | true 预检;false 提交 |
|
|
8
|
-
| items | array | 是 | 1–200 项 |
|
|
9
|
-
| items[].id | string | 是 | 正十进制 int64 字符串 |
|
|
10
|
-
| items[].expectedRevision | integer | 是 | 已知的当前修订 |
|
|
11
|
-
| items[].confirmedImpactRevision | string | 有引用时 | action=delete 的影响回执 |
|
|
12
|
-
| mode | auto/sync | 否 | 不支持 async |
|
|
13
|
-
| allowPartial | false | 否 | 不支持部分提交 |
|
|
14
|
-
| idempotencyKey | string | 否 | 最多 128 字符 |
|
|
5
|
+
传入单个 id、当前 expectedRevision、可选 dryRun(默认 false)与本次意图的 idempotencyKey。Source 本身必须先变为 disabled,仅停 Stream 不够。创建默认 enabled:先按[影响分析](changes.md)评估 action=disable,再调用 documents.state.update({id,expectedRevision,desiredState:'disabled',dryRun:false,...});取得新 revision 后重新评估 action=delete。每一步只使用对应意图的 confirmedImpactRevision,不能复用 disable 的确认值删除。无依赖时可省确认值,不自动同意依赖影响。此接口不接受旧批量 items。
|
|
15
6
|
|
|
16
|
-
Source
|
|
7
|
+
下方函数要求调用方已完成 Source 禁用,并提供最新 revision 与删除影响确认。
|
|
17
8
|
|
|
18
9
|
```ts
|
|
19
10
|
import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
|
|
@@ -22,18 +13,13 @@ export async function deleteSource(
|
|
|
22
13
|
id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
|
|
23
14
|
intentKey: string, client: Tier0Client = createClient(), confirmedImpactRevision?: string,
|
|
24
15
|
) {
|
|
25
|
-
const receipt = await client.source.delete({
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
...(confirmedImpactRevision === undefined ? {} : { confirmedImpactRevision }) }],
|
|
16
|
+
const receipt = await client.source.documents.delete({
|
|
17
|
+
id, expectedRevision, dryRun: false, idempotencyKey: intentKey,
|
|
18
|
+
...(confirmedImpactRevision === undefined ? {} : { confirmedImpactRevision }),
|
|
29
19
|
});
|
|
30
|
-
if (receipt.data.
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
const archived = receipt.data.results?.find(item => item.id === id && item.status === 'deleted');
|
|
34
|
-
if (!archived) return { state: 'unconfirmed' as const, receipt };
|
|
35
|
-
return { state: 'archived' as const, receipt, archived };
|
|
20
|
+
if (receipt.data.id !== id) return { state: 'unconfirmed' as const, receipt };
|
|
21
|
+
return { state: 'archived' as const, receipt, archived: receipt.data };
|
|
36
22
|
}
|
|
37
23
|
```
|
|
38
24
|
|
|
39
|
-
|
|
25
|
+
提交返回 {id};预检不删除。结果未知时先对账,保留原请求、requestId 和意图键,不自动重试;不能把任意 get 错误当成删除成功。
|
|
@@ -1,42 +1,25 @@
|
|
|
1
1
|
# 协议与连接配置
|
|
2
2
|
|
|
3
|
-
先调用
|
|
4
|
-
|
|
5
|
-
| 配置字段 | 类型 | 必填 | 说明 |
|
|
6
|
-
| --- | --- | --- | --- |
|
|
7
|
-
| role | client / server | HTTP 示例显式指定 | 省略时为 client;Server 使用托管地址和空 options |
|
|
8
|
-
| endpoint | string | 是 | 地址,不内嵌凭据 |
|
|
9
|
-
| options | object | 是 | 协议专用选项 |
|
|
10
|
-
| auth.kind | string | 有认证时 | basic/bearer/apiKey/usernamePassword/oauth2ClientCredentials |
|
|
11
|
-
| auth.credentialRef | string | 有认证时 | 已存在且可用的凭据引用 |
|
|
12
|
-
| tls.caRef / clientIdentityRef | string | 否 | 已存在的 CA/客户端身份引用 |
|
|
13
|
-
|
|
14
|
-
以下只构造文档,不执行创建;实际地址、主题、设备 unitId 由任务上下文提供。需要预览配置问题时使用 documents.create 的 dryRun;正式创建本身执行校验。
|
|
3
|
+
先调用 source.protocols.list({}) 核对目标能力。Cloud / Enterprise 统一使用 SourceDefinition:顶层 role、endpoint、runtimeLocation,以及协议专属 http/sql/mqtt/modbus 等。没有旧 config/options/auth/material 层。HTTP 使用 http-api,OAuth 使用 oauth2,SQL 使用 edge-sql,Modbus TCP 使用 modbus-tcp。角色默认 client;server 使用目标支持的托管 endpoint。
|
|
15
4
|
|
|
16
5
|
```ts
|
|
17
|
-
import { createClient, type
|
|
6
|
+
import { createClient, type SourceDefinition } from '@tier0/sdk-v2';
|
|
18
7
|
|
|
19
8
|
export async function inspectProtocolExamples() {
|
|
20
9
|
const capabilities = await createClient().source.protocols.list({});
|
|
21
|
-
const examples:
|
|
22
|
-
{ name: 'orders-http', protocol: 'http-api',
|
|
23
|
-
|
|
24
|
-
{ name: 'line-plc', protocol: 'modbus',
|
|
25
|
-
|
|
26
|
-
{ name: 'line-mqtt', protocol: 'mqtt',
|
|
27
|
-
|
|
28
|
-
|
|
10
|
+
const examples: SourceDefinition[] = [
|
|
11
|
+
{ name: 'orders-http', protocol: 'http-api', role: 'client',
|
|
12
|
+
endpoint: 'https://orders.example.com', http: { anonymous: true } },
|
|
13
|
+
{ name: 'line-plc', protocol: 'modbus-tcp', role: 'client',
|
|
14
|
+
endpoint: 'tcp://plc.example.com:502', modbus: { unitId: 1 } },
|
|
15
|
+
{ name: 'line-mqtt', protocol: 'mqtt', role: 'client',
|
|
16
|
+
endpoint: 'mqtt://broker.example.com:1883',
|
|
17
|
+
mqtt: { clientId: 'tier0-line-reader', subscriptions: { 'factory/line1/status': 1 } } },
|
|
29
18
|
];
|
|
30
19
|
return { capabilities: capabilities.data, examples };
|
|
31
20
|
}
|
|
32
21
|
```
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
SQL options 包含 tlsMode(verify-full/disable)和 queries(资源名→固定 SQL);脚本不能替换任意 SQL。OPC UA、SAP、Teamcenter 等按能力和服务端校验配置,不从 HTTP 模板生造字段。不要为通过校验自动移除认证或关闭 TLS。
|
|
37
|
-
|
|
38
|
-
HTTP Client 示例不能用于 Server。HTTPServer 通过 `source.documents.*` 配置监听源,固定前缀为 `/ingest/v1/{workspaceId}/{sourceId}`;Stream 注册相对业务路由和处理函数,见 [HTTPServer Stream](../../tier0-sdk-v2-stream/references/http-server.md)。响应时机在 Stream 层处理。
|
|
39
|
-
|
|
40
|
-
Cloud 的角色位于 `config.role`;Enterprise 投影的顶层 `role` 不能直接抄入 Cloud 管理文档。Server 配置见[创建](create.md),以 `http://managed` 和空 options 保存,不从 Client 模板推导。
|
|
23
|
+
http.headers 仅放非秘密业务头,不能塞 Authorization/Cookie;http.parameters 保存命名厂商配置。sql.query 或 sql.queries 选择固定声明查询,不在脚本执行任意 SQL。TLS 公共 CA 使用协议 caCertificate;秘密密钥经 credentials.values 本地预配,已有引用使用 credentialRef。extensions.tls 引用只有目标明确支持时可用,不自动关闭 TLS。
|
|
41
24
|
|
|
42
|
-
|
|
25
|
+
以上仅构造配置,不创建 Source。HTTP Server 使用 http://managed,业务路由在 Stream 注册,见[HTTPServer](../../tier0-sdk-v2-stream/references/http-server.md)。配置与凭据创建见[创建](create.md)。
|
|
@@ -23,12 +23,11 @@ export async function* listSources(client: Tier0Client = createClient()) {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
export async function readSource(id: string, client: Tier0Client = createClient()) {
|
|
26
|
-
const current = await client.source.documents.get({ id });
|
|
27
|
-
|
|
28
|
-
items: [{ id, expectedRevision: current.data.revision }],
|
|
29
|
-
});
|
|
30
|
-
return { current: current.data, observation: observation.data };
|
|
26
|
+
const current = await client.source.documents.get({ id, view: 'summary' });
|
|
27
|
+
return { current: current.data };
|
|
31
28
|
}
|
|
32
29
|
```
|
|
33
30
|
|
|
31
|
+
查询摘要只需一次请求。需要完整配置时显式使用 `documents.get({ id, view: 'full' })`;需要运行观测时使用已有摘要或写回执的 `id/revision` 调用 `observations.get({ items: [{ id, expectedRevision: revision }] })`,无需再次读取详情。
|
|
32
|
+
|
|
34
33
|
ID 不得转 Number;跨页不是稳定快照。权限错误、网络故障与不存在应分别处理,不能把任何 get 失败当成删除成功。probe 可能触达外部系统,不属于单纯读取。
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
| 字段 | 类型 | 必填 | 说明 |
|
|
6
6
|
| --- | --- | --- | --- |
|
|
7
7
|
| id | string | 是 | 已知的 Source ID |
|
|
8
|
-
| patch / document | object /
|
|
8
|
+
| patch / document | object / SourceDefinition | 二选一 | patch 保留未提供的字段;document 完整替换 |
|
|
9
9
|
| expectedRevision | integer | 是 | 已读取或上次提交返回的 revision,原样传回 |
|
|
10
10
|
| confirmedImpactRevision | string | 有引用的连接变更时 | 相同修改意图和修订的 impact 回执;仅改名称、描述无需提供 |
|
|
11
11
|
| dryRun | boolean | 否 | 默认 false 提交;true 仅预检 |
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
|
|
14
14
|
## 示例:一次请求修改名称
|
|
15
15
|
|
|
16
|
-
已有 ID 和 revision 时直接提交 patch。仅改名称、描述无需 impact;连接配置变更在没有任何草稿、活动或历史 Stream 引用时也无需 impact。服务端在同一事务和依赖锁下检查并修改。patch
|
|
16
|
+
已有 ID 和 revision 时直接提交 patch。仅改名称、描述无需 impact;连接配置变更在没有任何草稿、活动或历史 Stream 引用时也无需 impact。服务端在同一事务和依赖锁下检查并修改。patch 中未提供的字段保留原值,协议子对象如果提供则整体替换;完整 document 更新需先取得完整文档并保留未改配置和认证引用。
|
|
17
17
|
|
|
18
18
|
```ts
|
|
19
19
|
import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
|
|
@@ -37,14 +37,14 @@ export async function renameSource(
|
|
|
37
37
|
prepare 收集全部影响分页。在已有授权范围内评估 counts、restrictedCount 和引用后,再调用 commit。不可见引用也要求确认。影响字段说明见[影响分析](changes.md)。
|
|
38
38
|
|
|
39
39
|
```ts
|
|
40
|
-
import { createClient, type Tier0Client, type UnsV2Request, type
|
|
40
|
+
import { createClient, type Tier0Client, type UnsV2Request, type SourceDefinitionPatch } from '@tier0/sdk-v2';
|
|
41
41
|
|
|
42
42
|
export async function prepareSourceConfigUpdate(
|
|
43
43
|
id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
|
|
44
|
-
|
|
44
|
+
patch: SourceDefinitionPatch, client: Tier0Client = createClient(),
|
|
45
45
|
) {
|
|
46
46
|
const intent: UnsV2Request<'sourceImpact'> = {
|
|
47
|
-
id, expectedRevision, action: 'update', patch
|
|
47
|
+
id, expectedRevision, action: 'update', patch,
|
|
48
48
|
};
|
|
49
49
|
const impact = await client.source.impact({ ...intent, offset: 0, size: 200 });
|
|
50
50
|
const references = [...impact.data.references];
|
|
@@ -5,7 +5,7 @@ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和
|
|
|
5
5
|
|
|
6
6
|
# Stream 处理与运行
|
|
7
7
|
|
|
8
|
-
应用代码使用 client.stream;外部连接用 [Source](../tier0-sdk-v2-source/SKILL.md),集合和记录用 [UNS](../tier0-sdk-v2-uns/SKILL.md)。服务端 `createClient()`
|
|
8
|
+
应用代码使用 client.stream;外部连接用 [Source](../tier0-sdk-v2-source/SKILL.md),集合和记录用 [UNS](../tier0-sdk-v2-uns/SKILL.md)。服务端 `createClient()` 读 TIER0_API_HOST / TIER0_API_KEY(平台里由平台注入 App 的 Key),也可显式传 apiHost/apiKey。Tier0 App 的 Key 无权调 Stream 管理接口(Backend 回 403)。
|
|
9
9
|
|
|
10
10
|
## 按任务加载参考
|
|
11
11
|
|
|
@@ -23,7 +23,7 @@ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和
|
|
|
23
23
|
|
|
24
24
|
| 形态 | 完整输入 | 适用入口 |
|
|
25
25
|
| --- | --- | --- |
|
|
26
|
-
| Runtime program | name、script
|
|
26
|
+
| Runtime program | name、script {code,timeoutMs}、sourceBindings | documents.create/update/validate({program}) |
|
|
27
27
|
| 云端原生文档 | name、model、script 对象、sources、entries | documents.create/get/update/validate |
|
|
28
28
|
|
|
29
29
|
程序必须是完整 `module.exports = api => { ... }`,执行器 API 是 api.sources/api.uns/api.stream,与 npm 包的 client.source 不同。Runtime sourceBindings 为 sourceId/configRevision/acquisition;原生 sources 还使用 alias/resources。连接凭据不进脚本或 acquisition,秘密材料由 Source 执行宿主管理,不通过脚本读取、记录或返回。定时入口使用 api.stream.every,不传播旧注册别名;App 请求与消息交互由本包 @tier0/sdk-v2 的 client.streams.requests/messages 提供,不作为 Goja 注册参数。
|
|
@@ -32,7 +32,7 @@ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和
|
|
|
32
32
|
|
|
33
33
|
1. documents.get({id,view:"summary"}) 返回安全摘要,不含可回写脚本;完整编辑使用 documents.get 或上次 documents.create/update 返回的完整文档。保留未修改的 sources/entries/script 字段。
|
|
34
34
|
2. create/update 保存草稿,不自动发布;documents 没有 deploy,云端 program 发布使用 programs.deploy。不能将已保存报告为已运行。
|
|
35
|
-
3. 所有更新/部署/删除携带当前 expectedRevision
|
|
35
|
+
3. 所有更新/部署/删除携带当前 expectedRevision。发布/停用/回滚使用权威 activeVersion 字符串作为 expectedActiveVersion,避免停掉他人刚发布的版本。
|
|
36
36
|
4. versionId 使用已知发布回执的 activeVersion,或从 versions.list 选定,不把 release 序号当 ID。expectedSourceRevision 仅用于恰好一个依赖源,不代表多个源的修订。
|
|
37
37
|
5. resources=[] 是空冻结资源集,不是通配符。写入本身由服务端校验,需要预览时单独 validate;当前云端程序 timeoutMs 上限 30000。
|
|
38
38
|
6. HTTPServer 响应时机在 Stream:普通返回等处理/提交完成;HTTP onRequest 内 await ctx.reply 可先回复一次再继续,仍受超时/并发/权限约束,断线不取消但 shutdown 可取消,不保证崩溃重放。
|
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
| --- | --- | --- | --- |
|
|
7
7
|
| dryRun | boolean | 否 | 默认 false 提交;true 仅预检 |
|
|
8
8
|
| program.name | string | 是 | 1–63 字符 |
|
|
9
|
-
| program.script |
|
|
10
|
-
| program.timeoutMs | integer |
|
|
9
|
+
| program.script | object | 是 | code 为完整 module.exports 程序,timeoutMs 为超时 |
|
|
10
|
+
| program.script.timeoutMs | integer | 是 | 当前云端上限 30000 ms |
|
|
11
11
|
| program.sourceBindings | array | 否 | sourceId、configRevision、acquisition |
|
|
12
12
|
| idempotencyKey | string | 否 | 最多 128 字符,本次创建的固定意图键 |
|
|
13
13
|
|
|
14
14
|
## HTTP Client Source 绑定示例
|
|
15
15
|
|
|
16
|
-
先按[Source 查询](../../tier0-sdk-v2-source/references/read.md)选定真实 HTTP Client Source。脚本的 api.sources 属于平台执行器,与应用中的 client.source 不同。sourceId 保持字符串,configRevision 使用 Source 创建、更新回执或完整查询得到的修订。已有回执时直接传入 source;没有快照时再调用 source.documents.get({id,view:"full"}) 并检查 data.document。省略 `
|
|
16
|
+
先按[Source 查询](../../tier0-sdk-v2-source/references/read.md)选定真实 HTTP Client Source。脚本的 api.sources 属于平台执行器,与应用中的 client.source 不同。sourceId 保持字符串,configRevision 使用 Source 创建、更新回执或完整查询得到的修订。已有回执时直接传入 source;没有快照时再调用 source.documents.get({id,view:"full"}) 并检查 data.document。省略 `role` 时按正式协议目录默认为 client;Server 走入站语义,不能创建为主动请求程序。
|
|
17
17
|
|
|
18
18
|
Source 负责基址和认证,Stream 负责请求的 method/path/query。以下示例与 [Source Bearer 创建](../../tier0-sdk-v2-source/references/create.md#http-client-bearer-凭据)配合:Source endpoint 为 `https://inventory.example.com/api/v1`,凭据使用默认基址绑定;实际请求是 `GET https://inventory.example.com/api/v1/inventory?limit=5000`。已有 Source 的凭据若只绑定精确 URL `/api/v1` 的 GET,不能用于此子路径;不要通过改写请求为 REQUEST 或自动扩大凭据授权来绕过拒绝。
|
|
19
19
|
|
|
@@ -26,14 +26,14 @@ export async function createHttpStream(
|
|
|
26
26
|
if (!collectionId.trim()) throw new Error('需要实际 Collection ID');
|
|
27
27
|
const sourceId = source.id;
|
|
28
28
|
if (!/^[1-9][0-9]*$/.test(sourceId)) throw new Error('Source ID 必须是正十进制字符串');
|
|
29
|
-
if (source.document.protocol !== 'http-api' || 'sourceType' in source.document
|
|
30
|
-
(source.document.
|
|
29
|
+
if (source.document.protocol !== 'http-api' || 'sourceType' in source.document ||
|
|
30
|
+
(source.document.role ?? 'client') !== 'client') {
|
|
31
31
|
throw new Error('此主动请求示例需要 HTTP API Client Source');
|
|
32
32
|
}
|
|
33
33
|
const document: RuntimeStreamDefinition = {
|
|
34
|
-
name,
|
|
34
|
+
name,
|
|
35
35
|
sourceBindings: [{ sourceId, configRevision: source.revision, acquisition: {} }],
|
|
36
|
-
script: [
|
|
36
|
+
script: { timeoutMs: 5000, code: [
|
|
37
37
|
'module.exports = api => {',
|
|
38
38
|
' const upstream = api.sources.use({ id: ' + JSON.stringify(sourceId) + ', resources: [] });',
|
|
39
39
|
' const output = api.uns.use({ collectionId: ' + JSON.stringify(collectionId) + ', access: "write" });',
|
|
@@ -49,7 +49,7 @@ export async function createHttpStream(
|
|
|
49
49
|
' return { acceptedRows: records.length };',
|
|
50
50
|
' });',
|
|
51
51
|
'};',
|
|
52
|
-
].join('\n'),
|
|
52
|
+
].join('\n') },
|
|
53
53
|
};
|
|
54
54
|
const saved = await client.stream.documents.create({
|
|
55
55
|
dryRun: false, program: document, idempotencyKey: intentKey,
|
|
@@ -73,4 +73,18 @@ validate 检查配置、程序和可确定的绑定问题,不执行任意业
|
|
|
73
73
|
|
|
74
74
|
创建结局未知时先按已知 ID 或业务标识核对状态;允许重试时保留原请求与幂等键。
|
|
75
75
|
|
|
76
|
-
原生编辑器形态 `documents.create({dryRun, document})` 的 document 为 name/model/script对象/sources/entries,script 为 `{code,timeoutMs}`,sources 用 alias/sourceId/configRevision/resources/acquisition
|
|
76
|
+
原生编辑器形态 `documents.create({dryRun, document})` 的 document 为 name/model/script对象/sources/entries,script 为 `{code,timeoutMs}`,sources 用 alias/sourceId/configRevision/resources/acquisition。两种入口均使用 script 对象;不接受 script 字符串。
|
|
77
|
+
|
|
78
|
+
远端 Edge 绑定使用 `target: {fleetNodeId, sourceId, configRevision}` 替代同一绑定上的 sourceId/configRevision。fleetNodeId 是发现返回的复合节点字符串,sourceId 是该节点上的原生十进制 ID。服务端验证并创建引用,调用方不拼装 edge:// 引用,也不创建另一种 Source 文档。
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import type { RuntimeStreamDefinition, StreamSourceTarget } from '@tier0/sdk-v2';
|
|
82
|
+
|
|
83
|
+
export function bindApprovedEdgeSource(
|
|
84
|
+
program: RuntimeStreamDefinition, target: StreamSourceTarget,
|
|
85
|
+
): RuntimeStreamDefinition {
|
|
86
|
+
return { ...program, sourceBindings: [{ target, acquisition: {} }] };
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
该函数只构造绑定;脚本仍须使用声明资源并通过目标目录授权。厂商凭据在 Edge 本地预配,target 不携带秘密。配置成功不证明端到端采集完成。
|
|
@@ -4,18 +4,18 @@
|
|
|
4
4
|
| --- | --- | --- |
|
|
5
5
|
| programs.deploy | /openapi/v2/uns/streams/program/deploy | id;dryRun 默认 false,建议 expectedRevision 和发布状态守卫 |
|
|
6
6
|
| programs.rollback | /openapi/v2/uns/streams/program/rollback | id、versionId、dryRun;建议 expectedRevision 和发布状态守卫 |
|
|
7
|
-
| documents.disable | /openapi/v2/uns/streams/documents/disable | id、expectedRevision、
|
|
7
|
+
| documents.disable | /openapi/v2/uns/streams/documents/disable | id、expectedRevision、expectedActiveVersion、dryRun |
|
|
8
8
|
|
|
9
9
|
全部写操作使用各自的 idempotencyKey。expectedSourceRevision 只适用于恰好一个 Source 依赖,且同时保护草稿冻结修订与当前 Source head;多源不能塞入单个修订值。原生文档没有 documents.deploy,当前云端 program 模型发布走 programs.deploy。
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
发布、停用和回滚使用 `expectedActiveVersion` 并发守卫:传服务端回执的十进制字符串 activeVersion,'0' 表示无生效发布。它是不可推算的发布 ID,不是 activeRelease 序号;不再传 expectedReleaseState。服务端在事务内比较当前状态,变化时返回版本冲突;重新读取并决策后才能使用新的业务意图。守卫比较当前值,不记录中间发生的全部切换。
|
|
12
12
|
|
|
13
13
|
发布、停用和回滚需要 uns.stream.manage;相关 Source 访问还受各自授权约束。保存回执中的 revision、发布回执中的 activeVersion 与 activeRelease 分别用于不同目的:
|
|
14
14
|
|
|
15
15
|
| 字段 | 含义与用途 |
|
|
16
16
|
| --- | --- |
|
|
17
17
|
| revision | 草稿修订;传给下次写入的 expectedRevision,冲突时显式处理 |
|
|
18
|
-
| activeVersion |
|
|
18
|
+
| activeVersion | 十进制字符串形式的不可变发布 ID;用于 expectedActiveVersion 与回滚 versionId,不由 activeRelease 序号推算 |
|
|
19
19
|
| activeRelease | 本次事务记录的正整数发布序号;与 runs.list 中的 release 对照;无活跃发布或回执未记录时省略 |
|
|
20
20
|
|
|
21
21
|
programs 回执的 activeVersion:'0' 表示无活跃版本;programs 的 activeRelease 此时省略;documents 的 activeRelease 此时为 0。
|
|
@@ -24,11 +24,12 @@ programs 回执的 activeVersion:'0' 表示无活跃版本;programs 的 active
|
|
|
24
24
|
import { createClient, type Tier0Client, type CloudStreamDocumentView, type CloudStreamStopView } from '@tier0/sdk-v2';
|
|
25
25
|
|
|
26
26
|
export async function deployStream(current: CloudStreamDocumentView, intentKey: string, client: Tier0Client = createClient()) {
|
|
27
|
+
if (typeof current.activeVersion !== 'string' || !/^(0|[1-9][0-9]*)$/.test(current.activeVersion)) throw new Error('缺少权威 activeVersion;读取当前文档后再决定');
|
|
27
28
|
const sources = current.document.sources ?? [];
|
|
28
29
|
const request = {
|
|
29
30
|
id: current.id, expectedRevision: current.revision,
|
|
30
|
-
|
|
31
|
-
...(sources.length === 1 ? { expectedSourceRevision: sources[0]!.configRevision } : {}),
|
|
31
|
+
expectedActiveVersion: current.activeVersion,
|
|
32
|
+
...(sources.length === 1 && !sources[0]!.target ? { expectedSourceRevision: sources[0]!.configRevision } : {}),
|
|
32
33
|
};
|
|
33
34
|
const receipt = await client.stream.programs.deploy({
|
|
34
35
|
...request, dryRun: false, idempotencyKey: intentKey,
|
|
@@ -44,22 +45,22 @@ export async function deployStream(current: CloudStreamDocumentView, intentKey:
|
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
export async function disableStream(
|
|
47
|
-
current: Pick<CloudStreamStopView, 'id' | 'revision' | '
|
|
48
|
+
current: Pick<CloudStreamStopView, 'id' | 'revision' | 'activeVersion'>,
|
|
48
49
|
intentKey: string, client: Tier0Client = createClient(),
|
|
49
50
|
) {
|
|
50
|
-
if (
|
|
51
|
+
if (typeof current.activeVersion !== 'string' || !/^[1-9][0-9]*$/.test(current.activeVersion)) throw new Error('没有已确认的活跃版本可停用');
|
|
51
52
|
const receipt = await client.stream.documents.disable({
|
|
52
|
-
id: current.id, expectedRevision: current.revision,
|
|
53
|
+
id: current.id, expectedRevision: current.revision, expectedActiveVersion: current.activeVersion,
|
|
53
54
|
dryRun: false, idempotencyKey: intentKey,
|
|
54
55
|
});
|
|
55
|
-
if (!('id' in receipt.data) ||
|
|
56
|
+
if (!('id' in receipt.data) || receipt.data.activeVersion !== '0') {
|
|
56
57
|
throw new Error('未返回停用回执');
|
|
57
58
|
}
|
|
58
59
|
return { receipt, current: receipt.data };
|
|
59
60
|
}
|
|
60
61
|
```
|
|
61
62
|
|
|
62
|
-
将创建或更新回执的 current 传给 deployStream,只发一次发布请求。只有手上没有草稿快照时才先 documents.get。使用 [按发布号查询运行记录](read.md#观察本次发布) 才能观察这次发布,观察窗口汇总不能证明该版本运行。发布成功不表示外部连接健康或执行成功。停用使用已确认的 id/revision/
|
|
63
|
+
将创建或更新回执的 current 传给 deployStream,只发一次发布请求。只有手上没有草稿快照时才先 documents.get。使用 [按发布号查询运行记录](read.md#观察本次发布) 才能观察这次发布,观察窗口汇总不能证明该版本运行。发布成功不表示外部连接健康或执行成功。停用使用已确认的 id/revision/activeVersion(可来自发布回执),返回的 current 可直接用于删除;不需要前后各 get。停用保留草稿。仅修改草稿的任务不额外发布/停用。
|
|
63
64
|
|
|
64
65
|
## 回滚到明确版本
|
|
65
66
|
|
|
@@ -67,12 +68,13 @@ export async function disableStream(
|
|
|
67
68
|
import { createClient, type Tier0Client, type CloudStreamStopView } from '@tier0/sdk-v2';
|
|
68
69
|
|
|
69
70
|
export async function rollbackStream(
|
|
70
|
-
current: Pick<CloudStreamStopView, 'id' | 'revision' | '
|
|
71
|
+
current: Pick<CloudStreamStopView, 'id' | 'revision' | 'activeVersion'>, versionId: string, intentKey: string, client: Tier0Client = createClient(),
|
|
71
72
|
) {
|
|
72
73
|
// versionId 使用已知发布回执的 activeVersion,或从 programs.versions.list 选定。
|
|
74
|
+
if (typeof current.activeVersion !== 'string' || !/^(0|[1-9][0-9]*)$/.test(current.activeVersion)) throw new Error('缺少权威 activeVersion;读取当前文档后再决定');
|
|
73
75
|
return client.stream.programs.rollback({
|
|
74
76
|
id: current.id, versionId, expectedRevision: current.revision,
|
|
75
|
-
|
|
77
|
+
expectedActiveVersion: current.activeVersion,
|
|
76
78
|
dryRun: false, idempotencyKey: intentKey,
|
|
77
79
|
});
|
|
78
80
|
}
|