@squadbase/vantage 0.0.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.
Files changed (42) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +95 -0
  3. package/dist/chunk-73J5ZD4C.js +96 -0
  4. package/dist/chunk-73J5ZD4C.js.map +1 -0
  5. package/dist/chunk-ATYZ45XL.js +19 -0
  6. package/dist/chunk-ATYZ45XL.js.map +1 -0
  7. package/dist/chunk-B7LLBNLV.js +23 -0
  8. package/dist/chunk-B7LLBNLV.js.map +1 -0
  9. package/dist/chunk-ZGDU5YLH.js +753 -0
  10. package/dist/chunk-ZGDU5YLH.js.map +1 -0
  11. package/dist/cli.d.ts +1 -0
  12. package/dist/cli.js +765 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/client/index.d.ts +45 -0
  15. package/dist/client/index.js +141 -0
  16. package/dist/client/index.js.map +1 -0
  17. package/dist/define-page-B6y9TOfZ.d.ts +44 -0
  18. package/dist/index.d.ts +15 -0
  19. package/dist/index.js +13 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/query/index.d.ts +11 -0
  22. package/dist/query/index.js +4 -0
  23. package/dist/query/index.js.map +1 -0
  24. package/dist/router/index.d.ts +36 -0
  25. package/dist/router/index.js +27 -0
  26. package/dist/router/index.js.map +1 -0
  27. package/dist/server/index.d.ts +53 -0
  28. package/dist/server/index.js +3 -0
  29. package/dist/server/index.js.map +1 -0
  30. package/dist/server/node.d.ts +35 -0
  31. package/dist/server/node.js +84 -0
  32. package/dist/server/node.js.map +1 -0
  33. package/dist/ui/index.d.ts +217 -0
  34. package/dist/ui/index.js +616 -0
  35. package/dist/ui/index.js.map +1 -0
  36. package/dist/vite/index.d.ts +15 -0
  37. package/dist/vite/index.js +5 -0
  38. package/dist/vite/index.js.map +1 -0
  39. package/package.json +108 -0
  40. package/registry/blocks/sales-overview.tsx +37 -0
  41. package/registry/ui/data-table.tsx +115 -0
  42. package/theme.css +101 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Squadbase
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # @squadbase/vantage
2
+
3
+ Data dashboard framework for [Squadbase](https://squadbase.dev) Editor —
4
+ Vite-powered, config-free, one-file first.
5
+
6
+ You write `index.tsx`. Vantage owns routing, React, TanStack Query, Tailwind v4,
7
+ the UI kit, the dev server, the optional API server, and the build. There is no
8
+ config file.
9
+
10
+ > **Status: prototype (v0.0.1).** APIs may still change between releases.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install @squadbase/vantage
16
+ # or: pnpm add @squadbase/vantage
17
+ ```
18
+
19
+ `react` and `react-dom` (>=18.2) are peer dependencies — install them if your
20
+ project doesn't have them yet.
21
+
22
+ ## Quick start
23
+
24
+ Create a single `index.tsx` at your project root. The default-exported component
25
+ becomes the `/` route:
26
+
27
+ ```tsx
28
+ // index.tsx
29
+ export default function Dashboard() {
30
+ return (
31
+ <main className="p-6">
32
+ <h1 className="text-2xl font-semibold">Dashboard</h1>
33
+ </main>
34
+ );
35
+ }
36
+ ```
37
+
38
+ Add scripts to your `package.json` so the CLI runs with the local binary on
39
+ `PATH`, then start the dev server:
40
+
41
+ ```json
42
+ {
43
+ "scripts": {
44
+ "dev": "vantage dev",
45
+ "build": "vantage build",
46
+ "preview": "vantage preview"
47
+ }
48
+ }
49
+ ```
50
+
51
+ ```bash
52
+ npm run dev # → http://localhost:5173 (HMR + optional API)
53
+ ```
54
+
55
+ Prefer a one-off invocation? Use `pnpm exec vantage dev` or `npx vantage dev` —
56
+ a bare `vantage dev` only works from inside an npm script, where
57
+ `node_modules/.bin` is on `PATH`.
58
+
59
+ ## CLI
60
+
61
+ | Command | What it does |
62
+ |---|---|
63
+ | `vantage dev` | Dev server (HMR + optional API). Default `:5173` |
64
+ | `vantage build` | Production build → `dist/` (client + optional server + `vantage-manifest.json`) |
65
+ | `vantage preview` | Run the production build locally |
66
+ | `vantage check` | Static diagnostics (routes, boundaries, forbidden files). Exit 1 on error |
67
+ | `vantage routes` | Print the page + API URL map |
68
+ | `vantage add` | Copy an editable UI component or block into your project |
69
+ | `vantage doctor` | Report environment / project health |
70
+ | `vantage upgrade` | Regenerate the `.vantage/` artifacts |
71
+
72
+ ## Growing past one file
73
+
74
+ Vantage discovers structure from the filesystem — no config, no route table:
75
+
76
+ - **Pages** — any `*.tsx` with a default export becomes a route
77
+ (`sales/index.tsx` → `/sales`, `sales/[customerId].tsx` → `/sales/:customerId`).
78
+ - **Layouts** — `_layout.tsx` wraps its directory; `_404.tsx` / `_error.tsx`
79
+ handle not-found and errors.
80
+ - **API** — add `server/api/**` handlers to enable a backend; they run
81
+ identically in `dev` and in the production build.
82
+ - **Styling** — Tailwind v4 works out of the box; drop in a `styles.css`.
83
+
84
+ Import only from the curated `@squadbase/vantage` subpaths (`/query`, `/router`,
85
+ `/ui`, `/server`); the internally-managed stack (TanStack, Hono, Vite) is not
86
+ imported directly.
87
+
88
+ ## Documentation
89
+
90
+ Full guides live in the [Vantage docs](https://github.com/squadbase/vantage-framework/tree/main/docs)
91
+ (bilingual — English under `docs/content/en`, Japanese under `docs/content`).
92
+
93
+ ## License
94
+
95
+ [MIT](./LICENSE) © Squadbase
@@ -0,0 +1,96 @@
1
+ import { isHttpError } from './chunk-B7LLBNLV.js';
2
+
3
+ // @squadbase/vantage — generated build. Do not edit.
4
+
5
+ // src/server/dispatch.ts
6
+ function sortApiRoutes(routes) {
7
+ return [...routes].sort((a, b) => {
8
+ if (a.hasCatchall !== b.hasCatchall) return a.hasCatchall ? 1 : -1;
9
+ if (a.staticCount !== b.staticCount) return b.staticCount - a.staticCount;
10
+ return b.segments.length - a.segments.length;
11
+ });
12
+ }
13
+ function matchSegments(segments, parts) {
14
+ const params = {};
15
+ let i = 0;
16
+ for (const seg of segments) {
17
+ if (seg.kind === "catchall") {
18
+ params[seg.name] = parts.slice(i).map(decode).join("/");
19
+ return params;
20
+ }
21
+ if (i >= parts.length) return null;
22
+ if (seg.kind === "static") {
23
+ if (parts[i] !== seg.value) return null;
24
+ } else {
25
+ params[seg.name] = decode(parts[i]);
26
+ }
27
+ i++;
28
+ }
29
+ return i === parts.length ? params : null;
30
+ }
31
+ function decode(s) {
32
+ try {
33
+ return decodeURIComponent(s);
34
+ } catch {
35
+ return s;
36
+ }
37
+ }
38
+ function matchApiRoute(routes, pathname) {
39
+ if (pathname !== "/api" && !pathname.startsWith("/api/")) return null;
40
+ let rest = pathname.slice(4);
41
+ if (rest.startsWith("/")) rest = rest.slice(1);
42
+ if (rest.endsWith("/")) rest = rest.slice(0, -1);
43
+ const parts = rest === "" ? [] : rest.split("/");
44
+ for (const route of routes) {
45
+ const params = matchSegments(route.segments, parts);
46
+ if (params) return { route, params };
47
+ }
48
+ return null;
49
+ }
50
+ function requestId() {
51
+ const g = globalThis;
52
+ if (g.crypto?.randomUUID) return g.crypto.randomUUID();
53
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
54
+ }
55
+ async function dispatchApi(mod, request, params, env) {
56
+ const method = request.method.toUpperCase();
57
+ const handler = mod[method];
58
+ const rid = requestId();
59
+ if (typeof handler !== "function") {
60
+ const allowed = ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS"].filter(
61
+ (m) => typeof mod[m] === "function"
62
+ );
63
+ return Response.json(
64
+ { error: "Method Not Allowed", method: request.method, requestId: rid },
65
+ { status: 405, headers: { Allow: allowed.join(", "), "x-vantage-request-id": rid } }
66
+ );
67
+ }
68
+ const ctx = {
69
+ request,
70
+ params,
71
+ env,
72
+ // Fire-and-forget: runs after the response is sent, on the server's own
73
+ // event loop; errors are swallowed so background work can't crash it.
74
+ waitUntil: (p) => {
75
+ void Promise.resolve(p).catch(() => void 0);
76
+ }
77
+ };
78
+ try {
79
+ const res = await handler(ctx);
80
+ const headers = new Headers(res.headers);
81
+ headers.set("x-vantage-request-id", rid);
82
+ return new Response(res.body, { status: res.status, statusText: res.statusText, headers });
83
+ } catch (err) {
84
+ const status = isHttpError(err) ? err.status : 500;
85
+ const message = isHttpError(err) ? err.message : "Internal Server Error";
86
+ console.error(`[vantage] API error (${rid}) ${request.method} ${new URL(request.url).pathname}:`, err);
87
+ return Response.json(
88
+ { error: message, requestId: rid },
89
+ { status, headers: { "x-vantage-request-id": rid } }
90
+ );
91
+ }
92
+ }
93
+
94
+ export { dispatchApi, matchApiRoute, sortApiRoutes };
95
+ //# sourceMappingURL=chunk-73J5ZD4C.js.map
96
+ //# sourceMappingURL=chunk-73J5ZD4C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/dispatch.ts"],"names":[],"mappings":"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","file":"chunk-73J5ZD4C.js","sourcesContent":["import type { Segment } from \"../core/types.js\"\nimport type { ApiContext, ApiHandler, ApiModule } from \"./index.js\"\nimport { isHttpError } from \"./index.js\"\n\n/** A resolvable API route: its segments plus a lazy module loader. */\nexport interface ApiRouteEntry {\n routePath: string\n segments: Segment[]\n hasCatchall: boolean\n staticCount: number\n load: () => Promise<ApiModule>\n}\n\n/** Order routes so the most specific matches first (static > param > catchall). */\nexport function sortApiRoutes<T extends ApiRouteEntry>(routes: T[]): T[] {\n return [...routes].sort((a, b) => {\n if (a.hasCatchall !== b.hasCatchall) return a.hasCatchall ? 1 : -1\n if (a.staticCount !== b.staticCount) return b.staticCount - a.staticCount\n return b.segments.length - a.segments.length\n })\n}\n\nfunction matchSegments(segments: Segment[], parts: string[]): Record<string, string> | null {\n const params: Record<string, string> = {}\n let i = 0\n for (const seg of segments) {\n if (seg.kind === \"catchall\") {\n params[seg.name] = parts.slice(i).map(decode).join(\"/\")\n return params\n }\n if (i >= parts.length) return null\n if (seg.kind === \"static\") {\n if (parts[i] !== seg.value) return null\n } else {\n params[seg.name] = decode(parts[i]!)\n }\n i++\n }\n return i === parts.length ? params : null\n}\n\nfunction decode(s: string): string {\n try {\n return decodeURIComponent(s)\n } catch {\n return s\n }\n}\n\n/** Match a pathname (e.g. `/api/customers/42`) against the API routes. */\nexport function matchApiRoute(\n routes: ApiRouteEntry[],\n pathname: string,\n): { route: ApiRouteEntry; params: Record<string, string> } | null {\n if (pathname !== \"/api\" && !pathname.startsWith(\"/api/\")) return null\n let rest = pathname.slice(4)\n if (rest.startsWith(\"/\")) rest = rest.slice(1)\n // Normalize a single trailing slash so `/api/customers/` doesn't match a\n // `:id` route with an empty-string param.\n if (rest.endsWith(\"/\")) rest = rest.slice(0, -1)\n const parts = rest === \"\" ? [] : rest.split(\"/\")\n for (const route of routes) {\n const params = matchSegments(route.segments, parts)\n if (params) return { route, params }\n }\n return null\n}\n\n/** Unique per-request id used to correlate the terminal log with the response. */\nfunction requestId(): string {\n const g = globalThis as { crypto?: { randomUUID?: () => string } }\n if (g.crypto?.randomUUID) return g.crypto.randomUUID()\n return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`\n}\n\n/**\n * Invoke a matched API module for a request. Shared by the dev middleware and\n * the production Node server so behavior is identical across environments.\n */\nexport async function dispatchApi(\n mod: ApiModule,\n request: Request,\n params: Record<string, string>,\n env: Record<string, string | undefined>,\n): Promise<Response> {\n const method = request.method.toUpperCase() as keyof ApiModule\n const handler = mod[method] as ApiHandler | undefined\n const rid = requestId()\n\n if (typeof handler !== \"function\") {\n const allowed = ([\"GET\", \"POST\", \"PUT\", \"PATCH\", \"DELETE\", \"OPTIONS\"] as const).filter(\n (m) => typeof mod[m] === \"function\",\n )\n return Response.json(\n { error: \"Method Not Allowed\", method: request.method, requestId: rid },\n { status: 405, headers: { Allow: allowed.join(\", \"), \"x-vantage-request-id\": rid } },\n )\n }\n\n const ctx: ApiContext = {\n request,\n params,\n env,\n // Fire-and-forget: runs after the response is sent, on the server's own\n // event loop; errors are swallowed so background work can't crash it.\n waitUntil: (p) => {\n void Promise.resolve(p).catch(() => undefined)\n },\n }\n\n try {\n const res = await handler(ctx)\n // waitUntil work runs after the response is returned, never blocking it.\n const headers = new Headers(res.headers)\n headers.set(\"x-vantage-request-id\", rid)\n return new Response(res.body, { status: res.status, statusText: res.statusText, headers })\n } catch (err) {\n const status = isHttpError(err) ? err.status : 500\n // Only surface intentional HttpError messages; internal errors are logged\n // server-side but returned generically to avoid information disclosure.\n const message = isHttpError(err) ? err.message : \"Internal Server Error\"\n // Logged with request id so agents can correlate terminal + response.\n console.error(`[vantage] API error (${rid}) ${request.method} ${new URL(request.url).pathname}:`, err)\n return Response.json(\n { error: message, requestId: rid },\n { status, headers: { \"x-vantage-request-id\": rid } },\n )\n }\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import { QueryClient } from '@tanstack/react-query';
2
+
3
+ // @squadbase/vantage — generated build. Do not edit.
4
+
5
+ function createQueryClient() {
6
+ return new QueryClient({
7
+ defaultOptions: {
8
+ queries: {
9
+ staleTime: 3e4,
10
+ retry: 1,
11
+ refetchOnWindowFocus: false
12
+ }
13
+ }
14
+ });
15
+ }
16
+
17
+ export { createQueryClient };
18
+ //# sourceMappingURL=chunk-ATYZ45XL.js.map
19
+ //# sourceMappingURL=chunk-ATYZ45XL.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/query/client.ts"],"names":[],"mappings":";;;;AAOO,SAAS,iBAAA,GAAiC;AAC/C,EAAA,OAAO,IAAI,WAAA,CAAY;AAAA,IACrB,cAAA,EAAgB;AAAA,MACd,OAAA,EAAS;AAAA,QACP,SAAA,EAAW,GAAA;AAAA,QACX,KAAA,EAAO,CAAA;AAAA,QACP,oBAAA,EAAsB;AAAA;AACxB;AACF,GACD,CAAA;AACH","file":"chunk-ATYZ45XL.js","sourcesContent":["import { QueryClient } from \"@tanstack/react-query\"\n\n/**\n * Create the QueryClient with Vantage defaults. Individual queries may override\n * these, but replacing the QueryClient wholesale is intentionally not exposed —\n * Squadbase relies on a single managed client for auth, logging and telemetry.\n */\nexport function createQueryClient(): QueryClient {\n return new QueryClient({\n defaultOptions: {\n queries: {\n staleTime: 30_000,\n retry: 1,\n refetchOnWindowFocus: false,\n },\n },\n })\n}\n"]}
@@ -0,0 +1,23 @@
1
+ // @squadbase/vantage — generated build. Do not edit.
2
+
3
+ // src/server/index.ts
4
+ function json(data, init) {
5
+ return Response.json(data, init);
6
+ }
7
+ var HTTP_ERROR_BRAND = /* @__PURE__ */ Symbol.for("vantage.HttpError");
8
+ var HttpError = class extends Error {
9
+ status;
10
+ [HTTP_ERROR_BRAND] = true;
11
+ constructor(status, message) {
12
+ super(message);
13
+ this.status = status;
14
+ this.name = "HttpError";
15
+ }
16
+ };
17
+ function isHttpError(err) {
18
+ return typeof err === "object" && err !== null && err[HTTP_ERROR_BRAND] === true;
19
+ }
20
+
21
+ export { HttpError, isHttpError, json };
22
+ //# sourceMappingURL=chunk-B7LLBNLV.js.map
23
+ //# sourceMappingURL=chunk-B7LLBNLV.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/server/index.ts"],"names":[],"mappings":";;;AAiCO,SAAS,IAAA,CAAK,MAAe,IAAA,EAA+B;AACjE,EAAA,OAAO,QAAA,CAAS,IAAA,CAAK,IAAA,EAAM,IAAI,CAAA;AACjC;AAUA,IAAM,gBAAA,mBAAkC,MAAA,CAAO,GAAA,CAAI,mBAAmB,CAAA;AAG/D,IAAM,SAAA,GAAN,cAAwB,KAAA,CAAM;AAAA,EACnC,MAAA;AAAA,EACA,CAAU,gBAAgB,IAAI,IAAA;AAAA,EAC9B,WAAA,CAAY,QAAgB,OAAA,EAAiB;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AACb,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,IAAA,CAAK,IAAA,GAAO,WAAA;AAAA,EACd;AACF;AAOO,SAAS,YAAY,GAAA,EAAgC;AAC1D,EAAA,OACE,OAAO,GAAA,KAAQ,QAAA,IACf,QAAQ,IAAA,IACP,GAAA,CAAqC,gBAAgB,CAAA,KAAM,IAAA;AAEhE","file":"chunk-B7LLBNLV.js","sourcesContent":["/**\n * `@squadbase/vantage/server` — the server API contract.\n *\n * API modules under `server/api/**` export HTTP method handlers that receive an\n * `ApiContext` built from Web Standards (`Request`, `Response`, `URL`).\n */\n\n/** Context passed to every API handler. */\nexport interface ApiContext {\n /** The incoming Web `Request`. */\n request: Request\n /** Route params, e.g. `{ customerId: \"42\" }`. */\n params: Record<string, string>\n /** Server environment variables (secrets included; never sent to the client). */\n env: Record<string, string | undefined>\n /** Register background work to run after the response is sent. */\n waitUntil(promise: Promise<unknown>): void\n}\n\n/** An API method handler. */\nexport type ApiHandler = (ctx: ApiContext) => Response | Promise<Response>\n\n/** The set of method exports an API module may provide. */\nexport interface ApiModule {\n GET?: ApiHandler\n POST?: ApiHandler\n PUT?: ApiHandler\n PATCH?: ApiHandler\n DELETE?: ApiHandler\n OPTIONS?: ApiHandler\n}\n\n/** Convenience JSON response helper (equivalent to `Response.json`). */\nexport function json(data: unknown, init?: ResponseInit): Response {\n return Response.json(data, init)\n}\n\n/**\n * Stable cross-realm brand. `instanceof HttpError` breaks when this module is\n * evaluated in two realms — in dev the user's API module is loaded through\n * Vite's `ssrLoadModule`, a separate module graph from the Node-side dispatch\n * chunk — so the two `HttpError` classes are different objects. `Symbol.for`\n * draws from the process-global registry, so every realm resolves the same\n * symbol; `isHttpError` matches on this brand instead of class identity.\n */\nconst HTTP_ERROR_BRAND: unique symbol = Symbol.for(\"vantage.HttpError\")\n\n/** Throwable HTTP error that the runtime converts into a JSON response. */\nexport class HttpError extends Error {\n status: number\n readonly [HTTP_ERROR_BRAND] = true\n constructor(status: number, message: string) {\n super(message)\n this.status = status\n this.name = \"HttpError\"\n }\n}\n\n/**\n * Realm-independent check for {@link HttpError}. Use this instead of\n * `instanceof` anywhere an error may have crossed a module-realm boundary\n * (notably the dev `ssrLoadModule` seam), so dev and prod behave identically.\n */\nexport function isHttpError(err: unknown): err is HttpError {\n return (\n typeof err === \"object\" &&\n err !== null &&\n (err as Record<PropertyKey, unknown>)[HTTP_ERROR_BRAND] === true\n )\n}\n"]}