Sign in

    smithy-build

    Smithy build projections and plugins

    smithy
    build
    projection
    moonbit
    Download zip
    Author
    Version
    0.5.0
    License
    Apache-2.0
    Last updated
    2 days ago
    Downloads
    28

    #Smithy build

    Parses smithy-build.json, applies model projections and invokes registered plugins. BuildRunner::run returns relative artifact paths and contents; the CLI writes them to the configured output directory.

    run_result also returns errors and keeps successful projection artifacts. An invalid projected model writes build information, while plugins that require a valid model are skipped. run raises when any projection fails.

    Local and public URL sources and imports are loaded by the CLI. Maven dependencies are reported as unsupported. The runner includes the source projection and the model, sources and build-info plugins for each concrete projection.

    BuildConfig::parse accepts an environment map for ${NAME} substitutions in string values and object keys. Undefined variables fail configuration loading; \${NAME} keeps a literal placeholder. The CLI uses process variables and sets SMITHY_ROOT_DIR to its current working directory.

    Local JAR inputs load the IDL and JSON files listed in META-INF/smithy/manifest. archive_models remains the compatible bytes-to-model entry point. declared_models(tree) applies the same manifest rules to a moonrockz/artifact-resources entry tree and returns logical resources with physical origins. Generic ZIP, tar/gzip and filesystem access live in that independent module. Stored and deflated entries are read without extracting files. Source artifacts retain their manifest paths under the JAR filename without its extension.

    Explicit resource objects are accepted in sources, global imports and projection imports:

    { "version": "2.0", "sources": [{ "path": "module.zip", "root": "models", "paths": [{"path": "service.smithy", "name": "public/service.smithy"}], "globs": ["shared/**/*.json"] }] }

    path is resolved relative to the configuration file. root is mandatory; use . for the container root. Paths and globs are relative to it. The same object works with a directory, ZIP/JAR, .tar, .tar.gz or npm .tgz, without a Smithy manifest. Selected models must be .smithy or .json, and aliases must retain the original format. Globs use case-sensitive *, ? and whole-component **. Every selector must match a file. Results sort lexically by logical name; overlapping identical selections deduplicate and conflicting names fail.

    Selected source artifacts use root-relative logical names or explicit aliases. Imports contribute models without exporting source files. Projection imports remain scoped to their projection. Diagnostics keep physical filenames, including archive.zip!/path/model.smithy, independently of logical aliases. Selecting one physical model under two aliases assembles it once and exports both names. Source artifact collisions across input objects still fail.

    String inputs retain directory/model discovery and JAR manifest behavior. Ordinary ZIP and tar/gzip inputs require explicit selection. Nested ZIP and tar/gzip archives are not opened by legacy directory discovery. Explicit selection does not execute included code or recursively open archives. See the independent resource module for limits, path rules and backend acquisition requirements.

    For library callers, BuildConfig.sources, BuildConfig.imports and ProjectionConfig.imports now contain BuildInput values. Use BuildInput::from_path(string) for legacy discovery or Selected(RepositoryLocation, Selection) for explicit resources. JSON string configuration remains compatible. selected_models(tree, selection) exposes the Smithy format checks over the generic resource API.

    Public archive objects replace path with url and retain the same explicit selection in sources, global imports and projection imports:

    {"url":"https://example.org/models.zip","format":"zip","root":"models","paths":["service.smithy"]}

    format defaults to zip; jar, tar, tgz and tar.gz are also accepted. The optional digest is sha256: plus 64 hexadecimal digits. It verifies the whole downloaded archive before loading. URLs are never resolved as local paths, and url and path cannot be combined. String inputs remain local discovery; use an object for public acquisition. Remote JARs use explicit selection too. Model diagnostics retain the requested and resolved URLs, digest and physical archive entry. Selected source artifacts keep their logical names.

    Library configurations use Remote(PublicArchive, Selection). Existing exhaustive BuildInput matches need this new case. with_location now raises BuildError when a replacement location is not a valid URL for a remote input. The build library does not initiate I/O. Use register_public_http and a transport to obtain a tree, then selected_models and the usual loader/runner methods. See the acquisition limits and host matrix and runnable example.

    Call add_projection_import to supply inputs for a projection when using the runner directly. add_source marks files for source artifacts; its optional source_file argument identifies the original model filename when the artifact uses a relative name. Projected sources contain source shapes and metadata, including newly created shapes, and omit imported definitions.

    apply_transform applies a single built-in transform without running validation or plugins.

    Use plugin::artifactName to run a plugin with separate settings and an output directory of its own. Artifact names must be unique within a projection, including the default model, sources and build-info artifacts. Registered plugins return relative filenames; absolute paths and parent traversal are rejected.

    #Acquisition settings

    BuildConfig::parse accepts top-level cacheDirectory, a portable filesystem directory path defaulting to .smithy/cache, and offline, a boolean defaulting to false. The CLI resolves cache paths relative to the configuration file and shares the cache across sources, imports and projection imports. Library consumers receive these settings in cache_directory: CacheDirectory and offline and supply acquisition through artifact-resources; parsing configuration performs no I/O. See CLI cache behavior and the cache contract.

    Code constructing BuildConfig directly must initialize the new cache_directory and offline fields. BuildConfig::parse supplies their defaults.

    cacheDirectory rejects invalid filesystem syntax such as cache:* and reserved Windows device components such as NUL, including when parsed on another host.

    #GitHub release inputs

    A selected input can use github instead of path or url in sources, global imports and projection imports:

    { "github": { "repository": "owner/models", "tag": "v1.2.3", "asset": "models.tar.gz" }, "format": "tgz", "root": "package/models", "globs": ["**/*.smithy"] }

    An exact tag and exact asset name are required. format defaults to zip and accepts zip, jar, tar, tgz or tar.gz; add digest with an expected sha256: value to pin the bytes. An optional github.api selects a compatible public API base, defaulting to https://api.github.com. Source fields are exclusive and unknown fields fail validation. Resource roots, path/glob selection and logical name validation are unchanged.

    The library case is GitHub(GitHubArchive, Selection, HttpUrl), where the URL is the API base. Exhaustive BuildInput matches must handle it. location() returns the repository coordinate; with_location() validates and replaces that coordinate. to_json() preserves all reference, API, format, digest and selection settings. The CLI handles acquisition before calling the common model selector. The same cache/offline settings apply to metadata and archive bytes. See the provider contract and runnable example.

    #Public npm and Maven inputs

    Sources, global imports and projection imports accept exact npm package inputs:

    { "npm": { "package": "@scope/models", "version": "1.2.3" }, "root": "package/models", "globs": ["**/*.smithy"] }

    npm.registry defaults to https://registry.npmjs.org; an explicit public base URL can replace it. Selection is required and the archive format is always tgz. Scoped/unscoped names, strict exact SemVer, registry integrity checks and optional top-level SHA-256 digest are supported. npm is never installed or invoked.

    An exact Maven JAR defaults to Smithy manifest discovery:

    { "maven": { "repository": "https://repo.maven.apache.org/maven2", "group": "software.amazon.smithy", "artifact": "smithy-aws-traits", "version": "1.72.0", "checksum": "sha1" } }

    repository defaults to Maven Central. Optional classifier selects a classified JAR; checksum selects sha1 or sha256 sidecars and defaults to sha1. A top-level digest supplies the expected SHA-256 and takes precedence over sidecars. Add root and paths/globs for explicit selection instead of manifest discovery. The same acquired tree and model-selection path serve every build position.

    Only one of path, url, github, npm or maven may select an input. Unknown coordinate fields, input-level credentials, explicit format overrides, dependency ranges, mutable snapshots and transitive resolution settings are rejected. The legacy root-level maven.dependencies configuration remains unsupported; these selected inputs acquire direct artifacts and do not resolve a dependency graph.

    Library callers construct BuildInput::Npm(NpmArchive, Selection) or BuildInput::Maven(MavenArchive, Selection?). None selects manifest discovery for Maven. Exhaustive matches must handle both variants. location() returns the registry/repository base; with_location() validates a replacement base and to_json() preserves coordinates, checksum policy, digest and selection.

    See the provider contracts, npm example and Maven example. All remote inputs share cacheDirectory, offline and the CLI cache flags.

    #Credential bindings

    Root-level credentials is an array of CredentialBinding values. Each binding has an exact HttpOrigin and a CredentialSource: BearerEnvironment or BasicEnvironment, using validated CredentialVariable names. JSON uses origin plus bearerTokenEnv, or origin plus usernameEnv and passwordEnv. Literal secrets, mixed methods, duplicate origins and insecure remote HTTP origins are rejected. Credentials are parsed before general environment expansion; this section never expands ${NAME} placeholders.

    BuildConfig::resolve_credentials(environment) resolves supplied values into the resource library's redacted Credentials. The configuration itself retains only references. The CLI resolves them once per build and passes them through every provider in sources and both import scopes. The library does not read ambient environment variables or initiate I/O. Missing/empty values and malformed credentials report generic errors without echoing secrets. See the CLI setup and cache/redirect policy.

    BuildError

    pub(all) suberror BuildError {
    InvalidBuildConfig(String)
    } derive(Eq,
    Debug
    )

    BuildConfig

    pub(all) struct BuildConfig {
    version : String
    sources : Array[BuildInput]
    imports : Array[BuildInput]
    cache_directory :
    CacheDirectory

    credentials : Array[CredentialBinding]
    offline : Bool
    output_directory : String
    projections : Array[ProjectionConfig]
    plugins : Map[String, Json]
    ignore_missing_plugins : Bool
    } derive(Eq,
    Debug
    )

    BuildConfig::parse

    fn BuildConfig::parse(source : String, environment? : Map[String, String]) -> BuildConfig raise BuildError

    BuildConfig::resolve_credentials

    fn BuildConfig::resolve_credentials(self : BuildConfig, environment : Map[String, String]) ->
    Credentials
    raise BuildError

    Resolve secrets only at invocation time. The BuildConfig retains references.

    BuildResult

    pub(all) struct BuildResult {
    artifacts : Map[String, String]
    errors : Array[String]
    } derive(
    Debug
    )

    Artifacts from successful plugins and failures reported by the build.

    BuildRunner

    pub struct BuildRunner {
    config : BuildConfig
    plugins : Map[String, (
    Model
    , Json) -> Map[String, String] raise BuildError]
    sources : Map[String, String]
    source_conflicts : Array[String]
    source_origins :
    Set
    [String]
    source_metadata :
    Set
    [String]
    projection_imports : Map[String, Array[
    ModelInput
    ]]
    }

    BuildRunner::add_projection_import

    fn BuildRunner::add_projection_import(self : BuildRunner, projection : String, input :
    ModelInput
    ) -> BuildRunner

    Supply local projection imports; the caller owns file access.

    BuildRunner::add_source

    fn BuildRunner::add_source(self : BuildRunner, name : String, content : String, source_file? : String?) -> BuildRunner

    BuildRunner::new

    fn BuildRunner::new(config : BuildConfig) -> BuildRunner

    BuildRunner::register_plugin

    fn BuildRunner::register_plugin(self : BuildRunner, name : String, execute : (
    Model
    , Json) -> Map[String, String] raise BuildError) -> BuildRunner

    Register a plugin that writes relative filenames for a projected model.

    BuildRunner::run

    fn BuildRunner::run(self : BuildRunner, model :
    Model
    ) -> Map[String, String] raise BuildError

    Produce artifacts, raising if any projection failed.

    BuildRunner::run_result

    Preserve successful projections and build information when another projection fails.

    CredentialBinding

    CredentialSource

    pub(all) enum CredentialSource {
    BearerEnvironment(CredentialVariable)
    BasicEnvironment(CredentialVariable, CredentialVariable)
    } derive(Eq,
    Debug
    )

    CredentialVariable

    pub struct CredentialVariable {
    // private fields
    } derive(Eq,
    Debug
    )

    An environment variable name, never its secret value.

    CredentialVariable::parse

    fn CredentialVariable::parse(text : String) -> CredentialVariable?

    CredentialVariable::to_string

    fn CredentialVariable::to_string(self : CredentialVariable) -> String

    ProjectionConfig

    pub(all) struct ProjectionConfig {
    name : String
    is_abstract : Bool
    imports : Array[BuildInput]
    transforms : Array[TransformConfig]
    plugins : Map[String, Json]
    } derive(Eq,
    Debug
    )

    TransformConfig

    pub(all) struct TransformConfig {
    name : String
    args : Json
    } derive(Eq,
    Debug
    )

    apply_transform

    Apply one built-in transform without validating or running plugins.

    archive_models

    fn archive_models(data : Bytes, origin : String) -> Map[String, String] raise BuildError

    Discover models listed by META-INF/smithy/manifest in a local JAR or ZIP. Keys are relative to META-INF/smithy; no archive files are extracted.

    declared_models

    Discover the Smithy manifest in any resource entry tree. Manifest duplicates are ignored, as in archive_models; other resource consumers reject aliases.

    selected_models

    Smithy accepts only selected model resources; generic selectors stay format-independent.

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io