@contractkit/plugin-typescript
Advanced tools
| > @contractkit/plugin-typescript@0.17.3 build:ci /home/runner/work/ContractKit/ContractKit/packages/plugin-typescript | ||
| > @contractkit/plugin-typescript@0.17.4 build:ci /home/runner/work/ContractKit/ContractKit/packages/plugin-typescript | ||
| > eslint --max-warnings=0 && pnpm run build | ||
| > @contractkit/plugin-typescript@0.17.3 build /home/runner/work/ContractKit/ContractKit/packages/plugin-typescript | ||
| > @contractkit/plugin-typescript@0.17.4 build /home/runner/work/ContractKit/ContractKit/packages/plugin-typescript | ||
| > tsup src/index.ts --format esm --sourcemap --dts && tsc --emitDeclarationOnly --declaration | ||
@@ -14,7 +14,7 @@ | ||
| [34mESM[39m Build start | ||
| [32mESM[39m [1mdist/index.js [22m[32m125.56 KB[39m | ||
| [32mESM[39m [1mdist/index.js.map [22m[32m272.67 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 328ms | ||
| [32mESM[39m [1mdist/index.js [22m[32m126.39 KB[39m | ||
| [32mESM[39m [1mdist/index.js.map [22m[32m274.93 KB[39m | ||
| [32mESM[39m ⚡️ Build success in 216ms | ||
| [34mDTS[39m Build start | ||
| [32mDTS[39m ⚡️ Build success in 5174ms | ||
| [32mDTS[39m ⚡️ Build success in 5850ms | ||
| [32mDTS[39m [1mdist/index.d.ts [22m[32m3.44 KB[39m |
| > @contractkit/plugin-typescript@0.17.3 test:ci /home/runner/work/ContractKit/ContractKit/packages/plugin-typescript | ||
| > @contractkit/plugin-typescript@0.17.4 test:ci /home/runner/work/ContractKit/ContractKit/packages/plugin-typescript | ||
| > vitest run --coverage | ||
@@ -9,13 +9,13 @@ | ||
| [32m✓[39m tests/codegen-operation.test.ts [2m([22m[2m88 tests[22m[2m)[22m[32m 168[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-sdk.test.ts [2m([22m[2m123 tests[22m[2m)[22m[32m 255[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-contract.test.ts [2m([22m[2m124 tests[22m[2m)[22m[32m 248[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-plain-types.test.ts [2m([22m[2m58 tests[22m[2m)[22m[32m 35[2mms[22m[39m | ||
| [32m✓[39m tests/pipeline.test.ts [2m([22m[2m25 tests[22m[2m)[22m[32m 111[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-server.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 17[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-operation.test.ts [2m([22m[2m88 tests[22m[2m)[22m[32m 98[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-contract.test.ts [2m([22m[2m124 tests[22m[2m)[22m[32m 242[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-sdk.test.ts [2m([22m[2m123 tests[22m[2m)[22m[32m 282[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-plain-types.test.ts [2m([22m[2m61 tests[22m[2m)[22m[32m 45[2mms[22m[39m | ||
| [32m✓[39m tests/codegen-server.test.ts [2m([22m[2m15 tests[22m[2m)[22m[32m 22[2mms[22m[39m | ||
| [32m✓[39m tests/pipeline.test.ts [2m([22m[2m25 tests[22m[2m)[22m[32m 120[2mms[22m[39m | ||
| [2m Test Files [22m [1m[32m6 passed[39m[22m[90m (6)[39m | ||
| [2m Tests [22m [1m[32m433 passed[39m[22m[90m (433)[39m | ||
| [2m Start at [22m 15:36:42 | ||
| [2m Duration [22m 6.17s[2m (transform 2.45s, setup 0ms, import 11.28s, tests 833ms, environment 7ms)[22m | ||
| [2m Tests [22m [1m[32m436 passed[39m[22m[90m (436)[39m | ||
| [2m Start at [22m 15:55:13 | ||
| [2m Duration [22m 6.81s[2m (transform 3.80s, setup 0ms, import 13.43s, tests 808ms, environment 1ms)[22m | ||
@@ -26,7 +26,7 @@ [34m % [39m[2mCoverage report from [22m[33mv8[39m | ||
| -------------------|---------|----------|---------|---------|------------------- | ||
| All files | 77.65 | 74.31 | 82.12 | 79.62 | | ||
| src | 77.35 | 73.93 | 81.51 | 79.28 | | ||
| All files | 77.84 | 74.45 | 82.5 | 79.74 | | ||
| src | 77.54 | 74.08 | 81.92 | 79.4 | | ||
| ...n-contract.ts | 87.83 | 82.12 | 90.08 | 88.96 | ...1069,1074-1075 | ||
| ...-operation.ts | 78.18 | 74.26 | 78.08 | 79.69 | ...68-679,684-685 | ||
| ...lain-types.ts | 87.5 | 76.76 | 92.85 | 91.66 | ...99,211,217,269 | ||
| ...lain-types.ts | 89.08 | 78.37 | 96.66 | 92.3 | ...31,243,249,301 | ||
| codegen-sdk.ts | 88.75 | 83.6 | 85 | 91.49 | ...23,678,712-729 | ||
@@ -33,0 +33,0 @@ index.ts | 23.35 | 19.51 | 33.33 | 25.69 | ...97,415,418,421 |
+6
-0
| # @contractkit/contractkit-plugin-typescript | ||
| ## 0.17.4 | ||
| ### Patch Changes | ||
| - 684a639: Fix plain TypeScript codegen producing invalid `extends` clauses when a child contract redeclares an inherited field without the explicit `override` keyword (e.g. narrowing `kind: BusinessRoleKind` to `kind: 'employee'`). The base is now wrapped in `Omit<Base, 'fieldName'>` for any redeclared field, matching the behaviour for explicit `override` fields. | ||
| ## 0.17.3 | ||
@@ -4,0 +10,0 @@ |
+18
-18
@@ -26,5 +26,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">77.65% </span> | ||
| <span class="strong">77.84% </span> | ||
| <span class="quiet">Statements</span> | ||
| <span class='fraction'>1717/2211</span> | ||
| <span class='fraction'>1732/2225</span> | ||
| </div> | ||
@@ -34,5 +34,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">74.31% </span> | ||
| <span class="strong">74.45% </span> | ||
| <span class="quiet">Branches</span> | ||
| <span class='fraction'>1108/1491</span> | ||
| <span class='fraction'>1119/1503</span> | ||
| </div> | ||
@@ -42,5 +42,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">82.12% </span> | ||
| <span class="strong">82.5% </span> | ||
| <span class="quiet">Functions</span> | ||
| <span class='fraction'>294/358</span> | ||
| <span class='fraction'>297/360</span> | ||
| </div> | ||
@@ -50,5 +50,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">79.62% </span> | ||
| <span class="strong">79.74% </span> | ||
| <span class="quiet">Lines</span> | ||
| <span class='fraction'>1497/1880</span> | ||
| <span class='fraction'>1508/1891</span> | ||
| </div> | ||
@@ -87,13 +87,13 @@ | ||
| <td class="file medium" data-value="src"><a href="src/index.html">src</a></td> | ||
| <td data-value="77.35" class="pic medium"> | ||
| <td data-value="77.54" class="pic medium"> | ||
| <div class="chart"><div class="cover-fill" style="width: 77%"></div><div class="cover-empty" style="width: 23%"></div></div> | ||
| </td> | ||
| <td data-value="77.35" class="pct medium">77.35%</td> | ||
| <td data-value="2159" class="abs medium">1670/2159</td> | ||
| <td data-value="73.93" class="pct medium">73.93%</td> | ||
| <td data-value="1458" class="abs medium">1078/1458</td> | ||
| <td data-value="81.51" class="pct high">81.51%</td> | ||
| <td data-value="330" class="abs high">269/330</td> | ||
| <td data-value="79.28" class="pct medium">79.28%</td> | ||
| <td data-value="1834" class="abs medium">1454/1834</td> | ||
| <td data-value="77.54" class="pct medium">77.54%</td> | ||
| <td data-value="2173" class="abs medium">1685/2173</td> | ||
| <td data-value="74.08" class="pct medium">74.08%</td> | ||
| <td data-value="1470" class="abs medium">1089/1470</td> | ||
| <td data-value="81.92" class="pct high">81.92%</td> | ||
| <td data-value="332" class="abs high">272/332</td> | ||
| <td data-value="79.4" class="pct medium">79.4%</td> | ||
| <td data-value="1845" class="abs medium">1465/1845</td> | ||
| </tr> | ||
@@ -124,3 +124,3 @@ | ||
| <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> | ||
| at 2026-05-05T15:36:48.642Z | ||
| at 2026-05-05T15:55:20.433Z | ||
| </div> | ||
@@ -127,0 +127,0 @@ <script src="prettify.js"></script> |
@@ -26,5 +26,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">87.5% </span> | ||
| <span class="strong">89.08% </span> | ||
| <span class="quiet">Statements</span> | ||
| <span class='fraction'>140/160</span> | ||
| <span class='fraction'>155/174</span> | ||
| </div> | ||
@@ -34,5 +34,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">76.76% </span> | ||
| <span class="strong">78.37% </span> | ||
| <span class="quiet">Branches</span> | ||
| <span class='fraction'>76/99</span> | ||
| <span class='fraction'>87/111</span> | ||
| </div> | ||
@@ -42,5 +42,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">92.85% </span> | ||
| <span class="strong">96.66% </span> | ||
| <span class="quiet">Functions</span> | ||
| <span class='fraction'>26/28</span> | ||
| <span class='fraction'>29/30</span> | ||
| </div> | ||
@@ -50,5 +50,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">91.66% </span> | ||
| <span class="strong">92.3% </span> | ||
| <span class="quiet">Lines</span> | ||
| <span class='fraction'>121/132</span> | ||
| <span class='fraction'>132/143</span> | ||
| </div> | ||
@@ -342,3 +342,35 @@ | ||
| <a name='L272'></a><a href='#L272'>272</a> | ||
| <a name='L273'></a><a href='#L273'>273</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> | ||
| <a name='L273'></a><a href='#L273'>273</a> | ||
| <a name='L274'></a><a href='#L274'>274</a> | ||
| <a name='L275'></a><a href='#L275'>275</a> | ||
| <a name='L276'></a><a href='#L276'>276</a> | ||
| <a name='L277'></a><a href='#L277'>277</a> | ||
| <a name='L278'></a><a href='#L278'>278</a> | ||
| <a name='L279'></a><a href='#L279'>279</a> | ||
| <a name='L280'></a><a href='#L280'>280</a> | ||
| <a name='L281'></a><a href='#L281'>281</a> | ||
| <a name='L282'></a><a href='#L282'>282</a> | ||
| <a name='L283'></a><a href='#L283'>283</a> | ||
| <a name='L284'></a><a href='#L284'>284</a> | ||
| <a name='L285'></a><a href='#L285'>285</a> | ||
| <a name='L286'></a><a href='#L286'>286</a> | ||
| <a name='L287'></a><a href='#L287'>287</a> | ||
| <a name='L288'></a><a href='#L288'>288</a> | ||
| <a name='L289'></a><a href='#L289'>289</a> | ||
| <a name='L290'></a><a href='#L290'>290</a> | ||
| <a name='L291'></a><a href='#L291'>291</a> | ||
| <a name='L292'></a><a href='#L292'>292</a> | ||
| <a name='L293'></a><a href='#L293'>293</a> | ||
| <a name='L294'></a><a href='#L294'>294</a> | ||
| <a name='L295'></a><a href='#L295'>295</a> | ||
| <a name='L296'></a><a href='#L296'>296</a> | ||
| <a name='L297'></a><a href='#L297'>297</a> | ||
| <a name='L298'></a><a href='#L298'>298</a> | ||
| <a name='L299'></a><a href='#L299'>299</a> | ||
| <a name='L300'></a><a href='#L300'>300</a> | ||
| <a name='L301'></a><a href='#L301'>301</a> | ||
| <a name='L302'></a><a href='#L302'>302</a> | ||
| <a name='L303'></a><a href='#L303'>303</a> | ||
| <a name='L304'></a><a href='#L304'>304</a> | ||
| <a name='L305'></a><a href='#L305'>305</a></td><td class="line-coverage quiet"><span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -366,28 +398,28 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">19x</span> | ||
| <span class="cline-any cline-yes">19x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-no"> </span> | ||
@@ -401,9 +433,10 @@ <span class="cline-any cline-no"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">60x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">63x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -414,3 +447,10 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">5x</span> | ||
@@ -421,27 +461,51 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">88x</span> | ||
| <span class="cline-any cline-yes">97x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">3x</span> | ||
| <span class="cline-any cline-yes">3x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">66x</span> | ||
| <span class="cline-any cline-yes">73x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">73x</span> | ||
| <span class="cline-any cline-yes">73x</span> | ||
| <span class="cline-any cline-yes">17x</span> | ||
| <span class="cline-any cline-yes">17x</span> | ||
| <span class="cline-any cline-yes">8x</span> | ||
| <span class="cline-any cline-yes">6x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">73x</span> | ||
| <span class="cline-any cline-yes">73x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">73x</span> | ||
| <span class="cline-any cline-yes">109x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-no"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">1x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-yes">78x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -468,52 +532,52 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">82x</span> | ||
| <span class="cline-any cline-yes">11x</span> | ||
| <span class="cline-any cline-yes">3x</span> | ||
| <span class="cline-any cline-yes">3x</span> | ||
| <span class="cline-any cline-yes">2x</span> | ||
| <span class="cline-any cline-yes">91x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">7x</span> | ||
| <span class="cline-any cline-yes">7x</span> | ||
| <span class="cline-any cline-yes">6x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">50x</span> | ||
| <span class="cline-any cline-yes">50x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">50x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">50x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">50x</span> | ||
| <span class="cline-any cline-yes">71x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-yes">77x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">50x</span> | ||
| <span class="cline-any cline-yes">50x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-yes">55x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">28x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">28x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">25x</span> | ||
| <span class="cline-any cline-yes">32x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">29x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">28x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">32x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -524,27 +588,27 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-no"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">96x</span> | ||
| <span class="cline-any cline-yes">106x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-no"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">18x</span> | ||
| <span class="cline-any cline-yes">21x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -678,4 +742,6 @@ <span class="cline-any cline-neutral"> </span> | ||
| | ||
| const modelMap = new Map(root.models.map(m => [m.name, m])); | ||
| | ||
| for (const model of topoSortModels(root.models)) { | ||
| lines.push(...generateModel(model, context?.currentOutPath, allModelsWithInput, allModelsWithOutput)); | ||
| lines.push(...generateModel(model, context?.currentOutPath, allModelsWithInput, allModelsWithOutput, modelMap)); | ||
| lines.push(''); | ||
@@ -689,3 +755,9 @@ } | ||
| | ||
| function generateModel(model: ModelNode, outPath?: string, modelsWithInput?: Set<string>, modelsWithOutput?: Set<string>): string[] { | ||
| function generateModel( | ||
| model: ModelNode, | ||
| outPath?: string, | ||
| modelsWithInput?: Set<string>, | ||
| modelsWithOutput?: Set<string>, | ||
| modelMap?: Map<string, ModelNode>, | ||
| ): string[] { | ||
| // Type alias: Name : typeExpression | ||
@@ -700,3 +772,3 @@ if (model.type) { | ||
| | ||
| const lines = needsInputSplit ? generateVisibilityModel(model, outPath, modelsWithInput) : generateSimpleModel(model, outPath); | ||
| const lines = needsInputSplit ? generateVisibilityModel(model, outPath, modelsWithInput, modelMap) : generateSimpleModel(model, outPath, modelMap); | ||
| | ||
@@ -710,2 +782,26 @@ if (modelsWithOutput?.has(model.name)) { | ||
| | ||
| /** Recursively collect every field name defined on `bases` and their ancestors. Used to detect | ||
| * fields that the child re-declares without an explicit `override` keyword — those still need an | ||
| * `Omit<Base, …>` wrap, otherwise the child's narrower/incompatible declaration collides with the | ||
| * inherited one. */ | ||
| function collectInheritedFieldNames(bases: string[], modelMap: Map<string, ModelNode>): Set<string> { | ||
| const result = new Set<string>(); | ||
| const visit = (name: string): void => { | ||
| const m = modelMap.get(name); | ||
| if (!m || m.type) return; | ||
| for (const f of m.fields) result.add(f.name); | ||
| for (const b of m.bases ?? []) visit(b); | ||
| }; | ||
| for (const b of bases) visit(b); | ||
| return result; | ||
| } | ||
| | ||
| /** Names of fields the child declaration overrides — explicit `override` plus any field whose | ||
| * name shadows an inherited one. The latter catches single-base redeclarations that omit the | ||
| * `override` keyword (e.g. narrowing `kind: BusinessRoleKind` → `kind: 'employee'`). */ | ||
| function computeOverrideNames(model: ModelNode, modelMap?: Map<string, ModelNode>): string[] { | ||
| const inherited = modelMap ? collectInheritedFieldNames(model.bases ?? [], modelMap) : <span class="branch-1 cbranch-no" title="branch not covered" >new Set<string>();</span> | ||
| return model.fields.filter(f => f.override || inherited.has(f.name)).map(f => f.name); | ||
| } | ||
| | ||
| function generateComments(model: ModelNode, outPath?: string): string[] { | ||
@@ -740,7 +836,7 @@ const lines: string[] = []; | ||
| | ||
| /** Build the `extends` clause for a multi-base model. | ||
| * Override-marked field names are wrapped in `Omit<Base, 'name1' | 'name2'>` per base so the | ||
| * subclass can legally redeclare them with new types. TypeScript's `Omit<T, K extends keyof any>` | ||
| * tolerates omit keys that don't appear on the base, so we omit unconditionally — no need to know | ||
| * each base's actual field set. */ | ||
| /** Build the `extends` clause for a model. | ||
| * Each entry in `overrideNames` is wrapped in `Omit<Base, 'name1' | 'name2'>` per base so the | ||
| * subclass can legally redeclare those fields with new (possibly incompatible) types. | ||
| * TypeScript's `Omit<T, K extends keyof any>` tolerates omit keys that don't appear on the base, | ||
| * so we apply the same omit list to every base without per-base field-set lookup. */ | ||
| function buildExtendsClause(bases: string[], overrideNames: string[], baseNameResolver: (b: string) => string): string { | ||
@@ -754,3 +850,3 @@ if (bases.length === 0) return ''; | ||
| | ||
| function generateSimpleModel(model: ModelNode, outPath?: string): string[] { | ||
| function generateSimpleModel(model: ModelNode, outPath?: string, modelMap?: Map<string, ModelNode>): string[] { | ||
| const lines: string[] = []; | ||
@@ -760,3 +856,3 @@ lines.push(...generateComments(model, outPath)); | ||
| const bases = model.bases ?? []; | ||
| const overrideNames = model.fields.filter(f => f.override).map(f => f.name); | ||
| const overrideNames = computeOverrideNames(model, modelMap); | ||
| lines.push(`export interface ${model.name}${buildExtendsClause(bases, overrideNames, b => b)} {`); | ||
@@ -772,3 +868,3 @@ | ||
| | ||
| function generateVisibilityModel(model: ModelNode, outPath?: string, modelsWithInput?: Set<string>): string[] { | ||
| function generateVisibilityModel(model: ModelNode, outPath?: string, modelsWithInput?: Set<string>, modelMap?: Map<string, ModelNode>): string[] { | ||
| const lines: string[] = []; | ||
@@ -778,3 +874,3 @@ lines.push(...generateComments(model, outPath)); | ||
| const bases = model.bases ?? []; | ||
| const overrideNames = model.fields.filter(f => f.override).map(<span class="fstat-no" title="function not covered" >f => <span class="cstat-no" title="statement not covered" >f</span>.name)</span>; | ||
| const overrideNames = computeOverrideNames(model, modelMap); | ||
| | ||
@@ -909,3 +1005,3 @@ // Read type — omit writeonly fields | ||
| <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> | ||
| at 2026-05-05T15:36:48.642Z | ||
| at 2026-05-05T15:55:20.433Z | ||
| </div> | ||
@@ -912,0 +1008,0 @@ <script src="../prettify.js"></script> |
+19
-19
@@ -26,5 +26,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">77.35% </span> | ||
| <span class="strong">77.54% </span> | ||
| <span class="quiet">Statements</span> | ||
| <span class='fraction'>1670/2159</span> | ||
| <span class='fraction'>1685/2173</span> | ||
| </div> | ||
@@ -34,5 +34,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">73.93% </span> | ||
| <span class="strong">74.08% </span> | ||
| <span class="quiet">Branches</span> | ||
| <span class='fraction'>1078/1458</span> | ||
| <span class='fraction'>1089/1470</span> | ||
| </div> | ||
@@ -42,5 +42,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">81.51% </span> | ||
| <span class="strong">81.92% </span> | ||
| <span class="quiet">Functions</span> | ||
| <span class='fraction'>269/330</span> | ||
| <span class='fraction'>272/332</span> | ||
| </div> | ||
@@ -50,5 +50,5 @@ | ||
| <div class='fl pad1y space-right2'> | ||
| <span class="strong">79.28% </span> | ||
| <span class="strong">79.4% </span> | ||
| <span class="quiet">Lines</span> | ||
| <span class='fraction'>1454/1834</span> | ||
| <span class='fraction'>1465/1845</span> | ||
| </div> | ||
@@ -117,13 +117,13 @@ | ||
| <td class="file high" data-value="codegen-plain-types.ts"><a href="codegen-plain-types.ts.html">codegen-plain-types.ts</a></td> | ||
| <td data-value="87.5" class="pic high"> | ||
| <div class="chart"><div class="cover-fill" style="width: 87%"></div><div class="cover-empty" style="width: 13%"></div></div> | ||
| <td data-value="89.08" class="pic high"> | ||
| <div class="chart"><div class="cover-fill" style="width: 89%"></div><div class="cover-empty" style="width: 11%"></div></div> | ||
| </td> | ||
| <td data-value="87.5" class="pct high">87.5%</td> | ||
| <td data-value="160" class="abs high">140/160</td> | ||
| <td data-value="76.76" class="pct medium">76.76%</td> | ||
| <td data-value="99" class="abs medium">76/99</td> | ||
| <td data-value="92.85" class="pct high">92.85%</td> | ||
| <td data-value="28" class="abs high">26/28</td> | ||
| <td data-value="91.66" class="pct high">91.66%</td> | ||
| <td data-value="132" class="abs high">121/132</td> | ||
| <td data-value="89.08" class="pct high">89.08%</td> | ||
| <td data-value="174" class="abs high">155/174</td> | ||
| <td data-value="78.37" class="pct medium">78.37%</td> | ||
| <td data-value="111" class="abs medium">87/111</td> | ||
| <td data-value="96.66" class="pct high">96.66%</td> | ||
| <td data-value="30" class="abs high">29/30</td> | ||
| <td data-value="92.3" class="pct high">92.3%</td> | ||
| <td data-value="143" class="abs high">132/143</td> | ||
| </tr> | ||
@@ -199,3 +199,3 @@ | ||
| <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> | ||
| at 2026-05-05T15:36:48.642Z | ||
| at 2026-05-05T15:55:20.433Z | ||
| </div> | ||
@@ -202,0 +202,0 @@ <script src="../prettify.js"></script> |
@@ -637,3 +637,3 @@ | ||
| <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> | ||
| at 2026-05-05T15:36:48.642Z | ||
| at 2026-05-05T15:55:20.433Z | ||
| </div> | ||
@@ -640,0 +640,0 @@ <script src="../prettify.js"></script> |
@@ -240,3 +240,3 @@ | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">165x</span> | ||
| <span class="cline-any cline-yes">178x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -258,5 +258,5 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">330x</span> | ||
| <span class="cline-any cline-yes">343x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">164x</span> | ||
| <span class="cline-any cline-yes">170x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -278,3 +278,3 @@ <span class="cline-any cline-yes">20x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">5x</span> | ||
| <span class="cline-any cline-yes">12x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -298,3 +298,3 @@ <span class="cline-any cline-yes">3x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">164x</span> | ||
| <span class="cline-any cline-yes">170x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -304,3 +304,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">113x</span> | ||
| <span class="cline-any cline-yes">116x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -312,3 +312,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">2x</span> | ||
| <span class="cline-any cline-yes">5x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -348,4 +348,4 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">89x</span> | ||
| <span class="cline-any cline-yes">43x</span> | ||
| <span class="cline-any cline-yes">92x</span> | ||
| <span class="cline-any cline-yes">46x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -373,3 +373,3 @@ <span class="cline-any cline-yes">15x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">16x</span> | ||
| <span class="cline-any cline-yes">19x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -588,3 +588,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> | ||
| at 2026-05-05T15:36:48.642Z | ||
| at 2026-05-05T15:55:20.433Z | ||
| </div> | ||
@@ -591,0 +591,0 @@ <script src="../prettify.js"></script> |
@@ -344,7 +344,7 @@ | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">857x</span> | ||
| <span class="cline-any cline-yes">874x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">313x</span> | ||
| <span class="cline-any cline-yes">318x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -369,3 +369,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">10x</span> | ||
| <span class="cline-any cline-yes">15x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -394,3 +394,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">247x</span> | ||
| <span class="cline-any cline-yes">257x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -407,3 +407,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">171x</span> | ||
| <span class="cline-any cline-yes">178x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -418,3 +418,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
| <span class="cline-any cline-yes">134x</span> | ||
| <span class="cline-any cline-yes">137x</span> | ||
| <span class="cline-any cline-neutral"> </span> | ||
@@ -819,3 +819,3 @@ <span class="cline-any cline-neutral"> </span> | ||
| <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> | ||
| at 2026-05-05T15:36:48.642Z | ||
| at 2026-05-05T15:55:20.433Z | ||
| </div> | ||
@@ -822,0 +822,0 @@ <script src="../prettify.js"></script> |
@@ -104,3 +104,3 @@ | ||
| <a href="https://istanbul.js.org/" target="_blank" rel="noopener noreferrer">istanbul</a> | ||
| at 2026-05-05T15:36:48.642Z | ||
| at 2026-05-05T15:55:20.433Z | ||
| </div> | ||
@@ -107,0 +107,0 @@ <script src="../prettify.js"></script> |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"codegen-plain-types.d.ts","sourceRoot":"","sources":["../src/codegen-plain-types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAwB,MAAM,mBAAmB,CAAC;AAEhF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAapE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,CAyCnG"} | ||
| {"version":3,"file":"codegen-plain-types.d.ts","sourceRoot":"","sources":["../src/codegen-plain-types.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,gBAAgB,EAAwB,MAAM,mBAAmB,CAAC;AAEhF,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAapE;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,gBAAgB,EAAE,OAAO,CAAC,EAAE,sBAAsB,GAAG,MAAM,CA2CnG"} |
+3
-3
| { | ||
| "name": "@contractkit/plugin-typescript", | ||
| "version": "0.17.3", | ||
| "version": "0.17.4", | ||
| "description": "ContractKit built-in plugin: TypeScript codegen (SDK clients, Koa routers, Zod schemas, plain types)", | ||
@@ -32,4 +32,4 @@ "author": { | ||
| "devDependencies": { | ||
| "@repo/config-eslint": "0.3.1", | ||
| "@repo/config-typescript": "0.1.0" | ||
| "@repo/config-typescript": "0.1.0", | ||
| "@repo/config-eslint": "0.3.1" | ||
| }, | ||
@@ -36,0 +36,0 @@ "scripts": { |
@@ -58,4 +58,6 @@ import { relative, dirname } from 'node:path'; | ||
| const modelMap = new Map(root.models.map(m => [m.name, m])); | ||
| for (const model of topoSortModels(root.models)) { | ||
| lines.push(...generateModel(model, context?.currentOutPath, allModelsWithInput, allModelsWithOutput)); | ||
| lines.push(...generateModel(model, context?.currentOutPath, allModelsWithInput, allModelsWithOutput, modelMap)); | ||
| lines.push(''); | ||
@@ -69,3 +71,9 @@ } | ||
| function generateModel(model: ModelNode, outPath?: string, modelsWithInput?: Set<string>, modelsWithOutput?: Set<string>): string[] { | ||
| function generateModel( | ||
| model: ModelNode, | ||
| outPath?: string, | ||
| modelsWithInput?: Set<string>, | ||
| modelsWithOutput?: Set<string>, | ||
| modelMap?: Map<string, ModelNode>, | ||
| ): string[] { | ||
| // Type alias: Name : typeExpression | ||
@@ -80,3 +88,3 @@ if (model.type) { | ||
| const lines = needsInputSplit ? generateVisibilityModel(model, outPath, modelsWithInput) : generateSimpleModel(model, outPath); | ||
| const lines = needsInputSplit ? generateVisibilityModel(model, outPath, modelsWithInput, modelMap) : generateSimpleModel(model, outPath, modelMap); | ||
@@ -90,2 +98,26 @@ if (modelsWithOutput?.has(model.name)) { | ||
| /** Recursively collect every field name defined on `bases` and their ancestors. Used to detect | ||
| * fields that the child re-declares without an explicit `override` keyword — those still need an | ||
| * `Omit<Base, …>` wrap, otherwise the child's narrower/incompatible declaration collides with the | ||
| * inherited one. */ | ||
| function collectInheritedFieldNames(bases: string[], modelMap: Map<string, ModelNode>): Set<string> { | ||
| const result = new Set<string>(); | ||
| const visit = (name: string): void => { | ||
| const m = modelMap.get(name); | ||
| if (!m || m.type) return; | ||
| for (const f of m.fields) result.add(f.name); | ||
| for (const b of m.bases ?? []) visit(b); | ||
| }; | ||
| for (const b of bases) visit(b); | ||
| return result; | ||
| } | ||
| /** Names of fields the child declaration overrides — explicit `override` plus any field whose | ||
| * name shadows an inherited one. The latter catches single-base redeclarations that omit the | ||
| * `override` keyword (e.g. narrowing `kind: BusinessRoleKind` → `kind: 'employee'`). */ | ||
| function computeOverrideNames(model: ModelNode, modelMap?: Map<string, ModelNode>): string[] { | ||
| const inherited = modelMap ? collectInheritedFieldNames(model.bases ?? [], modelMap) : new Set<string>(); | ||
| return model.fields.filter(f => f.override || inherited.has(f.name)).map(f => f.name); | ||
| } | ||
| function generateComments(model: ModelNode, outPath?: string): string[] { | ||
@@ -120,7 +152,7 @@ const lines: string[] = []; | ||
| /** Build the `extends` clause for a multi-base model. | ||
| * Override-marked field names are wrapped in `Omit<Base, 'name1' | 'name2'>` per base so the | ||
| * subclass can legally redeclare them with new types. TypeScript's `Omit<T, K extends keyof any>` | ||
| * tolerates omit keys that don't appear on the base, so we omit unconditionally — no need to know | ||
| * each base's actual field set. */ | ||
| /** Build the `extends` clause for a model. | ||
| * Each entry in `overrideNames` is wrapped in `Omit<Base, 'name1' | 'name2'>` per base so the | ||
| * subclass can legally redeclare those fields with new (possibly incompatible) types. | ||
| * TypeScript's `Omit<T, K extends keyof any>` tolerates omit keys that don't appear on the base, | ||
| * so we apply the same omit list to every base without per-base field-set lookup. */ | ||
| function buildExtendsClause(bases: string[], overrideNames: string[], baseNameResolver: (b: string) => string): string { | ||
@@ -134,3 +166,3 @@ if (bases.length === 0) return ''; | ||
| function generateSimpleModel(model: ModelNode, outPath?: string): string[] { | ||
| function generateSimpleModel(model: ModelNode, outPath?: string, modelMap?: Map<string, ModelNode>): string[] { | ||
| const lines: string[] = []; | ||
@@ -140,3 +172,3 @@ lines.push(...generateComments(model, outPath)); | ||
| const bases = model.bases ?? []; | ||
| const overrideNames = model.fields.filter(f => f.override).map(f => f.name); | ||
| const overrideNames = computeOverrideNames(model, modelMap); | ||
| lines.push(`export interface ${model.name}${buildExtendsClause(bases, overrideNames, b => b)} {`); | ||
@@ -152,3 +184,3 @@ | ||
| function generateVisibilityModel(model: ModelNode, outPath?: string, modelsWithInput?: Set<string>): string[] { | ||
| function generateVisibilityModel(model: ModelNode, outPath?: string, modelsWithInput?: Set<string>, modelMap?: Map<string, ModelNode>): string[] { | ||
| const lines: string[] = []; | ||
@@ -158,3 +190,3 @@ lines.push(...generateComments(model, outPath)); | ||
| const bases = model.bases ?? []; | ||
| const overrideNames = model.fields.filter(f => f.override).map(f => f.name); | ||
| const overrideNames = computeOverrideNames(model, modelMap); | ||
@@ -161,0 +193,0 @@ // Read type — omit writeonly fields |
@@ -422,2 +422,40 @@ import { describe, it, expect } from 'vitest'; | ||
| }); | ||
| it('omits implicit single-base redeclarations even without explicit override', () => { | ||
| // BusinessRoleOfficer-style: child redeclares `kind` without `override` keyword, | ||
| // narrowing to an incompatible literal — must wrap base in Omit to compile. | ||
| const root = contractRoot([ | ||
| model('Employee', [field('kind', literalType('employee')), field('title', scalarType('string'))]), | ||
| model('Officer', [field('kind', literalType('officer')), field('isControlPerson', scalarType('boolean'))], { | ||
| bases: ['Employee'], | ||
| }), | ||
| ]); | ||
| const output = generatePlainTypes(root); | ||
| expect(output).toContain("export interface Officer extends Omit<Employee, 'kind'> {"); | ||
| }); | ||
| it('applies implicit-override Omit to both Read and Input interfaces', () => { | ||
| const root = contractRoot([ | ||
| model('Employee', [ | ||
| field('id', scalarType('uuid'), { visibility: 'readonly' }), | ||
| field('kind', literalType('employee')), | ||
| ]), | ||
| model('Officer', [field('kind', literalType('officer')), field('isControlPerson', scalarType('boolean'))], { | ||
| bases: ['Employee'], | ||
| }), | ||
| ]); | ||
| const output = generatePlainTypes(root); | ||
| expect(output).toContain("export interface Officer extends Omit<Employee, 'kind'> {"); | ||
| expect(output).toContain("export interface OfficerInput extends Omit<EmployeeInput, 'kind'> {"); | ||
| }); | ||
| it('detects redeclaration through transitive base chain', () => { | ||
| const root = contractRoot([ | ||
| model('Root', [field('kind', scalarType('string'))]), | ||
| model('Mid', [], { bases: ['Root'] }), | ||
| model('Leaf', [field('kind', literalType('leaf'))], { bases: ['Mid'] }), | ||
| ]); | ||
| const output = generatePlainTypes(root); | ||
| expect(output).toContain("export interface Leaf extends Omit<Mid, 'kind'> {"); | ||
| }); | ||
| }); | ||
@@ -424,0 +462,0 @@ |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
2204774
0.75%14261
0.71%