@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,78 @@
1
+ ---
2
+ name: tier0-sdk-v2-mq
3
+ description: 使用 @tier0/sdk-v2/mq 连接 Tier0 MQTT WebSocket Broker,管理凭证、订阅和发布消息、清理连接及处理背压;不替代 Source 配置或 Stream 执行。
4
+ ---
5
+
6
+ # MQTT 实时消息
7
+
8
+ 连接配置、完整订阅生命周期、通配符、发布及鉴权排查见 [Quickstart](references/quickstart.md)。v1 的旧 UNS 路径/字段规则不适用于新架构;实际 MQTT 映射需按目标环境确认。
9
+
10
+ `Tier0MQClient` 从独立子入口导入。它面向消息客户端;配置平台采集连接用 Source,运行处理逻辑用 Stream。HTTP SDK 的“不自动重试”不等于 MQTT 禁用重连或 QoS 重投递。
11
+
12
+ ## 使用已有凭证订阅
13
+
14
+ ```ts
15
+ import { Tier0MQClient, toWebSocketUrl, type TopicHandler } from '@tier0/sdk-v2/mq';
16
+
17
+ export async function watchTopic(
18
+ broker: string,
19
+ credentials: { clientID: string; username: string; password: string },
20
+ topic: string,
21
+ handle: TopicHandler,
22
+ ) {
23
+ const mq = new Tier0MQClient({
24
+ host: toWebSocketUrl(broker),
25
+ clientId: credentials.clientID,
26
+ username: credentials.username,
27
+ password: credentials.password,
28
+ reconnectPeriod: 1000,
29
+ });
30
+ mq.on('error', error => console.error(error.name));
31
+ await mq.connect();
32
+ mq.subscribe(topic, handle);
33
+ return () => {
34
+ mq.unsubscribe(topic, handle);
35
+ mq.disconnect();
36
+ };
37
+ }
38
+ ```
39
+
40
+ broker 可来自 `client.system.info().mqttBroker`,先检查字段存在。保留已有 ws/wss URL 的端口和路径;HTTP 页面与 TLS/混合内容策略按实际部署配置,不能简单把 TCP 端口当 WebSocket 端口。
41
+
42
+ subscribe 返回 void,错误通过 error 事件报告;回调参数是 topic 和字符串 payload。按业务格式解析 JSON,非法消息应隔离处理,避免一条坏消息打断消费。多个组件共享连接时,只清理自己的 handler,不直接 disconnect 其他订阅。
43
+
44
+ ## 凭证生命周期
45
+
46
+ ```ts
47
+ import { createClient } from '@tier0/sdk-v2';
48
+
49
+ export async function provisionMqttCredential(name: string) {
50
+ return createClient().mqttAuth.create({ name });
51
+ }
52
+ export async function revokeMqttCredential(id: number | bigint) {
53
+ return createClient().mqttAuth.delete({ id });
54
+ }
55
+ ```
56
+
57
+ 仅在任务需要创建凭证时使用 create,普通订阅重用已有受控凭证。完整 username/password/clientID 只在创建时返回一次,按秘密管理,别写日志。SDK 配置的 clientId 小写 d,接口回执的 clientID 大写 ID。
58
+
59
+ 也可从编码了 Workspace 的平台 Key 推导 MQTT 身份;无法解析的 Key 会拒绝连接,不回退到 Enterprise 身份。浏览器场景须使用针对当前用户/主题授权的凭证方案,不能为了省事下发长期 App Key。
60
+
61
+ ## 发布与确认边界
62
+
63
+ ```ts
64
+ import { Tier0MQClient } from '@tier0/sdk-v2/mq';
65
+
66
+ export async function publishMeasurement(mq: Tier0MQClient, topic: string, value: number) {
67
+ if (!Number.isFinite(value)) throw new Error('非法测量值');
68
+ await mq.publish(topic, { value, time: Date.now() }, { qos: 1, retain: false });
69
+ }
70
+ ```
71
+
72
+ publish 目前在建立连接并调用 MQTT 库发布后返回,不等待业务执行确认,也不保证已收到 broker PUBACK。需要闭环时使用业务 ACK 主题/关联 ID 或 Control 契约,不能把 Promise resolve 当成设备执行完成。
73
+
74
+ 订阅内部 QoS 为 1;发布默认 QoS 0、retain=false。业务消费者需考虑重复消息。对象 payload 经 JSON.stringify,不能直接包含 bigint;按协议约定编码精确值,不假设 MQTT 自动使用 UNS 的无损 codec。
75
+
76
+ ## 清理与背压
77
+
78
+ 组件卸载/任务结束时用原 handler 退订,连接归当前任务独占时再 disconnect。可配置 maxBackpressuredDeliveries;handler 连续同步返回严格 false 达到阈值后会移除订阅并触发 subscriptionDropped。异步 Promise 的 false 不等同同步背压信号。通过 isConnected/subscribedTopics 观察本地连接状态,不把它当作服务器完整订阅清单。
@@ -0,0 +1,69 @@
1
+ # MQTT 连接、订阅与清理
2
+
3
+ 入口:@tier0/sdk-v2/mq。使用 Tier0 平台 Broker 和已授权的真实主题;配置外部采集源转 Source,处理脚本转 Stream。
4
+
5
+ | 配置 | 类型 | 说明 |
6
+ | --- | --- | --- |
7
+ | host | string | 完整 ws/wss URL,或通过 toWebSocketUrl 解析 |
8
+ | clientId / username / password | string | 显式凭据;不要暴露到日志 |
9
+ | reconnectPeriod | number | MQTT 重连间隔,与 HTTP 无重试不同 |
10
+ | connectTimeout / keepAlive | number | 连接超时/保活配置 |
11
+ | maxBackpressuredDeliveries | number | handler 连续同步返回 false 的退订阈值 |
12
+
13
+ Broker 可从 system.info().mqttBroker 获取。用 parseMqttBroker/toWebSocketUrl,不手工解析 scheme 或把 TCP 1883 当 WebSocket 端口;显式环境地址优先。平台 Key 可派生身份,但浏览器不得接收长期 App Key。
14
+
15
+ ```ts
16
+ import { Tier0MQClient, toWebSocketUrl, type TopicHandler } from '@tier0/sdk-v2/mq';
17
+
18
+ export async function subscribeTelemetry(
19
+ broker: string, credentials: { clientID: string; username: string; password: string },
20
+ filter: string, onValue: (topic: string, value: unknown) => void,
21
+ onError: (error: Error) => void,
22
+ ) {
23
+ const mq = new Tier0MQClient({
24
+ host: toWebSocketUrl(broker), clientId: credentials.clientID,
25
+ username: credentials.username, password: credentials.password,
26
+ reconnectPeriod: 1000, maxBackpressuredDeliveries: 10,
27
+ });
28
+ const handler: TopicHandler = (topic, payload) => {
29
+ let value: unknown;
30
+ try { value = JSON.parse(payload); }
31
+ catch { onError(new Error('消息不是有效 JSON')); return; }
32
+ onValue(topic, value);
33
+ };
34
+ mq.on('error', onError);
35
+ try {
36
+ await mq.connect();
37
+ mq.subscribe(filter, handler);
38
+ } catch (error) {
39
+ mq.disconnect();
40
+ throw error;
41
+ }
42
+ return () => { mq.unsubscribe(filter, handler); mq.disconnect(); };
43
+ }
44
+ ```
45
+
46
+ 回调是 (topic,payload),payload 为字符串。subscribe 返回 void,订阅失败通过 error 事件,不把函数返回当 broker SUBACK。此例独占连接;共享连接只退订自己的 handler,不关闭其他消费者。
47
+
48
+ + 匹配一层,# 匹配多层,订阅范围必须属于任务和主题授权。不能从旧 v1 的 Metric/Action/State 路径、enableHistory 或字段规则推断新 UNS MQTT 映射;先核实目标平台的实际主题和消息契约。App 服务端订阅新 UNS Record 变更用 `@tier0/sdk-v2/data` 的 `data.subscribe`(`records:subscribe` 服务端推送),不是 MQTT 主题。
49
+
50
+ ## 发布
51
+
52
+ ```ts
53
+ import { Tier0MQClient } from '@tier0/sdk-v2/mq';
54
+
55
+ export async function publishEvent(mq: Tier0MQClient, topic: string, eventId: string, value: number) {
56
+ if (!Number.isFinite(value)) throw new Error('测量值非法');
57
+ await mq.publish(topic, { eventId, value }, { qos: 1, retain: false });
58
+ }
59
+ ```
60
+
61
+ payload 必须符合实际主题契约;对象用 JSON.stringify,不可包含 bigint。publish resolve 不证明已收 PUBACK,更不证明设备执行;业务闭环用关联 ID/ACK 或 Control。订阅 QoS 1,发布默认 QoS 0/retain=false,消费端考虑重复消息。
62
+
63
+ ## 事件、背压和鉴权
64
+
65
+ connect/disconnect/error/message/subscriptionDropped 反映客户端状态。isConnected/subscribedTopics 不是服务器全量状态。连续同步返回严格 false 才触发背压计数,Promise<false> 不等价;消费者不应无限缓存。
66
+
67
+ 创建凭据用 client.mqttAuth.create({name}),撤销用 delete({id}),检查 success。回执的 clientID 对应配置 clientId;完整密码只在创建时返回一次,受控保存。
68
+
69
+ Not authorized/CONNACK 5/重连循环时核对注入的 Key 类型、过期/撤销、授权和 Broker ws/wss 地址。v2 不回退 Enterprise 身份,也不套用旧包升级到 @tier0/sdk@latest 的建议;不因连接失败自动新建凭据。
@@ -0,0 +1,42 @@
1
+ ---
2
+ name: tier0-sdk-v2-notifications
3
+ description: 使用 @tier0/sdk-v2 发送和查询 Tier0 站内通知、Web/Desktop 提醒及 Mobile 推送,解析收件人,处理发送者、渠道、业务幂等与投递状态。
4
+ ---
5
+
6
+ # 通知
7
+
8
+ 服务端使用 `createClient()` 读取 TIER0_API_HOST / TIER0_API_KEY,或显式传 apiHost/apiKey。发送必须符合用户已授权的收件人和内容范围,查询状态不自动补发。
9
+
10
+ | 任务 | 参考 | 方法 |
11
+ | --- | --- | --- |
12
+ | 收件人选择、完整发送、渠道、模式、错误 | [发送](references/send.md) | notifications.send |
13
+ | 查询回执、有界等待投递完成 | [查询](references/get.md) | notifications.get |
14
+ | 按姓名或邮箱查收件人 | [成员](../tier0-sdk-v2-members/SKILL.md) | members.listWorkspace |
15
+
16
+ ## 核心约束
17
+
18
+ - type 固定 inbox;Swagger 的 string 不代表接受任意类型。
19
+ - 用人读姓名/邮箱选择收件人,ID 由成员数据解析并保持字符串,不让用户填写 ID。Workspace 成员不等于 App 可访问用户。
20
+ - title 最多50字符,content 最多800字符。mode 按真实发布环境选择 test/live;test 会创建测试消息,不能当预检。
21
+ - App sender 使用 getCurrentAppId() 的真实 APP_ID,v2 不注入 project 上下文,不复制旧 getCurrentProjectId。导航和名称展示按目标前端支持核实。
22
+ - sender/link/meta 是展示提示,不作为授权。新代码不使用废弃 source 字段。
23
+ - 同一业务事件、收件人、内容使用稳定 idempotencyKey;新事件使用新键,不因超时随机换键。
24
+
25
+ ## 渠道
26
+
27
+ | channels | 提醒范围 |
28
+ | --- | --- |
29
+ | 省略 | SDK 默认 web + mobile |
30
+ | ['web'] | Web/Desktop |
31
+ | ['mobile'] | 手机 |
32
+ | [] | 只建站内信 |
33
+
34
+ Desktop 属于 web,不存在 desktop 渠道。显式单渠道不补齐,重复项会去重。SDK 默认和裸后端省略参数的行为不同,不混用。
35
+
36
+ ## 返回与失败
37
+
38
+ send 返回直接对象 {messageId,status,createdAt},get 返回直接状态对象,没有 data 外层。accepted 表示受理,sent 表示已发送,不是用户已读;failed 检查 errorCode/message。
39
+
40
+ v2 ApiError 提供 status/errorCode/msg;不要沿用 v1 JSON.parse(error.msg) 的旧解析方式。未知结果先对账;已有 messageId 按 ID 查,没有按 idempotencyKey 查询的 SDK 入口。HTTP SDK 不自动重试。
41
+
42
+ 完整示例与参数边界均在操作参考中。Skill 示例不会自动发送消息,也不授予真实发送权限。
@@ -0,0 +1,34 @@
1
+ # 查询通知投递状态
2
+
3
+ 方法:`notifications.get({messageId})`;POST /openapi/v1/notifications/get。需要 notifications:read,与 send 权限独立;仅查询当前发送 Key 可见的消息。
4
+
5
+ | 参数/结果 | 类型 | 说明 |
6
+ | --- | --- | --- |
7
+ | messageId | string | 发送回执 ID,不转 Number |
8
+ | status | string | accepted / sent / failed |
9
+ | createdAt / completedAt | string | ISO 时间,completedAt 可省略 |
10
+ | errorCode / message | string | 失败原因,可省略 |
11
+
12
+ ```ts
13
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
14
+
15
+ export async function waitForNotification(
16
+ messageId: string, client: Tier0Client = createClient(), maxAttempts = 10,
17
+ ) {
18
+ if (!Number.isInteger(maxAttempts) || maxAttempts < 1 || maxAttempts > 20) {
19
+ throw new Error('查询次数应为 1–20');
20
+ }
21
+ for (let attempt = 0; attempt < maxAttempts; attempt++) {
22
+ const result = await client.notifications.get({ messageId });
23
+ if (result.status === 'sent' || result.status === 'failed') return result;
24
+ if (result.status !== 'accepted') throw new Error('未识别的通知状态');
25
+ if (attempt === maxAttempts - 1) return result;
26
+ await new Promise(resolve => setTimeout(resolve, 1500));
27
+ }
28
+ throw new Error('未取得通知状态');
29
+ }
30
+ ```
31
+
32
+ accepted 表示仍处理,达到次数上限就返回处理中;sent 表示站内信已创建、推送交给渠道,不代表用户收到或阅读。failed 显示 errorCode/message,不继续当成功。
33
+
34
+ 返回直接对象,不读取 result.data。404 MESSAGE_NOT_FOUND 也可能是发送 Key 不同,不能直接断言消息丢失;先核对原 messageId 与发送身份。查询任务不自动补发。
@@ -0,0 +1,72 @@
1
+ # 发送通知
2
+
3
+ 方法:`notifications.send(body)`;POST /openapi/v1/notifications/send。需要 notifications:send;收件人为当前 Workspace 内可用的成员,按[成员查询](../../tier0-sdk-v2-members/references/platform-members.md)解析。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | recipientUserId | string | 是 | 已解析的用户 ID,保持字符串 |
8
+ | type | inbox | 是 | 后端只接受 inbox;不是 business |
9
+ | title | string | 是 | 1–50 字符 |
10
+ | content | string | 是 | 1–800 字符 |
11
+ | idempotencyKey | string | 是 | 最多 128 字符;同一次业务事件固定 |
12
+ | mode | test/live | 否 | 根据实际发布环境显式选择;省略服务端默认 live |
13
+ | channels | array | 否 | SDK 省略补 web+mobile;[] 仅站内信 |
14
+ | sender | object | 否 | app/other;system 仅平台内部服务 Key |
15
+ | link | string | 否 | https:// 或单斜杠开头,最多 500 字符 |
16
+
17
+ ## 完整 App 示例
18
+
19
+ 下面函数供应用在已授权的业务事件中调用;写示例不意味着发送真实消息。intentKey 应包含收件人、业务对象和事件版本,不因网络重试换键。
20
+
21
+ ```ts
22
+ import { createClient, getCurrentAppId, type Tier0Client } from '@tier0/sdk-v2';
23
+
24
+ export async function sendCompletedOrder(
25
+ recipientUserId: string, orderId: string, intentKey: string, mode: 'test' | 'live',
26
+ client: Tier0Client = createClient(),
27
+ ) {
28
+ return client.notifications.send({
29
+ recipientUserId, type: 'inbox', title: '工单已完成',
30
+ content: '工单 ' + orderId + ' 已完成,请查看处理结果。',
31
+ idempotencyKey: intentKey, mode, channels: ['web', 'mobile'],
32
+ sender: { type: 'app', id: getCurrentAppId() },
33
+ });
34
+ }
35
+ ```
36
+
37
+ sender.id 来自真实 APP_ID UUID。v2 不注入 project 上下文,也没有 getCurrentProjectId;不要把 Folder/Workspace ID 填进 meta.projectId。旧 UI 的 App 名称解析/打开 App 按钮依赖 appId+projectId,不能将旧导航规则原样承诺到新架构。需带链接时传已验证可访问的业务 https 地址,或确认目标前端支持的相对路由;缺少旧上下文时不猜拼地址。
38
+
39
+ other 发送者应给人读名称,如 `{type:'other',name:'库存同步服务'}`。app 不重复硬编码名称。sender/meta/link 都是展示导航提示,不是授权证明。meta 值为字符串,序列化最多 500 字节;sender.name 最多100字符。source 是废弃别名,不用于新代码。
40
+
41
+ ## 渠道、模式与幂等
42
+
43
+ | channels | 提醒范围 |
44
+ | --- | --- |
45
+ | 省略 | SDK 显式发送 web+mobile |
46
+ | ['web'] | Web/Desktop |
47
+ | ['mobile'] | 手机 |
48
+ | [] | 只建站内信 |
49
+ | 重复项 | SDK 去重 |
50
+
51
+ 没有 desktop 渠道。不要将 SDK 默认值与裸后端省略渠道的静默语义混淆。test 也会创建测试消息,不是 dryRun;仅因 NODE_ENV=production 不能证明 App 已发布。
52
+
53
+ 同键同内容用于重放原意图;同键改内容产生冲突。新事件/不同收件人使用不同键。SDK 不自动重试,结果未知先对账;已有 messageId 用 get,没有按意图键查询的 SDK 方法。
54
+
55
+ ## 回执与错误
56
+
57
+ 成功为直接 {messageId,status,createdAt},没有 data。accepted 是异步受理,sent 不是已读,详见[查询](get.md)。
58
+
59
+ v2 的 ApiError 已提供 status/errorCode/msg,不再 JSON.parse(error.msg) 提取旧版原始错误。
60
+
61
+ | HTTP / errorCode | 处理 |
62
+ | --- | --- |
63
+ | 400 INVALID_NOTIFICATION_TYPE | type 必须 inbox |
64
+ | 400 INVALID_REQUEST | 检查字段、枚举和长度 |
65
+ | 401 INVALID_CREDENTIAL | 核对注入身份 |
66
+ | 403 NOTIFICATION_NOT_ALLOWED | 核对 send 权限 |
67
+ | 404 RECIPIENT_NOT_AVAILABLE | 刷新成员并重新选择 |
68
+ | 409 IDEMPOTENCY_KEY_CONFLICT | 区分原事件与新事件,不静默换键重发 |
69
+ | 422 CONTENT_LIMIT_EXCEEDED | 缩短内容 |
70
+ | 429 NOTIFICATION_RATE_LIMITED | 有界退避;保留原键,不自动广播重发 |
71
+
72
+ link 拒绝 //host、反斜杠、Unicode 空白/控制/不可见格式字符。省略 link 不保证无按钮,实际导航还取决于发送者与目标前端。
@@ -0,0 +1,38 @@
1
+ ---
2
+ name: tier0-sdk-v2-source
3
+ description: 使用 @tier0/sdk-v2 的 client.source 查询、创建、修改、启停和删除新架构 Source,配置协议连接、处理影响分析、版本冲突与运行观测。
4
+ ---
5
+
6
+ # Source 数据接入
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()`;密钥不进入浏览器。
9
+
10
+ ## 按任务加载参考
11
+
12
+ | 用户任务 | 参考 | SDK 方法 |
13
+ | --- | --- | --- |
14
+ | 选协议、准备连接配置 | [协议配置](references/protocols.md) | protocols.list |
15
+ | 创建 HTTP/带凭据源 | [创建](references/create.md) | documents.create |
16
+ | 列表、详情、运行状态 | [查询](references/read.md) | documents.list/get、observations.get、runtime.get |
17
+ | 修改名称、端点或配置 | [修改](references/update.md) | documents.update |
18
+ | 查看修改/启停/删除影响 | [影响分析](references/changes.md) | impact |
19
+ | 启用、停用 | [状态变更](references/state.md) | state.update |
20
+ | 删除并核验 | [删除](references/delete.md) | delete |
21
+
22
+ 先加载对应操作文档,使用其中的参数表、完整请求及返回判断。只执行用户任务所需步骤;示例函数调用才会执行写入,导入不执行。新建→查询→修改→删除可组成生命周期,但查询任务不触发其他操作。
23
+
24
+ ## 核心约束
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。先形成精确意图,再读取全部影响分页;回执不可合成、跨意图复用或静默刷新。
29
+ 4. 配置中保留认证/TLS 引用,不写明文秘密;HTTP 新凭据走创建专用 credentials。
30
+ 5. desiredState 不代表实际健康,保存配置不代表 Stream 已切换至新 configRevision。运行状态另行读取。
31
+
32
+ ## 返回值与异常
33
+
34
+ 所有调用返回完整 code/msg/requestId/data。documents.create/update 的预检返回 validated/sideEffects,提交返回完整 Source view;批量状态/删除返回 Outcome。只有 committed 且无项错误才可报告提交成功;accepted/jobId 继续查询作业。
35
+
36
+ 需要查看历史用 source.history({id,beforeRevision,size}),按 nextBeforeRevision 继续;探测用 source.probe,其外部系统访问应属于当前任务。source.connection.update 属于现有源变更,同样遵守影响确认契约,不能作为绕过文档校验的入口。
37
+
38
+ UnsV2Error 表示已知拒绝;UnsV2OutcomeUnknownError 表示可能已写入。保存 requestId、原请求和意图键,先查详情/历史/作业对账。取消等待不撤销服务端操作;SDK 不自动重试。权限不足不能解释为资源不存在。
@@ -0,0 +1,40 @@
1
+ # Source 影响分析
2
+
3
+ 方法:`source.impact`;POST `/openapi/v2/uns/sources/impact`。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | id / expectedRevision | string / integer | 是 | 当前 ID 和读取到的修订 |
8
+ | action | update/enable/disable/delete | 是 | 精确变更类型 |
9
+ | document | CloudSourceDocument | 更新时 | 完整拟提交文档 |
10
+ | offset / size | integer | 否 | 首次 0;size 1–200 |
11
+ | impactRevision | string | 翻页时 | 沿用首次返回的确认值 |
12
+
13
+ ```ts
14
+ import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
15
+
16
+ export async function collectSourceImpact(
17
+ intent: Pick<UnsV2Request<'sourceImpact'>, 'id' | 'expectedRevision' | 'action' | 'document'>,
18
+ client: Tier0Client = createClient(),
19
+ ) {
20
+ const first = await client.source.impact({ ...intent, offset: 0, size: 200 });
21
+ const references = [...first.data.references];
22
+ let offset = first.data.nextOffset;
23
+ const seen = new Set<string>();
24
+ while (String(offset) !== '0') {
25
+ if (seen.has(String(offset))) throw new Error('影响分页未前进');
26
+ seen.add(String(offset));
27
+ const next = await client.source.impact({
28
+ ...intent, offset, size: 200, impactRevision: first.data.impactRevision,
29
+ });
30
+ if (next.data.impactRevision !== first.data.impactRevision) throw new Error('影响确认值发生变化');
31
+ references.push(...next.data.references);
32
+ offset = next.data.nextOffset;
33
+ }
34
+ return { ...first.data, references, nextOffset: offset };
35
+ }
36
+ ```
37
+
38
+ data:impactRevision、sourceID/sourceRevision、action、counts(draft/activeRelease/historicalRelease)、restrictedCount、references、nextOffset、expiresAt。nextOffset=0 结束;complete=1 表示计算完成,不表示首页有全部引用。
39
+
40
+ 确认值绑定身份、修订、精确意图,不能合成或自动刷新。评估 counts 和 restrictedCount;有受限引用时不能说“无影响”。Source 更新不会自动替换 Stream 冻结修订。已有明确操作授权时不重复索要确认;影响分析本身不授予额外操作权限。
@@ -0,0 +1,63 @@
1
+ # 创建 Source
2
+
3
+ 方法:`source.documents.create`;POST `/openapi/v2/uns/sources/documents/create`。需要 Source manage 权限。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | dryRun | boolean | 是 | true 校验;false 保存 |
8
+ | document.name | string | 是 | 1–128 字符 |
9
+ | document.protocol | string | 是 | 原生协议,如 http、mqtt、modbus |
10
+ | document.config | object | 是 | configVersion=2、endpoint、options;见[协议配置](protocols.md) |
11
+ | document.description | string | 否 | 最多 512 字符 |
12
+ | credentials | object | 否 | 仅创建时提供新 HTTP 凭据,与已有 auth/TLS 引用互斥 |
13
+ | idempotencyKey | string | 否 | 建议提供,最多 128 字符,同一业务意图保持不变 |
14
+
15
+ ## 完整示例:HTTP 数据源
16
+
17
+ 传入实际端点、名称和意图键。此函数创建配置,不启用源。client 从服务端环境读取 API Host/Key,也可显式注入。
18
+
19
+ ```ts
20
+ import { createClient, type Tier0Client, type CloudSourceDocument } from '@tier0/sdk-v2';
21
+
22
+ export async function createHttpSource(
23
+ endpoint: string, name: string, intentKey: string, client: Tier0Client = createClient(),
24
+ ) {
25
+ const document: CloudSourceDocument = {
26
+ name, protocol: 'http', description: '订单系统 HTTP 接入',
27
+ config: { configVersion: 2, endpoint, options: {} },
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
+ const saved = await client.source.documents.create({
32
+ dryRun: false, document, idempotencyKey: intentKey,
33
+ });
34
+ 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 };
37
+ }
38
+ ```
39
+
40
+ 提交返回 data:id、revision、document、desiredState、runtimeState、health、createdAt、updatedAt;预检返回 `{ validated: true, sideEffects: false }`,没有 ID。ID 原样保留十进制字符串。
41
+
42
+ ## HTTP Bearer 凭据
43
+
44
+ token 从服务端密钥提供者取得,不写入脚本、文档、日志或仓库。
45
+
46
+ ```ts
47
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
48
+
49
+ export async function createAuthenticatedHttpSource(
50
+ endpoint: string, name: string, token: string, intentKey: string,
51
+ client: Tier0Client = createClient(),
52
+ ) {
53
+ const saved = await client.source.documents.create({
54
+ dryRun: false, idempotencyKey: intentKey,
55
+ document: { name, protocol: 'http', config: { configVersion: 2, endpoint, options: {} } },
56
+ credentials: { method: 'GET', kind: 'bearer', material: { token } },
57
+ });
58
+ if (!('id' in saved.data)) throw new Error('未返回 Source ID');
59
+ return client.source.documents.get({ id: saved.data.id });
60
+ }
61
+ ```
62
+
63
+ 配置保存不代表连接健康;见[查询](read.md)。仅在任务包含启用时执行[启停](state.md)。结果未知时保留原请求、requestId、意图键,先核对列表/历史,不自动重复创建。
@@ -0,0 +1,47 @@
1
+ # 删除 Source
2
+
3
+ 方法:`source.delete`;POST `/openapi/v2/uns/sources/delete`。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | dryRun | boolean | 是 | true 预检;false 提交 |
8
+ | items | array | 是 | 1–200 项 |
9
+ | items[].id | string | 是 | 正十进制 int64 字符串 |
10
+ | items[].expectedRevision | integer | 是 | get 返回的修订 |
11
+ | items[].confirmedImpactRevision | string | 是 | action=delete 的影响回执 |
12
+ | mode | auto/sync | 否 | 不支持 async |
13
+ | allowPartial | false | 否 | 不支持部分提交 |
14
+ | idempotencyKey | string | 否 | 最多 128 字符 |
15
+
16
+ 先 get → impact(action=delete) → [遍历并评估影响](changes.md)。存在 Stream 依赖时遵守服务端保护,不自动删除依赖流。
17
+
18
+ ```ts
19
+ import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
20
+
21
+ export async function deleteSource(
22
+ id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
23
+ confirmedImpactRevision: string, intentKey: string, client: Tier0Client = createClient(),
24
+ ) {
25
+ const receipt = await client.source.delete({
26
+ dryRun: false, mode: 'sync', allowPartial: false, idempotencyKey: intentKey,
27
+ items: [{ id, expectedRevision, confirmedImpactRevision }],
28
+ });
29
+ if (receipt.data.status !== 'committed' || receipt.data.results?.some(item => item.error)) {
30
+ return { state: 'unconfirmed' as const, receipt };
31
+ }
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 };
44
+ }
45
+ ```
46
+
47
+ 返回 Outcome,HTTP 200/validated/accepted 不等于完成。归档列表找到 ID 是额外核验;读回不可见时保留提交回执,报告核验未完成。不能把任意 get 异常当成成功。
@@ -0,0 +1,36 @@
1
+ # 协议与连接配置
2
+
3
+ 先调用 `source.protocols.list({})`。协议枚举存在不等于目标环境驱动或凭据解析器已就绪。原生 `protocol: 'http'` 与通用投影 `adapter: 'http-api'` 不可混用。
4
+
5
+ | 配置字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | configVersion | 2 | 是 | 新架构配置快照 |
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 校验。
15
+
16
+ ```ts
17
+ import { createClient, type CloudSourceDocument } from '@tier0/sdk-v2';
18
+
19
+ export async function inspectProtocolExamples() {
20
+ const capabilities = await createClient().source.protocols.list({});
21
+ const examples: CloudSourceDocument[] = [
22
+ { name: 'orders-http', protocol: 'http',
23
+ config: { configVersion: 2, endpoint: 'https://orders.example.com', options: {} } },
24
+ { name: 'line-plc', protocol: 'modbus',
25
+ config: { configVersion: 2, endpoint: 'tcp://plc.example.com:502', options: { unitId: 1 } } },
26
+ { name: 'line-mqtt', protocol: 'mqtt',
27
+ config: { configVersion: 2, endpoint: 'mqtt://broker.example.com:1883',
28
+ options: { clientId: 'tier0-line-reader', subscriptions: { 'factory/line1/status': 1 } } } },
29
+ ];
30
+ return { capabilities: capabilities.data, examples };
31
+ }
32
+ ```
33
+
34
+ HTTP 公开 headers 只允许 Accept/Content-Type,不能塞 Authorization/Cookie。Modbus 寄存器范围和轮询频率在 Stream acquisition 中定义;MQTT QoS 为 0/1/2。认证创建见[创建](create.md),修改时保留原 auth/tls 引用。
35
+
36
+ SQL options 包含 tlsMode(verify-full/disable)和 queries(资源名→固定 SQL);脚本不能替换任意 SQL。OPC UA、SAP、Teamcenter 等按能力和服务端校验配置,不从 HTTP 模板生造字段。不要为通过校验自动移除认证或关闭 TLS。
@@ -0,0 +1,34 @@
1
+ # 查询 Source
2
+
3
+ | 方法 | POST 路径 | 输入 | data |
4
+ | --- | --- | --- | --- |
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、状态 |
7
+ | source.runtime.get | /openapi/v2/uns/sources/runtime/get | id(必填) | 运行状态 |
8
+ | source.observations.get | /openapi/v2/uns/sources/observations/get | items:id、expectedRevision | 指定源和修订的观测 |
9
+
10
+ page 从 1 开始,size 1–200。列表默认安全摘要;完整文档需要管理权限,编辑时显式 get。
11
+
12
+ ```ts
13
+ import { createClient, type Tier0Client } from '@tier0/sdk-v2';
14
+
15
+ export async function* listSources(client: Tier0Client = createClient()) {
16
+ let page = 1;
17
+ while (true) {
18
+ const { data } = await client.source.documents.list({ page, size: 100, includeDocument: false });
19
+ yield data.list;
20
+ if (!data.hasMore) return;
21
+ if (typeof data.nextPage !== 'number' || data.nextPage <= page) throw new Error('无有效下一页');
22
+ page = data.nextPage;
23
+ }
24
+ }
25
+ export async function readSource(id: string, client: Tier0Client = createClient()) {
26
+ const current = await client.source.documents.get({ id });
27
+ const observation = await client.source.observations.get({
28
+ items: [{ id, expectedRevision: current.data.revision }],
29
+ });
30
+ return { current: current.data, observation: observation.data };
31
+ }
32
+ ```
33
+
34
+ ID 不得转 Number;跨页不是稳定快照。权限错误、网络故障与不存在应分别处理,不能把任何 get 失败当成删除成功。probe 可能触达外部系统,不属于单纯读取。
@@ -0,0 +1,37 @@
1
+ # 启用、停用 Source
2
+
3
+ 方法:`source.state.update`;POST `/openapi/v2/uns/sources/state/update`。
4
+
5
+ | 字段 | 类型 | 必填 | 说明 |
6
+ | --- | --- | --- | --- |
7
+ | dryRun | boolean | 是 | 提交 false |
8
+ | items[].id / expectedRevision | string / integer | 是 | 当前对象和修订 |
9
+ | items[].desiredState | enabled/disabled | 是 | 目标状态 |
10
+ | items[].confirmedImpactRevision | string | 是 | enable/disable 对应的影响回执 |
11
+ | mode / allowPartial | string / boolean | 否 | 单项示例 sync / false |
12
+ | idempotencyKey | string | 否 | 本次状态变更的独立意图键 |
13
+
14
+ 先 get,以相同修订执行 impact(action=enable 或 disable),按[影响分析](changes.md)遍历并评估。将原修订和回执传给下例。
15
+
16
+ ```ts
17
+ import { createClient, type Tier0Client, type UnsV2Request } from '@tier0/sdk-v2';
18
+
19
+ export async function setSourceState(
20
+ id: string, expectedRevision: UnsV2Request<'sourceImpact'>['expectedRevision'],
21
+ desiredState: 'enabled' | 'disabled', confirmedImpactRevision: string,
22
+ intentKey: string, client: Tier0Client = createClient(),
23
+ ) {
24
+ const receipt = await client.source.state.update({
25
+ dryRun: false, mode: 'sync', allowPartial: false, idempotencyKey: intentKey,
26
+ items: [{ id, expectedRevision, desiredState, confirmedImpactRevision }],
27
+ });
28
+ if (receipt.data.status !== 'committed' || receipt.data.results?.some(item => item.error)) {
29
+ return { state: 'unconfirmed' as const, receipt };
30
+ }
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 };
34
+ }
35
+ ```
36
+
37
+ 响应为 Outcome;accepted/jobId 仅表示受理,继续查询作业。enabled 是期望状态;健康与连通性另用 observations/runtime 检查。