@malloy-publisher/server 0.0.235 → 0.0.237
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/dist/app/api-doc.yaml +83 -27
- package/dist/app/assets/{EnvironmentPage-BsAnavYN.js → EnvironmentPage-DaP6CpgK.js} +1 -1
- package/dist/app/assets/{HomePage-CADE138j.js → HomePage-C9yNw3iu.js} +1 -1
- package/dist/app/assets/{LightMode-Cfh7KzN8.js → LightMode-Be4-G-dX.js} +1 -1
- package/dist/app/assets/{MainPage-CO3pRlnV.js → MainPage-J_rU2SgI.js} +2 -2
- package/dist/app/assets/{MaterializationsPage-p9YjkRXZ.js → MaterializationsPage-DHgPI4MO.js} +1 -1
- package/dist/app/assets/ModelPage-BzXfjTu5.js +1 -0
- package/dist/app/assets/{PackagePage-e4kN75YR.js → PackagePage-ByoSTLJ4.js} +1 -1
- package/dist/app/assets/RouteError-CrSeKN2r.js +1 -0
- package/dist/app/assets/{ThemeEditorPage-CciagFTq.js → ThemeEditorPage-Btxnmhtk.js} +1 -1
- package/dist/app/assets/{WorkbookPage-DNWmkCXa.js → WorkbookPage-D6JLPnWO.js} +1 -1
- package/dist/app/assets/{core-Rj_4rRnA.es-BZyvITuO.js → core-BSRgt1mG.es-Bc_D2Lq4.js} +1 -1
- package/dist/app/assets/{index-CH2AcDzc.js → index-BRijWj6K.js} +15 -15
- package/dist/app/assets/{index-DQa463gC.js → index-BX4D94xw.js} +1 -1
- package/dist/app/assets/{index-VBbcc8s6.js → index-Cvy0xtb7.js} +1 -1
- package/dist/app/assets/{index-DQpV7MyA.js → index-DMAhIJNC.js} +1 -1
- package/dist/app/index.html +1 -1
- package/dist/package_load_worker.mjs +59 -20
- package/dist/server.mjs +1342 -616
- package/package.json +8 -2
- package/.eslintrc.json +0 -44
- package/.prettierignore +0 -1
- package/.prettierrc +0 -4
- package/build.ts +0 -97
- package/dist/app/assets/ModelPage-C1OSTv-x.js +0 -1
- package/dist/app/assets/RouteError-CzbfOkng.js +0 -1
- package/eslint.config.mjs +0 -76
- package/k6-tests/README.md +0 -144
- package/k6-tests/bun.lock +0 -797
- package/k6-tests/load-test/load-test-crud-connections.ts +0 -263
- package/k6-tests/load-test/load-test-crud-packages.ts +0 -461
- package/k6-tests/load-test/load-test-crud-projects.ts +0 -160
- package/k6-tests/load-test/load-test-crud.ts +0 -142
- package/k6-tests/load-test/load-test.ts +0 -784
- package/k6-tests/package.json +0 -27
- package/k6-tests/scripts/run-with-otel.sh +0 -50
- package/k6-tests/smoke-test/smoke-test.ts +0 -158
- package/k6-tests/tsconfig.json +0 -29
- package/k6-tests/utils/client_factory.ts +0 -128
- package/k6-tests/utils/common.ts +0 -489
- package/k6-tests/utils/logger.ts +0 -62
- package/k6-tests/utils/types.d.ts +0 -35
- package/malloy_mcp.dxt +0 -0
- package/publisher.config.example.bigquery.json +0 -33
- package/publisher.config.example.duckdb.json +0 -23
- package/publisher.config.json +0 -23
- package/scripts/bake-duckdb-extensions.js +0 -110
- package/src/config.spec.ts +0 -1535
- package/src/config.theme.spec.ts +0 -178
- package/src/config.ts +0 -1142
- package/src/constants.ts +0 -105
- package/src/controller/compile.controller.ts +0 -40
- package/src/controller/connection.controller.spec.ts +0 -849
- package/src/controller/connection.controller.ts +0 -901
- package/src/controller/database.controller.ts +0 -24
- package/src/controller/materialization.controller.spec.ts +0 -293
- package/src/controller/materialization.controller.ts +0 -319
- package/src/controller/model.controller.ts +0 -164
- package/src/controller/package.controller.spec.ts +0 -273
- package/src/controller/package.controller.ts +0 -306
- package/src/controller/query.controller.ts +0 -152
- package/src/controller/theme.controller.ts +0 -83
- package/src/controller/watch-mode.controller.ts +0 -243
- package/src/data_styles.ts +0 -71
- package/src/default-publisher.config.json +0 -23
- package/src/ducklake_version.spec.ts +0 -163
- package/src/ducklake_version.ts +0 -153
- package/src/errors.spec.ts +0 -119
- package/src/errors.ts +0 -237
- package/src/filter_deprecation.spec.ts +0 -64
- package/src/filter_deprecation.ts +0 -42
- package/src/health.spec.ts +0 -123
- package/src/health.ts +0 -233
- package/src/heap_check.spec.ts +0 -144
- package/src/heap_check.ts +0 -144
- package/src/instrumentation.ts +0 -214
- package/src/json_utils.spec.ts +0 -51
- package/src/json_utils.ts +0 -33
- package/src/logger.spec.ts +0 -210
- package/src/logger.ts +0 -251
- package/src/malloy_pin_prereqs.spec.ts +0 -25
- package/src/materialization_metrics.spec.ts +0 -169
- package/src/materialization_metrics.ts +0 -346
- package/src/mcp/error_messages.spec.ts +0 -35
- package/src/mcp/error_messages.ts +0 -183
- package/src/mcp/handler_utils.spec.ts +0 -108
- package/src/mcp/handler_utils.ts +0 -251
- package/src/mcp/mcp_constants.ts +0 -6
- package/src/mcp/query_envelope.spec.ts +0 -229
- package/src/mcp/query_envelope.ts +0 -240
- package/src/mcp/server.protocol.spec.ts +0 -250
- package/src/mcp/server.ts +0 -87
- package/src/mcp/skills/build_skills_bundle.spec.ts +0 -51
- package/src/mcp/skills/build_skills_bundle.ts +0 -176
- package/src/mcp/skills/skills_bundle.json +0 -1
- package/src/mcp/skills/skills_bundle.spec.ts +0 -171
- package/src/mcp/tool_response.spec.ts +0 -108
- package/src/mcp/tool_response.ts +0 -138
- package/src/mcp/tools/compile_tool.spec.ts +0 -315
- package/src/mcp/tools/compile_tool.ts +0 -208
- package/src/mcp/tools/docs_search/build_docs_index.ts +0 -132
- package/src/mcp/tools/docs_search/malloy_docs_index.json +0 -1
- package/src/mcp/tools/docs_search_tool.spec.ts +0 -32
- package/src/mcp/tools/docs_search_tool.ts +0 -128
- package/src/mcp/tools/embedding_index.spec.ts +0 -1236
- package/src/mcp/tools/embedding_index.ts +0 -808
- package/src/mcp/tools/execute_query_tool.spec.ts +0 -294
- package/src/mcp/tools/execute_query_tool.ts +0 -316
- package/src/mcp/tools/get_context_eval.ts +0 -275
- package/src/mcp/tools/get_context_tool.spec.ts +0 -592
- package/src/mcp/tools/get_context_tool.ts +0 -585
- package/src/mcp/tools/reload_package_tool.spec.ts +0 -232
- package/src/mcp/tools/reload_package_tool.ts +0 -132
- package/src/mcp_config.spec.ts +0 -919
- package/src/mcp_config.ts +0 -425
- package/src/oom_guards.integration.spec.ts +0 -269
- package/src/package_load/package_load_pool.spec.ts +0 -252
- package/src/package_load/package_load_pool.ts +0 -931
- package/src/package_load/package_load_worker.ts +0 -1034
- package/src/package_load/protocol.ts +0 -364
- package/src/package_load/rpc_wait_accountant.spec.ts +0 -109
- package/src/package_load/rpc_wait_accountant.ts +0 -76
- package/src/package_load_metrics.spec.ts +0 -114
- package/src/package_load_metrics.ts +0 -127
- package/src/path_safety.spec.ts +0 -158
- package/src/path_safety.ts +0 -146
- package/src/pg_helpers.spec.ts +0 -223
- package/src/pg_helpers.ts +0 -52
- package/src/query_cap_metrics.spec.ts +0 -89
- package/src/query_cap_metrics.ts +0 -116
- package/src/query_concurrency.spec.ts +0 -247
- package/src/query_concurrency.ts +0 -237
- package/src/query_metadata_metrics.ts +0 -49
- package/src/query_param_utils.ts +0 -29
- package/src/query_timeout.spec.ts +0 -224
- package/src/query_timeout.ts +0 -179
- package/src/runtime/publisher.js +0 -328
- package/src/server-old.ts +0 -988
- package/src/server.ts +0 -2059
- package/src/service/annotations.spec.ts +0 -118
- package/src/service/annotations.ts +0 -91
- package/src/service/authorize.spec.ts +0 -154
- package/src/service/authorize.ts +0 -498
- package/src/service/authorize_integration.spec.ts +0 -2041
- package/src/service/build_plan.spec.ts +0 -685
- package/src/service/build_plan.ts +0 -797
- package/src/service/compile_authorize.spec.ts +0 -85
- package/src/service/compile_fragment_techniques.spec.ts +0 -156
- package/src/service/connection.spec.ts +0 -2360
- package/src/service/connection.ts +0 -2187
- package/src/service/connection_config.spec.ts +0 -734
- package/src/service/connection_config.ts +0 -899
- package/src/service/connection_federation.spec.ts +0 -184
- package/src/service/connection_fingerprint.spec.ts +0 -102
- package/src/service/connection_service.spec.ts +0 -711
- package/src/service/connection_service.ts +0 -291
- package/src/service/cron_evaluator.spec.ts +0 -79
- package/src/service/cron_evaluator.ts +0 -105
- package/src/service/db_utils.spec.ts +0 -1085
- package/src/service/db_utils.ts +0 -1502
- package/src/service/duckdb_instance_isolation.spec.ts +0 -137
- package/src/service/ducklake_lazy_attach.spec.ts +0 -110
- package/src/service/embedding_provider.spec.ts +0 -329
- package/src/service/embedding_provider.ts +0 -236
- package/src/service/environment.ts +0 -2191
- package/src/service/environment_admission.spec.ts +0 -344
- package/src/service/environment_compile.spec.ts +0 -197
- package/src/service/environment_store.spec.ts +0 -2274
- package/src/service/environment_store.ts +0 -2434
- package/src/service/environment_store_anchoring.spec.ts +0 -107
- package/src/service/environment_store_clone.spec.ts +0 -350
- package/src/service/explore_visibility.spec.ts +0 -434
- package/src/service/exports_probe.spec.ts +0 -107
- package/src/service/extension_fetch_policy.spec.ts +0 -256
- package/src/service/filter.spec.ts +0 -458
- package/src/service/filter.ts +0 -341
- package/src/service/filter_bypass.spec.ts +0 -418
- package/src/service/filter_integration.spec.ts +0 -1004
- package/src/service/freshness.spec.ts +0 -183
- package/src/service/freshness.ts +0 -112
- package/src/service/gcs_s3_utils.ts +0 -427
- package/src/service/given.ts +0 -105
- package/src/service/givens_integration.spec.ts +0 -219
- package/src/service/manifest_loader.spec.ts +0 -189
- package/src/service/manifest_loader.ts +0 -156
- package/src/service/materialization_build_session.spec.ts +0 -435
- package/src/service/materialization_build_session.ts +0 -681
- package/src/service/materialization_config_validation.spec.ts +0 -99
- package/src/service/materialization_config_validation.ts +0 -120
- package/src/service/materialization_eligibility.spec.ts +0 -158
- package/src/service/materialization_eligibility.ts +0 -305
- package/src/service/materialization_schedule_surface.spec.ts +0 -256
- package/src/service/materialization_scheduler.spec.ts +0 -289
- package/src/service/materialization_scheduler.ts +0 -304
- package/src/service/materialization_serve_transform.spec.ts +0 -1003
- package/src/service/materialization_serve_transform.ts +0 -779
- package/src/service/materialization_service.spec.ts +0 -2373
- package/src/service/materialization_service.ts +0 -2342
- package/src/service/materialization_test_fixtures.ts +0 -249
- package/src/service/model.spec.ts +0 -1157
- package/src/service/model.ts +0 -3370
- package/src/service/model_limits.spec.ts +0 -209
- package/src/service/model_limits.ts +0 -131
- package/src/service/model_storage_serve.spec.ts +0 -193
- package/src/service/model_storage_serve_joins.spec.ts +0 -193
- package/src/service/package.spec.ts +0 -612
- package/src/service/package.ts +0 -1799
- package/src/service/package_manifest.spec.ts +0 -230
- package/src/service/package_manifest.ts +0 -241
- package/src/service/package_memory_governor.spec.ts +0 -173
- package/src/service/package_memory_governor.ts +0 -233
- package/src/service/package_quote_bound_tables.spec.ts +0 -171
- package/src/service/package_race.spec.ts +0 -208
- package/src/service/package_reload_safety.spec.ts +0 -193
- package/src/service/package_rollback.spec.ts +0 -190
- package/src/service/package_worker_path.spec.ts +0 -645
- package/src/service/path_injection.spec.ts +0 -39
- package/src/service/persist_annotation_validation.spec.ts +0 -89
- package/src/service/persist_annotation_validation.ts +0 -59
- package/src/service/persistence_policy.spec.ts +0 -374
- package/src/service/proxy.spec.ts +0 -414
- package/src/service/proxy.ts +0 -248
- package/src/service/query_boundary.spec.ts +0 -470
- package/src/service/query_metadata.spec.ts +0 -408
- package/src/service/query_metadata.ts +0 -492
- package/src/service/query_metadata_identity.spec.ts +0 -149
- package/src/service/query_text.spec.ts +0 -79
- package/src/service/query_text.ts +0 -43
- package/src/service/quoting.spec.ts +0 -135
- package/src/service/quoting.ts +0 -78
- package/src/service/resolve_environment.ts +0 -15
- package/src/service/restricted_mode.spec.ts +0 -299
- package/src/service/source_extraction.ts +0 -225
- package/src/service/theme_store.ts +0 -199
- package/src/storage/DatabaseInterface.ts +0 -198
- package/src/storage/StorageManager.ts +0 -113
- package/src/storage/duckdb/ConnectionRepository.ts +0 -143
- package/src/storage/duckdb/DuckDBConnection.ts +0 -123
- package/src/storage/duckdb/DuckDBRepository.ts +0 -208
- package/src/storage/duckdb/EnvironmentRepository.ts +0 -148
- package/src/storage/duckdb/MaterializationRepository.spec.ts +0 -191
- package/src/storage/duckdb/MaterializationRepository.ts +0 -336
- package/src/storage/duckdb/PackageRepository.ts +0 -135
- package/src/storage/duckdb/schema.ts +0 -229
- package/src/stream_helpers.spec.ts +0 -280
- package/src/stream_helpers.ts +0 -162
- package/src/telemetry.ts +0 -20
- package/src/test_helpers/metrics_harness.ts +0 -166
- package/src/theme_key_parity.spec.ts +0 -57
- package/src/utils.ts +0 -29
- package/tests/fixtures/authorize-compile/model.malloy +0 -9
- package/tests/fixtures/authorize-compile/publisher.json +0 -4
- package/tests/fixtures/html-pages-nopublic/model.malloy +0 -1
- package/tests/fixtures/html-pages-nopublic/publisher.json +0 -5
- package/tests/fixtures/html-pages-test/data.csv +0 -3
- package/tests/fixtures/html-pages-test/public/assets/app.css +0 -3
- package/tests/fixtures/html-pages-test/public/barehtml.html +0 -4
- package/tests/fixtures/html-pages-test/public/bodymeta.html +0 -8
- package/tests/fixtures/html-pages-test/public/data.json +0 -1
- package/tests/fixtures/html-pages-test/public/fitcomment.html +0 -11
- package/tests/fixtures/html-pages-test/public/index.html +0 -9
- package/tests/fixtures/html-pages-test/public/nohead.html +0 -8
- package/tests/fixtures/html-pages-test/public/notfit.html +0 -13
- package/tests/fixtures/html-pages-test/public/slides.html +0 -12
- package/tests/fixtures/html-pages-test/public/sub/page2.html +0 -9
- package/tests/fixtures/html-pages-test/public/unterminated.html +0 -10
- package/tests/fixtures/html-pages-test/publisher.json +0 -5
- package/tests/fixtures/html-pages-test/report.malloy +0 -1
- package/tests/fixtures/persist-multi-level/data/orders.csv +0 -5
- package/tests/fixtures/persist-multi-level/multi_level.malloy +0 -18
- package/tests/fixtures/persist-multi-level/publisher.json +0 -5
- package/tests/fixtures/persist-schedule-test/data/orders.csv +0 -5
- package/tests/fixtures/persist-schedule-test/persist_schedule_test.malloy +0 -11
- package/tests/fixtures/persist-schedule-test/publisher.json +0 -7
- package/tests/fixtures/persist-schedule-warn-test/data/orders.csv +0 -5
- package/tests/fixtures/persist-schedule-warn-test/persist_warn_test.malloy +0 -11
- package/tests/fixtures/persist-schedule-warn-test/publisher.json +0 -6
- package/tests/fixtures/persist-test/data/orders.csv +0 -5
- package/tests/fixtures/persist-test/persist_test.malloy +0 -11
- package/tests/fixtures/persist-test/publisher.json +0 -5
- package/tests/fixtures/publisher.config.json +0 -15
- package/tests/fixtures/query-givens/data/orders.csv +0 -7
- package/tests/fixtures/query-givens/model.malloy +0 -34
- package/tests/fixtures/query-givens/publisher.json +0 -5
- package/tests/fixtures/xlsx/database.xlsx +0 -0
- package/tests/harness/mcp_test_setup.ts +0 -332
- package/tests/harness/rest_e2e.ts +0 -68
- package/tests/integration/authorize/compile_authorize_http.integration.spec.ts +0 -92
- package/tests/integration/concurrent_package/concurrent_package.integration.spec.ts +0 -280
- package/tests/integration/duckdb_storage/duckdb_storage.integration.spec.ts +0 -138
- package/tests/integration/first_boot/readiness_line.integration.spec.ts +0 -177
- package/tests/integration/html_pages/html_pages.integration.spec.ts +0 -440
- package/tests/integration/legacy_routes/legacy_routes.integration.spec.ts +0 -259
- package/tests/integration/materialization/environment_list.integration.spec.ts +0 -133
- package/tests/integration/materialization/freshness_gate.integration.spec.ts +0 -292
- package/tests/integration/materialization/manifest_binding.integration.spec.ts +0 -430
- package/tests/integration/materialization/materialization_lifecycle.integration.spec.ts +0 -441
- package/tests/integration/materialization/orchestrated_rebind.integration.spec.ts +0 -150
- package/tests/integration/materialization/reference_manifest.integration.spec.ts +0 -251
- package/tests/integration/materialization/schedule_edit.integration.spec.ts +0 -126
- package/tests/integration/materialization/scheduler.integration.spec.ts +0 -200
- package/tests/integration/materialization/scheduler_recovery.integration.spec.ts +0 -172
- package/tests/integration/materialization/scheduler_transitions.integration.spec.ts +0 -256
- package/tests/integration/materialization/scheduler_wiring.integration.spec.ts +0 -143
- package/tests/integration/mcp/mcp_execute_query_tool.integration.spec.ts +0 -438
- package/tests/integration/mcp/mcp_get_context_semantic.integration.spec.ts +0 -235
- package/tests/integration/mcp/mcp_transport.integration.spec.ts +0 -98
- package/tests/integration/query_givens/query_givens.integration.spec.ts +0 -146
- package/tests/integration/query_givens/query_givens_authorize.integration.spec.ts +0 -121
- package/tests/integration/sdk_givens/sdk_givens.integration.spec.ts +0 -110
- package/tests/integration/watch-mode/watch_mode.integration.spec.ts +0 -421
- package/tests/unit/controller/theme.controller.spec.ts +0 -141
- package/tests/unit/duckdb/attached_databases.test.ts +0 -1243
- package/tests/unit/duckdb/duckdb_connection.test.ts +0 -181
- package/tests/unit/duckdb/legacy_schema_migration.test.ts +0 -197
- package/tests/unit/duckdb/repositories.test.ts +0 -208
- package/tests/unit/ducklake/ducklake.test.ts +0 -952
- package/tests/unit/service/theme_store.spec.ts +0 -139
- package/tsconfig.json +0 -32
|
@@ -1,225 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared source / query introspection extracted from a compiled `ModelDef`.
|
|
3
|
-
*
|
|
4
|
-
* Both the in-process `Model.create` path (`service/model.ts`) and the
|
|
5
|
-
* package-load worker (`package_load/package_load_worker.ts`, which runs in a
|
|
6
|
-
* separate bundle and serializes the result over the worker protocol) need to
|
|
7
|
-
* walk a `ModelDef` and produce the same `sources` / `queries` shapes plus the
|
|
8
|
-
* `#(filter)` `filterMap`. This module is the single source of truth for that
|
|
9
|
-
* walk so the two call sites can't drift out of lockstep — the two callers
|
|
10
|
-
* differ only in how they type the result
|
|
11
|
-
* (generated API types vs. worker wire types — structurally identical, so each
|
|
12
|
-
* casts at its boundary) and in how they report a filter parse failure (the
|
|
13
|
-
* service logs a warning; the worker has no logger and stays silent), which is
|
|
14
|
-
* threaded through the optional `onParseError` callback.
|
|
15
|
-
*/
|
|
16
|
-
|
|
17
|
-
import {
|
|
18
|
-
isSourceDef,
|
|
19
|
-
ModelDef,
|
|
20
|
-
NamedModelObject,
|
|
21
|
-
NamedQueryDef,
|
|
22
|
-
StructDef,
|
|
23
|
-
TurtleDef,
|
|
24
|
-
} from "@malloydata/malloy";
|
|
25
|
-
import { annotationTexts, modelAnnotations } from "./annotations";
|
|
26
|
-
import { collectAuthorizeExprs, type AuthorizeMap } from "./authorize";
|
|
27
|
-
import { parseFilters, type FilterDefinition } from "./filter";
|
|
28
|
-
|
|
29
|
-
/** A `#(filter)` definition enriched with the dimension's Malloy type. */
|
|
30
|
-
export interface ExtractedFilter {
|
|
31
|
-
name: string;
|
|
32
|
-
dimension: string;
|
|
33
|
-
type: string;
|
|
34
|
-
implicit: boolean;
|
|
35
|
-
required: boolean;
|
|
36
|
-
dimensionType: string | undefined;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export interface ExtractedView {
|
|
40
|
-
name: string;
|
|
41
|
-
annotations: string[] | undefined;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Structural source shape both callers cast to their own typed view
|
|
46
|
-
* (`ApiSource` in the service, `ApiSourceWire` in the worker). `givens` is
|
|
47
|
-
* attached verbatim from the caller-supplied list, so it stays `unknown` here.
|
|
48
|
-
*/
|
|
49
|
-
export interface ExtractedSource {
|
|
50
|
-
name: string;
|
|
51
|
-
annotations: string[] | undefined;
|
|
52
|
-
views: ExtractedView[];
|
|
53
|
-
filters: ExtractedFilter[] | undefined;
|
|
54
|
-
givens: unknown;
|
|
55
|
-
/**
|
|
56
|
-
* Effective `#(authorize)` / `##(authorize)` expressions gating this source:
|
|
57
|
-
* file-level expressions first, then the source's own. Undefined when the
|
|
58
|
-
* source carries no authorize annotations. Surfaced for introspection;
|
|
59
|
-
* enforcement happens server-side.
|
|
60
|
-
*/
|
|
61
|
-
authorize: string[] | undefined;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface ExtractedQuery {
|
|
65
|
-
name: string;
|
|
66
|
-
sourceName: string | undefined;
|
|
67
|
-
annotations: string[] | undefined;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Extract every source from a compiled model, parsing `#(filter)` annotations
|
|
72
|
-
* along the way.
|
|
73
|
-
*
|
|
74
|
-
* Filters are collected by walking the `annotations.inherits` chain so that
|
|
75
|
-
* filters declared on a base source flow to an extending source. The chain runs
|
|
76
|
-
* child → parent, so we collect child-first then reverse — `parseFilters` uses
|
|
77
|
-
* "last wins" dedup, which lets a child's `#(filter)` override the base's.
|
|
78
|
-
*
|
|
79
|
-
* `givens` is attached unchanged to every source (Malloy exposes givens at the
|
|
80
|
-
* model level, not per-source). `onParseError`, when supplied, is invoked with
|
|
81
|
-
* the source name and error if a source's `#(filter)` annotations fail to parse;
|
|
82
|
-
* filter extraction then continues. Authorize parse errors are NOT routed here —
|
|
83
|
-
* they propagate (a malformed gate fails model load) so a security gate is never
|
|
84
|
-
* silently dropped.
|
|
85
|
-
*
|
|
86
|
-
* Authorize (`#(authorize)` / `##(authorize)`) is collected from the source's
|
|
87
|
-
* own `blockNotes` only — we do NOT walk the `inherits` chain. Note Malloy's
|
|
88
|
-
* behavior for `X is Y extend {...}`: if X declares its own `#(authorize)`,
|
|
89
|
-
* X.blockNotes holds only X's gates (Y's are dropped — the intended "curated
|
|
90
|
-
* re-exposure"); if X declares none, Malloy surfaces Y's blockNotes on X, so
|
|
91
|
-
* the base gate carries to the un-annotated extension (a safe default — a
|
|
92
|
-
* locked base stays locked unless an extension explicitly re-exposes itself).
|
|
93
|
-
* This carry happens through `blockNotes`, not the `inherits` chain, so reading
|
|
94
|
-
* own-blockNotes is sufficient. Joins are a separate concern and are not gated.
|
|
95
|
-
* The effective list per source is the file-level `##(authorize)` expressions
|
|
96
|
-
* (from `modelDef.annotations.notes`) followed by the source's own
|
|
97
|
-
* `#(authorize)` expressions, evaluated as one OR disjunction at request time.
|
|
98
|
-
*/
|
|
99
|
-
export function extractSourcesFromModelDef(
|
|
100
|
-
modelDef: ModelDef,
|
|
101
|
-
givens: unknown,
|
|
102
|
-
onParseError?: (sourceName: string, err: unknown) => void,
|
|
103
|
-
): {
|
|
104
|
-
sources: ExtractedSource[];
|
|
105
|
-
filterMap: Map<string, FilterDefinition[]>;
|
|
106
|
-
authorizeMap: AuthorizeMap;
|
|
107
|
-
} {
|
|
108
|
-
const filterMap = new Map<string, FilterDefinition[]>();
|
|
109
|
-
const authorizeMap: AuthorizeMap = new Map();
|
|
110
|
-
|
|
111
|
-
// File-level ##(authorize) is collected once and prepended to every source.
|
|
112
|
-
// Unlike filters, a malformed authorize annotation is NOT swallowed: the
|
|
113
|
-
// parse error propagates so the model fails to load loudly (caught per-model
|
|
114
|
-
// upstream and turned into a compilationError). Silently dropping a gate —
|
|
115
|
-
// and in the worker path there is no onParseError callback, so it would be
|
|
116
|
-
// truly silent — could leave a source that the author meant to lock looking
|
|
117
|
-
// unrestricted.
|
|
118
|
-
const fileLevelAuthorize = collectAuthorizeExprs(
|
|
119
|
-
(modelAnnotations(modelDef).notes ?? []).map((note) => note.text),
|
|
120
|
-
);
|
|
121
|
-
|
|
122
|
-
const sources: ExtractedSource[] = Object.values(modelDef.contents)
|
|
123
|
-
.filter((obj) => isSourceDef(obj))
|
|
124
|
-
.map((sourceObj) => {
|
|
125
|
-
const struct = sourceObj as StructDef;
|
|
126
|
-
const sourceName = struct.as || struct.name;
|
|
127
|
-
const annotations = annotationTexts(struct.annotations);
|
|
128
|
-
|
|
129
|
-
const collected: string[][] = [];
|
|
130
|
-
let cur = struct.annotations;
|
|
131
|
-
while (cur) {
|
|
132
|
-
if (cur.blockNotes) {
|
|
133
|
-
collected.push(cur.blockNotes.map((note) => note.text));
|
|
134
|
-
}
|
|
135
|
-
cur = cur.inherits;
|
|
136
|
-
}
|
|
137
|
-
const allAnnotations = collected.reverse().flat();
|
|
138
|
-
|
|
139
|
-
let filters: ExtractedFilter[] | undefined;
|
|
140
|
-
if (allAnnotations.length > 0) {
|
|
141
|
-
try {
|
|
142
|
-
const parsed = parseFilters(allAnnotations);
|
|
143
|
-
if (parsed.length > 0) {
|
|
144
|
-
filterMap.set(sourceName, parsed);
|
|
145
|
-
const fields = struct.fields;
|
|
146
|
-
filters = parsed.map((f) => {
|
|
147
|
-
const field = fields.find(
|
|
148
|
-
(fd) => (fd.as || fd.name) === f.dimension,
|
|
149
|
-
);
|
|
150
|
-
return {
|
|
151
|
-
name: f.name,
|
|
152
|
-
dimension: f.dimension,
|
|
153
|
-
type: f.type,
|
|
154
|
-
implicit: f.implicit,
|
|
155
|
-
required: f.required,
|
|
156
|
-
dimensionType: field?.type as string | undefined,
|
|
157
|
-
};
|
|
158
|
-
});
|
|
159
|
-
}
|
|
160
|
-
} catch (err) {
|
|
161
|
-
onParseError?.(sourceName, err);
|
|
162
|
-
}
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
// Authorize: the source's OWN #(authorize) annotations only — no
|
|
166
|
-
// inherits walk. File-level ##(authorize) is prepended so file gates
|
|
167
|
-
// and source gates form one OR disjunction. A malformed annotation
|
|
168
|
-
// propagates (model fails to load) rather than silently dropping the
|
|
169
|
-
// gate — see the file-level note above.
|
|
170
|
-
const ownNotes = (struct.annotations?.blockNotes ?? []).map(
|
|
171
|
-
(note) => note.text,
|
|
172
|
-
);
|
|
173
|
-
const effective = [
|
|
174
|
-
...fileLevelAuthorize,
|
|
175
|
-
...collectAuthorizeExprs(ownNotes),
|
|
176
|
-
];
|
|
177
|
-
let authorize: string[] | undefined;
|
|
178
|
-
if (effective.length > 0) {
|
|
179
|
-
authorizeMap.set(sourceName, effective);
|
|
180
|
-
authorize = effective;
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
const views: ExtractedView[] = struct.fields
|
|
184
|
-
.filter((field) => field.type === "turtle")
|
|
185
|
-
.filter((turtle) =>
|
|
186
|
-
// Filter out non-reduce views (e.g. indexes).
|
|
187
|
-
(turtle as TurtleDef).pipeline
|
|
188
|
-
.map((stage) => stage.type)
|
|
189
|
-
.every((type) => type === "reduce"),
|
|
190
|
-
)
|
|
191
|
-
.map((turtle) => ({
|
|
192
|
-
name: turtle.as || turtle.name,
|
|
193
|
-
annotations: annotationTexts(turtle.annotations),
|
|
194
|
-
}));
|
|
195
|
-
|
|
196
|
-
return {
|
|
197
|
-
name: sourceName,
|
|
198
|
-
annotations,
|
|
199
|
-
views,
|
|
200
|
-
filters,
|
|
201
|
-
givens,
|
|
202
|
-
authorize,
|
|
203
|
-
};
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
return { sources, filterMap, authorizeMap };
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
/** Extract every named query from a compiled model. */
|
|
210
|
-
export function extractQueriesFromModelDef(
|
|
211
|
-
modelDef: ModelDef,
|
|
212
|
-
): ExtractedQuery[] {
|
|
213
|
-
const isNamedQuery = (obj: NamedModelObject): obj is NamedQueryDef =>
|
|
214
|
-
obj.type === "query";
|
|
215
|
-
return Object.values(modelDef.contents)
|
|
216
|
-
.filter(isNamedQuery)
|
|
217
|
-
.map((queryObj) => ({
|
|
218
|
-
name: queryObj.as || queryObj.name,
|
|
219
|
-
sourceName:
|
|
220
|
-
typeof queryObj.structRef === "string"
|
|
221
|
-
? queryObj.structRef
|
|
222
|
-
: undefined,
|
|
223
|
-
annotations: annotationTexts(queryObj.annotations),
|
|
224
|
-
}));
|
|
225
|
-
}
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { Mutex } from "async-mutex";
|
|
2
|
-
import { getInstanceTheme, sanitizeTheme, Theme } from "../config";
|
|
3
|
-
import { logger } from "../logger";
|
|
4
|
-
import { DuckDBConnection } from "../storage/duckdb/DuckDBConnection";
|
|
5
|
-
import { StorageManager } from "../storage/StorageManager";
|
|
6
|
-
|
|
7
|
-
const THEME_ROW_ID = "default";
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Persistence for the instance-wide theme edited via the in-app Theme
|
|
11
|
-
* Editor. Backed by a single row in the `themes` table (DuckDB).
|
|
12
|
-
*
|
|
13
|
-
* Boot semantics: on first read after process start, if the table is
|
|
14
|
-
* empty, the row is seeded from `publisher.config.json`'s top-level
|
|
15
|
-
* `theme` block (if any). Subsequent writes go to DuckDB; the JSON file
|
|
16
|
-
* remains the boot seed only. This mirrors how environments + packages
|
|
17
|
-
* are handled. The JSON config is the seed; runtime mutations live in
|
|
18
|
-
* the DB and survive across restarts.
|
|
19
|
-
*
|
|
20
|
-
* Every payload read out of the DB is run through `sanitizeTheme` so a
|
|
21
|
-
* schema change can't put a stale shape in front of the editor (e.g.
|
|
22
|
-
* old per-mode `series` arrays after the simplification revert). The
|
|
23
|
-
* editor receives only fields that match the current type.
|
|
24
|
-
*
|
|
25
|
-
* Single in-process consumer; a Mutex serializes set / reset against
|
|
26
|
-
* concurrent reads to avoid the cache + DB diverging.
|
|
27
|
-
*/
|
|
28
|
-
export class ThemeStore {
|
|
29
|
-
private mutex = new Mutex();
|
|
30
|
-
private cached: Theme | undefined;
|
|
31
|
-
private cacheLoaded = false;
|
|
32
|
-
|
|
33
|
-
constructor(
|
|
34
|
-
private storageManager: StorageManager,
|
|
35
|
-
private serverRoot: string,
|
|
36
|
-
) {}
|
|
37
|
-
|
|
38
|
-
private get db(): DuckDBConnection {
|
|
39
|
-
return this.storageManager.getDuckDbConnection();
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Idempotent. Loads the persisted theme into memory. If the table is
|
|
44
|
-
* empty, seeds from `publisher.config.json`'s instance theme (if
|
|
45
|
-
* present) and persists the seed so subsequent reads + the editor see
|
|
46
|
-
* the same baseline.
|
|
47
|
-
*/
|
|
48
|
-
async initialize(): Promise<void> {
|
|
49
|
-
await this.mutex.runExclusive(async () => {
|
|
50
|
-
await this.loadLocked();
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
async get(): Promise<Theme | undefined> {
|
|
55
|
-
if (!this.cacheLoaded) {
|
|
56
|
-
await this.initialize();
|
|
57
|
-
}
|
|
58
|
-
return this.cached;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
async set(theme: Theme): Promise<Theme> {
|
|
62
|
-
return this.mutex.runExclusive(async () => {
|
|
63
|
-
await this.persistLocked(theme);
|
|
64
|
-
this.cached = theme;
|
|
65
|
-
this.cacheLoaded = true;
|
|
66
|
-
return theme;
|
|
67
|
-
});
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Drops the persisted row so the next read falls back to the boot
|
|
72
|
-
* seed (or to no theme at all if the config doesn't define one).
|
|
73
|
-
*/
|
|
74
|
-
async reset(): Promise<Theme | undefined> {
|
|
75
|
-
return this.mutex.runExclusive(async () => {
|
|
76
|
-
await this.db.run("DELETE FROM themes WHERE id = ?", [THEME_ROW_ID]);
|
|
77
|
-
this.cached = undefined;
|
|
78
|
-
this.cacheLoaded = false;
|
|
79
|
-
await this.loadLocked();
|
|
80
|
-
return this.cached;
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* Single source of truth for loading the cache. Must be called with
|
|
86
|
-
* the mutex held. Idempotent: returns immediately if already loaded.
|
|
87
|
-
*/
|
|
88
|
-
private async loadLocked(): Promise<void> {
|
|
89
|
-
if (this.cacheLoaded) return;
|
|
90
|
-
const row = await this.db.get<{ payload: string }>(
|
|
91
|
-
"SELECT payload FROM themes WHERE id = ?",
|
|
92
|
-
[THEME_ROW_ID],
|
|
93
|
-
);
|
|
94
|
-
if (row?.payload) {
|
|
95
|
-
let parsed: unknown;
|
|
96
|
-
try {
|
|
97
|
-
parsed = JSON.parse(row.payload);
|
|
98
|
-
} catch (error) {
|
|
99
|
-
logger.warn(
|
|
100
|
-
"ThemeStore: stored theme JSON is unparseable; treating as empty",
|
|
101
|
-
{ error },
|
|
102
|
-
);
|
|
103
|
-
this.cacheLoaded = true;
|
|
104
|
-
return;
|
|
105
|
-
}
|
|
106
|
-
// Run through sanitizeTheme so stale schema shapes (e.g. an
|
|
107
|
-
// old per-mode `series` object) get dropped before the editor
|
|
108
|
-
// ever sees them. Operators can keep editing without hitting
|
|
109
|
-
// Reset; fields that match the current shape survive.
|
|
110
|
-
const sanitized = sanitizeTheme(parsed, "ThemeStore.load");
|
|
111
|
-
const dropped = listSanitizerDrops(parsed, sanitized);
|
|
112
|
-
if (dropped.length > 0) {
|
|
113
|
-
// Surface what disappeared so operators reading the server
|
|
114
|
-
// log can see why the editor doesn't show their old custom
|
|
115
|
-
// values after an upgrade. Re-saving from the editor will
|
|
116
|
-
// overwrite the on-disk payload with the current shape.
|
|
117
|
-
logger.info(
|
|
118
|
-
"ThemeStore: dropped stale fields from stored theme during load",
|
|
119
|
-
{ dropped },
|
|
120
|
-
);
|
|
121
|
-
}
|
|
122
|
-
this.cached = sanitized;
|
|
123
|
-
} else {
|
|
124
|
-
const seed = getInstanceTheme(this.serverRoot);
|
|
125
|
-
if (seed) {
|
|
126
|
-
this.cached = seed;
|
|
127
|
-
await this.persistLocked(seed);
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
this.cacheLoaded = true;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private async persistLocked(theme: Theme): Promise<void> {
|
|
134
|
-
const now = new Date().toISOString();
|
|
135
|
-
const payload = JSON.stringify(theme);
|
|
136
|
-
await this.db.run(
|
|
137
|
-
`INSERT INTO themes (id, payload, created_at, updated_at)
|
|
138
|
-
VALUES (?, ?, ?, ?)
|
|
139
|
-
ON CONFLICT (id) DO UPDATE SET
|
|
140
|
-
payload = EXCLUDED.payload,
|
|
141
|
-
updated_at = EXCLUDED.updated_at`,
|
|
142
|
-
[THEME_ROW_ID, payload, now, now],
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/**
|
|
148
|
-
* Return the list of top-level Theme keys present on `raw` but absent
|
|
149
|
-
* from `sanitized` (i.e. dropped by `sanitizeTheme`). Reports dotted
|
|
150
|
-
* paths down one level so the log says e.g. `palette.series` rather
|
|
151
|
-
* than just `palette`. Returns an empty array when nothing was lost.
|
|
152
|
-
*/
|
|
153
|
-
function listSanitizerDrops(
|
|
154
|
-
raw: unknown,
|
|
155
|
-
sanitized: Theme | undefined,
|
|
156
|
-
): string[] {
|
|
157
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw)) return [];
|
|
158
|
-
const r = raw as Record<string, unknown>;
|
|
159
|
-
const drops: string[] = [];
|
|
160
|
-
|
|
161
|
-
const topKeys = ["defaultMode", "allowUserToggle"] as const;
|
|
162
|
-
for (const k of topKeys) {
|
|
163
|
-
if (r[k] !== undefined && sanitized?.[k] === undefined) drops.push(k);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
r.palette &&
|
|
168
|
-
typeof r.palette === "object" &&
|
|
169
|
-
!Array.isArray(r.palette)
|
|
170
|
-
) {
|
|
171
|
-
const rp = r.palette as Record<string, unknown>;
|
|
172
|
-
const sp = (sanitized?.palette ?? {}) as Record<string, unknown>;
|
|
173
|
-
for (const k of Object.keys(rp)) {
|
|
174
|
-
if (rp[k] !== undefined && sp[k] === undefined)
|
|
175
|
-
drops.push(`palette.${k}`);
|
|
176
|
-
}
|
|
177
|
-
} else if (
|
|
178
|
-
r.palette !== undefined &&
|
|
179
|
-
(!sanitized || sanitized.palette === undefined)
|
|
180
|
-
) {
|
|
181
|
-
drops.push("palette");
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
if (r.font && typeof r.font === "object" && !Array.isArray(r.font)) {
|
|
185
|
-
const rf = r.font as Record<string, unknown>;
|
|
186
|
-
const sf = (sanitized?.font ?? {}) as Record<string, unknown>;
|
|
187
|
-
for (const k of Object.keys(rf)) {
|
|
188
|
-
if (rf[k] !== undefined && sf[k] === undefined)
|
|
189
|
-
drops.push(`font.${k}`);
|
|
190
|
-
}
|
|
191
|
-
} else if (
|
|
192
|
-
r.font !== undefined &&
|
|
193
|
-
(!sanitized || sanitized.font === undefined)
|
|
194
|
-
) {
|
|
195
|
-
drops.push("font");
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
return drops;
|
|
199
|
-
}
|
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { components } from "../api";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Generic database interface for storage abstraction
|
|
5
|
-
* This allows switching between DuckDB, PostgreSQL, MySQL, etc.
|
|
6
|
-
*/
|
|
7
|
-
export interface DatabaseConnection {
|
|
8
|
-
initialize(): Promise<void>;
|
|
9
|
-
close(): Promise<void>;
|
|
10
|
-
isInitialized(): Promise<boolean>;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export interface ResourceRepository {
|
|
14
|
-
// Environments
|
|
15
|
-
listEnvironments(): Promise<Environment[]>;
|
|
16
|
-
getEnvironmentById(id: string): Promise<Environment | null>;
|
|
17
|
-
getEnvironmentByName(name: string): Promise<Environment | null>;
|
|
18
|
-
createEnvironment(
|
|
19
|
-
environment: Omit<Environment, "id" | "createdAt" | "updatedAt">,
|
|
20
|
-
): Promise<Environment>;
|
|
21
|
-
updateEnvironment(
|
|
22
|
-
id: string,
|
|
23
|
-
updates: Partial<Environment>,
|
|
24
|
-
): Promise<Environment>;
|
|
25
|
-
deleteEnvironment(id: string): Promise<void>;
|
|
26
|
-
|
|
27
|
-
// Packages
|
|
28
|
-
listPackages(environmentId: string): Promise<Package[]>;
|
|
29
|
-
getPackageById(id: string): Promise<Package | null>;
|
|
30
|
-
getPackageByName(
|
|
31
|
-
environmentId: string,
|
|
32
|
-
name: string,
|
|
33
|
-
): Promise<Package | null>;
|
|
34
|
-
createPackage(
|
|
35
|
-
pkg: Omit<Package, "id" | "createdAt" | "updatedAt">,
|
|
36
|
-
): Promise<Package>;
|
|
37
|
-
updatePackage(id: string, updates: Partial<Package>): Promise<Package>;
|
|
38
|
-
deletePackage(id: string): Promise<void>;
|
|
39
|
-
|
|
40
|
-
// Connections
|
|
41
|
-
listConnections(environmentId: string): Promise<Connection[]>;
|
|
42
|
-
getConnectionById(id: string): Promise<Connection | null>;
|
|
43
|
-
getConnectionByName(
|
|
44
|
-
environmentId: string,
|
|
45
|
-
name: string,
|
|
46
|
-
): Promise<Connection | null>;
|
|
47
|
-
createConnection(
|
|
48
|
-
connection: Omit<Connection, "id" | "createdAt" | "updatedAt">,
|
|
49
|
-
): Promise<Connection>;
|
|
50
|
-
updateConnection(
|
|
51
|
-
id: string,
|
|
52
|
-
updates: Partial<Connection>,
|
|
53
|
-
): Promise<Connection>;
|
|
54
|
-
deleteConnection(id: string): Promise<void>;
|
|
55
|
-
|
|
56
|
-
// Materializations
|
|
57
|
-
listMaterializations(
|
|
58
|
-
environmentId: string,
|
|
59
|
-
packageName: string,
|
|
60
|
-
options?: { limit?: number; offset?: number },
|
|
61
|
-
): Promise<Materialization[]>;
|
|
62
|
-
listMaterializationsByEnvironment(
|
|
63
|
-
environmentId: string,
|
|
64
|
-
options?: { limit?: number; offset?: number },
|
|
65
|
-
): Promise<Materialization[]>;
|
|
66
|
-
getLatestScheduledFireAt(
|
|
67
|
-
environmentId: string,
|
|
68
|
-
packageName: string,
|
|
69
|
-
): Promise<Date | null>;
|
|
70
|
-
getMaterializationById(id: string): Promise<Materialization | null>;
|
|
71
|
-
getActiveMaterialization(
|
|
72
|
-
environmentId: string,
|
|
73
|
-
packageName: string,
|
|
74
|
-
): Promise<Materialization | null>;
|
|
75
|
-
createMaterialization(
|
|
76
|
-
environmentId: string,
|
|
77
|
-
packageName: string,
|
|
78
|
-
status?: MaterializationStatus,
|
|
79
|
-
metadata?: Record<string, unknown> | null,
|
|
80
|
-
): Promise<Materialization>;
|
|
81
|
-
updateMaterialization(
|
|
82
|
-
id: string,
|
|
83
|
-
updates: MaterializationUpdate,
|
|
84
|
-
): Promise<Materialization>;
|
|
85
|
-
deleteMaterialization(id: string): Promise<void>;
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
export interface Environment {
|
|
89
|
-
id: string;
|
|
90
|
-
name: string;
|
|
91
|
-
path: string;
|
|
92
|
-
description?: string;
|
|
93
|
-
createdAt: Date;
|
|
94
|
-
updatedAt: Date;
|
|
95
|
-
metadata?: Record<string, unknown>;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export interface Package {
|
|
99
|
-
id: string;
|
|
100
|
-
environmentId: string;
|
|
101
|
-
name: string;
|
|
102
|
-
description?: string;
|
|
103
|
-
manifestPath: string;
|
|
104
|
-
createdAt: Date;
|
|
105
|
-
updatedAt: Date;
|
|
106
|
-
metadata?: Record<string, unknown>;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export interface Connection {
|
|
110
|
-
id: string;
|
|
111
|
-
environmentId: string;
|
|
112
|
-
name: string;
|
|
113
|
-
type: "bigquery" | "postgres" | "duckdb" | "mysql" | "snowflake" | "trino";
|
|
114
|
-
config: Record<string, unknown>;
|
|
115
|
-
createdAt: Date;
|
|
116
|
-
updatedAt: Date;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
// Wire types for the build protocol, kept in sync with the OpenAPI spec via
|
|
120
|
-
// the generated `api.ts`.
|
|
121
|
-
export type MaterializationStatus =
|
|
122
|
-
components["schemas"]["MaterializationStatus"];
|
|
123
|
-
export type BuildPlan = components["schemas"]["BuildPlan"];
|
|
124
|
-
export type BuildManifestResult = components["schemas"]["BuildManifest"];
|
|
125
|
-
export type ManifestEntry = components["schemas"]["ManifestEntry"];
|
|
126
|
-
export type BuildInstruction = components["schemas"]["BuildInstruction"];
|
|
127
|
-
export type ManifestReference = components["schemas"]["ManifestReference"];
|
|
128
|
-
export type Realization = components["schemas"]["Realization"];
|
|
129
|
-
|
|
130
|
-
export interface Materialization {
|
|
131
|
-
id: string;
|
|
132
|
-
environmentId: string;
|
|
133
|
-
packageName: string;
|
|
134
|
-
status: MaterializationStatus;
|
|
135
|
-
/** Build output. Null until status = MANIFEST_FILE_READY. */
|
|
136
|
-
manifest: BuildManifestResult | null;
|
|
137
|
-
startedAt: Date | null;
|
|
138
|
-
completedAt: Date | null;
|
|
139
|
-
error: string | null;
|
|
140
|
-
metadata: Record<string, unknown> | null;
|
|
141
|
-
createdAt: Date;
|
|
142
|
-
updatedAt: Date;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface MaterializationUpdate {
|
|
146
|
-
status?: MaterializationStatus;
|
|
147
|
-
manifest?: BuildManifestResult | null;
|
|
148
|
-
startedAt?: Date;
|
|
149
|
-
completedAt?: Date;
|
|
150
|
-
error?: string | null;
|
|
151
|
-
metadata?: Record<string, unknown> | null;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Malloy-facing build manifest: maps a sourceEntityId to the physical table backing
|
|
156
|
-
* that persist source. This is the shape the Malloy runtime consumes when
|
|
157
|
-
* (re)loading models so persist references resolve to materialized tables.
|
|
158
|
-
* Distinct from {@link BuildManifestResult} (the wire build output, which also
|
|
159
|
-
* carries caller bookkeeping like materializedTableId and rowCount).
|
|
160
|
-
*/
|
|
161
|
-
export interface BuildManifestEntry {
|
|
162
|
-
tableName: string;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
export interface BuildManifest {
|
|
166
|
-
entries: Record<string, BuildManifestEntry>;
|
|
167
|
-
strict?: boolean;
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* A wire manifest entry carrying the control-plane freshness fields alongside
|
|
172
|
-
* the physical `tableName`. This is what the publisher retains at bind so the
|
|
173
|
-
* serve path can re-evaluate `age vs window` per query (see
|
|
174
|
-
* {@link ../service/freshness}). A `{ tableName }`-only value is structurally
|
|
175
|
-
* assignable here (the freshness fields are optional), so callers that only
|
|
176
|
-
* know a table name — e.g. the post-build auto-load — bind un-gated entries.
|
|
177
|
-
*
|
|
178
|
-
* - `dataAsOf` the artifact's data-as-of instant (snapshot start); the age
|
|
179
|
-
* anchor. `age = now - dataAsOf`. Absent ⇒ never stale.
|
|
180
|
-
* - `freshnessWindowSeconds` the version's effective window. Absent ⇒ un-gated.
|
|
181
|
-
* - `freshnessFallback` per-version read-time policy when stale.
|
|
182
|
-
*/
|
|
183
|
-
export interface FreshnessAwareManifestEntry {
|
|
184
|
-
tableName: string;
|
|
185
|
-
/**
|
|
186
|
-
* The connection the physical table lives on, carried from the wire
|
|
187
|
-
* manifest so the bind step can quote `tableName` for that connection's
|
|
188
|
-
* dialect (see Package.quoteBoundTableNames). Absent on entries whose
|
|
189
|
-
* producer didn't record it; those bind verbatim.
|
|
190
|
-
*/
|
|
191
|
-
connectionName?: string;
|
|
192
|
-
dataAsOf?: string;
|
|
193
|
-
freshnessWindowSeconds?: number;
|
|
194
|
-
freshnessFallback?: "live" | "stale_ok" | "fail";
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
/** Full (unfiltered) manifest map keyed by sourceEntityId. */
|
|
198
|
-
export type FreshnessManifest = Record<string, FreshnessAwareManifestEntry>;
|