任务:核心的 xlsx@1 解析器(上真实台架第 2 件的通用部分)
依据:docs/hub-r4-device-run.md 第 3 节第 1 条,第 8 节第 2 件;docs/hub-r4-tasks/hub-case-workbook.md 第 1 条(这一件就是那一条,拆出来先做)。
Hub 要回读 Circle 上传的工作簿,读取分两层:
- 核心加一个通用的 xlsx@1 解析器,只给出格式上的结构,不带运行器和生成器的任何字;
-
按运行器的写法解释单元格、判“只认生成器写的子集”,是 case-compile 包的核验检查的事,在 hub-case-workbook 里做,不在这一件。
- 分支和工作树:
xlsx-parser,目录circle-hub-xlsx-parser(从 hub-redesign 开出,依赖已装好) - 可以改的路径:
hub/refs/parsers/xlsx.ts(新文件)和它的测试;hub/refs/parsers/index.ts里注册的一行;hub/refs/parser.test.ts里固定默认解析器清单和数量的两处断言;hub/server/upload.ts的扩展名和媒体类型表加 xlsx;hub/refs/README.md加一节。
别的路径不动。不加新的 npm 依赖:解压用 Node 自带的 zlib(带输出上限和 CRC 校验)或已有的 fflate,XML 用现有的 xml@1 解析器。
- 规则:同前(不推送、不建 PR、不发布、不部署;不碰 7420、钥匙串、环境配置文件和任何真实系统;测试只用合成的工作簿,在测试里现生成;
git commit -s)。所有者的规矩:未知只能是过渡状态,写明缺的事实和下一步动作;Hub 只核验,不生成内容。 - 验证:
npx tsc --noEmit;node --test --test-concurrency=1对hub/refs/**、hub/server/**。
要做的
- 只因通用理由整份拒绝,并写明是哪一项:
- zip 上限:总字节数、成员数、单个和总解压量、解压比;
- 成员路径:不许绝对路径、
..、反斜杠、NUL; - 加密成员、重复成员;
- 缺工作簿部件,或关系指向不存在的部件;
- 某个部件的 XML 被 xml@1 修复过;
- 字节不是 zip:不被识别。
- 模型如实给出结构:
- 成员清单(名字、大小、内容类型);
- 工作表(名字、可见性);
- 行(行号、是否隐藏);
- 单元格(引用、类型、值文本、是否公式、样式号);
- 共享字符串解开后的文本;
- 定义名(名字、作用域、引用);
- 每张表的最后一行,只有样式的单元格也算。
样式、主题、文档属性这类部件不解释,只出现在成员清单里;宏和外部链接也只列出,从不跟随。选择器写法照其他解析器(例如
c/<表>/<单元格>、n/<定义名>),写进 README。 - 同样的字节给出同样的模型;解析失败时报的是确定的原因,不是未知。
- 测试:
- 模型:内联和共享字符串、数字、公式标记、隐藏行、隐藏的表、只有样式的空行计入最后一行、表级和工作簿级定义名、以
=开头的值原样作文本; - 拒绝:超大、解压比过大(炸弹)、成员过多、路径穿越、加密成员、重复成员、关系断链、XML 被修复过;
- 不是 zip 的字节不被识别;
- 两次解析的模型相同。
- 模型:内联和共享字符串、数字、公式标记、隐藏行、隐藏的表、只有样式的空行计入最后一行、表级和工作簿级定义名、以
完成后在终端里回报:提交号、测试数量、没做完或拿不准的地方。