@malloy-publisher/server 0.0.232 → 0.0.234

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 (83) hide show
  1. package/README.docker.md +1 -0
  2. package/dist/app/api-doc.yaml +269 -10
  3. package/dist/app/assets/{EnvironmentPage-DXEaZIPx.js → EnvironmentPage-DTZQ4Gxc.js} +1 -1
  4. package/dist/app/assets/{HomePage-kofsqpZt.js → HomePage-C5mlDPXK.js} +1 -1
  5. package/dist/app/assets/{LightMode-CNhIlIlJ.js → LightMode-DGNmhG0u.js} +1 -1
  6. package/dist/app/assets/{MainPage-Bgqo8jCy.js → MainPage-CVL_wmP4.js} +1 -1
  7. package/dist/app/assets/{MaterializationsPage-CgBlgGz2.js → MaterializationsPage-DmzMBCpy.js} +1 -1
  8. package/dist/app/assets/{ModelPage-B0TjoDtf.js → ModelPage-Dbvf4QbB.js} +1 -1
  9. package/dist/app/assets/{PackagePage-BL8vnFj1.js → PackagePage-DxdHc2Qs.js} +1 -1
  10. package/dist/app/assets/{RouteError-BzPby0X2.js → RouteError-OJdT4tCd.js} +1 -1
  11. package/dist/app/assets/{ThemeEditorPage-CTEP_9r3.js → ThemeEditorPage-Bk7s0KXY.js} +1 -1
  12. package/dist/app/assets/{WorkbookPage-BwM3BmKw.js → WorkbookPage-j_vCWdN3.js} +1 -1
  13. package/dist/app/assets/{core-CK68iv6w.es-CpRxXBt7.js → core-Rj_4rRnA.es-DoIfLxDJ.js} +1 -1
  14. package/dist/app/assets/{index-B33zGctF.js → index-B_jKMR35.js} +4 -4
  15. package/dist/app/assets/{index-CmkW1MiE.js → index-D-rDyK11.js} +1 -1
  16. package/dist/app/assets/{index-tXJXwdyj.js → index-DWIe_hK0.js} +1 -1
  17. package/dist/app/assets/{index-BkiWKaAF.js → index-hw-xn0X7.js} +1 -1
  18. package/dist/app/index.html +1 -1
  19. package/dist/package_load_worker.mjs +53 -3
  20. package/dist/server.mjs +20277 -925
  21. package/package.json +1 -1
  22. package/src/config.ts +35 -1
  23. package/src/controller/connection.controller.spec.ts +46 -0
  24. package/src/controller/connection.controller.ts +105 -2
  25. package/src/controller/materialization.controller.spec.ts +25 -0
  26. package/src/controller/materialization.controller.ts +60 -0
  27. package/src/controller/model.controller.ts +24 -0
  28. package/src/controller/query.controller.ts +83 -10
  29. package/src/json_utils.spec.ts +51 -0
  30. package/src/json_utils.ts +33 -0
  31. package/src/mcp/handler_utils.ts +10 -2
  32. package/src/mcp/query_envelope.spec.ts +229 -0
  33. package/src/mcp/query_envelope.ts +240 -0
  34. package/src/mcp/server.protocol.spec.ts +128 -16
  35. package/src/mcp/skills/build_skills_bundle.ts +94 -4
  36. package/src/mcp/skills/skills_bundle.json +1 -1
  37. package/src/mcp/skills/skills_bundle.spec.ts +113 -4
  38. package/src/mcp/tool_response.spec.ts +108 -0
  39. package/src/mcp/tool_response.ts +138 -0
  40. package/src/mcp/tools/compile_tool.spec.ts +112 -4
  41. package/src/mcp/tools/compile_tool.ts +61 -30
  42. package/src/mcp/tools/docs_search_tool.ts +6 -16
  43. package/src/mcp/tools/execute_query_tool.spec.ts +154 -3
  44. package/src/mcp/tools/execute_query_tool.ts +131 -155
  45. package/src/mcp/tools/get_context_tool.spec.ts +63 -3
  46. package/src/mcp/tools/get_context_tool.ts +43 -46
  47. package/src/mcp/tools/reload_package_tool.ts +3 -29
  48. package/src/mcp_config.spec.ts +919 -0
  49. package/src/mcp_config.ts +425 -0
  50. package/src/oom_guards.integration.spec.ts +11 -3
  51. package/src/package_load/package_load_pool.ts +2 -0
  52. package/src/package_load/package_load_worker.ts +17 -5
  53. package/src/package_load/protocol.ts +6 -0
  54. package/src/query_metadata_metrics.ts +49 -0
  55. package/src/server.ts +99 -3
  56. package/src/service/build_plan.spec.ts +125 -0
  57. package/src/service/build_plan.ts +108 -7
  58. package/src/service/compile_fragment_techniques.spec.ts +156 -0
  59. package/src/service/connection.spec.ts +371 -1
  60. package/src/service/connection.ts +77 -14
  61. package/src/service/connection_config.spec.ts +60 -0
  62. package/src/service/connection_config.ts +75 -0
  63. package/src/service/duckdb_instance_isolation.spec.ts +137 -0
  64. package/src/service/environment.ts +57 -3
  65. package/src/service/materialization_config_validation.spec.ts +99 -0
  66. package/src/service/materialization_config_validation.ts +120 -0
  67. package/src/service/materialization_schedule_surface.spec.ts +124 -0
  68. package/src/service/materialization_service.spec.ts +119 -0
  69. package/src/service/materialization_service.ts +186 -3
  70. package/src/service/materialization_test_fixtures.ts +86 -21
  71. package/src/service/model.spec.ts +45 -1
  72. package/src/service/model.ts +171 -23
  73. package/src/service/model_limits.spec.ts +28 -0
  74. package/src/service/model_limits.ts +21 -0
  75. package/src/service/package.ts +24 -1
  76. package/src/service/package_manifest.spec.ts +137 -4
  77. package/src/service/package_manifest.ts +140 -5
  78. package/src/service/persist_annotation_validation.spec.ts +12 -0
  79. package/src/service/persist_annotation_validation.ts +9 -4
  80. package/src/service/query_metadata.spec.ts +408 -0
  81. package/src/service/query_metadata.ts +492 -0
  82. package/src/service/query_metadata_identity.spec.ts +149 -0
  83. package/tests/integration/mcp/mcp_execute_query_tool.integration.spec.ts +37 -12
package/README.docker.md CHANGED
@@ -68,6 +68,7 @@ All flags exposed by `bin/malloy-publisher --help` have an equivalent env var, s
68
68
  | `PUBLISHER_PORT` | `--port <n>` | `4000` | REST API port. |
69
69
  | `PUBLISHER_HOST` | `--host <h>` | `0.0.0.0` | Bind address. |
70
70
  | `MCP_PORT` | `--mcp_port <n>` | `4040` | MCP API port. |
