@tier0/sdk-v2 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/README.md +29 -12
  2. package/dist/cjs/capabilities.js +2 -2
  3. package/dist/cjs/capabilities.js.map +1 -1
  4. package/dist/cjs/client.d.ts +284 -374
  5. package/dist/cjs/cloud-transport.js +6 -1
  6. package/dist/cjs/cloud-transport.js.map +1 -1
  7. package/dist/cjs/controls.d.ts +19 -7
  8. package/dist/cjs/controls.js +37 -34
  9. package/dist/cjs/controls.js.map +1 -1
  10. package/dist/cjs/data/bootstrap.js +3 -2
  11. package/dist/cjs/data/bootstrap.js.map +1 -1
  12. package/dist/cjs/data/collection.d.ts +64 -2
  13. package/dist/cjs/data/collection.js +15 -11
  14. package/dist/cjs/data/collection.js.map +1 -1
  15. package/dist/cjs/data/index.d.ts +1 -1
  16. package/dist/cjs/data/index.js.map +1 -1
  17. package/dist/cjs/files.d.ts +9 -9
  18. package/dist/cjs/mq/broker.d.ts +1 -1
  19. package/dist/cjs/mq/broker.js +1 -1
  20. package/dist/cjs/mq/broker.js.map +1 -1
  21. package/dist/cjs/mq/types.d.ts +1 -1
  22. package/dist/cjs/mq/types.js.map +1 -1
  23. package/dist/cjs/openapi/api.generated.d.ts +417 -541
  24. package/dist/cjs/openapi/api.generated.js +292 -377
  25. package/dist/cjs/openapi/api.generated.js.map +1 -1
  26. package/dist/cjs/openapi/client.js +1 -1
  27. package/dist/cjs/openapi/client.js.map +1 -1
  28. package/dist/cjs/openapi/codecs.generated.d.ts +394 -652
  29. package/dist/cjs/openapi/codecs.generated.js +2 -2
  30. package/dist/cjs/openapi/codecs.generated.js.map +1 -1
  31. package/dist/cjs/openapi/types.generated.d.ts +697 -906
  32. package/dist/cjs/openapi/types.generated.js.map +1 -1
  33. package/dist/cjs/source.d.ts +0 -7
  34. package/dist/cjs/source.js +1 -3
  35. package/dist/cjs/source.js.map +1 -1
  36. package/dist/cjs/stream.d.ts +0 -5
  37. package/dist/cjs/stream.js +3 -4
  38. package/dist/cjs/stream.js.map +1 -1
  39. package/dist/cjs/uns-v2/codec.js +1 -1
  40. package/dist/cjs/uns-v2/codec.js.map +1 -1
  41. package/dist/cjs/uns-v2/generated.d.ts +4741 -13453
  42. package/dist/cjs/uns-v2/generated.js +12 -33
  43. package/dist/cjs/uns-v2/generated.js.map +1 -1
  44. package/dist/esm/capabilities.js +2 -2
  45. package/dist/esm/capabilities.js.map +1 -1
  46. package/dist/esm/client.d.ts +284 -374
  47. package/dist/esm/cloud-transport.js +6 -1
  48. package/dist/esm/cloud-transport.js.map +1 -1
  49. package/dist/esm/controls.d.ts +19 -7
  50. package/dist/esm/controls.js +38 -35
  51. package/dist/esm/controls.js.map +1 -1
  52. package/dist/esm/data/bootstrap.js +4 -3
  53. package/dist/esm/data/bootstrap.js.map +1 -1
  54. package/dist/esm/data/collection.d.ts +64 -2
  55. package/dist/esm/data/collection.js +15 -12
  56. package/dist/esm/data/collection.js.map +1 -1
  57. package/dist/esm/data/index.d.ts +1 -1
  58. package/dist/esm/data/index.js.map +1 -1
  59. package/dist/esm/files.d.ts +9 -9
  60. package/dist/esm/mq/broker.d.ts +1 -1
  61. package/dist/esm/mq/broker.js +1 -1
  62. package/dist/esm/mq/broker.js.map +1 -1
  63. package/dist/esm/mq/types.d.ts +1 -1
  64. package/dist/esm/mq/types.js.map +1 -1
  65. package/dist/esm/openapi/api.generated.d.ts +417 -541
  66. package/dist/esm/openapi/api.generated.js +292 -377
  67. package/dist/esm/openapi/api.generated.js.map +1 -1
  68. package/dist/esm/openapi/client.js +1 -1
  69. package/dist/esm/openapi/client.js.map +1 -1
  70. package/dist/esm/openapi/codecs.generated.d.ts +394 -652
  71. package/dist/esm/openapi/codecs.generated.js +1 -1
  72. package/dist/esm/openapi/codecs.generated.js.map +1 -1
  73. package/dist/esm/openapi/types.generated.d.ts +697 -906
  74. package/dist/esm/openapi/types.generated.js.map +1 -1
  75. package/dist/esm/source.d.ts +0 -7
  76. package/dist/esm/source.js +1 -3
  77. package/dist/esm/source.js.map +1 -1
  78. package/dist/esm/stream.d.ts +0 -5
  79. package/dist/esm/stream.js +3 -4
  80. package/dist/esm/stream.js.map +1 -1
  81. package/dist/esm/uns-v2/codec.js +2 -2
  82. package/dist/esm/uns-v2/codec.js.map +1 -1
  83. package/dist/esm/uns-v2/generated.d.ts +4741 -13453
  84. package/dist/esm/uns-v2/generated.js +12 -33
  85. package/dist/esm/uns-v2/generated.js.map +1 -1
  86. package/package.json +17 -5
  87. package/skills/tier0-sdk-v2/SKILL.md +5 -3
  88. package/skills/tier0-sdk-v2/tier0-sdk-v2-agent/SKILL.md +4 -4
  89. package/skills/tier0-sdk-v2/tier0-sdk-v2-controls/SKILL.md +3 -3
  90. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +17 -1
  91. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/delete.md +1 -1
  92. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/url.md +1 -1
  93. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +1 -1
  94. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/platform-members.md +1 -1
  95. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/get.md +1 -1
  96. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +1 -1
  97. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +5 -5
  98. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +4 -4
  99. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +3 -6
  100. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +10 -18
  101. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +2 -2
  102. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/state.md +9 -10
  103. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +39 -21
  104. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +7 -7
  105. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +13 -13
  106. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +21 -11
  107. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/lifecycle.md +1 -1
  108. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +25 -5
  109. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/update.md +3 -5
  110. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/info.md +1 -1
  111. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/whoami.md +1 -1
  112. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +3 -3
  113. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +14 -9
  114. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +5 -5
  115. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/namespace.md +4 -4
  116. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +8 -7
  117. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/restore.md +2 -2
  118. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/update.md +4 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tier0/sdk-v2",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "Tier0 Cloud new-architecture SDK for TypeScript and JavaScript",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -58,12 +58,24 @@
