@malloy-publisher/server 0.0.197-dev → 0.0.197
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.docker.md +88 -20
- package/README.md +15 -0
- package/build.ts +16 -0
- package/dist/app/api-doc.yaml +20 -3
- package/dist/app/assets/EnvironmentPage-BVkQH_xQ.js +1 -0
- package/dist/app/assets/HomePage-BgH9UkjK.js +1 -0
- package/dist/app/assets/MainPage-DiBxABem.js +2 -0
- package/dist/app/assets/ModelPage-oS70fj83.js +1 -0
- package/dist/app/assets/PackagePage-F_qLDAdv.js +1 -0
- package/dist/app/assets/RouteError-WqpffppN.js +1 -0
- package/dist/app/assets/WorkbookPage-_YmC-ebR.js +1 -0
- package/dist/app/assets/{core-w79IMXAG.es-Bd0UlzOL.js → core-B8L9xCYT.es-BcRLJTnC.js} +14 -14
- package/dist/app/assets/index-BMViiwtJ.js +451 -0
- package/dist/app/assets/{index-C513UodQ.js → index-C3XPaTaS.js} +15 -15
- package/dist/app/assets/index-rg8Ok8nl.js +1803 -0
- package/dist/app/assets/{index.umd-BMeMPq_9.js → index.umd-CCAfKkxY.js} +1 -1
- package/dist/app/index.html +2 -3
- package/dist/default-publisher.config.json +23 -0
- package/dist/instrumentation.mjs +1 -3
- package/dist/server.mjs +958 -177
- package/package.json +11 -12
- package/publisher.config.example.bigquery.json +33 -0
- package/publisher.config.example.duckdb.json +23 -0
- package/publisher.config.json +1 -11
- package/src/config.spec.ts +225 -0
- package/src/config.ts +96 -2
- package/src/controller/connection.controller.ts +1 -1
- package/src/default-publisher.config.json +23 -0
- package/src/errors.spec.ts +42 -0
- package/src/errors.ts +8 -0
- package/src/health.ts +26 -0
- package/src/logger.ts +1 -3
- package/src/pg_helpers.spec.ts +226 -0
- package/src/pg_helpers.ts +129 -0
- package/src/server-old.ts +1119 -0
- package/src/server.ts +36 -0
- package/src/service/connection.spec.ts +6 -4
- package/src/service/connection.ts +8 -3
- package/src/service/connection_config.ts +2 -2
- package/src/service/environment.ts +53 -25
- package/src/service/environment_store.spec.ts +19 -0
- package/src/service/environment_store.ts +21 -2
- package/src/service/package.ts +4 -3
- package/src/storage/StorageManager.ts +71 -11
- package/src/storage/duckdb/schema.ts +41 -0
- package/src/utils.ts +11 -0
- package/tests/harness/rest_e2e.ts +2 -2
- package/tests/integration/legacy_routes/legacy_routes.integration.spec.ts +259 -0
- package/tests/unit/duckdb/attached_databases.test.ts +5 -5
- package/tests/unit/duckdb/legacy_schema_migration.test.ts +194 -0
- package/tests/unit/storage/StorageManager.test.ts +166 -0
- package/dist/app/assets/EnvironmentPage-1j6QDWAy.js +0 -1
- package/dist/app/assets/HomePage-DMop21VG.js +0 -1
- package/dist/app/assets/MainPage-BbE8ETz1.js +0 -2
- package/dist/app/assets/ModelPage-D2jvfe3t.js +0 -1
- package/dist/app/assets/PackagePage-BbnhGoD3.js +0 -1
- package/dist/app/assets/RouteError-D3LGEZ3i.js +0 -1
- package/dist/app/assets/WorkbookPage-DttVIj4u.js +0 -1
- package/dist/app/assets/index-5K9YjIxF.js +0 -456
- package/dist/app/assets/index-DIgzgp69.js +0 -1742
package/README.docker.md
CHANGED
|
@@ -1,32 +1,100 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Publisher in Docker
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
The canonical build is the root [`Dockerfile`](../../Dockerfile) and the CI smoke test (`docker_smoke_test` in `.github/workflows/build.yml`) builds and runs that exact image. The two-port REST + MCP server, the Snowflake ADBC driver, the DuckDB CLI, and the production app bundle all ship in it.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
A short Docker section in the [repo root README](../../README.md#docker) covers the canonical build + run; this doc goes deeper on runtime layout, environment variables, persistent storage, and credentials.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Build and run
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
```bash
|
|
10
|
+
docker build -t malloy-publisher .
|
|
11
|
+
docker run -d \
|
|
12
|
+
--name malloy-publisher \
|
|
13
|
+
-p 4000:4000 -p 4040:4040 \
|
|
14
|
+
-v $(pwd)/publisher.config.json:/publisher/publisher.config.json:ro \
|
|
15
|
+
malloy-publisher
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Once `/api/v0/status` reports `operationalState: "serving"`, the REST API is at `http://localhost:4000` and MCP at `http://localhost:4040/mcp`.
|
|
19
|
+
|
|
20
|
+
If you don't have a config of your own yet, copy [`packages/server/publisher.config.example.duckdb.json`](./publisher.config.example.duckdb.json) (DuckDB-only samples, no credentials required) and mount that. There's also a [`publisher.config.example.bigquery.json`](./publisher.config.example.bigquery.json) sibling for the BigQuery samples.
|
|
21
|
+
|
|
22
|
+
## Pre-built image
|
|
23
|
+
|
|
24
|
+
If you don't want to build the image yourself, the official pre-built image is published to Docker Hub under the **`ms2data/`** namespace (not `malloydata/`):
|
|
10
25
|
|
|
11
|
-
|
|
26
|
+
```bash
|
|
27
|
+
docker pull ms2data/malloy-publisher
|
|
28
|
+
docker run -d \
|
|
29
|
+
--name malloy-publisher \
|
|
30
|
+
-p 4000:4000 -p 4040:4040 \
|
|
31
|
+
-v $(pwd)/publisher.config.json:/publisher/publisher.config.json:ro \
|
|
32
|
+
ms2data/malloy-publisher
|
|
33
|
+
```
|
|
12
34
|
|
|
13
|
-
|
|
14
|
-
docker build -t malloy-publisher:latest -f docker/production.docker .
|
|
15
|
-
docker build -t malloy-samples:latest -f docker/malloy-samples.docker .
|
|
16
|
-
```
|
|
35
|
+
See the [Docker Hub tags page](https://hub.docker.com/r/ms2data/malloy-publisher/tags) for available versions. Tag-scheme guidance (`:latest`, `:X.Y.Z`, `:next`) lives in the root README's [Docker section](../../README.md#docker).
|
|
17
36
|
|
|
18
|
-
|
|
19
|
-
The Publisher server runs at port 4000, the MCP server at port 4040.
|
|
37
|
+
## Runtime layout
|
|
20
38
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
39
|
+
| Path inside container | What's there |
|
|
40
|
+
|---|---|
|
|
41
|
+
| `/publisher/` | `WORKDIR`. The server reads `<WORKDIR>/publisher.config.json` by default — that's the file you mount. |
|
|
42
|
+
| `/publisher/packages/server/dist/` | The bundled server (built by `bun run build` in CI). |
|
|
43
|
+
| `/publisher/packages/app/dist/` | The static SPA the server serves. |
|
|
44
|
+
| `/publisher/publisher_data/` | Per-environment package clones, DuckDB extension cache, and per-package sandbox DBs. Created at runtime; **persist this as a named volume if you want first-run sample clones to survive a container restart.** |
|
|
45
|
+
| `/root/.duckdb/` | DuckDB CLI + extension install dir. Bundled into the image. |
|
|
24
46
|
|
|
25
|
-
|
|
26
|
-
Note that you cannot use personal credentials- only service account credentials can be used in the docker image.
|
|
47
|
+
To keep `publisher_data/` across restarts:
|
|
27
48
|
|
|
28
49
|
```bash
|
|
29
|
-
docker run -
|
|
30
|
-
|
|
31
|
-
|
|
50
|
+
docker run -d \
|
|
51
|
+
--name malloy-publisher \
|
|
52
|
+
-p 4000:4000 -p 4040:4040 \
|
|
53
|
+
-v $(pwd)/publisher.config.json:/publisher/publisher.config.json:ro \
|
|
54
|
+
-v publisher_data:/publisher/publisher_data \
|
|
55
|
+
malloy-publisher
|
|
32
56
|
```
|
|
57
|
+
|
|
58
|
+
The first request after a fresh start clones sample packages from GitHub — a named volume turns that one-time cost into a one-time cost across all container lifecycles.
|
|
59
|
+
|
|
60
|
+
For the same pattern as a complete Compose file (with a healthcheck against `/api/v0/status` and both ports mapped), see [`docker-compose.example.yml`](../../docker-compose.example.yml) at the repo root.
|
|
61
|
+
|
|
62
|
+
## Configuration via environment variables
|
|
63
|
+
|
|
64
|
+
All flags exposed by `bin/malloy-publisher --help` have an equivalent env var, so they're easy to set from `docker run -e` or compose:
|
|
65
|
+
|
|
66
|
+
| Env var | Equivalent flag | Default | Purpose |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `PUBLISHER_PORT` | `--port <n>` | `4000` | REST API port. |
|
|
69
|
+
| `PUBLISHER_HOST` | `--host <h>` | `0.0.0.0` | Bind address. |
|
|
70
|
+
| `MCP_PORT` | `--mcp_port <n>` | `4040` | MCP API port. |
|
|
71
|
+
| `SERVER_ROOT` | `--server_root <path>` | `.` (cwd) at the server level; overridden to `/publisher` by the bundled CMD | Directory the server treats as its working dir. The image's CMD passes `--server_root /publisher` explicitly so the zero-arg `npx` bundled-default trigger doesn't fire inside the container. If you override CMD with your own entrypoint, set `SERVER_ROOT` yourself to keep this behaviour. |
|
|
72
|
+
| `PUBLISHER_CONFIG_PATH` | `--config <path>` | unset | Absolute path to a `publisher.config.json`. Wins over `<SERVER_ROOT>/publisher.config.json`. Use this if you want to mount your config somewhere other than `/publisher/`. |
|
|
73
|
+
| `INITIALIZE_STORAGE` | `--init` | `false` | Wipes persisted storage state on startup. Useful when `frozenConfig: false` has let `publisher_data/` drift from the on-disk config; destructive otherwise. |
|
|
74
|
+
| `SHUTDOWN_DRAIN_DURATION_SECONDS` | — | `0` | On SIGTERM, how long to keep accepting requests while draining before closing server sockets. Set this to your typical request duration to avoid 502s from K8s rolling deploys. |
|
|
75
|
+
| `SHUTDOWN_GRACEFUL_CLOSE_TIMEOUT_SECONDS` | — | `0` | Additional grace period after server close before `process.exit`. |
|
|
76
|
+
| `GOOGLE_APPLICATION_CREDENTIALS` | — | unset | Path inside the container to a GCP service-account JSON. Required for BigQuery-backed environments. Personal user credentials don't work inside the container — use a service account. |
|
|
77
|
+
|
|
78
|
+
## BigQuery credentials
|
|
79
|
+
|
|
80
|
+
To enable BigQuery samples or your own BigQuery connections, mount a service-account key and point `GOOGLE_APPLICATION_CREDENTIALS` at it:
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
docker run -d \
|
|
84
|
+
--name malloy-publisher \
|
|
85
|
+
-p 4000:4000 -p 4040:4040 \
|
|
86
|
+
-v $(pwd)/publisher.config.json:/publisher/publisher.config.json:ro \
|
|
87
|
+
-v $(pwd)/gcp-sa.json:/etc/publisher/gcp-sa.json:ro \
|
|
88
|
+
-e GOOGLE_APPLICATION_CREDENTIALS=/etc/publisher/gcp-sa.json \
|
|
89
|
+
malloy-publisher
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
The Dockerfile creates `/etc/publisher/` as an empty directory outside the application tree at `/publisher/`. By the convention this doc establishes, mount credential material there to keep it separated from the app — but any writable path inside the container works.
|
|
93
|
+
|
|
94
|
+
## The CI Dockerfile (`docker/Dockerfile.ci`)
|
|
95
|
+
|
|
96
|
+
`docker/Dockerfile.ci` exists for the CI integration-test path (referenced from the repo's `docker-compose.yml`). It is **not** the production image and should not be used for deployment. Production users build the root [`Dockerfile`](../../Dockerfile).
|
|
97
|
+
|
|
98
|
+
## Deprecated build paths
|
|
99
|
+
|
|
100
|
+
`docker/production.docker` and `docker/malloy-samples.docker` are leftover from a previous Docker layout. They are not built by CI, are not referenced by any current workflow, and produce a different image than what is deployed. Don't use them. They will be removed in a follow-up cleanup PR; the audit and tracking is in `publisher-audit-docker.md` (finding #1).
|
package/README.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
The Malloy Publisher Server is an Express.js server that provides an API for managing and accessing Malloy data models, packages, and queries
|
|
4
4
|
|
|
5
|
+
## Configuration
|
|
6
|
+
|
|
7
|
+
`publisher.config.json` lives in this directory. The repository root also contains a symlink (`/publisher.config.json` → `./packages/server/publisher.config.json`) so that running the server from either location picks up the same config. Edit one and you've edited both.
|
|
8
|
+
|
|
9
|
+
For the BigQuery-enabled variant, see [`publisher.config.example.bigquery.json`](./publisher.config.example.bigquery.json) and the [Quick Start in the repo root README](../../README.md#quick-start).
|
|
10
|
+
|
|
11
|
+
### Remaining deprecation warnings
|
|
12
|
+
|
|
13
|
+
Removing the unused `trino` CLI direct dep (it pulled in `@google-cloud/translate@0.7.x` → `request@2.x` → `har-validator` → `hawk` → `cryptiles`) cleaned the worst chain. About 25 `npm warn deprecated` lines remain on `npx @malloy-publisher/server` install, all upstream-owned:
|
|
14
|
+
|
|
15
|
+
- **npm CLI tooling**: `npmlog`, `gauge`, `are-we-there-yet`, `glob@7/8/10`, `rimraf@3`, `tar@6.2.1`, `inflight`, `@npmcli/move-file`, `node-domexception`, `querystring` — pulled in by npm itself and by `node-pre-gyp`/`node-gyp`. Not actionable from this repo.
|
|
16
|
+
- **`uuid@8.x` / `uuid@9.x`**: surfaced across multiple transitives (Malloy, AWS SDKs, others). Resolves when each upstream bumps to `uuid@11`.
|
|
17
|
+
- **`q@1.5.1`**: pulled in via `thrift` → `@databricks/sql` → `@malloydata/db-databricks`. Resolves when Databricks upgrades `@databricks/sql` past the thrift dep, or when we replace the Databricks driver.
|
|
18
|
+
- **`aws-sdk@2.1693.0`**: listed as a direct dep in `packages/server/package.json` but not imported anywhere in source — leftover, candidate for removal in a follow-up PR. The actual consumer is `@aws-sdk/client-s3` v3.
|
|
19
|
+
|
|
5
20
|
## K6 Test Presets
|
|
6
21
|
|
|
7
22
|
The Malloy Publisher Server includes several K6 test presets to help you test its performance and stability.
|
package/build.ts
CHANGED
|
@@ -29,6 +29,22 @@ await build({
|
|
|
29
29
|
|
|
30
30
|
fs.cpSync("../app/dist", "./dist/app", { recursive: true });
|
|
31
31
|
|
|
32
|
+
// Ship a default publisher.config.json inside the bundle so that
|
|
33
|
+
// `npx @malloy-publisher/server` works with zero args (uses
|
|
34
|
+
// DuckDB-only samples). config.ts looks for this file next to
|
|
35
|
+
// server.mjs.
|
|
36
|
+
//
|
|
37
|
+
// IMPORTANT: keep `packages/server/src/default-publisher.config.json`
|
|
38
|
+
// in sync with `packages/server/publisher.config.json`. The two files
|
|
39
|
+
// have intentionally identical content — the committed one drives the
|
|
40
|
+
// dev workflow (`bun run start`, integration tests), the bundled one
|
|
41
|
+
// is the fallback for npx users with no config of their own. A drift
|
|
42
|
+
// here surfaces as "npx users see different samples than dev users."
|
|
43
|
+
fs.copyFileSync(
|
|
44
|
+
"./src/default-publisher.config.json",
|
|
45
|
+
"./dist/default-publisher.config.json",
|
|
46
|
+
);
|
|
47
|
+
|
|
32
48
|
// Rename ESM outputs to .mjs so both Node and Bun can execute them
|
|
33
49
|
fs.renameSync("./dist/server.js", "./dist/server.mjs");
|
|
34
50
|
fs.renameSync("./dist/instrumentation.js", "./dist/instrumentation.mjs");
|
package/dist/app/api-doc.yaml
CHANGED
|
@@ -2498,11 +2498,28 @@ components:
|
|
|
2498
2498
|
description: Whether the server is fully initialized and ready to serve requests
|
|
2499
2499
|
operationalState:
|
|
2500
2500
|
type: string
|
|
2501
|
-
enum: [ "initializing", "serving", "draining" ]
|
|
2501
|
+
enum: [ "initializing", "serving", "degraded", "draining" ]
|
|
2502
2502
|
description: Status of the server; initializing when the server is loading
|
|
2503
2503
|
environments, packages and connections, serving when the server is
|
|
2504
|
-
initialized and ready to serve requests,
|
|
2505
|
-
|
|
2504
|
+
initialized and ready to serve requests, degraded when initialization
|
|
2505
|
+
completed but one or more environments failed to load (the surviving
|
|
2506
|
+
environments are served; see failedEnvironments), and draining when
|
|
2507
|
+
the server is going to shut down
|
|
2508
|
+
failedEnvironments:
|
|
2509
|
+
type: array
|
|
2510
|
+
description: Environments that failed to initialize. Present only when
|
|
2511
|
+
operationalState is "degraded". Healthy environments are listed under
|
|
2512
|
+
"environments".
|
|
2513
|
+
items:
|
|
2514
|
+
type: object
|
|
2515
|
+
required: [name, error]
|
|
2516
|
+
properties:
|
|
2517
|
+
name:
|
|
2518
|
+
type: string
|
|
2519
|
+
description: Environment name as declared in publisher.config.json
|
|
2520
|
+
error:
|
|
2521
|
+
type: string
|
|
2522
|
+
description: Error message from the initialization failure
|
|
2506
2523
|
frozenConfig:
|
|
2507
2524
|
type: boolean
|
|
2508
2525
|
description: Whether the server configuration is frozen (read-only mode). When
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{S as r,F as t,j as e,_ as i,a2 as o}from"./index-BMViiwtJ.js";function m(){const s=r(),{environmentName:n}=t();if(n){const a=i({environmentName:n});return e.jsx(o,{onSelectPackage:s,resourceUri:a})}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing environment name"})})}export{m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{S as t,j as o,L as a}from"./index-BMViiwtJ.js";function s(){const n=t();return o.jsx(a,{onClickEnvironment:n})}export{s as default};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{u as we,g as ke,r as u,R as Se,a as Pe,c as $,j as t,s as I,B as Ce,m as _,e as re,b as oe,d as se,f as ae,h as Ee,i as O,k as ie,T as K,l as G,n as Ie,o as Me,p as Re,q as le,t as ze,v as ne,w as De,x as Te,y as Be,z as A,A as L,M as $e,P as He,C as Le,D as Ne,E as Ae,F as ce,S as J,G as x,H as We,I as X,J as Oe,K as Z,X as Ve,N as Ue,O as de,Q as pe,U as ue,V as he,W as Qe,Y as Fe,Z as Xe}from"./index-BMViiwtJ.js";function Ye(e,r,n,o,s){const[a,i]=u.useState(()=>s&&n?n(e).matches:o?o(e).matches:r);return Pe(()=>{if(!n)return;const c=n(e),h=()=>{i(c.matches)};return h(),c.addEventListener("change",h),()=>{c.removeEventListener("change",h)}},[e,n]),a}const _e={...Se},fe=_e.useSyncExternalStore;function Ke(e,r,n,o,s){const a=u.useCallback(()=>r,[r]),i=u.useMemo(()=>{if(s&&n)return()=>n(e).matches;if(o!==null){const{matches:p}=o(e);return()=>p}return a},[a,e,o,s,n]),[c,h]=u.useMemo(()=>{if(n===null)return[a,()=>()=>{}];const p=n(e);return[()=>p.matches,m=>(p.addEventListener("change",m),()=>{p.removeEventListener("change",m)})]},[a,n,e]);return fe(h,c,i)}function me(e={}){const{themeId:r}=e;return function(o,s={}){let a=we();a&&r&&(a=a[r]||a);const i=typeof window<"u"&&typeof window.matchMedia<"u",{defaultMatches:c=!1,matchMedia:h=i?window.matchMedia:null,ssrMatchMedia:f=null,noSsr:p=!1}=ke({name:"MuiUseMediaQuery",props:s,theme:a});let m=typeof o=="function"?o(a):o;return m=m.replace(/^@media( ?)/m,""),m.includes("print")&&console.warn(["MUI: You have provided a `print` query to the `useMediaQuery` hook.","Using the print media query to modify print styles can lead to unexpected results.","Consider using the `displayPrint` field in the `sx` prop instead.","More information about `displayPrint` on our docs: https://mui.com/system/display/#display-in-print."].join(`
|
|
2
|
+
`)),(fe!==void 0?Ke:Ye)(m,c,h,f,p)}}me();const Ge=$(t.jsx("path",{d:"M6 10c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm12 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm-6 0c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"})),Je=I(Ce,{name:"MuiBreadcrumbCollapsed"})(_(({theme:e})=>({display:"flex",marginLeft:`calc(${e.spacing(1)} * 0.5)`,marginRight:`calc(${e.spacing(1)} * 0.5)`,...e.palette.mode==="light"?{backgroundColor:e.palette.grey[100],color:e.palette.grey[700]}:{backgroundColor:e.palette.grey[700],color:e.palette.grey[100]},borderRadius:2,"&:hover, &:focus":{...e.palette.mode==="light"?{backgroundColor:e.palette.grey[200]}:{backgroundColor:e.palette.grey[600]}},"&:active":{boxShadow:e.shadows[0],...e.palette.mode==="light"?{backgroundColor:re(e.palette.grey[200],.12)}:{backgroundColor:re(e.palette.grey[600],.12)}}}))),Ze=I(Ge)({width:24,height:16});function qe(e){const{slots:r={},slotProps:n={},...o}=e,s=e;return t.jsx("li",{children:t.jsx(Je,{focusRipple:!0,...o,ownerState:s,children:t.jsx(Ze,{as:r.CollapsedIcon,ownerState:s,...n.collapsedIcon})})})}function et(e){return se("MuiBreadcrumbs",e)}const tt=oe("MuiBreadcrumbs",["root","ol","li","separator"]),rt=e=>{const{classes:r}=e;return ie({root:["root"],li:["li"],ol:["ol"],separator:["separator"]},et,r)},nt=I(K,{name:"MuiBreadcrumbs",slot:"Root",overridesResolver:(e,r)=>[{[`& .${tt.li}`]:r.li},r.root]})({}),ot=I("ol",{name:"MuiBreadcrumbs",slot:"Ol"})({display:"flex",flexWrap:"wrap",alignItems:"center",padding:0,margin:0,listStyle:"none"}),st=I("li",{name:"MuiBreadcrumbs",slot:"Separator"})({display:"flex",userSelect:"none",marginLeft:8,marginRight:8});function at(e,r,n,o){return e.reduce((s,a,i)=>(i<e.length-1?s=s.concat(a,t.jsx(st,{"aria-hidden":!0,className:r,ownerState:o,children:n},`separator-${i}`)):s.push(a),s),[])}const it=u.forwardRef(function(r,n){const o=ae({props:r,name:"MuiBreadcrumbs"}),{children:s,className:a,component:i="nav",slots:c={},slotProps:h={},expandText:f="Show path",itemsAfterCollapse:p=1,itemsBeforeCollapse:m=1,maxItems:y=8,separator:S="/",...H}=o,[M,P]=u.useState(!1),v={...o,component:i,expanded:M,expandText:f,itemsAfterCollapse:p,itemsBeforeCollapse:m,maxItems:y,separator:S},C=rt(v),R=Ee({elementType:c.CollapsedIcon,externalSlotProps:h.collapsedIcon,ownerState:v}),j=u.useRef(null),w=d=>{const k=()=>{P(!0);const b=j.current.querySelector("a[href],button,[tabindex]");b&&b.focus()};return m+p>=d.length?d:[...d.slice(0,m),t.jsx(qe,{"aria-label":f,slots:{CollapsedIcon:c.CollapsedIcon},slotProps:{collapsedIcon:R},onClick:k},"ellipsis"),...d.slice(d.length-p,d.length)]},z=u.Children.toArray(s).filter(d=>u.isValidElement(d)).map((d,k)=>t.jsx("li",{className:C.li,children:d},`child-${k}`));return t.jsx(nt,{ref:n,component:i,color:"textSecondary",className:O(C.root,a),ownerState:v,...H,children:t.jsx(ot,{className:C.ol,ref:j,ownerState:v,children:at(M||y&&z.length<=y?z:w(z),C.separator,S,v)})})});function lt(e,r,n){const o=r.getBoundingClientRect(),s=n&&n.getBoundingClientRect(),a=le(r);let i;if(r.fakeTransform)i=r.fakeTransform;else{const f=a.getComputedStyle(r);i=f.getPropertyValue("-webkit-transform")||f.getPropertyValue("transform")}let c=0,h=0;if(i&&i!=="none"&&typeof i=="string"){const f=i.split("(")[1].split(")")[0].split(",");c=parseInt(f[4],10),h=parseInt(f[5],10)}return e==="left"?s?`translateX(${s.right+c-o.left}px)`:`translateX(${a.innerWidth+c-o.left}px)`:e==="right"?s?`translateX(-${o.right-s.left-c}px)`:`translateX(-${o.left+o.width-c}px)`:e==="up"?s?`translateY(${s.bottom+h-o.top}px)`:`translateY(${a.innerHeight+h-o.top}px)`:s?`translateY(-${o.top-s.top+o.height-h}px)`:`translateY(-${o.top+o.height-h}px)`}function ct(e){return typeof e=="function"?e():e}function W(e,r,n){const o=ct(n),s=lt(e,r,o);s&&(r.style.webkitTransform=s,r.style.transform=s)}const dt=u.forwardRef(function(r,n){const o=G(),s={enter:o.transitions.easing.easeOut,exit:o.transitions.easing.sharp},a={enter:o.transitions.duration.enteringScreen,exit:o.transitions.duration.leavingScreen},{addEndListener:i,appear:c=!0,children:h,container:f,direction:p="down",easing:m=s,in:y,onEnter:S,onEntered:H,onEntering:M,onExit:P,onExited:v,onExiting:C,style:R,timeout:j=a,TransitionComponent:w=Ie,...z}=r,d=u.useRef(null),k=Me(Re(h),d,n),b=l=>g=>{l&&(g===void 0?l(d.current):l(d.current,g))},V=b((l,g)=>{W(p,l,f),De(l),S&&S(l,g)}),q=b((l,g)=>{const B=ne({timeout:j,style:R,easing:m},{mode:"enter"});l.style.webkitTransition=o.transitions.create("-webkit-transform",{...B}),l.style.transition=o.transitions.create("transform",{...B}),l.style.webkitTransform="none",l.style.transform="none",M&&M(l,g)}),D=b(H),T=b(C),E=b(l=>{const g=ne({timeout:j,style:R,easing:m},{mode:"exit"});l.style.webkitTransition=o.transitions.create("-webkit-transform",g),l.style.transition=o.transitions.create("transform",g),W(p,l,f),P&&P(l)}),U=b(l=>{l.style.webkitTransition="",l.style.transition="",v&&v(l)}),Q=l=>{i&&i(d.current,l)},N=u.useCallback(()=>{d.current&&W(p,d.current,f)},[p,f]);return u.useEffect(()=>{if(y||p==="down"||p==="right")return;const l=ze(()=>{d.current&&W(p,d.current,f)}),g=le(d.current);return g.addEventListener("resize",l),()=>{l.clear(),g.removeEventListener("resize",l)}},[p,y,f]),u.useEffect(()=>{y||N()},[y,N]),t.jsx(w,{nodeRef:d,onEnter:V,onEntered:D,onEntering:q,onExit:E,onExited:U,onExiting:T,addEndListener:Q,appear:c,in:y,timeout:j,...z,children:(l,{ownerState:g,...B})=>u.cloneElement(h,{ref:k,style:{visibility:l==="exited"&&!y?"hidden":void 0,...R,...h.props.style},...B})})});function pt(e){return se("MuiDrawer",e)}oe("MuiDrawer",["root","docked","paper","anchorLeft","anchorRight","anchorTop","anchorBottom","paperAnchorLeft","paperAnchorRight","paperAnchorTop","paperAnchorBottom","paperAnchorDockedLeft","paperAnchorDockedRight","paperAnchorDockedTop","paperAnchorDockedBottom","modal"]);const xe=(e,r)=>{const{ownerState:n}=e;return[r.root,(n.variant==="permanent"||n.variant==="persistent")&&r.docked,r.modal]},ut=e=>{const{classes:r,anchor:n,variant:o}=e,s={root:["root",`anchor${L(n)}`],docked:[(o==="permanent"||o==="persistent")&&"docked"],modal:["modal"],paper:["paper",`paperAnchor${L(n)}`,o!=="temporary"&&`paperAnchorDocked${L(n)}`]};return ie(s,pt,r)},ht=I($e,{name:"MuiDrawer",slot:"Root",overridesResolver:xe})(_(({theme:e})=>({zIndex:(e.vars||e).zIndex.drawer}))),ft=I("div",{shouldForwardProp:Le,name:"MuiDrawer",slot:"Docked",skipVariantsResolver:!1,overridesResolver:xe})({flex:"0 0 auto"}),mt=I(He,{name:"MuiDrawer",slot:"Paper",overridesResolver:(e,r)=>{const{ownerState:n}=e;return[r.paper,r[`paperAnchor${L(n.anchor)}`],n.variant!=="temporary"&&r[`paperAnchorDocked${L(n.anchor)}`]]}})(_(({theme:e})=>({overflowY:"auto",display:"flex",flexDirection:"column",height:"100%",flex:"1 0 auto",zIndex:(e.vars||e).zIndex.drawer,WebkitOverflowScrolling:"touch",position:"fixed",top:0,outline:0,variants:[{props:{anchor:"left"},style:{left:0}},{props:{anchor:"top"},style:{top:0,left:0,right:0,height:"auto",maxHeight:"100%"}},{props:{anchor:"right"},style:{right:0}},{props:{anchor:"bottom"},style:{top:"auto",left:0,bottom:0,right:0,height:"auto",maxHeight:"100%"}},{props:({ownerState:r})=>r.anchor==="left"&&r.variant!=="temporary",style:{borderRight:`1px solid ${(e.vars||e).palette.divider}`}},{props:({ownerState:r})=>r.anchor==="top"&&r.variant!=="temporary",style:{borderBottom:`1px solid ${(e.vars||e).palette.divider}`}},{props:({ownerState:r})=>r.anchor==="right"&&r.variant!=="temporary",style:{borderLeft:`1px solid ${(e.vars||e).palette.divider}`}},{props:({ownerState:r})=>r.anchor==="bottom"&&r.variant!=="temporary",style:{borderTop:`1px solid ${(e.vars||e).palette.divider}`}}]}))),ge={left:"right",right:"left",top:"down",bottom:"up"};function xt(e){return["left","right"].includes(e)}function gt({direction:e},r){return e==="rtl"&&xt(r)?ge[r]:r}const yt=u.forwardRef(function(r,n){const o=ae({props:r,name:"MuiDrawer"}),s=G(),a=Te(),i={enter:s.transitions.duration.enteringScreen,exit:s.transitions.duration.leavingScreen},{anchor:c="left",BackdropProps:h,children:f,className:p,elevation:m=16,hideBackdrop:y=!1,ModalProps:{BackdropProps:S,...H}={},onClose:M,open:P=!1,PaperProps:v={},SlideProps:C,TransitionComponent:R,transitionDuration:j=i,variant:w="temporary",slots:z={},slotProps:d={},...k}=o,b=u.useRef(!1);u.useEffect(()=>{b.current=!0},[]);const V=gt({direction:a?"rtl":"ltr"},c),D={...o,anchor:c,elevation:m,open:P,variant:w,...k},T=ut(D),E={slots:{transition:R,...z},slotProps:{paper:v,transition:C,...d,backdrop:Be(d.backdrop||{...h,...S},{transitionDuration:j})}},[U,Q]=A("root",{ref:n,elementType:ht,className:O(T.root,T.modal,p),shouldForwardComponentProp:!0,ownerState:D,externalForwardedProps:{...E,...k,...H},additionalProps:{open:P,onClose:M,hideBackdrop:y,slots:{backdrop:E.slots.backdrop},slotProps:{backdrop:E.slotProps.backdrop}}}),[N,l]=A("paper",{elementType:mt,shouldForwardComponentProp:!0,className:O(T.paper,v.className),ownerState:D,externalForwardedProps:E,additionalProps:{elevation:w==="temporary"?m:0,square:!0,...w==="temporary"&&{role:"dialog","aria-modal":"true"}}}),[g,B]=A("docked",{elementType:ft,ref:n,className:O(T.root,T.docked,p),ownerState:D,externalForwardedProps:E,additionalProps:k}),[ve,je]=A("transition",{elementType:dt,ownerState:D,externalForwardedProps:E,additionalProps:{in:P,direction:ge[V],timeout:j,appear:b.current}}),ee=t.jsx(N,{...l,children:f});if(w==="permanent")return t.jsx(g,{...B,children:ee});const te=t.jsx(ve,{...je,children:ee});return w==="persistent"?t.jsx(g,{...B,children:te}):t.jsx(U,{...Q,children:te})}),bt=me({themeId:Ne}),vt=$([t.jsx("path",{d:"M19 5v14H5V5zm0-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2"},"0"),t.jsx("path",{d:"M14 17H7v-2h7zm3-4H7v-2h10zm0-4H7V7h10z"},"1")]),jt=$(t.jsx("path",{d:"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"})),wt=$(t.jsx("path",{d:"M9.4 16.6 4.8 12l4.6-4.6L8 6l-6 6 6 6zm5.2 0 4.6-4.6-4.6-4.6L16 6l6 6-6 6z"})),kt=$(t.jsx("path",{d:"m9.17 6 2 2H20v10H4V6zM10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8z"})),St=$(t.jsx("path",{d:"m12 5.69 5 4.5V18h-2v-6H9v6H7v-7.81zM12 3 2 12h3v8h6v-6h2v6h6v-8h3z"})),Pt=$(t.jsx("path",{d:"M19 19H5V5h7V3H5c-1.11 0-2 .9-2 2v14c0 1.1.89 2 2 2h14c1.1 0 2-.9 2-2v-7h-2zM14 3v2h3.59l-9.83 9.83 1.41 1.41L19 6.41V10h2V3z"}));function Y(e){return t.jsxs(Ae,{...e,viewBox:"0 0 24 24",sx:{fill:"none",...e.sx},children:[t.jsx("rect",{x:"3.25",y:"4.75",width:"17.5",height:"14.5",rx:"2.25",stroke:"currentColor",strokeWidth:"1.5"}),t.jsx("line",{x1:"8.5",y1:"5",x2:"8.5",y2:"19",stroke:"currentColor",strokeWidth:"1.5"})]})}function F({label:e,onClick:r}){return t.jsx(We,{clickable:!0,onClick:r,label:e,size:"small","aria-label":`Navigate to ${e}`,sx:{backgroundColor:"background.paper",color:"text.primary",fontWeight:500,fontSize:"0.875rem",height:32,cursor:"pointer",borderRadius:"4px",maxWidth:320,"& .MuiChip-label":{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},"&:hover":{backgroundColor:"grey.100"}}})}function Ct(){const e=ce(),r=e["*"],n=J();return!e.environmentName&&!e.packageName&&!r?null:t.jsx(x,{sx:{display:"flex",alignItems:"center",minWidth:0},children:t.jsxs(it,{"aria-label":"breadcrumb",separator:t.jsx(jt,{sx:{fontSize:14,color:"text.secondary"}}),children:[e.environmentName&&t.jsx(F,{label:e.environmentName,onClick:o=>n(`/${e.environmentName}/`,o)}),e.packageName&&t.jsx(F,{label:e.packageName,onClick:o=>n(`/${e.environmentName}/${e.packageName}/`,o)}),r&&t.jsx(F,{label:r,onClick:o=>n(`/${e.environmentName}/${e.packageName}/${r}`,o)})]})})}const Et=260,It=64;function ye({isCollapsed:e,onToggleCollapse:r,logoHeader:n}){return t.jsxs(x,{sx:{height:"100dvh",width:e?It:Et,flexShrink:0,display:"flex",flexDirection:"column",backgroundColor:"background.paper",transition:"width 0.2s cubic-bezier(0.4, 0, 0.2, 1)",overflow:"hidden"},children:[t.jsx(Mt,{isCollapsed:e,onToggleCollapse:r,logoHeader:n}),t.jsxs(x,{sx:{flex:1,overflowY:"auto",overflowX:"hidden",py:1},children:[t.jsx(Rt,{isCollapsed:e}),t.jsx(zt,{isCollapsed:e})]}),t.jsx(Dt,{isCollapsed:e})]})}function Mt({isCollapsed:e,onToggleCollapse:r,logoHeader:n}){const o=J();return n?t.jsxs(x,{sx:{height:56,display:"flex",alignItems:"center",justifyContent:"space-between",px:e?0:2,flexShrink:0},children:[n,t.jsx(X,{size:"small",onClick:r,"aria-label":e?"Expand sidebar":"Collapse sidebar",children:t.jsx(Y,{fontSize:"small"})})]}):t.jsxs(x,{sx:{height:56,display:"flex",alignItems:"center",justifyContent:e?"center":"space-between",px:e?0:2,flexShrink:0},children:[t.jsxs(x,{onClick:s=>o("/",s),sx:{display:"flex",alignItems:"center",gap:1,cursor:"pointer",minWidth:0},children:[t.jsx(x,{component:"img",src:"/logo.svg",alt:"Malloy",sx:{width:24,height:24,flexShrink:0}}),!e&&t.jsx(K,{variant:"subtitle1",sx:{color:"text.primary",fontWeight:500,letterSpacing:"-0.025em",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:"Malloy Publisher"})]}),!e&&t.jsx(X,{size:"small",onClick:r,"aria-label":"Collapse sidebar",children:t.jsx(Y,{fontSize:"small"})})]})}function Rt({isCollapsed:e}){const n=Oe().pathname==="/";return t.jsx(Z,{sx:{py:0},children:t.jsx(be,{icon:t.jsx(St,{fontSize:"small"}),label:"Home",to:"/",selected:n,isCollapsed:e})})}function zt({isCollapsed:e}){const{apiClients:r}=Ve(),n=ce(),{data:o}=Ue({queryKey:["environments"],queryFn:()=>r.environments.listEnvironments()}),s=o?.data??[];return s.length===0?null:t.jsxs(x,{sx:{mt:1},children:[!e&&t.jsx(K,{variant:"caption",sx:{display:"block",px:3,py:1,color:"text.secondary",fontWeight:500,textTransform:"uppercase",fontSize:"0.6875rem",letterSpacing:"0.5px"},children:"Environments"}),t.jsx(Z,{sx:{py:0},children:s.map(a=>{const i=a.name??"";return t.jsx(be,{icon:t.jsx(kt,{fontSize:"small"}),label:i,to:`/${i}`,selected:n.environmentName===i,isCollapsed:e},i)})})]})}function Dt({isCollapsed:e}){const r=[{label:"Malloy Docs",href:"https://docs.malloydata.dev/documentation/",icon:t.jsx(vt,{fontSize:"small"}),external:!0},{label:"Publisher Docs",href:"https://github.com/malloydata/publisher/blob/main/README.md",icon:t.jsx(Pt,{fontSize:"small"}),external:!0},{label:"Publisher API",href:"/api-doc.html",icon:t.jsx(wt,{fontSize:"small"}),external:!1}];return t.jsx(Z,{sx:{py:1},children:r.map(n=>t.jsx(Tt,{label:n.label,href:n.href,icon:n.icon,external:n.external,isCollapsed:e},n.label))})}function be({icon:e,label:r,to:n,selected:o,isCollapsed:s}){const a=J(),i=t.jsxs(pe,{selected:o,onClick:c=>a(n,c),sx:{justifyContent:s?"center":"flex-start",px:s?0:2},children:[t.jsx(ue,{sx:{minWidth:s?0:36,justifyContent:"center",color:o?"text.primary":"text.secondary"},children:e}),!s&&t.jsx(he,{primary:r,primaryTypographyProps:{variant:"body2",sx:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}})]});return s?t.jsx(de,{title:r,placement:"right",children:t.jsx(x,{children:i})}):i}function Tt({label:e,href:r,icon:n,external:o,isCollapsed:s}){const a=t.jsxs(pe,{component:"a",href:r,target:o?"_blank":void 0,rel:o?"noopener noreferrer":void 0,sx:{justifyContent:s?"center":"flex-start",px:s?0:2},children:[t.jsx(ue,{sx:{minWidth:s?0:36,justifyContent:"center",color:"text.secondary"},children:n}),!s&&t.jsx(he,{primary:e,primaryTypographyProps:{variant:"body2",sx:{color:"text.secondary",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}})]});return s?t.jsx(de,{title:e,placement:"right",children:t.jsx(x,{children:a})}):a}function Bt({open:e,onClose:r,logoHeader:n}){return t.jsx(yt,{anchor:"left",open:e,onClose:r,ModalProps:{keepMounted:!0},sx:{display:{xs:"block",md:"none"},"& .MuiDrawer-paper":{boxSizing:"border-box",width:260}},children:t.jsx(ye,{isCollapsed:!1,onToggleCollapse:r,logoHeader:n})})}function Ht({headerProps:e}){const r=G(),n=bt(r.breakpoints.up("md")),[o,s]=u.useState(!1),[a,i]=u.useState(!1);return u.useEffect(()=>{n&&o&&s(!1)},[n,o]),t.jsxs(x,{sx:{height:"100dvh",display:"flex",flexDirection:"row",bgcolor:"background.default"},children:[n&&t.jsx(ye,{isCollapsed:a,onToggleCollapse:()=>i(c=>!c),logoHeader:e?.logoHeader}),t.jsxs(x,{component:"main",sx:{flex:1,display:"flex",flexDirection:"column",minWidth:0},children:[t.jsxs(x,{sx:{flexShrink:0,display:"flex",alignItems:"center",justifyContent:"space-between",height:Qe.headerHeight,px:{xs:1,md:3},backgroundColor:"background.default"},children:[t.jsx(x,{sx:{display:{xs:"flex",md:"none"},alignItems:"center",mr:1},children:t.jsx(X,{size:"small",onClick:()=>s(!0),"aria-label":"Open navigation",children:t.jsx(Y,{fontSize:"small"})})}),t.jsx(x,{sx:{flex:1,minWidth:0,display:"flex",alignItems:"center"},children:t.jsx(Ct,{})}),t.jsx(x,{id:"header-actions-portal",sx:{display:"flex",alignItems:"center",flexShrink:0,gap:1},children:e?.endCap})]}),t.jsx(x,{sx:{flex:1,overflow:"auto",minWidth:320,minHeight:0},children:t.jsx(u.Suspense,{fallback:t.jsx(Xe,{}),children:t.jsx(Fe,{})})})]}),t.jsx(Bt,{open:o,onClose:()=>s(!1),logoHeader:e?.logoHeader})]})}export{Ht as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{F as t,j as e,_ as m,G as r,$ as x,a0 as o}from"./index-BMViiwtJ.js";function l(){const n=t(),a=n["*"];if(!n.environmentName)return e.jsx("div",{children:e.jsx("h2",{children:"Missing environment name"})});if(!n.packageName)return e.jsx("div",{children:e.jsx("h2",{children:"Missing package name"})});const i=m({environmentName:n.environmentName,packageName:n.packageName,modelPath:a}),s={p:3,maxWidth:1200,mx:"auto"};return a?.endsWith(".malloy")?e.jsx(r,{sx:s,children:e.jsx(x,{resourceUri:i,runOnDemand:!0,maxResultSize:512*1024})}):a?.endsWith(".malloynb")?e.jsx(r,{sx:s,children:e.jsx(o,{resourceUri:i,maxResultSize:1024*1024})}):e.jsx(r,{sx:s,children:e.jsxs("h2",{children:["Unrecognized file type: ",a]})})}export{l as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{F as r,S as t,j as e,_ as c,a1 as o}from"./index-BMViiwtJ.js";function m(){const{environmentName:a,packageName:n}=r(),s=t();if(a)if(n){const i=c({environmentName:a,packageName:n});return e.jsx(o,{onClickPackageFile:s,resourceUri:i})}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing package name"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing environment name"})})}export{m as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a3 as o,j as r,a4 as s,a5 as n,G as t,T as a}from"./index-BMViiwtJ.js";function x(){const e=o();return console.error(e),r.jsx(s,{maxWidth:"lg",component:"main",sx:{display:"flex",flexDirection:"column",my:2,gap:0},children:r.jsxs(n,{sx:{m:"auto",flexDirection:"column"},children:[r.jsx(t,{sx:{height:"300px"}}),r.jsx("img",{src:"/error.png"}),r.jsx(a,{variant:"subtitle1",children:"An unexpected error occurred"})]})})}export{x as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{F as o,j as e,_ as t,a6 as c}from"./index-BMViiwtJ.js";function l(){const{workspace:r,workbookPath:s,environmentName:i,packageName:n}=o();if(r)if(s)if(i)if(n){const a=t({environmentName:i,packageName:n});return e.jsx(c,{workbookPath:{path:s,workspace:r},resourceUri:a},`${s}`)}else return e.jsx("div",{children:e.jsx("h2",{children:"Missing package name"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing environment name"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing workbook path"})});else return e.jsx("div",{children:e.jsx("h2",{children:"Missing workspace"})})}export{l as default};
|