Skip to content

Commit 811c30c

Browse files
qq9340100claude
andauthored
refactor(spec)!: 按 ADR-0049 退役 FieldMapping.transform 与整个 FieldMappingTransform 联合 —— 五成员零执行者 (#5552) (#6078)
* refactor(spec)!: 按 ADR-0049 退役 FieldMapping.transform 与整个 FieldMappingTransform 联合 (#5552) WIP: schema tombstone + D2 conversion + D3 chain step + 两张退役登记表首入。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY * refactor(spec)!: 按 ADR-0049 退役 FieldMapping.transform 与整个 FieldMappingTransform 联合 (#5552) 测量结论:五个成员(constant/cast/lookup/javascript/map)无一存在执行者。 fieldMappings 只在 packages/spec 自身被拼写,connector 包/automation engine/REST/ objectui 均不读取,全仓无任何代码对 transform.type 分支。 退役套件:retiredKey() 墓碑(schema 与两个 extender 均为普通 z.object,直接删键会静默 strip)、D2 conversion field-mapping-transform-removed、D3 chain step、 RETIRED_KEYS_BY_MAJOR/RETIRED_DEFS_BY_MAJOR 两表首批条目、生成物重生成、changeset。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY * chore(spec): 退役读数物化进 #5837 分片布局 api-surface/shared.json −2 导出;authorable-surface 的 data/integration/shared 三个分片各一行转 [RETIRED];json-schema.manifest/shared.json −1 def。 manifest ratchet 在分片布局下再次自行开火并点名分片路径,处置同前:有意删除 + RETIRED_DEFS_BY_MAJOR 已登记。check:generated 10/10 绿。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY * chore(spec,qa): 退役收尾 —— 删除两处引用已退役联合的账本条目 (#5552) 1. packages/spec/variant-docs.json:孤儿条目 "sync mapping transform" (key type:cast|constant|javascript|lookup|map) —— 该判别联合已随 FieldMapping.transform 一并退役,按 check:variant-docs 自身处方删除条目。 门读数:19 unions / 9 governed / exempt 11 → 10。 2. packages/qa/dogfood/test/expression-conformance.ledger.ts:cel-formula 行的 cover 'shared/mapping.zod.ts:expression' —— 该 expression 面由被退役的 javascript 成员携带,源码里已不存在,故删除该 cover(沿用同一行 #3605 kernel/feature.zod.ts 的处理先例并留注释);summary 同步去掉 "+ mapping expressions",因该侧已无可解释的东西。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY * chore(spec): 按 #6058 新渲染器重生成三张墓碑参考页 (#5552) main 落了 6e82972(#5606/#6058):docs-gen 把 retiredKey() 墓碑从 any 渲染成 never。本分支的 FieldMapping.transform 墓碑正好出现在这三页上,故 merge ref 用新 渲染器重算与分支内旧产物不一致。按门自身处方 gen:schema + gen:docs 重生成。 三页 diff 即 any→never 形状(同页上先前就存在的 rateLimitConfig 墓碑 #4911 也一并 翻新,可证是渲染器变更而非本分支改动),外加同一渲染器变更的连带效果: fieldMappings 的内联形状摘要不再打印 never 化的已退役属性,腾出的位置显示真实键。 strictness ledger 的 cloud/ 82→83 来自本次 merge(本分支从未触及 cloud/)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011M7UwH25Unfi73UHim7ajY --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 880d343 commit 811c30c

25 files changed

Lines changed: 568 additions & 346 deletions
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
'@objectstack/spec': major
3+
---
4+
5+
按 ADR-0049 enforce-or-remove 退役字段映射的 `transform` 键与整个 `FieldMappingTransform` 联合(#5552)
6+
7+
`shared/FieldMappingSchema.transform` 由一个五成员判别联合承载(`constant` / `cast` /
8+
`lookup` / `javascript` / `map`),并被两个 `.extend()` 它的 schema 继承 ——
9+
`integration/ConnectorFieldMapping``data/ExternalFieldMapping`**五个成员没有一个
10+
存在执行者**:`fieldMappings` 只在 `packages/spec` 自己的 schema 和测试里被拼写过,四个
11+
connector 包、automation engine、REST 与 objectui 都不读它,全仓也没有任何代码对
12+
`transform.type` 分支。这是完整意义上的 declared-but-unenforced(Prime Directive #10),
13+
不只是报单所指的那一个成员。
14+
15+
`javascript` 成员是让缺口显形的那一个:它的 `.describe()` 推荐 `dialect: "js"`,而 `js`
16+
方言早在 #3278(ADR-0058 addendum)就退役了 —— 于是文档教的信封写法被枚举直接拒收,唯一
17+
能通过 parse 的裸字符串又被 `ExpressionInputSchema` 包成 `dialect: 'cel'`,而同一行给出的
18+
例子 `value.toUpperCase()` 作为 CEL 并不成立。三处互相打架,且三处底下都没有实现。
19+
20+
## FROM → TO
21+
22+
| 你现在写的 | 改成 |
23+
|:---|:---|
24+
| `connector.fieldMappings[].transform: { type: 'cast', targetType: 'string' }` | 删除该键 |
25+
| `connector.fieldMappings[].transform: { type: 'javascript', expression: '…' }` | 删除该键 |
26+
| `externalLookup.fieldMappings[].transform: { … }` | 删除该键 |
27+
28+
**一句话修复:删掉 `transform` 键。** 没有等价替换成员 —— L3 connector 的字段映射只做
29+
`source``target` 的搬运,从来没有做过值变换。真正要做值变换的地方有两个,都是活的:
30+
31+
- **导入映射** `mapping.fieldMapping[].transform` —— 一个扁平字符串枚举
32+
(`none`/`constant`/`map`/`split`/`join`/`lookup`,配置放在 `params`),由 REST 导入
33+
路径逐行执行。注意它对自己的 `javascript` 值是**直接 400 拒收**(服务端没有沙箱),
34+
而不是解析通过然后什么都不做。
35+
- **ETL transformation 步骤**,面向多源、多阶段的复杂变换。
36+
37+
存量元数据无需手改:`os migrate meta --from 16` 会自动重写(ADR-0087 D2 conversion
38+
`field-mapping-transform-removed`);`sys_metadata` 里的存量行在 rehydration 时由
39+
`applyConversionsToStoredItem` 重放同一条转换。直接 parse 会命中 `retiredKey()` 墓碑,
40+
错误信息本身就是上面这段处方。
41+
42+
## 退役套件
43+
44+
- **Schema**:`shared/mapping.zod.ts``transform` 改为 `retiredKey()` 墓碑(该 schema
45+
与两个 extender 都是普通 `z.object`,直接删键会被静默 strip —— 用另一个静默 no-op 替换
46+
原来的静默 no-op);`FieldMappingTransformSchema` / `FieldMappingTransform` 两个导出随键
47+
一起删除(无其他消费者的值 schema 会被后来者读成一项能力,#3950)。
48+
- **D2 conversion**:`field-mapping-transform-removed`,`toMajor: 17`,
49+
`retiredFromLoadPath: true`,重写 `connectors[].fieldMappings[]`
50+
- **D3 chain step**:接入 `MIGRATIONS_BY_MAJOR[17].conversionIds` 并扩写 rationale。
51+
- **退役登记**:`RETIRED_KEYS_BY_MAJOR[17]` 收三个键(一个墓碑 → 三处可作者化拼写,因为
52+
两个 extender 各自复制了该属性);`RETIRED_DEFS_BY_MAJOR[17]`
53+
`shared/FieldMappingTransform`。这是自 #4659 / #4725 建表以来两张表的首批条目。
54+
- **生成物**:`authorable-surface.json` 三行转 `[RETIRED]`;`api-surface.json` −2;
55+
`json-schema.manifest.json` −1 def;spec-changes / upgrade-guide / references 重生成。
56+
57+
**未受影响**:`ExpressionDialect` 本体、`ExternalLookup.transform`(lookup 级
58+
request/response 管线,与字段映射无关)、以及上面那个活着的导入映射 `transform`

content/docs/getting-started/quick-reference.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ Common utilities used across all protocols.
213213
| **[Expression](/docs/references/shared/expression)** | `expression.zod.ts` | Expression, ExpressionInput | CEL expression values and inputs |
214214
| **[HTTP](/docs/references/shared/http)** | `http.zod.ts` | HttpRequest, HttpMethod, CorsConfig | HTTP utilities |
215215
| **[Identifiers](/docs/references/shared/identifiers)** | `identifiers.zod.ts` | SystemIdentifier, SnakeCaseIdentifier | Standard ID patterns |
216-
| **[Mapping](/docs/references/shared/mapping)** | `mapping.zod.ts` | FieldMapping, FieldMappingTransform | Field mapping utilities |
216+
| **[Mapping](/docs/references/shared/mapping)** | `mapping.zod.ts` | FieldMapping | Field mapping utilities |
217217
| **[Connector Auth](/docs/references/shared/connector-auth)** | `connector-auth.zod.ts` | ConnectorAuthConfig | Connector auth patterns |
218218

219219
## QA Protocol (1 schema)

content/docs/references/data/external-lookup.mdx

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,10 +84,10 @@ const result = ExternalDataSourceSchema.parse(data);
8484
| :--- | :--- | :--- | :--- |
8585
| **source** | `string` || Source field name |
8686
| **target** | `string` || Target field name |
87-
| **transform** | `{ type: 'constant'; value: any } \| { type: 'cast'; targetType: Enum<'string' \| 'number' \| 'boolean' \| 'date'> } \| { type: 'lookup'; table: string; keyField: string; valueField: string } \| { type: 'javascript'; expression: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object } } \| { type: 'map'; mappings: Record<string, any> }` | optional | Transformation to apply |
87+
| **transform** | `never` | optional | [REMOVED] `FieldMapping.transform` — authored as `connector.fieldMappings[].transform` and `externalLookup.fieldMappings[].transform` — was removed in @objectstack/spec 17.0.0 (#5552, ADR-0049), and the whole `FieldMappingTransform` union went with it (`constant` / `cast` / `lookup` / `javascript` / `map`) — no runtime ever executed any of the five, and the `javascript` member advertised `dialect: "js"`, a dialect retired in #3278. Delete the key. The transform pipeline that IS enforced is the import mapping's: `mapping.fieldMapping[].transform` (a string enum — `none`/`constant`/`map`/`split`/`join`/`lookup` — with its settings in `params`), applied by the REST import path, which rejects `javascript` with a 400 rather than pretending to run it. Run `os migrate meta --from 16` to rewrite it automatically. |
8888
| **defaultValue** | `any` | optional | Default if source is null/undefined |
8989
| **type** | `string` | optional | Field type |
90-
| **readonly** | `boolean` | optional | Read-only field |
90+
| **readonly** | `boolean` | | Read-only field |
9191

9292

9393
---
@@ -100,14 +100,14 @@ const result = ExternalDataSourceSchema.parse(data);
100100
| :--- | :--- | :--- | :--- |
101101
| **fieldName** | `string` || Field name |
102102
| **dataSource** | `{ id: string; name: string; type: Enum<'odata' \| 'rest-api' \| 'graphql' \| 'custom'>; endpoint: string; … }` || External data source |
103-
| **query** | `{ endpoint: string; method?: Enum<'GET' \| 'POST'>; parameters?: Record<string, any> }` || Query configuration |
104-
| **fieldMappings** | `{ source: string; target: string; transform?: { type: 'constant'; value: any } \| { type: 'cast'; targetType: Enum<'string' \| 'number' \| 'boolean' \| 'date'> } \| { type: 'lookup'; table: string; keyField: string; valueField: string } \| { type: 'javascript'; expression: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object } } \| { type: 'map'; mappings: Record<string, any> }; defaultValue?: any; … }[]` || Field mappings |
105-
| **caching** | `{ enabled?: boolean; ttl?: number; strategy?: Enum<'lru' \| 'lfu' \| 'ttl'> }` | optional | Caching configuration |
106-
| **fallback** | `{ enabled?: boolean; defaultValue?: any; showError?: boolean }` | optional | Fallback configuration |
103+
| **query** | `{ endpoint: string; method: Enum<'GET' \| 'POST'>; parameters?: Record<string, any> }` || Query configuration |
104+
| **fieldMappings** | `{ source: string; target: string; defaultValue?: any; type?: string; … }[]` || Field mappings |
105+
| **caching** | `{ enabled: boolean; ttl: number; strategy: Enum<'lru' \| 'lfu' \| 'ttl'> }` | optional | Caching configuration |
106+
| **fallback** | `{ enabled: boolean; defaultValue?: any; showError: boolean }` | optional | Fallback configuration |
107107
| **rateLimit** | `{ requestsPerSecond: number; burstSize?: number }` | optional | Rate limiting |
108-
| **retry** | `{ maxRetries?: number; initialDelayMs?: number; maxDelayMs?: number; backoffMultiplier?: number; … }` | optional | Retry configuration with exponential backoff |
108+
| **retry** | `{ maxRetries: number; initialDelayMs: number; maxDelayMs: number; backoffMultiplier: number; … }` | optional | Retry configuration with exponential backoff |
109109
| **transform** | `{ request?: object; response?: object }` | optional | Request/response transformation pipeline |
110-
| **pagination** | `{ type?: Enum<'offset' \| 'cursor' \| 'page'>; pageSize?: number; maxPages?: number }` | optional | Pagination configuration for external data |
110+
| **pagination** | `{ type: Enum<'offset' \| 'cursor' \| 'page'>; pageSize: number; maxPages?: number }` | optional | Pagination configuration for external data |
111111

112112

113113
---

content/docs/references/index.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: Protocol Reference
3-
description: Every schema published by @objectstack/spec — 1610 schemas across 14 protocol modules
3+
description: Every schema published by @objectstack/spec — 1609 schemas across 14 protocol modules
44
---
55

66
{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}
@@ -29,11 +29,11 @@ counts are sums of the rows they head. Regenerate with
2929
| [Kernel Protocol](/docs/references/kernel) | 31 | 187 | Plugin lifecycle and manifests, capabilities and security, metadata loading, service registry. |
3030
| [Qa Protocol](/docs/references/qa) | 1 | 8 | Declarative test suites — scenarios, steps, actions and assertions. |
3131
| [Security Protocol](/docs/references/security) | 5 | 27 | Permission sets, row-level security, sharing rules, tenancy posture. |
32-
| [Shared Protocol](/docs/references/shared) | 8 | 32 | Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums. |
32+
| [Shared Protocol](/docs/references/shared) | 8 | 31 | Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums. |
3333
| [Studio Protocol](/docs/references/studio) | 3 | 35 | Studio designer metadata — the authoring surfaces for the protocols above. |
3434
| [System Protocol](/docs/references/system) | 37 | 295 | The runtime environment — logging, jobs, cache, metrics, notifications, i18n and compliance. |
3535
| [UI Protocol](/docs/references/ui) | 17 | 155 | Apps, pages, views, dashboards, reports, actions and themes — the ObjectUI layer. |
36-
| **Total** | **201** | **1610** | 14 protocol modules |
36+
| **Total** | **201** | **1609** | 14 protocol modules |
3737

3838
---
3939

@@ -285,7 +285,7 @@ Permission sets, row-level security, sharing rules, tenancy posture.
285285

286286
## Shared Protocol
287287

288-
**Source:** `packages/spec/src/shared/` · **Import:** `@objectstack/spec/shared` · **8 pages, 32 schemas**
288+
**Source:** `packages/spec/src/shared/` · **Import:** `@objectstack/spec/shared` · **8 pages, 31 schemas**
289289

290290
Primitives used across every protocol — identifiers, HTTP, expressions, error maps, enums.
291291

@@ -296,7 +296,7 @@ Primitives used across every protocol — identifiers, HTTP, expressions, error
296296
| [`expression.zod.ts`](/docs/references/shared/expression) | `CronExpressionInput`, `Expression`, `ExpressionDialect`, `ExpressionInput`, `ExpressionMeta`, `Predicate`, `PredicateInput`, `TemplateExpressionInput` |
297297
| [`http.zod.ts`](/docs/references/shared/http) | `CorsConfig`, `HttpMethod`, `HttpMethodSubset`, `HttpRequest`, `RateLimitConfig`, `StaticMount` |
298298
| [`identifiers.zod.ts`](/docs/references/shared/identifiers) | `EventName`, `SnakeCaseIdentifier`, `SystemIdentifier` |
299-
| [`mapping.zod.ts`](/docs/references/shared/mapping) | `FieldMapping`, `FieldMappingTransform` |
299+
| [`mapping.zod.ts`](/docs/references/shared/mapping) | `FieldMapping` |
300300
| [`metadata-types.zod.ts`](/docs/references/shared/metadata-types) | `BaseMetadataRecord`, `MetadataFormat` |
301301
| [`protection.zod.ts`](/docs/references/shared/protection) | `Protection` |
302302

content/docs/references/integration/connector.mdx

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ Circuit breaker configuration
179179
| **actions** | `{ key: string; label: string; description?: string; inputSchema?: Record<string, any>; … }[]` | optional | |
180180
| **triggers** | `{ key: string; label: string; description?: string; type: Enum<'polling' \| 'webhook'>; … }[]` | optional | Trigger definitions (not yet enforced — never read at registration; see #3197) |
181181
| **syncConfig** | `{ strategy?: Enum<'full' \| 'incremental' \| 'upsert' \| 'append_only'>; direction?: Enum<'import' \| 'export' \| 'bidirectional'>; schedule?: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; realtimeSync?: boolean; … }` | optional | Data sync configuration |
182-
| **fieldMappings** | `{ source: string; target: string; transform?: { type: 'constant'; value: any } \| { type: 'cast'; targetType: Enum<'string' \| 'number' \| 'boolean' \| 'date'> } \| { type: 'lookup'; table: string; keyField: string; valueField: string } \| { type: 'javascript'; expression: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object } } \| { type: 'map'; mappings: Record<string, any> }; defaultValue?: any; … }[]` | optional | Field mapping rules |
182+
| **fieldMappings** | `{ source: string; target: string; defaultValue?: any; dataType?: Enum<'string' \| 'number' \| 'boolean' \| 'date' \| 'datetime' \| 'json' \| 'array'>; … }[]` | optional | Field mapping rules |
183183
| **webhooks** | `{ name: string; label?: string; object?: string; triggers?: Enum<'create' \| 'update' \| 'delete' \| 'bulk_update' \| 'bulk_delete'>[]; … }[]` | optional | Webhook configurations (not yet enforced — never read at registration; see #3197) |
184184
| **rateLimitConfig** | `never` | optional | [REMOVED] `connector.rateLimitConfig` was removed in @objectstack/spec 17.0.0 (#4911, ADR-0049 D2) — the entire shape is gone, not just this key: `ConnectorRateLimitConfig` and its `RateLimitStrategy` enum were removed with it, because no outbound rate-limiting engine ever existed. The platform's only token bucket (runtime `security/rate-limit.ts`) throttles INBOUND requests to us; nothing throttled the calls a connector makes out, so every knob here was inert while reading like a configured cap. Delete the key. Do NOT substitute `shared` `RateLimitConfig` — that is the inbound limiter and would cap the wrong direction; until an outbound throttle exists, rate-limit at the connector provider or upstream gateway. Run `os migrate meta --from 16` to rewrite it automatically. |
185185
| **retryConfig** | `{ strategy?: Enum<'exponential_backoff' \| 'linear_backoff' \| 'fixed_delay' \| 'no_retry'>; maxAttempts?: number; initialDelayMs?: number; maxDelayMs?: number; … }` | optional | Retry configuration |
@@ -249,11 +249,11 @@ Standard error category
249249
| :--- | :--- | :--- | :--- |
250250
| **source** | `string` || Source field name |
251251
| **target** | `string` || Target field name |
252-
| **transform** | `{ type: 'constant'; value: any } \| { type: 'cast'; targetType: Enum<'string' \| 'number' \| 'boolean' \| 'date'> } \| { type: 'lookup'; table: string; keyField: string; valueField: string } \| { type: 'javascript'; expression: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object } } \| { type: 'map'; mappings: Record<string, any> }` | optional | Transformation to apply |
252+
| **transform** | `never` | optional | [REMOVED] `FieldMapping.transform` — authored as `connector.fieldMappings[].transform` and `externalLookup.fieldMappings[].transform` — was removed in @objectstack/spec 17.0.0 (#5552, ADR-0049), and the whole `FieldMappingTransform` union went with it (`constant` / `cast` / `lookup` / `javascript` / `map`) — no runtime ever executed any of the five, and the `javascript` member advertised `dialect: "js"`, a dialect retired in #3278. Delete the key. The transform pipeline that IS enforced is the import mapping's: `mapping.fieldMapping[].transform` (a string enum — `none`/`constant`/`map`/`split`/`join`/`lookup` — with its settings in `params`), applied by the REST import path, which rejects `javascript` with a 400 rather than pretending to run it. Run `os migrate meta --from 16` to rewrite it automatically. |
253253
| **defaultValue** | `any` | optional | Default if source is null/undefined |
254254
| **dataType** | `Enum<'string' \| 'number' \| 'boolean' \| 'date' \| 'datetime' \| 'json' \| 'array'>` | optional | Target data type |
255-
| **required** | `boolean` | optional | Field is required |
256-
| **syncMode** | `Enum<'read_only' \| 'write_only' \| 'bidirectional'>` | optional | Sync mode |
255+
| **required** | `boolean` | | Field is required |
256+
| **syncMode** | `Enum<'read_only' \| 'write_only' \| 'bidirectional'>` | | Sync mode |
257257

258258

259259
---
@@ -481,7 +481,7 @@ Connector type
481481
| **actions** | `{ key: string; label: string; description?: string; inputSchema?: Record<string, any>; … }[]` | optional | |
482482
| **triggers** | `{ key: string; label: string; description?: string; type: Enum<'polling' \| 'webhook'>; … }[]` | optional | Trigger definitions (not yet enforced — never read at registration; see #3197) |
483483
| **syncConfig** | `{ strategy?: Enum<'full' \| 'incremental' \| 'upsert' \| 'append_only'>; direction?: Enum<'import' \| 'export' \| 'bidirectional'>; schedule?: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object }; realtimeSync?: boolean; … }` | optional | Data sync configuration |
484-
| **fieldMappings** | `{ source: string; target: string; transform?: { type: 'constant'; value: any } \| { type: 'cast'; targetType: Enum<'string' \| 'number' \| 'boolean' \| 'date'> } \| { type: 'lookup'; table: string; keyField: string; valueField: string } \| { type: 'javascript'; expression: string \| { dialect: Enum<'cel' \| 'cron' \| 'template'>; source?: string; ast?: any; meta?: object } } \| { type: 'map'; mappings: Record<string, any> }; defaultValue?: any; … }[]` | optional | Field mapping rules |
484+
| **fieldMappings** | `{ source: string; target: string; defaultValue?: any; dataType?: Enum<'string' \| 'number' \| 'boolean' \| 'date' \| 'datetime' \| 'json' \| 'array'>; … }[]` | optional | Field mapping rules |
485485
| **webhooks** | `{ name: string; label?: string; object?: string; triggers?: Enum<'create' \| 'update' \| 'delete' \| 'bulk_update' \| 'bulk_delete'>[]; … }[]` | optional | Webhook configurations (not yet enforced — never read at registration; see #3197) |
486486
| **rateLimitConfig** | `never` | optional | [REMOVED] `connector.rateLimitConfig` was removed in @objectstack/spec 17.0.0 (#4911, ADR-0049 D2) — the entire shape is gone, not just this key: `ConnectorRateLimitConfig` and its `RateLimitStrategy` enum were removed with it, because no outbound rate-limiting engine ever existed. The platform's only token bucket (runtime `security/rate-limit.ts`) throttles INBOUND requests to us; nothing throttled the calls a connector makes out, so every knob here was inert while reading like a configured cap. Delete the key. Do NOT substitute `shared` `RateLimitConfig` — that is the inbound limiter and would cap the wrong direction; until an outbound throttle exists, rate-limit at the connector provider or upstream gateway. Run `os migrate meta --from 16` to rewrite it automatically. |
487487
| **retryConfig** | `{ strategy?: Enum<'exponential_backoff' \| 'linear_backoff' \| 'fixed_delay' \| 'no_retry'>; maxAttempts?: number; initialDelayMs?: number; maxDelayMs?: number; … }` | optional | Retry configuration |

0 commit comments

Comments
 (0)