@tier0/sdk-v2 0.0.0-stage → 0.2.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.
Files changed (310) hide show
  1. package/LICENSE +21 -0
  2. package/NOTICE.md +7 -0
  3. package/README.md +201 -2
  4. package/dist/cjs/app-identity-contract.generated.d.ts +22 -0
  5. package/dist/cjs/app-identity-contract.generated.js +51 -0
  6. package/dist/cjs/app-identity-contract.generated.js.map +1 -0
  7. package/dist/cjs/capabilities.d.ts +54 -0
  8. package/dist/cjs/capabilities.js +134 -0
  9. package/dist/cjs/capabilities.js.map +1 -0
  10. package/dist/cjs/client.d.ts +604 -0
  11. package/dist/cjs/client.js +35 -0
  12. package/dist/cjs/client.js.map +1 -0
  13. package/dist/cjs/cloud-server.d.ts +31 -0
  14. package/dist/cjs/cloud-server.js +114 -0
  15. package/dist/cjs/cloud-server.js.map +1 -0
  16. package/dist/cjs/cloud-transport.d.ts +67 -0
  17. package/dist/cjs/cloud-transport.js +272 -0
  18. package/dist/cjs/cloud-transport.js.map +1 -0
  19. package/dist/cjs/controls.d.ts +93 -0
  20. package/dist/cjs/controls.js +169 -0
  21. package/dist/cjs/controls.js.map +1 -0
  22. package/dist/cjs/data/bootstrap.d.ts +70 -0
  23. package/dist/cjs/data/bootstrap.js +291 -0
  24. package/dist/cjs/data/bootstrap.js.map +1 -0
  25. package/dist/cjs/data/call.d.ts +33 -0
  26. package/dist/cjs/data/call.js +216 -0
  27. package/dist/cjs/data/call.js.map +1 -0
  28. package/dist/cjs/data/client.d.ts +134 -0
  29. package/dist/cjs/data/client.js +185 -0
  30. package/dist/cjs/data/client.js.map +1 -0
  31. package/dist/cjs/data/collection.d.ts +335 -0
  32. package/dist/cjs/data/collection.js +601 -0
  33. package/dist/cjs/data/collection.js.map +1 -0
  34. package/dist/cjs/data/context.d.ts +12 -0
  35. package/dist/cjs/data/context.js +50 -0
  36. package/dist/cjs/data/context.js.map +1 -0
  37. package/dist/cjs/data/declarations.d.ts +11 -0
  38. package/dist/cjs/data/declarations.js +18 -0
  39. package/dist/cjs/data/declarations.js.map +1 -0
  40. package/dist/cjs/data/define.d.ts +77 -0
  41. package/dist/cjs/data/define.js +31 -0
  42. package/dist/cjs/data/define.js.map +1 -0
  43. package/dist/cjs/data/error.d.ts +78 -0
  44. package/dist/cjs/data/error.js +182 -0
  45. package/dist/cjs/data/error.js.map +1 -0
  46. package/dist/cjs/data/index.d.ts +24 -0
  47. package/dist/cjs/data/index.js +49 -0
  48. package/dist/cjs/data/index.js.map +1 -0
  49. package/dist/cjs/data/schema.d.ts +88 -0
  50. package/dist/cjs/data/schema.js +657 -0
  51. package/dist/cjs/data/schema.js.map +1 -0
  52. package/dist/cjs/data/sort.d.ts +8 -0
  53. package/dist/cjs/data/sort.js +21 -0
  54. package/dist/cjs/data/sort.js.map +1 -0
  55. package/dist/cjs/data/subscribe.d.ts +108 -0
  56. package/dist/cjs/data/subscribe.js +270 -0
  57. package/dist/cjs/data/subscribe.js.map +1 -0
  58. package/dist/cjs/files.d.ts +67 -0
  59. package/dist/cjs/files.js +119 -0
  60. package/dist/cjs/files.js.map +1 -0
  61. package/dist/cjs/framework-scope.d.ts +1 -0
  62. package/dist/cjs/framework-scope.js +14 -0
  63. package/dist/cjs/framework-scope.js.map +1 -0
  64. package/dist/cjs/index.d.ts +14 -0
  65. package/dist/cjs/index.js +33 -0
  66. package/dist/cjs/index.js.map +1 -0
  67. package/dist/cjs/mq/broker.d.ts +65 -0
  68. package/dist/cjs/mq/broker.js +115 -0
  69. package/dist/cjs/mq/broker.js.map +1 -0
  70. package/dist/cjs/mq/client.d.ts +37 -0
  71. package/dist/cjs/mq/client.js +321 -0
  72. package/dist/cjs/mq/client.js.map +1 -0
  73. package/dist/cjs/mq/index.d.ts +5 -0
  74. package/dist/cjs/mq/index.js +11 -0
  75. package/dist/cjs/mq/index.js.map +1 -0
  76. package/dist/cjs/mq/types.d.ts +48 -0
  77. package/dist/cjs/mq/types.js +3 -0
  78. package/dist/cjs/mq/types.js.map +1 -0
  79. package/dist/cjs/openapi/api.generated.d.ts +820 -0
  80. package/dist/cjs/openapi/api.generated.js +607 -0
  81. package/dist/cjs/openapi/api.generated.js.map +1 -0
  82. package/dist/cjs/openapi/client.d.ts +56 -0
  83. package/dist/cjs/openapi/client.js +219 -0
  84. package/dist/cjs/openapi/client.js.map +1 -0
  85. package/dist/cjs/openapi/codecs.generated.d.ts +2234 -0
  86. package/dist/cjs/openapi/codecs.generated.js +6 -0
  87. package/dist/cjs/openapi/codecs.generated.js.map +1 -0
  88. package/dist/cjs/openapi/index.d.ts +5 -0
  89. package/dist/cjs/openapi/index.js +12 -0
  90. package/dist/cjs/openapi/index.js.map +1 -0
  91. package/dist/cjs/openapi/types.generated.d.ts +3227 -0
  92. package/dist/cjs/openapi/types.generated.js +3 -0
  93. package/dist/cjs/openapi/types.generated.js.map +1 -0
  94. package/dist/cjs/package.json +1 -0
  95. package/dist/cjs/react.d.ts +9 -0
  96. package/dist/cjs/react.js +16 -0
  97. package/dist/cjs/react.js.map +1 -0
  98. package/dist/cjs/runtime-context.d.ts +9 -0
  99. package/dist/cjs/runtime-context.js +25 -0
  100. package/dist/cjs/runtime-context.js.map +1 -0
  101. package/dist/cjs/runtime-env.d.ts +1 -0
  102. package/dist/cjs/runtime-env.js +18 -0
  103. package/dist/cjs/runtime-env.js.map +1 -0
  104. package/dist/cjs/source.d.ts +39 -0
  105. package/dist/cjs/source.js +29 -0
  106. package/dist/cjs/source.js.map +1 -0
  107. package/dist/cjs/stream.d.ts +40 -0
  108. package/dist/cjs/stream.js +33 -0
  109. package/dist/cjs/stream.js.map +1 -0
  110. package/dist/cjs/uns-v2/client.d.ts +132 -0
  111. package/dist/cjs/uns-v2/client.js +352 -0
  112. package/dist/cjs/uns-v2/client.js.map +1 -0
  113. package/dist/cjs/uns-v2/codec.d.ts +11 -0
  114. package/dist/cjs/uns-v2/codec.js +290 -0
  115. package/dist/cjs/uns-v2/codec.js.map +1 -0
  116. package/dist/cjs/uns-v2/data-client.d.ts +10 -0
  117. package/dist/cjs/uns-v2/data-client.js +18 -0
  118. package/dist/cjs/uns-v2/data-client.js.map +1 -0
  119. package/dist/cjs/uns-v2/generated.d.ts +18178 -0
  120. package/dist/cjs/uns-v2/generated.js +144 -0
  121. package/dist/cjs/uns-v2/generated.js.map +1 -0
  122. package/dist/cjs/uns-v2/index.d.ts +5 -0
  123. package/dist/cjs/uns-v2/index.js +24 -0
  124. package/dist/cjs/uns-v2/index.js.map +1 -0
  125. package/dist/cjs/uns-v2/sse.d.ts +20 -0
  126. package/dist/cjs/uns-v2/sse.js +65 -0
  127. package/dist/cjs/uns-v2/sse.js.map +1 -0
  128. package/dist/cjs/vue.d.ts +9 -0
  129. package/dist/cjs/vue.js +39 -0
  130. package/dist/cjs/vue.js.map +1 -0
  131. package/dist/esm/app-identity-contract.generated.d.ts +22 -0
  132. package/dist/esm/app-identity-contract.generated.js +48 -0
  133. package/dist/esm/app-identity-contract.generated.js.map +1 -0
  134. package/dist/esm/capabilities.d.ts +54 -0
  135. package/dist/esm/capabilities.js +129 -0
  136. package/dist/esm/capabilities.js.map +1 -0
  137. package/dist/esm/client.d.ts +604 -0
  138. package/dist/esm/client.js +32 -0
  139. package/dist/esm/client.js.map +1 -0
  140. package/dist/esm/cloud-server.d.ts +31 -0
  141. package/dist/esm/cloud-server.js +109 -0
  142. package/dist/esm/cloud-server.js.map +1 -0
  143. package/dist/esm/cloud-transport.d.ts +67 -0
  144. package/dist/esm/cloud-transport.js +267 -0
  145. package/dist/esm/cloud-transport.js.map +1 -0
  146. package/dist/esm/controls.d.ts +93 -0
  147. package/dist/esm/controls.js +163 -0
  148. package/dist/esm/controls.js.map +1 -0
  149. package/dist/esm/data/bootstrap.d.ts +70 -0
  150. package/dist/esm/data/bootstrap.js +286 -0
  151. package/dist/esm/data/bootstrap.js.map +1 -0
  152. package/dist/esm/data/call.d.ts +33 -0
  153. package/dist/esm/data/call.js +211 -0
  154. package/dist/esm/data/call.js.map +1 -0
  155. package/dist/esm/data/client.d.ts +134 -0
  156. package/dist/esm/data/client.js +181 -0
  157. package/dist/esm/data/client.js.map +1 -0
  158. package/dist/esm/data/collection.d.ts +335 -0
  159. package/dist/esm/data/collection.js +594 -0
  160. package/dist/esm/data/collection.js.map +1 -0
  161. package/dist/esm/data/context.d.ts +12 -0
  162. package/dist/esm/data/context.js +44 -0
  163. package/dist/esm/data/context.js.map +1 -0
  164. package/dist/esm/data/declarations.d.ts +11 -0
  165. package/dist/esm/data/declarations.js +10 -0
  166. package/dist/esm/data/declarations.js.map +1 -0
  167. package/dist/esm/data/define.d.ts +77 -0
  168. package/dist/esm/data/define.js +27 -0
  169. package/dist/esm/data/define.js.map +1 -0
  170. package/dist/esm/data/error.d.ts +78 -0
  171. package/dist/esm/data/error.js +176 -0
  172. package/dist/esm/data/error.js.map +1 -0
  173. package/dist/esm/data/index.d.ts +24 -0
  174. package/dist/esm/data/index.js +20 -0
  175. package/dist/esm/data/index.js.map +1 -0
  176. package/dist/esm/data/schema.d.ts +88 -0
  177. package/dist/esm/data/schema.js +646 -0
  178. package/dist/esm/data/schema.js.map +1 -0
  179. package/dist/esm/data/sort.d.ts +8 -0
  180. package/dist/esm/data/sort.js +18 -0
  181. package/dist/esm/data/sort.js.map +1 -0
  182. package/dist/esm/data/subscribe.d.ts +108 -0
  183. package/dist/esm/data/subscribe.js +265 -0
  184. package/dist/esm/data/subscribe.js.map +1 -0
  185. package/dist/esm/files.d.ts +67 -0
  186. package/dist/esm/files.js +113 -0
  187. package/dist/esm/files.js.map +1 -0
  188. package/dist/esm/framework-scope.d.ts +1 -0
  189. package/dist/esm/framework-scope.js +11 -0
  190. package/dist/esm/framework-scope.js.map +1 -0
  191. package/dist/esm/index.d.ts +14 -0
  192. package/dist/esm/index.js +10 -0
  193. package/dist/esm/index.js.map +1 -0
  194. package/dist/esm/mq/broker.d.ts +65 -0
  195. package/dist/esm/mq/broker.js +109 -0
  196. package/dist/esm/mq/broker.js.map +1 -0
  197. package/dist/esm/mq/client.d.ts +37 -0
  198. package/dist/esm/mq/client.js +314 -0
  199. package/dist/esm/mq/client.js.map +1 -0
  200. package/dist/esm/mq/index.d.ts +5 -0
  201. package/dist/esm/mq/index.js +3 -0
  202. package/dist/esm/mq/index.js.map +1 -0
  203. package/dist/esm/mq/types.d.ts +48 -0
  204. package/dist/esm/mq/types.js +2 -0
  205. package/dist/esm/mq/types.js.map +1 -0
  206. package/dist/esm/openapi/api.generated.d.ts +820 -0
  207. package/dist/esm/openapi/api.generated.js +603 -0
  208. package/dist/esm/openapi/api.generated.js.map +1 -0
  209. package/dist/esm/openapi/client.d.ts +56 -0
  210. package/dist/esm/openapi/client.js +210 -0
  211. package/dist/esm/openapi/client.js.map +1 -0
  212. package/dist/esm/openapi/codecs.generated.d.ts +2234 -0
  213. package/dist/esm/openapi/codecs.generated.js +3 -0
  214. package/dist/esm/openapi/codecs.generated.js.map +1 -0
  215. package/dist/esm/openapi/index.d.ts +5 -0
  216. package/dist/esm/openapi/index.js +3 -0
  217. package/dist/esm/openapi/index.js.map +1 -0
  218. package/dist/esm/openapi/types.generated.d.ts +3227 -0
  219. package/dist/esm/openapi/types.generated.js +2 -0
  220. package/dist/esm/openapi/types.generated.js.map +1 -0
  221. package/dist/esm/package.json +1 -0
  222. package/dist/esm/react.d.ts +9 -0
  223. package/dist/esm/react.js +12 -0
  224. package/dist/esm/react.js.map +1 -0
  225. package/dist/esm/runtime-context.d.ts +9 -0
  226. package/dist/esm/runtime-context.js +22 -0
  227. package/dist/esm/runtime-context.js.map +1 -0
  228. package/dist/esm/runtime-env.d.ts +1 -0
  229. package/dist/esm/runtime-env.js +15 -0
  230. package/dist/esm/runtime-env.js.map +1 -0
  231. package/dist/esm/source.d.ts +39 -0
  232. package/dist/esm/source.js +25 -0
  233. package/dist/esm/source.js.map +1 -0
  234. package/dist/esm/stream.d.ts +40 -0
  235. package/dist/esm/stream.js +29 -0
  236. package/dist/esm/stream.js.map +1 -0
  237. package/dist/esm/uns-v2/client.d.ts +132 -0
  238. package/dist/esm/uns-v2/client.js +343 -0
  239. package/dist/esm/uns-v2/client.js.map +1 -0
  240. package/dist/esm/uns-v2/codec.d.ts +11 -0
  241. package/dist/esm/uns-v2/codec.js +284 -0
  242. package/dist/esm/uns-v2/codec.js.map +1 -0
  243. package/dist/esm/uns-v2/data-client.d.ts +10 -0
  244. package/dist/esm/uns-v2/data-client.js +14 -0
  245. package/dist/esm/uns-v2/data-client.js.map +1 -0
  246. package/dist/esm/uns-v2/generated.d.ts +18178 -0
  247. package/dist/esm/uns-v2/generated.js +141 -0
  248. package/dist/esm/uns-v2/generated.js.map +1 -0
  249. package/dist/esm/uns-v2/index.d.ts +5 -0
  250. package/dist/esm/uns-v2/index.js +5 -0
  251. package/dist/esm/uns-v2/index.js.map +1 -0
  252. package/dist/esm/uns-v2/sse.d.ts +20 -0
  253. package/dist/esm/uns-v2/sse.js +60 -0
  254. package/dist/esm/uns-v2/sse.js.map +1 -0
  255. package/dist/esm/vue.d.ts +9 -0
  256. package/dist/esm/vue.js +36 -0
  257. package/dist/esm/vue.js.map +1 -0
  258. package/docs/acceptance-2026-10-22.md +88 -0
  259. package/package.json +243 -4
  260. package/skills/tier0-sdk-v2/SKILL.md +66 -0
  261. package/skills/tier0-sdk-v2/references/integration.md +72 -0
  262. package/skills/tier0-sdk-v2/tier0-sdk-v2-agent/SKILL.md +73 -0
  263. package/skills/tier0-sdk-v2/tier0-sdk-v2-agent/references/results.md +45 -0
  264. package/skills/tier0-sdk-v2/tier0-sdk-v2-controls/SKILL.md +63 -0
  265. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/SKILL.md +58 -0
  266. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/consistency.md +70 -0
  267. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/errors.md +82 -0
  268. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/modeling.md +113 -0
  269. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/read-write.md +168 -0
  270. package/skills/tier0-sdk-v2/tier0-sdk-v2-data/references/schema-evolution.md +36 -0
  271. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/SKILL.md +85 -0
  272. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/delete.md +22 -0
  273. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/download.md +49 -0
  274. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/multipart.md +42 -0
  275. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/upload.md +27 -0
  276. package/skills/tier0-sdk-v2/tier0-sdk-v2-files/references/url.md +22 -0
  277. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/SKILL.md +56 -0
  278. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/app-members.md +41 -0
  279. package/skills/tier0-sdk-v2/tier0-sdk-v2-members/references/platform-members.md +56 -0
  280. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/SKILL.md +78 -0
  281. package/skills/tier0-sdk-v2/tier0-sdk-v2-mq/references/quickstart.md +69 -0
  282. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/SKILL.md +42 -0
  283. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/get.md +34 -0
  284. package/skills/tier0-sdk-v2/tier0-sdk-v2-notifications/references/send.md +72 -0
  285. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/SKILL.md +38 -0
  286. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/changes.md +40 -0
  287. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/create.md +63 -0
  288. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/delete.md +47 -0
  289. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/protocols.md +36 -0
  290. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/read.md +34 -0
  291. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/state.md +37 -0
  292. package/skills/tier0-sdk-v2/tier0-sdk-v2-source/references/update.md +62 -0
  293. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/SKILL.md +43 -0
  294. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/create.md +56 -0
  295. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/delete.md +35 -0
  296. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/deploy.md +64 -0
  297. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/lifecycle.md +26 -0
  298. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/read.md +35 -0
  299. package/skills/tier0-sdk-v2/tier0-sdk-v2-stream/references/update.md +36 -0
  300. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/SKILL.md +64 -0
  301. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/info.md +23 -0
  302. package/skills/tier0-sdk-v2/tier0-sdk-v2-system/references/whoami.md +21 -0
  303. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/SKILL.md +55 -0
  304. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/create.md +56 -0
  305. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/data-workflows.md +69 -0
  306. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/delete.md +53 -0
  307. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/namespace.md +38 -0
  308. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/read.md +34 -0
  309. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/restore.md +39 -0
  310. package/skills/tier0-sdk-v2/tier0-sdk-v2-uns/references/update.md +62 -0