71
+ | `PUBLISHER_NO_MCP_CONFIG` | `--no-mcp-config` | `1` **in this image** | Suppresses the `.mcp.json` the server otherwise writes into its working directory on startup. That file exists so an AI agent opened in that directory finds the server; nothing starts an agent session inside the container, and the git-working-tree guard that would normally cover `/publisher` cannot fire because `.dockerignore` excludes `.git`. Left on, every boot would create a root-owned file, which matters if you bind-mount a project directory at `/publisher`. Pass `-e PUBLISHER_NO_MCP_CONFIG=` to turn it back on. Note this is the one env var the image sets for you: `docker run -e PUBLISHER_NO_MCP_CONFIG` (no `=`) and a Compose `environment:` entry with no value both *delete* it when the host does not have it set, which re-enables the write. |
71
72
  | `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
73
  | `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
74
  | `INITIALIZE_STORAGE` | `--init` | `false` | Wipes `publisher_data/` and re-syncs it from the config on boot. A first boot with empty storage loads the config automatically, so set this only to reset state or resync after the on-disk config has drifted from `publisher_data/`. Re-initializing discards any state there that isn't reproducible from the config. See [configuration.md](../../docs/configuration.md#environment-variables--cli-flags). |
@@ -792,6 +792,22 @@ paths:
792
792
  options:
793
793
  type: string
794
794
  description: Options
795
+ queryMetadata:
796
+ $ref: "#/components/schemas/QueryMetadata"
797
+ description: >-
798
+ Per-query metadata to attach to this statement, overriding
799
+ the connection default property by property. A bag that
800
+ violates the contract is rejected with 400.
801
+ (`options.queryMetadata` is honored too, since `options` is
802
+ forwarded as `RunSQLOptions`, but this field is the
803
+ documented surface and wins when both are present.)
804
+ queryClass:
805
+ $ref: "#/components/schemas/QueryClass"
806
+ description: >-
807
+ What class of work this statement belongs to, attached as the
808
+ `class` property. Defaults to `ops`: raw SQL against a
809
+ connection is platform maintenance unless the caller says
810
+ otherwise.
795
811
  responses:
796
812
  "200":
797
813
  description: Query execution results
@@ -1142,6 +1158,22 @@ paths:
1142
1158
  options:
1143
1159
  type: string
1144
1160
  description: Options
1161
+ queryMetadata:
1162
+ $ref: "#/components/schemas/QueryMetadata"
1163
+ description: >-
1164
+ Per-query metadata to attach to this statement, overriding
1165
+ the connection default property by property. A bag that
1166
+ violates the contract is rejected with 400.
1167
+ (`options.queryMetadata` is honored too, since `options` is
1168
+ forwarded as `RunSQLOptions`, but this field is the
1169
+ documented surface and wins when both are present.)
1170
+ queryClass:
1171
+ $ref: "#/components/schemas/QueryClass"
1172
+ description: >-
1173
+ What class of work this statement belongs to, attached as the
1174
+ `class` property. Defaults to `ops`: raw SQL against a
1175
+ connection is platform maintenance unless the caller says
1176
+ otherwise.
1145
1177
  responses:
1146
1178
  "200":
1147
1179
  description: Query execution results
@@ -1356,6 +1388,12 @@ paths:
1356
1388
  Updates the configuration and metadata of an existing package. This allows you to
1357
1389
  modify package settings, update the description, change the location, or update other
1358
1390
  package-level properties. The package must exist and be accessible.
1391
+
1392
+ A supplied `materialization` block REPLACES the one on disk, so re-send every
1393
+ field of it you want to keep. Two exceptions, because neither is expressible
1394
+ in the block a caller sends: `scope` (a top-level field) and `queryMetadata`
1395
+ (orthogonal to the schedule and freshness policy this call usually carries) are
1396
+ preserved when omitted. Send `queryMetadata: null` to clear it.
1359
1397
  parameters:
1360
1398
  - name: environmentName
1361
1399
  in: path
@@ -2468,8 +2506,7 @@ components:
2468
2506
  properties:
2469
2507
  environment:
2470
2508
  type: string
2471
- description:
2472
- Name of the configured environment the failure belongs to.
2509
+ description: Name of the configured environment the failure belongs to.
2473
2510
  package:
2474
2511
  type: string
2475
2512
  description:
@@ -2488,12 +2525,14 @@ components:
2488
2525
  true, all mutation operations are disabled.
2489
2526
  theme:
2490
2527
  $ref: "#/components/schemas/Theme"
2491
- description: Instance-wide default theme for the Malloy renderer and the
2528
+ description:
2529
+ Instance-wide default theme for the Malloy renderer and the
2492
2530
  Publisher app shell.
2493
2531
 
2494
2532
  Theme:
2495
2533
  type: object
