ts

    TypeScript <-> MoonBit bridge generator

    typescript
    javascript
    moonbit
    bridge
    ffi
    d.ts
    Download zip
    Author
    Version
    0.6.0
    License
    Apache-2.0
    Last updated
    14 days ago
    Downloads
    1K

    Dependencies

    #mizchi/ts

    Status: Experimental

    MoonBit と TypeScript の間で bridge package を生成する toolchain です。TypeScript の 型定義から MoonBit bridge を生成し、MoonBit package から JavaScript runtime と .d.ts を持つ npm package を生成します。生成物は再生成可能な output として扱います。

    #Quick start

    TypeScript dependencies を MoonBit から使う場合:

    moon install mizchi/ts/cmd/mtsc mtsc bridge generate

    MoonBit package を npm package にする場合:

    moon install mizchi/ts/cmd/mtsc cd my-moonbit-library mtsc pkg npm cd npm && npm publish --access public

    公開済み @mizchi/ts の type checker は global install なしで実行できます。

    npx --package=@mizchi/ts mtsc --help

    Hono を MoonBit から使う完全な手順は Quick start を参照してください。

    #Requirements

    • MoonBit toolchain(moon が $PATH にあること)
    • Node.js 24+
    • pnpm(verification scripts 用)
    • 任意: just

    #Install

    moon install mizchi/ts/cmd/mtsc

    install 後は ~/.moon/bin/ を $PATH に追加します。source checkout から実行する 場合は moon run src/cmd/mtsc -- ... を使います。

    #Tools

    binary は mtsc 1 つだけです。TypeScript の compile は default の位置引数で、 それ以外の機能は verb で分かれています。

    Command概要詳細
    mtsc [files...]TypeScript / TSX を型検査して JavaScript に変換docs/mtsc.md
    mtsc bridgeTypeScript declaration / npm package を MoonBit bridge に変換docs/ts2mbt.md
    mtsc pkgMoonBit package を TypeScript declaration / npm package に変換docs/mbt2ts.md
    mtsc check1 file の checker 診断(開発用)docs/mtsc.md
    mtsc conformanceTypeScript conformance corpus に対する精度集計(開発用)docs/tsacc.md

    compile mode の command line は tsc / tsgo の superset です。tsc の option 名はそのまま通り、-p / tsconfig.json の読み取り、--noEmit、 --watch、tsc 準拠の exit code に対応します。mtsc が動作を持たない option (--target、--module、--strict など)は受け取ったうえで「honour していない」 と 1 行報告します。黙って無視はしません。

    ts2mbt / mbt2ts / tscheck / tsacc の 4 binary は mtsc に集約されました。 対応は ts2mbt X → mtsc bridge X、mbt2ts X → mtsc pkg X、 mbt2ts --pkg → mtsc pkg npm、tscheck → mtsc check、 tsacc → mtsc conformance です。

    #Generated package contract

    • mtsc bridge の output は consumer module の internal/generated/ に置く bridge package です。SCAFFOLD_DIAGNOSTICS.md で widen / omit した surface を確認します。
    • mtsc pkg npm の output は npm/ です。moon.mod の version と metadata を使い、 package.json、index.js、.d.ts、subpath export、必要なら npm bin を生成します。
    • どちらも output を手編集せず、入力と option から再生成してください。

    詳細な type boundary、facade、runtime validation、package export、unsupported surface は 各 tool guide に記載しています。

    #Diagnostics and examples

    • docs/ts2mbt.md — mtsc bridge: SCAFFOLD_DIAGNOSTICS.md、vendor と bridge。
    • docs/mbt2ts.md — mtsc pkg: AUTOLINK_DIAGNOSTICS.md、npm publish。
    • docs/mtsc.md — checker の CLI、ABI、既知ギャップ。
    • docs/mangle-safety.md — 型追跡による安全な property mangling と、その検証 corpus。
    • docs/minify-patterns.md — minify / mangle パターンの一覧と、各パターンの証明義務。
    • examples/ — just verify-examples で検証する runnable fixture。

    #Development

    moon fmt moon info just check just test just verify-scaffolds just verify-examples

    checker の TypeScript conformance gate は次を使います。

    just verify-checker-soundness # FP 0 / PFLEGAL 0 / MISS in scope <= budget をゲート

    軽量な conformance 集計には mtsc conformance guide を参照してください。

    checker が検出しない構文と、その優先度・スコープ外の判断は checker triage(方針と tier)と src/checker/UNSUPPORTED.md(残り MISS ファイルの一覧と、実測したコード形状)を参照してください。 docs/checker-priority.md は TS6 オラクル時代の文書で、結論は棄却済みです。

    #License

    Apache-2.0

    CliArgScan

    pub enum CliArgScan {
    Args(Array[String])
    HelpRequested
    }

    Outcome of a CLI subcommand argument scan.

    • Args(positionals): the parse succeeded; positionals are the subcommand-specific args (args[start:]).
    • HelpRequested: the next token after the subcommand was a help marker; the caller should print usage and return without erroring.

    CLI_VERSION

    let CLI_VERSION : String

    mizchi/ts package version reported by --version / -V. Sourced from moon.mod and bumped together with it at release time.

    It had drifted to 0.4.0 against a moon.mod reading 0.5.2, which nothing noticed because the only consumer was a banner nobody asserted. mtsc --version is a tsc-compatible surface now — tsc -v prints a version people act on — so a stale number here is a wrong answer rather than a cosmetic one.

    bridge_help_lines

    fn bridge_help_lines() -> Array[String]

    Every verb of mtsc bridge, one line each, in help order.

    all is the verb the ts2mbt binary spelled bridge. Under a bridge namespace that spelling reads as mtsc bridge bridge, so the verb is renamed and the old spelling kept as an accepted alias — a rename that breaks a script is not a consolidation.

    cli_bail

    fn cli_bail(message : String) -> Unit

    Bail out of the CLI: print Error: <message> then exit with status 1. Suitable for missing-argument, unknown-subcommand, and other usage errors that should not be silently ignored.

    cli_clean_error

    fn cli_clean_error(message : String) -> String

    Sanitize a raw bridge / IO error message so the printed CLI text doesn't leak the MoonBit OSError("@fs.open(): ...") debug shape. Specifically: when the message contains OSError("..."), replace that fragment with the inner reason (after the first : delimiter) so users see a single-quoted file path + plain reason.

    cli_exit

    fn cli_exit(code : Int) -> Unit

    Exit the CLI with the given status code. Use 0 for success and a non-zero value for any failure path.

    cli_fail

    fn cli_fail(binary_name : String) -> Unit

    Print a one-line " command failed" banner and exit with status 1. Cmd dispatchers should call this from every error path so CI / scripts can detect failure.

    cli_parse_subcommand_args

    fn cli_parse_subcommand_args(args : Array[String], start : Int, min_args : Int, usage : String, help_hint? : String) -> CliArgScan

    Parse the positional arguments for a subcommand. Returns HelpRequested when the user passed --help / -h / help. Calls cli_bail (which exits with status 1) when fewer than min_args positionals are present — the bail message includes a hint pointing at the per-subcommand --help so users know how to recover.

    args is the full process argv slice (@env.args()), start is the index of the first positional after the subcommand verb, and usage is the bail message printed when the arity check fails. The optional help_hint (e.g. "ts2mbt decl --help") is appended to the bail message; pass "" to suppress it.

    cli_print_version

    fn cli_print_version(binary_name : String) -> Unit

    Print the version banner for the given binary name and exit with status 0. Cmd dispatchers should intercept --version / -V and route here.

    cli_subcommand_is_help

    fn cli_subcommand_is_help(token : String) -> Bool

    Treat the given subcommand token as a help request — --help, -h, or help. Cmd dispatchers use this to short-circuit per-subcommand help before treating the next positional as a path.

    cli_token_is_version

    fn cli_token_is_version(token : String) -> Bool

    Treat the given top-level token as a version request — --version or -V. Cmd dispatchers use this to short-circuit the help/dispatch pipeline and just print the version banner.

    compute_vendor_root

    fn compute_vendor_root(module_root : String, moon_mod_source : String) -> String

    Pure-function variant of resolve_default_vendor_root for testing. Given a moon module root and the raw moon.mod.json contents, returns the directory the vendor pipeline should write into.

    When moon.mod.json does not declare a source field MoonBit treats the module root itself as the source directory, so the fallback here is "." rather than "src". Picking "src" for missing-source projects would emit the bridge under a phantom <root>/src/internal/generated/... path that the moon module can't see, and moon build would silently skip it.
    async fn emit_js_link_config_from_mbti(file_path : String, output_path : String?) -> Bool

    emit_moonbit_bridge

    async fn emit_moonbit_bridge(file_path : String, module_spec : String, decl_output_path : String?, ffi_output_path : String?, bridge_output_path : String?) -> Bool

    emit_moonbit_bridge_package

    async fn emit_moonbit_bridge_package(file_path : String, module_spec : String, output_dir : String, bare_module_specifier? : String?, moonbitlang_async_integration? : Bool, runtime_validation? : Bool) -> Bool

    emit_moonbit_decl

    async fn emit_moonbit_decl(file_path : String, output_path : String?) -> Bool

    emit_moonbit_js_ffi

    async fn emit_moonbit_js_ffi(file_path : String, module_spec : String, ffi_output_path : String?, bridge_output_path : String?) -> Bool

    emit_moonbit_scaffold_from_ts

    async fn emit_moonbit_scaffold_from_ts(file_path : String, module_spec : String, output_dir : String, write_diagnostics? : Bool, bare_module_specifier? : String?) -> Bool

    emit_typescript_decl

    async fn emit_typescript_decl(file_path : String, output_path : String?) -> Bool

    emit_typescript_decl_from_mbti

    async fn emit_typescript_decl_from_mbti(file_path : String, output_path : String?) -> Bool

    emit_typescript_facade_scaffold_from_mbti

    async fn emit_typescript_facade_scaffold_from_mbti(file_path : String, output_dir : String, import_rewrite_path : String?) -> Bool

    emit_typescript_package_from_mbti

    async fn emit_typescript_package_from_mbti(file_path : String, output_dir : String, import_rewrite_path : String?) -> Bool

    emit_typescript_scaffold_from_mbti

    async fn emit_typescript_scaffold_from_mbti(file_path : String, output_dir : String, import_rewrite_path : String?) -> Bool

    pkg_help_lines

    fn pkg_help_lines() -> Array[String]

    Every verb of mtsc pkg, one line each, in help order.

    npm is the flow the mbt2ts binary selected with a bare --pkg flag. A flag that picks a whole mode is a verb wearing a flag's spelling, and under a namespace it would have read as mtsc pkg --pkg; --pkg stays an accepted alias.

    run_bridge_cli

    async fn run_bridge_cli(args : Array[String], start : Int) -> Unit

    mtsc bridge … — the TypeScript -> MoonBit direction.

    start is the index of the verb (or of the first --input-style flag for the unified flow), so mtsc bridge decl x.d.ts passes 2.

    run_mbt_to_ts_pkg_cli

    async fn run_mbt_to_ts_pkg_cli(args : Array[String], start : Int, print_help~ : () -> Unit) -> Bool

    Public entry for mtsc pkg npm. It discovers the enclosing MoonBit module from the caller's working directory and leaves all package policy to the project-level generator above.

    run_mbt_to_ts_unified_cli

    async fn run_mbt_to_ts_unified_cli(args : Array[String], start : Int, print_help~ : () -> Unit) -> Bool

    Public entry: run the unified MoonBit -> TypeScript scaffold driver with the direction locked to mbt-to-ts. Used by mtsc pkg.

    run_pkg_cli

    async fn run_pkg_cli(args : Array[String], start : Int) -> Unit

    mtsc pkg … — the MoonBit -> TypeScript direction.

    start is the index of the verb, so mtsc pkg decl x.mbti passes 2.

    run_ts_to_mbt_unified_cli

    async fn run_ts_to_mbt_unified_cli(args : Array[String], start : Int, print_help~ : () -> Unit) -> Bool

    Public entry: run the unified TS -> MoonBit scaffold driver with the direction locked to ts-to-mbt. Used by mtsc bridge.

    ts2mbt_generate_from_package_json

    async fn ts2mbt_generate_from_package_json(package_json_path_override? : String?, vendor_root_override? : String?) -> Bool

    Generate MoonBit bridges for every dependency listed in a package.json (dependencies + devDependencies) and write them under <source>/internal/generated/<safe>/. Emits a per-package summary at the end and returns true only when every package generated successfully.

    package_json_path_override defaults to ./package.json.

    ts2mbt_vendor_package

    async fn ts2mbt_vendor_package(pkg_spec : String, module_spec_override? : String?, vendor_root_override? : String?, print_import_hint? : Bool) -> Bool