moonnginx

    nginx.conf directive-tree codec for MoonBit

    nginx
    nginx.conf
    crossplane
    config
    parser
    Download zip
    Version
    0.2.0
    License
    Apache-2.0
    Last updated
    last month
    Downloads
    50

    No dependencies

    #MoonNginx

    MoonBit codec for nginx.conf: lex, parse to a directive tree, dump, build, query, and check OSS core-module context/arity.

    Behavioral reference: nginxinc/nginx-go-crossplane (Apache-2.0). Go sources are not copied; see THIRD_PARTY.md.

    #What it provides

    • A loss-aware lexer and nested directive-tree parser for common nginx.conf syntax.
    • Stable dumping with quoting, comments, nested blocks, and variable tokens preserved.
    • Typed builders for common events, http, server, location, and upstream structures.
    • Core-context and argument validation for the supported OSS directive profile.
    • Queries for servers, locations, upstream peers, includes, proxy backends, and rewrite rules.
    • Structural analysis with directive counts, nesting depth, and extension-directive discovery.
    • Crossplane-style JSON payload output for tooling and migration workflows.

    The package is a configuration codec and static validator. It does not start nginx or execute configuration directives.

    #Install

    The package is published as LuoYunxin1/moonnginx@0.1.0 on MoonCakes:

    moon add LuoYunxin1/moonnginx

    For a checked-out development copy, run commands from the repository root. MoonBit 0.10.14 or newer is required for acceptance and CI.

    #Minimal use

    Add the package import to the consumer package's moon.pkg:

    import {
    "LuoYunxin1/moonnginx" @ngx,
    }

    Then call the public API through the package alias:

    let cfg = @ngx.unwrap_ngx(@ngx.parse_and_validate("worker_processes 4;\\n"))
    let text = @ngx.dump_conf(cfg)
    println(text)

    parse_and_validate returns a structured NgxError instead of silently accepting an invalid core-module context. Use parse_conf when you need parsing without policy validation.

    #Three runnable scenarios

    The repository includes a runnable executable covering three representative workflows:

    moon run cmd/main --target wasm-gc

    1. PARSE — parse an upstream and a server/location containing proxy_pass, then dump the tree.
    2. BUILD — construct an http/server configuration with listen 8080 and root /var/www.
    3. VALIDATE — reject listen nested inside location and print the diagnostic.

    The demo is intentionally independent of a locally installed nginx process and is therefore reproducible on the MoonBit WebAssembly target.

    #Verify locally

    moon version --all moon info moon fmt moon check --target wasm-gc --deny-warn moon test --target wasm-gc --deny-warn moon build --target wasm-gc --deny-warn moon run cmd/main --target wasm-gc

    The test suite covers lexing, comments and quoting, nested parsing, round-trip dumping, builders, queries, JSON payloads, validation errors, and whitebox token behavior. CI runs check, build, test, and the runnable demo on every push and pull request.

    #Boundary

    MoonNginx does not start nginx, terminate TLS, execute Lua/OpenResty, follow include files on disk, or speak the HAProxy PROXY protocol. Those responsibilities remain with the caller or a runtime integration.

    #License

    Apache-2.0. See LICENSE.

    Config

    pub(all) struct Config {
    file : String
    parsed : Array[Directive]
    status : String
    } derive(Eq,
    Debug
    )

    Config::equal

    fn Config::equal(Config, Config) -> Bool

    Config::find

    fn Config::find(self : Config, name : String) -> Array[Directive]

    Config::find_all

    fn Config::find_all(self : Config, name : String) -> Array[Directive]

    Config::not_equal

    fn Config::not_equal(x : Config, y : Config) -> Bool

    Config::to_repr

    ConfigStats

    pub(all) struct ConfigStats {
    directives : Int
    blocks : Int
    simple : Int
    comments : Int
    max_depth : Int
    servers : Int
    locations : Int
    upstreams : Int
    includes : Int
    unknown : Array[String]
    } derive(Eq,
    Debug
    )

    Structural metrics for a parsed nginx configuration.

    ConfigStats::equal

    fn ConfigStats::equal(ConfigStats, ConfigStats) -> Bool

    ConfigStats::not_equal

    fn ConfigStats::not_equal(x : ConfigStats, y : ConfigStats) -> Bool

    Directive

    pub(all) struct Directive {
    name : String
    line : Int
    args : Array[String]
    quoted : Array[Bool]
    children : Array[Directive]
    has_block : Bool
    comment : String?
    } derive(Eq,
    Debug
    )

    One nginx statement: simple, block, or comment.

    Directive::arg0

    fn Directive::arg0(self : Directive) -> String?

    Directive::child

    fn Directive::child(self : Directive, name : String) -> Array[Directive]

    Directive::equal

    fn Directive::equal(Directive, Directive) -> Bool

    Directive::is_block

    fn Directive::is_block(self : Directive) -> Bool

    Directive::is_comment

    fn Directive::is_comment(self : Directive) -> Bool

    Directive::is_include

    fn Directive::is_include(self : Directive) -> Bool

    Directive::not_equal

    fn Directive::not_equal(x : Directive, y : Directive) -> Bool

    NgxError

    pub(all) enum NgxError {
    Syntax(String)
    Unexpected(String)
    Unterminated(String)
    Constraint(String)
    NotImplemented(String)
    } derive(Eq,
    Debug
    )

    nginx.conf codec errors.

    NgxError::equal

    fn NgxError::equal(NgxError, NgxError) -> Bool

    NgxError::message

    fn NgxError::message(self : NgxError) -> String

    NgxError::not_equal

    fn NgxError::not_equal(x : NgxError, y : NgxError) -> Bool

    NgxError::to_repr

    Tok

    pub(all) struct Tok {
    kind : TokKind
    value : String
    line : Int
    } derive(Eq,
    Debug
    )

    Tok::equal

    fn Tok::equal(Tok, Tok) -> Bool

    Tok::not_equal

    fn Tok::not_equal(x : Tok, y : Tok) -> Bool

    Tok::to_repr

    TokKind

    pub(all) enum TokKind {
    Word
    Quoted
    LBrace
    RBrace
    Semi
    Comment
    } derive(Eq,
    Debug
    )

    TokKind::equal

    fn TokKind::equal(TokKind, TokKind) -> Bool

    TokKind::not_equal

    fn TokKind::not_equal(x : TokKind, y : TokKind) -> Bool

    TokKind::to_repr

    analyze_config

    fn analyze_config(cfg : Config) -> ConfigStats

    Analyze the directive tree without executing nginx or resolving includes.

    build_config

    fn build_config(dirs : Array[Directive]) -> Config

    collect_names

    fn collect_names(cfg : Config) -> Array[String]

    config_json

    fn config_json(cfg : Config) -> Json

    config_ok

    fn config_ok(file : String, parsed : Array[Directive]) -> Config

    config_summary

    fn config_summary(cfg : Config) -> String

    Compact deterministic summary suitable for command-line diagnostics.

    count_directives

    fn count_directives(cfg : Config) -> Int

    dir_block

    fn dir_block(name : String, args : Array[String], children : Array[Directive], line : Int) -> Directive

    dir_comment

    fn dir_comment(text : String, line : Int) -> Directive

    dir_simple

    fn dir_simple(name : String, args : Array[String], line : Int) -> Directive

    dump_conf

    fn dump_conf(cfg : Config) -> String

    empty_config

    fn empty_config(file : String) -> Config

    first_server_name

    fn first_server_name(server : Directive) -> String?

    has_ssl

    fn has_ssl(server : Directive) -> Bool

    includes_of

    fn includes_of(cfg : Config) -> Array[String]

    known_core_directive

    fn known_core_directive(name : String) -> Bool

    library_name

    fn library_name() -> String

    line_msg

    fn line_msg(line : Int, msg : String) -> String

    listen_addrs

    fn listen_addrs(server : Directive) -> Array[String]

    location_paths

    fn location_paths(server : Directive) -> Array[String]

    locations_of

    fn locations_of(server : Directive) -> Array[Directive]

    ngx_access_log

    fn ngx_access_log(path : String) -> Directive

    ngx_add_header

    fn ngx_add_header(name : String, value : String) -> Directive

    ngx_allow

    fn ngx_allow(spec : String) -> Directive

    ngx_client_max_body_size

    fn ngx_client_max_body_size(value : String) -> Directive

    ngx_deny

    fn ngx_deny(spec : String) -> Directive

    ngx_error_log

    fn ngx_error_log(path : String) -> Directive

    ngx_events

    fn ngx_events(children : Array[Directive]) -> Directive

    ngx_gzip

    fn ngx_gzip(onoff : String) -> Directive

    ngx_http

    fn ngx_http(children : Array[Directive]) -> Directive

    ngx_if

    fn ngx_if(cond : Array[String], children : Array[Directive]) -> Directive

    ngx_include

    fn ngx_include(path : String) -> Directive

    ngx_index

    fn ngx_index(names : Array[String]) -> Directive

    ngx_keepalive_timeout

    fn ngx_keepalive_timeout(value : String) -> Directive

    ngx_listen

    fn ngx_listen(addr : String) -> Directive

    ngx_location

    fn ngx_location(path : String, children : Array[Directive]) -> Directive

    ngx_location_mod

    fn ngx_location_mod(modifier : String, path : String, children : Array[Directive]) -> Directive

    ngx_pid

    fn ngx_pid(path : String) -> Directive

    ngx_proxy_pass

    fn ngx_proxy_pass(url : String) -> Directive

    ngx_return_code

    fn ngx_return_code(code : String) -> Directive

    ngx_return_url

    fn ngx_return_url(code : String, url : String) -> Directive

    ngx_rewrite

    fn ngx_rewrite(regex : String, replacement : String) -> Directive

    ngx_root

    fn ngx_root(path : String) -> Directive

    ngx_sendfile

    fn ngx_sendfile(onoff : String) -> Directive

    ngx_server

    fn ngx_server(children : Array[Directive]) -> Directive

    ngx_server_name

    fn ngx_server_name(name : String) -> Directive

    ngx_set

    fn ngx_set(variable : String, value : String) -> Directive

    ngx_try_files

    fn ngx_try_files(args : Array[String]) -> Directive

    ngx_upstream

    fn ngx_upstream(name : String, children : Array[Directive]) -> Directive

    ngx_upstream_server

    fn ngx_upstream_server(addr : String) -> Directive

    ngx_worker_connections

    fn ngx_worker_connections(n : String) -> Directive

    ngx_worker_processes

    fn ngx_worker_processes(n : String) -> Directive

    parse_and_validate

    fn parse_and_validate(text : String) -> Result[Config, NgxError]

    parse_conf

    fn parse_conf(text : String) -> Result[Config, NgxError]

    parse_conf_named

    fn parse_conf_named(file : String, text : String) -> Result[Config, NgxError]

    parse_dump

    fn parse_dump(text : String) -> Result[String, NgxError]

    payload_json

    fn payload_json(cfg : Config) -> Json

    payload_text

    fn payload_text(cfg : Config) -> String

    proxy_backends

    fn proxy_backends(cfg : Config) -> Array[String]

    rewrite_rules

    fn rewrite_rules(cfg : Config) -> Array[(String, String)]

    roundtrip

    fn roundtrip(text : String) -> Result[String, NgxError]

    servers_of

    fn servers_of(cfg : Config) -> Array[Directive]

    supported_blocks

    fn supported_blocks() -> Array[String]

    syntax_profile

    fn syntax_profile() -> String

    unknown_directives

    fn unknown_directives(cfg : Config) -> Array[String]

    Return unique directive names that are outside the built-in core profile.

    unwrap_ngx

    fn[T] unwrap_ngx(r : Result[T, NgxError]) -> T

    upstream_peers

    fn upstream_peers(cfg : Config, name : String) -> Array[String]

    uses_known_directives_only

    fn uses_known_directives_only(cfg : Config) -> Bool

    True when every non-comment directive belongs to the built-in core profile.

    validate_core

    fn validate_core(cfg : Config) -> Result[Unit, NgxError]