diff --git a/.github/workflows/loco-cli-e2e-master.yaml b/.github/workflows/loco-cli-e2e-master.yaml
deleted file mode 100644
index 6ffba1494..000000000
--- a/.github/workflows/loco-cli-e2e-master.yaml
+++ /dev/null
@@ -1,105 +0,0 @@
-name: "[loco-cli:e2e(master)]"
-
-on:
- push:
- branches:
- - master
- pull_request:
-
-jobs:
- # TODO: re-enable after 0.8 to check cmd spawning fix
- saas-win32:
- runs-on: windows-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: nightly
- components: rustfmt
- - name: Install seaorm cli
- run: cargo install sea-orm-cli
- - run: |
- cargo install --path .
- working-directory: ./loco-cli
- - run: |
- loco new -n saas -t saas --db sqlite --bg async --assets serverside
- env:
- ALLOW_IN_GIT_REPO: true
- - run: |
- cargo build
- working-directory: ./saas
- - run: |
- cargo loco routes
- working-directory: ./saas
- - run: |
- cargo loco db migrate
- working-directory: ./saas
- - run: |
- cargo loco generate scaffold movie title:string --htmx
- working-directory: ./saas
- - run: |
- cargo loco db migrate
- working-directory: ./saas
-
- saas:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: nightly
- - run: |
- cargo install loco-cli
- ALLOW_IN_GIT_REPO=true LOCO_APP_NAME=saas LOCO_TEMPLATE=saas loco new --db postgres --bg queue --assets serverside
- - run: |
- cargo build
- working-directory: ./saas
-
- rest-api:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: nightly
- - run: |
- cargo install loco-cli
- ALLOW_IN_GIT_REPO=true LOCO_APP_NAME=restapi LOCO_TEMPLATE=rest-api loco new --db postgres --bg queue
- - run: |
- cargo build
- working-directory: ./restapi
-
- lightweight-service:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: nightly
- override: true
- - run: |
- cargo install loco-cli
- ALLOW_IN_GIT_REPO=true LOCO_APP_NAME=lightweight LOCO_TEMPLATE=lightweight-service loco new
- - run: |
- cargo build
- working-directory: ./lightweight
diff --git a/.github/workflows/loco-cli-e2e.yaml b/.github/workflows/loco-cli-e2e.yaml
deleted file mode 100644
index 88f55aea3..000000000
--- a/.github/workflows/loco-cli-e2e.yaml
+++ /dev/null
@@ -1,63 +0,0 @@
-name: "[loco-cli:e2e]"
-
-on:
- schedule:
- - cron: 0 * * * * # every hour
-
-jobs:
- saas:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: nightly
- - run: |
- cargo install loco-cli
- ALLOW_IN_GIT_REPO=true loco new --template saas --name saas --db sqlite --bg async --assets serverside
- - run: |
- cargo build
- working-directory: ./saas
-
- rest-api:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: nightly
- - run: |
- cargo install loco-cli
- ALLOW_IN_GIT_REPO=true loco new --template rest-api --name restapi --db sqlite --bg async
- - run: |
- cargo build
- working-directory: ./restapi
-
- lightweight-service:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: nightly
- - run: |
- cargo install loco-cli
- ALLOW_IN_GIT_REPO=true loco new --template lightweight-service --name lightweight --db sqlite --bg async
- - run: |
- cargo build
- working-directory: ./lightweight
diff --git a/.github/workflows/loco-gen-ci.yml b/.github/workflows/loco-gen-ci.yml
index cf097c80e..6c72b4c82 100644
--- a/.github/workflows/loco-gen-ci.yml
+++ b/.github/workflows/loco-gen-ci.yml
@@ -58,10 +58,9 @@ jobs:
uses: Swatinem/rust-cache@v2
- run: |
- cargo install --path ../loco-cli
+ cargo install --path ../loco-new
- name: Run cargo test
- uses: actions-rs/cargo@v1
- with:
- command: test
- args: --all-features
+ run: cargo test --all-features
+ env:
+ LOCO_DEV_MODE_PATH: ${{ github.workspace }}
diff --git a/.github/workflows/loco-cli.yml b/.github/workflows/loco-new.yml
similarity index 60%
rename from .github/workflows/loco-cli.yml
rename to .github/workflows/loco-new.yml
index 09f8874bb..300ab45a2 100644
--- a/.github/workflows/loco-cli.yml
+++ b/.github/workflows/loco-new.yml
@@ -1,10 +1,14 @@
-name: "[loco-cli:ci]"
+name: "[loco-new:ci]"
on:
push:
branches:
- master
+ paths:
+ - "loco-new/**"
pull_request:
+ paths:
+ - "loco-new/**"
env:
RUST_TOOLCHAIN: stable
@@ -27,13 +31,13 @@ jobs:
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
- run: cargo fmt --all -- --check
- working-directory: ./loco-cli
+ working-directory: ./loco-new
- name: Run cargo clippy
run: cargo clippy --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery -W rust-2018-idioms
- working-directory: ./loco-cli
+ working-directory: ./loco-new
test:
- needs: [style]
+ # needs: [style]
runs-on: ${{ matrix.os }}
strategy:
matrix:
@@ -53,8 +57,18 @@ jobs:
- name: Setup Rust cache
uses: Swatinem/rust-cache@v2
+ - name: Configure sccache
+ run: |
+ echo "RUSTC_WRAPPER=sccache" >> $GITHUB_ENV
+ echo "SCCACHE_GHA_ENABLED=true" >> $GITHUB_ENV
+
+ - name: Run sccache-cache
+ uses: mozilla-actions/sccache-action@v0.0.6
+
- name: Run cargo test
- run: cargo test --all-features --all
- working-directory: ./loco-cli
+ run: cargo test --all-features -- --test-threads 1
+ working-directory: ./loco-new
env:
- LOCO_CI_MODE: 1
+ LOCO_DEV_MODE_PATH: ${{ github.workspace }}
+ # NOTE NOTE NOTE: this is for optimizing build and may result in strange behavior
+ CARGO_TARGET_DIR: /tmp/shared-target
diff --git a/.github/workflows/loco-rs-ci.yml b/.github/workflows/loco-rs-ci.yml
index 4c822a841..5129cfc2b 100644
--- a/.github/workflows/loco-rs-ci.yml
+++ b/.github/workflows/loco-rs-ci.yml
@@ -57,4 +57,4 @@ jobs:
uses: actions-rs/cargo@v1
with:
command: test
- args: --all-features --workspace --exclude loco-gen
+ args: --all-features --workspace --exclude loco-gen --exclude loco
diff --git a/.github/workflows/starter-lightweight-service.yml b/.github/workflows/starter-lightweight-service.yml
deleted file mode 100644
index c8f0d8ccd..000000000
--- a/.github/workflows/starter-lightweight-service.yml
+++ /dev/null
@@ -1,84 +0,0 @@
-name: "[starters/lightweight:ci]"
-
-on:
- push:
- branches:
- - master
- paths:
- - starters/lightweight-service/**
- pull_request:
- paths:
- - starters/lightweight-service/**
-
-env:
- RUST_TOOLCHAIN: stable
- TOOLCHAIN_PROFILE: minimal
-
-jobs:
- style:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: ${{ env.RUST_TOOLCHAIN }}
- components: rustfmt
- - name: Setup Rust cache
- uses: Swatinem/rust-cache@v2
- - run: cargo fmt --all -- --check
- working-directory: ./starters/lightweight-service
- - name: Run cargo clippy
- run: cargo clippy -- -W clippy::nursery -W clippy::pedantic -W rust-2018-idioms -W rust-2021-compatibility
- working-directory: ./starters/lightweight-service
-
- test:
- needs: [style]
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: ${{ env.RUST_TOOLCHAIN }}
- - name: Setup Rust cache
- uses: Swatinem/rust-cache@v2
- - name: Run cargo test
- run: cargo test --all-features --all
- working-directory: ./starters/lightweight-service
-
- # generate_template:
- # name: Generate Template
- # needs: [test]
- # runs-on: ubuntu-latest
-
- # permissions:
- # contents: read
-
- # steps:
- # - name: Checkout the code
- # uses: actions/checkout@v4
- # - uses: dtolnay/rust-toolchain@stable
- # with:
- # toolchain: ${{ env.RUST_TOOLCHAIN }}
- # - name: Setup Rust cache
- # uses: Swatinem/rust-cache@v2
- # - name: Inject slug/short variables
- # uses: rlespinasse/github-slug-action@v3.x
- # - name: Generate template
- # run: |
- # cargo build --release --features github_ci
- # RUST_LOG=debug LOCO_CURRENT_REPOSITORY=${{ github.event.pull_request.head.repo.html_url }} LOCO_CI_MODE=true LOCO_APP_NAME=stateless_html_starter LOCO_TEMPLATE=stateless_html LOCO_BRANCH=${{ env.GITHUB_HEAD_REF_SLUG }} ./target/release/loco new
- # cd stateless_html_starter
- # echo "Building generate template..."
- # cargo build --release
- # echo "Run cargo test on generated template..."
- # cargo test
- # working-directory: ./loco-cli
diff --git a/.github/workflows/starter-rest-api.yml b/.github/workflows/starter-rest-api.yml
deleted file mode 100644
index 56f4d9b25..000000000
--- a/.github/workflows/starter-rest-api.yml
+++ /dev/null
@@ -1,118 +0,0 @@
-name: "[starters/rest-api:ci]"
-
-on:
- push:
- branches:
- - master
- paths:
- - starters/rest-api/**
- pull_request:
- paths:
- - starters/rest-api/**
-
-env:
- RUST_TOOLCHAIN: stable
- TOOLCHAIN_PROFILE: minimal
-
-jobs:
- style:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: ${{ env.RUST_TOOLCHAIN }}
- components: rustfmt
- - name: Setup Rust cache
- uses: Swatinem/rust-cache@v2
- - run: cargo fmt --all -- --check
- working-directory: ./starters/rest-api
- - name: Run cargo clippy
- run: cargo clippy -- -W clippy::nursery -W clippy::pedantic -W rust-2018-idioms -W rust-2021-compatibility
- working-directory: ./starters/rest-api
-
- test:
- needs: [style]
- runs-on: ubuntu-latest
- strategy:
- matrix:
- db:
- - "postgres://postgres:postgres@localhost:5432/postgres_test"
- - "sqlite://loco_app.sqlite?mode=rwc"
-
- permissions:
- contents: read
-
- services:
- redis:
- image: redis
- options: >-
- --health-cmd "redis-cli ping"
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
- ports:
- - "6379:6379"
- postgres:
- image: postgres
- env:
- POSTGRES_DB: postgres_test
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- ports:
- - "5432:5432"
- # Set health checks to wait until postgres has started
- options: --health-cmd pg_isready
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: ${{ env.RUST_TOOLCHAIN }}
- - name: Setup Rust cache
- uses: Swatinem/rust-cache@v2
- - name: Install seaorm cli
- run: cargo install sea-orm-cli
- - name: Run cargo test
- run: cargo loco db reset && cargo loco db entities && cargo test --all-features --all
- working-directory: ./starters/rest-api
- env:
- REDIS_URL: redis://localhost:${{job.services.redis.ports[6379]}}
- DATABASE_URL: ${{matrix.db}}
- # generate_template:
- # name: Generate Template
- # needs: [test]
- # runs-on: ubuntu-latest
-
- # permissions:
- # contents: read
-
- # steps:
- # - name: Checkout the code
- # uses: actions/checkout@v4
- # - uses: dtolnay/rust-toolchain@stable
- # with:
- # toolchain: ${{ env.RUST_TOOLCHAIN }}
- # - name: Setup Rust cache
- # uses: Swatinem/rust-cache@v2
- # - name: Inject slug/short variables
- # uses: rlespinasse/github-slug-action@v3.x
- # - name: Generate template
- # run: |
- # cargo build --release --features github_ci
- # RUST_LOG=debug LOCO_CURRENT_REPOSITORY=${{ github.event.pull_request.head.repo.html_url }} LOCO_CI_MODE=true LOCO_APP_NAME=stateless_starter LOCO_TEMPLATE=stateless LOCO_BRANCH=${{ env.GITHUB_HEAD_REF_SLUG }} ./target/release/loco new
- # cd stateless_starter
- # echo "Building generate template..."
- # cargo build --release
- # echo "Run cargo test on generated template..."
- # cargo test
- # working-directory: ./loco-cli
diff --git a/.github/workflows/starter-saas.yml b/.github/workflows/starter-saas.yml
deleted file mode 100644
index a59e0be4f..000000000
--- a/.github/workflows/starter-saas.yml
+++ /dev/null
@@ -1,146 +0,0 @@
-name: "[starters/saas:ci]"
-
-on:
- push:
- branches:
- - master
- paths:
- - starters/saas/**
- pull_request:
- paths:
- - starters/saas/**
-
-env:
- RUST_TOOLCHAIN: stable
- TOOLCHAIN_PROFILE: minimal
-
-jobs:
- style:
- runs-on: ubuntu-latest
-
- permissions:
- contents: read
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: ${{ env.RUST_TOOLCHAIN }}
- components: rustfmt
- - name: Setup Rust cache
- uses: Swatinem/rust-cache@v2
- - run: cargo fmt --all -- --check
- working-directory: ./starters/saas
- - name: Run cargo clippy
- run: cargo clippy -- -W clippy::nursery -W clippy::pedantic -W rust-2018-idioms -W rust-2021-compatibility
- working-directory: ./starters/saas
-
- test:
- needs: [style]
- runs-on: ubuntu-latest
- strategy:
- matrix:
- db:
- - "postgres://postgres:postgres@localhost:5432/postgres_test"
- - "sqlite://loco_app.sqlite?mode=rwc"
-
- permissions:
- contents: read
-
- services:
- redis:
- image: redis
- options: >-
- --health-cmd "redis-cli ping"
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
- ports:
- - "6379:6379"
- postgres:
- image: postgres
- env:
- POSTGRES_DB: postgres_test
- POSTGRES_USER: postgres
- POSTGRES_PASSWORD: postgres
- ports:
- - "5432:5432"
- # Set health checks to wait until postgres has started
- options: --health-cmd pg_isready
- --health-interval 10s
- --health-timeout 5s
- --health-retries 5
-
- steps:
- - name: Checkout the code
- uses: actions/checkout@v4
- - uses: dtolnay/rust-toolchain@stable
- with:
- toolchain: ${{ env.RUST_TOOLCHAIN }}
- - name: Setup Rust cache
- uses: Swatinem/rust-cache@v2
- - name: Install seaorm cli
- run: cargo install sea-orm-cli
- - name: Run cargo test
- run: cargo loco db reset && cargo loco db entities && cargo test --all-features --all
- working-directory: ./starters/saas
- env:
- REDIS_URL: redis://localhost:${{job.services.redis.ports[6379]}}
- DATABASE_URL: ${{matrix.db}}
-
- # generate_template:
- # name: Generate Template
- # needs: [test]
- # runs-on: ubuntu-latest
-
- # permissions:
- # contents: read
-
- # services:
- # redis:
- # image: redis
- # options: >-
- # --health-cmd "redis-cli ping"
- # --health-interval 10s
- # --health-timeout 5s
- # --health-retries 5
- # ports:
- # - "6379:6379"
- # postgres:
- # image: postgres
- # env:
- # POSTGRES_DB: postgres_test
- # POSTGRES_USER: postgres
- # POSTGRES_PASSWORD: postgres
- # ports:
- # - "5432:5432"
- # # Set health checks to wait until postgres has started
- # options: --health-cmd pg_isready
- # --health-interval 10s
- # --health-timeout 5s
- # --health-retries 5
- #
- # steps:
- # - name: Checkout the code
- # uses: actions/checkout@v4
- # - uses: dtolnay/rust-toolchain@stable
- # with:
- # toolchain: ${{ env.RUST_TOOLCHAIN }}
- # - name: Setup Rust cache
- # uses: Swatinem/rust-cache@v2
- # - name: Inject slug/short variables
- # uses: rlespinasse/github-slug-action@v3.x
- # - name: Generate template
- # run: |
- # cargo build --release --features github_ci
- # RUST_LOG=debug LOCO_CURRENT_REPOSITORY=${{ github.event.pull_request.head.repo.html_url }} LOCO_CI_MODE=true LOCO_APP_NAME=saas_starter LOCO_TEMPLATE=saas LOCO_BRANCH=${{ env.GITHUB_HEAD_REF_SLUG }} ./target/release/loco new
- # cd saas_starter
- # echo "Building generate template..."
- # cargo build --release
- # echo "Run cargo test on generated template..."
- # cargo test
- # working-directory: ./loco-cli
- # env:
- # APP_REDIS_URI: redis://localhost:${{job.services.redis.ports[6379]}}
- # APP_DATABASE_URI: postgres://postgres:postgres@localhost:5432/postgres_test
diff --git a/Cargo.toml b/Cargo.toml
index ad57098a2..ab93f5e5c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -1,5 +1,5 @@
[workspace]
-members = ["xtask", "loco-gen"]
+members = ["xtask", "loco-gen", "loco-new"]
exclude = ["starters"]
[workspace.package]
@@ -138,6 +138,7 @@ english-to-cron = { version = "0.1.2" }
# bg_pg: postgres workers
sqlx = { version = "0.8.2", default-features = false, features = [
"postgres",
+ "chrono",
"sqlite",
], optional = true }
ulid = { version = "1", optional = true }
diff --git a/README-pt_BR.md b/README-pt_BR.md
index 81f2e3af6..ce34820a5 100644
--- a/README-pt_BR.md
+++ b/README-pt_BR.md
@@ -54,7 +54,7 @@ Para ver mais recursos do Loco, confira nosso [site de documentação](https://l
## Começando
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # Only when DB is needed
```
diff --git a/README-zh_CN.md b/README-zh_CN.md
index 9bc439a55..123c0e2c1 100644
--- a/README-zh_CN.md
+++ b/README-zh_CN.md
@@ -27,7 +27,7 @@ Loco 是一个用 Rust 编写的 Web 框架,类似于 Rails。Loco 提供快
通过 Cargo 安装 Loco:
```sh
-cargo install loco-cli
+cargo install loco
```
## 快速开始
diff --git a/README.fr.md b/README.fr.md
index 8c21a21db..52e55f129 100644
--- a/README.fr.md
+++ b/README.fr.md
@@ -48,7 +48,7 @@ Pour en savoir plus sur les fonctionnalités de Loco, consultez notre [site Web
## Commencez rapidement
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # Only when DB is needed
```
diff --git a/README.ja.md b/README.ja.md
index 4ab130385..4843c141e 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -47,7 +47,7 @@ Locoの詳細な機能については、[ドキュメントウェブサイト](h
## 始め方
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # データベースが必要な場合のみ
```
diff --git a/README.md b/README.md
index f445016c2..eafc5c5df 100644
--- a/README.md
+++ b/README.md
@@ -54,7 +54,7 @@ So see more Loco features, check out our [documentation website](https://loco.rs
## Getting Started
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # Only when DB is needed
```
diff --git a/docs-site/content/blog/axum-session.md b/docs-site/content/blog/axum-session.md
index 7054dcb05..95e8a21e1 100644
--- a/docs-site/content/blog/axum-session.md
+++ b/docs-site/content/blog/axum-session.md
@@ -16,7 +16,7 @@ To build a Rust app with [Axum session](https://crates.io/crates/axum_session),
Start by creating a new project and selecting the `SaaS app` template:
```sh
-$ cargo install loco-cli
+$ cargo install loco
$ loco new
✔ ❯ App name? · myapp
? ❯ What would you like to build? ›
diff --git a/docs-site/content/blog/deploy-aws.md b/docs-site/content/blog/deploy-aws.md
index 51d18f203..8752ae3ed 100644
--- a/docs-site/content/blog/deploy-aws.md
+++ b/docs-site/content/blog/deploy-aws.md
@@ -18,7 +18,7 @@ In this article, we will explore how to deploy a Rust app built with [loco](http
````sh
```sh
-$ cargo install loco-cli
+$ cargo install loco
$ loco new
✔ ❯ App name? · myapp
? ❯ What would you like to build? ›
diff --git a/docs-site/content/docs/extras/authentication.md b/docs-site/content/docs/extras/authentication.md
index 561fd5ffe..05acd694a 100644
--- a/docs-site/content/docs/extras/authentication.md
+++ b/docs-site/content/docs/extras/authentication.md
@@ -25,7 +25,7 @@ The `auth` feature comes as a default with the library. If desired, you can turn
### Getting Started with a SaaS App
-Create your app using the [loco-cli](/docs/getting-started/tour) and select the `SaaS app (with DB and user auth)` option.
+Create your app using the [loco cli](/docs/getting-started/tour) and select the `SaaS app (with DB and user auth)` option.
To explore the out-of-the-box auth controllers, run the following command:
@@ -177,7 +177,7 @@ async fn current(
### Creating new app
-For this time, let create your rest app using the [loco-cli](/docs/getting-started/tour) and select the `Rest app` option.
+For this time, let create your rest app using the [loco cli](/docs/getting-started/tour) and select the `Rest app` option.
To create new app, run the following command and follow the instructions:
```sh
diff --git a/docs-site/content/docs/getting-started/guide.md b/docs-site/content/docs/getting-started/guide.md
index cbf2c4fa8..bc4f9b813 100644
--- a/docs-site/content/docs/getting-started/guide.md
+++ b/docs-site/content/docs/getting-started/guide.md
@@ -51,7 +51,7 @@ You can follow this guide for a step-by-step "bottom up" learning, or you can ju
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # Only when DB is needed
```
diff --git a/docs-site/content/docs/getting-started/starters.md b/docs-site/content/docs/getting-started/starters.md
index 09fc01015..31ba3320e 100644
--- a/docs-site/content/docs/getting-started/starters.md
+++ b/docs-site/content/docs/getting-started/starters.md
@@ -17,7 +17,7 @@ Simplify your project setup with Loco's predefined boilerplates, designed to mak
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # Only when DB is needed
```
diff --git a/docs-site/content/docs/getting-started/tour/index.md b/docs-site/content/docs/getting-started/tour/index.md
index d99c4d46f..44aa5e4e9 100644
--- a/docs-site/content/docs/getting-started/tour/index.md
+++ b/docs-site/content/docs/getting-started/tour/index.md
@@ -18,11 +18,11 @@ flair =[]
-Let's create a blog backend on Loco in just a few minutes. First install `loco-cli` and `sea-orm-cli`:
+Let's create a blog backend on Loco in just a few minutes. First install `loco` and `sea-orm-cli`:
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # Only when DB is needed
```
@@ -165,7 +165,7 @@ $ curl localhost:5150/posts
For those counting -- the commands for creating a blog backend were:
-1. `cargo install loco-cli`
+1. `cargo install loco`
2. `cargo install sea-orm-cli`
3. `loco new`
4. `cargo loco generate scaffold post title:string content:text --api`
diff --git a/docs-site/content/docs/processing/task.md b/docs-site/content/docs/processing/task.md
index 51d88c540..114d9f582 100644
--- a/docs-site/content/docs/processing/task.md
+++ b/docs-site/content/docs/processing/task.md
@@ -32,17 +32,7 @@ Generate the task:
```sh
-Generate a Task based on the given name
-
-Usage: demo_app-cli generate task [OPTIONS]
-
-Arguments:
- Name of the thing to generate
-
-Options:
- -e, --environment Specify the environment [default: development]
- -h, --help Print help
- -V, --version Print version
+cd ./examples/demo && cargo loco generate task --help
```
diff --git a/docs-site/content/docs/the-app/your-project.md b/docs-site/content/docs/the-app/your-project.md
index 22f8082cc..9c9b52952 100644
--- a/docs-site/content/docs/the-app/your-project.md
+++ b/docs-site/content/docs/the-app/your-project.md
@@ -43,27 +43,7 @@ cargo loco --help
```sh
-The one-person framework for Rust
-
-Usage: demo_app-cli [OPTIONS]
-
-Commands:
- start Start an app
- db Perform DB operations
- routes Describe all application endpoints
- middleware Describe all application middlewares
- task Run a custom task
- scheduler Run the scheduler
- generate code generation creates a set of files and code templates based on a predefined set of rules
- doctor Validate and diagnose configurations
- version Display the app version
- watch Watch and restart the app
- help Print this message or the help of the given subcommand(s)
-
-Options:
- -e, --environment Specify the environment [default: development]
- -h, --help Print help
- -V, --version Print version
+cd ./examples/demo && cargo loco --help
```
@@ -134,22 +114,7 @@ Scaffolding is an efficient and speedy method for generating key components of a
See scaffold command:
```sh
-Generates a CRUD scaffold, model and controller
-
-Usage: demo_app-cli generate scaffold [OPTIONS] [FIELDS]...
-
-Arguments:
- Name of the thing to generate
- [FIELDS]... Model fields, eg. title:string hits:int
-
-Options:
- -k, --kind The kind of scaffold to generate [possible values: api, html, htmx]
- --htmx Use HTMX scaffold
- --html Use HTML scaffold
- --api Use API scaffold
- -e, --environment Specify the environment [default: development]
- -h, --help Print help
- -V, --version Print version
+cd ./examples/demo && cargo loco generate scaffold --help
```
diff --git a/docs-site/translations/tour-fr.md b/docs-site/translations/tour-fr.md
index 8a21b4683..1475b3921 100644
--- a/docs-site/translations/tour-fr.md
+++ b/docs-site/translations/tour-fr.md
@@ -19,11 +19,11 @@ flair =[]
-Créons un blog coté serveur sur Loco en quelques minutes. Commençons par installer `loco-cli` et `sea-orm-cli`:
+Créons un blog coté serveur sur Loco en quelques minutes. Commençons par installer `loco` et `sea-orm-cli`:
```sh
-cargo install loco-cli
+cargo install loco
cargo install sea-orm-cli # Only when DB is needed
```
@@ -146,7 +146,7 @@ $ curl localhost:5150/posts
Pour ceux qui comptent -- les commandes pour créer un backend de blog étaient:
-1. `cargo install loco-cli`
+1. `cargo install loco`
2. `cargo install sea-orm-cli`
3. `loco new`
4. `cargo loco generate scaffold post title:string content:text`
diff --git a/loco-cli/src/bin/main.rs b/loco-cli/src/bin/main.rs
index 44deca9b0..866473bd5 100644
--- a/loco-cli/src/bin/main.rs
+++ b/loco-cli/src/bin/main.rs
@@ -51,6 +51,17 @@ enum Commands {
}
#[allow(clippy::unnecessary_wraps)]
fn main() -> eyre::Result<()> {
+ println!("");
+ println!("");
+ println!("!!!!!");
+ println!("!!!!! NOTE: `loco-cli` is now replaced with `loco` which is a much more powerful ");
+ println!("!!!!! and flexible new app creator for Loco. To install the new CLI run:");
+ println!("!!!!!");
+ println!("!!!!! $ cargo uninstall loco-cli && cargo install loco");
+ println!("!!!!!");
+ println!("");
+ println!("");
+ println!("");
let cli = Cli::parse();
tracing_subscriber::fmt()
diff --git a/loco-gen/src/model.rs b/loco-gen/src/model.rs
index 0d70c1100..0e1a74041 100644
--- a/loco-gen/src/model.rs
+++ b/loco-gen/src/model.rs
@@ -108,22 +108,20 @@ mod tests {
where
F: FnOnce(),
{
- testutil::with_temp_dir(|previous, current| {
+ testutil::with_temp_dir(|_previous, current| {
let status = Command::new("loco")
.args([
"new",
"-n",
app_name,
- "-t",
- "saas",
"--db",
"sqlite",
"--bg",
"async",
"--assets",
"serverside",
+ "-a",
])
- .env("STARTERS_LOCAL_PATH", previous.join("../"))
.status()
.expect("cannot run command");
diff --git a/loco-new/Cargo.toml b/loco-new/Cargo.toml
new file mode 100644
index 000000000..f2f71e97c
--- /dev/null
+++ b/loco-new/Cargo.toml
@@ -0,0 +1,52 @@
+[package]
+name = "loco"
+version = "0.2.10"
+edition = "2021"
+description = "Loco new app generator"
+license = "Apache-2.0"
+homepage = "https://docs.rs/loco"
+documentation = "https://docs.rs/loco"
+authors = ["Dotan Nahum ", "Elad Kaplan "]
+
+[features]
+test-wizard = []
+
+[profile.release]
+strip = true
+
+[[bin]]
+name = "loco"
+path = "src/bin/main.rs"
+required-features = []
+
+
+[dependencies]
+thiserror = { version = "1.0.63" }
+clap = { version = "4.4.7", features = ["derive"] }
+serde = { version = "1", features = ["derive"] }
+serde_json = { version = "1.0" }
+serde_variant = { version = "0.1.3" }
+tracing = { version = "0.1.40" }
+tracing-subscriber = { version = "0.3.16", features = ["env-filter"] }
+heck = { version = "0.5.0" }
+dialoguer = "0.11.0"
+strum = { version = "0.26", features = ["derive"] }
+unicode-xid = { version = "0.2.6" }
+rhai = { version = "1.20.0" }
+include_dir = { version = "0.7.4" }
+fs_extra = { version = "1.3.0" }
+walkdir = { version = "2.5.0" }
+tera = { version = "1.20.0" }
+colored = { version = "2" }
+duct = { version = "0.13.6" }
+rand = { version = "0.8.5" }
+
+[dev-dependencies]
+uuid = { version = "1.11.0", features = ["v4", "fast-rng"] }
+serde_yaml = { version = "0.9" }
+insta = { version = "1.41.1", features = ["redactions", "yaml", "filters"] }
+rstest = { version = "0.23.0" }
+tree-fs = "0.2.0"
+mockall = "0.13.0"
+toml = "0.8.19"
+regex = "1.11.1"
diff --git a/loco-new/base_template/.cargo/config.toml b/loco-new/base_template/.cargo/config.toml
new file mode 100644
index 000000000..fb921ea85
--- /dev/null
+++ b/loco-new/base_template/.cargo/config.toml
@@ -0,0 +1,4 @@
+[alias]
+loco = "run --"
+loco-tool = "run --bin tool --"
+playground = "run --example playground"
diff --git a/loco-new/base_template/.github/workflows/ci.yaml b/loco-new/base_template/.github/workflows/ci.yaml
new file mode 100644
index 000000000..75ba8a5e3
--- /dev/null
+++ b/loco-new/base_template/.github/workflows/ci.yaml
@@ -0,0 +1,102 @@
+name: CI
+on:
+ push:
+ branches:
+ - master
+ - main
+ pull_request:
+
+env:
+ RUST_TOOLCHAIN: stable
+ TOOLCHAIN_PROFILE: minimal
+
+jobs:
+ rustfmt:
+ name: Check Style
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout the code
+ uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: ${{ env.RUST_TOOLCHAIN }}
+ components: rustfmt
+ - name: Run cargo fmt
+ uses: actions-rs/cargo@v1
+ with:
+ command: fmt
+ args: --all -- --check
+
+ clippy:
+ name: Run Clippy
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+
+ steps:
+ - name: Checkout the code
+ uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: ${{ env.RUST_TOOLCHAIN }}
+ - name: Setup Rust cache
+ uses: Swatinem/rust-cache@v2
+ - name: Run cargo clippy
+ uses: actions-rs/cargo@v1
+ with:
+ command: clippy
+ args: --all-features -- -D warnings -W clippy::pedantic -W clippy::nursery -W rust-2018-idioms
+
+ test:
+ name: Run Tests
+ runs-on: ubuntu-latest
+
+ permissions:
+ contents: read
+
+ services:
+ redis:
+ image: redis
+ options: >-
+ --health-cmd "redis-cli ping"
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+ ports:
+ - "6379:6379"
+ postgres:
+ image: postgres
+ env:
+ POSTGRES_DB: postgres_test
+ POSTGRES_USER: postgres
+ POSTGRES_PASSWORD: postgres
+ ports:
+ - "5432:5432"
+ # Set health checks to wait until postgres has started
+ options: --health-cmd pg_isready
+ --health-interval 10s
+ --health-timeout 5s
+ --health-retries 5
+
+ steps:
+ - name: Checkout the code
+ uses: actions/checkout@v4
+ - uses: dtolnay/rust-toolchain@stable
+ with:
+ toolchain: ${{ env.RUST_TOOLCHAIN }}
+ - name: Setup Rust cache
+ uses: Swatinem/rust-cache@v2
+ - name: Run cargo test
+ uses: actions-rs/cargo@v1
+ with:
+ command: test
+ args: --all-features --all
+ env:
+ REDIS_URL: redis://localhost:${{job.services.redis.ports[6379]}}
+ DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres_test
+
diff --git a/loco-new/base_template/.gitignore b/loco-new/base_template/.gitignore
new file mode 100644
index 000000000..d83d21a83
--- /dev/null
+++ b/loco-new/base_template/.gitignore
@@ -0,0 +1,19 @@
+**/config/local.yaml
+**/config/*.local.yaml
+**/config/production.yaml
+
+# Generated by Cargo
+# will have compiled files and executables
+debug/
+target/
+
+# include cargo lock
+!Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
+
+*.sqlite
\ No newline at end of file
diff --git a/loco-new/base_template/.rustfmt.toml b/loco-new/base_template/.rustfmt.toml
new file mode 100644
index 000000000..d862e0810
--- /dev/null
+++ b/loco-new/base_template/.rustfmt.toml
@@ -0,0 +1,2 @@
+max_width = 100
+use_small_heuristics = "Default"
diff --git a/loco-new/base_template/Cargo.toml.t b/loco-new/base_template/Cargo.toml.t
new file mode 100644
index 000000000..d449a99c9
--- /dev/null
+++ b/loco-new/base_template/Cargo.toml.t
@@ -0,0 +1,70 @@
+{%- set_global feature_list = [] -%}
+{%- if settings.features.names | length > 0 -%}
+ {%- for name in settings.features.names -%}
+ {%- set_global feature_list = feature_list | concat(with=['"' ~ name ~ '"']) -%}
+ {%- endfor -%}
+{%- endif -%}
+[workspace]
+
+[package]
+name = "{{settings.package_name}}"
+version = "0.1.0"
+edition = "2021"
+publish = false
+default-run = "{{settings.module_name}}-cli"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[workspace.dependencies]
+loco-rs = { {{settings.loco_version_text}} {%- if not settings.features.default_features %}, default-features = false {%- endif %} }
+
+[dependencies]
+loco-rs = { workspace = true {% if feature_list | length > 0 %}, features = {{feature_list}}{% endif %} }
+serde = { version = "1", features = ["derive"] }
+serde_json = "1"
+tokio = { version = "1.33.0", default-features = false, features = [
+ "rt-multi-thread",
+] }
+async-trait = "0.1.74"
+axum = "0.7.5"
+tracing = "0.1.40"
+tracing-subscriber = { version = "0.3.17", features = ["env-filter", "json"] }
+{%- if settings.db %}
+migration = { path = "migration" }
+sea-orm = { version = "1.1.0", features = [
+ "sqlx-sqlite",
+ "sqlx-postgres",
+ "runtime-tokio-rustls",
+ "macros",
+] }
+chrono = "0.4"
+validator = { version = "0.18" }
+uuid = { version = "1.6.0", features = ["v4"] }
+{%- endif %}
+
+{%- if settings.mailer %}
+include_dir = "0.7"
+{%- endif %}
+
+{%- if settings.asset %}
+# view engine i18n
+fluent-templates = { version = "0.8.0", features = ["tera"] }
+unic-langid = "0.9.4"
+# /view engine
+{%- endif %}
+
+[[bin]]
+name = "{{settings.module_name}}-cli"
+path = "src/bin/main.rs"
+required-features = []
+
+[[bin]]
+name = "tool"
+path = "src/bin/tool.rs"
+required-features = []
+
+[dev-dependencies]
+loco-rs = { workspace = true, features = ["testing"] }
+serial_test = "3.1.1"
+rstest = "0.21.0"
+insta = { version = "1.34.0", features = ["redactions", "yaml", "filters"] }
diff --git a/loco-new/base_template/README.md b/loco-new/base_template/README.md
new file mode 100644
index 000000000..43b9bddaa
--- /dev/null
+++ b/loco-new/base_template/README.md
@@ -0,0 +1,58 @@
+# Welcome to Loco :train:
+
+[Loco](https://loco.rs) is a web and API framework running on Rust.
+
+This is the **SaaS starter** which includes a `User` model and authentication based on JWT.
+It also include configuration sections that help you pick either a frontend or a server-side template set up for your fullstack server.
+
+
+## Quick Start
+
+```sh
+cargo loco start
+```
+
+```sh
+$ cargo loco start
+Finished dev [unoptimized + debuginfo] target(s) in 21.63s
+ Running `target/debug/myapp start`
+
+ :
+ :
+ :
+
+controller/app_routes.rs:203: [Middleware] Adding log trace id
+
+ ▄ ▀
+ ▀ ▄
+ ▄ ▀ ▄ ▄ ▄▀
+ ▄ ▀▄▄
+ ▄ ▀ ▀ ▀▄▀█▄
+ ▀█▄
+▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄▄▄ ▄▄▄▄▄▄▄▄▄ ▀▀█
+ ██████ █████ ███ █████ ███ █████ ███ ▀█
+ ██████ █████ ███ █████ ▀▀▀ █████ ███ ▄█▄
+ ██████ █████ ███ █████ █████ ███ ████▄
+ ██████ █████ ███ █████ ▄▄▄ █████ ███ █████
+ ██████ █████ ███ ████ ███ █████ ███ ████▀
+ ▀▀▀██▄ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ▀▀▀▀▀▀▀▀▀▀ ██▀
+ ▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀
+ https://loco.rs
+
+environment: development
+ database: automigrate
+ logger: debug
+compilation: debug
+ modes: server
+
+listening on http://localhost:5150
+```
+
+## Full Stack Serving
+
+You can check your [configuration](config/development.yaml) to pick either frontend setup or server-side rendered template, and activate the relevant configuration sections.
+
+
+## Getting help
+
+Check out [a quick tour](https://loco.rs/docs/getting-started/tour/) or [the complete guide](https://loco.rs/docs/getting-started/guide/).
diff --git a/loco-new/base_template/assets/i18n/de-DE/main.ftl b/loco-new/base_template/assets/i18n/de-DE/main.ftl
new file mode 100644
index 000000000..ced609fe4
--- /dev/null
+++ b/loco-new/base_template/assets/i18n/de-DE/main.ftl
@@ -0,0 +1,4 @@
+hello-world = Hallo Welt!
+greeting = Hallochen { $name }!
+ .placeholder = Hallo Freund!
+about = Uber
diff --git a/loco-new/base_template/assets/i18n/en-US/main.ftl b/loco-new/base_template/assets/i18n/en-US/main.ftl
new file mode 100644
index 000000000..9d4d5e7c4
--- /dev/null
+++ b/loco-new/base_template/assets/i18n/en-US/main.ftl
@@ -0,0 +1,10 @@
+hello-world = Hello World!
+greeting = Hello { $name }!
+ .placeholder = Hello Friend!
+about = About
+simple = simple text
+reference = simple text with a reference: { -something }
+parameter = text with a { $param }
+parameter2 = text one { $param } second { $multi-word-param }
+email = text with an EMAIL("example@example.org")
+fallback = this should fall back
diff --git a/loco-new/base_template/assets/i18n/shared.ftl b/loco-new/base_template/assets/i18n/shared.ftl
new file mode 100644
index 000000000..f169eca9d
--- /dev/null
+++ b/loco-new/base_template/assets/i18n/shared.ftl
@@ -0,0 +1 @@
+-something = foo
diff --git a/loco-new/base_template/assets/static/404.html b/loco-new/base_template/assets/static/404.html
new file mode 100644
index 000000000..66e78fb22
--- /dev/null
+++ b/loco-new/base_template/assets/static/404.html
@@ -0,0 +1,3 @@
+
+not found :-(
+
diff --git a/loco-new/base_template/assets/static/image.png b/loco-new/base_template/assets/static/image.png
new file mode 100644
index 000000000..fa5a09508
Binary files /dev/null and b/loco-new/base_template/assets/static/image.png differ
diff --git a/loco-new/base_template/assets/views/home/hello.html b/loco-new/base_template/assets/views/home/hello.html
new file mode 100644
index 000000000..6b97c398e
--- /dev/null
+++ b/loco-new/base_template/assets/views/home/hello.html
@@ -0,0 +1,12 @@
+
+
+
+ find this tera template at assets/views/home/hello.html:
+
+
+ {{ t(key="hello-world", lang="en-US") }},
+
+ {{ t(key="hello-world", lang="de-DE") }}
+
+
+
\ No newline at end of file
diff --git a/loco-new/base_template/config/development.yaml.t b/loco-new/base_template/config/development.yaml.t
new file mode 100644
index 000000000..44ba73f03
--- /dev/null
+++ b/loco-new/base_template/config/development.yaml.t
@@ -0,0 +1,129 @@
+# Loco configuration file documentation
+
+# Application logging configuration
+logger:
+ # Enable or disable logging.
+ enable: true
+ # Enable pretty backtrace (sets RUST_BACKTRACE=1)
+ pretty_backtrace: true
+ # Log level, options: trace, debug, info, warn or error.
+ level: debug
+ # Define the logging format. options: compact, pretty or json
+ format: compact
+ # By default the logger has filtering only logs that came from your code or logs that came from `loco` framework. to see all third party libraries
+ # Uncomment the line below to override to see all third party libraries you can enable this config and override the logger filters.
+ # override_filter: trace
+
+# Web server configuration
+server:
+ # Port on which the server will listen. the server binding is 0.0.0.0:{PORT}
+ port: 5150
+ # The UI hostname or IP address that mailers will point to.
+ host: http://localhost
+ # Out of the box middleware configuration. to disable middleware you can changed the `enable` field to `false` of comment the middleware block
+ middlewares:
+ {%- if settings.asset %}
+ {%- if settings.asset.kind == "server" %}
+ static:
+ enable: true
+ must_exist: true
+ precompressed: false
+ folder:
+ uri: "/static"
+ path: "assets/static"
+ fallback: "assets/static/404.html"
+ {%- elif settings.asset.kind == "client" %}
+ static:
+ enable: true
+ must_exist: true
+ precompressed: false
+ folder:
+ uri: "/"
+ path: "frontend/dist"
+ fallback: "frontend/dist/index.html"
+ {%- endif -%}
+
+ {%- endif -%}
+
+{%- if settings.background%}
+
+# Worker Configuration
+workers:
+ # specifies the worker mode. Options:
+ # - BackgroundQueue - Workers operate asynchronously in the background, processing queued.
+ # - ForegroundBlocking - Workers operate in the foreground and block until tasks are completed.
+ # - BackgroundAsync - Workers operate asynchronously in the background, processing tasks with async capabilities.
+ mode: {{settings.background.kind}}
+
+ {% if settings.background.kind == "BackgroundQueue"%}
+# Queue Configuration
+queue:
+ kind: Redis
+ # Redis connection URI
+ uri: {% raw %}{{{% endraw %} get_env(name="REDIS_URL", default="redis://127.0.0.1") {% raw %}}}{% endraw %}
+ # Dangerously flush all data in Redis on startup. dangerous operation, make sure that you using this flag only on dev environments or test mode
+ dangerously_flush: false
+ {%- endif %}
+{%- endif -%}
+
+{%- if settings.mailer %}
+
+# Mailer Configuration.
+mailer:
+ # SMTP mailer configuration.
+ smtp:
+ # Enable/Disable smtp mailer.
+ enable: true
+ # SMTP server host. e.x localhost, smtp.gmail.com
+ host: {{ get_env(name="MAILER_HOST", default="localhost") }}
+ # SMTP server port
+ port: 1025
+ # Use secure connection (SSL/TLS).
+ secure: false
+ # auth:
+ # user:
+ # password:
+{%- endif %}
+
+# Initializers Configuration
+# initializers:
+# oauth2:
+# authorization_code: # Authorization code grant type
+# - client_identifier: google # Identifier for the OAuth2 provider. Replace 'google' with your provider's name if different, must be unique within the oauth2 config.
+# ... other fields
+
+{%- if settings.db %}
+
+# Database Configuration
+database:
+ # Database connection URI
+ uri: {% raw %}{{{% endraw %} get_env(name="DATABASE_URL", default="{{settings.db.endpoint}}") {% raw %}}}{% endraw %}
+ # When enabled, the sql query will be logged.
+ enable_logging: false
+ # Set the timeout duration when acquiring a connection.
+ connect_timeout: {% raw %}{{{% endraw %} get_env(name="DB_CONNECT_TIMEOUT", default="500") {% raw %}}}{% endraw %}
+ # Set the idle duration before closing a connection.
+ idle_timeout: {% raw %}{{{% endraw %} get_env(name="DB_IDLE_TIMEOUT", default="500") {% raw %}}}{% endraw %}
+ # Minimum number of connections for a pool.
+ min_connections: {% raw %}{{{% endraw %} get_env(name="DB_MIN_CONNECTIONS", default="1") {% raw %}}}{% endraw %}
+ # Maximum number of connections for a pool.
+ max_connections: {% raw %}{{{% endraw %} get_env(name="DB_MAX_CONNECTIONS", default="1") {% raw %}}}{% endraw %}
+ # Run migration up when application loaded
+ auto_migrate: true
+ # Truncate database when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode
+ dangerously_truncate: false
+ # Recreating schema when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode
+ dangerously_recreate: false
+{%- endif %}
+
+{%- if settings.auth %}
+
+# Authentication Configuration
+auth:
+ # JWT authentication
+ jwt:
+ # Secret key for token generation and verification
+ secret: {{20 | random_string }}
+ # Token expiration time in seconds
+ expiration: 604800 # 7 days
+{%- endif %}
diff --git a/loco-new/base_template/config/production.yaml b/loco-new/base_template/config/production.yaml
new file mode 100644
index 000000000..e69de29bb
diff --git a/loco-new/base_template/config/test.yaml.t b/loco-new/base_template/config/test.yaml.t
new file mode 100644
index 000000000..dcc902fc7
--- /dev/null
+++ b/loco-new/base_template/config/test.yaml.t
@@ -0,0 +1,129 @@
+# Loco configuration file documentation
+
+# Application logging configuration
+logger:
+ # Enable or disable logging.
+ enable: false
+ # Enable pretty backtrace (sets RUST_BACKTRACE=1)
+ pretty_backtrace: true
+ # Log level, options: trace, debug, info, warn or error.
+ level: debug
+ # Define the logging format. options: compact, pretty or json
+ format: compact
+ # By default the logger has filtering only logs that came from your code or logs that came from `loco` framework. to see all third party libraries
+ # Uncomment the line below to override to see all third party libraries you can enable this config and override the logger filters.
+ # override_filter: trace
+
+# Web server configuration
+server:
+ # Port on which the server will listen. the server binding is 0.0.0.0:{PORT}
+ port: 5150
+ # The UI hostname or IP address that mailers will point to.
+ host: http://localhost
+ # Out of the box middleware configuration. to disable middleware you can changed the `enable` field to `false` of comment the middleware block
+ middlewares:
+ {%- if settings.asset %}
+ {%- if settings.asset.kind == "server" %}
+ static:
+ enable: true
+ must_exist: true
+ precompressed: false
+ folder:
+ uri: "/static"
+ path: "assets/static"
+ fallback: "assets/static/404.html"
+ {%- elif settings.asset.kind == "client" %}
+ static:
+ enable: true
+ must_exist: true
+ precompressed: false
+ folder:
+ uri: "/"
+ path: "frontend/dist"
+ fallback: "frontend/dist/index.html"
+ {%- endif -%}
+
+ {%- endif -%}
+
+{%- if settings.background%}
+
+# Worker Configuration
+workers:
+ # specifies the worker mode. Options:
+ # - BackgroundQueue - Workers operate asynchronously in the background, processing queued.
+ # - ForegroundBlocking - Workers operate in the foreground and block until tasks are completed.
+ # - BackgroundAsync - Workers operate asynchronously in the background, processing tasks with async capabilities.
+ mode: {{settings.background.kind}}
+
+ {% if settings.background.kind == "BackgroundQueue"%}
+# Queue Configuration
+queue:
+ kind: Redis
+ # Redis connection URI
+ uri: {% raw %}{{{% endraw %} get_env(name="REDIS_URL", default="redis://127.0.0.1") {% raw %}}}{% endraw %}
+ # Dangerously flush all data in Redis on startup. dangerous operation, make sure that you using this flag only on dev environments or test mode
+ dangerously_flush: false
+ {%- endif %}
+{%- endif -%}
+
+{%- if settings.mailer %}
+
+# Mailer Configuration.
+mailer:
+ # SMTP mailer configuration.
+ smtp:
+ # Enable/Disable smtp mailer.
+ enable: true
+ # SMTP server host. e.x localhost, smtp.gmail.com
+ host: {{ get_env(name="MAILER_HOST", default="localhost") }}
+ # SMTP server port
+ port: 1025
+ # Use secure connection (SSL/TLS).
+ secure: false
+ # auth:
+ # user:
+ # password:
+{%- endif %}
+
+# Initializers Configuration
+# initializers:
+# oauth2:
+# authorization_code: # Authorization code grant type
+# - client_identifier: google # Identifier for the OAuth2 provider. Replace 'google' with your provider's name if different, must be unique within the oauth2 config.
+# ... other fields
+
+{%- if settings.db %}
+
+# Database Configuration
+database:
+ # Database connection URI
+ uri: {% raw %}{{{% endraw %} get_env(name="DATABASE_URL", default="{{settings.db.endpoint}}") {% raw %}}}{% endraw %}
+ # When enabled, the sql query will be logged.
+ enable_logging: false
+ # Set the timeout duration when acquiring a connection.
+ connect_timeout: {% raw %}{{{% endraw %} get_env(name="DB_CONNECT_TIMEOUT", default="500") {% raw %}}}{% endraw %}
+ # Set the idle duration before closing a connection.
+ idle_timeout: {% raw %}{{{% endraw %} get_env(name="DB_IDLE_TIMEOUT", default="500") {% raw %}}}{% endraw %}
+ # Minimum number of connections for a pool.
+ min_connections: {% raw %}{{{% endraw %} get_env(name="DB_MIN_CONNECTIONS", default="1") {% raw %}}}{% endraw %}
+ # Maximum number of connections for a pool.
+ max_connections: {% raw %}{{{% endraw %} get_env(name="DB_MAX_CONNECTIONS", default="1") {% raw %}}}{% endraw %}
+ # Run migration up when application loaded
+ auto_migrate: true
+ # Truncate database when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode
+ dangerously_truncate: true
+ # Recreating schema when application loaded. This is a dangerous operation, make sure that you using this flag only on dev environments or test mode
+ dangerously_recreate: false
+{%- endif %}
+
+{%- if settings.auth %}
+
+# Authentication Configuration
+auth:
+ # JWT authentication
+ jwt:
+ # Secret key for token generation and verification
+ secret: {{20 | random_string }}
+ # Token expiration time in seconds
+ expiration: 604800 # 7 days
+{%- endif %}
diff --git a/loco-new/base_template/examples/playground.rs.t b/loco-new/base_template/examples/playground.rs.t
new file mode 100644
index 000000000..2a2c362fd
--- /dev/null
+++ b/loco-new/base_template/examples/playground.rs.t
@@ -0,0 +1,21 @@
+#[allow(unused_imports)]
+use loco_rs::{cli::playground, prelude::*};
+use {{settings.module_name}}::app::App;
+
+#[tokio::main]
+async fn main() -> loco_rs::Result<()> {
+ let _ctx = playground::().await?;
+
+ // let active_model: articles::ActiveModel = ActiveModel {
+ // title: Set(Some("how to build apps in 3 steps".to_string())),
+ // content: Set(Some("use Loco: https://loco.rs".to_string())),
+ // ..Default::default()
+ // };
+ // active_model.insert(&ctx.db).await.unwrap();
+
+ // let res = articles::Entity::find().all(&ctx.db).await.unwrap();
+ // println!("{:?}", res);
+ println!("welcome to playground. edit me at `examples/playground.rs`");
+
+ Ok(())
+}
diff --git a/loco-new/base_template/frontend/.gitignore b/loco-new/base_template/frontend/.gitignore
new file mode 100644
index 000000000..a1dccae53
--- /dev/null
+++ b/loco-new/base_template/frontend/.gitignore
@@ -0,0 +1,31 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+lerna-debug.log*
+
+node_modules
+dist-ssr
+dist/
+*.local
+
+# Editor directories and files
+.vscode/*
+!.vscode/extensions.json
+.idea
+.DS_Store
+*.suo
+*.ntvs*
+*.njsproj
+*.sln
+*.sw?
+
+# Common local dotenv files popularised by Create React App & Next.js
+# https://rsbuild.dev/guide/advanced/env-vars#env-file
+.env.local
+.env.development.local
+.env.production.local
+.env.test.local
diff --git a/loco-new/base_template/frontend/README.md b/loco-new/base_template/frontend/README.md
new file mode 100644
index 000000000..9fd9aed41
--- /dev/null
+++ b/loco-new/base_template/frontend/README.md
@@ -0,0 +1,42 @@
+# SaaS Frontend
+
+## Batteries included
+
+- [TypeScript](https://www.typescriptlang.org/): A typed superset of JavaScript
+- [Rsbuild](https://rsbuild.dev/): A Rust-based web build tool
+- [Biome](https://biomejs.dev/): A Rust-based formatter and sensible linter for the web
+- [React](https://reactjs.org/): A JavaScript library for building user interfaces
+
+If you don't like React for some reason, Rsbuild makes it easy to replace it with something else!
+
+# Development
+
+To get started with the development of the SaaS frontend, follow these steps:
+
+### 1. Install Packages
+
+Use the following command to install the required packages using pnpm:
+
+```sh
+pnpm install
+```
+
+### 2. Run in Development Mode
+
+Once the packages are installed, run your frontend application in development mode with the following command:
+
+```sh
+pnpm dev
+```
+
+This will start the development frontend server serving via vit
+
+### 3. Build The application
+
+To build your application run the following command:
+
+```sh
+pnpm build
+```
+
+After the build `dist` folder is ready to served by loco. run loco `cargo loco start` and the frontend application will served via Loco
\ No newline at end of file
diff --git a/loco-new/base_template/frontend/biome.json b/loco-new/base_template/frontend/biome.json
new file mode 100644
index 000000000..0dd32511a
--- /dev/null
+++ b/loco-new/base_template/frontend/biome.json
@@ -0,0 +1,24 @@
+{
+ "$schema": "https://biomejs.dev/schemas/1.8.2/schema.json",
+ "organizeImports": {
+ "enabled": true
+ },
+ "linter": {
+ "enabled": true,
+ "rules": {
+ "recommended": true
+ }
+ },
+ "javascript": {
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "space"
+ }
+ },
+ "json": {
+ "formatter": {
+ "enabled": true,
+ "indentStyle": "space"
+ }
+ }
+}
diff --git a/loco-new/base_template/frontend/package.json b/loco-new/base_template/frontend/package.json
new file mode 100644
index 000000000..dd7a791da
--- /dev/null
+++ b/loco-new/base_template/frontend/package.json
@@ -0,0 +1,24 @@
+{
+ "name": "frontend",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "rsbuild dev --open",
+ "build": "rsbuild build",
+ "lint": "biome check src/",
+ "preview": "rsbuild preview"
+ },
+ "dependencies": {
+ "react": "^18",
+ "react-dom": "^18"
+ },
+ "devDependencies": {
+ "@biomejs/biome": "^1",
+ "@rsbuild/core": "^1",
+ "@rsbuild/plugin-react": "^1",
+ "@types/react": "^18",
+ "@types/react-dom": "^18",
+ "typescript": "^5"
+ }
+}
diff --git a/loco-new/base_template/frontend/rsbuild.config.ts b/loco-new/base_template/frontend/rsbuild.config.ts
new file mode 100644
index 000000000..d86582c5d
--- /dev/null
+++ b/loco-new/base_template/frontend/rsbuild.config.ts
@@ -0,0 +1,20 @@
+import { defineConfig } from "@rsbuild/core";
+import { pluginReact } from "@rsbuild/plugin-react";
+
+// https://rsbuild.dev/guide/basic/configure-rsbuild
+export default defineConfig({
+ plugins: [pluginReact()],
+ html: {
+ favicon: "src/assets/favicon.ico",
+ title: "Loco SaaS Starter",
+ },
+ server: {
+ proxy: {
+ "/api": {
+ target: "http://127.0.0.1:5150",
+ changeOrigin: true,
+ secure: false,
+ },
+ },
+ },
+});
diff --git a/loco-new/base_template/frontend/src/LocoSplash.tsx b/loco-new/base_template/frontend/src/LocoSplash.tsx
new file mode 100644
index 000000000..cb96ace54
--- /dev/null
+++ b/loco-new/base_template/frontend/src/LocoSplash.tsx
@@ -0,0 +1,105 @@
+export const LocoSplash = () => {
+ return (
+