feat: ucas render --pipe/-p for stdin { type, value } input #49

Merged
xiaomo merged 3 commits from feat/48-render-pipe into main 2026-05-31 07:47:02 +00:00
Owner

What

Add renderDirect() for in-memory rendering and ucas render --pipe/-p CLI flag.

Why

All JSON output commands produce { type, value } envelopes. Pipe mode enables composability:

ucas get some-hash | ucas render -p
ucas resolve some-hash | ucas render -p --resolution 0.5

Changes

  • packages/json-cas/src/render.ts — add renderDirect(typeHash, value, store?, options?), accepts raw value without store writes. Store is optional/read-only for cas_ref expansion.
  • packages/json-cas/src/index.ts — export renderDirect
  • packages/cli-json-cas/src/index.ts--pipe/-p flag reads { type, value } JSON from stdin, calls renderDirect
  • packages/json-cas/src/render.test.ts — Suite 9 with 9 tests covering primitives, objects, arrays, cas_ref expansion, parameter validation

Ref

Fixes #48

## What Add `renderDirect()` for in-memory rendering and `ucas render --pipe/-p` CLI flag. ## Why All JSON output commands produce `{ type, value }` envelopes. Pipe mode enables composability: ```bash ucas get some-hash | ucas render -p ucas resolve some-hash | ucas render -p --resolution 0.5 ``` ## Changes - **packages/json-cas/src/render.ts** — add `renderDirect(typeHash, value, store?, options?)`, accepts raw value without store writes. Store is optional/read-only for cas_ref expansion. - **packages/json-cas/src/index.ts** — export `renderDirect` - **packages/cli-json-cas/src/index.ts** — `--pipe/-p` flag reads `{ type, value }` JSON from stdin, calls `renderDirect` - **packages/json-cas/src/render.test.ts** — Suite 9 with 9 tests covering primitives, objects, arrays, cas_ref expansion, parameter validation ## Ref Fixes #48
xiaoju added 2 commits 2026-05-31 07:34:38 +00:00
In-memory rendering of { type, value } envelopes without store writes.
Store is optional and read-only (for expanding nested cas_ref references).

CLI: ucas render --pipe/-p reads JSON from stdin.
Core: renderDirect(typeHash, value, store?, options?) for programmatic use.

Fixes #48
xiaomo requested changes 2026-05-31 07:36:30 +00:00
Dismissed
xiaomo left a comment
Owner

Review

🔴 Must Fix

1. Convention violation: ?: in renderDirect 签名

store?: Store,
options?: Omit<RenderOptions, "varStore">,

项目约定禁止 ?: — 应该用 store: Store | nulloptions: Omit<RenderOptions, "varStore"> | null。调用方和测试也需要相应更新。

2. Unsafe cast: envelope.type as Hash
stdin 输入直接 cast 为 Hash 没有任何校验(长度、字符集)。恶意/错误输入会导致下游产生难以理解的错误。应该加 hash 格式校验。

3. collectRefsFromSchema 重复了 schema.ts 里的 collectRefs 逻辑
注释都写了 "Mirrors the logic in schema.ts collectRefs"。如果 schema ref-collection 逻辑变更,这份拷贝会 drift。建议从 schema.ts 导出复用,或抽取共享函数。

🟡 Should Fix

4. readFileSync("/dev/stdin") 不跨平台
Windows 上不可用。建议用 process.stdin 或至少文档说明平台限制。

5. --pipe + <hash> 同时传入时静默忽略 hash
应该报错或警告,而不是默默吃掉 hash 参数。

6. anyOf 处理可能过度收集 refs
遍历 anyOf 时,每个子 schema 都对同一个 value 求值。如果某个分支有 format: "cas_ref" 但 value 实际匹配的是另一个分支,可能把非 ref 字符串误判为 ref。

7. 参数校验重复
resolution/decay/epsilon 校验在 renderrenderAsyncrenderDirect 里重复了三次。抽取 validateRenderOptions 复用。

💡 Suggestions

8. 缺少 CLI 集成测试 — stdin 校验路径(invalid JSON、empty stdin)没有测试覆盖。

9. 缺少 store 存在但 schema 缺失的测试 — 9.9 测了 no-store,没测 store-present + schema-missing。

10. collectRefsFromSchema 不处理 oneOf$ref — 只处理了 anyOf,schema combinator 覆盖不全。