58
58
  }
59
59
  },
60
60
  "./source": {
61
- "import": { "types": "./dist/esm/source.d.ts", "default": "./dist/esm/source.js" },
62
- "require": { "types": "./dist/cjs/source.d.ts", "default": "./dist/cjs/source.js" }
61
+ "import": {
62
+ "types": "./dist/esm/source.d.ts",
63
+ "default": "./dist/esm/source.js"
64
+ },
65
+ "require": {
66
+ "types": "./dist/cjs/source.d.ts",
67
+ "default": "./dist/cjs/source.js"
68
+ }
63
69
  },
64
70
  "./stream": {
65
- "import": { "types": "./dist/esm/stream.d.ts", "default": "./dist/esm/stream.js" },
66
- "require": { "types": "./dist/cjs/stream.d.ts", "default": "./dist/cjs/stream.js" }
71
+ "import": {
72
+ "types": "./dist/esm/stream.d.ts",
73
+ "default": "./dist/esm/stream.js"
74
+ },
75
+ "require": {
76
+ "types": "./dist/cjs/stream.d.ts",
77
+ "default": "./dist/cjs/stream.js"
78
+ }
67
79
  },
68
80
  "./files": {
69
81
  "import": {
@@ -5,7 +5,7 @@ description: 使用 @tier0/sdk-v2 开发或迁移 Tier0 云端 TypeScript/JavaSc
5
5
 
6
6
  # Tier0 SDK v2 应用集成
7
7
 
8
- 面向应用代码编写;运行时为 Node.js 20.19+。独立包 `@tier0/sdk-v2` 的当前源码版本为 0.2.0(UNS v2 契约 5.0.0),是否可从 npm 安装须检查实际发布状态;未发布时安装仓库构建的 tarball。不要改回旧包或旧 Flow API。
8
+ 面向应用代码编写;运行时为 Node.js 20.19+。独立包 `@tier0/sdk-v2` 的版本以 package.json 为准(UNS v2 契约 5.0.0),是否可从 npm 安装须检查实际发布状态;未发布时安装仓库构建的 tarball。新参数还需要目标环境部署对应后端,不能只凭 SDK 方法存在判断可用。不要改回旧包或旧 Flow API。
9
9
 
10
10
  ## 选择业务入口
11
11
 
@@ -46,7 +46,7 @@ export async function inspectConnection() {
46
46
  | 入口 | 成功值 | 失败类型 |
47
47
  | --- | --- | --- |
48
48
  | Source、Stream、UNS | 完整 `{ code, msg, requestId, data }` | `UnsV2Error` / `UnsV2OutcomeUnknownError` |
49
- | 普通 v1,如 system、members、agent、mqttAuth | 解包后的 `data` | `ApiError` / `TransportError` |
49
+ | 平台 v2,如 system、members、agent、mqttAuth | 解包后的 `data` | `ApiError` / `TransportError` |
50
50
  | notifications | 直接对象,如 `messageId`、`status` | `ApiError` |
51
51
  | controls、capabilities | 专属响应对象 | `ControlError` / `CapabilityError` |
52
52
 
@@ -56,7 +56,7 @@ export async function inspectConnection() {
56
56
 
57
57
  ## 从首版入口迁移
58
58
 
59
- - `client.uns.sourceList(body)` → `client.source.list(body)`。
59
+ - `client.uns.sourceList(body)` → `client.source.documents.list(body)`。
60
60
  - `client.uns.sourceDocumentGet(body)` → `client.source.documents.get(body)`。
61
61
  - `client.uns.streamProgramDeploy(body)` → `client.stream.programs.deploy(body)`。
62
62
  - `client.uns.streamDocumentValidate(body)` → `client.stream.documents.validate(body)`。
@@ -64,3 +64,5 @@ export async function inspectConnection() {
64
64
  - 低层 `createUnsV2Client` 保留完整生成契约,供契约工具使用;业务主入口不再把 Source/Stream/Control 混入 `client.uns`。
65
65
 
66
66
  React/Vue 示例与验签见 [集成参考](references/integration.md)。完成接入时验证目标入口、真实身份、响应解包和错误分支;SDK 本地测试通过不代表环境联调完成。
67
+
68
+ 公开 HTTP 入口统一为 `/openapi/v2`。旧的重复操作已退役,不生成兼容调用或回退。Source 配置用 documents.*,Stream 草稿用 documents.*、发布用 programs.deploy;App 数据层仍提供 insertMany/findOneAnd*/distinct 等便捷方法。历史旧写结果未知时先核对业务状态,不能转换路由后盲目重放。
@@ -5,7 +5,7 @@ description: 使用 @tier0/sdk-v2 的 client.agent 查询和管理 Agent 作业
5
5
 
6
6
  # Agent 作业与结果
7
7
 
8
- Agent 是平台应用能力,区别于 Stream 数据处理程序。使用服务端 client.agent;本领域普通 v1 响应已解包,直接读取 list/job/run/result 等字段。
8
+ Agent 是平台应用能力,区别于 Stream 数据处理程序。使用服务端 client.agent;本领域平台 v2 响应已解包,直接读取 list/job/run/result 等字段。
9
9
 
10
10
  ## 入口选择
11
11
 
@@ -18,10 +18,8 @@ Agent 是平台应用能力,区别于 Stream 数据处理程序。使用服务
18
18
  | cards | list/get/update/delete,操作画布卡片 |
19
19
  | canvases | list,查找画布 |
20
20
  | library | list/get/create/update/delete,复用卡片定义 |
21
- | nodes | searchSemantic/indexSync,语义搜索与索引同步 |
22
- | relations | list/teach,读取和写入数据关系 |
23
21
 
24
- dispatch、trigger、indexSync、teach 都有副作用,不能在普通查询流程中悄悄执行。
22
+ dispatch、trigger 都有副作用,不能在普通查询流程中悄悄执行。
25
23
 
26
24
  ## 查询作业与运行
27
25
 
@@ -71,3 +69,5 @@ result.create 的 operationId 由调用方持有;保存超时后可用 `result
71
69
  cards.update 要带读取时的完整 expectedCardSpec;library.update 要带完整 expectedItem 快照。409 表示内容已变化,应重新读取并合并用户意图,不能自动覆盖。具体示例见 [结果与卡片编辑](references/results.md)。
72
70
 
73
71
  结果附件/图片使用 [文件 Skill](../tier0-sdk-v2-files/SKILL.md) 的持久化 filePath,不保存签名 URL 作为长期资源。失败保留 ApiError.status/code/errorCode;写入 outcomeUnknown 时先查询对应资源,不自动重发。
72
+
73
+ 旧 Namespace 节点的语义索引和 path 关系接口未纳入 v2,不再提供 nodes/relations 方法。
@@ -5,7 +5,7 @@ description: 使用 @tier0/sdk-v2 发现、描述和调用 Tier0 Control 业务
5
5
 
6
6
  # Control 契约调用
7
7
 
8
- Control 是已发布的业务调用入口;它可由 Stream 提供,但调用方不选择内部 streamId、entryId 或部署版本。使用服务端 client.controls,不重建旧 Flow 调用。
8
+ Control 是已发布的业务调用入口;它可由 Stream 提供,但调用方不选择内部 streamId、entryId 或部署版本。使用服务端 client.controls,实际调用 `/openapi/v2/uns/controls/discover|describe|invoke`,不重建旧 Flow 调用。
9
9
 
10
10
  ## 发现和读取契约
11
11
 
@@ -52,12 +52,12 @@ export async function invokePreparedControl(code: string, input: ControlJSON, in
52
52
  }
53
53
  ```
54
54
 
55
- 幂等键非空、不能有首尾空白,最多 128 UTF-8 字节。输入只能是普通 JSON,不传 Date、函数、循环对象、bigint、NaN/Infinity。业务 input 内名为 timeoutMs/streamId 的字段仍只是业务输入;不能借它覆盖服务端绑定、版本或执行超时。
55
+ 幂等键非空、不能有首尾空白,最多 128 UTF-8 字节。输入使用 JSON;需要保留精确数字时可用 UnsV2RawNumber,不传 Date、函数、循环对象、bigint、NaN/Infinity。业务 input 内名为 timeoutMs/streamId 的字段仍只是业务输入;不能借它覆盖服务端绑定、版本或执行超时。
56
56
 
57
57
  ## 返回与失败
58
58
 
59
59
  成功值为直接对象:code(Control 标识)、contractVersion、result、runID、status、replayed。这里的 code 不是 HTTP 业务状态码;replayed 只有服务端明确报告重放时才为 true。
60
60
 
61
- `ControlError` 含 status/errorCode/runID 等信息,SDK 不自动重试。`ControlResultUnknownError` 表示执行可能已经发生,包括调用响应无法证明最终结果的情况;按业务或平台运行记录对账。本 SDK 未提供通用 `controls.getRun`,不要虚构方法。若业务明确允许重放,保留原 key 和原输入,不能换新 key 重做。
61
+ `ControlError` 含 status/errorCode/runID 与 requestId/execution/retry 等信息,SDK 不自动重试。`ControlResultUnknownError` 表示执行可能已经发生,包括调用响应无法证明最终结果的情况;按业务或平台运行记录对账。本 SDK 未提供通用 `controls.getRun`,不要虚构方法。若业务明确允许重放,保留原 key 和原输入,不能换新 key 重做。
62
62
 
63
63
  `client.capabilities.discover()` 的 control.invoke.v1 就绪只是入口条件,不等于有权调用每一个 Control。执行源发布和内部绑定管理请使用 [Stream Skill](../tier0-sdk-v2-stream/SKILL.md)。
@@ -41,6 +41,16 @@ export async function releasedBadge() {
41
41
  export async function addNote(id: string, notes: string, revision: number) {
42
42
  return orders.updateOne({ _id: id }, { $set: { notes } }, { expectedRevision: revision });
43
43
  }
44
+
45
+ export async function createWorkOrder(
46
+ code: string, line: { id: string; name: string }, targetQty: number, intentKey: string,
47
+ ) {
48
+ const { value } = await orders.insertOne({ code, status: 'DRAFT', line, targetQty }, {
49
+ returnDocument: 'after', projection: { code: 1, 'line.name': 1 }, idempotencyKey: intentKey,
50
+ });
51
+ // 投影后的业务字段可能缺失,元信息仍必有;revision 可交给下一次更新。
52
+ return { id: value._id, revision: value._meta.revision, code: value.code, lineName: value.line?.name };
53
+ }
44
54
  ```
45
55
 
46
56
  ## 一个页面一次请求:`data.queryBatch`
@@ -88,13 +98,19 @@ export async function ordersScreen(page: number, selectedId: string) {
88
98
 
89
99
  | 写入 | 说明 |
90
100
  | --- | --- |
91
- | `insertOne(doc)`、`insertMany(docs)` | 可带 `_id`;`insertMany` 最多 200 条、原子 |
101
+ | `insertOne(doc, options)`、`insertMany(docs)` | 可带 `_id`;单条默认返回 `{ insertedId }`,`returnDocument:'after'` 同次写入返回 `{ insertedId, value }`;`insertMany` 最多 200 条、原子 |
92
102
  | `updateOne` / `updateMany` / `replaceOne` | 更新用操作符(`$set` `$inc` `$push` `$unset`…);`replaceOne` 会丢掉其他代码版本写入的字段 |
93
103
  | `deleteOne` / `deleteMany` | 软删除,App Key 需要 `uns.delete` |
94
104
  | `findOneAndUpdate` / `findOneAndReplace` / `findOneAndDelete` | 原子读改写,默认返回更新后的文档 |
95
105
  | `bulkWrite(ops)` | `insertOne` / `updateOne` / `replaceOne` / `deleteOne` 混合,最多 200 项、原子 |
96
106
  | `data.transact(steps)` | 跨集合原子写,见 [一致性](consistency.md) |
97
107
 
108
+ 新建后需要显示保存结果或继续按版本编辑时,使用 `insertOne(doc, { returnDocument: 'after', idempotencyKey })`。`value` 与查询结果一样是 `{ _id, ...业务字段, _meta }`,包含服务端生成的数据和 `_meta.revision`,无需额外查询。返回快照需要当前读取权限;`projection` 只能与 `after` 一起提供。重放返回当次创建的快照,不能当成记录当前最新版本;之后的版本冲突仍需显式读取并处理。
109
+
110
+ 带 `projection` 时,返回类型将业务字段递归标为可选,包括嵌套对象和数组元素的字段;读取前需判断是否存在。`_id` 和 `_meta` 仍然必有。不带 `projection` 的 `after` 保持完整文档类型。
111
+
112
+ 上面的 createWorkOrder 在一次记录写入中取得投影和修订;首次使用集合时仍会先 ensure 声明,不代表首次调用总共只有一次 HTTP。用于跨调用恢复时保存 intentKey,并重发同一创建意图;不要把原来的默认返回改为 after 来补取数据。读取权限在首次提交和历史重放时都检查,具体边界见 [UNS 创建快照](../../tier0-sdk-v2-uns/references/create.md)。
113
+
98
114
  ## 批量与原子性
99
115
 
100
116
  | 调用 | 上限 | 原子 |
@@ -1,6 +1,6 @@
1
1
  # 删除文件
2
2
 
3
- 方法:`files.delete({filePath}, {signal}?)`;POST /openapi/v1/assets/files/delete。
3
+ 方法:`files.delete({filePath}, {signal}?)`;POST /openapi/v2/assets/files/delete。
4
4
 
5
5
  | 字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
@@ -1,6 +1,6 @@
1
1
  # 获取文件访问地址
2
2
 
3
- 方法:`files.url({filePath,expiredSec?,responseContentDisposition?}, {signal}?)`;GET /openapi/v1/assets/files/url。
3
+ 方法:`files.url({filePath,expiredSec?,responseContentDisposition?}, {signal}?)`;GET /openapi/v2/assets/files/url。
4
4
 
5
5
  | 字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
@@ -1,6 +1,6 @@
1
1
  # App 可用成员
2
2
 
3
- 方法:`members.listApp(body)`;POST /openapi/v1/apps/access-members/list。返回能使用该 App 线上版本的有效成员。`appId` 必填且由调用方显式传入,SDK 不隐式读取 `APP_ID`;查询当前 App 时传 `getCurrentAppId()`。接口只接受 API Key,登录会话不能调用;绑定 App 的凭证只能查自己的 appId,查其他 App 返回 403。
3
+ 方法:`members.listApp(body)`;POST /openapi/v2/apps/access-members/list。返回能使用该 App 线上版本的有效成员。`appId` 必填且由调用方显式传入,SDK 不隐式读取 `APP_ID`;查询当前 App 时传 `getCurrentAppId()`。接口只接受 API Key,登录会话不能调用;绑定 App 的凭证只能查自己的 appId,查其他 App 返回 403。
4
4
 
5
5
  | 字段 | 类型 | 说明 |
6
6
  | --- | --- | --- |
@@ -1,6 +1,6 @@
1
1
  # Workspace 成员查询与选择
2
2
 
3
- 方法:`members.listWorkspace(body)`;POST /openapi/v1/platform/getMembers。查询当前 Key 所属 Workspace;云端需要 uns:read。通知读写权限不自动包含成员查询。
3
+ 方法:`members.listWorkspace(body)`;POST /openapi/v2/platform/getMembers。查询当前 Key 所属 Workspace;云端需要 uns:read。通知读写权限不自动包含成员查询。
4
4
 
5
5
  | 字段 | 类型 | 说明 |
6
6
  | --- | --- | --- |
@@ -1,6 +1,6 @@
1
1
  # 查询通知投递状态
2
2
 
3
- 方法:`notifications.get({messageId})`;POST /openapi/v1/notifications/get。需要 notifications:read,与 send 权限独立;仅查询当前发送 Key 可见的消息。
3
+ 方法:`notifications.get({messageId})`;POST /openapi/v2/notifications/get。需要 notifications:read,与 send 权限独立;仅查询当前发送 Key 可见的消息。
4
4
 
5
5
  | 参数/结果 | 类型 | 说明 |
6
6
  | --- | --- | --- |
@@ -1,6 +1,6 @@
1
1
  # 发送通知
2
2
 
3
- 方法:`notifications.send(body)`;POST /openapi/v1/notifications/send。需要 notifications:send;收件人为当前 Workspace 内可用的成员,按[成员查询](../../tier0-sdk-v2-members/references/platform-members.md)解析。
3
+ 方法:`notifications.send(body)`;POST /openapi/v2/notifications/send。需要 notifications:send;收件人为当前 Workspace 内可用的成员,按[成员查询](../../tier0-sdk-v2-members/references/platform-members.md)解析。
4
4
 
5
5
  | 字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
@@ -23,16 +23,16 @@ Source 维护连接配置、认证引用与源状态。脚本处理用 [Stream](
23
23
 
24
24
  ## 核心约束
25
25
 
26
- 1. 原生文档 `{name,protocol,config}` 使用 documents.*;通用投影使用 source.list/get/create/update。http 原生协议与 http-api adapter 不可互换。
27
- 2. 编辑前读取完整 documents.get;安全列表摘要不能无损回写。原生 ID 是十进制字符串,revision 原样传递,不转 Number。
28
- 3. 现有 Source 修改、启停、删除都要 expectedRevision + confirmedImpactRevision。先形成精确意图,再读取全部影响分页;回执不可合成、跨意图复用或静默刷新。
26
+ 1. Source 配置统一使用 documents.*,原生文档为 `{name,protocol,config}`。http 原生协议与 http-api adapter 不可互换。
27
+ 2. 已有 ID 和 revision 时优先用 documents.update 的 patch,避免额外 get;完整替换 document 前读取完整文档,安全列表摘要不能无损回写。原生 ID 是十进制字符串,revision 原样传递,不转 Number。
28
+ 3. 现有 Source 修改、启停、删除都要 expectedRevision。没有任何 Stream 引用时可直接提交;有草稿、活动、历史或不可见引用时仍需 confirmedImpactRevision。先形成精确意图,再读取全部影响分页;回执不可合成、跨意图复用或静默刷新。提供的回执始终严格校验,不自动获取并同意影响。
29
29
  4. 配置中保留认证/TLS 引用,不写明文秘密;HTTP 新凭据走创建专用 credentials。
30
30
  5. desiredState 不代表实际健康,保存配置不代表 Stream 已切换至新 configRevision。运行状态另行读取。
31
31
 
32
32
  ## 返回值与异常
33
33
 
34
- 所有调用返回完整 code/msg/requestId/data。documents.create/update 的预检返回 validated/sideEffects,提交返回完整 Source view;批量状态/删除返回 Outcome。只有 committed 且无项错误才可报告提交成功;accepted/jobId 继续查询作业。
34
+ 所有调用返回完整 code/msg/requestId/data。documents.create/update 的预检返回 validated/sideEffects,提交返回完整 Source view,可直接使用其中的文档和 revision,无需额外 get;批量状态/删除返回 Outcome。只有 committed 且无项错误才可报告提交成功;accepted/jobId 继续查询作业。预检按需使用,不是每次提交的必经步骤。
35
35
 
36
- 需要查看历史用 source.history({id,beforeRevision,size}),按 nextBeforeRevision 继续;探测用 source.probe,其外部系统访问应属于当前任务。source.connection.update 属于现有源变更,同样遵守影响确认契约,不能作为绕过文档校验的入口。
36
+ 需要查看历史用 source.history({id,beforeRevision,size}),按 nextBeforeRevision 继续;探测用 source.probe,其外部系统访问应属于当前任务。连接配置修改使用 documents.update,遵守同一影响确认契约。
37
37
 
38
38
  UnsV2Error 表示已知拒绝;UnsV2OutcomeUnknownError 表示可能已写入。保存 requestId、原请求和意图键,先查详情/历史/作业对账。取消等待不撤销服务端操作;SDK 不自动重试。权限不足不能解释为资源不存在。
@@ -4,9 +4,9 @@
4
4
 
5
5
  | 字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
7
- | id / expectedRevision | string / integer | 是 | 当前 ID 和读取到的修订 |
7
+ | id / expectedRevision | string / integer | 是 | 当前 ID 和最近写回执或读取取得的修订 |
8
8
  | action | update/enable/disable/delete | 是 | 精确变更类型 |
9
- | document | CloudSourceDocument | 更新时 | 完整拟提交文档 |
9
+ | patch / document | CloudSourceDocumentPatch / CloudSourceDocument | 更新时二选一 | 与随后提交完全相同的补丁或完整文档;其他 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: Pick<UnsV2Request<'sourceImpact'>, 'id' | 'expectedRevision' | 'action' | 'document'>,
17
+ intent: Pick<UnsV2Request<'sourceImpact'>, 'id' | 'expectedRevision' | 'action' | 'patch' | 'document'>,
18
18
  client: Tier0Client = createClient(),
19
19
  ) {
20
20
  const first = await client.source.impact({ ...intent, offset: 0, size: 200 });
@@ -37,4 +37,4 @@ export async function collectSourceImpact(
37
37
 
38
38
  data:impactRevision、sourceID/sourceRevision、action、counts(draft/activeRelease/historicalRelease)、restrictedCount、references、nextOffset、expiresAt。nextOffset=0 结束;complete=1 表示计算完成,不表示首页有全部引用。
39
39
 
40
- 确认值绑定身份、修订、精确意图,不能合成或自动刷新。评估 counts 和 restrictedCount;有受限引用时不能说“无影响”。Source 更新不会自动替换 Stream 冻结修订。已有明确操作授权时不重复索要确认;影响分析本身不授予额外操作权限。
40
+ 确认值绑定身份、修订、精确意图,不能合成或自动刷新。分析时用 patch,提交时就沿用该 patch;不要另行补齐为 document 或更改字段。评估 counts 和 restrictedCount;有受限引用时不能说“无影响”。Source 更新不会自动替换 Stream 冻结修订。已有明确操作授权时不重复索要确认;影响分析本身不授予额外操作权限。没有任何引用时可直接变更,见 [修改](update.md),不必先执行本流程。
@@ -26,18 +26,15 @@ export async function createHttpSource(
26
26
  name, protocol: 'http', description: '订单系统 HTTP 接入',
27
27
  config: { configVersion: 2, endpoint, options: {} },
28
28
  };
29
- const preview = await client.source.documents.create({ dryRun: true, document });
30
- if (!('validated' in preview.data) || !preview.data.validated) throw new Error('Source 预检未通过');
31
29
  const saved = await client.source.documents.create({
32
30
  dryRun: false, document, idempotencyKey: intentKey,
33
31
  });
34
32
  if (!('id' in saved.data)) throw new Error('未返回已保存的 Source');
35
- const current = await client.source.documents.get({ id: saved.data.id });
36
- return { receipt: saved, current: current.data };
33
+ return { receipt: saved, current: saved.data };
37
34
  }
38
35
  ```
39
36
 
40
- 提交返回 data:id、revision、document、desiredState、runtimeState、health、createdAt、updatedAt;预检返回 `{ validated: true, sideEffects: false }`,没有 ID。ID 原样保留十进制字符串。
37
+ 一次提交即可返回完整 data:id、revision、document、desiredState、runtimeState、health、createdAt、updatedAt,无需另行 get。需要单独预检时可先传 `dryRun: true`,返回 `{ validated: true, sideEffects: false }`,没有 ID。预检不保留提交条件;实际保存仍会校验。ID 原样保留十进制字符串。
41
38
 
42
39
  ## HTTP Bearer 凭据
43
40
 
@@ -56,7 +53,7 @@ export async function createAuthenticatedHttpSource(
56
53
  credentials: { method: 'GET', kind: 'bearer', material: { token } },
57
54
  });
58
55
  if (!('id' in saved.data)) throw new Error('未返回 Source ID');
59
- return client.source.documents.get({ id: saved.data.id });
56
+ return { receipt: saved, current: saved.data };
60
57
  }
61
58
  ```
62
59
 
@@ -7,41 +7,33 @@
7
7
  | dryRun | boolean | 是 | true 预检;false 提交 |
8
8
  | items | array | 是 | 1–200 项 |
9
9
  | items[].id | string | 是 | 正十进制 int64 字符串 |
10
- | items[].expectedRevision | integer | 是 | get 返回的修订 |
11
- | items[].confirmedImpactRevision | string | 是 | action=delete 的影响回执 |
10
+ | items[].expectedRevision | integer | 是 | 已知的当前修订 |
11
+ | items[].confirmedImpactRevision | string | 有引用时 | action=delete 的影响回执 |
12
12
  | mode | auto/sync | 否 | 不支持 async |
13
13
  | allowPartial | false | 否 | 不支持部分提交 |
14
14
  | idempotencyKey | string | 否 | 最多 128 字符 |
15
15
 
16
- 先 get → impact(action=delete) → [遍历并评估影响](changes.md)。存在 Stream 依赖时遵守服务端保护,不自动删除依赖流。
16
+ Source 必须已停用。没有任何 Stream 引用时,直接用已有 ID 和 revision 提交;有引用时先 impact(action=delete) 并[遍历和评估影响](changes.md),再显式传入回执。服务端在同一事务中检查依赖和修订,不自动删除或停用依赖流。
17
17
 
18
18
  ```ts
19
19
  import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
20
20
 
21
21
  export async function deleteSource(
22
22
  id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
23
- confirmedImpactRevision: string, intentKey: string, client: Tier0Client = createClient(),
23
+ intentKey: string, client: Tier0Client = createClient(), confirmedImpactRevision?: string,
24
24
  ) {
25
25
  const receipt = await client.source.delete({
26
26
  dryRun: false, mode: 'sync', allowPartial: false, idempotencyKey: intentKey,
27
- items: [{ id, expectedRevision, confirmedImpactRevision }],
27
+ items: [{ id, expectedRevision,
28
+ ...(confirmedImpactRevision === undefined ? {} : { confirmedImpactRevision }) }],
28
29
  });
29
30
  if (receipt.data.status !== 'committed' || receipt.data.results?.some(item => item.error)) {
30
31
  return { state: 'unconfirmed' as const, receipt };
31
32
  }
32
- let page = 1;
33
- while (true) {
34
- const { data } = await client.source.documents.list({
35
- archived: true, page, size: 200, includeDocument: false,
36
- });
37
- const archived = data.list.find(item => item.id === id);
38
- if (archived) return { state: 'archived' as const, receipt, archived };
39
- if (!data.hasMore) break;
40
- if (typeof data.nextPage !== 'number' || data.nextPage <= page) throw new Error('无有效下一页');
41
- page = data.nextPage;
42
- }
43
- return { state: 'committed-readback-unconfirmed' as const, receipt };
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 };
44
36
  }
45
37
  ```
46
38
 
47
- 返回 Outcome,HTTP 200/validated/accepted 不等于完成。归档列表找到 ID 是额外核验;读回不可见时保留提交回执,报告核验未完成。不能把任意 get 异常当成成功。
39
+ 返回 Outcome,HTTP 200/validated/accepted 不等于完成。已提交回执中对应 ID 的 deleted 结果足以确认归档,无需遍历归档列表;不能把任意 get 异常当成成功。传输结果未知时保留原请求、requestId 和意图键,不自动重试。补充确认回执是新请求,应使用新幂等键。
@@ -3,11 +3,11 @@
3
3
  | 方法 | POST 路径 | 输入 | data |
4
4
  | --- | --- | --- | --- |
5
5
  | source.documents.list | /openapi/v2/uns/sources/documents/list | page、size、search、protocol、desiredState、health、archived、includeDocument | list、total、page、hasMore、nextPage |
6
- | source.documents.get | /openapi/v2/uns/sources/documents/get | id(必填) | id、revision、完整 document、状态 |
6
+ | source.documents.get | /openapi/v2/uns/sources/documents/get | id(必填)、view:'summary' 或 'full' | id、revision、状态;full 才包含完整 document |
7
7
  | source.runtime.get | /openapi/v2/uns/sources/runtime/get | id(必填) | 运行状态 |
8
8
  | source.observations.get | /openapi/v2/uns/sources/observations/get | items:id、expectedRevision | 指定源和修订的观测 |
9
9
 
10
- page 从 1 开始,size 1–200。列表默认安全摘要;完整文档需要管理权限,编辑时显式 get。
10
+ page 从 1 开始,size 1–200。列表默认安全摘要。get 省略 view 保持旧的 full 行为;summary 需要 uns.source.view 或 uns.source.manage,full 需要 uns.source.manage;API Key 读取完整文档还必须是 full_access(includeDocument:true 同样适用)。未知 revision 时可读取 summary;要完整替换 document 或查看配置时读取 full。已持有写回执中的 ID/revision 时,可直接提交 patch,无需为了编辑再 get;服务端仍会检查版本冲突。摘要不能用于重建完整配置。
11
11
 
12
12
  ```ts
13
13
  import { createClient, type Tier0Client } from '@tier0/sdk-v2';
@@ -5,33 +5,32 @@
5
5
  | 字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
7
7
  | dryRun | boolean | 是 | 提交 false |
8
- | items[].id / expectedRevision | string / integer | 是 | 当前对象和修订 |
8
+ | items[].id / expectedRevision | string / integer | 是 | 当前对象和已知修订 |
9
9
  | items[].desiredState | enabled/disabled | 是 | 目标状态 |
10
- | items[].confirmedImpactRevision | string | 是 | enable/disable 对应的影响回执 |
10
+ | items[].confirmedImpactRevision | string | 有引用时 | enable/disable 对应的影响回执 |
11
11
  | mode / allowPartial | string / boolean | 否 | 单项示例 sync / false |
12
12
  | idempotencyKey | string | 否 | 本次状态变更的独立意图键 |
13
13
 
14
- 先 get,以相同修订执行 impact(action=enable 或 disable),按[影响分析](changes.md)遍历并评估。将原修订和回执传给下例。
14
+ 没有任何 Stream 引用时,一次请求即可提交期望状态。有引用时先以相同修订执行 impact(action=enable 或 disable),按[影响分析](changes.md)遍历并评估,再显式传入回执。服务端在同一事务中检查引用和修订,不会因未传回执而自动同意影响。
15
15
 
16
16
  ```ts
17
17
  import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
18
18
 
19
19
  export async function setSourceState(
20
20
  id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
21
- desiredState: 'enabled' | 'disabled', confirmedImpactRevision: string,
22
- intentKey: string, client: Tier0Client = createClient(),
21
+ desiredState: 'enabled' | 'disabled', intentKey: string,
22
+ client: Tier0Client = createClient(), confirmedImpactRevision?: string,
23
23
  ) {
24
24
  const receipt = await client.source.state.update({
25
25
  dryRun: false, mode: 'sync', allowPartial: false, idempotencyKey: intentKey,
26
- items: [{ id, expectedRevision, desiredState, confirmedImpactRevision }],
26
+ items: [{ id, expectedRevision, desiredState,
27
+ ...(confirmedImpactRevision === undefined ? {} : { confirmedImpactRevision }) }],
27
28
  });
28
29
  if (receipt.data.status !== 'committed' || receipt.data.results?.some(item => item.error)) {
29
30
  return { state: 'unconfirmed' as const, receipt };
30
31
  }
31
- const current = await client.source.documents.get({ id });
32
- if (current.data.desiredState !== desiredState) throw new Error('读回状态与目标不一致');
33
- return { state: 'committed' as const, receipt, current: current.data };
32
+ return { state: 'committed' as const, receipt };
34
33
  }
35
34
  ```
36
35
 
37
- 响应为 Outcome;accepted/jobId 仅表示受理,继续查询作业。enabled 是期望状态;健康与连通性另用 observations/runtime 检查。
36
+ 响应为 Outcome;committed 且无项错误即可确认期望状态已提交,无需额外 get。accepted/jobId 仅表示受理,继续查询作业。enabled 是期望状态;健康与连通性另用 observations/runtime 检查。提供的回执始终严格校验,确认过期或依赖变化不能自动刷新同意。
@@ -4,26 +4,47 @@
4
4
 
5
5
  | 字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
7
- | id | string | 是 | get 返回的 ID |
8
- | document | CloudSourceDocument | 是 | 完整新文档,保留未改字段和认证引用 |
9
- | expectedRevision | integer | 是 | 读取时的 revision,原样传回 |
10
- | confirmedImpactRevision | string | 是 | 相同文档和修订的 impact 回执 |
7
+ | id | string | 是 | 已知的 Source ID |
8
+ | patch / document | object / CloudSourceDocument | 二选一 | patch 保留未提供的字段;document 完整替换 |
9
+ | expectedRevision | integer | 是 | 已读取或上次提交返回的 revision,原样传回 |
10
+ | confirmedImpactRevision | string | 有引用时 | 相同修改意图和修订的 impact 回执 |
11
11
  | dryRun | boolean | 是 | true 预检;false 提交 |
12
12
  | idempotencyKey | string | 否 | 最多 128 字符 |
13
13
 
14
- ## 示例:修改名称并保留连接
14
+ ## 示例:一次请求修改名称
15
15
 
16
- prepare 读取文档、形成新文档并收集全部影响分页。在已有授权范围内评估 counts、restrictedCount 和引用后调用 commit,不自动串联未经授权的操作。影响字段说明见[影响分析](changes.md)。
16
+ 已有 ID 和 revision 时直接提交 patch。服务端在同一事务和依赖锁下检查引用并修改:没有任何草稿、活动或历史 Stream 引用时无需 impact。patch 中未提供的字段保留原值,config 如果提供则整体替换;完整 document 更新需先取得完整文档并保留未改配置和认证引用。
17
17
 
18
18
  ```ts
19
- import { createClient, type Tier0Client, type CloudSourceDocument, type UnsV2Request } from '@tier0/sdk-v2';
19
+ import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
20
20
 
21
- export async function prepareSourceRename(id: string, name: string, client: Tier0Client = createClient()) {
22
- const { data: current } = await client.source.documents.get({ id, view: 'full' });
23
- if (!('document' in current)) throw new Error('需要完整 Source 文档');
24
- const document: CloudSourceDocument = { ...current.document, name };
21
+ export async function renameSource(
22
+ id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
23
+ name: string, intentKey: string, client: Tier0Client = createClient(),
24
+ ) {
25
+ const saved = await client.source.documents.update({
26
+ id, expectedRevision, patch: { name }, dryRun: false, idempotencyKey: intentKey,
27
+ });
28
+ if (!('id' in saved.data)) throw new Error('未收到更新提交结果');
29
+ return { receipt: saved, current: saved.data };
30
+ }
31
+ ```
32
+
33
+ 提交直接返回完整 Source view 和新的 revision,无需额外 get。版本冲突时不会覆盖其他人的修改。返回 `SOURCE_IMPACT_CONFIRMATION_REQUIRED` 表示存在引用且未提交,进入下面的显式评估流程;不要自动获取并同意影响。
34
+
35
+ ## 有引用时:评估后确认相同意图
36
+
37
+ prepare 收集全部影响分页。在已有授权范围内评估 counts、restrictedCount 和引用后,再调用 commit。不可见引用也要求确认。影响字段说明见[影响分析](changes.md)。
38
+
39
+ ```ts
40
+ import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
41
+
42
+ export async function prepareSourceRename(
43
+ id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
44
+ name: string, client: Tier0Client = createClient(),
45
+ ) {
25
46
  const intent: UnsV2Request<'sourceImpact'> = {
26
- id, expectedRevision: current.revision, action: 'update', document,
47
+ id, expectedRevision, action: 'update', patch: { name },
27
48
  };
28
49
  const impact = await client.source.impact({ ...intent, offset: 0, size: 200 });
29
50
  const references = [...impact.data.references];
@@ -45,18 +66,15 @@ export async function commitSourceRename(
45
66
  plan: { intent: UnsV2Request<'sourceImpact'>; impact: { impactRevision: string } },
46
67
  intentKey: string, client: Tier0Client = createClient(),
47
68
  ) {
48
- const { id, expectedRevision, document, action } = plan.intent;
49
- if (action !== 'update' || !document) throw new Error('需要完整更新意图');
50
- const request = { id, expectedRevision, document,
51
- confirmedImpactRevision: plan.impact.impactRevision };
52
- const preview = await client.source.documents.update({ ...request, dryRun: true });
53
- if (!('validated' in preview.data) || !preview.data.validated) throw new Error('预检未通过');
69
+ const { id, expectedRevision, patch, action } = plan.intent;
70
+ if (action !== 'update' || !patch) throw new Error('需要修改意图');
54
71
  const saved = await client.source.documents.update({
55
- ...request, dryRun: false, idempotencyKey: intentKey,
72
+ id, expectedRevision, patch, confirmedImpactRevision: plan.impact.impactRevision,
73
+ dryRun: false, idempotencyKey: intentKey,
56
74
  });
57
75
  if (!('id' in saved.data)) throw new Error('未收到更新提交结果');
58
- return { receipt: saved, current: (await client.source.documents.get({ id })).data };
76
+ return { receipt: saved, current: saved.data };
59
77
  }
60
78
  ```
61
79
 
62
- 提交返回完整 Source view。核对读回名称、配置和提交修订;若读回又被别人修改,报告并发变化。影响评估后的 plan 保持不变。遇到 VERSION_CONFLICT、确认过期/不匹配,重新读取并评估,不静默刷新 token 重放。
80
+ 影响评估后的 plan 保持不变;已提供的确认回执始终严格校验,即使之后已无引用。修订冲突、确认过期或不匹配时重新读取并评估,不静默刷新回执重放。修改请求内容或补充确认回执属于新请求,应使用新幂等键;传输结果未知时保留原路由、请求和键,SDK 不自动重试。
@@ -11,8 +11,8 @@ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和
11
11
 
12
12
  | 用户任务 | 参考 | 方法 |
13
13
  | --- | --- | --- |
14
- | 新建并绑定 HTTP Source | [创建](references/create.md) | programs.validate/create |
15
- | 列表、完整文档、运行记录 | [查询](references/read.md) | programs.list/get、documents.get、observations.get、runs.list |
14
+ | 新建并绑定 HTTP Source | [创建](references/create.md) | documents.create({program}) |
15
+ | 列表、完整文档、运行记录 | [查询](references/read.md) | programs.list、documents.get、observations.get、runs.list |
16
16
  | 修改草稿、脚本和绑定 | [修改](references/update.md) | documents.validate/update |
17
17
  | 发布、停用、版本回滚 | [部署](references/deploy.md) | programs.deploy/rollback、documents.disable |
18
18
  | 删除并核验归档 | [删除](references/delete.md) | programs.delete |
@@ -22,22 +22,22 @@ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和
22
22
 
23
23
  | 形态 | 完整输入 | 适用入口 |
24
24
  | --- | --- | --- |
25
- | Runtime program | name、sdkVersion、script 字符串、sourceBindings、timeoutMs | programs.create/update/validate |
25
+ | Runtime program | name、sdkVersion、script 字符串、sourceBindings、timeoutMs | documents.create/update/validate({program}) |
26
26
  | 云端原生文档 | name、model、script 对象、sources、entries | documents.create/get/update/validate |
27
27
 
28
28
  程序必须是完整 `module.exports = api => { ... }`,执行器 API 是 api.sources/api.uns/api.stream,与 npm 包的 client.source 不同。Runtime sourceBindings 为 sourceId/configRevision/acquisition;原生 sources 还使用 alias/resources。连接凭据不进脚本或 acquisition。
29
29
 
30
30
  ## 核心约束
31
31
 
32
- 1. programs.get 返回脱敏摘要,不含可回写脚本;编辑必须 documents.get。保留未修改的 sources/entries/script 字段。
32
+ 1. documents.get({id,view:"summary"}) 返回安全摘要,不含可回写脚本;完整编辑使用 documents.get 或上次 documents.create/update 返回的完整文档。保留未修改的 sources/entries/script 字段。
33
33
  2. create/update 保存草稿,不自动发布;documents 没有 deploy,云端 program 发布使用 programs.deploy。不能将已保存报告为已运行。
34
34
  3. 所有更新/部署/删除携带当前 expectedRevision。原生停用另需 expectedActiveRelease,避免停掉他人刚发布的版本。
35
35
  4. versionId 从 versions.list 取得,不把 release 序号当 ID。expectedSourceRevision 仅用于恰好一个依赖源,不代表多个源的修订。
36
- 5. resources=[] 是空冻结资源集,不是通配符。先查询 runtime.capabilities,并让服务端 validate 检查能力;当前云端程序 timeoutMs 上限 30000。
36
+ 5. resources=[] 是空冻结资源集,不是通配符。能力选择可查询 runtime.capabilities,写入本身由服务端校验;需要预览时单独 validate。当前云端程序 timeoutMs 上限 30000。
37
37
  6. 仅执行用户要求的生命周期步骤;修改脚本不自动授予发布、停用或删除权限。
38
38
 
39
39
  ## 成功与异常
40
40
 
41
- 响应保留 code/msg/requestId/data。校验要检查 valid,样例要检查 completed/failed,删除要检查 deleted,发布要检查 activeVersion 和观测。样例 writePreview 不代表线上数据写入。
41
+ 响应保留 code/msg/requestId/data。创建/更新回执的 revision 可直接用于发布;programs 发布回执的 activeRelease 是同次事务保存的正整数发布序号,无需前后 get。programs 回执和查询结果无活跃发布时省略 activeRelease,activeVersion 保留字符串 0 的兼容语义。校验要检查 valid,样例要检查 completed/failed,删除要检查 deleted;发布后按回执的 activeRelease 筛选 runs.list 才能确认该版本运行。样例 writePreview 不代表线上数据写入。
42
42
 
43
- UnsV2OutcomeUnknownError、发布超时或取消后先读取版本/观测对账,保留原请求意图键,不自动重复发布。版本冲突先比较当前草稿,不能忽略 expectedRevision。不同写入意图使用不同键;本地 SDK 测试不能代替目标环境联调。
43
+ UnsV2OutcomeUnknownError、发布超时或取消后保留原路由、载荷和幂等键;允许恢复时原样重发取得原回执,不用新键重复发布。历史回执可能缺少 activeRelease,不得用当前 head 替代。版本冲突先比较当前草稿,不能忽略 expectedRevision。不同写入意图使用不同键;本地 SDK 测试不能代替目标环境联调。
@@ -1,15 +1,15 @@
1
1
  # 创建 Stream
2
2
 
3
- 方法:`stream.programs.create`;POST `/openapi/v2/uns/streams/program/create`。
3
+ 方法:`stream.documents.create({program})`;POST `/openapi/v2/uns/streams/documents/create`。服务端编译并校验程序,回执包含完整草稿和修订,可直接用于下一步发布。
4
4
 
5
5
  | 字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
7
7
  | dryRun | boolean | 是 | true 预检,false 保存草稿 |
8
- | document.name | string | 是 | 1–63 字符 |
9
- | document.sdkVersion | tier0-stream/v2 | 是 | 运行时脚本版本 |
10
- | document.script | string | 是 | 完整 module.exports 程序 |
11
- | document.timeoutMs | integer | 否 | 当前云端上限 30000 ms |
12
- | document.sourceBindings | array | 否 | sourceId、configRevision、acquisition |
8
+ | program.name | string | 是 | 1–63 字符 |
9
+ | program.sdkVersion | tier0-stream/v2 | 是 | 运行时脚本版本 |
10
+ | program.script | string | 是 | 完整 module.exports 程序 |
11
+ | program.timeoutMs | integer | 否 | 当前云端上限 30000 ms |
12
+ | program.sourceBindings | array | 否 | sourceId、configRevision、acquisition |
13
13
  | idempotencyKey | string | 否 | 最多 128 字符,本次创建的固定意图键 |
14
14
 
15
15
  ## HTTP Source 绑定示例
@@ -39,18 +39,18 @@ export async function createHttpStream(
39
39
  '};',
40
40
  ].join('\n'),
41
41
  };
42
- const validation = await client.stream.programs.validate({ document });
43
- if (validation.data.valid !== true) throw new Error('Stream 校验未通过');
44
- const saved = await client.stream.programs.create({
45
- dryRun: false, document, idempotencyKey: intentKey,
42
+ const saved = await client.stream.documents.create({
43
+ dryRun: false, program: document, idempotencyKey: intentKey,
46
44
  });
47
- if (typeof saved.data.id !== 'string') throw new Error('创建回执缺少 ID');
48
- return { receipt: saved, current: (await client.stream.documents.get({ id: saved.data.id })).data };
45
+ if (!('id' in saved.data)) throw new Error('创建未返回已保存的草稿');
46
+ return { receipt: saved, current: saved.data };
49
47
  }
50
48
  ```
51
49
 
52
50
  将 path="orders"、60 秒周期改为业务实际值。示例保存草稿,不部署,也不将返回值自动写入 UNS;需要写入集合时按执行器能力定义 api.uns 操作。resources=[] 是空冻结资源集,不是通配授权。源地址和凭据留在 Source,不能拷进 acquisition 或脚本。
53
51
 
54
- 创建 data 是开放对象,成功返回 id、revision、activeVersion、executionState、脱敏 document;以实际字段判断,预检不生成 ID。当前后端创建/校验需要注册 Worker 可用。TEMPORARILY_UNAVAILABLE 不代表脚本一定错误;不要自动改用旧 Flow。
52
+ 创建 data 为 CloudStreamDocumentView 或预检结果,实际保存返回 id、revision 和完整 document;预检不生成 ID。需要展示预检时单独调用 documents.validate({program});普通保存无需先校验再保存。当前后端创建/校验需要注册 Worker 可用。TEMPORARILY_UNAVAILABLE 不代表脚本一定错误;不要自动改用旧 Flow。
53
+
54
+ programs.create 已退役,创建统一使用 documents.create。历史创建结局未知时先按已知 ID 或业务标识核对状态,不能将旧请求或幂等键改投 documents.create 重做。
55
55
 
56
56
  原生编辑器形态 `documents.create({dryRun, document})` 的 document 为 name/model/script对象/sources/entries,script 为 `{sdkVersion,code,timeoutMs}`,sources 用 alias/sourceId/configRevision/resources/acquisition。不要把上面的 script 字符串直接塞入原生文档。