nest-rs-cli 1.1.0

Scaffolding CLI for NestRS — new projects, feature generators, and project health checks.
//! **Standalone mode** — one Cargo crate, all logic under `src/`.
//!
//! Generated by `nestrs new <name> --standalone`.
//! Contrasts with [`super::workspace`] (monorepo + `crates/features/`).

pub const CARGO: &str = r#"[package]
name = "{{kebab}}"
version = "0.1.0"
edition = "2024"
rust-version = "1.96"

# Own workspace root — scaffold works even inside another repo's tree.
[workspace]

[dependencies]
anyhow = "1"
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
nest-rs-core = "{{nestrs_version}}"
nest-rs-config = "{{nestrs_version}}"
nest-rs-guards = "{{nestrs_version}}"
nest-rs-http = "{{nestrs_version}}"
nest-rs-interceptors = "{{nestrs_version}}"
poem = { version = "3", features = ["tower-compat", "anyhow", "rustls"] }

[dev-dependencies]
nest-rs-testing = "{{nestrs_version}}"

# Release: the smallest, fastest single binary — production defaults.
[profile.release]
opt-level = 3       # maximum runtime performance
lto = "fat"         # whole-program optimisation across all crates
codegen-units = 1   # give the optimiser the whole crate at once
strip = true        # drop symbols for a smaller binary

# Dev: fastest iterative rebuilds; keep file:line in backtraces.
[profile.dev]
debug = "line-tables-only"
"#;

pub const MAIN: &str = r#"use anyhow::Result;
use nest_rs_config::Environment;
use nest_rs_core::App;

use {{snake}}::{{module}};

#[tokio::main]
async fn main() -> Result<()> {
    let _environment = Environment::init();

    App::builder()
        .module::<{{module}}>()
        .build()
        .await?
        .run()
        .await
}
"#;

pub const LIB: &str = r#"mod controller;
mod module;
mod service;

pub use module::{{module}};
"#;

/// The single crate's root module. `service.rs` and `controller.rs` are the
/// shared [`super::hello`] templates — one starter, both layouts.
pub const MODULE: &str = r#"use nest_rs_core::module;
use nest_rs_http::HttpModule;

use crate::controller::{{controller}};
use crate::service::{{service}};

#[module(
    imports = [
        HttpModule::for_root(None),
    ],
    providers = [{{service}}, {{controller}}],
)]
pub struct {{module}};
"#;

pub const DOCKERFILE: &str = r#"# syntax=docker/dockerfile:1.7
#
# Build:  docker build -t {{kebab}} .
# Run:    docker run --rm -p 3000:3000 {{kebab}}
#
# Multi-stage: compile in Rust slim, run on distroless nonroot.

ARG RUST_VERSION=1.96

FROM rust:${RUST_VERSION}-slim-trixie AS builder
WORKDIR /app
COPY Cargo.toml ./
COPY src ./src
RUN cargo build --release

FROM gcr.io/distroless/cc-debian13:nonroot AS runtime
COPY --from=builder /app/target/release/{{kebab}} /usr/local/bin/app
EXPOSE 3000
USER nonroot:nonroot
ENTRYPOINT ["/usr/local/bin/app"]
"#;

pub const JUSTFILE: &str = r#"_default:
    @just --list

# Run the app with auto-reload — watches the source, rebuilds and restarts on
# save (loads `.env` / `.env.development` from the project root).
dev:
    bacon run-long

# Run an optimized build.
start:
    cargo run --release

# Build the release binary (target/release/{{kebab}}).
build:
    cargo build --release

# Type-check without codegen.
check:
    cargo check

# Tests — unit/integration/e2e/doctests. Usage: nestrs run test [unit|e2e|doc]
mod test

# No database module here: those verbs drive the workspace's `migrations` and
# `seed` crates, which a single-crate layout has nowhere to put. Scaffold a
# workspace (`nestrs new <name>`) when this app grows a database.

# Apply rustfmt.
fmt:
    cargo fmt

# Clippy (strict) + format check.
lint:
    cargo clippy -- -D warnings
    cargo fmt --check
"#;

pub const TEST_JUSTFILE: &str = r#"# Test recipes, exposed as `nestrs run test <kind>` (see `mod test` in the
# Justfile). Bare `nestrs run test` lists these — pick a kind to run.

# Bare `nestrs run test` lists the kinds instead of running one.
_default:
    @just --list test

# Unit + integration + doctests, no DB.
unit:
    cargo nextest run -E 'not binary(e2e)'
    cargo test --doc          # nextest skips doctests; run them too

# e2e tests — the `tests/e2e/main.rs` suite (live infra). Scaffolded empty, so
# `--no-tests=pass` keeps this green until you write the first one.
e2e:
    cargo nextest run -E 'binary(e2e)' --no-tests=pass

# Doctests only — the code examples inside `///` doc comments.
doc:
    cargo test --doc
"#;

pub const README: &str = r#"# {{kebab}}

**Standalone** NestRS app — one crate, logic in `src/`. `GET /`, HTTP only,
no auth, no database. Generated by `nestrs new {{kebab}}`.

## Run

```bash
nestrs run dev
nestrs run build    # → target/release/{{kebab}}
nestrs run start    # build + run in release
```

Open **http://localhost:3000/** in your browser — you should see `Hello World`.

Need several apps sharing product code — or a database? Scaffold a
[workspace](https://nestrs.dev/cli/#layout-detection) instead:
`nestrs new <name>`. The generators (`g resource`, `g migration`) and the
`nestrs run db …` verbs are workspace-only.

## Configuration

Environment variables load from the
[`.env` cascade](https://nestrs.dev/configuration/env-cascade/). Committed
defaults live in `.env` and `.env.development`; copy `.env.example` to
`.env.local` for anything machine-specific or secret.
"#;