feat(cli,playground,docs,generators): Export LikeC4 views to Draw.io#13
feat(cli,playground,docs,generators): Export LikeC4 views to Draw.io#13
Conversation
Co-authored-by: Cursor <[email protected]>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📝 WalkthroughWalkthroughAdded safer, index-based XML/path parsing helpers, adjusted draw.io geometry emission, hardened server lifecycle and round‑trip traversal, sanitized embedded project IDs, and minor playground callback refactors. No public API signature changes. (50 words) Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts (beta)
No actionable comments were generated in the recent review. 🎉 Comment |
…utView.req, mxGeometry relative=1, parse trim, PNG timeout+try/finally) Co-authored-by: Cursor <[email protected]>
…depth limit, normalizeEdgePoint type, JSDoc compressed, charCodeAt, parse fallback comment, decompress success test, spec comments) Co-authored-by: Cursor <[email protected]>
Co-authored-by: Cursor <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@packages/vite-plugin/src/virtuals/icons.ts`:
- Around line 68-77: embedAsJsString currently enforces SAFE_PROJECT_ID_REGEX
against the entire package path (the value constructed via joinURL like
'likec4:icons/someProject'), causing throws because ':' and '/' are valid in the
known-safe prefix; change the logic so only the dynamic project id is validated
with SAFE_PROJECT_ID_REGEX (e.g., validate p.id before building the path), then
construct the full package path using the known-safe prefix
(joinURL('likec4:icons', p.id)) and return JSON.stringify of that full path
without revalidating it in embedAsJsString; update references to
embedAsJsString, SAFE_PROJECT_ID_REGEX, joinURL and p.id accordingly so only the
dynamic portion is checked.
🧹 Nitpick comments (1)
apps/playground/src/monaco/LanguageClientSync.tsx (1)
8-8: Use typedsendRequestoverload withLayoutView.reqinstead of string method.The
LayoutView.reqproperty is aRequestTypeobject (likeFetchComputedModel.req,FetchLayoutedModel.req, and other requests in this file), so it can be passed directly tosendRequestto leverage the typed overload. This eliminates the need for anas LayoutViewProtocol.Rescast and the separate type-only import, while keeping full type inference.♻️ Suggested update
-import type { LayoutView as LayoutViewProtocol } from '@likec4/language-server/protocol' import { BuildDocuments, ChangeView, DidChangeModelNotification, FetchComputedModel, FetchLayoutedModel, LayoutView, Locate, } from '@likec4/language-server/protocol' @@ - const res = (await c.sendRequest(LayoutView.req.method, { - viewId, - })) as LayoutViewProtocol.Res + const res = await c.sendRequest(LayoutView.req, { viewId }) @@ - const res = (await languageClient().sendRequest(LayoutView.req.method, { - viewId, - })) as LayoutViewProtocol.Res + const res = await languageClient().sendRequest(LayoutView.req, { viewId })Also applies to: 114-116, 130-132
…ct ids like e2e and issue-2282 Co-authored-by: Cursor <[email protected]>
…ve cast and type-only import Co-authored-by: Cursor <[email protected]>
…overload compatibility Co-authored-by: Cursor <[email protected]>
…t for wrapper API limitation Co-authored-by: Cursor <[email protected]>
…utView Co-authored-by: Cursor <[email protected]>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/playground/src/monaco/LanguageClientSync.tsx`:
- Line 8: The type-only import "LayoutView as LayoutViewProtocol" is mixed with
value imports in LanguageClientSync.tsx; move this type-only import into the
dedicated type-only import block at the top of the file and split any mixed
imports so that value imports remain in their own block, keeping all imports
sorted alphabetically; specifically relocate the "import type { LayoutView as
LayoutViewProtocol } from '@likec4/language-server/protocol'" line into the
type-only section to comply with the repo import grouping guideline.
… in LanguageClientSync Co-authored-by: Cursor <[email protected]>
Summary
This PR adds export of LikeC4 views to Draw.io (
.drawio) format from the CLI (likec4 export drawio) and the Playground (right-click on diagram → DrawIO → Export view / Export all). It does not include import; import will be proposed in a separate PR.Context for maintainers: This work was first submitted in PR #2614, which received substantial review feedback focused on clean code, structure, and maintainability. We took that feedback seriously and ran a deliberate refactor pass (Uncle Bob / Clean Code) over the DrawIO-related code. This PR re-submits the same feature set with a cleaner, refactored codebase that we believe is easier to review and maintain. We're grateful for the earlier review and have aimed to address those concerns in this iteration.
What's in this PR
1. Generators (
@likec4/generators)computeDiagramLayoutsplit into smaller helpers;getViewDescriptionStringextracted;buildNodeCellXml/buildEdgeCellXmland constants (SOLID/DRY/KISS); exported typeDrawioViewModelLike.parseDrawioToLikeC4Multisplit intomergeDiagramStatesIntoMaps,buildRootsFromFqnToCell,emitMultiDiagramModel(orchestrator ~50–60 lines);buildViewBlockLines/escapeLikec4Quotes; O(n²) deduplication replaced withparsedIdsSet; UserObjectfullTagusesinnerXmlso sibling<data>is preserved.generate-drawio.spec.ts,parse-drawio.spec.ts; snapshots in__snapshots__/. Decompress error assertion accepts (base64 decode|inflate|URI decode) for Node/env behavior; snapshots updated for CI.2. CLI (
@likec4/likec4)likec4 export drawiowith--outdir/-o,--all-in-one,--roundtrip,--uncompressed,--project,--use-dot. UsesDEFAULT_DRAWIO_ALL_FILENAMEfrom@likec4/generators(DRY). Phase comments and thin handler pattern aligned with other export commands.PngExportArgs,runExportPng(args, logger); PNG export supports--outdir/-o(docs updated).likec4 import drawioin this PR (nopackages/likec4/src/cli/import/).3. Playground
generateDrawio/generateDrawioMultiandparseDrawioRoundtripComments. No Import menu item or file input.4. Documentation
--outdir; no Import section.5. E2E & tests
playwright.playground.config.ts.drawio-demo-export-import.spec.ts,drawio-tutorial-export-import.spec.ts— export tests; import/round-trip tests skipped in this PR.What's not in this PR
likec4 import drawiocommand.Refactor summary (response to PR likec4#2614 feedback)
After the initial submission (PR likec4#2614), we applied a structured clean-code pass:
DrawioViewModelLike); constants; phase comments; DRY (e.g.DEFAULT_DRAWIO_ALL_FILENAME, shared helpers).runExport*(args, logger)pattern for drawio/PNG/JSON; consistent error handling and JSDoc.e2e/helpers/.We believe this version is in better shape for review and long-term maintenance.
Correções após review (PR #11)
Incorporadas as sugestões do review anterior:
apimemoizado comuseMemo(..., [actions.openMenu])para evitar re-renders desnecessários.LayoutView.reqemsendRequest(type-safe; removido cast manual).exitCode === 1no erro rejeitado.basenameremove barras finais (/e\) e trata resultado vazio com fallback.arcSize=12(inteiro percentagem) em vez de0.12para cantos ligeiramente arredondados no Draw.io.buildCommonDiagramStateFromCells;buildSingleDiagramStateebuildDiagramStatereutilizam (DRY).useDotlido dos args e passado arunExportDrawio; graphvizbinaryvswasmconforme flag--use-dot.useDotnos args e emrunExportJson; guard quandoprojectsModels.length === 0(warn + throw).Checklist
main(merge/rebase as appropriate).feat:,refactor:,test:).pnpm ci:test(Vitest) passes.Verification
pnpm build(filter!./apps/*),pnpm typecheck,pnpm test(orpnpm ci:test) — pass.Notes for reviewers
DrawioViewModelLikeis the public type for view models passed togenerateDrawio/generateDrawioMulti.runExport*+ thin handler).Reference
Summary by CodeRabbit
Improvements
Chores
Tests
Documentation