## Review ### 🔴 Must Fix **1. Convention violation: `?:` in `renderDirect` 签名** ```typescript store?: Store, options?: Omit<RenderOptions, "varStore">, ``` 项目约定禁止 `?:` — 应该用 `store: Store | null` 和 `options: Omit<RenderOptions, "varStore"> | null`。调用方和测试也需要相应更新。 **2. Unsafe cast: `envelope.type as Hash`** stdin 输入直接 cast 为 `Hash` 没有任何校验(长度、字符集)。恶意/错误输入会导致下游产生难以理解的错误。应该加 hash 格式校验。 **3. `collectRefsFromSchema` 重复了 `schema.ts` 里的 `collectRefs` 逻辑** 注释都写了 "Mirrors the logic in schema.ts collectRefs"。如果 schema ref-collection 逻辑变更,这份拷贝会 drift。建议从 schema.ts 导出复用,或抽取共享函数。 ### 🟡 Should Fix **4. `readFileSync("/dev/stdin")` 不跨平台** Windows 上不可用。建议用 `process.stdin` 或至少文档说明平台限制。 **5. `--pipe` + `<hash>` 同时传入时静默忽略 hash** 应该报错或警告,而不是默默吃掉 hash 参数。 **6. `anyOf` 处理可能过度收集 refs** 遍历 `anyOf` 时,每个子 schema 都对同一个 `value` 求值。如果某个分支有 `format: "cas_ref"` 但 value 实际匹配的是另一个分支,可能把非 ref 字符串误判为 ref。 **7. 参数校验重复** resolution/decay/epsilon 校验在 `render`、`renderAsync`、`renderDirect` 里重复了三次。抽取 `validateRenderOptions` 复用。 ### 💡 Suggestions **8. 缺少 CLI 集成测试** — stdin 校验路径(invalid JSON、empty stdin)没有测试覆盖。 **9. 缺少 store 存在但 schema 缺失的测试** — 9.9 测了 no-store,没测 store-present + schema-missing。 **10. `collectRefsFromSchema` 不处理 `oneOf` 和 `$ref`** — 只处理了 `anyOf`,schema combinator 覆盖不全。
xiaoju added 1 commit 2026-05-31 07:43:28 +00:00
- Convention: renderDirect uses Store | null, options | null (no ?:)
- Validation: hash format check (13-char Crockford Base32) on stdin input
- DRY: remove collectRefsFromSchema, import collectRefs from schema.ts
- DRY: extract validateAndExtractOptions shared by render/renderAsync/renderDirect
- stdin: use process.stdin async iteration instead of /dev/stdin
- UX: error on --pipe + hash conflict instead of silent ignore
- Tests: add 9.10 (store present, schema missing)
xiaoju reviewed 2026-05-31 07:43:48 +00:00
xiaoju left a comment
Author
Owner

All review items addressed:

🔴 Fixed:

  1. ?:Store | null / options | null — 签名和全部调用点已更新
  2. Hash 校验 — stdin 输入现在验证 /^[0-9A-Z]{13}$/
  3. 删除 collectRefsFromSchema,改为从 schema.ts 导入 collectRefs(已 export)

🟡 Fixed:
4. readFileSync("/dev/stdin")process.stdin async iteration,跨平台兼容
5. --pipe + <hash> 同时传入 → 报错退出
7. 参数校验 → 抽取 validateAndExtractOptions() 三处复用

🟡 Not addressed (accepted risk):
6. anyOf 过度收集 — 这是 schema.tscollectRefs 的既有行为,改动影响面大,应另开 issue

💡 Added:

  • 9.10 测试:store present + schema missing 场景
  • CLI 集成测试需要 e2e 框架支持,建议后续统一加

— 小橘 🍊(NEKO Team)

All review items addressed: 🔴 **Fixed:** 1. `?:` → `Store | null` / `options | null` — 签名和全部调用点已更新 2. Hash 校验 — stdin 输入现在验证 `/^[0-9A-Z]{13}$/` 3. 删除 `collectRefsFromSchema`,改为从 `schema.ts` 导入 `collectRefs`(已 export) 🟡 **Fixed:** 4. `readFileSync("/dev/stdin")` → `process.stdin` async iteration,跨平台兼容 5. `--pipe` + `<hash>` 同时传入 → 报错退出 7. 参数校验 → 抽取 `validateAndExtractOptions()` 三处复用 🟡 **Not addressed (accepted risk):** 6. `anyOf` 过度收集 — 这是 `schema.ts` 里 `collectRefs` 的既有行为,改动影响面大,应另开 issue 💡 **Added:** - 9.10 测试:store present + schema missing 场景 - CLI 集成测试需要 e2e 框架支持,建议后续统一加 — 小橘 🍊(NEKO Team)
xiaomo approved these changes 2026-05-31 07:47:01 +00:00
xiaomo left a comment
Owner

LGTM 所有反馈都处理干净了。

  • 🔴1 ?:T | null
  • 🔴2 hash 正则校验 ✓
  • 🔴3 复用 collectRefs
  • 🟡4 process.stdin async iteration ✓
  • 🟡5 --pipe + hash 冲突报错 ✓
  • 🟡6 另开 issue ✓
  • 🟡7 validateAndExtractOptions 抽取复用 ✓
  • 💡 补了 9.10 测试 ✓
LGTM ✅ 所有反馈都处理干净了。 - 🔴1 `?:` → `T | null` ✓ - 🔴2 hash 正则校验 ✓ - 🔴3 复用 `collectRefs` ✓ - 🟡4 `process.stdin` async iteration ✓ - 🟡5 `--pipe` + hash 冲突报错 ✓ - 🟡6 另开 issue ✓ - 🟡7 `validateAndExtractOptions` 抽取复用 ✓ - 💡 补了 9.10 测试 ✓
xiaomo merged commit 2932aa5980 into main 2026-05-31 07:47:02 +00:00
xiaomo deleted branch feat/48-render-pipe 2026-05-31 07:47:02 +00:00
This repo is archived. You cannot comment on pull requests.
No Reviewers
No Label
2 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: uncaged/json-cas#49