@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,24 +0,0 @@
|
|
|
1
|
-
import { components } from "../api";
|
|
2
|
-
import { EnvironmentStore } from "../service/environment_store";
|
|
3
|
-
|
|
4
|
-
type ApiDatabase = components["schemas"]["Database"];
|
|
5
|
-
|
|
6
|
-
export class DatabaseController {
|
|
7
|
-
private environmentStore: EnvironmentStore;
|
|
8
|
-
|
|
9
|
-
constructor(environmentStore: EnvironmentStore) {
|
|
10
|
-
this.environmentStore = environmentStore;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
public async listDatabases(
|
|
14
|
-
environmentName: string,
|
|
15
|
-
packageName: string,
|
|
16
|
-
): Promise<ApiDatabase[]> {
|
|
17
|
-
const environment = await this.environmentStore.getEnvironment(
|
|
18
|
-
environmentName,
|
|
19
|
-
false,
|
|
20
|
-
);
|
|
21
|
-
const p = await environment.getPackage(packageName, false);
|
|
22
|
-
return p.listDatabases();
|
|
23
|
-
}
|
|
24
|
-
}
|
|
@@ -1,293 +0,0 @@
|
|
|
1
|
-
import { describe, expect, it } from "bun:test";
|
|
2
|
-
import * as sinon from "sinon";
|
|
3
|
-
import { BadRequestError } from "../errors";
|
|
4
|
-
import type { MaterializationService } from "../service/materialization_service";
|
|
5
|
-
import { MaterializationController } from "./materialization.controller";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Unit tests for {@link MaterializationController.createMaterialization}'s body
|
|
9
|
-
* validation. The service is stubbed so each test asserts the parsed options
|
|
10
|
-
* the controller forwards (or the rejection for a malformed body).
|
|
11
|
-
*/
|
|
12
|
-
function build() {
|
|
13
|
-
const createMaterialization = sinon.stub().resolves({ id: "m1" });
|
|
14
|
-
const service = {
|
|
15
|
-
createMaterialization,
|
|
16
|
-
} as unknown as MaterializationService;
|
|
17
|
-
const controller = new MaterializationController(service);
|
|
18
|
-
return { controller, createMaterialization };
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/** Parsed options the controller forwards for a given request body. */
|
|
22
|
-
async function parse(body: Record<string, unknown>) {
|
|
23
|
-
const { controller, createMaterialization } = build();
|
|
24
|
-
await controller.createMaterialization("env", "pkg", body);
|
|
25
|
-
return createMaterialization.firstCall.args[2];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
describe("MaterializationController.createMaterialization validation", () => {
|
|
29
|
-
it("forwards an empty body as empty options", async () => {
|
|
30
|
-
expect(await parse({})).toEqual({});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
it("passes through forceRefresh and sourceNames", async () => {
|
|
34
|
-
expect(
|
|
35
|
-
await parse({ forceRefresh: true, sourceNames: ["a", "b"] }),
|
|
36
|
-
).toEqual({ forceRefresh: true, sourceNames: ["a", "b"] });
|
|
37
|
-
});
|
|
38
|
-
|
|
39
|
-
it("never forwards a client-supplied trigger (SCHEDULER cannot be forged)", async () => {
|
|
40
|
-
// trigger is service-level-only: the controller must strip it so an API
|
|
41
|
-
// caller cannot mint a run that reads as scheduler-driven. The service
|
|
42
|
-
// then defaults it to ON_DEMAND.
|
|
43
|
-
const parsed = await parse({ forceRefresh: true, trigger: "SCHEDULER" });
|
|
44
|
-
expect(parsed).toEqual({ forceRefresh: true });
|
|
45
|
-
expect("trigger" in (parsed as object)).toBe(false);
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
it("rejects a non-boolean forceRefresh", async () => {
|
|
49
|
-
const { controller } = build();
|
|
50
|
-
await expect(
|
|
51
|
-
controller.createMaterialization("env", "pkg", {
|
|
52
|
-
forceRefresh: "yes",
|
|
53
|
-
}),
|
|
54
|
-
).rejects.toThrow(BadRequestError);
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
it("rejects sourceNames that is not an array of strings", async () => {
|
|
58
|
-
const { controller } = build();
|
|
59
|
-
await expect(
|
|
60
|
-
controller.createMaterialization("env", "pkg", {
|
|
61
|
-
sourceNames: [1, 2],
|
|
62
|
-
}),
|
|
63
|
-
).rejects.toThrow(BadRequestError);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("flattens buildInstructions.sources into the instruction list", async () => {
|
|
67
|
-
const parsed = await parse({
|
|
68
|
-
buildInstructions: {
|
|
69
|
-
sources: [
|
|
70
|
-
{
|
|
71
|
-
sourceEntityId: "b1",
|
|
72
|
-
sourceID: "orders@m",
|
|
73
|
-
materializedTableId: "mt-1",
|
|
74
|
-
physicalTableName: "orders_v1",
|
|
75
|
-
realization: "COPY",
|
|
76
|
-
},
|
|
77
|
-
],
|
|
78
|
-
},
|
|
79
|
-
});
|
|
80
|
-
expect(parsed).toEqual({
|
|
81
|
-
buildInstructions: [
|
|
82
|
-
{
|
|
83
|
-
sourceEntityId: "b1",
|
|
84
|
-
sourceID: "orders@m",
|
|
85
|
-
materializedTableId: "mt-1",
|
|
86
|
-
physicalTableName: "orders_v1",
|
|
87
|
-
realization: "COPY",
|
|
88
|
-
},
|
|
89
|
-
],
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it("treats null buildInstructions as absent (auto-run)", async () => {
|
|
94
|
-
expect(await parse({ buildInstructions: null })).toEqual({});
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("parses referenceManifest and strictUpstreams alongside sources", async () => {
|
|
98
|
-
const parsed = await parse({
|
|
99
|
-
buildInstructions: {
|
|
100
|
-
sources: [
|
|
101
|
-
{
|
|
102
|
-
sourceEntityId: "b2",
|
|
103
|
-
materializedTableId: "mt-2",
|
|
104
|
-
physicalTableName: "downstream_v1",
|
|
105
|
-
realization: "COPY",
|
|
106
|
-
},
|
|
107
|
-
],
|
|
108
|
-
referenceManifest: [
|
|
109
|
-
{ sourceEntityId: "b1", physicalTableName: "upstream_table" },
|
|
110
|
-
],
|
|
111
|
-
strictUpstreams: true,
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
expect(parsed).toEqual({
|
|
115
|
-
buildInstructions: [
|
|
116
|
-
{
|
|
117
|
-
sourceEntityId: "b2",
|
|
118
|
-
sourceID: undefined,
|
|
119
|
-
materializedTableId: "mt-2",
|
|
120
|
-
physicalTableName: "downstream_v1",
|
|
121
|
-
realization: "COPY",
|
|
122
|
-
},
|
|
123
|
-
],
|
|
124
|
-
referenceManifest: [
|
|
125
|
-
{ sourceEntityId: "b1", physicalTableName: "upstream_table" },
|
|
126
|
-
],
|
|
127
|
-
strictUpstreams: true,
|
|
128
|
-
});
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
it("preserves the storage `destination` on a build instruction", async () => {
|
|
132
|
-
// Regression: `destination` is the orchestrated `storage=` axis. Dropping it
|
|
133
|
-
// here silently downgrades an orchestrated build to a colocated
|
|
134
|
-
// build, so it never materializes into the storage destination.
|
|
135
|
-
const parsed = await parse({
|
|
136
|
-
buildInstructions: {
|
|
137
|
-
sources: [
|
|
138
|
-
{
|
|
139
|
-
sourceEntityId: "b2",
|
|
140
|
-
materializedTableId: "mt-2",
|
|
141
|
-
physicalTableName: "downstream_v1",
|
|
142
|
-
realization: "COPY",
|
|
143
|
-
destination: "lake",
|
|
144
|
-
},
|
|
145
|
-
],
|
|
146
|
-
},
|
|
147
|
-
});
|
|
148
|
-
expect(parsed.buildInstructions).toEqual([
|
|
149
|
-
{
|
|
150
|
-
sourceEntityId: "b2",
|
|
151
|
-
sourceID: undefined,
|
|
152
|
-
materializedTableId: "mt-2",
|
|
153
|
-
physicalTableName: "downstream_v1",
|
|
154
|
-
realization: "COPY",
|
|
155
|
-
destination: "lake",
|
|
156
|
-
},
|
|
157
|
-
]);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("preserves the optional `connectionName` on a manifest reference", async () => {
|
|
161
|
-
// Regression: `connectionName` (added by #904) lets the seed loop dialect-
|
|
162
|
-
// quote the referenced upstream for a case-folding engine. Dropping it here
|
|
163
|
-
// silently reverts to an unquoted seed — the same manual-copy drift that
|
|
164
|
-
// dropped BuildInstruction.destination.
|
|
165
|
-
const parsed = await parse({
|
|
166
|
-
buildInstructions: {
|
|
167
|
-
sources: [
|
|
168
|
-
{
|
|
169
|
-
sourceEntityId: "b2",
|
|
170
|
-
materializedTableId: "mt-2",
|
|
171
|
-
physicalTableName: "downstream_v1",
|
|
172
|
-
realization: "COPY",
|
|
173
|
-
},
|
|
174
|
-
],
|
|
175
|
-
referenceManifest: [
|
|
176
|
-
{
|
|
177
|
-
sourceEntityId: "b1",
|
|
178
|
-
physicalTableName: "upstream_table",
|
|
179
|
-
connectionName: "sf",
|
|
180
|
-
},
|
|
181
|
-
],
|
|
182
|
-
},
|
|
183
|
-
});
|
|
184
|
-
expect(parsed.referenceManifest).toEqual([
|
|
185
|
-
{
|
|
186
|
-
sourceEntityId: "b1",
|
|
187
|
-
physicalTableName: "upstream_table",
|
|
188
|
-
connectionName: "sf",
|
|
189
|
-
},
|
|
190
|
-
]);
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
it("rejects a referenceManifest entry missing a required field", async () => {
|
|
194
|
-
const { controller } = build();
|
|
195
|
-
await expect(
|
|
196
|
-
controller.createMaterialization("env", "pkg", {
|
|
197
|
-
buildInstructions: {
|
|
198
|
-
sources: [
|
|
199
|
-
{
|
|
200
|
-
sourceEntityId: "b2",
|
|
201
|
-
materializedTableId: "mt-2",
|
|
202
|
-
physicalTableName: "downstream_v1",
|
|
203
|
-
realization: "COPY",
|
|
204
|
-
},
|
|
205
|
-
],
|
|
206
|
-
referenceManifest: [{ sourceEntityId: "b1" }],
|
|
207
|
-
},
|
|
208
|
-
}),
|
|
209
|
-
).rejects.toThrow(BadRequestError);
|
|
210
|
-
});
|
|
211
|
-
|
|
212
|
-
it("rejects a non-boolean strictUpstreams", async () => {
|
|
213
|
-
const { controller } = build();
|
|
214
|
-
await expect(
|
|
215
|
-
controller.createMaterialization("env", "pkg", {
|
|
216
|
-
buildInstructions: {
|
|
217
|
-
sources: [
|
|
218
|
-
{
|
|
219
|
-
sourceEntityId: "b2",
|
|
220
|
-
materializedTableId: "mt-2",
|
|
221
|
-
physicalTableName: "downstream_v1",
|
|
222
|
-
realization: "COPY",
|
|
223
|
-
},
|
|
224
|
-
],
|
|
225
|
-
strictUpstreams: "yes",
|
|
226
|
-
},
|
|
227
|
-
}),
|
|
228
|
-
).rejects.toThrow(BadRequestError);
|
|
229
|
-
});
|
|
230
|
-
|
|
231
|
-
it("rejects buildInstructions without a non-empty sources array", async () => {
|
|
232
|
-
const { controller } = build();
|
|
233
|
-
await expect(
|
|
234
|
-
controller.createMaterialization("env", "pkg", {
|
|
235
|
-
buildInstructions: { sources: [] },
|
|
236
|
-
}),
|
|
237
|
-
).rejects.toThrow(BadRequestError);
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
it("rejects an instruction missing a required field", async () => {
|
|
241
|
-
const { controller } = build();
|
|
242
|
-
await expect(
|
|
243
|
-
controller.createMaterialization("env", "pkg", {
|
|
244
|
-
buildInstructions: {
|
|
245
|
-
sources: [{ sourceEntityId: "b1", materializedTableId: "mt-1" }],
|
|
246
|
-
},
|
|
247
|
-
}),
|
|
248
|
-
).rejects.toThrow(BadRequestError);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
it("rejects an unrecognized realization", async () => {
|
|
252
|
-
const { controller } = build();
|
|
253
|
-
await expect(
|
|
254
|
-
controller.createMaterialization("env", "pkg", {
|
|
255
|
-
buildInstructions: {
|
|
256
|
-
sources: [
|
|
257
|
-
{
|
|
258
|
-
sourceEntityId: "b1",
|
|
259
|
-
materializedTableId: "mt-1",
|
|
260
|
-
physicalTableName: "orders_v1",
|
|
261
|
-
realization: "MERGE",
|
|
262
|
-
},
|
|
263
|
-
],
|
|
264
|
-
},
|
|
265
|
-
}),
|
|
266
|
-
).rejects.toThrow(BadRequestError);
|
|
267
|
-
});
|
|
268
|
-
|
|
269
|
-
it("rejects a runId the metadata contract cannot carry", async () => {
|
|
270
|
-
// runId becomes the `run_id` property on every statement of the build, so
|
|
271
|
-
// an over-long or unrenderable value is silently truncated and rewritten
|
|
272
|
-
// at dispatch — leaving the caller holding an id that joins to nothing.
|
|
273
|
-
// The neighbouring `trigger` is enum-validated; this is the same kind of
|
|
274
|
-
// boundary and gets the same treatment.
|
|
275
|
-
const { controller } = build();
|
|
276
|
-
await expect(
|
|
277
|
-
controller.createMaterialization("env", "pkg", {
|
|
278
|
-
runContext: { runId: "x".repeat(300) },
|
|
279
|
-
}),
|
|
280
|
-
).rejects.toThrow(BadRequestError);
|
|
281
|
-
await expect(
|
|
282
|
-
controller.createMaterialization("env", "pkg", {
|
|
283
|
-
runContext: { runId: 'has "quotes"' },
|
|
284
|
-
}),
|
|
285
|
-
).rejects.toThrow(BadRequestError);
|
|
286
|
-
});
|
|
287
|
-
|
|
288
|
-
it("still accepts a conforming runId", async () => {
|
|
289
|
-
expect(
|
|
290
|
-
await parse({ runContext: { trigger: "publish", runId: "run-42" } }),
|
|
291
|
-
).toEqual({ runContext: { trigger: "publish", runId: "run-42" } });
|
|
292
|
-
});
|
|
293
|
-
});
|
|
@@ -1,319 +0,0 @@
|
|
|
1
|
-
import type { components } from "../api";
|
|
2
|
-
import { BadRequestError } from "../errors";
|
|
3
|
-
import {
|
|
4
|
-
BuildInstruction,
|
|
5
|
-
ManifestReference,
|
|
6
|
-
} from "../storage/DatabaseInterface";
|
|
7
|
-
import { MaterializationService } from "../service/materialization_service";
|
|
8
|
-
import { queryMetadataViolations } from "../service/query_metadata";
|
|
9
|
-
|
|
10
|
-
type RunContext = components["schemas"]["RunContext"];
|
|
11
|
-
|
|
12
|
-
const RUN_TRIGGERS = ["publish", "on_demand", "scheduler"] as const;
|
|
13
|
-
|
|
14
|
-
export class MaterializationController {
|
|
15
|
-
constructor(private materializationService: MaterializationService) {}
|
|
16
|
-
|
|
17
|
-
async createMaterialization(
|
|
18
|
-
environmentName: string,
|
|
19
|
-
packageName: string,
|
|
20
|
-
body: Record<string, unknown>,
|
|
21
|
-
) {
|
|
22
|
-
return this.materializationService.createMaterialization(
|
|
23
|
-
environmentName,
|
|
24
|
-
packageName,
|
|
25
|
-
this.validateCreateBody(body),
|
|
26
|
-
);
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
// Whitelist: only these fields are read off the client body. `trigger` is
|
|
30
|
-
// deliberately NOT accepted here — it is service-level-only, defaulted to
|
|
31
|
-
// `ON_DEMAND` and set to `SCHEDULER` solely by the in-process scheduler
|
|
32
|
-
// (which calls the service directly, not this HTTP path). Do not add
|
|
33
|
-
// `trigger` to this parser, or an API caller could forge a scheduled run.
|
|
34
|
-
private validateCreateBody(body: Record<string, unknown>): {
|
|
35
|
-
forceRefresh?: boolean;
|
|
36
|
-
sourceNames?: string[];
|
|
37
|
-
buildInstructions?: BuildInstruction[];
|
|
38
|
-
referenceManifest?: ManifestReference[];
|
|
39
|
-
strictUpstreams?: boolean;
|
|
40
|
-
runContext?: RunContext;
|
|
41
|
-
} {
|
|
42
|
-
const result: {
|
|
43
|
-
forceRefresh?: boolean;
|
|
44
|
-
sourceNames?: string[];
|
|
45
|
-
buildInstructions?: BuildInstruction[];
|
|
46
|
-
referenceManifest?: ManifestReference[];
|
|
47
|
-
strictUpstreams?: boolean;
|
|
48
|
-
runContext?: RunContext;
|
|
49
|
-
} = {};
|
|
50
|
-
if (body.runContext !== undefined && body.runContext !== null) {
|
|
51
|
-
result.runContext = this.validateRunContext(body.runContext);
|
|
52
|
-
}
|
|
53
|
-
if (
|
|
54
|
-
body.buildInstructions !== undefined &&
|
|
55
|
-
body.buildInstructions !== null
|
|
56
|
-
) {
|
|
57
|
-
const parsed = this.validateBuildInstructions(body.buildInstructions);
|
|
58
|
-
result.buildInstructions = parsed.sources;
|
|
59
|
-
if (parsed.referenceManifest !== undefined) {
|
|
60
|
-
result.referenceManifest = parsed.referenceManifest;
|
|
61
|
-
}
|
|
62
|
-
if (parsed.strictUpstreams !== undefined) {
|
|
63
|
-
result.strictUpstreams = parsed.strictUpstreams;
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (body.forceRefresh !== undefined) {
|
|
67
|
-
if (typeof body.forceRefresh !== "boolean") {
|
|
68
|
-
throw new BadRequestError("forceRefresh must be a boolean");
|
|
69
|
-
}
|
|
70
|
-
result.forceRefresh = body.forceRefresh;
|
|
71
|
-
}
|
|
72
|
-
if (body.sourceNames !== undefined) {
|
|
73
|
-
if (
|
|
74
|
-
!Array.isArray(body.sourceNames) ||
|
|
75
|
-
body.sourceNames.some((n) => typeof n !== "string")
|
|
76
|
-
) {
|
|
77
|
-
throw new BadRequestError(
|
|
78
|
-
"sourceNames must be an array of strings",
|
|
79
|
-
);
|
|
80
|
-
}
|
|
81
|
-
result.sourceNames = body.sourceNames as string[];
|
|
82
|
-
}
|
|
83
|
-
return result;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Validate `runContext`, the caller's observability context for one run.
|
|
88
|
-
* `trigger` is a closed enum here even though it feeds a metadata property:
|
|
89
|
-
* the whole point is that a reader can group runs by how they started, which a
|
|
90
|
-
* free-form value would quietly break.
|
|
91
|
-
*
|
|
92
|
-
* Note this is NOT the service-level `trigger` the parser above deliberately
|
|
93
|
-
* refuses. That one decides whether the run counts as scheduled; this one only
|
|
94
|
-
* labels the statements the run issues, so accepting `publish` from a caller
|
|
95
|
-
* forges nothing.
|
|
96
|
-
*/
|
|
97
|
-
private validateRunContext(raw: unknown): RunContext {
|
|
98
|
-
if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
|
|
99
|
-
throw new BadRequestError("runContext must be an object");
|
|
100
|
-
}
|
|
101
|
-
const obj = raw as Record<string, unknown>;
|
|
102
|
-
const context: RunContext = {};
|
|
103
|
-
if (obj.trigger !== undefined && obj.trigger !== null) {
|
|
104
|
-
if (
|
|
105
|
-
typeof obj.trigger !== "string" ||
|
|
106
|
-
!RUN_TRIGGERS.includes(obj.trigger as (typeof RUN_TRIGGERS)[number])
|
|
107
|
-
) {
|
|
108
|
-
throw new BadRequestError(
|
|
109
|
-
`runContext.trigger must be one of ${RUN_TRIGGERS.join(" | ")}`,
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
context.trigger = obj.trigger as RunContext["trigger"];
|
|
113
|
-
}
|
|
114
|
-
if (obj.runId !== undefined && obj.runId !== null) {
|
|
115
|
-
if (typeof obj.runId !== "string") {
|
|
116
|
-
throw new BadRequestError("runContext.runId must be a string");
|
|
117
|
-
}
|
|
118
|
-
// Held to the metadata contract like any other caller-supplied
|
|
119
|
-
// property: it becomes the `run_id` on every statement of the build,
|
|
120
|
-
// and a value the contract rejects would otherwise be truncated and
|
|
121
|
-
// rewritten in silence — leaving the caller with an id it cannot join
|
|
122
|
-
// on and no way to know why.
|
|
123
|
-
const violations = queryMetadataViolations({ run_id: obj.runId });
|
|
124
|
-
if (violations.length > 0) {
|
|
125
|
-
throw new BadRequestError(
|
|
126
|
-
`runContext.runId is attached to every statement as the run_id ` +
|
|
127
|
-
`property: ${violations.join("; ")}`,
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
context.runId = obj.runId;
|
|
131
|
-
}
|
|
132
|
-
return context;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* Validate the orchestrated `buildInstructions` payload (BuildInstructions:
|
|
137
|
-
* `{ sources: BuildInstruction[], referenceManifest?, strictUpstreams? }`)
|
|
138
|
-
* into the parts the service consumes: the flattened instruction list, the
|
|
139
|
-
* optional upstream reference manifest, and the strict flag.
|
|
140
|
-
*/
|
|
141
|
-
private validateBuildInstructions(raw: unknown): {
|
|
142
|
-
sources: BuildInstruction[];
|
|
143
|
-
referenceManifest?: ManifestReference[];
|
|
144
|
-
strictUpstreams?: boolean;
|
|
145
|
-
} {
|
|
146
|
-
if (typeof raw !== "object" || raw === null) {
|
|
147
|
-
throw new BadRequestError("buildInstructions must be an object");
|
|
148
|
-
}
|
|
149
|
-
const obj = raw as Record<string, unknown>;
|
|
150
|
-
const sources = obj.sources;
|
|
151
|
-
if (!Array.isArray(sources) || sources.length === 0) {
|
|
152
|
-
throw new BadRequestError(
|
|
153
|
-
"buildInstructions requires a non-empty 'sources' array of BuildInstruction",
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
const result: {
|
|
157
|
-
sources: BuildInstruction[];
|
|
158
|
-
referenceManifest?: ManifestReference[];
|
|
159
|
-
strictUpstreams?: boolean;
|
|
160
|
-
} = {
|
|
161
|
-
sources: sources.map((instruction) =>
|
|
162
|
-
this.validateInstruction(instruction),
|
|
163
|
-
),
|
|
164
|
-
};
|
|
165
|
-
if (
|
|
166
|
-
obj.referenceManifest !== undefined &&
|
|
167
|
-
obj.referenceManifest !== null
|
|
168
|
-
) {
|
|
169
|
-
if (!Array.isArray(obj.referenceManifest)) {
|
|
170
|
-
throw new BadRequestError(
|
|
171
|
-
"buildInstructions.referenceManifest must be an array of ManifestReference",
|
|
172
|
-
);
|
|
173
|
-
}
|
|
174
|
-
result.referenceManifest = obj.referenceManifest.map((ref) =>
|
|
175
|
-
this.validateManifestReference(ref),
|
|
176
|
-
);
|
|
177
|
-
}
|
|
178
|
-
if (obj.strictUpstreams !== undefined) {
|
|
179
|
-
if (typeof obj.strictUpstreams !== "boolean") {
|
|
180
|
-
throw new BadRequestError(
|
|
181
|
-
"buildInstructions.strictUpstreams must be a boolean",
|
|
182
|
-
);
|
|
183
|
-
}
|
|
184
|
-
result.strictUpstreams = obj.strictUpstreams;
|
|
185
|
-
}
|
|
186
|
-
return result;
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
private validateManifestReference(raw: unknown): ManifestReference {
|
|
190
|
-
if (typeof raw !== "object" || raw === null) {
|
|
191
|
-
throw new BadRequestError("Each manifest reference must be an object");
|
|
192
|
-
}
|
|
193
|
-
const ref = raw as Record<string, unknown>;
|
|
194
|
-
for (const field of ["sourceEntityId", "physicalTableName"] as const) {
|
|
195
|
-
if (typeof ref[field] !== "string") {
|
|
196
|
-
throw new BadRequestError(
|
|
197
|
-
`Manifest reference is missing required string field '${field}'`,
|
|
198
|
-
);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
return {
|
|
202
|
-
sourceEntityId: ref.sourceEntityId as string,
|
|
203
|
-
physicalTableName: ref.physicalTableName as string,
|
|
204
|
-
// The connection the upstream table lives on. Optional; carried through
|
|
205
|
-
// so the seed loop can dialect-quote the reference for a case-folding
|
|
206
|
-
// engine (#904). Dropping it silently reverts to an unquoted seed, which
|
|
207
|
-
// fails a downstream build on such an engine — the same manual-copy drift
|
|
208
|
-
// that dropped BuildInstruction.destination.
|
|
209
|
-
...(typeof ref.connectionName === "string"
|
|
210
|
-
? { connectionName: ref.connectionName }
|
|
211
|
-
: {}),
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
private validateInstruction(raw: unknown): BuildInstruction {
|
|
216
|
-
if (typeof raw !== "object" || raw === null) {
|
|
217
|
-
throw new BadRequestError("Each build instruction must be an object");
|
|
218
|
-
}
|
|
219
|
-
const instruction = raw as Record<string, unknown>;
|
|
220
|
-
const required = [
|
|
221
|
-
"sourceEntityId",
|
|
222
|
-
"materializedTableId",
|
|
223
|
-
"physicalTableName",
|
|
224
|
-
"realization",
|
|
225
|
-
] as const;
|
|
226
|
-
for (const field of required) {
|
|
227
|
-
if (typeof instruction[field] !== "string") {
|
|
228
|
-
throw new BadRequestError(
|
|
229
|
-
`Build instruction is missing required string field '${field}'`,
|
|
230
|
-
);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
if (
|
|
234
|
-
instruction.realization !== "COPY" &&
|
|
235
|
-
instruction.realization !== "SNAPSHOT"
|
|
236
|
-
) {
|
|
237
|
-
throw new BadRequestError(
|
|
238
|
-
"Build instruction 'realization' must be COPY or SNAPSHOT",
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
return {
|
|
242
|
-
sourceEntityId: instruction.sourceEntityId as string,
|
|
243
|
-
sourceID:
|
|
244
|
-
typeof instruction.sourceID === "string"
|
|
245
|
-
? instruction.sourceID
|
|
246
|
-
: undefined,
|
|
247
|
-
materializedTableId: instruction.materializedTableId as string,
|
|
248
|
-
physicalTableName: instruction.physicalTableName as string,
|
|
249
|
-
realization: instruction.realization,
|
|
250
|
-
// The `storage=` destination the orchestrator targets. Optional in the
|
|
251
|
-
// schema; must be carried through, or an orchestrated build silently
|
|
252
|
-
// falls back to a colocated build (isStorageBuild=false) and
|
|
253
|
-
// never materializes into the storage destination.
|
|
254
|
-
...(typeof instruction.destination === "string"
|
|
255
|
-
? { destination: instruction.destination }
|
|
256
|
-
: {}),
|
|
257
|
-
};
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
async stopMaterialization(
|
|
261
|
-
environmentName: string,
|
|
262
|
-
packageName: string,
|
|
263
|
-
materializationId: string,
|
|
264
|
-
) {
|
|
265
|
-
return this.materializationService.stopMaterialization(
|
|
266
|
-
environmentName,
|
|
267
|
-
packageName,
|
|
268
|
-
materializationId,
|
|
269
|
-
);
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
async listMaterializations(
|
|
273
|
-
environmentName: string,
|
|
274
|
-
packageName: string,
|
|
275
|
-
options?: { limit?: number; offset?: number },
|
|
276
|
-
) {
|
|
277
|
-
return this.materializationService.listMaterializations(
|
|
278
|
-
environmentName,
|
|
279
|
-
packageName,
|
|
280
|
-
options,
|
|
281
|
-
);
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
async listEnvironmentMaterializations(
|
|
285
|
-
environmentName: string,
|
|
286
|
-
options?: { limit?: number; offset?: number },
|
|
287
|
-
) {
|
|
288
|
-
return this.materializationService.listEnvironmentMaterializations(
|
|
289
|
-
environmentName,
|
|
290
|
-
options,
|
|
291
|
-
);
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
async getMaterialization(
|
|
295
|
-
environmentName: string,
|
|
296
|
-
packageName: string,
|
|
297
|
-
materializationId: string,
|
|
298
|
-
) {
|
|
299
|
-
return this.materializationService.getMaterialization(
|
|
300
|
-
environmentName,
|
|
301
|
-
packageName,
|
|
302
|
-
materializationId,
|
|
303
|
-
);
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
async deleteMaterialization(
|
|
307
|
-
environmentName: string,
|
|
308
|
-
packageName: string,
|
|
309
|
-
materializationId: string,
|
|
310
|
-
options: { dropTables?: boolean } = {},
|
|
311
|
-
) {
|
|
312
|
-
return this.materializationService.deleteMaterialization(
|
|
313
|
-
environmentName,
|
|
314
|
-
packageName,
|
|
315
|
-
materializationId,
|
|
316
|
-
options,
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
}
|