Repository navigation
Commit 1dc6029
refactor(metadata-protocol): type the six query-options erasures in protocol.ts data reads (#29834)
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8HsXKaPvAsTjybiH6QpVnvn)_
Fixes #29764
Clause-②: no
Metadata-protocol: none
## 维护者速读
- **改了什么**:`protocol.ts` 数据读取里六处把引擎查询参数擦成 `any` 的调用点(`findData` 的
find、count、aggregate,`getData`,`cloneData`,`probeRecord`)改为按引擎声明的类型传参(`EngineQueryOptions`、`EngineCountOptions`、`EngineAggregateOptions`);`protocol.ts`
从擦除基线中移除(计数归零)。
- **为什么改**:#25467 席位裁决
A(6594932448):基线按文件登记且只减不增,这四个方法体带着擦除点搬不出类。类型化之后,#25467
才能把剩下四个方法体作为下一刀搬走。
- **风险与回滚**:低。不改行为:find 与 findOne
的参数包按键逐个从原工作包复制,只复制存在的键,引擎收到的键与之前相同;唯一不再带上的是值为 null 的
`groupBy`/`aggregations`,引擎本来就把 null 读作缺省。回滚即整体 revert。
- **先看**:`protocol.ts` 中 `findQuery` 的构造(`findData` 里);`getData` 的
`findOneQuery`;`scripts/query-options-erasure-baseline.json` 删掉的一行。
- **两分钟验证**:`pnpm check:query-options-erasure`,预期 `✓ … holds`,且输出里不再出现
`protocol.ts`。
- **需要你做的**:无,席位落地。
## What changes
`scripts/query-options-erasure-baseline.json` grandfathered six
`query-options/no-any-erasure` sites in
`packages/metadata-protocol/src/protocol.ts`. Measured on `origin/main`
`eb05ea2f` with the rule run over the file and the grandfathering
lifted:
| line on main | member | engine call | erased expression | declared
type now |
|---:|---|---|---|---|
| 6124 | `findData` | `aggregate` | `{ where, groupBy, aggregations,
having, search, searchFields, context } as any` |
`EngineAggregateOptions` |
| 6220 | `findData` | `find` | `options`, declared `const options: any`
| `EngineQueryOptions` |
| 6296 | `findData` | `count` | `{ where, search, searchFields, context
} as any` | `EngineCountOptions` |
| 6371 | `getData` | `findOne` | `queryOptions`, declared `const
queryOptions: any` | `EngineQueryOptions` |
| 6455 | `cloneData` | `findOne` | `{ where: { id }, ...(ctxOpt as any)
} as any` | `EngineQueryOptions` |
| 6612 | `probeRecord` | `findOne` | `{ where: { id }, context: {
isSystem: true } } as any` | `EngineQueryOptions` |
Each type is the one `IDataEngine` declares for that method
(`packages/spec/src/contracts/data-engine.ts`). How each site is typed:
- **`aggregate` and `count`**: the literal is bound to a typed const
(`aggregateQuery`, `countQuery`) and the assertion is gone.
- **`cloneData` and `probeRecord`**: the assertions are dropped. The
literals already match `findOne`'s parameter.
- **`find` in `findData`**: `options` is the caller's raw request bag,
normalized in place over about 600 lines, so it keeps its working type.
The bag handed to the engine is now a typed `findQuery`, built from the
nine keys the engine's find set holds (`context`, `where`, `fields`,
`orderBy`, `limit`, `offset`, `search`, `searchFields`, `expand`). Each
key is copied only when it is present. By that line every other key has
been folded (`top`, `select` and the other aliases), deleted (`object`,
`count`, `joins`, `windowFunctions`, `cursor`, `distinct`, `having`) or
moved into `where` (the implicit field filters). `groupBy` and
`aggregations` can only be null there: a non-empty one takes the
aggregate branch, an empty one is refused, and a non-array is refused.
The engine already reads a null option as absent
(`rejectUnknownEngineOptions` skips it, and nothing on the find path
reads either key), so leaving them out changes nothing.
- **`findOne` in `getData`**: `queryOptions` stays the working bag,
because the two projection helpers it calls (`projectionFieldsValue`,
`storedMetadataBodyProjection`) answer `unknown`. The bag handed to the
engine is a typed `findOneQuery` built the same way from its four keys
(`where`, `context`, `fields`, `expand`).
`protocol.ts` leaves the baseline: its count is 0, and its key is
removed, as the ratchet asks of a fixed file. `eslint.config.mjs` needs
no edit, since the rule's `ignores` are read from the baseline's keys.
No body moves: that is #25467's next cut.
## Tests
No pin needed an edit, and no new pin was added: the change is in types
plus a key-by-key copy that hands the engine the same keys. A reverse
check shows the types reach the six bags. With one wrong key planted in
each (`direction` in `findQuery` and in `probeRecord`, `limit` in
`aggregateQuery`, `orderBy` in `countQuery`, `sort` in `findOneQuery`,
`filter` in `cloneData`'s literal), the package typecheck exited 2 with
six `TS2353` errors, one per site. The file was restored from `HEAD` and
`git diff HEAD` was empty afterwards.
## Acceptance notes
- `getData`'s working bag and `findData`'s raw request bag still hold
`any` values. What tsc now checks at all six sites is the key set the
engine receives, which is the failure the rule exists for. Typing
`getData`'s working bag itself would need `projectionFieldsValue` and
`storedMetadataBodyProjection` to answer `string[]` when they are given
`string[]`. Those are type-only signature changes in
`protocol-list-query-params.ts` and `metadata-redaction.ts`, outside
this card's surface, and they are noted here, not filed.
- The ratchet also reports `plugin-approvals/src/approval-service.ts`
falling 10 → 4 on main. That row belongs to another file and is left as
it is.
## Verification
On `e16c71d2` (the branch merged with `origin/main` `b0ef25f5`; no file
of this diff moved on main):
- Measure on main `eb05ea2f`, the rule run over `protocol.ts` with the
grandfathering lifted: 6 sites (the table above). On this head: 0.
- Build of the package's dependency closure plus
`@objectstack/objectql`, package typecheck and package test, each
through os-verify-lock: `VERDICT command-exit 0`. Test Files 310 passed,
4 skipped (314); Tests 22305 passed, 26 skipped (22331).
- `pnpm check:query-options-erasure` exits 0: `✓ query-options-erasure
ratchet holds: 38 unswept non-test site(s) in 14 file(s), none new`,
baseline key set verified against `b0ef25f`, no files added.
- `pnpm lint` exits 0, and `eslint packages/metadata-protocol
--no-inline-config` exits 0 with `protocol.ts` now under the rule.
- The published `index.d.ts` is byte-identical. Built from main's
`protocol.ts` and from this head with the same dependency build: sha256
`3a15d153…f48075` on both sides, ESM equal to CJS.
- `node scripts/pm/dispatch-gates.mjs --commands` derived 63 commands.
`--ran` reports 63 derived, 61 run, 2 NOT-MEASURED, 0 UNRUN, and each
run family exits 0. The two NOT-MEASURED exit 3 on a prerequisite, so
their reading is CI's: `check:dual-build-cjs-loads` needs every package
built, and `check-plugin-teardown-shape.mjs --self-test` needs an
unshallowed clone.
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(untouched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes.
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: n/a.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English (the 维护者速读 block is the
dispatch template's).
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbYv9aJAo6MEAcF1dRK)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 3cdb162 commit 1dc6029
3 files changed
Lines changed: 53 additions & 9 deletions
File tree
- .changeset
- packages/metadata-protocol/src
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
113 | 113 | | |
114 | 114 | | |
115 | 115 | | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
116 | 119 | | |
117 | 120 | | |
118 | 121 | | |
| |||
6121 | 6124 | | |
6122 | 6125 | | |
6123 | 6126 | | |
6124 | | - | |
| 6127 | + | |
6125 | 6128 | | |
6126 | 6129 | | |
6127 | 6130 | | |
| |||
6140 | 6143 | | |
6141 | 6144 | | |
6142 | 6145 | | |
6143 | | - | |
| 6146 | + | |
| 6147 | + | |
6144 | 6148 | | |
6145 | 6149 | | |
6146 | 6150 | | |
| |||
6209 | 6213 | | |
6210 | 6214 | | |
6211 | 6215 | | |
| 6216 | + | |
| 6217 | + | |
| 6218 | + | |
| 6219 | + | |
| 6220 | + | |
| 6221 | + | |
| 6222 | + | |
| 6223 | + | |
| 6224 | + | |
| 6225 | + | |
| 6226 | + | |
| 6227 | + | |
| 6228 | + | |
| 6229 | + | |
| 6230 | + | |
| 6231 | + | |
| 6232 | + | |
| 6233 | + | |
| 6234 | + | |
6212 | 6235 | | |
6213 | 6236 | | |
6214 | 6237 | | |
| |||
6217 | 6240 | | |
6218 | 6241 | | |
6219 | 6242 | | |
6220 | | - | |
| 6243 | + | |
6221 | 6244 | | |
6222 | 6245 | | |
6223 | 6246 | | |
| |||
6293 | 6316 | | |
6294 | 6317 | | |
6295 | 6318 | | |
6296 | | - | |
| 6319 | + | |
6297 | 6320 | | |
6298 | 6321 | | |
6299 | 6322 | | |
6300 | 6323 | | |
6301 | | - | |
| 6324 | + | |
| 6325 | + | |
6302 | 6326 | | |
6303 | 6327 | | |
6304 | 6328 | | |
| |||
6368 | 6392 | | |
6369 | 6393 | | |
6370 | 6394 | | |
6371 | | - | |
| 6395 | + | |
| 6396 | + | |
| 6397 | + | |
| 6398 | + | |
| 6399 | + | |
| 6400 | + | |
| 6401 | + | |
| 6402 | + | |
| 6403 | + | |
| 6404 | + | |
| 6405 | + | |
| 6406 | + | |
6372 | 6407 | | |
6373 | 6408 | | |
6374 | 6409 | | |
| |||
6452 | 6487 | | |
6453 | 6488 | | |
6454 | 6489 | | |
6455 | | - | |
| 6490 | + | |
6456 | 6491 | | |
6457 | 6492 | | |
6458 | 6493 | | |
| |||
6609 | 6644 | | |
6610 | 6645 | | |
6611 | 6646 | | |
6612 | | - | |
| 6647 | + | |
6613 | 6648 | | |
6614 | 6649 | | |
6615 | 6650 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
38 | 37 | | |
39 | 38 | | |
40 | 39 | | |
| |||
0 commit comments