@@ -0,0 +1,62 @@
1
+ # 修改 Source
2
+
3
+ 方法:`source.documents.update`;POST `/openapi/v2/uns/sources/documents/update`。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | id | string | 是 | get 返回的 ID |
8
+ | document | CloudSourceDocument | 是 | 完整新文档,保留未改字段和认证引用 |
9
+ | expectedRevision | integer | 是 | 读取时的 revision,原样传回 |
10
+ | confirmedImpactRevision | string | 是 | 相同文档和修订的 impact 回执 |
11
+ | dryRun | boolean | 是 | true 预检;false 提交 |
12
+ | idempotencyKey | string | 否 | 最多 128 字符 |
13
+
14
+ ## 示例:修改名称并保留连接
15
+
16
+ prepare 读取文档、形成新文档并收集全部影响分页。在已有授权范围内评估 counts、restrictedCount 和引用后调用 commit,不自动串联未经授权的操作。影响字段说明见[影响分析](changes.md)。
17
+
18
+ ```ts
19
+ import { createClient, type Tier0Client, type CloudSourceDocument, type UnsV2Request } from '@tier0/sdk-v2';
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 };
25
+ const intent: UnsV2Request<'sourceImpact'> = {
26
+ id, expectedRevision: current.revision, action: 'update', document,
27
+ };
28
+ const impact = await client.source.impact({ ...intent, offset: 0, size: 200 });
29
+ const references = [...impact.data.references];
30
+ let offset = impact.data.nextOffset;
31
+ const seen = new Set<string>();
32
+ while (String(offset) !== '0') {
33
+ if (seen.has(String(offset))) throw new Error('影响分页未前进');
34
+ seen.add(String(offset));
35
+ const next = await client.source.impact({
36
+ ...intent, offset, size: 200, impactRevision: impact.data.impactRevision,
37
+ });
38
+ if (next.data.impactRevision !== impact.data.impactRevision) throw new Error('影响确认值发生变化');
39
+ references.push(...next.data.references);
40
+ offset = next.data.nextOffset;
41
+ }
42
+ return { intent, impact: { ...impact.data, references, nextOffset: offset } };
43
+ }
44
+ export async function commitSourceRename(
45
+ plan: { intent: UnsV2Request<'sourceImpact'>; impact: { impactRevision: string } },
46
+ intentKey: string, client: Tier0Client = createClient(),
47
+ ) {
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('预检未通过');
54
+ const saved = await client.source.documents.update({
55
+ ...request, dryRun: false, idempotencyKey: intentKey,
56
+ });
57
+ if (!('id' in saved.data)) throw new Error('未收到更新提交结果');
58
+ return { receipt: saved, current: (await client.source.documents.get({ id })).data };
59
+ }
60
+ ```
61
+
62
+ 提交返回完整 Source view。核对读回名称、配置和提交修订;若读回又被别人修改,报告并发变化。影响评估后的 plan 保持不变。遇到 VERSION_CONFLICT、确认过期/不匹配,重新读取并评估,不静默刷新 token 重放。
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: tier0-sdk-v2-stream
3
+ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和删除 Stream,绑定 Source,校验脚本,发布、停用、回滚及检查运行结果。
4
+ ---
5
+
6
+ # Stream 处理与运行
7
+
8
+ 应用代码使用 client.stream;外部连接用 [Source](../tier0-sdk-v2-source/SKILL.md),集合和记录用 [UNS](../tier0-sdk-v2-uns/SKILL.md)。服务端 `createClient()` 读取 TIER0_API_HOST / TIER0_API_KEY,也可显式传 apiHost/apiKey。
9
+
10
+ ## 按任务加载参考
11
+
12
+ | 用户任务 | 参考 | 方法 |
13
+ | --- | --- | --- |
14
+ | 新建并绑定 HTTP Source | [创建](references/create.md) | programs.validate/create |
15
+ | 列表、完整文档、运行记录 | [查询](references/read.md) | programs.list/get、documents.get、observations.get、runs.list |
16
+ | 修改草稿、脚本和绑定 | [修改](references/update.md) | documents.validate/update |
17
+ | 发布、停用、版本回滚 | [部署](references/deploy.md) | programs.deploy/rollback、documents.disable |
18
+ | 删除并核验归档 | [删除](references/delete.md) | programs.delete |
19
+ | 隔离样例测试、流程衔接 | [生命周期](references/lifecycle.md) | sampleTest |
20
+
21
+ ## 两种文档形态
22
+
23
+ | 形态 | 完整输入 | 适用入口 |
24
+ | --- | --- | --- |
25
+ | Runtime program | name、sdkVersion、script 字符串、sourceBindings、timeoutMs | programs.create/update/validate |
26
+ | 云端原生文档 | name、model、script 对象、sources、entries | documents.create/get/update/validate |
27
+
28
+ 程序必须是完整 `module.exports = api => { ... }`,执行器 API 是 api.sources/api.uns/api.stream,与 npm 包的 client.source 不同。Runtime sourceBindings 为 sourceId/configRevision/acquisition;原生 sources 还使用 alias/resources。连接凭据不进脚本或 acquisition。
29
+
30
+ ## 核心约束
31
+
32
+ 1. programs.get 返回脱敏摘要,不含可回写脚本;编辑必须 documents.get。保留未修改的 sources/entries/script 字段。
33
+ 2. create/update 保存草稿,不自动发布;documents 没有 deploy,云端 program 发布使用 programs.deploy。不能将已保存报告为已运行。
34
+ 3. 所有更新/部署/删除携带当前 expectedRevision。原生停用另需 expectedActiveRelease,避免停掉他人刚发布的版本。
35
+ 4. versionId 从 versions.list 取得,不把 release 序号当 ID。expectedSourceRevision 仅用于恰好一个依赖源,不代表多个源的修订。
36
+ 5. resources=[] 是空冻结资源集,不是通配符。先查询 runtime.capabilities,并让服务端 validate 检查能力;当前云端程序 timeoutMs 上限 30000。
37
+ 6. 仅执行用户要求的生命周期步骤;修改脚本不自动授予发布、停用或删除权限。
38
+
39
+ ## 成功与异常
40
+
41
+ 响应保留 code/msg/requestId/data。校验要检查 valid,样例要检查 completed/failed,删除要检查 deleted,发布要检查 activeVersion 和观测。样例 writePreview 不代表线上数据写入。
42
+
43
+ UnsV2OutcomeUnknownError、发布超时或取消后先读取版本/观测对账,保留原请求意图键,不自动重复发布。版本冲突先比较当前草稿,不能忽略 expectedRevision。不同写入意图使用不同键;本地 SDK 测试不能代替目标环境联调。
@@ -0,0 +1,56 @@
1
+ # 创建 Stream
2
+
3
+ 方法:`stream.programs.create`;POST `/openapi/v2/uns/streams/program/create`。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
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 |
13
+ | idempotencyKey | string | 否 | 最多 128 字符,本次创建的固定意图键 |
14
+
15
+ ## HTTP Source 绑定示例
16
+
17
+ 先按[Source 查询](../../tier0-sdk-v2-source/references/read.md)选定真实 HTTP Source。脚本的 api.sources 属于平台执行器,与应用中的 client.source 不同。sourceId 保持字符串,configRevision 从完整源读取。
18
+
19
+ ```ts
20
+ import { createClient, type Tier0Client, type RuntimeStreamDefinition } from '@tier0/sdk-v2';
21
+
22
+ export async function createHttpStream(
23
+ sourceId: string, name: string, intentKey: string, client: Tier0Client = createClient(),
24
+ ) {
25
+ if (!/^[1-9][0-9]*$/.test(sourceId)) throw new Error('Source ID 必须是正十进制字符串');
26
+ const source = await client.source.documents.get({ id: sourceId, view: 'full' });
27
+ if (!('document' in source.data)) throw new Error('需要完整 Source 文档');
28
+ if (source.data.document.protocol !== 'http') throw new Error('此示例需要 HTTP Source');
29
+ const document: RuntimeStreamDefinition = {
30
+ name, sdkVersion: 'tier0-stream/v2', timeoutMs: 5000,
31
+ sourceBindings: [{ sourceId, configRevision: source.data.revision, acquisition: {} }],
32
+ script: [
33
+ 'module.exports = api => {',
34
+ ' const upstream = api.sources.use({ id: ' + JSON.stringify(sourceId) + ', resources: [] });',
35
+ ' api.stream.onTimer({ id: "tick", intervalMs: 60000 }, async () => {',
36
+ ' const response = await upstream.request({ method: "GET", path: "orders" });',
37
+ ' return response.data;',
38
+ ' });',
39
+ '};',
40
+ ].join('\n'),
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,
46
+ });
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 };
49
+ }
50
+ ```
51
+
52
+ 将 path="orders"、60 秒周期改为业务实际值。示例保存草稿,不部署,也不将返回值自动写入 UNS;需要写入集合时按执行器能力定义 api.uns 操作。resources=[] 是空冻结资源集,不是通配授权。源地址和凭据留在 Source,不能拷进 acquisition 或脚本。
53
+
54
+ 创建 data 是开放对象,成功返回 id、revision、activeVersion、executionState、脱敏 document;以实际字段判断,预检不生成 ID。当前后端创建/校验需要注册 Worker 可用。TEMPORARILY_UNAVAILABLE 不代表脚本一定错误;不要自动改用旧 Flow。
55
+
56
+ 原生编辑器形态 `documents.create({dryRun, document})` 的 document 为 name/model/script对象/sources/entries,script 为 `{sdkVersion,code,timeoutMs}`,sources 用 alias/sourceId/configRevision/resources/acquisition。不要把上面的 script 字符串直接塞入原生文档。
@@ -0,0 +1,35 @@
1
+ # 删除 Stream
2
+
3
+ 方法:`stream.programs.delete`;POST `/openapi/v2/uns/streams/program/delete`。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | id | string | 是 | 十进制字符串 |
8
+ | expectedRevision | integer | 建议提供 | 当前 get 返回修订 |
9
+ | dryRun | boolean | 是 | true 预检;false 提交 |
10
+ | idempotencyKey | string | 否 | 最多 128 字符 |
11
+
12
+ 先读取明确目标并评估活跃发布/调用依赖。停止运行与删除是两个操作,删除请求不自动授予对 Source/UNS 数据的清理权限。
13
+
14
+ ```ts
15
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
16
+
17
+ export async function deleteStream(id: string, intentKey: string, client: Tier0Client = createClient()) {
18
+ const { data: current } = await client.stream.documents.get({ id });
19
+ const receipt = await client.stream.programs.delete({
20
+ id, expectedRevision: current.revision, dryRun: false, idempotencyKey: intentKey,
21
+ });
22
+ if (!('deleted' in receipt.data) || receipt.data.deleted !== true) throw new Error('未确认删除');
23
+ let page = 1;
24
+ while (true) {
25
+ const { data } = await client.stream.programs.list({ archived: true, page, size: 200 });
26
+ const archived = data.list.find(item => item.id === id);
27
+ if (archived) return { receipt, archived };
28
+ if (!data.hasMore) return { receipt, archived: undefined };
29
+ if (typeof data.nextPage !== 'number' || data.nextPage <= page) throw new Error('无有效下一页');
30
+ page = data.nextPage;
31
+ }
32
+ }
33
+ ```
34
+
35
+ 成功 data 为 `{id,revision,deleted:true}`;预检为 `{validated:true,sideEffects:false}`。归档列表额外核验,未查到时报告“删除有回执,读回未确认”。不要捕获所有 get 异常并返回删除成功。并发冲突重新评估,不用无版本保护的请求覆盖。
@@ -0,0 +1,64 @@
1
+ # 发布、停用与回滚 Stream
2
+
3
+ | 方法 | POST 路径 | 必要参数 |
4
+ | --- | --- | --- |
5
+ | programs.deploy | /openapi/v2/uns/streams/program/deploy | id、dryRun;建议 expectedRevision |
6
+ | programs.disable | /openapi/v2/uns/streams/program/disable | id、dryRun;建议 expectedRevision |
7
+ | programs.rollback | /openapi/v2/uns/streams/program/rollback | id、versionId、dryRun;建议 expectedRevision |
8
+ | documents.disable | /openapi/v2/uns/streams/documents/disable | id、expectedRevision、expectedActiveRelease、dryRun |
9
+
10
+ 全部写操作使用各自的 idempotencyKey。expectedSourceRevision 只适用于恰好一个 Source 依赖,且同时保护草稿冻结修订与当前 Source head;多源不能塞入单个修订值。原生文档没有 documents.deploy,当前云端 program 模型发布走 programs.deploy。
11
+
12
+ ```ts
13
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
14
+
15
+ export async function deployStream(id: string, intentKey: string, client: Tier0Client = createClient()) {
16
+ const { data: current } = await client.stream.documents.get({ id, view: 'full' });
17
+ if (!('document' in current)) throw new Error('需要完整 Stream 文档');
18
+ const sources = current.document.sources ?? [];
19
+ const request = {
20
+ id, expectedRevision: current.revision,
21
+ ...(sources.length === 1 ? { expectedSourceRevision: sources[0]!.configRevision } : {}),
22
+ };
23
+ const receipt = await client.stream.programs.deploy({
24
+ ...request, dryRun: false, idempotencyKey: intentKey,
25
+ });
26
+ if (typeof receipt.data.activeVersion !== 'string' || receipt.data.activeVersion === '0') {
27
+ throw new Error('未确认发布版本');
28
+ }
29
+ return { receipt, current: (await client.stream.documents.get({ id })).data,
30
+ observation: (await client.stream.observations.get({ id })).data };
31
+ }
32
+
33
+ export async function disableStream(id: string, intentKey: string, client: Tier0Client = createClient()) {
34
+ const { data: current } = await client.stream.documents.get({ id });
35
+ if (String(current.activeRelease) === '0') throw new Error('没有活跃发布可停用');
36
+ const receipt = await client.stream.documents.disable({
37
+ id, expectedRevision: current.revision, expectedActiveRelease: current.activeRelease,
38
+ dryRun: false, idempotencyKey: intentKey,
39
+ });
40
+ const after = await client.stream.documents.get({ id });
41
+ if (String(after.data.activeRelease) !== '0') throw new Error('停用读回未确认');
42
+ return { receipt, current: after.data };
43
+ }
44
+ ```
45
+
46
+ 发布成功不表示外部连接健康或每次执行成功;检查 observation 与执行记录。停用保留草稿。仅修改草稿的任务不额外发布/停用。
47
+
48
+ ## 回滚到明确版本
49
+
50
+ ```ts
51
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
52
+
53
+ export async function rollbackStream(
54
+ id: string, versionId: string, intentKey: string, client: Tier0Client = createClient(),
55
+ ) {
56
+ // versionId 必须先从 programs.versions.list({id,page,size}) 查询并选定。
57
+ const { data: current } = await client.stream.documents.get({ id });
58
+ return client.stream.programs.rollback({
59
+ id, versionId, expectedRevision: current.revision, dryRun: false, idempotencyKey: intentKey,
60
+ });
61
+ }
62
+ ```
63
+
64
+ 检查回执 activeVersion,并重新 get/observation。超时或 UnsV2OutcomeUnknownError 时先核对版本和观测,保留原请求意图键,不重复 deploy/rollback。预览用 dryRun=true,但不保证稍后的实际发布一定成功。
@@ -0,0 +1,26 @@
1
+ # Stream 样例测试与流程衔接
2
+
3
+ 完整流程按任务选取:[创建](create.md) → [查询](read.md) → [修改](update.md) → [发布/停用/回滚](deploy.md) → [删除](delete.md)。不要为了完成一次查询自动执行整套流程。
4
+
5
+ ## 原生文档样例测试
6
+
7
+ 方法:stream.sampleTest;输入 document、entryId、input。document 来自 documents.get 的完整草稿,entryId 必须在该文档注册的 entries 内。
8
+
9
+ ```ts
10
+ import { createClient, type Tier0Client, type UnsV2JSONValue } from '@tier0/sdk-v2';
11
+
12
+ export async function testStreamSample(
13
+ id: string, entryId: string, input: UnsV2JSONValue, client: Tier0Client = createClient(),
14
+ ) {
15
+ const { data: current } = await client.stream.documents.get({ id, view: 'full' });
16
+ if (!('document' in current)) throw new Error('需要完整 Stream 文档');
17
+ if (!current.document.entries?.some(entry => entry.id === entryId)) throw new Error('入口不在草稿中');
18
+ const response = await client.stream.sampleTest({ document: current.document, entryId, input });
19
+ return { status: response.data.status, errorCode: response.data.errorCode,
20
+ writes: response.data.writePreview, logs: response.data.logs, mode: response.data.mode };
21
+ }
22
+ ```
23
+
24
+ HTTP 成功也要检查 completed/failed 和 errorCode。模式为 isolated-sample,writePreview 不是线上写入;样例成功不能证明线上依赖健康。日志可能有业务数据,不直接公开。
25
+
26
+ 所有 Source/Stream 接口返回完整 code/msg/requestId/data。预检、草稿保存、发布回执和真实运行应分别记录;不要以 SDK 本地测试通过宣称完成真实环境联调。
@@ -0,0 +1,35 @@
1
+ # 查询 Stream
2
+
3
+ | 方法 | POST 路径 | 输入 | 结果 |
4
+ | --- | --- | --- | --- |
5
+ | programs.list | /openapi/v2/uns/streams/program/list | page、size、search、sourceId、model、status、archived | list、total、hasMore、nextPage |
6
+ | programs.get | /openapi/v2/uns/streams/program/get | id | 运行摘要,document 已脱敏 |
7
+ | documents.get | /openapi/v2/uns/streams/documents/get | id | 完整草稿、revision、status、activeRelease、可选 activeDocument |
8
+ | observations.get | /openapi/v2/uns/streams/observation/get | id | 运行观测 |
9
+ | runs.list | /openapi/v2/uns/streams/runs/list | id、size、cursor | 执行记录 |
10
+ | programs.versions.list | /openapi/v2/uns/streams/program/versions/list | id、page、size | list、total,含 versionId |
11
+
12
+ page 从 1 开始,size 最大 200。完整文档需要 Stream manage 权限;programs.get 的 scriptConfigured 不是脚本内容,不能据此重建草稿。
13
+
14
+ ```ts
15
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
16
+
17
+ export async function readStream(id: string, client: Tier0Client = createClient()) {
18
+ const draft = await client.stream.documents.get({ id });
19
+ const summary = await client.stream.programs.get({ id });
20
+ const observation = await client.stream.observations.get({ id });
21
+ return { draft: draft.data, summary: summary.data, observation: observation.data };
22
+ }
23
+ export async function* listStreams(client: Tier0Client = createClient()) {
24
+ let page = 1;
25
+ while (true) {
26
+ const { data } = await client.stream.programs.list({ page, size: 100, archived: false });
27
+ yield data.list;
28
+ if (!data.hasMore) return;
29
+ if (typeof data.nextPage !== 'number' || data.nextPage <= page) throw new Error('无有效下一页');
30
+ page = data.nextPage;
31
+ }
32
+ }
33
+ ```
34
+
35
+ 保存、发布、某次执行成功是三个事实。显示实际 revision/activeVersion/release,不用旧 runs 证明新版本生效。版本列表不保证与普通列表相同分页结构;按其 list/total/page/size 读取,versionId 不是 release 序号。
@@ -0,0 +1,36 @@
1
+ # 修改 Stream 草稿
2
+
3
+ 方法:`stream.documents.update`;POST `/openapi/v2/uns/streams/documents/update`。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | id | string | 是 | 十进制字符串 |
8
+ | document | CloudStreamDocument | 是 | name、model、script、sources、entries 完整文档 |
9
+ | expectedRevision | integer | 建议始终提供 | get 返回修订,防止覆盖他人修改 |
10
+ | dryRun | boolean | 是 | true 预检;false 保存 |
11
+ | idempotencyKey | string | 否 | 本次更新独立意图键 |
12
+
13
+ ## 示例:更新描述,保持脚本和绑定
14
+
15
+ ```ts
16
+ import { createClient, type Tier0Client, type CloudStreamDocument } from '@tier0/sdk-v2';
17
+
18
+ export async function updateStreamDescription(
19
+ id: string, description: string, intentKey: string, client: Tier0Client = createClient(),
20
+ ) {
21
+ const { data: current } = await client.stream.documents.get({ id, view: 'full' });
22
+ if (!('document' in current)) throw new Error('需要完整 Stream 文档');
23
+ const document: CloudStreamDocument = { ...current.document, description };
24
+ const checked = await client.stream.documents.validate({ document });
25
+ if (!checked.data.valid) throw new Error('Stream 文档校验失败,请检查 issues');
26
+ const saved = await client.stream.documents.update({
27
+ id, expectedRevision: current.revision, document, dryRun: false, idempotencyKey: intentKey,
28
+ });
29
+ if (!('id' in saved.data)) throw new Error('未返回已保存文档');
30
+ return { receipt: saved, current: (await client.stream.documents.get({ id })).data };
31
+ }
32
+ ```
33
+
34
+ 需要改脚本时构造 `{ ...current.document, script: { ...current.document.script, code: newCode } }`,保留 sdkVersion/timeoutMs;变更入口或绑定时同步修改 entries/sources 并重新 validate。不要对脱敏 programs.get.document 做展开更新。
35
+
36
+ 响应是完整 CloudStreamDocumentView 或预检结果;保存草稿不会自动部署,activeDocument 可能仍是旧发布版本。VERSION_CONFLICT 后重新读取、比较并决策;不无条件覆盖。下一步发布见[部署](deploy.md)。
@@ -0,0 +1,64 @@
1
+ ---
2
+ name: tier0-sdk-v2-system
3
+ description: 使用 @tier0/sdk-v2 查询 Tier0 凭证身份、平台版本、MQTT Broker 与能力就绪状态,区分身份、授权、发布开关和实际可用性。
4
+ ---
5
+
6
+ # 系统与能力发现
7
+
8
+ | 任务 | 参考 |
9
+ | --- | --- |
10
+ | 诊断 Key 所属 Workspace 和权限 | [whoami](references/whoami.md) |
11
+ | 查看平台版本、解析 Broker 地址 | [info](references/info.md) |
12
+
13
+ v1 的内部 reload 接口不属于 v2 公共 SDK,不能在普通诊断时调用。
14
+
15
+ 使用服务端 `createClient()` 或显式传入 apiHost/apiKey。系统排查从只读信息开始,不因功能不可用自动创建 Key、修改权限或部署服务。
16
+
17
+ ## 最小诊断
18
+
19
+ ```ts
20
+ import { createClient } from '@tier0/sdk-v2';
21
+
22
+ export async function diagnose() {
23
+ const client = createClient();
24
+ const identity = await client.system.whoami();
25
+ const info = await client.system.info();
26
+ const discovery = await client.capabilities.discover();
27
+ return {
28
+ workspaceId: String(identity.workspaceID),
29
+ keyType: identity.keyType,
30
+ platformVersion: info.version,
31
+ capabilities: discovery.capabilities.map(item => ({
32
+ code: item.code, state: item.state, allowed: item.allowed,
33
+ availability: item.availability,
34
+ })),
35
+ };
36
+ }
37
+ ```
38
+
39
+ whoami 返回 Key 关联的主体与 Workspace,包括 userID、workspaceID、permissions、roles、keyType;它不是当前浏览器员工的身份证明。不要将关联 userID 当作 App 请求的当前访问者。
40
+
41
+ info 返回 name/version/mqttBroker/capabilities,字段可能省略。MQTT broker 地址先用 `toWebSocketUrl` 转换,详见 [MQTT](../tier0-sdk-v2-mq/SKILL.md)。info 中的 capabilities 字符串列表不替代完整能力发现。
42
+
43
+ ## 读懂能力结果
44
+
45
+ | 字段/状态 | 判断 |
46
+ | --- | --- |
47
+ | releaseEnabled | 平台/Workspace 发布开关,不代表运行时已准备好 |
48
+ | allowed | 当前身份的授权摘要,不是所有具体 Control 的执行许可 |
49
+ | enabled、state=ready | 服务端评估就绪 |
50
+ | availability=available | 能力可用性,不是设备在线、业务执行或 ACK |
51
+ | disabled / not_supported / unavailable | 展示具体不可用原因,不强制调用 |
52
+ | readiness_unknown | 保留未知状态,不能按成功处理 |
53
+
54
+ 能力目录当前识别 namespace.v2、source.v1、stream.v2、control.v1、control.invoke.v1。contractVersions、apiContractVersions、sdkContractVersions 是契约标签,不是 npm 包版本;productVersion 未配置时可缺省。
55
+
56
+ ## 定位问题
57
+
58
+ - 401/403:核对目标 Host、Key 对应 Workspace 和所需权限;不输出完整 Key。
59
+ - 方法存在但能力关闭:记录 code/state/availability,检查该环境的部署与配置,不能凭本地生成文件推断线上已支持。
60
+ - `CapabilityError`:保留 status/errorCode;不支持的契约版本与错误响应格式需要排查服务端/SDK 配套版本。
61
+ - 系统普通 API 使用 `ApiError`,HTTP 200 的业务失败仍会抛错。
62
+ - 仅上报排查需要的字段;whoami 中的邮箱、角色和 Key 前缀不应无差别返回给浏览器。
63
+
64
+ 需要 Source/Stream 运行健康信息时,进一步使用对应领域的 observations/runs;系统能力就绪只说明可以进入该领域流程。
@@ -0,0 +1,23 @@
1
+ # 服务信息与 MQTT 地址
2
+
3
+ 方法:`system.info()`;POST /openapi/v1/info,无业务参数。
4
+
5
+ ```ts
6
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
7
+ import { parseMqttBroker, toWebSocketUrl } from '@tier0/sdk-v2/mq';
8
+
9
+ export async function inspectService(client: Tier0Client = createClient()) {
10
+ const info = await client.system.info();
11
+ const endpoint = parseMqttBroker(info.mqttBroker);
12
+ return {
13
+ name: info.name, version: info.version, capabilities: info.capabilities,
14
+ mqtt: endpoint && info.mqttBroker ? toWebSocketUrl(info.mqttBroker) : undefined,
15
+ };
16
+ }
17
+ ```
18
+
19
+ 返回已解包对象,name/version/capabilities/mqttBroker 均可能省略。mqttBroker 是连接串,可能裸 host、host:port、tcp://host:1883 或完整 ws/wss,不能直接拼 wss:// 前缀。toWebSocketUrl 保留已有 WebSocket URL;TCP 端口不直接复用为 WebSocket 端口。实际端口/路径由环境决定。
20
+
21
+ info.capabilities 的简略字符串列表不是就绪证明。进一步读取 client.capabilities.discover 的 releaseEnabled、allowed、state、availability,区分开关、授权与运行能力;详见[系统 Skill](../SKILL.md)。
22
+
23
+ v1 的 /gw/reload 是内部管理操作,未纳入 v2 公共 SDK,不复制旧 reload 示例,也不在连通性诊断中尝试重载服务。
@@ -0,0 +1,21 @@
1
+ # API Key 身份诊断
2
+
3
+ 方法:`system.whoami()`;POST /openapi/v1/auth/whoami,无业务参数。不是调用其他 API 的强制前置步骤。
4
+
5
+ ```ts
6
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
7
+
8
+ export async function inspectCredential(client: Tier0Client = createClient()) {
9
+ const identity = await client.system.whoami();
10
+ return {
11
+ workspaceId: String(identity.workspaceID), workspaceName: identity.workspaceName,
12
+ keyType: identity.keyType, permissions: identity.permissions, roles: identity.roles,
13
+ };
14
+ }
15
+ ```
16
+
17
+ 返回已解包的 userID/userName/email/workspaceID/workspaceName/apiKeyName/keyPrefix/permissions/roles/keyType。v2 对大整数保留 number|bigint,不能套用 v1 “一定已经丢精度”的描述;需要字符串时用 String,不先转 Number。
18
+
19
+ App Key 是共享业务凭证,不代表访问 App 的自然人。whoami 不能用于登录、当前用户、操作人审计或选择通知收件人;当前人来自应用认证会话,收件人从成员数据解析。
20
+
21
+ 401 核对 Host/Key,403 核对权限;不要输出完整 Key、无差别展示邮箱或所有角色,也不自动换更高权限身份。
@@ -0,0 +1,55 @@
1
+ ---
2
+ name: tier0-sdk-v2-uns
3
+ description: 使用 @tier0/sdk-v2 的 client.uns 完成新架构集合、Schema、目录、Topic、Record 增删改查、归档恢复、采样历史与事务,区分 App 和 Workspace 数据权限。
4
+ ---
5
+
6
+ # UNS 数据操作
7
+
8
+ UNS 管数据命名空间、集合、Record 和 Sample;外部连接与脚本分别用 [Source](../tier0-sdk-v2-source/SKILL.md)、[Stream](../tier0-sdk-v2-stream/SKILL.md)。服务端 `createClient()` 读取 TIER0_API_HOST / TIER0_API_KEY,或显式传 apiHost/apiKey。数据权限不自动授予管理权限:管理操作中 App 凭证只能调用本 App 集合的 appCollectionsEnsure / SchemaReplace / Archive / Restore;appDataPolicyGet/Update 的调用方必须是持有 uns.write 的登录会话、持有 uns.write 且 full_access、不绑定 App 的 personal / agent Key,或治理会话;运行时 App 凭证不能管理数据授权。
9
+
10
+ ## 按任务加载参考
11
+
12
+ | 用户任务 | 参考 | 方法 |
13
+ | --- | --- | --- |
14
+ | 创建集合、定义 Schema、新增记录 | [创建](references/create.md) | metadataInsertOne/Many、recordInsertOne |
15
+ | 查询集合、筛选/排序记录 | [查询](references/read.md) | dataAppContext、metadataFind/FindOne(非 App 凭证)、collectionDescribe、recordFind |
16
+ | 改记录、集合名称、扩展 Schema | [修改](references/update.md) | recordUpdateOne、metadataUpdateOne/Many、metadataFindOneAndUpdate |
17
+ | 删记录、软删除集合 | [删除](references/delete.md) | recordDeleteOne、metadataDeleteOne/Many |
18
+ | 恢复集合或记录 | [恢复](references/restore.md) | metadataRestore、recordRestore |
19
+ | 分页、历史采样、事务、写入结果 | [数据工作流](references/data-workflows.md) | sampleFind、recordTransactionExecute |
20
+ | 目录、Topic 元数据及组合事务 | [命名空间](references/namespace.md) | metadata*、metadataBulkWrite、metadataTransact |
21
+
22
+ ## 找到正确数据上下文
23
+
24
+ 托管 App 使用 dataAppContext,按业务 alias 精确选择授权集合;它同时给出每个集合的 revision、索引就绪状态(indexStatus)、TTL 和平台限额(limits)。App 凭证不能调用 metadataFind/FindOne、async 模式与 jobs 查询;Workspace 集成(会话、personal / agent Key)用 dataDiscover/metadataFind,不强制 App 上下文。通用元数据管理写入不向 App 凭证开放。App 自有业务数据优先用 [App 数据层](../tier0-sdk-v2-data/SKILL.md)(`@tier0/sdk-v2/data`),变更订阅只在那里提供(`data.subscribe`)。
25
+
26
+ ```ts
27
+ import { createClient } from '@tier0/sdk-v2';
28
+
29
+ export async function findAppCollection(alias: string) {
30
+ const client = createClient();
31
+ const context = await client.uns.dataAppContext({});
32
+ const collection = context.data.collections.find(item => item.alias === alias);
33
+ if (!collection) throw new Error('当前 App 未获得目标集合授权');
34
+ return client.uns.collectionDescribe({ collectionId: collection.collectionId });
35
+ }
36
+ ```
37
+
38
+ 不要把 alias/名称当 collectionId,不猜第一个集合是业务目标。
39
+
40
+ 平台签发的 App Key 声明本 App 自有集合使用 appCollectionsEnsure,修改结构、停用及恢复分别使用 appCollectionsSchemaReplace/Archive/Restore;这些保留专用 App 归属和授权语义,不能改成 metadataInsertOne 或普通元数据写入。会话或个人 Key 查询自有集合使用 appCollectionsList。Builder 创建普通授权集合可在 metadataInsertOne 中提供 appId/alias,具体凭证与权限由服务端复验。
41
+
42
+ ## 核心约束
43
+
44
+ 1. 记录行是 id/data/revision;filter 与 update 的业务路径用 name、customer.name,不加 data.;系统路径用 _id、_meta.revision。
45
+ 2. 改/删前读取 expectedRevision;不同操作使用独立意图键,长度上限以当前操作契约为准。
46
+ 3. metadataUpdateOne 的 $set.recordSchema 替换完整 Schema,不迁移已有记录;未更新的 sampleSchema/indexes 保留。先预检兼容性。
47
+ 4. 集合无硬删除入口,用 metadataDeleteOne/Many 软删除;Record 删除会物理删除关联 Sample,恢复 Record 不会恢复这些 Sample。
48
+ 5. recordFind 使用 pageInfo.hasMore/nextCursor,limit 1–200;sort 为 [['field',1]]。单页不是全量,跨页不是稳定快照。
49
+ 6. Sample 的时间是 Unix 毫秒,查询范围 [from,to)。Record 代表业务实体,不用覆盖它来保存历史。
50
+
51
+ ## 结果与异常
52
+
53
+ 响应为 code/msg/requestId/data。元数据 find 返回 items/pageInfo;findOne 与 findOneAnd* 返回 value;普通写入返回对应计数和 ID。metadataTransact 的 results 按 opId 对应。检查 committed、每项错误和实际计数;dryRun 只校验。metadataBulkWrite 默认原子,显式非原子时必须逐项检查 results/errors;跨 kind 的依赖写入使用 metadataTransact。recordBulkWrite 不保证跨集合事务。
54
+
55
+ 大整数与 JSON 精确数字可能为 bigint/UnsV2RawNumber;保留读取到的 revision 类型,不用 Number 或普通 JSON.stringify 做无损往返。错误带 execution(notStarted / rolledBack / committed / unknown)与 retry(safe、afterMs)。UnsV2OutcomeUnknownError(execution 为 unknown)先读回核对内容;retry.safe 时可以用同一请求、同一幂等键原样重发。取消请求不撤销写入;client.uns 不自动重试。
@@ -0,0 +1,56 @@
1
+ # 创建集合与记录
2
+
3
+ 元数据使用 metadataInsertOne(POST /openapi/v2/uns/metadata)或 metadataInsertMany;kind 指定 directory/topic/collection。单条提供 data、可选 id;批量提供同一 kind 的 documents[{id?,data}]。idempotencyKey 标识一个写入意图;dryRun=true 仅校验。schemaVersion 由服务端赋默认值。
4
+
5
+ 集合 data 必须包含 name、recordSchema,可选 description、parentId、sampleSchema、indexes、semantics。parentId=null 表示根目录。索引创建后仍需确认状态为 ready。
6
+
7
+ ```ts
8
+ import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
9
+
10
+ export async function createDeviceCollection(
11
+ collectionId: string, name: string, intentKey: string, client: Tier0Client = createClient(),
12
+ ) {
13
+ const request: UnsV2Request<'metadataInsertOne'> = {
14
+ kind: 'collection', id: collectionId,
15
+ data: {
16
+ name, parentId: null,
17
+ recordSchema: {
18
+ type: 'object', additionalProperties: false, required: ['name', 'enabled'],
19
+ properties: { name: { type: 'string' }, enabled: { type: 'boolean' } },
20
+ },
21
+ sampleSchema: {
22
+ type: 'object', additionalProperties: false, required: ['temperature'],
23
+ properties: { temperature: { type: 'number', unit: '°C' } },
24
+ },
25
+ },
26
+ };
27
+ const preview = await client.uns.metadataInsertOne({ ...request, dryRun: true });
28
+ if (preview.data.status !== 'validated') throw new Error('集合预检未通过');
29
+ const receipt = await client.uns.metadataInsertOne({ ...request, dryRun: false, idempotencyKey: intentKey });
30
+ if (receipt.data.status !== 'committed') return { state: 'unconfirmed' as const, receipt };
31
+ const current = await client.uns.metadataFindOne({ kind: 'collection', filter: { _id: collectionId } });
32
+ if (!current.data.value) throw new Error('集合创建有回执,读回未确认');
33
+ return { state: 'committed' as const, receipt, current: current.data.value };
34
+ }
35
+ ```
36
+
37
+ 单条新增返回 insertedId/status/replayed;批量新增返回 insertedCount/insertedIds 及适用的逐项错误。insertedIds 的键是原始输入从 0 开始的索引。省略自定义 ID 时从成功回执取得实际 ID,不能把名称当成 ID。
38
+
39
+ ```ts
40
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
41
+
42
+ export async function insertDevice(
43
+ collectionId: string, id: string, name: string, intentKey: string,
44
+ client: Tier0Client = createClient(),
45
+ ) {
46
+ const receipt = await client.uns.recordInsertOne({
47
+ collectionId, id, data: { name, enabled: true }, dryRun: false, idempotencyKey: intentKey,
48
+ });
49
+ if (receipt.data.status !== 'committed') return { state: 'unconfirmed' as const, receipt };
50
+ const found = await client.uns.recordFind({ collectionId, filter: { _id: receipt.data.insertedId }, limit: 1 });
51
+ if (!found.data.items[0]) throw new Error('新增有回执,但读回未找到记录');
52
+ return { state: 'committed' as const, receipt, current: found.data.items[0] };
53
+ }
54
+ ```
55
+
56
+ 记录创建与集合创建使用不同意图键。未知结果先按 ID 核对内容,不仅检查存在;SDK 不自动重试。