@squadbase/vantage 0.0.1 → 0.1.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 +24 -4
- package/dist/{chunk-ZGDU5YLH.js → chunk-5L2MH2NG.js} +16 -7
- package/dist/chunk-5L2MH2NG.js.map +1 -0
- package/dist/chunk-7IPAXPPY.js +51 -0
- package/dist/chunk-7IPAXPPY.js.map +1 -0
- package/dist/chunk-A2UUGASH.js +12 -0
- package/dist/chunk-A2UUGASH.js.map +1 -0
- package/dist/chunk-DTDVSFRY.js +29 -0
- package/dist/chunk-DTDVSFRY.js.map +1 -0
- package/dist/chunk-WQZYXXQW.js +2249 -0
- package/dist/chunk-WQZYXXQW.js.map +1 -0
- package/dist/{chunk-73J5ZD4C.js → chunk-YLAB6UQS.js} +17 -3
- package/dist/chunk-YLAB6UQS.js.map +1 -0
- package/dist/cli.js +607 -36
- package/dist/cli.js.map +1 -1
- package/dist/client/index.d.ts +2 -1
- package/dist/client/index.js +3 -1
- package/dist/client/index.js.map +1 -1
- package/dist/components/index.d.ts +575 -0
- package/dist/components/index.js +2097 -0
- package/dist/components/index.js.map +1 -0
- package/dist/{define-page-B6y9TOfZ.d.ts → define-page-BfhrK99G.d.ts} +5 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/markdown/index.d.ts +9 -0
- package/dist/markdown/index.js +26 -0
- package/dist/markdown/index.js.map +1 -0
- package/dist/query/index.d.ts +95 -2
- package/dist/query/index.js +102 -1
- package/dist/query/index.js.map +1 -1
- package/dist/router/index.d.ts +86 -1
- package/dist/router/index.js +71 -7
- package/dist/router/index.js.map +1 -1
- package/dist/server/node.js +6 -1
- package/dist/server/node.js.map +1 -1
- package/dist/ui/index.d.ts +316 -200
- package/dist/ui/index.js +566 -511
- package/dist/ui/index.js.map +1 -1
- package/dist/vite/index.js +2 -2
- package/docs/en/agent-skills.md +89 -0
- package/docs/en/api-and-server.md +84 -0
- package/docs/en/build-and-deploy.md +280 -0
- package/docs/en/cli-reference.md +311 -0
- package/docs/en/components.md +235 -0
- package/docs/en/data-fetching.md +142 -0
- package/docs/en/environment-variables.md +69 -0
- package/docs/en/getting-started.md +95 -0
- package/docs/en/index.md +65 -0
- package/docs/en/markdown/markdown-renderer.md +44 -0
- package/docs/en/pages-and-metadata.md +59 -0
- package/docs/en/parts/app-shell.md +54 -0
- package/docs/en/parts/dashboard-card.md +64 -0
- package/docs/en/parts/data-table.md +86 -0
- package/docs/en/parts/date-range-picker.md +41 -0
- package/docs/en/parts/echart.md +53 -0
- package/docs/en/parts/filter-bar.md +66 -0
- package/docs/en/parts/funnel-steps.md +33 -0
- package/docs/en/parts/metric-value.md +23 -0
- package/docs/en/parts/multi-select.md +27 -0
- package/docs/en/parts/page-shell.md +45 -0
- package/docs/en/parts/placeholder.md +38 -0
- package/docs/en/parts/searchable-select.md +47 -0
- package/docs/en/parts/section-header.md +20 -0
- package/docs/en/parts/segmented-control.md +25 -0
- package/docs/en/parts/sparkline.md +47 -0
- package/docs/en/parts/status-badge.md +44 -0
- package/docs/en/parts/trend-indicator.md +26 -0
- package/docs/en/routing.md +177 -0
- package/docs/en/ui/accordion.md +36 -0
- package/docs/en/ui/alert.md +31 -0
- package/docs/en/ui/badge.md +23 -0
- package/docs/en/ui/breadcrumb.md +38 -0
- package/docs/en/ui/button.md +39 -0
- package/docs/en/ui/calendar.md +28 -0
- package/docs/en/ui/card.md +35 -0
- package/docs/en/ui/checkbox.md +34 -0
- package/docs/en/ui/cn.md +34 -0
- package/docs/en/ui/collapsible.md +21 -0
- package/docs/en/ui/command.md +37 -0
- package/docs/en/ui/dialog.md +52 -0
- package/docs/en/ui/dropdown-menu.md +50 -0
- package/docs/en/ui/empty.md +22 -0
- package/docs/en/ui/error-state.md +50 -0
- package/docs/en/ui/input-group.md +30 -0
- package/docs/en/ui/input.md +28 -0
- package/docs/en/ui/label.md +19 -0
- package/docs/en/ui/loading.md +19 -0
- package/docs/en/ui/popover.md +34 -0
- package/docs/en/ui/progress.md +28 -0
- package/docs/en/ui/scroll-area.md +23 -0
- package/docs/en/ui/select.md +63 -0
- package/docs/en/ui/separator.md +15 -0
- package/docs/en/ui/sheet.md +28 -0
- package/docs/en/ui/sidebar.md +92 -0
- package/docs/en/ui/skeleton.md +16 -0
- package/docs/en/ui/slider.md +21 -0
- package/docs/en/ui/spinner.md +14 -0
- package/docs/en/ui/switch.md +19 -0
- package/docs/en/ui/table.md +24 -0
- package/docs/en/ui/tabs.md +23 -0
- package/docs/en/ui/textarea.md +15 -0
- package/docs/en/ui/toggle-group.md +26 -0
- package/docs/en/ui/toggle.md +19 -0
- package/docs/en/ui/tooltip.md +22 -0
- package/docs/en/ui/use-is-mobile.md +18 -0
- package/docs/en/ui-and-theming.md +95 -0
- package/docs/index.json +1346 -0
- package/docs/ja/agent-skills.md +87 -0
- package/docs/ja/api-and-server.md +84 -0
- package/docs/ja/build-and-deploy.md +279 -0
- package/docs/ja/cli-reference.md +305 -0
- package/docs/ja/components.md +231 -0
- package/docs/ja/data-fetching.md +142 -0
- package/docs/ja/environment-variables.md +68 -0
- package/docs/ja/getting-started.md +95 -0
- package/docs/ja/index.md +65 -0
- package/docs/ja/markdown/markdown-renderer.md +43 -0
- package/docs/ja/pages-and-metadata.md +59 -0
- package/docs/ja/parts/app-shell.md +54 -0
- package/docs/ja/parts/dashboard-card.md +64 -0
- package/docs/ja/parts/data-table.md +85 -0
- package/docs/ja/parts/date-range-picker.md +41 -0
- package/docs/ja/parts/echart.md +52 -0
- package/docs/ja/parts/filter-bar.md +64 -0
- package/docs/ja/parts/funnel-steps.md +33 -0
- package/docs/ja/parts/metric-value.md +25 -0
- package/docs/ja/parts/multi-select.md +27 -0
- package/docs/ja/parts/page-shell.md +45 -0
- package/docs/ja/parts/placeholder.md +37 -0
- package/docs/ja/parts/searchable-select.md +47 -0
- package/docs/ja/parts/section-header.md +20 -0
- package/docs/ja/parts/segmented-control.md +26 -0
- package/docs/ja/parts/sparkline.md +47 -0
- package/docs/ja/parts/status-badge.md +44 -0
- package/docs/ja/parts/trend-indicator.md +26 -0
- package/docs/ja/routing.md +175 -0
- package/docs/ja/ui/accordion.md +37 -0
- package/docs/ja/ui/alert.md +31 -0
- package/docs/ja/ui/badge.md +23 -0
- package/docs/ja/ui/breadcrumb.md +38 -0
- package/docs/ja/ui/button.md +39 -0
- package/docs/ja/ui/calendar.md +28 -0
- package/docs/ja/ui/card.md +35 -0
- package/docs/ja/ui/checkbox.md +34 -0
- package/docs/ja/ui/cn.md +34 -0
- package/docs/ja/ui/collapsible.md +21 -0
- package/docs/ja/ui/command.md +36 -0
- package/docs/ja/ui/dialog.md +51 -0
- package/docs/ja/ui/dropdown-menu.md +50 -0
- package/docs/ja/ui/empty.md +22 -0
- package/docs/ja/ui/error-state.md +50 -0
- package/docs/ja/ui/input-group.md +30 -0
- package/docs/ja/ui/input.md +28 -0
- package/docs/ja/ui/label.md +19 -0
- package/docs/ja/ui/loading.md +19 -0
- package/docs/ja/ui/popover.md +34 -0
- package/docs/ja/ui/progress.md +28 -0
- package/docs/ja/ui/scroll-area.md +24 -0
- package/docs/ja/ui/select.md +64 -0
- package/docs/ja/ui/separator.md +15 -0
- package/docs/ja/ui/sheet.md +28 -0
- package/docs/ja/ui/sidebar.md +92 -0
- package/docs/ja/ui/skeleton.md +16 -0
- package/docs/ja/ui/slider.md +21 -0
- package/docs/ja/ui/spinner.md +14 -0
- package/docs/ja/ui/switch.md +19 -0
- package/docs/ja/ui/table.md +24 -0
- package/docs/ja/ui/tabs.md +24 -0
- package/docs/ja/ui/textarea.md +15 -0
- package/docs/ja/ui/toggle-group.md +27 -0
- package/docs/ja/ui/toggle.md +19 -0
- package/docs/ja/ui/tooltip.md +22 -0
- package/docs/ja/ui/use-is-mobile.md +18 -0
- package/docs/ja/ui-and-theming.md +95 -0
- package/package.json +29 -4
- package/registry/blocks/sales-overview.tsx +43 -19
- package/registry/ui/data-table.tsx +702 -102
- package/skills/vantage-add-feature/SKILL.md +153 -0
- package/skills/vantage-app/SKILL.md +291 -0
- package/skills/vantage-pitfalls/SKILL.md +139 -0
- package/templates/AGENTS.md +313 -0
- package/theme.css +178 -40
- package/dist/chunk-73J5ZD4C.js.map +0 -1
- package/dist/chunk-ATYZ45XL.js +0 -19
- package/dist/chunk-ATYZ45XL.js.map +0 -1
- package/dist/chunk-ZGDU5YLH.js.map +0 -1
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Build & deploy
|
|
2
|
+
|
|
3
|
+
> What's in dist/ and vantage-manifest.json. Same-origin serving, and splitting the client and server across origins (S3+CloudFront ⇄ Lambda, etc.).
|
|
4
|
+
|
|
5
|
+
`vantage build` emits the production artifacts into `dist/`. From there, serving splits into two shapes:
|
|
6
|
+
serve the client and server together from the **same origin**, or **split** them — the client on static
|
|
7
|
+
hosting (S3+CloudFront / Cloudflare Pages) and the server on a separate origin (Lambda / a container).
|
|
8
|
+
For the split shape, Vantage provides an **API base URL switch** and **CORS**.
|
|
9
|
+
|
|
10
|
+
## Build output
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
vantage build # → dist/
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```text
|
|
17
|
+
dist/
|
|
18
|
+
├── client/ Client (index.html + hashed assets, code-split per route)
|
|
19
|
+
├── server/index.mjs Only when server/ exists (esbuild / node20 / ESM bundle)
|
|
20
|
+
└── vantage-manifest.json Deploy contract
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
`vantage-manifest.json` is the one contract the host reads. Its fields:
|
|
24
|
+
|
|
25
|
+
| Field | Meaning |
|
|
26
|
+
|---|---|
|
|
27
|
+
| `schemaVersion` | Manifest schema version (currently `1`) |
|
|
28
|
+
| `mode` | `"spa"` (client only) / `"fullstack"` (has server). Derived from `server/` |
|
|
29
|
+
| `client` | Relative path to the client output (`"./client"`) |
|
|
30
|
+
| `server` | Relative path to the server bundle (`"./server/index.mjs"`). Fullstack only |
|
|
31
|
+
| `spaFallback` | HTML for the SPA fallback (`"./client/index.html"`) |
|
|
32
|
+
| `runtime` | Server runtime (`"node"`) |
|
|
33
|
+
|
|
34
|
+
> [!NOTE]
|
|
35
|
+
> `mode` is decided automatically by the presence of a `server/` directory: no `server/` → `spa`
|
|
36
|
+
> (client only); with it → `fullstack`. The same derivation is used by `vantage check` and
|
|
37
|
+
> `vantage routes`.
|
|
38
|
+
|
|
39
|
+
## Preview locally
|
|
40
|
+
|
|
41
|
+
Before deploying, run the production build locally to verify it.
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
vantage preview
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`vantage preview` reads `mode` from `vantage-manifest.json`: `fullstack` starts the Node server
|
|
48
|
+
(default `:4173`), `spa` serves a static preview.
|
|
49
|
+
|
|
50
|
+
## Two deployment shapes
|
|
51
|
+
|
|
52
|
+
### Same origin
|
|
53
|
+
|
|
54
|
+
One Node process serves both the client and `/api`. Minimal setup, and no CORS needed.
|
|
55
|
+
|
|
56
|
+
### Split client & server
|
|
57
|
+
|
|
58
|
+
Client on S3+CloudFront etc., server on Lambda / a container. Needs the API base URL switch
|
|
59
|
+
and CORS.
|
|
60
|
+
|
|
61
|
+
## Deploy to a single origin
|
|
62
|
+
|
|
63
|
+
The simplest shape. Place all of `dist/` on a host that runs Node (a container / VM) and start the
|
|
64
|
+
generated server. One process serves both static assets and `/api/*`, so there is nothing to switch
|
|
65
|
+
and no CORS to configure.
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# on the host where dist/ lives
|
|
69
|
+
PORT=8080 node dist/server/index.mjs
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
The server listens on `PORT` (or `3000` if unset). The client calls relative `/api/...` paths on the
|
|
73
|
+
same origin.
|
|
74
|
+
|
|
75
|
+
> [!NOTE]
|
|
76
|
+
> `spa` mode (no `server/`) has no server to start. Upload `dist/client/` to any static host and fall
|
|
77
|
+
> back unknown paths to `index.html` (see the SPA fallback settings below).
|
|
78
|
+
|
|
79
|
+
## Split the client and server (S3+CloudFront ⇄ Lambda)
|
|
80
|
+
|
|
81
|
+
Here the client lives on CDN static hosting and the server on a separate origin. A common pairing is
|
|
82
|
+
"`dist/client` on S3+CloudFront, `dist/server/index.mjs` on Lambda / a container". Because the
|
|
83
|
+
origins differ, two things are required.
|
|
84
|
+
|
|
85
|
+
### 1. Switch the API base URL
|
|
86
|
+
|
|
87
|
+
Client API calls go through `apiFetch` / `apiUrl` from `@squadbase/vantage/query`. This is the one
|
|
88
|
+
seam that calls `/api`, and it's where the base URL is swapped.
|
|
89
|
+
|
|
90
|
+
```tsx
|
|
91
|
+
import { apiFetch, useQuery } from "@squadbase/vantage/query";
|
|
92
|
+
|
|
93
|
+
useQuery({
|
|
94
|
+
queryKey: ["monthly-analysis"],
|
|
95
|
+
// Keep the path as it maps in server/api (include /api)
|
|
96
|
+
queryFn: () => apiFetch("/api/monthly-analysis").then((r) => r.json()),
|
|
97
|
+
});
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
The base URL is read from `PUBLIC_API_BASE_URL`. **Unset means empty**, so requests stay same-origin
|
|
101
|
+
relative paths (`/api/monthly-analysis`). Set it and the value is prepended
|
|
102
|
+
(`https://api.example.com/api/monthly-analysis`). Two ways to set it:
|
|
103
|
+
|
|
104
|
+
**(a) Override via env** — put it in `.env` or a CI environment variable. Because of the `PUBLIC_`
|
|
105
|
+
prefix it is inlined into the client bundle.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# .env (or a CI env var)
|
|
109
|
+
PUBLIC_API_BASE_URL=https://api.example.com
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
**(b) Specify at build time** — pass `--api-base-url` to `vantage build`.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
vantage build --api-base-url https://api.example.com
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
> [!NOTE]
|
|
119
|
+
> `--api-base-url` **takes precedence** over `PUBLIC_API_BASE_URL` from `.env`. You can keep a base
|
|
120
|
+
> value in `.env` and override per environment with the flag.
|
|
121
|
+
|
|
122
|
+
> [!TIP]
|
|
123
|
+
> Pass the path to `apiUrl("/api/...")` with the **`/api` prefix included**, matching how it maps under
|
|
124
|
+
> `server/api/**`. The base URL represents the origin (or up to a prefix); the path is concatenated
|
|
125
|
+
> as-is.
|
|
126
|
+
|
|
127
|
+
### 2. Allow CORS
|
|
128
|
+
|
|
129
|
+
Once the client and server are on different origins, the browser requires CORS. Setting `CORS_ORIGIN`
|
|
130
|
+
on the server enables CORS on `/api` (including the preflight `OPTIONS` response). **Unset means CORS
|
|
131
|
+
is off**, leaving same-origin serving unchanged.
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
# environment variables on the server (Lambda / container)
|
|
135
|
+
CORS_ORIGIN=https://app.example.com # a single origin
|
|
136
|
+
# CORS_ORIGIN=https://a.example.com,https://b.example.com # comma-separated for several
|
|
137
|
+
# CORS_ORIGIN=* # allow all (not usable with credentials)
|
|
138
|
+
CORS_CREDENTIALS=true # only if you allow cookies / credentials
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
| Variable | Role |
|
|
142
|
+
|---|---|
|
|
143
|
+
| `CORS_ORIGIN` | Allowed origin(s): `*` / a single value / comma-separated. Unset → CORS off |
|
|
144
|
+
| `CORS_CREDENTIALS` | When `true`, allow credentials (cookies, etc.). Not used with `*` |
|
|
145
|
+
|
|
146
|
+
The allowed methods are set automatically to the ones Vantage APIs can use
|
|
147
|
+
(`GET,POST,PUT,PATCH,DELETE,OPTIONS`). This behavior is **shared** by the dev server and the
|
|
148
|
+
production Node server, so you can verify CORS during development.
|
|
149
|
+
|
|
150
|
+
### 3. Put the client on static hosting
|
|
151
|
+
|
|
152
|
+
Upload `dist/client/` to S3 (+ CloudFront) or Cloudflare Pages. As an SPA, unknown paths must fall
|
|
153
|
+
back to `spaFallback` (`index.html`).
|
|
154
|
+
|
|
155
|
+
- **S3 + CloudFront**: use a CloudFront "custom error response" to rewrite `403` / `404` to
|
|
156
|
+
`/index.html` with status `200`.
|
|
157
|
+
- **S3 static website hosting**: set the error document to `index.html`.
|
|
158
|
+
- **Cloudflare Pages**: SPA fallback is on by default.
|
|
159
|
+
|
|
160
|
+
### 4. Put the server on Lambda / a container
|
|
161
|
+
|
|
162
|
+
`dist/server/index.mjs` is a Node HTTP server that listens on `PORT` (the manifest's `runtime` is
|
|
163
|
+
`"node"`). It runs anywhere a Node process runs.
|
|
164
|
+
|
|
165
|
+
- **Container (Cloud Run / ECS·Fargate / Render / Fly, etc.)**: use `node dist/server/index.mjs` as
|
|
166
|
+
the start command and pass `PORT`.
|
|
167
|
+
- **AWS Lambda**: since it is a listening Node server, a container image + AWS Lambda Web Adapter (or
|
|
168
|
+
another "run an HTTP server on Lambda" approach) is a good fit.
|
|
169
|
+
- Pass secrets (DB credentials, API keys) as **server environment variables**. They are only readable
|
|
170
|
+
via `ApiContext.env` and never reach the client.
|
|
171
|
+
|
|
172
|
+
> [!WARNING]
|
|
173
|
+
> The production Node server snapshots `process.env` **once at startup** (dev re-reads it per request).
|
|
174
|
+
> Restart the server after changing environment variables.
|
|
175
|
+
|
|
176
|
+
## Deploy to AWS Lambda (a concrete walkthrough)
|
|
177
|
+
|
|
178
|
+
The generated `dist/server/index.mjs` is a Node HTTP server that **listens** on `PORT`. Lambda, on the
|
|
179
|
+
other hand, invokes a handler per event, so the natural way to run a listening server there is to put
|
|
180
|
+
the [AWS Lambda Web Adapter](https://github.com/awslabs/aws-lambda-web-adapter) (LWA) in front of it.
|
|
181
|
+
LWA proxies Function URL / API Gateway events to the HTTP server running locally. No Vantage code
|
|
182
|
+
changes are needed.
|
|
183
|
+
|
|
184
|
+
### 1. Run it as a container image (recommended)
|
|
185
|
+
|
|
186
|
+
esbuild bundles into a **single file** `dist/server/index.mjs`, so you don't need to carry
|
|
187
|
+
`node_modules`.
|
|
188
|
+
|
|
189
|
+
```dockerfile
|
|
190
|
+
# Dockerfile
|
|
191
|
+
FROM public.ecr.aws/docker/library/node:20-slim
|
|
192
|
+
|
|
193
|
+
# Bundle the Lambda Web Adapter as an extension (bump the version as needed)
|
|
194
|
+
COPY --from=public.ecr.aws/awsguru/aws-lambda-adapter:0.9.1 /lambda-adapter /opt/extensions/lambda-adapter
|
|
195
|
+
|
|
196
|
+
WORKDIR /var/task
|
|
197
|
+
# Copy all of dist/ (the server resolves ../client, so keep the layout)
|
|
198
|
+
COPY dist ./dist
|
|
199
|
+
|
|
200
|
+
# Keep LWA and the Node server on the same port (LWA defaults to 8080)
|
|
201
|
+
ENV PORT=8080
|
|
202
|
+
CMD ["node", "dist/server/index.mjs"]
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
```bash
|
|
206
|
+
vantage build # produce dist/
|
|
207
|
+
docker build -t vantage-api .
|
|
208
|
+
|
|
209
|
+
# Log in to ECR and push (<acct> / <region> are yours)
|
|
210
|
+
aws ecr get-login-password --region ap-northeast-1 \
|
|
211
|
+
| docker login --username AWS --password-stdin <acct>.dkr.ecr.ap-northeast-1.amazonaws.com
|
|
212
|
+
docker tag vantage-api <acct>.dkr.ecr.ap-northeast-1.amazonaws.com/vantage-api:latest
|
|
213
|
+
docker push <acct>.dkr.ecr.ap-northeast-1.amazonaws.com/vantage-api:latest
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Create a Lambda function from this image and enable a **Function URL** to get an HTTPS endpoint. Use
|
|
217
|
+
it as the `/api/*` origin in CloudFront, or point the client's `PUBLIC_API_BASE_URL` at it directly.
|
|
218
|
+
|
|
219
|
+
> [!TIP]
|
|
220
|
+
> **Running from a zip**
|
|
221
|
+
> You can also run from a zip instead of a container. Since the output is bundled, zip
|
|
222
|
+
> `dist/server/index.mjs` (and `dist/client` if you want), attach LWA as a **Lambda layer**, set
|
|
223
|
+
> `AWS_LAMBDA_EXEC_WRAPPER=/opt/bootstrap` and `PORT=8080`, and use the Node.js 20.x runtime.
|
|
224
|
+
|
|
225
|
+
### 2. Set the Lambda environment variables
|
|
226
|
+
|
|
227
|
+
Pass server config and secrets as Lambda environment variables (they never reach the client).
|
|
228
|
+
|
|
229
|
+
| Variable | Example | Purpose |
|
|
230
|
+
|---|---|---|
|
|
231
|
+
| `CORS_ORIGIN` | `https://d111111abcdef8.cloudfront.net` | Allow the client's origin |
|
|
232
|
+
| `CORS_CREDENTIALS` | `true` | Only if you use cookies / credentials |
|
|
233
|
+
| `SECRET_*`, etc. | `sk_live_xxx` | Secrets read via `ApiContext.env` |
|
|
234
|
+
|
|
235
|
+
`PORT` is already set in the Dockerfile (matching LWA's default 8080).
|
|
236
|
+
|
|
237
|
+
> [!NOTE]
|
|
238
|
+
> A Function URL has its own CORS settings, but configuring CORS **both** there and in the app
|
|
239
|
+
> (`CORS_ORIGIN`) **conflicts**. Consolidate on Vantage's `CORS_ORIGIN` and leave the Function URL's
|
|
240
|
+
> CORS empty for a clearer setup.
|
|
241
|
+
|
|
242
|
+
### 3. Point the client at Lambda
|
|
243
|
+
|
|
244
|
+
At client build time, set `PUBLIC_API_BASE_URL` to the Lambda (or the CloudFront in front of it)
|
|
245
|
+
origin.
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
vantage build --api-base-url https://d111111abcdef8.cloudfront.net
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
`apiUrl("/api/monthly-analysis")` then calls that origin with `/api/monthly-analysis` appended.
|
|
252
|
+
|
|
253
|
+
> [!WARNING]
|
|
254
|
+
> Lambda starts the process on a cold start and reads `process.env` at that moment. After changing
|
|
255
|
+
> environment variables, deploy a new version to apply them (running environments are not updated
|
|
256
|
+
> retroactively).
|
|
257
|
+
|
|
258
|
+
## Production environment variables at a glance
|
|
259
|
+
|
|
260
|
+
The boundary is the prefix (see also [Environment variables](environment-variables)).
|
|
261
|
+
|
|
262
|
+
| Kind | Set where | When it applies | Example |
|
|
263
|
+
|---|---|---|---|
|
|
264
|
+
| Public client value | Build time (`.env` / `--api-base-url`) | Baked into the build | `PUBLIC_API_BASE_URL` |
|
|
265
|
+
| Server config | Server environment variable | Read at startup | `PORT`, `CORS_ORIGIN`, `CORS_CREDENTIALS` |
|
|
266
|
+
| Secret | Server environment variable | Read at startup (`ApiContext.env`) | `SECRET_API_KEY`, etc. |
|
|
267
|
+
|
|
268
|
+
## Pre-deploy checklist
|
|
269
|
+
|
|
270
|
+
- [ ] `vantage check` passes with no errors
|
|
271
|
+
- [ ] `vantage build` (with `--api-base-url` for a split setup, or `PUBLIC_API_BASE_URL` in `.env`)
|
|
272
|
+
- [ ] `vantage preview` verifies it locally
|
|
273
|
+
- [ ] For a split setup, set `CORS_ORIGIN` (the client's origin) on the server
|
|
274
|
+
- [ ] Configure SPA fallback (unknown paths → `index.html`) on the static host
|
|
275
|
+
- [ ] Keep secrets in server environment variables only (never expose to the client)
|
|
276
|
+
|
|
277
|
+
## What to read next
|
|
278
|
+
|
|
279
|
+
- [CLI reference](cli-reference) — every command, including the `build` flags
|
|
280
|
+
- [Environment variables](environment-variables) — the public / secret boundary
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
# CLI reference
|
|
2
|
+
|
|
3
|
+
> Every vantage command. dev, build, preview, check, routes, add, docs, search, doctor, upgrade.
|
|
4
|
+
|
|
5
|
+
`vantage` is the only CLI an app author uses. Run it from the project root unless noted.
|
|
6
|
+
|
|
7
|
+
## Commands
|
|
8
|
+
|
|
9
|
+
| Command | Role |
|
|
10
|
+
|---|---|
|
|
11
|
+
| `vantage dev` | Dev server (HMR + optional API). Default `:5173` |
|
|
12
|
+
| `vantage build` | Build client + optional server → `dist/` |
|
|
13
|
+
| `vantage preview` | Run the production build locally (fullstack default `:4173`; spa via Vite preview) |
|
|
14
|
+
| `vantage check` | Static checks (routes, boundaries, forbidden files). Exit 1 on error |
|
|
15
|
+
| `vantage routes` | Print the page + API URL map |
|
|
16
|
+
| `vantage add <kind> <name>` | Scaffold or place a `page` / `api` / `ui` / `block` / `skill` / `agents` (`--force` to overwrite) |
|
|
17
|
+
| `vantage docs [name]` | Show the bundled guide and component reference |
|
|
18
|
+
| `vantage search <query>` | Search that same reference in full text (natural language or `--regex`) |
|
|
19
|
+
| `vantage doctor` | Diagnose environment / installation health |
|
|
20
|
+
| `vantage upgrade` | Regenerate artifacts and sync a placed `AGENTS.md` from the canonical copy |
|
|
21
|
+
|
|
22
|
+
## Quick mode (pass a path directly)
|
|
23
|
+
|
|
24
|
+
Instead of `cd`-ing in before running a command, you can pass a **project path directly**. When the
|
|
25
|
+
first argument isn't a known command but points at a filesystem path, Vantage starts `dev` with that
|
|
26
|
+
path as the root (printing `quick dev → <path>`).
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
vantage ./demo # folder → run dev inside it
|
|
30
|
+
vantage ./demo/index.tsx # page file → use its parent folder as the root
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Path resolution rules:
|
|
34
|
+
|
|
35
|
+
| Path you pass | Root that's used |
|
|
36
|
+
|---|---|
|
|
37
|
+
| A directory | the directory itself |
|
|
38
|
+
| A `.tsx` / `.jsx` page file | its parent directory |
|
|
39
|
+
| A missing path / anything else | none (`Unknown command` error) |
|
|
40
|
+
|
|
41
|
+
Every root-scoped command except `add`, `docs` and `search` may also take a trailing path positional. You can spell out
|
|
42
|
+
`dev`, or pass the same path to `build` / `check` / `routes`, etc.
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
vantage dev ./demo # explicit quick dev
|
|
46
|
+
vantage build ./demo # build ./demo
|
|
47
|
+
vantage check ./demo/index.tsx # a file argument still checks its parent directory
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
> [!NOTE]
|
|
51
|
+
> `add`, `docs` and `search` use their positionals for their own arguments (`add page dashboard`,
|
|
52
|
+
> `docs button`, `search date picker`) rather than a path, so they are excluded from this shortcut.
|
|
53
|
+
|
|
54
|
+
## `vantage docs` — read the docs from the CLI
|
|
55
|
+
|
|
56
|
+
The content of this site is **bundled into the package**, so `vantage docs` prints it as plain
|
|
57
|
+
Markdown. No network and no browser, which makes it the fastest way for a coding agent to check
|
|
58
|
+
props.
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
vantage docs # list every page (guide + components)
|
|
62
|
+
vantage docs button # show one page (short name → ui/button)
|
|
63
|
+
vantage docs parts/data-table # full slugs work too
|
|
64
|
+
vantage docs --all # concatenate every page
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
| Flag | Meaning |
|
|
68
|
+
|---|---|
|
|
69
|
+
| `--list` | List page names only (no body) |
|
|
70
|
+
| `--all` | Concatenate every page |
|
|
71
|
+
| `--json` | Machine-readable (`{ slug, title, description, section, content }`) |
|
|
72
|
+
| `--lang <ja\|en>` | Language (default `ja`) |
|
|
73
|
+
|
|
74
|
+
With no argument, `vantage docs` lists **slugs and descriptions** by section — the left column is what
|
|
75
|
+
you pass back in.
|
|
76
|
+
|
|
77
|
+
```text
|
|
78
|
+
$ vantage docs --lang en
|
|
79
|
+
|
|
80
|
+
Guide
|
|
81
|
+
index A config-free React dashboard framework. You only write index.tsx.
|
|
82
|
+
getting-started From install to running your first Vantage app.
|
|
83
|
+
routing Dropping a file creates a route. Conventions for pages, layouts, dynamic params, and 404/error.
|
|
84
|
+
…
|
|
85
|
+
|
|
86
|
+
@squadbase/vantage/ui
|
|
87
|
+
ui/accordion A stack of headings that open and close. One at a time by default.
|
|
88
|
+
ui/alert An in-page notice that flags something while the content is still shown.
|
|
89
|
+
ui/badge A small label for counts, states and tags.
|
|
90
|
+
…
|
|
91
|
+
|
|
92
|
+
vantage docs <name> show one page --json machine-readable
|
|
93
|
+
vantage docs --all show every page --lang ja | en
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Pass a name and the page prints **as Markdown** (headings and quotes are coloured on a TTY, plain when
|
|
97
|
+
piped). Prop tables stay readable as Markdown tables.
|
|
98
|
+
|
|
99
|
+
````text
|
|
100
|
+
$ vantage docs button --lang en
|
|
101
|
+
|
|
102
|
+
# Button
|
|
103
|
+
|
|
104
|
+
> The button, with six variants and eight sizes.
|
|
105
|
+
|
|
106
|
+
The component you'll reach for most. `variant` carries the meaning, `size` the scale.
|
|
107
|
+
|
|
108
|
+
```tsx
|
|
109
|
+
import { Button, buttonVariants } from "@squadbase/vantage/ui";
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
| Prop | Type | Default | Description |
|
|
113
|
+
| --- | --- | --- | --- |
|
|
114
|
+
| `variant` | `"default" \| "secondary" \| …` | `"default"` | Look and meaning. |
|
|
115
|
+
| `size` | `"default" \| "xs" \| "sm" \| …` | `"default"` | Height and padding. The `icon` sizes are square. |
|
|
116
|
+
| `render` | `ReactElement` | | Render as a different element (Radix's `asChild`). |
|
|
117
|
+
…
|
|
118
|
+
````
|
|
119
|
+
|
|
120
|
+
Names resolve from their **short form**: `vantage docs button` finds `ui/button`, and
|
|
121
|
+
`vantage docs data-table` finds `parts/data-table`. An ambiguous or unknown name prints candidates and
|
|
122
|
+
exits 1.
|
|
123
|
+
|
|
124
|
+
```text
|
|
125
|
+
$ vantage docs sele
|
|
126
|
+
✗ No page named "sele". Did you mean: ui/select, parts/multi-select, parts/searchable-select?
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
`--json` is one page, machine-readable; `content` holds the whole Markdown body.
|
|
130
|
+
|
|
131
|
+
```json
|
|
132
|
+
{
|
|
133
|
+
"slug": "ui/badge",
|
|
134
|
+
"lang": "en",
|
|
135
|
+
"title": "Badge",
|
|
136
|
+
"description": "A small label for counts, states and tags.",
|
|
137
|
+
"section": "components/ui",
|
|
138
|
+
"sectionTitle": "@squadbase/vantage/ui",
|
|
139
|
+
"content": "# Badge\n\n> A small label for counts, states and tags.\n\nA small label to sit beside…"
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Links in the body are slugs, so `[DataTable](parts/data-table)` opens with
|
|
144
|
+
`vantage docs parts/data-table`.
|
|
145
|
+
|
|
146
|
+
> [!NOTE]
|
|
147
|
+
> What ships is the MDX converted to plain Markdown. Live previews are a site-only feature; the CLI
|
|
148
|
+
> gives you the prop tables, code samples, and callouts.
|
|
149
|
+
|
|
150
|
+
## `vantage search` — find it without knowing its name
|
|
151
|
+
|
|
152
|
+
`vantage docs <name>` assumes you **know the name**. When you're coming from what you want to build —
|
|
153
|
+
"I need a UI for picking a date range" — use `vantage search`. It indexes the same bundled docs
|
|
154
|
+
(the guide plus every `ui` / `parts` / `markdown` component), and every result is a name you can hand
|
|
155
|
+
straight to `vantage docs <name>`.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
vantage search date range filter --lang en # natural language (quotes are optional)
|
|
159
|
+
vantage search "pagination" --lang en
|
|
160
|
+
vantage search "enable[A-Z]\w+" --regex # sweep prop names with a regular expression
|
|
161
|
+
vantage search chart --limit 3 --json # machine-readable
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
| Flag | Meaning |
|
|
165
|
+
|---|---|
|
|
166
|
+
| `--regex` | Treat the query as a regular expression (case-insensitive) |
|
|
167
|
+
| `--limit <n>` | Results to show (default `10`) |
|
|
168
|
+
| `--json` | Machine-readable output |
|
|
169
|
+
| `--lang <ja\|en>` | Language (default `ja`) |
|
|
170
|
+
|
|
171
|
+
The default mode is **BM25 full-text search**. Names, titles and descriptions weigh more than body
|
|
172
|
+
prose, and each hit shows the **passage that matched**. Japanese is segmented at script boundaries
|
|
173
|
+
(kanji / katakana / hiragana), so a whole sentence works as a query.
|
|
174
|
+
|
|
175
|
+
```text
|
|
176
|
+
$ vantage search date range picker --lang en --limit 3
|
|
177
|
+
|
|
178
|
+
parts/date-range-picker DateRangePicker · @squadbase/vantage/components
|
|
179
|
+
> A date-range picker with presets.
|
|
180
|
+
ui/calendar Calendar · @squadbase/vantage/ui
|
|
181
|
+
[`DateRangePicker`](parts/date-range-picker) gets you there faster than using this
|
|
182
|
+
components Components · Components
|
|
183
|
+
| [`DateRangePicker`](parts/date-range-picker) | Date range with presets |
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
The left column is the slug to hand to `vantage docs <name>`, the right one is the title and where it
|
|
187
|
+
is imported from, and below each is the matching passage. The real output also prints a
|
|
188
|
+
`11 results for "…" en · bm25` header and a footer with what `--limit` hid (elided above). **The count
|
|
189
|
+
is how many pages matched at least one term**, so the tail is mostly irrelevant — read the first few
|
|
190
|
+
and raise `--limit` only if they miss.
|
|
191
|
+
|
|
192
|
+
`--json` is the same result set, machine-readable. `score` is the BM25 score and `command` is ready to
|
|
193
|
+
run (below: `vantage search pagination --lang en --limit 1 --json`).
|
|
194
|
+
|
|
195
|
+
```json
|
|
196
|
+
{
|
|
197
|
+
"query": "pagination",
|
|
198
|
+
"mode": "bm25",
|
|
199
|
+
"lang": "en",
|
|
200
|
+
"count": 4,
|
|
201
|
+
"results": [
|
|
202
|
+
{
|
|
203
|
+
"slug": "parts/data-table",
|
|
204
|
+
"title": "DataTable",
|
|
205
|
+
"description": "The TanStack Table–backed table: sorting, search, pagination, selection.",
|
|
206
|
+
"section": "components/parts",
|
|
207
|
+
"sectionTitle": "@squadbase/vantage/components",
|
|
208
|
+
"command": "vantage docs parts/data-table",
|
|
209
|
+
"score": 5.404,
|
|
210
|
+
"snippet": "> The TanStack Table–backed table: sorting, search, pagination, selection."
|
|
211
|
+
}
|
|
212
|
+
]
|
|
213
|
+
}
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
`--regex` scans names, titles, descriptions and bodies, and prints matching lines **with line
|
|
217
|
+
numbers** — the mode to reach for when checking how a prop is spelled across pages.
|
|
218
|
+
|
|
219
|
+
```text
|
|
220
|
+
$ vantage search "enable(Sorting|Filtering)" --regex --lang en
|
|
221
|
+
|
|
222
|
+
parts/data-table DataTable 4 matches
|
|
223
|
+
30 | `enableSorting` | `boolean` | Sort by clicking a header. |
|
|
224
|
+
31 | `enableFiltering` | `boolean` | Put a search box in the toolbar. |
|
|
225
|
+
50 <DataTable columns={columns} data={data} enableSorting enableFiltering>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Only the first 3 lines of a page are printed, but the `4 matches` count is exact. A page that matched
|
|
229
|
+
on its name, title or description alone is marked `name match` and prints no body lines. Finding
|
|
230
|
+
nothing is not an error (exit code 0, `"count": 0` with `--json`); only an invalid regular expression
|
|
231
|
+
exits 1.
|
|
232
|
+
|
|
233
|
+
> [!NOTE]
|
|
234
|
+
> The index is built at run time (tens of milliseconds, reading the bundled docs included). Nothing
|
|
235
|
+
> prebuilt ships alongside the docs, so search results can never drift from the documentation.
|
|
236
|
+
>
|
|
237
|
+
> **This page is part of the corpus too.** Run the queries above verbatim and this CLI reference — which
|
|
238
|
+
> contains them as examples — shows up among the hits; the sample output above leaves that row out.
|
|
239
|
+
|
|
240
|
+
## `--json`
|
|
241
|
+
|
|
242
|
+
`check` / `routes` / `doctor` / `build` / `upgrade` / `docs` / `search` accept `--json`, useful for CI and agent
|
|
243
|
+
automation.
|
|
244
|
+
|
|
245
|
+
```bash
|
|
246
|
+
vantage check --json
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
```json
|
|
250
|
+
{
|
|
251
|
+
"code": "ROUTE_CONFLICT",
|
|
252
|
+
"severity": "error",
|
|
253
|
+
"message": "2 files resolve to /sales",
|
|
254
|
+
"files": ["sales.tsx", "sales/index.tsx"],
|
|
255
|
+
"fix": "Rename or remove one route file so each route is unique."
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
> [!NOTE]
|
|
260
|
+
> `build --json` prints a **compact single line**. Other commands' `--json` is pretty-printed with
|
|
261
|
+
> 2-space indentation.
|
|
262
|
+
|
|
263
|
+
## `build --api-base-url`
|
|
264
|
+
|
|
265
|
+
`vantage build` accepts `--api-base-url` to set the base URL the client uses to call `/api`. Use it
|
|
266
|
+
when deploying the client and server on different origins.
|
|
267
|
+
|
|
268
|
+
```bash
|
|
269
|
+
vantage build --api-base-url https://api.example.com
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
The flag takes precedence over `PUBLIC_API_BASE_URL` from `.env`. Unset means empty (same-origin
|
|
273
|
+
relative paths). See [Build & deploy](build-and-deploy) for details.
|
|
274
|
+
|
|
275
|
+
## Static diagnostics (`check`)
|
|
276
|
+
|
|
277
|
+
`vantage check` detects these six diagnostics (five errors, one warning).
|
|
278
|
+
|
|
279
|
+
| Code | Severity | Meaning |
|
|
280
|
+
|---|---|---|
|
|
281
|
+
| `FORBIDDEN_FILE` | error | A forbidden config file exists at the root |
|
|
282
|
+
| `ROUTE_CONFLICT` | error | Two files resolve to the same route |
|
|
283
|
+
| `MISSING_DEFAULT_EXPORT` | error | A page has no default export |
|
|
284
|
+
| `INVALID_API_EXPORT` | error | An API exports no valid HTTP method |
|
|
285
|
+
| `CLIENT_IMPORTS_SERVER` | error | Client code imports from `server/` |
|
|
286
|
+
| `PUBLIC_ENV_MISUSE` | warning | Client reads a non-`PUBLIC_` env variable |
|
|
287
|
+
|
|
288
|
+
None of them import or run your code — the checks are purely static.
|
|
289
|
+
|
|
290
|
+
## Build output
|
|
291
|
+
|
|
292
|
+
Inside `dist/`:
|
|
293
|
+
|
|
294
|
+
```text
|
|
295
|
+
dist/
|
|
296
|
+
├── client/ Client (index.html + hashed assets)
|
|
297
|
+
├── server/index.mjs Only when server/ exists
|
|
298
|
+
└── vantage-manifest.json Deploy contract (mode: "spa" | "fullstack")
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
`vantage preview` reads the `mode` in `vantage-manifest.json` to decide between starting a Node
|
|
302
|
+
server or serving a static preview. Deployment is covered in detail in
|
|
303
|
+
[Build & deploy](build-and-deploy).
|
|
304
|
+
|
|
305
|
+
## Done
|
|
306
|
+
|
|
307
|
+
That's the end of the app-author guide. Start from the smallest `index.tsx` and add pages, APIs, and
|
|
308
|
+
UI as you need them.
|
|
309
|
+
|
|
310
|
+
To hand those procedures to an AI agent, place the bundled [Agents and Skills](agent-skills)
|
|
311
|
+
with `vantage add skill`, and place the app map `AGENTS.md` with `vantage add agents`.
|