2496
- description: Visual theme applied to Malloy renderer output (chart palette,
2534
+ description:
2535
+ Visual theme applied to Malloy renderer output (chart palette,
2497
2536
  fonts, table chrome) and to the Publisher app shell. Cascade order is
2498
2537
  instance → per-chart Malloy annotation, with later layers overriding
2499
2538
  earlier ones for the keys they set. (A per-environment layer is reserved
@@ -2501,12 +2540,13 @@ components:
2501
2540
  properties:
2502
2541
  defaultMode:
2503
2542
  type: string
2504
- enum: [ "light", "dark", "auto" ]
2543
+ enum: ["light", "dark", "auto"]
2505
2544
  description: Initial color mode for new viewers. "auto" follows the
2506
2545
  browser's prefers-color-scheme until the viewer overrides.
2507
2546
  allowUserToggle:
2508
2547
  type: boolean
2509
- description: When true, the Publisher app renders a light/dark toggle and
2548
+ description:
2549
+ When true, the Publisher app renders a light/dark toggle and
2510
2550
  persists the viewer's choice to localStorage. When false, the
2511
2551
  defaultMode is enforced.
2512
2552
  palette:
@@ -2515,7 +2555,8 @@ components:
2515
2555
  properties:
2516
2556
  series:
2517
2557
  type: array
2518
- description: Ordered list of hex colors used by multi-series charts
2558
+ description:
2559
+ Ordered list of hex colors used by multi-series charts
2519
2560
  (passed to Vega's `range.category`). Shared across light
2520
2561
  and dark modes so the brand palette stays consistent
2521
2562
  when viewers switch modes.
@@ -2588,7 +2629,8 @@ components:
2588
2629
  type: string
2589
2630
  font:
2590
2631
  type: object
2591
- description: Typography overrides applied to both the app shell and the
2632
+ description:
2633
+ Typography overrides applied to both the app shell and the
2592
2634
  Malloy renderer (Vega text marks). Shared across light and
2593
2635
  dark modes because font choice is a brand decision, not a
2594
2636
  mode-specific one.
@@ -2882,6 +2924,16 @@ components:
2882
2924
  `fallback` is the declared query-time behavior when the objective
2883
2925
  is missed. The publisher only surfaces the values — the control
2884
2926
  plane owns the scheduling and gating logic.
2927
+ queryMetadata:
2928
+ oneOf:
2929
+ - $ref: "#/components/schemas/QueryMetadata"
2930
+ - type: "null"
2931
+ description: >-
2932
+ The manifest's `materialization.queryMetadata` block, verbatim. Null
2933
+ = none declared. The package-level layer of per-query metadata: it
2934
+ applies to every statement the package's sources issue, and a
2935
+ model-file, source or per-request declaration overrides it property
2936
+ by property.
2885
2937
 
2886
2938
  Freshness:
2887
2939
  type: object
@@ -3243,6 +3295,30 @@ components:
3243
3295
  When true, skip server-side `#(filter)` injection entirely.
3244
3296
  givens:
3245
3297
  $ref: "#/components/schemas/Givens"
3298
+ queryMetadata:
3299
+ $ref: "#/components/schemas/QueryMetadata"
3300
+ description: >-
3301
+ Per-request metadata to attach to the statements this query issues —
3302
+ the most specific author layer, overriding the connection default and
3303
+ any package/model/source declaration property by property. Rejected
3304
+ with 400 when it violates the contract (see `QueryMetadata`), so a
3305
+ caller learns at the boundary rather than having a backend refuse the
3306
+ statement.
3307
+ queryClass:
3308
+ $ref: "#/components/schemas/QueryClass"
3309
+ description: >-
3310
+ What class of work this request represents, attached as the `class`
3311
+ property. Defaults to `interactive`.
3312
+
3313
+ QueryClass:
3314
+ type: string
3315
+ enum: [interactive, materialize, index, ops]
3316
+ description: >-
3317
+ The class of work a statement belongs to, attached as the `class`
3318
+ query-metadata property: `interactive` (a user or application query),
3319
+ `materialize` (a persist-source build), `index` (an index build or scan),
3320
+ `ops` (platform maintenance). Attribution's primary axis — a backend bill
3321
+ separates traffic from builds only if every statement says which it is.
3246
3322
 
3247
3323
  NotebookCell:
3248
3324
  type: object
@@ -3290,6 +3366,40 @@ components:
3290
3366
  items:
3291
3367
  type: string
3292
3368
 
3369
+ QueryMetadata:
3370
+ type: object
3371
+ additionalProperties:
3372
+ type: string
3373
+ description: >-
3374
+ Per-query metadata: a flat bag of string properties attached to the
3375
+ statements a query issues, for the backend's own reporting — cost
3376
+ attribution, workload classification, tracing. Each backend applies it
3377
+ through a per-query mechanism: Snowflake a per-statement `QUERY_TAG`
3378
+ (the bag as JSON, so its properties are queryable in `QUERY_HISTORY`),
3379
+ BigQuery per-job `labels` (queryable in `INFORMATION_SCHEMA.JOBS`), and
3380
+ every other backend a leading SQL comment (`-- team="finance"`, visible
3381
+ in query history / `pg_stat_activity`). It never affects results, and it
3382
+ is excluded from connection fingerprints and from build identity, so
3383
+ changing a property never re-addresses or rebuilds anything.
3384
+
3385
+ The contract, which every backend can render and which the connector
3386
+ enforces at dispatch: property names are ASCII alphanumerics and
3387
+ underscore (<=128 chars), values are printable ASCII without `"`
3388
+ (<=256 chars), and a bag holds at most 20 properties. Declare a name
3389
+ starting with a LETTER: BigQuery drops a name it cannot fit to its label
3390
+ grammar while other backends keep it.
3391
+
3392
+ Layers, most specific wins per property: connection default < package
3393
+ `materialization.queryMetadata` < model-file
3394
+ `## materialization.queryMetadata.*` < `#@ persist queryMetadata.*` <
3395
+ per-request `queryMetadata`. The publisher's own context (`class`,
3396
+ `environment`, `package`, `model`, `source`, `trigger`, `run_id`,
3397
+ `query_id`) is applied on top and cannot be overwritten by a declaration
3398
+ — it is what the server is actually doing, and a caller must not be able
3399
+ to relabel it. Put no secrets or personal data here: a tag is visible to
3400
+ anyone who can read the backend's query history, and on a backend with no
3401
+ native tag mechanism it is visible in the statement text.
3402
+
3293
3403
  QueryResult:
3294
3404
  type: object
3295
3405
  description: Results from executing a Malloy query
@@ -3302,6 +3412,26 @@ components:
3302
3412
  resource:
3303
3413
  type: string
3304
3414
  description: Resource path to the query result
3415
+ queryCorrelationId:
3416
+ type: ["string", "null"]
3417
+ description: >-
3418
+ Id the server minted for this query and attached to its statements as
3419
+ the `query_id` query-metadata property — the join key back to the
3420
+ backend's own record of the query. Find the same value in
3421
+ `QUERY_HISTORY.query_tag` (Snowflake, inside the JSON tag),
3422
+ `INFORMATION_SCHEMA.JOBS.labels` (BigQuery), or the statement text
3423
+ (every other backend), and you have the warehouse-side row for this
3424
+ API call: its cost, its duration, its plan.
3425
+
3426
+ Minted by the server rather than taken from the request because it is
3427
+ the platform's join key — a caller-supplied value can be omitted or
3428
+ reused, leaving a response with nothing to hand back. To carry your
3429
+ own id as well, declare it in `queryMetadata` under your own property
3430
+ name (`query_id` is reserved).
3431
+
3432
+ Null when no metadata was attached — which is every query until a
3433
+ deployment sets `PUBLISHER_QUERY_METADATA=on`, since query metadata
3434
+ ships off by default.
3305
3435
  renderLogs:
3306
3436
  type: array
3307
3437
  description:
@@ -3309,6 +3439,21 @@ components:
3309
3439
  query preparation
3310
3440
  items:
3311
3441
  $ref: "#/components/schemas/LogMessage"
3442
+ queryRowLimit:
3443
+ type: integer
3444
+ description:
3445
+ Row cap pushed into the SQL for this query, taken from the query's
3446
+ own limit/top when it has one and otherwise from the server default.
3447
+ A caller cannot derive it, since it depends on server configuration
3448
+ as well as the query, and without it a result that the cap cut off
3449
+ is indistinguishable from a complete one.
3450
+ queryRowLimitSource:
3451
+ type: string
3452
+ enum: [query, server_default]
3453
+ description:
3454
+ Which of the two queryRowLimit came from. Only server_default means
3455
+ rows were probably left behind; a deliberate limit or top returning
3456
+ exactly that many rows is a complete answer.
3312
3457
 
3313
3458
  LogMessage:
3314
3459
  type: object
@@ -3424,6 +3569,38 @@ components:
3424
3569
  use the supplied value verbatim rather than deriving their own. This
3425
3570
  field is optional — when omitted, a connection identity is derived
3426
3571
  locally instead.
3572
+ queryMetadata:
3573
+ $ref: "#/components/schemas/QueryMetadata"
3574
+ description: >-
3575
+ Default per-query metadata for every statement this connection
3576
+ issues — the least specific layer, overridden per property by a
3577
+ package/model/source declaration or a per-request value. Use it for
3578
+ properties that are true of the whole connection (which deployment,
3579
+ which team owns it). Not a secret: it round-trips like any plain
3580
+ field and is never redacted.
3581
+ queryMetadataEnforced:
3582
+ $ref: "#/components/schemas/QueryMetadata"
3583
+ description: >-
3584
+ Per-query metadata this deployment owns: applied to every statement
3585
+ the connection issues, NOT overridable by a package, model-file,
3586
+ source or per-request declaration, and given up only after every
3587
+ declared property when a bag has to shrink.
3588
+
3589
+ For the properties a host is billed or audited by, in a deployment
3590
+ where writing a connection is an operator's to do and publishing a
3591
+ package is not — so a host running one Publisher for several tenants
3592
+ can label a connection's traffic without a tenant relabelling it as
3593
+ someone else's, or pushing the label out of the bag by declaring
3594
+ twenty properties of its own. That split lives in whatever fronts
3595
+ this API: Publisher does not authenticate it, so on an unfronted
3596
+ server the same caller can write both. The server's own context
3597
+ (`class`, `environment`, `query_id`, …) still wins over these,
3598
+ because it describes what the server is actually doing.
3599
+
3600
+ Same contract as `queryMetadata`, counted against the same
3601
+ 20-property budget. Rejected with 400 on a connection write when it
3602
+ violates the contract, and reported as a warning when a stored config
3603
+ loads.
3427
3604
  attributes:
3428
3605
  $ref: "#/components/schemas/ConnectionAttributes"
3429
3606
  proxy:
@@ -3701,6 +3878,39 @@ components:
3701
3878
  postgresConnection:
3702
3879
  $ref: "#/components/schemas/PostgresConnection"
3703
3880
  description: PostgreSQL connection for DuckLake metadata catalog
3881
+ metadataSchema:
3882
+ type: string
3883
+ description: >-
3884
+ Optional schema in the catalog database holding this DuckLake's
3885
+ metadata (`ducklake_*`) tables, passed to ATTACH as
3886
+ METADATA_SCHEMA. Absent means DuckLake's default — the catalog
3887
+ connection's default schema, typically `public` — which is the
3888
+ pre-existing behavior. Set it to run several independent DuckLake
3889
+ catalogs against ONE catalog database: each keeps its metadata in
3890
+ its own schema, so a catalog reads only the tables recorded in the
3891
+ schema it names. DuckLake creates the schema on a read-write attach
3892
+ if it does not exist; a read-only attach cannot, and fails until it
3893
+ does. Separating metadata does not separate data — give each catalog
3894
+ its own `storage.bucketUrl` prefix as well, since data-path-based
3895
+ maintenance (e.g. `ducklake_delete_orphaned_files`) treats a
3896
+ co-tenant catalog's files under a shared prefix as orphaned.
3897
+
3898
+ This is an ORGANIZATIONAL boundary, not an access-control one. The
3899
+ separation is which schema a configuration names, so any config
3900
+ whose catalog role can reach a sibling schema could name it and
3901
+ read that catalog's metadata — and therefore its data-file paths.
3902
+ Where catalogs must be isolated from one another rather than merely
3903
+ kept tidy, grant each its own role with `USAGE` limited to its own
3904
+ schema; a database-per-catalog remains the strongest separation.
3905
+
3906
+ Setting this on a catalog whose metadata already lives elsewhere
3907
+ does not move it: a read-write attach CREATES a new empty catalog
3908
+ in the named schema (and materializes into it), while a read-only
3909
+ attach fails because there is nothing there yet. Must be a plain
3910
+ identifier (`[A-Za-z_][A-Za-z0-9_]*`) — the value reaches both a
3911
+ quoted string literal in the ATTACH and an identifier position in
3912
+ the catalog-format preflight, so it is validated at config load
3913
+ rather than escaped for two different contexts.
3704
3914
  required:
3705
3915
  - postgresConnection
3706
3916
  required:
@@ -3936,6 +4146,12 @@ components:
3936
4146
  # Pass result as an opaque JSON string that is malloyVersion dependent.
3937
4147
  data:
3938
4148
  type: string
4149
+ queryCorrelationId:
4150
+ type: ["string", "null"]
4151
+ description: >-
4152
+ Id the server minted for this statement and attached as the
4153
+ `query_id` property. Same contract and correlation use as
4154
+ `QueryResult.queryCorrelationId`.
3939
4155
 
3940
4156
  Error:
3941
4157
  type: object
@@ -4108,8 +4324,7 @@ components:
4108
4324
  forceRefresh:
4109
4325
  type: boolean
4110
4326
  default: false
4111
- description:
4112
- Build a new table even when a source's sourceEntityId is unchanged.
4327
+ description: Build a new table even when a source's sourceEntityId is unchanged.
4113
4328
  sourceNames:
4114
4329
  type: array
4115
4330
  items:
@@ -4117,6 +4332,36 @@ components:
4117
4332
  description:
4118
4333
  Restrict the plan/build to these persist source names. Omit = all
4119
4334
  persist sources.
4335
+ runContext:
4336
+ oneOf:
4337
+ - $ref: "#/components/schemas/RunContext"
4338
+ - type: "null"
4339
+ description: >-
4340
+ What the caller knows about this run and the publisher does not,
4341
+ attached as query metadata to every statement the build issues so the
4342
+ backend's own reporting can attribute the build. Omit when there is
4343
+ nothing to add.
4344
+
4345
+ RunContext:
4346
+ type: object
4347
+ description: >-
4348
+ Caller-supplied context for one materialization run, folded into the
4349
+ per-query metadata of the statements it issues (see `QueryMetadata`).
4350
+ Observability only — it never affects what gets built or how anything is
4351
+ addressed.
4352
+ properties:
4353
+ trigger:
4354
+ type: string
4355
+ enum: [publish, on_demand, scheduler]
4356
+ description: >-
4357
+ What started this run, attached as the `trigger` property: a package
4358
+ publish, an explicit request, or the caller's scheduler.
4359
+ runId:
4360
+ type: string
4361
+ description: >-
4362
+ The caller's id for this run, attached as the `run_id` property so
4363
+ every statement of one build groups together in the backend's query
4364
+ history.
4120
4365
 
4121
4366
  MaterializationStatus:
4122
4367
  type: string
@@ -4263,6 +4508,20 @@ components:
4263
4508
  scope modes. (Per-source `sharing`/`schedule` were retired: scope is
4264
4509
  a single package-level mode and a schedule is package-root-only —
4265
4510
  declaring either on a source is a publish-time manifest error.)
4511
+ queryMetadata:
4512
+ oneOf:
4513
+ - $ref: "#/components/schemas/QueryMetadata"
4514
+ - type: "null"
4515
+ description: >-
4516
+ The source's EFFECTIVE per-query metadata after most-specific-wins
4517
+ resolution per property (`#@ persist queryMetadata.*` > model-file
4518
+ `## materialization.queryMetadata.*` > package
4519
+ `materialization.queryMetadata`). Null = declared at no level. The
4520
+ publisher attaches it — merged under its own context — to every
4521
+ statement it issues while building this source, and reports it here so
4522
+ a caller can see how a build will be tagged and tag its own queries
4523
+ the same way. Observability only: excluded from `sourceEntityId`, so
4524
+ editing it never re-addresses the source or orphans its table.
4266
4525
  columns:
4267
4526
  type: array
4268
4527
  description: Output schema of the source.
@@ -1 +1 @@
1
- import{$ as r,F as t,j as e,a0 as i,a6 as o}from"./index-B33zGctF.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};
1
+ import{$ as r,F as t,j as e,a0 as i,a6 as o}from"./index-B_jKMR35.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};
@@ -1 +1 @@
1
- import{$ as t,j as o,Z as a}from"./index-B33zGctF.js";function s(){const n=t();return o.jsx(a,{onClickEnvironment:n})}export{s as default};
1
+ import{$ as t,j as o,Z as a}from"./index-B_jKMR35.js";function s(){const n=t();return o.jsx(a,{onClickEnvironment:n})}export{s as default};
@@ -1 +1 @@
1
- import{c,j as s}from"./index-B33zGctF.js";const t=c(s.jsx("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1"})),a=c(s.jsx("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5M2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1m18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1m0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1M5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0z"}));export{t as D,a as L};
1
+ import{c,j as s}from"./index-B_jKMR35.js";const t=c(s.jsx("path",{d:"M12 3c-4.97 0-9 4.03-9 9s4.03 9 9 9 9-4.03 9-9c0-.46-.04-.92-.1-1.36-.98 1.37-2.58 2.26-4.4 2.26-2.98 0-5.4-2.42-5.4-5.4 0-1.81.89-3.42 2.26-4.4-.44-.06-.9-.1-1.36-.1"})),a=c(s.jsx("path",{d:"M12 7c-2.76 0-5 2.24-5 5s2.24 5 5 5 5-2.24 5-5-2.24-5-5-5M2 13h2c.55 0 1-.45 1-1s-.45-1-1-1H2c-.55 0-1 .45-1 1s.45 1 1 1m18 0h2c.55 0 1-.45 1-1s-.45-1-1-1h-2c-.55 0-1 .45-1 1s.45 1 1 1M11 2v2c0 .55.45 1 1 1s1-.45 1-1V2c0-.55-.45-1-1-1s-1 .45-1 1m0 18v2c0 .55.45 1 1 1s1-.45 1-1v-2c0-.55-.45-1-1-1s-1 .45-1 1M5.99 4.58c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0s.39-1.03 0-1.41zm12.37 12.37c-.39-.39-1.03-.39-1.41 0-.39.39-.39 1.03 0 1.41l1.06 1.06c.39.39 1.03.39 1.41 0 .39-.39.39-1.03 0-1.41zm1.06-10.96c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0zM7.05 18.36c.39-.39.39-1.03 0-1.41-.39-.39-1.03-.39-1.41 0l-1.06 1.06c-.39.39-.39 1.03 0 1.41s1.03.39 1.41 0z"}));export{t as D,a as L};
@@ -1,2 +1,2 @@
1
- import{u as Pe,g as Ee,r as u,R as Ce,a as Ie,c as S,j as t,s as M,B as Me,m as J,e as oe,b as le,d as ce,f as de,h as ze,i as O,k as pe,T as U,l as q,n as Te,o as De,p as Re,q as ue,t as Be,v as se,w as Le,x as He,y as $e,z as A,A as $,M as Ne,P as Ae,C as We,D as Oe,S as Ve,Y as Ue,E as Q,I as V,F as he,$ as Z,G as f,H as Qe,J as xe,L as F,X as Fe,K as Xe,N as ae,O as fe,Q as me,U as ge,V as Ye,W as _e,_ as Ke}from"./index-B33zGctF.js";import{D as Ge,L as Je}from"./LightMode-CNhIlIlJ.js";function qe(e,r,n,o,s){const[a,i]=u.useState(()=>s&&n?n(e).matches:o?o(e).matches:r);return Ie(()=>{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 Ze={...Ce},ye=Ze.useSyncExternalStore;function et(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 ye(h,c,i)}function be(e={}){const{themeId:r}=e;return function(o,s={}){let a=Pe();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:x=null,noSsr:p=!1}=Ee({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(`
1
+ import{u as Pe,g as Ee,r as u,R as Ce,a as Ie,c as S,j as t,s as M,B as Me,m as J,e as oe,b as le,d as ce,f as de,h as ze,i as O,k as pe,T as U,l as q,n as Te,o as De,p as Re,q as ue,t as Be,v as se,w as Le,x as He,y as $e,z as A,A as $,M as Ne,P as Ae,C as We,D as Oe,S as Ve,X as Ue,E as Q,I as V,F as he,$ as Z,G as f,H as Qe,J as xe,L as F,K as Fe,N as Xe,O as ae,Q as fe,U as me,V as ge,W as Ye,Y as _e,_ as Ke}from"./index-B_jKMR35.js";import{D as Ge,L as Je}from"./LightMode-DGNmhG0u.js";function qe(e,r,n,o,s){const[a,i]=u.useState(()=>s&&n?n(e).matches:o?o(e).matches:r);return Ie(()=>{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 Ze={...Ce},ye=Ze.useSyncExternalStore;function et(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 ye(h,c,i)}function be(e={}){const{themeId:r}=e;return function(o,s={}){let a=Pe();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:x=null,noSsr:p=!1}=Ee({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
2
  `)),(ye!==void 0?et:qe)(m,c,h,x,p)}}be();const tt=S(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"})),rt=M(Me,{name:"MuiBreadcrumbCollapsed"})(J(({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:oe(e.palette.grey[200],.12)}:{backgroundColor:oe(e.palette.grey[600],.12)}}}))),nt=M(tt)({width:24,height:16});function ot(e){const{slots:r={},slotProps:n={},...o}=e,s=e;return t.jsx("li",{children:t.jsx(rt,{focusRipple:!0,...o,ownerState:s,children:t.jsx(nt,{as:r.CollapsedIcon,ownerState:s,...n.collapsedIcon})})})}function st(e){return ce("MuiBreadcrumbs",e)}const at=le("MuiBreadcrumbs",["root","ol","li","separator"]),it=e=>{const{classes:r}=e;return pe({root:["root"],li:["li"],ol:["ol"],separator:["separator"]},st,r)},lt=M(U,{name:"MuiBreadcrumbs",slot:"Root",overridesResolver:(e,r)=>[{[`& .${at.li}`]:r.li},r.root]})({}),ct=M("ol",{name:"MuiBreadcrumbs",slot:"Ol"})({display:"flex",flexWrap:"wrap",alignItems:"center",padding:0,margin:0,listStyle:"none"}),dt=M("li",{name:"MuiBreadcrumbs",slot:"Separator"})({display:"flex",userSelect:"none",marginLeft:8,marginRight:8});function pt(e,r,n,o){return e.reduce((s,a,i)=>(i<e.length-1?s=s.concat(a,t.jsx(dt,{"aria-hidden":!0,className:r,ownerState:o,children:n},`separator-${i}`)):s.push(a),s),[])}const ut=u.forwardRef(function(r,n){const o=de({props:r,name:"MuiBreadcrumbs"}),{children:s,className:a,component:i="nav",slots:c={},slotProps:h={},expandText:x="Show path",itemsAfterCollapse:p=1,itemsBeforeCollapse:m=1,maxItems:y=8,separator:P="/",...H}=o,[z,E]=u.useState(!1),v={...o,component:i,expanded:z,expandText:x,itemsAfterCollapse:p,itemsBeforeCollapse:m,maxItems:y,separator:P},C=it(v),T=ze({elementType:c.CollapsedIcon,externalSlotProps:h.collapsedIcon,ownerState:v}),j=u.useRef(null),k=d=>{const w=()=>{E(!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(ot,{"aria-label":x,slots:{CollapsedIcon:c.CollapsedIcon},slotProps:{collapsedIcon:T},onClick:w},"ellipsis"),...d.slice(d.length-p,d.length)]},D=u.Children.toArray(s).filter(d=>u.isValidElement(d)).map((d,w)=>t.jsx("li",{className:C.li,children:d},`child-${w}`));return t.jsx(lt,{ref:n,component:i,color:"textSecondary",className:O(C.root,a),ownerState:v,...H,children:t.jsx(ct,{className:C.ol,ref:j,ownerState:v,children:pt(z||y&&D.length<=y?D:k(D),C.separator,P,v)})})});function ht(e,r,n){const o=r.getBoundingClientRect(),s=n&&n.getBoundingClientRect(),a=ue(r);let i;if(r.fakeTransform)i=r.fakeTransform;else{const x=a.getComputedStyle(r);i=x.getPropertyValue("-webkit-transform")||x.getPropertyValue("transform")}let c=0,h=0;if(i&&i!=="none"&&typeof i=="string"){const x=i.split("(")[1].split(")")[0].split(",");c=parseInt(x[4],10),h=parseInt(x[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 xt(e){return typeof e=="function"?e():e}function W(e,r,n){const o=xt(n),s=ht(e,r,o);s&&(r.style.webkitTransform=s,r.style.transform=s)}const ft=u.forwardRef(function(r,n){const o=q(),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:x,direction:p="down",easing:m=s,in:y,onEnter:P,onEntered:H,onEntering:z,onExit:E,onExited:v,onExiting:C,style:T,timeout:j=a,TransitionComponent:k=Te,...D}=r,d=u.useRef(null),w=De(Re(h),d,n),b=l=>g=>{l&&(g===void 0?l(d.current):l(d.current,g))},X=b((l,g)=>{W(p,l,x),Le(l),P&&P(l,g)}),te=b((l,g)=>{const L=se({timeout:j,style:T,easing:m},{mode:"enter"});l.style.webkitTransition=o.transitions.create("-webkit-transform",{...L}),l.style.transition=o.transitions.create("transform",{...L}),l.style.webkitTransform="none",l.style.transform="none",z&&z(l,g)}),R=b(H),B=b(C),I=b(l=>{const g=se({timeout:j,style:T,easing:m},{mode:"exit"});l.style.webkitTransition=o.transitions.create("-webkit-transform",g),l.style.transition=o.transitions.create("transform",g),W(p,l,x),E&&E(l)}),Y=b(l=>{l.style.webkitTransition="",l.style.transition="",v&&v(l)}),_=l=>{i&&i(d.current,l)},N=u.useCallback(()=>{d.current&&W(p,d.current,x)},[p,x]);return u.useEffect(()=>{if(y||p==="down"||p==="right")return;const l=Be(()=>{d.current&&W(p,d.current,x)}),g=ue(d.current);return g.addEventListener("resize",l),()=>{l.clear(),g.removeEventListener("resize",l)}},[p,y,x]),u.useEffect(()=>{y||N()},[y,N]),t.jsx(k,{nodeRef:d,onEnter:X,onEntered:R,onEntering:te,onExit:I,onExited:Y,onExiting:B,addEndListener:_,appear:c,in:y,timeout:j,...D,children:(l,{ownerState:g,...L})=>u.cloneElement(h,{ref:w,style:{visibility:l==="exited"&&!y?"hidden":void 0,...T,...h.props.style},...L})})});function mt(e){return ce("MuiDrawer",e)}le("MuiDrawer",["root","docked","paper","anchorLeft","anchorRight","anchorTop","anchorBottom","paperAnchorLeft","paperAnchorRight","paperAnchorTop","paperAnchorBottom","paperAnchorDockedLeft","paperAnchorDockedRight","paperAnchorDockedTop","paperAnchorDockedBottom","modal"]);const ve=(e,r)=>{const{ownerState:n}=e;return[r.root,(n.variant==="permanent"||n.variant==="persistent")&&r.docked,r.modal]},gt=e=>{const{classes:r,anchor:n,variant:o}=e,s={root:["root",`anchor${$(n)}`],docked:[(o==="permanent"||o==="persistent")&&"docked"],modal:["modal"],paper:["paper",`paperAnchor${$(n)}`,o!=="temporary"&&`paperAnchorDocked${$(n)}`]};return pe(s,mt,r)},yt=M(Ne,{name:"MuiDrawer",slot:"Root",overridesResolver:ve})(J(({theme:e})=>({zIndex:(e.vars||e).zIndex.drawer}))),bt=M("div",{shouldForwardProp:We,name:"MuiDrawer",slot:"Docked",skipVariantsResolver:!1,overridesResolver:ve})({flex:"0 0 auto"}),vt=M(Ae,{name:"MuiDrawer",slot:"Paper",overridesResolver:(e,r)=>{const{ownerState:n}=e;return[r.paper,r[`paperAnchor${$(n.anchor)}`],n.variant!=="temporary"&&r[`paperAnchorDocked${$(n.anchor)}`]]}})(J(({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}`}}]}))),je={left:"right",right:"left",top:"down",bottom:"up"};function jt(e){return["left","right"].includes(e)}function kt({direction:e},r){return e==="rtl"&&jt(r)?je[r]:r}const wt=u.forwardRef(function(r,n){const o=de({props:r,name:"MuiDrawer"}),s=q(),a=He(),i={enter:s.transitions.duration.enteringScreen,exit:s.transitions.duration.leavingScreen},{anchor:c="left",BackdropProps:h,children:x,className:p,elevation:m=16,hideBackdrop:y=!1,ModalProps:{BackdropProps:P,...H}={},onClose:z,open:E=!1,PaperProps:v={},SlideProps:C,TransitionComponent:T,transitionDuration:j=i,variant:k="temporary",slots:D={},slotProps:d={},...w}=o,b=u.useRef(!1);u.useEffect(()=>{b.current=!0},[]);const X=kt({direction:a?"rtl":"ltr"},c),R={...o,anchor:c,elevation:m,open:E,variant:k,...w},B=gt(R),I={slots:{transition:T,...D},slotProps:{paper:v,transition:C,...d,backdrop:$e(d.backdrop||{...h,...P},{transitionDuration:j})}},[Y,_]=A("root",{ref:n,elementType:yt,className:O(B.root,B.modal,p),shouldForwardComponentProp:!0,ownerState:R,externalForwardedProps:{...I,...w,...H},additionalProps:{open:E,onClose:z,hideBackdrop:y,slots:{backdrop:I.slots.backdrop},slotProps:{backdrop:I.slotProps.backdrop}}}),[N,l]=A("paper",{elementType:vt,shouldForwardComponentProp:!0,className:O(B.paper,v.className),ownerState:R,externalForwardedProps:I,additionalProps:{elevation:k==="temporary"?m:0,square:!0,...k==="temporary"&&{role:"dialog","aria-modal":"true"}}}),[g,L]=A("docked",{elementType:bt,ref:n,className:O(B.root,B.docked,p),ownerState:R,externalForwardedProps:I,additionalProps:w}),[we,Se]=A("transition",{elementType:ft,ownerState:R,externalForwardedProps:I,additionalProps:{in:E,direction:je[X],timeout:j,appear:b.current}}),re=t.jsx(N,{...l,children:x});if(k==="permanent")return t.jsx(g,{...L,children:re});const ne=t.jsx(we,{...Se,children:re});return k==="persistent"?t.jsx(g,{...L,children:ne}):t.jsx(Y,{..._,children:ne})}),St=be({themeId:Oe}),Pt=S([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")]),Et=S(t.jsx("path",{d:"M10.85 12.65h2.3L12 9zM20 8.69V4h-4.69L12 .69 8.69 4H4v4.69L.69 12 4 15.31V20h4.69L12 23.31 15.31 20H20v-4.69L23.31 12zM14.3 16l-.7-2h-3.2l-.7 2H7.8L11 7h2l3.2 9z"})),Ct=S(t.jsx("path",{d:"M10 6 8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"})),It=S(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"})),Mt=S(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"})),zt=S(t.jsx("path",{d:"m12 5.69 5 4.5V18h-2v-6H9v6H7v-7.81zM12 3 2 12h3v8h6v-6h2v6h6v-8h3z"})),Tt=S(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"})),Dt=S([t.jsx("path",{d:"M12 22C6.49 22 2 17.51 2 12S6.49 2 12 2s10 4.04 10 9c0 3.31-2.69 6-6 6h-1.77c-.28 0-.5.22-.5.5 0 .12.05.23.13.33.41.47.64 1.06.64 1.67 0 1.38-1.12 2.5-2.5 2.5m0-18c-4.41 0-8 3.59-8 8s3.59 8 8 8c.28 0 .5-.22.5-.5 0-.16-.08-.28-.14-.35-.41-.46-.63-1.05-.63-1.65 0-1.38 1.12-2.5 2.5-2.5H16c2.21 0 4-1.79 4-4 0-3.86-3.59-7-8-7"},"0"),t.jsx("circle",{cx:"6.5",cy:"11.5",r:"1.5"},"1"),t.jsx("circle",{cx:"9.5",cy:"7.5",r:"1.5"},"2"),t.jsx("circle",{cx:"14.5",cy:"7.5",r:"1.5"},"3"),t.jsx("circle",{cx:"17.5",cy:"11.5",r:"1.5"},"4")]);function G(e){return t.jsxs(Ve,{...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"})]})}const Rt={light:"dark",dark:"auto",auto:"light"},ie={light:"Light mode (click for dark)",dark:"Dark mode (click for auto)",auto:"Auto mode (follows OS, click for light)"};function Bt(){const{mode:e,userChoice:r,setMode:n,allowUserToggle:o}=Ue();if(!o)return null;const s=r??e,a=Rt[s],i=s==="auto"?Et:s==="dark"?Ge:Je;return t.jsx(Q,{title:ie[s],children:t.jsx(V,{"aria-label":ie[s],onClick:()=>n(a),size:"small",children:t.jsx(i,{fontSize:"small"})})})}function K({label:e,onClick:r}){return t.jsx(Qe,{clickable:!0,onClick:r,label:e,size:"small","aria-label":`Navigate to ${e}`,sx:n=>({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:n.palette.mode==="dark"?"rgba(255, 255, 255, 0.08)":"grey.100"}})})}function Lt(){const e=he(),r=e["*"],n=Z();return!e.environmentName&&!e.packageName&&!r?null:t.jsx(f,{sx:{display:"flex",alignItems:"center",minWidth:0},children:t.jsxs(ut,{"aria-label":"breadcrumb",separator:t.jsx(Ct,{sx:{fontSize:14,color:"text.secondary"}}),children:[e.environmentName&&t.jsx(K,{label:e.environmentName,onClick:o=>n(`/${e.environmentName}/`,o)}),e.packageName&&t.jsx(K,{label:e.packageName,onClick:o=>n(`/${e.environmentName}/${e.packageName}/`,o)}),r&&t.jsx(K,{label:r,onClick:o=>n(`/${e.environmentName}/${e.packageName}/${r}`,o)})]})})}const Ht=260,$t=64;function ke({isCollapsed:e,onToggleCollapse:r,logoHeader:n}){return t.jsxs(f,{sx:{height:"100dvh",width:e?$t:Ht,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(Nt,{isCollapsed:e,onToggleCollapse:r,logoHeader:n}),t.jsxs(f,{sx:{flex:1,overflowY:"auto",overflowX:"hidden",py:1},children:[t.jsx(At,{isCollapsed:e}),t.jsx(Wt,{isCollapsed:e}),t.jsx(Ot,{isCollapsed:e})]}),t.jsx(Vt,{isCollapsed:e})]})}function Nt({isCollapsed:e,onToggleCollapse:r,logoHeader:n}){const o=Z();return n?t.jsxs(f,{sx:{height:56,display:"flex",alignItems:"center",justifyContent:"space-between",px:e?0:2,flexShrink:0},children:[n,t.jsx(V,{size:"small",onClick:r,"aria-label":e?"Expand sidebar":"Collapse sidebar",children:t.jsx(G,{fontSize:"small"})})]}):t.jsxs(f,{sx:{minHeight:56,display:"flex",flexDirection:e?"column":"row",alignItems:"center",justifyContent:e?"center":"space-between",gap:e?.5:0,py:e?1:0,px:e?0:2,flexShrink:0},children:[t.jsxs(f,{onClick:s=>o("/",s),sx:{display:"flex",alignItems:"center",gap:1,cursor:"pointer",minWidth:0},children:[t.jsx(f,{component:"img",src:"/logo.svg",alt:"Malloy",sx:{width:24,height:24,flexShrink:0}}),!e&&t.jsx(U,{variant:"subtitle1",sx:{color:"text.primary",fontWeight:500,letterSpacing:"-0.025em",whiteSpace:"nowrap",overflow:"hidden",textOverflow:"ellipsis"},children:"Malloy Publisher"})]}),t.jsx(Q,{title:e?"Expand sidebar":"Collapse sidebar",placement:"right",children:t.jsx(V,{size:"small",onClick:r,"aria-label":e?"Expand sidebar":"Collapse sidebar",children:t.jsx(G,{fontSize:"small"})})})]})}function At({isCollapsed:e}){const n=xe().pathname==="/";return t.jsx(F,{sx:{py:0},children:t.jsx(ee,{icon:t.jsx(zt,{fontSize:"small"}),label:"Home",to:"/",selected:n,isCollapsed:e})})}function Wt({isCollapsed:e}){const{apiClients:r}=Fe(),n=he(),{data:o}=Xe({queryKey:["environments"],queryFn:()=>r.environments.listEnvironments()}),s=o?.data??[];return s.length===0?null:t.jsxs(f,{sx:{mt:1},children:[!e&&t.jsx(U,{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(F,{sx:{py:0},children:s.map(a=>{const i=a.name??"";return t.jsx(ee,{icon:t.jsx(Mt,{fontSize:"small"}),label:i,to:`/${i}`,selected:n.environmentName===i,isCollapsed:e},i)})})]})}function Ot({isCollapsed:e}){const n=xe().pathname.startsWith("/settings/theme");return t.jsxs(f,{sx:{mt:1},children:[!e&&t.jsx(U,{variant:"caption",sx:{display:"block",px:3,py:1,color:"text.secondary",fontWeight:500,textTransform:"uppercase",fontSize:"0.6875rem",letterSpacing:"0.5px"},children:"Settings"}),t.jsx(F,{sx:{py:0},children:t.jsx(ee,{icon:t.jsx(Dt,{fontSize:"small"}),label:"Visualization theme",to:"/settings/theme",selected:n,isCollapsed:e})})]})}function Vt({isCollapsed:e}){const r=[{label:"Malloy Docs",href:ae.docsHome,icon:t.jsx(Pt,{fontSize:"small"}),external:!0},{label:"Publisher Docs",href:ae.publishing,icon:t.jsx(Tt,{fontSize:"small"}),external:!0},{label:"Publisher API",href:"/api-doc.html",icon:t.jsx(It,{fontSize:"small"}),external:!1}];return t.jsx(F,{sx:{py:1},children:r.map(n=>t.jsx(Ut,{label:n.label,href:n.href,icon:n.icon,external:n.external,isCollapsed:e},n.label))})}function ee({icon:e,label:r,to:n,selected:o,isCollapsed:s}){const a=Z(),i=t.jsxs(fe,{selected:o,onClick:c=>a(n,c),sx:{justifyContent:s?"center":"flex-start",px:s?0:2},children:[t.jsx(me,{sx:{minWidth:s?0:36,justifyContent:"center",color:o?"text.primary":"text.secondary"},children:e}),!s&&t.jsx(ge,{primary:r,primaryTypographyProps:{variant:"body2",sx:{overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}})]});return s?t.jsx(Q,{title:r,placement:"right",children:t.jsx(f,{children:i})}):i}function Ut({label:e,href:r,icon:n,external:o,isCollapsed:s}){const a=t.jsxs(fe,{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(me,{sx:{minWidth:s?0:36,justifyContent:"center",color:"text.secondary"},children:n}),!s&&t.jsx(ge,{primary:e,primaryTypographyProps:{variant:"body2",sx:{color:"text.secondary",overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"}}})]});return s?t.jsx(Q,{title:e,placement:"right",children:t.jsx(f,{children:a})}):a}function Qt({open:e,onClose:r,logoHeader:n}){return t.jsx(wt,{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(ke,{isCollapsed:!1,onToggleCollapse:r,logoHeader:n})})}function Yt({headerProps:e}){const r=q(),n=St(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(f,{sx:{height:"100dvh",display:"flex",flexDirection:"row",bgcolor:"background.default"},children:[n&&t.jsx(ke,{isCollapsed:a,onToggleCollapse:()=>i(c=>!c),logoHeader:e?.logoHeader}),t.jsxs(f,{component:"main",sx:{flex:1,display:"flex",flexDirection:"column",minWidth:0},children:[t.jsxs(f,{sx:{flexShrink:0,display:"flex",alignItems:"center",justifyContent:"space-between",height:Ye.headerHeight,px:{xs:1,md:3},backgroundColor:"background.default"},children:[t.jsx(f,{sx:{display:{xs:"flex",md:"none"},alignItems:"center",mr:1},children:t.jsx(V,{size:"small",onClick:()=>s(!0),"aria-label":"Open navigation",children:t.jsx(G,{fontSize:"small"})})}),t.jsx(f,{sx:{flex:1,minWidth:0,display:"flex",alignItems:"center"},children:t.jsx(Lt,{})}),t.jsxs(f,{id:"header-actions-portal",sx:{display:"flex",alignItems:"center",flexShrink:0,gap:1},children:[t.jsx(Bt,{}),e?.endCap]})]}),t.jsx(f,{sx:{flex:1,overflow:"auto",minWidth:320,minHeight:0},children:t.jsx(u.Suspense,{fallback:t.jsx(Ke,{}),children:t.jsx(_e,{})})})]}),t.jsx(Qt,{open:o,onClose:()=>s(!1),logoHeader:e?.logoHeader})]})}export{Yt as default};
@@ -1 +1 @@
1
- import{F as r,$ as t,j as e,a0 as c,a5 as o}from"./index-B33zGctF.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};
1
+ import{F as r,$ as t,j as e,a0 as c,a5 as o}from"./index-B_jKMR35.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};
@@ -1 +1 @@
1
- import{F as l,$ as x,j as e,a0 as t,a1 as d,G as r,a2 as h,a3 as p}from"./index-B33zGctF.js";function g(){const n=l(),a=n["*"],m=x();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 s={p:3,maxWidth:1200,mx:"auto"};if(a?.startsWith("pages/")&&!a.endsWith(".malloy")&&!a.endsWith(".malloynb")){const o=a.slice(6),c=t({environmentName:n.environmentName,packageName:n.packageName,modelPath:o});return e.jsx(d,{resourceUri:c})}const i=t({environmentName:n.environmentName,packageName:n.packageName,modelPath:a});return a?.endsWith(".malloy")?e.jsx(r,{sx:s,children:e.jsx(h,{resourceUri:i,runOnDemand:!0,maxResultSize:512*1024})}):a?.endsWith(".malloynb")?e.jsx(r,{sx:s,children:e.jsx(p,{resourceUri:i,maxResultSize:1024*1024,onNavigate:m})}):e.jsx(r,{sx:s,children:e.jsxs("h2",{children:["Unrecognized file type: ",a]})})}export{g as default};
1
+ import{F as l,$ as x,j as e,a0 as t,a1 as d,G as r,a2 as h,a3 as p}from"./index-B_jKMR35.js";function g(){const n=l(),a=n["*"],m=x();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 s={p:3,maxWidth:1200,mx:"auto"};if(a?.startsWith("pages/")&&!a.endsWith(".malloy")&&!a.endsWith(".malloynb")){const o=a.slice(6),c=t({environmentName:n.environmentName,packageName:n.packageName,modelPath:o});return e.jsx(d,{resourceUri:c})}const i=t({environmentName:n.environmentName,packageName:n.packageName,modelPath:a});return a?.endsWith(".malloy")?e.jsx(r,{sx:s,children:e.jsx(h,{resourceUri:i,runOnDemand:!0,maxResultSize:512*1024})}):a?.endsWith(".malloynb")?e.jsx(r,{sx:s,children:e.jsx(p,{resourceUri:i,maxResultSize:1024*1024,onNavigate:m})}):e.jsx(r,{sx:s,children:e.jsxs("h2",{children:["Unrecognized file type: ",a]})})}export{g as default};
@@ -1 +1 @@
1
- import{F as r,$ as t,j as e,a0 as c,a4 as o}from"./index-B33zGctF.js";function l(){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{l as default};
1
+ import{F as r,$ as t,j as e,a0 as c,a4 as o}from"./index-B_jKMR35.js";function l(){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{l as default};
@@ -1 +1 @@
1
- import{a7 as o,j as r,a8 as s,a9 as n,G as t,T as a}from"./index-B33zGctF.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};
1
+ import{a7 as o,j as r,a8 as s,a9 as n,G as t,T as a}from"./index-B_jKMR35.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};