Commit d38ad7f
fix(rest): type the two production exceljs dynamic imports behind one named accessor (#13452)
* fix(rest): type the two production exceljs dynamic imports behind one named accessor
Both places `packages/rest` production source reached exceljs bound the module
as `const ExcelJS: any`, so `parseXlsxToRows` (the whole .xlsx import path) and
`createXlsxStream` (the streaming .xlsx export path) built workbooks, read
worksheets, iterated rows and read cells through a value tsc knew nothing
about. A misspelled method, a wrong arity or a property exceljs renamed was not
a compile error, only a runtime fault in a deployed import or export.
`src/xlsx-module.ts` is now the single binding site both paths share. It keeps
the load lazy (everything is either a type, erased at emit, or inside the async
accessor), and it states the trade it accepts: typing the dynamic import pulls
exceljs's declarations -- including the module-local `Buffer` shim -- into
production modules that previously kept them out. The cost drops from "the whole
path is unchecked" to "one named assertion with its reason written next to it".
That assertion, `asXlsxLoadInput`, takes `Buffer` and not `Buffer | ArrayBuffer`
deliberately: `ArrayBuffer` is already assignable to exceljs's shim, so that arm
reaches `load` unasserted and stays checked. `wb.getWorksheet(sheet as any)`
loses its cast for the same reason -- the real signature accepts `string |
number` as it stands.
Typing-only. No runtime behaviour change: the interop expression is the one the
call sites already ran (awaited once rather than twice -- the second await
resolved from the module cache to the identical record), and `Row.values`'s
non-array shape iterates zero times before and after.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvqBFLRzXdSPcbusDoED9k
* chore(changeset): @objectstack/rest patch for the production exceljs typing
Measured rather than assumed: the accessor reaches the published artifact
(`loadExcelJs` greps 3 in dist/index.js and 3 in dist/index.cjs, positive
control `RestServer` = 36), so this PR releases something and `skip-changeset`
would be false.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvqBFLRzXdSPcbusDoED9k
* test(rest): pin the accessor's interop and both parseXlsxToRows arms; re-anchor the isSystem census
The typed accessor's TYPE half is asserted by tsc; its runtime half is not, and
two things there can rot silently. `xlsx-module.test.ts` pins both: the
CommonJS interop (drop either half of `.default ?? namespace` and `Workbook` is
undefined, visible only in a deployed import/export), and both arms of
`parseXlsxToRows(buffer: Buffer | ArrayBuffer, ...)` -- the Node `Buffer` arm
that carries the assertion and the `ArrayBuffer` arm that stays checked without
one -- driven against bytes the accessor itself wrote.
`check:system-context-census` went red on this branch and the cause is this
branch: the one import line added to `rest-server.ts` shifted every elevation
read below it by one, so nine anchors on
`content/docs/permissions/system-context.mdx` pointed one line short. Measured,
not assumed -- with `rest-server.ts` alone restored to the merge base the gate
reads `OK - 109 elevation read sites ... 145 anchors resolve`. `--fix` refuses
this one by design (it counts 8 page read-anchors against 6 census sites and
calls that a population change, not a shift), so the nine anchors are bumped by
hand.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvqBFLRzXdSPcbusDoED9k
* docs(rest): the package-door census says which `.catch` is load-bearing, and stops claiming the swallow is documented nowhere
Comment-only. Item 3 of the 2026-08-29 ride-along ruling: the census file is
where a reader of this door lands, and it named two `.catch(() => undefined)`
sites without saying that a production fault reaches NEITHER of them as a
rejection. `computeExecCtx` wraps its whole body in `try { ... } catch { return
undefined; }`, so the resolve FULFILS with `undefined` and the
fault-to-anonymous conversion has already happened one level below -- which is
exactly the mistake the ruling names, "stops a future reader from removing the
wrong `.catch` expecting a fault to surface". It also records that this first
net is NOT per-door: the two `.catch`es are per-consumer (16 of them in
rest-server.ts) while computeExecCtx's catch is one site every consumer
inherits.
Both facts are cited, not restated -- they are measured in
package-door-execctx-fault-reading.test.ts,
package-door-execctx-fault-reachability.test.ts and
execctx-consumer-census.test.ts, and a second copy is a second thing to drift.
The same paragraph's closing note said the swallow is "documented at NEITHER
site". That is now half stale and was corrected in place rather than left
adjacent to a fresh correction: rest-server.ts's
resolvePackageRouteExecutionContext carries the reading (the second-net point
included); the package-routes.ts site still carries none.
Comment-only proven with scripts/js-comment-mask.mjs, on a comparator
calibrated in BOTH directions: code identity 9b977535ecc0592f before and after,
while a one-token code change to the same file DIFFERS and a comment word
change does not. Raw bytes differ (5dbceb5dddb84287 -> d74dac3166529e9f), so
the green is not "nothing happened". rest-server.ts is untouched, so the nine
hand-bumped anchors in content/docs/permissions/system-context.mdx cannot have
moved; check:system-context-census re-reads OK over 109 sites.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TvqBFLRzXdSPcbusDoED9k
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 370524d commit d38ad7f
7 files changed
Lines changed: 283 additions & 13 deletions
File tree
- .changeset
- content/docs/permissions
- packages/rest/src
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
64 | 64 | | |
65 | 65 | | |
66 | 66 | | |
67 | | - | |
| 67 | + | |
68 | 68 | | |
69 | 69 | | |
70 | 70 | | |
| |||
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
106 | | - | |
| 106 | + | |
107 | 107 | | |
108 | 108 | | |
109 | 109 | | |
| |||
158 | 158 | | |
159 | 159 | | |
160 | 160 | | |
161 | | - | |
| 161 | + | |
162 | 162 | | |
163 | 163 | | |
164 | 164 | | |
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
| 202 | + | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
16 | 17 | | |
17 | 18 | | |
18 | 19 | | |
| |||
138 | 139 | | |
139 | 140 | | |
140 | 141 | | |
141 | | - | |
| 142 | + | |
142 | 143 | | |
143 | | - | |
144 | | - | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
145 | 150 | | |
146 | 151 | | |
147 | 152 | | |
148 | | - | |
149 | | - | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
150 | 159 | | |
151 | 160 | | |
152 | 161 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
100 | 100 | | |
101 | 101 | | |
102 | 102 | | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
103 | 135 | | |
104 | 136 | | |
105 | 137 | | |
| |||
116 | 148 | | |
117 | 149 | | |
118 | 150 | | |
119 | | - | |
120 | | - | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
121 | 156 | | |
122 | 157 | | |
123 | 158 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
194 | 194 | | |
195 | 195 | | |
196 | 196 | | |
| 197 | + | |
197 | 198 | | |
198 | 199 | | |
199 | 200 | | |
| |||
605 | 606 | | |
606 | 607 | | |
607 | 608 | | |
608 | | - | |
| 609 | + | |
609 | 610 | | |
610 | 611 | | |
611 | 612 | | |
612 | | - | |
| 613 | + | |
613 | 614 | | |
614 | 615 | | |
615 | 616 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
0 commit comments