jerrycan 0.6.21

The AI-native Rust backend platform: framework, CLI, and MCP server. https://jerrycan.cc
Documentation
[package]
name = "jerrycan"
description = "The AI-native Rust backend platform: framework, CLI, and MCP server. https://jerrycan.cc"
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
repository.workspace = true
authors.workspace = true
rust-version.workspace = true
keywords = ["web", "framework", "backend", "ai", "mcp"]
categories = ["web-programming::http-server", "command-line-utilities"]
readme = "README.md"

[features]
# Generated apps depend on this crate with `default-features = false` (lib facade
# only). The default ON keeps `cargo install jerrycan` working for the platform.
default = ["cli"]
# The CLI always carries db (for `jerrycan db migrate`) + tokio (to run the
# async migrator); generated apps still choose their own features freely.
cli = ["dep:clap", "dep:serde", "dep:serde_json", "dep:tokio", "dep:sea-query", "dep:sqlparser", "dep:sha2", "dep:syn", "dep:proc-macro2", "db"]
db = ["dep:jerrycan-db"]
validate = ["dep:jerrycan-validate"]
auth = ["dep:jerrycan-auth"]
# OAuth2 client + provider presets (jerrycan-auth's `oauth`).
oauth = ["auth", "jerrycan-auth/oauth"]
# The deterministic mock OAuth2 IdP harness — test/eval-only. Non-default and kept
# off `oauth` so the token-minting harness never compiles into a prod client build;
# the v2.5 eval + generated tests enable it explicitly.
mock-idp = ["oauth", "jerrycan-auth/mock-idp"]
observe = ["dep:jerrycan-observe"]
# Jobs require a database: the engine's default store is Postgres and the
# generated `jobs(db)` wiring takes a `jerrycan::db::Db`, so `jobs` implies `db`.
jobs = ["dep:jerrycan-jobs", "db"]
# The Redis Streams job store (multi-node) as a facade feature. The RedisStore
# type is re-exported via `pub use jerrycan_jobs` (no extra wiring needed).
jobs-redis = ["jobs", "jerrycan-jobs/jobs-redis"]
rate-limit = ["dep:jerrycan-ratelimit"]
rate-limit-redis = ["rate-limit", "jerrycan-ratelimit/rate-limit-redis"]
# Object storage: design-modeled buckets + blob backends. Metadata lives in a
# jerrycan-db table, so `storage` implies `db` (like `jobs`).
storage = ["dep:jerrycan-storage", "db"]
# The S3-compatible backend (AWS/R2/MinIO/Supabase-S3) as a facade feature.
# Generated storage apps enable THIS one: JERRYCAN_STORAGE switches backends
# by env at runtime, so the S3 code must be compiled into the packaged binary.
storage-s3 = ["storage", "jerrycan-storage/storage-s3"]
# Realtime channels (Postgres Changes + Broadcast + Presence over WebSockets).
# Changes stream from the database, so `realtime` implies `db` (like jobs).
realtime = ["dep:jerrycan-realtime", "db"]
# Multi-node realtime fan-out over Redis (mirrors jobs-redis).
realtime-redis = ["realtime", "jerrycan-realtime/realtime-redis"]

[[bin]]
name = "jerrycan"
required-features = ["cli"]

[dependencies]
jerrycan-core.workspace = true
jerrycan-macros.workspace = true
jerrycan-db = { workspace = true, optional = true }
jerrycan-validate = { workspace = true, optional = true }
jerrycan-auth = { workspace = true, optional = true }
jerrycan-observe = { workspace = true, optional = true }
jerrycan-jobs = { workspace = true, optional = true }
jerrycan-ratelimit = { workspace = true, optional = true }
jerrycan-storage = { workspace = true, optional = true }
jerrycan-realtime = { workspace = true, optional = true }
clap = { version = "4", features = ["derive"], optional = true }
sea-query = { workspace = true, optional = true }
sqlparser = { workspace = true, optional = true }
sha2 = { workspace = true, optional = true }
# CLI-only: the JL0006 lint parses each tenant-owned handlers.rs into an AST and
# walks it for unscoped repo calls (issue #103 — a substring scan missed multi-line
# chains and never reached nested handlers). `span-locations` gives each call its
# real source line for the diagnostic and the `// jerrycan:allow JL0006` hatch.
syn = { version = "2", features = ["full", "visit"], optional = true }
proc-macro2 = { version = "1", features = ["span-locations"], optional = true }
serde = { workspace = true, optional = true }
serde_json = { workspace = true, optional = true }
tokio = { workspace = true, optional = true }

[dev-dependencies]
tokio.workspace = true
serde.workspace = true
serde_json.workspace = true
tempfile = "3"

# `cargo binstall jerrycan` resolves the prebuilt binary from the GitHub
# release produced by .github/workflows/release.yml (asset naming is
# taiki-e/upload-rust-binary-action's default: <bin>-<target>.tar.gz).
[package.metadata.binstall]
pkg-url = "{ repo }/releases/download/v{ version }/{ name }-{ target }.tar.gz"
pkg-fmt = "tgz"

# The `platform` module (behind the `cli` feature) is internal codegen — the
# `jerrycan` bin and MCP server share it, but it is NOT a supported stable Rust
# API; downstream crates are not expected to construct its config structs by
# literal. `platform::Entity` is a serde-deserialized design.json struct, so
# adding an opt-in field to it (0.6.1: `public_read`, #105) is additive for every
# real consumer (design authors) yet trips `constructible_struct_adds_field`,
# which for a 0.x crate would force a spurious 0.x-major bump. Scope-allow that one
# lint for this package. TRADEOFF (tracked, #145): this also stops the lint from
# catching a *genuinely* breaking field-add to another `platform` struct — re-enable
# it once the platform config structs are `#[non_exhaustive]` (a future 0.x-major).
[package.metadata.cargo-semver-checks.lints]
constructible_struct_adds_field = "allow"