@tier0/sdk-v2 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tier0/sdk-v2",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Tier0 Cloud new-architecture SDK for TypeScript and JavaScript",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -156,7 +156,7 @@
156
156
  "scripts": {
157
157
  "sync:contracts": "node scripts/sync-contracts.mjs",
158
158
  "generate": "node scripts/generate-openapi.mjs && node scripts/generate-uns-v2.mjs",
159
- "check:contracts": "node scripts/check-contracts.mjs && node --test scripts/retired-stream-probe.test.mjs && node scripts/generate-openapi.mjs --check && node scripts/generate-uns-v2.mjs --check",
159
+ "check:contracts": "node scripts/check-contracts.mjs && node --test scripts/retired-stream-probe.test.mjs scripts/sync-contracts.test.mjs && node scripts/generate-openapi.mjs --check && node scripts/generate-uns-v2.mjs --check",
160
160
  "check:skills": "node scripts/check-skills.mjs && node scripts/check-skill-examples.mjs",
161
161
  "typecheck": "tsc --noEmit && tsc -p tsconfig.tests.json",
162
162
  "build": "node scripts/build.mjs",
@@ -23,10 +23,10 @@ Source 维护连接配置、认证引用与源状态。脚本处理用 [Stream](
23
23
 
24
24
  ## 核心约束
25
25
 
26
- 1. Source 配置统一使用 documents.*,原生文档为 `{name,protocol,config}`。http 原生协议与 http-api adapter 不可互换。
26
+ 1. Source 配置统一使用 documents.*,原生文档为 `{name,protocol,config}`,HTTP API 显式指定 `config.role`。HTTP 统一为 `protocol: http-api` + `config.role: client/server`;Client 主动请求,Server 接收入站请求,不能互换。独立异步 http_push 的 202 accepted 合同继续保留。
27
27
  2. 已有 ID 和 revision 时优先用 documents.update 的 patch,避免额外 get;完整替换 document 前读取完整文档,安全列表摘要不能无损回写。原生 ID 是十进制字符串,revision 原样传递,不转 Number。
28
28
  3. 现有 Source 修改、启停、删除都要 expectedRevision。没有任何 Stream 引用时可直接提交;有草稿、活动、历史或不可见引用时仍需 confirmedImpactRevision。先形成精确意图,再读取全部影响分页;回执不可合成、跨意图复用或静默刷新。提供的回执始终严格校验,不自动获取并同意影响。
29
- 4. 配置中保留认证/TLS 引用,不写明文秘密;HTTP 新凭据走创建专用 credentials。
29
+ 4. 配置中保留认证/TLS 引用,不写明文秘密;HTTP Client 新凭据走创建专用 credentials;Server 不携带 Client auth/TLS 配置。
30
30
  5. desiredState 不代表实际健康,保存配置不代表 Stream 已切换至新 configRevision。运行状态另行读取。
31
31
 
32
32
  ## 返回值与异常
@@ -6,15 +6,16 @@
6
6
  | --- | --- | --- | --- |
7
7
  | dryRun | boolean | 是 | true 校验;false 保存 |
8
8
  | document.name | string | 是 | 1–128 字符 |
9
- | document.protocol | string | 是 | 原生协议,如 http、mqtt、modbus |
9
+ | document.protocol | string | 是 | 原生协议,如 http-api、mqtt、modbus |
10
+ | document.config.role | client / server | HTTP API 显式指定 | client 主动请求;server 接收入站请求 |
10
11
  | document.config | object | 是 | configVersion=2、endpoint、options;见[协议配置](protocols.md) |
11
12
  | document.description | string | 否 | 最多 512 字符 |
12
- | credentials | object | 否 | 仅创建时提供新 HTTP 凭据,与已有 auth/TLS 引用互斥 |
13
+ | credentials | object | 否 | 仅创建 HTTP Client 时提供新凭据,与已有 auth/TLS 引用互斥 |
13
14
  | idempotencyKey | string | 否 | 建议提供,最多 128 字符,同一业务意图保持不变 |
14
15
 
15
- ## 完整示例:HTTP 数据源
16
+ ## 完整示例:HTTP Client 数据源
16
17
 
17
- 传入实际端点、名称和意图键。此函数创建配置,不启用源。client 从服务端环境读取 API Host/Key,也可显式注入。
18
+ 传入实际端点、名称和意图键。此函数创建 `http-api` + `config.role: client` 配置,不启用源。client 从服务端环境读取 API Host/Key,也可显式注入。
18
19
 
19
20
  ```ts
20
21
  import { createClient, type Tier0Client, type CloudSourceDocument } from '@tier0/sdk-v2';
@@ -23,8 +24,8 @@ export async function createHttpSource(
23
24
  endpoint: string, name: string, intentKey: string, client: Tier0Client = createClient(),
24
25
  ) {
25
26
  const document: CloudSourceDocument = {
26
- name, protocol: 'http', description: '订单系统 HTTP 接入',
27
- config: { configVersion: 2, endpoint, options: {} },
27
+ name, protocol: 'http-api', description: '订单系统 HTTP 接入',
28
+ config: { configVersion: 2, role: 'client', endpoint, options: {} },
28
29
  };
29
30
  const saved = await client.source.documents.create({
30
31
  dryRun: false, document, idempotencyKey: intentKey,
@@ -36,7 +37,9 @@ export async function createHttpSource(
36
37
 
37
38
  一次提交即可返回完整 data:id、revision、document、desiredState、runtimeState、health、createdAt、updatedAt,无需另行 get。需要单独预检时可先传 `dryRun: true`,返回 `{ validated: true, sideEffects: false }`,没有 ID。预检不保留提交条件;实际保存仍会校验。ID 原样保留十进制字符串。
38
39
 
39
- ## HTTP Bearer 凭据
40
+ HTTP Server 同样使用 `protocol: http-api`,角色为 `config.role: server`;其配置以 `source.protocols.list({})` 返回的正式合同为准,不能复用下方 Client 的主动请求示例。独立异步 `http_push` 的 202 accepted 合同仍保留;202 仅表示接受,不能据此报告 Stream 执行完成。
41
+
42
+ ## HTTP Client Bearer 凭据
40
43
 
41
44
  token 从服务端密钥提供者取得,不写入脚本、文档、日志或仓库。
42
45
 
@@ -49,7 +52,7 @@ export async function createAuthenticatedHttpSource(
49
52
  ) {
50
53
  const saved = await client.source.documents.create({
51
54
  dryRun: false, idempotencyKey: intentKey,
52
- document: { name, protocol: 'http', config: { configVersion: 2, endpoint, options: {} } },
55
+ document: { name, protocol: 'http-api', config: { configVersion: 2, role: 'client', endpoint, options: {} } },
53
56
  credentials: { method: 'GET', kind: 'bearer', material: { token } },
54
57
  });
55
58
  if (!('id' in saved.data)) throw new Error('未返回 Source ID');
@@ -58,3 +61,58 @@ export async function createAuthenticatedHttpSource(
58
61
  ```
59
62
 
60
63
  配置保存不代表连接健康;见[查询](read.md)。仅在任务包含启用时执行[启停](state.md)。结果未知时保留原请求、requestId、意图键,先核对列表/历史,不自动重复创建。
64
+
65
+ ## HTTP Server:管理配置
66
+
67
+ 正式协议目录规定 Server 的 `config.endpoint` 为 `http://managed`、`options` 为 `{}`,不携带 Client 的 `auth` / `tls` 或创建专用 `credentials`。该函数只保存 Source,不启用、不创建 Stream,也不发起入站请求。
68
+
69
+ ```ts
70
+ import { createClient, type Tier0Client, type CloudSourceDocument } from '@tier0/sdk-v2';
71
+
72
+ export async function createHttpServerSource(
73
+ name: string, intentKey: string, client: Tier0Client = createClient(),
74
+ ) {
75
+ const document: CloudSourceDocument = {
76
+ name, protocol: 'http-api',
77
+ config: { configVersion: 2, role: 'server', endpoint: 'http://managed', options: {} },
78
+ };
79
+ const saved = await client.source.documents.create({
80
+ dryRun: false, document, idempotencyKey: intentKey,
81
+ });
82
+ if (!('id' in saved.data)) throw new Error('未返回已保存的 Source');
83
+ return { receipt: saved, current: saved.data };
84
+ }
85
+ ```
86
+
87
+ Server 的同步入站语义和 Bearer 要求由协议目录的 `x-tier0-http-in` 描述;本 npm 包提供 Source 管理方法,不把 Client 的 `upstream.request` 当作 Server 入站入口。独立异步 `http_push` 仍按自己的 202 accepted 合同处理。
88
+
89
+ ## 四类 inline 认证与 REQUEST 绑定
90
+
91
+ 单条创建可通过 `credentials` 提供以下只写材料;与已有 auth/TLS 引用互斥,并要求本次创建的 `idempotencyKey`。材料从调用方已授权的密钥提供者注入,不在示例中读取文件或环境中的秘密,不记录或返回材料。
92
+
93
+ | kind | material | method |
94
+ | --- | --- | --- |
95
+ | basic | username、password | 省略时 REQUEST;可显式绑定受限 HTTP 方法 |
96
+ | bearer | token | 省略时 REQUEST;上方 GET 示例保持明确的方法限制 |
97
+ | apiKey | headerName、value | 省略或 REQUEST;不接受旧 name/key 形态 |
98
+ | oauth2ClientCredentials | tokenUrl、clientId、clientSecret;可选 scope、clientAuthentication | 省略、REQUEST 或 GET |
99
+
100
+ OAuth 的 `clientAuthentication` 支持 `client_secret_post`(默认)和 `client_secret_basic`。REQUEST 表示绑定 Source 基址,实际路径和方法仍由执行宿主逐次授权;显式方法的已有绑定不能解释成 REQUEST 的基址范围。vendor SESSION 合同独立保留,不是此 inline 创建的 method,也不新增独立公开凭据 API。
101
+
102
+ ```ts
103
+ import { createClient, type Tier0Client, type CloudSourceCreateCredentials } from '@tier0/sdk-v2';
104
+
105
+ export async function createHttpSourceWithCredentials(
106
+ endpoint: string, name: string, credentials: CloudSourceCreateCredentials, intentKey: string,
107
+ client: Tier0Client = createClient(),
108
+ ) {
109
+ const saved = await client.source.documents.create({
110
+ dryRun: false, idempotencyKey: intentKey,
111
+ document: { name, protocol: 'http-api',
112
+ config: { configVersion: 2, role: 'client', endpoint, options: {} } },
113
+ credentials,
114
+ });
115
+ if (!('id' in saved.data)) throw new Error('未返回已保存的 Source');
116
+ return { receipt: saved, current: saved.data };
117
+ }
118
+ ```
@@ -1,9 +1,10 @@
1
1
  # 协议与连接配置
2
2
 
3
- 先调用 `source.protocols.list({})`。协议枚举存在不等于目标环境驱动或凭据解析器已就绪。原生 `protocol: 'http'` 与通用投影 `adapter: 'http-api'` 不可混用。
3
+ 先调用 `source.protocols.list({})`。协议枚举存在不等于目标环境驱动或凭据解析器已就绪。HTTP Source 统一使用 `protocol: 'http-api'`,通过文档的 `config.role: 'client' | 'server'` 区分主动请求和入站服务,与 Enterprise 的一协议两角色模型一致。角色和协议能力以目标环境目录为准;旧 `http` 不作为新建示例。
4
4
 
5
5
  | 配置字段 | 类型 | 必填 | 说明 |
6
6
  | --- | --- | --- | --- |
7
+ | role | client / server | HTTP 示例显式指定 | 省略时为 client;Server 使用托管地址和空 options |
7
8
  | configVersion | 2 | 是 | 新架构配置快照 |
8
9
  | endpoint | string | 是 | 地址,不内嵌凭据 |
9
10
  | options | object | 是 | 协议专用选项 |
@@ -19,8 +20,8 @@ import { createClient, type CloudSourceDocument } from '@tier0/sdk-v2';
19
20
  export async function inspectProtocolExamples() {
20
21
  const capabilities = await createClient().source.protocols.list({});
21
22
  const examples: CloudSourceDocument[] = [
22
- { name: 'orders-http', protocol: 'http',
23
- config: { configVersion: 2, endpoint: 'https://orders.example.com', options: {} } },
23
+ { name: 'orders-http', protocol: 'http-api',
24
+ config: { configVersion: 2, role: 'client', endpoint: 'https://orders.example.com', options: {} } },
24
25
  { name: 'line-plc', protocol: 'modbus',
25
26
  config: { configVersion: 2, endpoint: 'tcp://plc.example.com:502', options: { unitId: 1 } } },
26
27
  { name: 'line-mqtt', protocol: 'mqtt',
@@ -31,6 +32,12 @@ export async function inspectProtocolExamples() {
31
32
  }
32
33
  ```
33
34
 
34
- HTTP 公开 headers 只允许 Accept/Content-Type,不能塞 Authorization/Cookie。Modbus 寄存器范围和轮询频率在 Stream acquisition 中定义;MQTT QoS 为 0/1/2。认证创建见[创建](create.md),修改时保留原 auth/tls 引用。
35
+ HTTP Client 的 options 支持 headers 和 parameters;headers 可包含目录允许的非秘密自定义头,Accept/Content-Type 保留 MIME 校验,认证及传输头保留给服务端,不能塞 Authorization/Cookie。Modbus 寄存器范围和轮询频率在 Stream acquisition 中定义;MQTT QoS 为 0/1/2。认证创建见[创建](create.md),修改时保留原 auth/tls 引用。
35
36
 
36
37
  SQL options 包含 tlsMode(verify-full/disable)和 queries(资源名→固定 SQL);脚本不能替换任意 SQL。OPC UA、SAP、Teamcenter 等按能力和服务端校验配置,不从 HTTP 模板生造字段。不要为通过校验自动移除认证或关闭 TLS。
38
+
39
+ HTTP Client 示例不能用于 Server。独立异步 `http_push` 保留自己的 202 accepted 合同,不等同于同步 HTTP API Server 的响应;本管理 SDK 通过 `source.documents.*` 配置源,不据此新增 HTTP In 调用入口。
40
+
41
+ Cloud 的角色位于 `config.role`;Enterprise 投影的顶层 `role` 不能直接抄入 Cloud 管理文档。Server 配置见[创建](create.md),以 `http://managed` 和空 options 保存,不从 Client 模板推导。
42
+
43
+ HTTP Client 的单条 inline 认证支持 basic / bearer / apiKey / oauth2ClientCredentials,method 省略时由服务端按 REQUEST 绑定 Source 基址;显式方法限制保持不变。APIKey 材料为 headerName/value,OAuth 可提供 clientAuthentication。见[创建](create.md)。
@@ -25,7 +25,7 @@ description: 使用 @tier0/sdk-v2 的 client.stream 创建、查询、修改和
25
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
- 程序必须是完整 `module.exports = api => { ... }`,执行器 API 是 api.sources/api.uns/api.stream,与 npm 包的 client.source 不同。Runtime sourceBindings 为 sourceId/configRevision/acquisition;原生 sources 还使用 alias/resources。连接凭据不进脚本或 acquisition。
28
+ 程序必须是完整 `module.exports = api => { ... }`,执行器 API 是 api.sources/api.uns/api.stream,与 npm 包的 client.source 不同。Runtime sourceBindings 为 sourceId/configRevision/acquisition;原生 sources 还使用 alias/resources。连接凭据不进脚本或 acquisition,秘密材料由 Source 执行宿主管理,不通过脚本读取、记录或返回。定时入口使用 api.stream.every,不传播旧注册别名;npm 的 client.controls 管理入口不作为 Goja 的 Stream 注册参数。
29
29
 
30
30
  ## 核心约束
31
31
 
@@ -12,9 +12,9 @@
12
12
  | program.sourceBindings | array | 否 | sourceId、configRevision、acquisition |
13
13
  | idempotencyKey | string | 否 | 最多 128 字符,本次创建的固定意图键 |
14
14
 
15
- ## HTTP Source 绑定示例
15
+ ## HTTP Client Source 绑定示例
16
16
 
17
- 先按[Source 查询](../../tier0-sdk-v2-source/references/read.md)选定真实 HTTP Source。脚本的 api.sources 属于平台执行器,与应用中的 client.source 不同。sourceId 保持字符串,configRevision 从完整源读取。
17
+ 先按[Source 查询](../../tier0-sdk-v2-source/references/read.md)选定真实 HTTP Client Source。脚本的 api.sources 属于平台执行器,与应用中的 client.source 不同。sourceId 保持字符串,configRevision 从完整源读取。省略 `config.role` 时按正式协议目录默认为 client;Server 走入站语义,不能创建为主动请求程序。
18
18
 
19
19
  ```ts
20
20
  import { createClient, type Tier0Client, type RuntimeStreamDefinition } from '@tier0/sdk-v2';
@@ -25,14 +25,17 @@ export async function createHttpStream(
25
25
  if (!/^[1-9][0-9]*$/.test(sourceId)) throw new Error('Source ID 必须是正十进制字符串');
26
26
  const source = await client.source.documents.get({ id: sourceId, view: 'full' });
27
27
  if (!('document' in source.data)) throw new Error('需要完整 Source 文档');
28
- if (source.data.document.protocol !== 'http') throw new Error('此示例需要 HTTP Source');
28
+ if (source.data.document.protocol !== 'http-api' || source.data.document.config.configVersion !== 2 ||
29
+ (source.data.document.config.role ?? 'client') !== 'client') {
30
+ throw new Error('此主动请求示例需要 HTTP API Client Source');
31
+ }
29
32
  const document: RuntimeStreamDefinition = {
30
33
  name, sdkVersion: 'tier0-stream/v2', timeoutMs: 5000,
31
34
  sourceBindings: [{ sourceId, configRevision: source.data.revision, acquisition: {} }],
32
35
  script: [
33
36
  'module.exports = api => {',
34
37
  ' const upstream = api.sources.use({ id: ' + JSON.stringify(sourceId) + ', resources: [] });',
35
- ' api.stream.onTimer({ id: "tick", intervalMs: 60000 }, async () => {',
38
+ ' api.stream.every({ id: "tick", intervalMs: 60000 }, async () => {',
36
39
  ' const response = await upstream.request({ method: "GET", path: "orders" });',
37
40
  ' return response.data;',
38
41
  ' });',