plannar 0.0.3 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +4 -4
- package/dist/{editor-Bv5RTgcT.mjs → editor-Cc5XAM2j.mjs} +9 -8
- package/dist/export-BSvaL5R2.mjs +653 -0
- package/dist/{status-gCBxoymh.mjs → status-B4laDYjc.mjs} +1 -1
- package/package.json +11 -1
- package/dist/abap-BW9c03a7.mjs +0 -3
- package/dist/actionscript-3-B6AeQsdr.mjs +0 -3
- package/dist/ada-UAfcUgld.mjs +0 -3
- package/dist/andromeeda-Cu62joT4.mjs +0 -4
- package/dist/angular-html-C-eFVAIe.mjs +0 -33
- package/dist/angular-ts-BD6BhTYj.mjs +0 -27
- package/dist/apache-DWevXWr1.mjs +0 -3
- package/dist/apex-TPGYj5YO.mjs +0 -3
- package/dist/apl-DUmaAe2b.mjs +0 -17
- package/dist/applescript-DOvaC_Oy.mjs +0 -3
- package/dist/ara-D-j-XXGW.mjs +0 -3
- package/dist/asciidoc-Cds5g02g.mjs +0 -3
- package/dist/asm-fKrNhGI-.mjs +0 -3
- package/dist/astro-DO4Glno9.mjs +0 -19
- package/dist/aurora-x-BB0J0IeM.mjs +0 -4
- package/dist/awk-BffybAOE.mjs +0 -3
- package/dist/ayu-dark-BIk2eYyl.mjs +0 -4
- package/dist/ayu-light-pnpopa_u.mjs +0 -4
- package/dist/ayu-mirage-Dq1YQdbW.mjs +0 -4
- package/dist/ballerina-BD5CldPU.mjs +0 -3
- package/dist/bat-DMbz78YR.mjs +0 -3
- package/dist/beancount-CaTd9Bjz.mjs +0 -3
- package/dist/berry-BgUsmVaH.mjs +0 -3
- package/dist/bibtex-BS9dLuV0.mjs +0 -3
- package/dist/bicep-DWRRWjGd.mjs +0 -3
- package/dist/bird2-BlSty-nT.mjs +0 -3
- package/dist/blade-CH2DZiyx.mjs +0 -21
- package/dist/bsl-CJ91opd0.mjs +0 -6
- package/dist/c-D_Rf5vw8.mjs +0 -6
- package/dist/c3-CC9BmleM.mjs +0 -3
- package/dist/cadence-DrOG_Vzs.mjs +0 -3
- package/dist/cairo-BP4NeRvu.mjs +0 -6
- package/dist/catppuccin-frappe-CSSZy2I0.mjs +0 -4
- package/dist/catppuccin-latte-DnTXDnsj.mjs +0 -4
- package/dist/catppuccin-macchiato-Ckw0Vhkh.mjs +0 -4
- package/dist/catppuccin-mocha-BgepuhoR.mjs +0 -4
- package/dist/clarity-BUDmzLZe.mjs +0 -3
- package/dist/clojure-WWg3It68.mjs +0 -3
- package/dist/cmake-DFHdRVuU.mjs +0 -3
- package/dist/cobol-BAR5Vngc.mjs +0 -11
- package/dist/codeowners-DVDrZMQO.mjs +0 -3
- package/dist/codeql-CyBidtfP.mjs +0 -3
- package/dist/coffee-BInjHxEE.mjs +0 -6
- package/dist/common-lisp-QjFch7-u.mjs +0 -3
- package/dist/coq-BsUrCVvK.mjs +0 -3
- package/dist/cpp-CENjCKTD.mjs +0 -25
- package/dist/crystal-CXaN9OP7.mjs +0 -19
- package/dist/csharp-D-QFUFEE.mjs +0 -3
- package/dist/css-C2wCJA_G.mjs +0 -6
- package/dist/csv-Cb3ztF11.mjs +0 -3
- package/dist/cue-BRViwSb5.mjs +0 -3
- package/dist/cypher-DsZ0r_SN.mjs +0 -3
- package/dist/d-DeVAByS9.mjs +0 -3
- package/dist/dark-plus-DnPTOHJQ.mjs +0 -4
- package/dist/dart-DWVGvPVl.mjs +0 -3
- package/dist/dax-CCVgOCrm.mjs +0 -3
- package/dist/desktop-BLG2KUib.mjs +0 -3
- package/dist/diff-CR6iDLhj.mjs +0 -3
- package/dist/docker-ByH34NvG.mjs +0 -3
- package/dist/dotenv-el5rplMn.mjs +0 -3
- package/dist/dracula-CpEdEQts.mjs +0 -4
- package/dist/dracula-soft-CZr0C0df.mjs +0 -4
- package/dist/dream-maker-DDljGJt4.mjs +0 -3
- package/dist/edge-no12TFHE.mjs +0 -13
- package/dist/elixir-SbOgBhDM.mjs +0 -6
- package/dist/elm-BRsMBjKT.mjs +0 -6
- package/dist/emacs-lisp-C8HQcRPk.mjs +0 -3
- package/dist/erb-C1_C5jep.mjs +0 -11
- package/dist/erlang-C5gFQJZg.mjs +0 -6
- package/dist/everforest-dark-BAMXVMpE.mjs +0 -4
- package/dist/everforest-light-C_EkXd7H.mjs +0 -4
- package/dist/export-BPZixWW4.mjs +0 -59476
- package/dist/fennel-BBDzQpxJ.mjs +0 -3
- package/dist/fish-BVKcOoo3.mjs +0 -3
- package/dist/fluent-CiEY0tx7.mjs +0 -3
- package/dist/fortran-fixed-form-DPiyERAR.mjs +0 -6
- package/dist/fortran-free-form-Dy4Ia3xC.mjs +0 -3
- package/dist/fsharp-BXAgfpA4.mjs +0 -6
- package/dist/gdresource-CRXhH7lA.mjs +0 -11
- package/dist/gdscript-DUk6d3qS.mjs +0 -3
- package/dist/gdshader-DJwZO-zm.mjs +0 -3
- package/dist/genie-B2jvDwB3.mjs +0 -3
- package/dist/gherkin-CFYsr5Em.mjs +0 -3
- package/dist/git-commit-Bb8y57z7.mjs +0 -6
- package/dist/git-rebase-BECFh1Cx.mjs +0 -6
- package/dist/github-dark-DvHYl2p7.mjs +0 -4
- package/dist/github-dark-default-MALL2Q4C.mjs +0 -4
- package/dist/github-dark-dimmed-CFzqRqSr.mjs +0 -4
- package/dist/github-dark-high-contrast-Be0PQ9D9.mjs +0 -4
- package/dist/github-light-B84bxdHo.mjs +0 -4
- package/dist/github-light-default-B49MFeR5.mjs +0 -4
- package/dist/github-light-high-contrast-B9ThWYcN.mjs +0 -4
- package/dist/gleam-B7e4lIXe.mjs +0 -3
- package/dist/glimmer-js-BxRSm1Iz.mjs +0 -15
- package/dist/glimmer-ts-B-PXhnA-.mjs +0 -15
- package/dist/glsl-DCpEHOoJ.mjs +0 -8
- package/dist/gn-oCpvJfaB.mjs +0 -3
- package/dist/gnuplot-DGkrsXyD.mjs +0 -3
- package/dist/go-DOBPmz4q.mjs +0 -3
- package/dist/graphql-KsWq5dbl.mjs +0 -17
- package/dist/groovy-JRvXAe6e.mjs +0 -3
- package/dist/gruvbox-dark-hard-DZtjD3-K.mjs +0 -4
- package/dist/gruvbox-dark-medium-CnvJvh1e.mjs +0 -4
- package/dist/gruvbox-dark-soft-DT7fdnlk.mjs +0 -4
- package/dist/gruvbox-light-hard-Z0yBUPTq.mjs +0 -4
- package/dist/gruvbox-light-medium-VcFR0ZPw.mjs +0 -4
- package/dist/gruvbox-light-soft-BjpMTObq.mjs +0 -4
- package/dist/hack-Dl36VvRT.mjs +0 -11
- package/dist/haml-CybNLmKL.mjs +0 -13
- package/dist/handlebars-CjcvRR6G.mjs +0 -15
- package/dist/haskell-9GVaCDAy.mjs +0 -3
- package/dist/haxe-BjwmQP6x.mjs +0 -3
- package/dist/hcl-CGDoStcp.mjs +0 -3
- package/dist/hjson-CH_gnwQd.mjs +0 -3
- package/dist/hlsl-ivzEgiy0.mjs +0 -3
- package/dist/horizon-BAPJOej1.mjs +0 -4
- package/dist/horizon-bright-CBbQxVuj.mjs +0 -4
- package/dist/houston-Bsel4WXn.mjs +0 -4
- package/dist/html-DfZ5CvWO.mjs +0 -13
- package/dist/html-derivative-Bl2uHcRG.mjs +0 -6
- package/dist/http-2GSJ1Ota.mjs +0 -15
- package/dist/hurl-BuTA3a1U.mjs +0 -13
- package/dist/hxml-CIJx3GAL.mjs +0 -6
- package/dist/hy-CFVRK0Nt.mjs +0 -3
- package/dist/imba-CpUXJ8TV.mjs +0 -3
- package/dist/ini-CdpG8IPX.mjs +0 -3
- package/dist/java-Dd2Sr4ei.mjs +0 -6
- package/dist/javascript-CZ7QJWaI.mjs +0 -6
- package/dist/jinja-rGuAaq8y.mjs +0 -10
- package/dist/jison-f_1eFoen.mjs +0 -6
- package/dist/json-ufdHUD6V.mjs +0 -6
- package/dist/json5-7RecBf2_.mjs +0 -3
- package/dist/jsonc-CBGnPf32.mjs +0 -3
- package/dist/jsonl-CmLQaM5O.mjs +0 -3
- package/dist/jsonnet-tXOQdkDx.mjs +0 -3
- package/dist/jssm-CtDTf-es.mjs +0 -3
- package/dist/jsx-BY17L1TJ.mjs +0 -6
- package/dist/julia-jv62bi7k.mjs +0 -17
- package/dist/just-C6qr4mXt.mjs +0 -19
- package/dist/kanagawa-dragon-BDtUi23j.mjs +0 -4
- package/dist/kanagawa-lotus-BBtsE-9U.mjs +0 -4
- package/dist/kanagawa-wave-DehP6Jw_.mjs +0 -4
- package/dist/kdl-DGaDNPP2.mjs +0 -3
- package/dist/kotlin-B10KLoOh.mjs +0 -3
- package/dist/kusto-iwa79TLz.mjs +0 -3
- package/dist/laserwave-oGyAE_TK.mjs +0 -4
- package/dist/latex-bq3Inh3R.mjs +0 -6
- package/dist/lean-CIMS95nW.mjs +0 -3
- package/dist/less-BmQG9s2A.mjs +0 -3
- package/dist/light-plus-BKYJg4pO.mjs +0 -4
- package/dist/liquid-BGg1u_N2.mjs +0 -15
- package/dist/llvm-D_R1tubu.mjs +0 -3
- package/dist/log-A1ddhKk2.mjs +0 -3
- package/dist/logo-CAINsCxc.mjs +0 -3
- package/dist/lua-Ctym3rMV.mjs +0 -8
- package/dist/luau-CAYz1b8d.mjs +0 -3
- package/dist/make-BoMd6Eg0.mjs +0 -3
- package/dist/markdown-q2UTVhPv.mjs +0 -3
- package/dist/marko-3VCDTT2m.mjs +0 -15
- package/dist/material-theme-B5VoDPKV.mjs +0 -4
- package/dist/material-theme-darker-B1HCXk1e.mjs +0 -4
- package/dist/material-theme-lighter-Cj_YmAmc.mjs +0 -4
- package/dist/material-theme-ocean-BaeR8VhB.mjs +0 -4
- package/dist/material-theme-palenight-DieYMRIR.mjs +0 -4
- package/dist/matlab-BmW78Ua4.mjs +0 -3
- package/dist/mdc-n4CFO8GD.mjs +0 -13
- package/dist/mdx-IgTZ_PsQ.mjs +0 -3
- package/dist/mermaid-D1WKgk1u.mjs +0 -3
- package/dist/min-dark-Da4XHK1C.mjs +0 -4
- package/dist/min-light-B1G-gK7R.mjs +0 -4
- package/dist/mipsasm-D__MkRT6.mjs +0 -3
- package/dist/mojo-CMCD6kSt.mjs +0 -3
- package/dist/monokai-Dja8c9XW.mjs +0 -4
- package/dist/moonbit-BmzABvgk.mjs +0 -3
- package/dist/move-CtOzYpc7.mjs +0 -3
- package/dist/narrat-C8ZM2zHi.mjs +0 -3
- package/dist/nextflow-BuXhAF6g.mjs +0 -6
- package/dist/nextflow-groovy-BucdoGBt.mjs +0 -3
- package/dist/nginx-DCav9fr2.mjs +0 -6
- package/dist/night-owl-CFEDim2c.mjs +0 -4
- package/dist/night-owl-light-BABXmJim.mjs +0 -4
- package/dist/nim-D9QPp5kW.mjs +0 -21
- package/dist/nix-_kfSRp5x.mjs +0 -7
- package/dist/nord-BEvLRKJz.mjs +0 -4
- package/dist/nushell-CG6WVreI.mjs +0 -3
- package/dist/objective-c-DOVmNqC4.mjs +0 -3
- package/dist/objective-cpp-BWlpWva0.mjs +0 -3
- package/dist/ocaml-Wwmuez2Q.mjs +0 -3
- package/dist/odin-ByfuPSu8.mjs +0 -3
- package/dist/one-dark-pro-CXLLrmxx.mjs +0 -4
- package/dist/one-light-1TrAkc9b.mjs +0 -4
- package/dist/openscad-CYYW-Lvy.mjs +0 -3
- package/dist/pascal-DlWtMFUC.mjs +0 -3
- package/dist/perl-F1w6BTW4.mjs +0 -17
- package/dist/php-D5RNc8cb.mjs +0 -19
- package/dist/pkl-BJSLmUc7.mjs +0 -3
- package/dist/plastic-BOdHQ7hi.mjs +0 -4
- package/dist/plsql-CtnOltln.mjs +0 -3
- package/dist/po-ChBiJtw3.mjs +0 -3
- package/dist/poimandres-sZlsXmSW.mjs +0 -4
- package/dist/polar-BRgTqojJ.mjs +0 -3
- package/dist/postcss-DAhKZdRf.mjs +0 -3
- package/dist/powerquery-BKTL9xfg.mjs +0 -3
- package/dist/powershell-BmCCV9e7.mjs +0 -3
- package/dist/prisma-C-mW5eQ1.mjs +0 -3
- package/dist/prolog-BG0_G0sz.mjs +0 -3
- package/dist/proto-Cjvlr4bQ.mjs +0 -3
- package/dist/pug-BoqONK6L.mjs +0 -13
- package/dist/puppet-CjFnVLMe.mjs +0 -3
- package/dist/purescript-Vb2OcJR8.mjs +0 -3
- package/dist/python-ARgqtcr9.mjs +0 -3
- package/dist/qml-CN98xHYu.mjs +0 -6
- package/dist/qmldir-BR3wWyS0.mjs +0 -3
- package/dist/qss-Baln5J4y.mjs +0 -3
- package/dist/r-CgkRbgWa.mjs +0 -6
- package/dist/racket-HuXCA8Np.mjs +0 -3
- package/dist/raku--XBLzYuF.mjs +0 -3
- package/dist/razor-D9GoeIvC.mjs +0 -11
- package/dist/red-DieXtVH2.mjs +0 -4
- package/dist/reg-N3tN4G1s.mjs +0 -3
- package/dist/regexp-Cmzs-b17.mjs +0 -6
- package/dist/rel-BWA2fVVw.mjs +0 -3
- package/dist/riscv-CNsUL9F1.mjs +0 -3
- package/dist/ron-C_zPdle-.mjs +0 -3
- package/dist/rose-pine-NQGQN_Py.mjs +0 -4
- package/dist/rose-pine-dawn-CDEuRC-V.mjs +0 -4
- package/dist/rose-pine-moon-DN6_RPeE.mjs +0 -4
- package/dist/rosmsg-yiq-v07k.mjs +0 -3
- package/dist/rst-BMhVqyG1.mjs +0 -23
- package/dist/ruby-C7SejiSM.mjs +0 -31
- package/dist/rust-DYp2JQv-.mjs +0 -3
- package/dist/sas-CGU-Ko3q.mjs +0 -6
- package/dist/sass-DVKushYG.mjs +0 -3
- package/dist/scala-lpjTPFHX.mjs +0 -3
- package/dist/scheme-wOQJFUig.mjs +0 -3
- package/dist/scss-zkWWQrdN.mjs +0 -8
- package/dist/sdbl--PnDxzGT.mjs +0 -3
- package/dist/shaderlab-i7KCgReF.mjs +0 -6
- package/dist/shellscript-CaJ5viEZ.mjs +0 -6
- package/dist/shellsession-DuB7oTvQ.mjs +0 -6
- package/dist/slack-dark-6rIBdtCf.mjs +0 -4
- package/dist/slack-ochin-nUh4VZSG.mjs +0 -4
- package/dist/smalltalk-n_YRhdTv.mjs +0 -3
- package/dist/snazzy-light-DkuQw6Z-.mjs +0 -4
- package/dist/solarized-dark-DG_xfWAC.mjs +0 -4
- package/dist/solarized-light-CIcPm0uy.mjs +0 -4
- package/dist/solidity-BpTVGGR3.mjs +0 -3
- package/dist/soy-lf7Er5NU.mjs +0 -6
- package/dist/sparql-Bk-JyIQk.mjs +0 -6
- package/dist/splunk-D1Az7tvn.mjs +0 -3
- package/dist/sql-D1uCIb-4.mjs +0 -6
- package/dist/ssh-config-DAsGgEig.mjs +0 -3
- package/dist/stata-DenNw7ri.mjs +0 -6
- package/dist/stylus-CNLem3u-.mjs +0 -3
- package/dist/surrealql-CCYzU3tm.mjs +0 -6
- package/dist/svelte-C36RW4eY.mjs +0 -15
- package/dist/swift-DAcVMcFy.mjs +0 -3
- package/dist/synthwave-84-gkUURId2.mjs +0 -4
- package/dist/system-verilog-CL1nVinO.mjs +0 -3
- package/dist/systemd-C7P5y8lI.mjs +0 -3
- package/dist/talonscript-BE-x9pgh.mjs +0 -3
- package/dist/tasl-C7s9745E.mjs +0 -3
- package/dist/tcl-BLsPJ7iC.mjs +0 -3
- package/dist/templ-Dte43-Eo.mjs +0 -13
- package/dist/terraform-v0Ek_rks.mjs +0 -3
- package/dist/tex-CRJxStv9.mjs +0 -6
- package/dist/tokyo-night-Oja5OrLi.mjs +0 -4
- package/dist/toml-wLAVRnMH.mjs +0 -3
- package/dist/ts-tags-Cs6jrN-1.mjs +0 -59
- package/dist/tsv-Qo5b4XGG.mjs +0 -3
- package/dist/tsx-CZnUd1jF.mjs +0 -6
- package/dist/turtle-Bo7XW2KG.mjs +0 -3
- package/dist/twig-A2qf0tKU.mjs +0 -19
- package/dist/typescript-DgW8lbMR.mjs +0 -6
- package/dist/typespec-DvXBeCkw.mjs +0 -3
- package/dist/typst-D73qYMMw.mjs +0 -3
- package/dist/v-CpO787mz.mjs +0 -3
- package/dist/vala-BqFlVoH_.mjs +0 -3
- package/dist/vb-Bo7BiOwD.mjs +0 -3
- package/dist/verilog-DABjKKO6.mjs +0 -3
- package/dist/vesper-tVhzEr-k.mjs +0 -4
- package/dist/vhdl-CB8TvDTZ.mjs +0 -3
- package/dist/viml-CuM98KEF.mjs +0 -3
- package/dist/vitesse-black-P6rRX5YD.mjs +0 -4
- package/dist/vitesse-dark-Di9MWjvq.mjs +0 -4
- package/dist/vitesse-light-ChosFYw8.mjs +0 -4
- package/dist/vue-BtFfPSdA.mjs +0 -31
- package/dist/vue-html-BIVhvoTt.mjs +0 -6
- package/dist/vue-vine-BRJbnPV0.mjs +0 -19
- package/dist/vyper-DYoGCYmu.mjs +0 -3
- package/dist/wasm-DhFUmAQm.mjs +0 -7
- package/dist/wasm-NKC9-wJ8.mjs +0 -3
- package/dist/wenyan-CCNBOs6Y.mjs +0 -3
- package/dist/wgsl-n1IZMc_u.mjs +0 -3
- package/dist/wikitext-5isXOJoG.mjs +0 -3
- package/dist/wit-BP1frIMq.mjs +0 -3
- package/dist/wolfram-e8E-o4Bx.mjs +0 -3
- package/dist/xml-czz4UX4-.mjs +0 -8
- package/dist/xsl-BL1DqGMX.mjs +0 -6
- package/dist/yaml-B2yUh7a5.mjs +0 -6
- package/dist/zenscript-kGsI2Rqh.mjs +0 -3
- package/dist/zig-C5f0bk_4.mjs +0 -3
- /package/dist/{config-FJViU9hJ.mjs → config-C_Uf66xX.mjs} +0 -0
- /package/dist/{init-CK5HMoQf.mjs → init-OGg6OjUh.mjs} +0 -0
package/dist/cli.mjs
CHANGED
|
@@ -10,10 +10,10 @@ const main = defineCommand({
|
|
|
10
10
|
description: "MDX plan editor CLI — init, preview, and export plans"
|
|
11
11
|
},
|
|
12
12
|
subCommands: {
|
|
13
|
-
init: () => import("./init-
|
|
14
|
-
editor: () => import("./editor-
|
|
15
|
-
export: () => import("./export-
|
|
16
|
-
status: () => import("./status-
|
|
13
|
+
init: () => import("./init-OGg6OjUh.mjs").then((m) => m.default),
|
|
14
|
+
editor: () => import("./editor-Cc5XAM2j.mjs").then((m) => m.default),
|
|
15
|
+
export: () => import("./export-BSvaL5R2.mjs").then((m) => m.default),
|
|
16
|
+
status: () => import("./status-B4laDYjc.mjs").then((m) => m.default)
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
19
|
const junkCss = join(process.cwd(), ".plannar", "node_modules", ".plannar-junk.css");
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
-
import { n as resolveConfig, t as merge } from "./config-
|
|
1
|
+
import { n as resolveConfig, t as merge } from "./config-C_Uf66xX.mjs";
|
|
2
2
|
import { defineCommand } from "citty";
|
|
3
3
|
import { existsSync } from "node:fs";
|
|
4
4
|
import { resolve } from "node:path";
|
|
5
5
|
import { createServer } from "vite";
|
|
6
|
-
import { fileURLToPath } from "node:url";
|
|
7
6
|
//#region src/commands/editor.ts
|
|
8
|
-
function findEditorRoot(
|
|
9
|
-
|
|
10
|
-
|
|
7
|
+
function findEditorRoot(pkgDir) {
|
|
8
|
+
const bundled = resolve(pkgDir, "editor");
|
|
9
|
+
if (existsSync(resolve(bundled, "vite.config.ts"))) return bundled;
|
|
10
|
+
let dir = pkgDir;
|
|
11
11
|
for (let i = 0; i < 10; i++) {
|
|
12
|
-
|
|
12
|
+
const candidate = resolve(dir, "apps", "editor");
|
|
13
|
+
if (existsSync(resolve(candidate, "vite.config.ts"))) return candidate;
|
|
13
14
|
dir = resolve(dir, "..");
|
|
14
15
|
}
|
|
15
|
-
throw new Error("Could not find
|
|
16
|
+
throw new Error("Could not find editor relative to CLI package");
|
|
16
17
|
}
|
|
17
18
|
var editor_default = defineCommand({
|
|
18
19
|
meta: {
|
|
@@ -40,7 +41,7 @@ var editor_default = defineCommand({
|
|
|
40
41
|
if (config.globalCss) process.env.PLANNAR_GLOBAL_CSS = resolve(cwd, config.globalCss);
|
|
41
42
|
if (config.cssFilePath) process.env.PLANNAR_CSS_FILE_PATH = resolve(cwd, config.cssFilePath);
|
|
42
43
|
if (config.meta) process.env.PLANNAR_META = JSON.stringify(config.meta);
|
|
43
|
-
const editorRoot = findEditorRoot(
|
|
44
|
+
const editorRoot = findEditorRoot(import.meta.dirname);
|
|
44
45
|
const baseServerConfig = {
|
|
45
46
|
configFile: resolve(editorRoot, "vite.config.ts"),
|
|
46
47
|
root: editorRoot,
|
|
@@ -0,0 +1,653 @@
|
|
|
1
|
+
import { n as resolveConfig } from "./config-C_Uf66xX.mjs";
|
|
2
|
+
import { defineCommand } from "citty";
|
|
3
|
+
import { copyFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
4
|
+
import { basename, dirname, join, relative, resolve } from "node:path";
|
|
5
|
+
import { build } from "vite";
|
|
6
|
+
import { tmpdir } from "node:os";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
import react from "@vitejs/plugin-react";
|
|
9
|
+
import tailwindcss from "@tailwindcss/vite";
|
|
10
|
+
import { readFile } from "node:fs/promises";
|
|
11
|
+
import { compile } from "@mdx-js/mdx";
|
|
12
|
+
import remarkGfm from "remark-gfm";
|
|
13
|
+
import rehypePrettyCode from "rehype-pretty-code";
|
|
14
|
+
import rehypeAutolinkHeadings from "rehype-autolink-headings";
|
|
15
|
+
import { Parser } from "acorn";
|
|
16
|
+
import acornJsx from "acorn-jsx";
|
|
17
|
+
//#region ../core/dist/index.mjs
|
|
18
|
+
/**
|
|
19
|
+
* Built-in HTML element bindings.
|
|
20
|
+
* Keys are element name, or `element:type` for inputs with a type attribute.
|
|
21
|
+
*/
|
|
22
|
+
const htmlBindings = {
|
|
23
|
+
input: {
|
|
24
|
+
valueProp: "value",
|
|
25
|
+
changeProp: "onChange",
|
|
26
|
+
extract: "e.target.value"
|
|
27
|
+
},
|
|
28
|
+
"input:checkbox": {
|
|
29
|
+
valueProp: "checked",
|
|
30
|
+
changeProp: "onChange",
|
|
31
|
+
extract: "e.target.checked"
|
|
32
|
+
},
|
|
33
|
+
"input:number": {
|
|
34
|
+
valueProp: "value",
|
|
35
|
+
changeProp: "onChange",
|
|
36
|
+
extract: "e.target.valueAsNumber"
|
|
37
|
+
},
|
|
38
|
+
textarea: {
|
|
39
|
+
valueProp: "value",
|
|
40
|
+
changeProp: "onChange",
|
|
41
|
+
extract: "e.target.value"
|
|
42
|
+
},
|
|
43
|
+
select: {
|
|
44
|
+
valueProp: "value",
|
|
45
|
+
changeProp: "onChange",
|
|
46
|
+
extract: "e.target.value"
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const _parser = Parser.extend(acornJsx());
|
|
50
|
+
function parseEsm(code) {
|
|
51
|
+
return _parser.parse(code, {
|
|
52
|
+
ecmaVersion: "latest",
|
|
53
|
+
sourceType: "module",
|
|
54
|
+
locations: true
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
const remarkStateBind = (options) => {
|
|
58
|
+
const bindings = {
|
|
59
|
+
...htmlBindings,
|
|
60
|
+
...options?.bindings
|
|
61
|
+
};
|
|
62
|
+
const state = {
|
|
63
|
+
counter: 0,
|
|
64
|
+
importAdded: false
|
|
65
|
+
};
|
|
66
|
+
return (tree) => {
|
|
67
|
+
state.counter = 0;
|
|
68
|
+
state.importAdded = false;
|
|
69
|
+
visitAndTransform(tree, tree, state, bindings);
|
|
70
|
+
if (state.importAdded) tree.children.unshift({
|
|
71
|
+
type: "mdxjsEsm",
|
|
72
|
+
value: `import { useState } from "react"`,
|
|
73
|
+
data: { estree: parseEsm(`import { useState } from "react"`) }
|
|
74
|
+
});
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
function visitAndTransform(node, root, state, bindings) {
|
|
78
|
+
if (!node.children) return;
|
|
79
|
+
for (let i = node.children.length - 1; i >= 0; i--) {
|
|
80
|
+
const child = node.children[i];
|
|
81
|
+
if (child.children) visitAndTransform(child, root, state, bindings);
|
|
82
|
+
}
|
|
83
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
84
|
+
const child = node.children[i];
|
|
85
|
+
if (child.type === "mdxJsxFlowElement" && child.name === "Playground") {
|
|
86
|
+
const transformed = transformPlayground(child, node.children, i, root, state, bindings);
|
|
87
|
+
i += transformed.indexOffset;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
function transformPlayground(playground, siblings, index, root, state, bindings) {
|
|
92
|
+
const binds = collectBinds(playground, playground);
|
|
93
|
+
const names = binds.map((b) => b.name);
|
|
94
|
+
const dupes = names.filter((n, i) => names.indexOf(n) !== i);
|
|
95
|
+
if (dupes.length > 0) throw new Error(`Duplicate bind names in <Playground>: ${[...new Set(dupes)].join(", ")}`);
|
|
96
|
+
applyBindings(playground, binds, bindings);
|
|
97
|
+
const componentName = `_PlannarPlayground_${state.counter++}`;
|
|
98
|
+
const childrenJsx = (playground.children || []).map(serializeNode).join("\n");
|
|
99
|
+
const stateDecls = binds.map((b) => `const [${b.name}, set${capitalize(b.name)}] = useState(${b.initialValue})`).join("\n ");
|
|
100
|
+
const esmCode = `function ${componentName}() {\n ${stateDecls ? stateDecls + "\n " : ""}return (<>\n${indent(childrenJsx)}\n</>)\n}`;
|
|
101
|
+
if (stateDecls && !state.importAdded) state.importAdded = true;
|
|
102
|
+
const esmNode = {
|
|
103
|
+
type: "mdxjsEsm",
|
|
104
|
+
value: esmCode,
|
|
105
|
+
data: { estree: parseEsm(esmCode) }
|
|
106
|
+
};
|
|
107
|
+
siblings[index] = {
|
|
108
|
+
type: "mdxJsxFlowElement",
|
|
109
|
+
name: componentName,
|
|
110
|
+
attributes: [],
|
|
111
|
+
children: []
|
|
112
|
+
};
|
|
113
|
+
root.children.unshift(esmNode);
|
|
114
|
+
return { indexOffset: 0 };
|
|
115
|
+
}
|
|
116
|
+
function collectBinds(node, owningPlayground) {
|
|
117
|
+
const binds = [];
|
|
118
|
+
if (node !== owningPlayground && node.type === "mdxJsxFlowElement" && node.name === "Playground") return binds;
|
|
119
|
+
if (Array.isArray(node.attributes)) {
|
|
120
|
+
for (const attr of node.attributes) if (attr.type === "mdxJsxAttribute" && attr.name === "bind") {
|
|
121
|
+
const attrValue = attr.value;
|
|
122
|
+
if (typeof attrValue === "object" && attrValue !== null && attrValue.type === "mdxJsxAttributeValueExpression") {
|
|
123
|
+
const expr = String(attrValue.value ?? "");
|
|
124
|
+
const colonIdx = expr.indexOf(":");
|
|
125
|
+
if (colonIdx === -1) binds.push({
|
|
126
|
+
name: expr,
|
|
127
|
+
initialValue: "undefined"
|
|
128
|
+
});
|
|
129
|
+
else {
|
|
130
|
+
const name = expr.slice(0, colonIdx);
|
|
131
|
+
const initial = expr.slice(colonIdx + 1) || "undefined";
|
|
132
|
+
binds.push({
|
|
133
|
+
name,
|
|
134
|
+
initialValue: initial
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
const raw = String(attrValue ?? "");
|
|
139
|
+
const colonIdx = raw.indexOf(":");
|
|
140
|
+
if (colonIdx === -1) binds.push({
|
|
141
|
+
name: raw,
|
|
142
|
+
initialValue: "undefined"
|
|
143
|
+
});
|
|
144
|
+
else {
|
|
145
|
+
const name = raw.slice(0, colonIdx);
|
|
146
|
+
const initial = raw.slice(colonIdx + 1) || "undefined";
|
|
147
|
+
binds.push({
|
|
148
|
+
name,
|
|
149
|
+
initialValue: initial
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (Array.isArray(node.children)) for (const child of node.children) binds.push(...collectBinds(child, owningPlayground));
|
|
156
|
+
return binds;
|
|
157
|
+
}
|
|
158
|
+
function applyBindings(node, binds, bindings) {
|
|
159
|
+
const bindNameSet = new Set(binds.map((b) => b.name));
|
|
160
|
+
if (Array.isArray(node.attributes)) {
|
|
161
|
+
const attrs = node.attributes;
|
|
162
|
+
for (let i = attrs.length - 1; i >= 0; i--) {
|
|
163
|
+
const attr = attrs[i];
|
|
164
|
+
if (attr.type === "mdxJsxAttribute" && attr.name === "bind") {
|
|
165
|
+
const parsed = parseBindValue(attr);
|
|
166
|
+
if (parsed && bindNameSet.has(parsed.name)) {
|
|
167
|
+
const elName = String(node.name || "").toLowerCase();
|
|
168
|
+
const typeAttr = attrs.find((a) => a.type === "mdxJsxAttribute" && a.name === "type");
|
|
169
|
+
const replacement = bindingAttrs(elName, typeAttr ? String(typeAttr.value ?? "text") : "", parsed.name, bindings);
|
|
170
|
+
attrs.splice(i, 1, ...replacement);
|
|
171
|
+
} else attrs.splice(i, 1);
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
if (Array.isArray(node.children)) for (const child of node.children) applyBindings(child, binds, bindings);
|
|
176
|
+
}
|
|
177
|
+
function parseBindValue(attr) {
|
|
178
|
+
const raw = parseAttrValue(attr);
|
|
179
|
+
if (!raw) return null;
|
|
180
|
+
const colonIdx = raw.indexOf(":");
|
|
181
|
+
if (colonIdx === -1) return {
|
|
182
|
+
name: raw,
|
|
183
|
+
initialValue: "undefined"
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
name: raw.slice(0, colonIdx),
|
|
187
|
+
initialValue: raw.slice(colonIdx + 1) || "undefined"
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
function parseAttrValue(attr) {
|
|
191
|
+
const v = attr.value;
|
|
192
|
+
if (typeof v === "object" && v !== null && v.type === "mdxJsxAttributeValueExpression") return String(v.value ?? "");
|
|
193
|
+
if (typeof v === "string") return v;
|
|
194
|
+
if (v == null) return "";
|
|
195
|
+
return null;
|
|
196
|
+
}
|
|
197
|
+
function bindingAttrs(elName, inputType, name, bindings) {
|
|
198
|
+
const meta = bindings[inputType ? `${elName}:${inputType}` : elName] ?? bindings[elName];
|
|
199
|
+
if (!meta) return [];
|
|
200
|
+
const setter = `set${capitalize(name)}`;
|
|
201
|
+
const valueExpr = meta.inject ? meta.inject.replace(/\bv\b/g, name) : name;
|
|
202
|
+
return [exprAttr(meta.valueProp, valueExpr), exprAttr(meta.changeProp, `(e) => ${setter}(${meta.extract})`)];
|
|
203
|
+
}
|
|
204
|
+
function exprAttr(name, expr) {
|
|
205
|
+
return {
|
|
206
|
+
type: "mdxJsxAttribute",
|
|
207
|
+
name,
|
|
208
|
+
value: {
|
|
209
|
+
type: "mdxJsxAttributeValueExpression",
|
|
210
|
+
value: expr,
|
|
211
|
+
data: { estree: _parser.parse(expr, {
|
|
212
|
+
ecmaVersion: "latest",
|
|
213
|
+
sourceType: "module",
|
|
214
|
+
locations: true
|
|
215
|
+
}) }
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
function serializeNode(node) {
|
|
220
|
+
switch (node.type) {
|
|
221
|
+
case "text": return escapeJsxText(String(node.value ?? ""));
|
|
222
|
+
case "inlineCode": return `<code>${escapeJsxText(String(node.value ?? ""))}</code>`;
|
|
223
|
+
case "strong": return `<strong>${(node.children || []).map(serializeNode).join("")}</strong>`;
|
|
224
|
+
case "emphasis": return `<em>${(node.children || []).map(serializeNode).join("")}</em>`;
|
|
225
|
+
case "delete": return `<del>${(node.children || []).map(serializeNode).join("")}</del>`;
|
|
226
|
+
case "link": return `<a href="${node.url}">${(node.children || []).map(serializeNode).join("")}</a>`;
|
|
227
|
+
case "image": return `<img src="${node.url}" alt="${node.alt || ""}" />`;
|
|
228
|
+
case "break": return "<br />";
|
|
229
|
+
case "thematicBreak": return "<hr />";
|
|
230
|
+
case "mdxTextExpression":
|
|
231
|
+
case "mdxFlowExpression": return `{${node.value}}`;
|
|
232
|
+
case "mdxJsxTextElement":
|
|
233
|
+
case "mdxJsxFlowElement": return serializeJsxElement(node);
|
|
234
|
+
case "paragraph": return `<p>${(node.children || []).map(serializeNode).join("")}</p>`;
|
|
235
|
+
case "heading": return `<h${node.depth}>${(node.children || []).map(serializeNode).join("")}</h${node.depth}>`;
|
|
236
|
+
case "blockquote": return `<blockquote>${(node.children || []).map(serializeNode).join("")}</blockquote>`;
|
|
237
|
+
case "list": {
|
|
238
|
+
const tag = node.ordered ? "ol" : "ul";
|
|
239
|
+
return `<${tag}>${(node.children || []).map(serializeNode).join("")}</${tag}>`;
|
|
240
|
+
}
|
|
241
|
+
case "listItem": return `<li>${(node.children || []).map(serializeNode).join("")}</li>`;
|
|
242
|
+
case "code": return `<pre><code>${escapeJsxText(String(node.value ?? ""))}</code></pre>`;
|
|
243
|
+
default:
|
|
244
|
+
if (Array.isArray(node.children)) return node.children.map(serializeNode).join("");
|
|
245
|
+
return "";
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
function serializeJsxElement(node) {
|
|
249
|
+
const attrs = (node.attributes || []).map(serializeAttribute).filter(Boolean).join(" ");
|
|
250
|
+
const openTag = `<${node.name}${attrs ? " " + attrs : ""}>`;
|
|
251
|
+
const body = (node.children || []).map(serializeNode).join("");
|
|
252
|
+
const closeTag = `</${node.name}>`;
|
|
253
|
+
return openTag + body + closeTag;
|
|
254
|
+
}
|
|
255
|
+
function serializeAttribute(attr) {
|
|
256
|
+
if (attr.type === "mdxJsxExpressionAttribute") return `{...${attr.value}}`;
|
|
257
|
+
if (attr.type === "mdxJsxAttribute") {
|
|
258
|
+
if (typeof attr.value === "object" && attr.value !== null && attr.value.type === "mdxJsxAttributeValueExpression") return `${attr.name}={${attr.value.value}}`;
|
|
259
|
+
const strVal = attr.value == null ? "" : String(attr.value);
|
|
260
|
+
return `${attr.name}=${JSON.stringify(strVal)}`;
|
|
261
|
+
}
|
|
262
|
+
return "";
|
|
263
|
+
}
|
|
264
|
+
function escapeJsxText(text) {
|
|
265
|
+
return text.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/\{/g, "{").replace(/\}/g, "}");
|
|
266
|
+
}
|
|
267
|
+
function capitalize(s) {
|
|
268
|
+
return s.charAt(0).toUpperCase() + s.slice(1);
|
|
269
|
+
}
|
|
270
|
+
function indent(text) {
|
|
271
|
+
return text.split("\n").map((line) => " " + line).join("\n");
|
|
272
|
+
}
|
|
273
|
+
async function generateMdx(filepath, options = {}) {
|
|
274
|
+
const { content, bindings, ...mdxOptions } = options;
|
|
275
|
+
const absolutePath = resolve(filepath);
|
|
276
|
+
const result = await compile({
|
|
277
|
+
value: content ?? await readFile(absolutePath, "utf-8"),
|
|
278
|
+
path: absolutePath
|
|
279
|
+
}, {
|
|
280
|
+
development: false,
|
|
281
|
+
...mdxOptions,
|
|
282
|
+
remarkPlugins: [
|
|
283
|
+
[remarkStateBind, { bindings }],
|
|
284
|
+
remarkGfm,
|
|
285
|
+
...mdxOptions.remarkPlugins ?? []
|
|
286
|
+
],
|
|
287
|
+
rehypePlugins: [
|
|
288
|
+
rehypePrettyCode,
|
|
289
|
+
rehypeAutolinkHeadings,
|
|
290
|
+
...mdxOptions.rehypePlugins ?? []
|
|
291
|
+
]
|
|
292
|
+
});
|
|
293
|
+
return String(result.value);
|
|
294
|
+
}
|
|
295
|
+
//#endregion
|
|
296
|
+
//#region ../registry-metadata/dist/index.mjs
|
|
297
|
+
/**
|
|
298
|
+
* shadcn/ui component bindings for stateful two-way binding.
|
|
299
|
+
*
|
|
300
|
+
* Each key is the shadcn registry component name (lowercase), matching the
|
|
301
|
+
* name used in `npx shadcn add <name>`.
|
|
302
|
+
*
|
|
303
|
+
* Elements with a `type` attribute are looked up as `name:type` first,
|
|
304
|
+
* falling back to `name`. This mirrors the HTML binding lookup.
|
|
305
|
+
*/
|
|
306
|
+
const shadcnBindings = {
|
|
307
|
+
input: {
|
|
308
|
+
valueProp: "value",
|
|
309
|
+
changeProp: "onChange",
|
|
310
|
+
extract: "e.target.value"
|
|
311
|
+
},
|
|
312
|
+
"input:checkbox": {
|
|
313
|
+
valueProp: "checked",
|
|
314
|
+
changeProp: "onChange",
|
|
315
|
+
extract: "e.target.checked"
|
|
316
|
+
},
|
|
317
|
+
"input:number": {
|
|
318
|
+
valueProp: "value",
|
|
319
|
+
changeProp: "onChange",
|
|
320
|
+
extract: "e.target.valueAsNumber"
|
|
321
|
+
},
|
|
322
|
+
textarea: {
|
|
323
|
+
valueProp: "value",
|
|
324
|
+
changeProp: "onChange",
|
|
325
|
+
extract: "e.target.value"
|
|
326
|
+
},
|
|
327
|
+
"native-select": {
|
|
328
|
+
valueProp: "value",
|
|
329
|
+
changeProp: "onChange",
|
|
330
|
+
extract: "e.target.value"
|
|
331
|
+
},
|
|
332
|
+
checkbox: {
|
|
333
|
+
valueProp: "checked",
|
|
334
|
+
changeProp: "onCheckedChange",
|
|
335
|
+
extract: "e"
|
|
336
|
+
},
|
|
337
|
+
switch: {
|
|
338
|
+
valueProp: "checked",
|
|
339
|
+
changeProp: "onCheckedChange",
|
|
340
|
+
extract: "e"
|
|
341
|
+
},
|
|
342
|
+
toggle: {
|
|
343
|
+
valueProp: "pressed",
|
|
344
|
+
changeProp: "onPressedChange",
|
|
345
|
+
extract: "e"
|
|
346
|
+
},
|
|
347
|
+
slider: {
|
|
348
|
+
valueProp: "value",
|
|
349
|
+
changeProp: "onValueChange",
|
|
350
|
+
extract: "e[0]",
|
|
351
|
+
inject: "[v]"
|
|
352
|
+
},
|
|
353
|
+
select: {
|
|
354
|
+
valueProp: "value",
|
|
355
|
+
changeProp: "onValueChange",
|
|
356
|
+
extract: "e"
|
|
357
|
+
},
|
|
358
|
+
"radio-group": {
|
|
359
|
+
valueProp: "value",
|
|
360
|
+
changeProp: "onValueChange",
|
|
361
|
+
extract: "e"
|
|
362
|
+
},
|
|
363
|
+
tabs: {
|
|
364
|
+
valueProp: "value",
|
|
365
|
+
changeProp: "onValueChange",
|
|
366
|
+
extract: "e"
|
|
367
|
+
},
|
|
368
|
+
accordion: {
|
|
369
|
+
valueProp: "value",
|
|
370
|
+
changeProp: "onValueChange",
|
|
371
|
+
extract: "e"
|
|
372
|
+
},
|
|
373
|
+
dialog: {
|
|
374
|
+
valueProp: "open",
|
|
375
|
+
changeProp: "onOpenChange",
|
|
376
|
+
extract: "e"
|
|
377
|
+
},
|
|
378
|
+
"alert-dialog": {
|
|
379
|
+
valueProp: "open",
|
|
380
|
+
changeProp: "onOpenChange",
|
|
381
|
+
extract: "e"
|
|
382
|
+
},
|
|
383
|
+
sheet: {
|
|
384
|
+
valueProp: "open",
|
|
385
|
+
changeProp: "onOpenChange",
|
|
386
|
+
extract: "e"
|
|
387
|
+
},
|
|
388
|
+
drawer: {
|
|
389
|
+
valueProp: "open",
|
|
390
|
+
changeProp: "onOpenChange",
|
|
391
|
+
extract: "e"
|
|
392
|
+
},
|
|
393
|
+
popover: {
|
|
394
|
+
valueProp: "open",
|
|
395
|
+
changeProp: "onOpenChange",
|
|
396
|
+
extract: "e"
|
|
397
|
+
},
|
|
398
|
+
"hover-card": {
|
|
399
|
+
valueProp: "open",
|
|
400
|
+
changeProp: "onOpenChange",
|
|
401
|
+
extract: "e"
|
|
402
|
+
},
|
|
403
|
+
tooltip: {
|
|
404
|
+
valueProp: "open",
|
|
405
|
+
changeProp: "onOpenChange",
|
|
406
|
+
extract: "e"
|
|
407
|
+
},
|
|
408
|
+
"dropdown-menu": {
|
|
409
|
+
valueProp: "open",
|
|
410
|
+
changeProp: "onOpenChange",
|
|
411
|
+
extract: "e"
|
|
412
|
+
},
|
|
413
|
+
"context-menu": {
|
|
414
|
+
valueProp: "open",
|
|
415
|
+
changeProp: "onOpenChange",
|
|
416
|
+
extract: "e"
|
|
417
|
+
},
|
|
418
|
+
collapsible: {
|
|
419
|
+
valueProp: "open",
|
|
420
|
+
changeProp: "onOpenChange",
|
|
421
|
+
extract: "e"
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
//#endregion
|
|
425
|
+
//#region ../export/dist/index.mjs
|
|
426
|
+
const pkgDir = dirname(fileURLToPath(import.meta.url));
|
|
427
|
+
async function exportPlan(planName, options = {}) {
|
|
428
|
+
const cwd = options.cwd ?? process.cwd();
|
|
429
|
+
const plannarFolder = options.plannarFolder ?? ".plannar";
|
|
430
|
+
const exportsFolder = options.exportsFolder ?? `${plannarFolder}/exports`;
|
|
431
|
+
const compiled = await generateMdx(join(cwd, plannarFolder, "plans", `${planName}.mdx`), { bindings: {
|
|
432
|
+
...shadcnBindings,
|
|
433
|
+
...normalizeMeta(options.meta)
|
|
434
|
+
} });
|
|
435
|
+
const tmpDir = mkdtempSync(join(tmpdir(), "plannar-export-"));
|
|
436
|
+
try {
|
|
437
|
+
const html = await buildExportHtml(compiled, tmpDir, cwd, plannarFolder, options);
|
|
438
|
+
const outDir = resolve(cwd, exportsFolder);
|
|
439
|
+
mkdirSync(outDir, { recursive: true });
|
|
440
|
+
const outPath = join(outDir, `${planName}.html`);
|
|
441
|
+
writeFileSync(outPath, html, "utf-8");
|
|
442
|
+
return outPath;
|
|
443
|
+
} finally {
|
|
444
|
+
rmSync(tmpDir, {
|
|
445
|
+
recursive: true,
|
|
446
|
+
force: true
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
function normalizeMeta(meta) {
|
|
451
|
+
if (!meta || typeof meta !== "object" || Array.isArray(meta)) return {};
|
|
452
|
+
return meta;
|
|
453
|
+
}
|
|
454
|
+
function deepMerge(target, source) {
|
|
455
|
+
const result = { ...target };
|
|
456
|
+
for (const key of Object.keys(source)) {
|
|
457
|
+
const sv = source[key];
|
|
458
|
+
const tv = result[key];
|
|
459
|
+
if (sv && typeof sv === "object" && !Array.isArray(sv) && tv && typeof tv === "object" && !Array.isArray(tv)) result[key] = deepMerge(tv, sv);
|
|
460
|
+
else result[key] = sv;
|
|
461
|
+
}
|
|
462
|
+
return result;
|
|
463
|
+
}
|
|
464
|
+
function resolveExistingCssImport(cwd, tmpDir, cssPath) {
|
|
465
|
+
if (!cssPath) return null;
|
|
466
|
+
const cssAbs = resolve(cwd, cssPath);
|
|
467
|
+
if (!existsSync(cssAbs)) return null;
|
|
468
|
+
const destName = `plannar-${basename(cssAbs)}`;
|
|
469
|
+
copyFileSync(cssAbs, join(tmpDir, destName));
|
|
470
|
+
return `./${destName}`;
|
|
471
|
+
}
|
|
472
|
+
function injectBrowserProcessShim(html) {
|
|
473
|
+
if (!/(?<!window\.)process\.env\b/.test(html)) return html;
|
|
474
|
+
const shim = `<script>window.process ??= {}; window.process.env ??= {}; window.process.env.NODE_ENV ??= "production";<\/script>`;
|
|
475
|
+
return html.includes("</head>") ? html.replace("</head>", `${shim}</head>`) : `${shim}${html}`;
|
|
476
|
+
}
|
|
477
|
+
async function buildExportHtml(compiled, tmpDir, cwd, plannarFolder, options) {
|
|
478
|
+
const plannarDir = join(cwd, plannarFolder);
|
|
479
|
+
const sourcePath = relative(tmpDir, plannarDir).replaceAll("\\", "/");
|
|
480
|
+
const nodeModulesSource = findNearestNodeModules(pkgDir) ?? findNearestNodeModules(cwd) ?? findNearestNodeModules(plannarDir) ?? findNearestNodeModules(tmpDir);
|
|
481
|
+
if (nodeModulesSource) symlinkSync(nodeModulesSource, join(tmpDir, "node_modules"), "dir");
|
|
482
|
+
const planModule = compiled.replace(/export\s+default\s+function\s+MDXContent/g, "function Plan").replace(/export\s+{\s*MDXContent\s+as\s+default\s*}/g, "");
|
|
483
|
+
writeFileSync(join(tmpDir, "plan-content.tsx"), `${planModule}\nexport { Plan };\n`, "utf-8");
|
|
484
|
+
writeFileSync(join(tmpDir, "plan.tsx"), `import { Plan } from "./plan-content";
|
|
485
|
+
import { createRoot } from "react-dom/client";
|
|
486
|
+
import "./index.css";
|
|
487
|
+
|
|
488
|
+
const root = document.getElementById("root");
|
|
489
|
+
if (root) {
|
|
490
|
+
createRoot(root).render(
|
|
491
|
+
<div className="mdx-content">
|
|
492
|
+
<Plan />
|
|
493
|
+
</div>
|
|
494
|
+
);
|
|
495
|
+
}`, "utf-8");
|
|
496
|
+
let cssImports = "";
|
|
497
|
+
const globalCssRel = resolveExistingCssImport(cwd, tmpDir, options.globalCss);
|
|
498
|
+
if (globalCssRel) cssImports += `@import "${globalCssRel}";\n`;
|
|
499
|
+
const cssFilePathRel = resolveExistingCssImport(cwd, tmpDir, options.cssFilePath);
|
|
500
|
+
if (cssFilePathRel) cssImports += `@import "${cssFilePathRel}";\n`;
|
|
501
|
+
const coreStylesDir = join(pkgDir, "core-styles");
|
|
502
|
+
const mdxCssPath = join(coreStylesDir, "mdx.css").replaceAll("\\", "/");
|
|
503
|
+
const themeCssPath = join(coreStylesDir, "theme.css").replaceAll("\\", "/");
|
|
504
|
+
writeFileSync(join(tmpDir, "index.css"), `@import "tailwindcss";
|
|
505
|
+
@import "tw-animate-css";
|
|
506
|
+
@import "${mdxCssPath}";
|
|
507
|
+
@import "${themeCssPath}";
|
|
508
|
+
${cssImports}@source "${sourcePath}";
|
|
509
|
+
|
|
510
|
+
@custom-variant dark (&:is(.dark *));
|
|
511
|
+
|
|
512
|
+
@theme inline {
|
|
513
|
+
--color-background: var(--background);
|
|
514
|
+
--color-foreground: var(--foreground);
|
|
515
|
+
--color-card: var(--card);
|
|
516
|
+
--color-card-foreground: var(--card-foreground);
|
|
517
|
+
--color-popover: var(--popover);
|
|
518
|
+
--color-popover-foreground: var(--popover-foreground);
|
|
519
|
+
--color-primary: var(--primary);
|
|
520
|
+
--color-primary-foreground: var(--primary-foreground);
|
|
521
|
+
--color-secondary: var(--secondary);
|
|
522
|
+
--color-secondary-foreground: var(--secondary-foreground);
|
|
523
|
+
--color-muted: var(--muted);
|
|
524
|
+
--color-muted-foreground: var(--muted-foreground);
|
|
525
|
+
--color-accent: var(--accent);
|
|
526
|
+
--color-accent-foreground: var(--accent-foreground);
|
|
527
|
+
--color-destructive: var(--destructive);
|
|
528
|
+
--color-destructive-foreground: var(--destructive-foreground);
|
|
529
|
+
--color-border: var(--border);
|
|
530
|
+
--color-input: var(--input);
|
|
531
|
+
--color-ring: var(--ring);
|
|
532
|
+
--color-chart-1: var(--chart-1);
|
|
533
|
+
--color-chart-2: var(--chart-2);
|
|
534
|
+
--color-chart-3: var(--chart-3);
|
|
535
|
+
--color-chart-4: var(--chart-4);
|
|
536
|
+
--color-chart-5: var(--chart-5);
|
|
537
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
538
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
539
|
+
--radius-lg: var(--radius);
|
|
540
|
+
--radius-xl: calc(var(--radius) + 4px);
|
|
541
|
+
}`, "utf-8");
|
|
542
|
+
const outDir = join(tmpDir, "dist");
|
|
543
|
+
const baseBuildConfig = {
|
|
544
|
+
root: tmpDir,
|
|
545
|
+
define: { "process.env.NODE_ENV": JSON.stringify("production") },
|
|
546
|
+
build: {
|
|
547
|
+
outDir,
|
|
548
|
+
minify: false,
|
|
549
|
+
cssCodeSplit: false,
|
|
550
|
+
lib: {
|
|
551
|
+
entry: join(tmpDir, "plan.tsx"),
|
|
552
|
+
name: "PlannarExport",
|
|
553
|
+
formats: ["es"],
|
|
554
|
+
fileName: () => "plan.js",
|
|
555
|
+
cssFileName: "plan"
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
plugins: [
|
|
559
|
+
tailwindcss(),
|
|
560
|
+
react(),
|
|
561
|
+
inlineAssetsPlugin(outDir)
|
|
562
|
+
],
|
|
563
|
+
resolve: { alias: { "@": plannarDir } },
|
|
564
|
+
logLevel: "warn"
|
|
565
|
+
};
|
|
566
|
+
await build(options.viteConfig ? deepMerge(baseBuildConfig, options.viteConfig) : baseBuildConfig);
|
|
567
|
+
return injectBrowserProcessShim(readFileSync(join(outDir, "index.html"), "utf-8"));
|
|
568
|
+
}
|
|
569
|
+
function findNearestNodeModules(startDir) {
|
|
570
|
+
let dir = resolve(startDir);
|
|
571
|
+
for (let i = 0; i < 10; i++) {
|
|
572
|
+
const candidate = join(dir, "node_modules");
|
|
573
|
+
if (existsSync(candidate)) return candidate;
|
|
574
|
+
const parent = resolve(dir, "..");
|
|
575
|
+
if (parent === dir) break;
|
|
576
|
+
dir = parent;
|
|
577
|
+
}
|
|
578
|
+
return null;
|
|
579
|
+
}
|
|
580
|
+
function inlineAssetsPlugin(outDir) {
|
|
581
|
+
let css = "";
|
|
582
|
+
let js = "";
|
|
583
|
+
return {
|
|
584
|
+
name: "plannar-inline-assets",
|
|
585
|
+
enforce: "post",
|
|
586
|
+
apply: "build",
|
|
587
|
+
generateBundle(_opts, bundle) {
|
|
588
|
+
for (const [, chunk] of Object.entries(bundle)) {
|
|
589
|
+
const ch = chunk;
|
|
590
|
+
if (ch.type === "asset" && typeof ch.source === "string") {
|
|
591
|
+
if (ch.fileName.endsWith(".css")) css += ch.source;
|
|
592
|
+
}
|
|
593
|
+
if (ch.type === "chunk") js += chunk.code;
|
|
594
|
+
}
|
|
595
|
+
},
|
|
596
|
+
closeBundle() {
|
|
597
|
+
try {
|
|
598
|
+
const safeJs = js.replace(/<\//g, "<\\/");
|
|
599
|
+
const html = `<!DOCTYPE html>
|
|
600
|
+
<html lang="en">
|
|
601
|
+
<head>
|
|
602
|
+
<meta charset="UTF-8">
|
|
603
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
604
|
+
<script>
|
|
605
|
+
(function(){var e=localStorage.getItem("plannar-theme");if(e==="dark"||(!e&&window.matchMedia("(prefers-color-scheme: dark)").matches)){document.documentElement.classList.add("dark")}})();
|
|
606
|
+
<\/script>
|
|
607
|
+
<style>
|
|
608
|
+
${css}
|
|
609
|
+
</style>
|
|
610
|
+
</head>
|
|
611
|
+
<body>
|
|
612
|
+
<div id="root"></div>
|
|
613
|
+
<script>
|
|
614
|
+
${safeJs}
|
|
615
|
+
<\/script>
|
|
616
|
+
</body>
|
|
617
|
+
</html>`;
|
|
618
|
+
writeFileSync(join(outDir, "index.html"), html, "utf-8");
|
|
619
|
+
const entries = readdirSync(outDir);
|
|
620
|
+
for (const entry of entries) if (entry !== "index.html") rmSync(join(outDir, entry), { force: true });
|
|
621
|
+
} catch {}
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
625
|
+
//#endregion
|
|
626
|
+
//#region src/commands/export.ts
|
|
627
|
+
var export_default = defineCommand({
|
|
628
|
+
meta: {
|
|
629
|
+
name: "export",
|
|
630
|
+
description: "Export a plan to a self-contained HTML file"
|
|
631
|
+
},
|
|
632
|
+
args: { plan: {
|
|
633
|
+
type: "positional",
|
|
634
|
+
description: "Plan name (without .mdx extension)",
|
|
635
|
+
required: true
|
|
636
|
+
} },
|
|
637
|
+
async run({ args }) {
|
|
638
|
+
const cwd = process.cwd();
|
|
639
|
+
const config = await resolveConfig(cwd);
|
|
640
|
+
const outPath = await exportPlan(args.plan, {
|
|
641
|
+
cwd,
|
|
642
|
+
plannarFolder: config.plannarFolder,
|
|
643
|
+
exportsFolder: config.exportsFolder,
|
|
644
|
+
globalCss: config.globalCss,
|
|
645
|
+
cssFilePath: config.cssFilePath,
|
|
646
|
+
meta: config.meta,
|
|
647
|
+
viteConfig: config.viteConfig?.exports
|
|
648
|
+
});
|
|
649
|
+
console.log(`✓ Exported to ${outPath}`);
|
|
650
|
+
}
|
|
651
|
+
});
|
|
652
|
+
//#endregion
|
|
653
|
+
export { export_default as default };
|