@brendanbank/create-atrium-host 0.18.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/cli.js +1 -1
- package/template/.github/workflows/ci.yml +2 -2
- package/template/Dockerfile +5 -4
- package/template/README.md +1 -1
- package/template/backend/src/__HOST_PKG__/router.py +8 -6
- package/template/backend/tests/test_smoke.py +2 -2
- package/template/frontend/src/api.ts +5 -3
package/README.md
CHANGED
|
@@ -28,7 +28,7 @@ npx @brendanbank/create-atrium-host test-host --yes-defaults
|
|
|
28
28
|
| `--yes-defaults` | Skip prompts; derive everything from the project name |
|
|
29
29
|
| `--no-git` | Skip `git init` + initial commit |
|
|
30
30
|
| `--out <dir>` | Output directory (default: `./<name>`) |
|
|
31
|
-
| `--atrium <version>` | Atrium image / SDK version pin (default: `0.
|
|
31
|
+
| `--atrium <version>` | Atrium image / SDK version pin (default: `0.19`) |
|
|
32
32
|
| `-h`, `--help` | Show help |
|
|
33
33
|
|
|
34
34
|
## What it emits
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brendanbank/create-atrium-host",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Scaffolder for new atrium host extensions: backend Python package + frontend Vite bundle + compose stack + CI, all wired against atrium's published image and host SDK packages. Run via `npx @brendanbank/create-atrium-host <name>`.",
|
|
5
5
|
"license": "BSD-2-Clause",
|
|
6
6
|
"type": "module",
|
package/src/cli.js
CHANGED
|
@@ -37,7 +37,7 @@ const TEMPLATE_DIR = resolve(__dirname, '..', 'template');
|
|
|
37
37
|
// The atrium image + SDK packages version in lockstep. Bump this when
|
|
38
38
|
// cutting a new atrium release so freshly scaffolded hosts pin against
|
|
39
39
|
// the right line.
|
|
40
|
-
const DEFAULT_ATRIUM_VERSION = '0.
|
|
40
|
+
const DEFAULT_ATRIUM_VERSION = '0.19';
|
|
41
41
|
|
|
42
42
|
const HELP = `
|
|
43
43
|
${kleur.bold('create-atrium-host')} — scaffold a new atrium host extension
|
|
@@ -47,7 +47,7 @@ jobs:
|
|
|
47
47
|
|
|
48
48
|
smoke:
|
|
49
49
|
# Stand up the full stack (atrium image + this host extension on
|
|
50
|
-
# top), run migrations, seed an admin, hit /readyz. Catches the
|
|
50
|
+
# top), run migrations, seed an admin, hit /api/readyz. Catches the
|
|
51
51
|
# bootstrap-time failures (missing env, broken init_app, alembic
|
|
52
52
|
# chain mismatch) the frontend job won't see.
|
|
53
53
|
runs-on: ubuntu-latest
|
|
@@ -82,7 +82,7 @@ jobs:
|
|
|
82
82
|
- name: Wait for API
|
|
83
83
|
run: |
|
|
84
84
|
for i in $(seq 1 40); do
|
|
85
|
-
if curl -fsS http://localhost:8000/readyz > /dev/null; then exit 0; fi
|
|
85
|
+
if curl -fsS http://localhost:8000/api/readyz > /dev/null; then exit 0; fi
|
|
86
86
|
sleep 3
|
|
87
87
|
done
|
|
88
88
|
echo "API did not become ready" >&2
|
package/template/Dockerfile
CHANGED
|
@@ -18,7 +18,7 @@ COPY frontend/package.json frontend/pnpm-lock.yaml* ./
|
|
|
18
18
|
RUN pnpm install --frozen-lockfile 2>/dev/null || pnpm install
|
|
19
19
|
COPY frontend/ ./
|
|
20
20
|
|
|
21
|
-
ARG VITE_API_BASE_URL=""
|
|
21
|
+
ARG VITE_API_BASE_URL="/api"
|
|
22
22
|
ENV VITE_API_BASE_URL=${VITE_API_BASE_URL}
|
|
23
23
|
RUN pnpm build
|
|
24
24
|
|
|
@@ -40,7 +40,8 @@ COPY --from=frontend-builder /app/dist /opt/atrium/static/host
|
|
|
40
40
|
USER app
|
|
41
41
|
|
|
42
42
|
# Re-declare HEALTHCHECK on the derived image. The base atrium image
|
|
43
|
-
# already ships one (curl /healthz on :8000), but image scanners
|
|
44
|
-
# absence at the leaf Dockerfile because they don't trace
|
|
43
|
+
# already ships one (curl /api/healthz on :8000), but image scanners
|
|
44
|
+
# flag absence at the leaf Dockerfile because they don't trace
|
|
45
|
+
# inheritance.
|
|
45
46
|
HEALTHCHECK --interval=30s --timeout=5s --start-period=30s --retries=3 \
|
|
46
|
-
CMD curl -fsS http://localhost:8000/healthz || exit 1
|
|
47
|
+
CMD curl -fsS http://localhost:8000/api/healthz || exit 1
|
package/template/README.md
CHANGED
|
@@ -114,7 +114,7 @@ make typecheck # tsc --noEmit on the host bundle
|
|
|
114
114
|
against a specific release:
|
|
115
115
|
|
|
116
116
|
```bash
|
|
117
|
-
ATRIUM_IMAGE=ghcr.io/brendanbank/atrium:0.
|
|
117
|
+
ATRIUM_IMAGE=ghcr.io/brendanbank/atrium:0.19.1 make build up
|
|
118
118
|
```
|
|
119
119
|
|
|
120
120
|
The frontend SDK packages
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"""Demo HTTP surface.
|
|
2
2
|
|
|
3
|
-
- ``GET /__HOST_PKG__/state`` — read-only, auth required.
|
|
4
|
-
- ``POST /__HOST_PKG__/bump`` — gated by ``__HOST_PKG__.write``,
|
|
3
|
+
- ``GET /api/__HOST_PKG__/state`` — read-only, auth required.
|
|
4
|
+
- ``POST /api/__HOST_PKG__/bump`` — gated by ``__HOST_PKG__.write``,
|
|
5
5
|
increments the demo counter and writes an audit row.
|
|
6
6
|
|
|
7
|
-
Replace these with your real routes.
|
|
8
|
-
|
|
9
|
-
host
|
|
7
|
+
Replace these with your real routes. Atrium mounts every JSON route
|
|
8
|
+
under ``/api/...`` so the SPA owns un-prefixed URL space (atrium
|
|
9
|
+
issue #89); host routes follow the same contract. The auth
|
|
10
|
+
dependencies and the audit/notify helpers (imported from ``app.*``)
|
|
11
|
+
are the surface a host calls atrium through.
|
|
10
12
|
"""
|
|
11
13
|
from __future__ import annotations
|
|
12
14
|
|
|
@@ -23,7 +25,7 @@ from app.services.audit import record as record_audit
|
|
|
23
25
|
|
|
24
26
|
from .models import __BRAND_PASCAL__State
|
|
25
27
|
|
|
26
|
-
router = APIRouter(prefix="/__HOST_PKG__", tags=["__HOST_PKG__"])
|
|
28
|
+
router = APIRouter(prefix="/api/__HOST_PKG__", tags=["__HOST_PKG__"])
|
|
27
29
|
|
|
28
30
|
|
|
29
31
|
class StateOut(BaseModel):
|
|
@@ -29,8 +29,8 @@ def test_router_mounted() -> None:
|
|
|
29
29
|
from __HOST_PKG__.router import router
|
|
30
30
|
|
|
31
31
|
paths = {route.path for route in router.routes}
|
|
32
|
-
assert "/__HOST_PKG__/state" in paths
|
|
33
|
-
assert "/__HOST_PKG__/bump" in paths
|
|
32
|
+
assert "/api/__HOST_PKG__/state" in paths
|
|
33
|
+
assert "/api/__HOST_PKG__/bump" in paths
|
|
34
34
|
|
|
35
35
|
|
|
36
36
|
def test_models_isolated_from_atrium_base() -> None:
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
/** Plain fetch — no axios. `credentials: 'include'` carries atrium's
|
|
2
2
|
* auth cookie so authenticated routes work the same as from atrium's
|
|
3
|
-
* own SPA. Build with `VITE_API_BASE_URL=""` (the default in the
|
|
4
|
-
* Dockerfile) so the bundle calls
|
|
3
|
+
* own SPA. Build with `VITE_API_BASE_URL="/api"` (the default in the
|
|
4
|
+
* Dockerfile) so the bundle calls atrium's API namespace — every
|
|
5
|
+
* JSON route lives under /api/... so the SPA owns un-prefixed URL
|
|
6
|
+
* space (atrium issue #89).
|
|
5
7
|
*/
|
|
6
8
|
const apiBase =
|
|
7
9
|
(import.meta as { env?: { VITE_API_BASE_URL?: string } }).env?.VITE_API_BASE_URL ??
|
|
8
|
-
'';
|
|
10
|
+
'/api';
|
|
9
11
|
|
|
10
12
|
async function jsonOrThrow<T>(res: Response): Promise<T> {
|
|
11
13
|
if (!res.ok) {
|