@malloy-publisher/server 0.0.195 → 0.0.197-dev

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 (100) hide show
  1. package/dist/app/api-doc.yaml +213 -214
  2. package/dist/app/assets/EnvironmentPage-1j6QDWAy.js +1 -0
  3. package/dist/app/assets/HomePage-DMop21VG.js +1 -0
  4. package/dist/app/assets/MainPage-BbE8ETz1.js +2 -0
  5. package/dist/app/assets/ModelPage-D2jvfe3t.js +1 -0
  6. package/dist/app/assets/PackagePage-BbnhGoD3.js +1 -0
  7. package/dist/app/assets/{RouteError-DefbDO7F.js → RouteError-D3LGEZ3i.js} +1 -1
  8. package/dist/app/assets/WorkbookPage-DttVIj4u.js +1 -0
  9. package/dist/app/assets/{core-BrfQApxh.es-DnvCX4oH.js → core-w79IMXAG.es-Bd0UlzOL.js} +1 -1
  10. package/dist/app/assets/{index-Bu0ub036.js → index-5K9YjIxF.js} +117 -117
  11. package/dist/app/assets/{index-CkzK3JIl.js → index-C513UodQ.js} +1 -1
  12. package/dist/app/assets/{index-CoA6HIGS.js → index-DIgzgp69.js} +1 -1
  13. package/dist/app/assets/{index.umd-B6Ms2PpL.js → index.umd-BMeMPq_9.js} +1 -1
  14. package/dist/app/index.html +1 -1
  15. package/dist/server.mjs +1352 -1310
  16. package/package.json +2 -2
  17. package/publisher.config.json +2 -2
  18. package/src/config.spec.ts +74 -66
  19. package/src/config.ts +50 -47
  20. package/src/controller/compile.controller.ts +10 -7
  21. package/src/controller/connection.controller.ts +79 -58
  22. package/src/controller/database.controller.ts +10 -7
  23. package/src/controller/manifest.controller.ts +23 -14
  24. package/src/controller/materialization.controller.ts +14 -14
  25. package/src/controller/model.controller.ts +35 -20
  26. package/src/controller/package.controller.ts +83 -49
  27. package/src/controller/query.controller.ts +11 -8
  28. package/src/controller/watch-mode.controller.ts +35 -29
  29. package/src/errors.ts +2 -2
  30. package/src/mcp/error_messages.ts +2 -2
  31. package/src/mcp/handler_utils.ts +23 -20
  32. package/src/mcp/mcp_constants.ts +1 -1
  33. package/src/mcp/prompts/handlers.ts +3 -3
  34. package/src/mcp/prompts/prompt_service.ts +5 -5
  35. package/src/mcp/prompts/utils.ts +12 -12
  36. package/src/mcp/resource_metadata.ts +3 -3
  37. package/src/mcp/resources/environment_resource.ts +187 -0
  38. package/src/mcp/resources/model_resource.ts +19 -17
  39. package/src/mcp/resources/notebook_resource.ts +13 -13
  40. package/src/mcp/resources/package_resource.ts +30 -27
  41. package/src/mcp/resources/query_resource.ts +15 -10
  42. package/src/mcp/resources/source_resource.ts +10 -10
  43. package/src/mcp/resources/view_resource.ts +11 -11
  44. package/src/mcp/server.ts +16 -14
  45. package/src/mcp/tools/discovery_tools.ts +67 -49
  46. package/src/mcp/tools/execute_query_tool.ts +14 -14
  47. package/src/server.ts +175 -159
  48. package/src/service/connection.spec.ts +158 -133
  49. package/src/service/connection.ts +42 -39
  50. package/src/service/connection_config.spec.ts +13 -11
  51. package/src/service/connection_config.ts +28 -19
  52. package/src/service/connection_service.spec.ts +63 -43
  53. package/src/service/connection_service.ts +106 -89
  54. package/src/service/{project.ts → environment.ts} +92 -77
  55. package/src/service/{project_compile.spec.ts → environment_compile.spec.ts} +1 -1
  56. package/src/service/{project_store.spec.ts → environment_store.spec.ts} +99 -83
  57. package/src/service/{project_store.ts → environment_store.ts} +373 -327
  58. package/src/service/manifest_service.spec.ts +15 -15
  59. package/src/service/manifest_service.ts +26 -21
  60. package/src/service/materialization_service.spec.ts +93 -59
  61. package/src/service/materialization_service.ts +71 -62
  62. package/src/service/materialized_table_gc.spec.ts +15 -15
  63. package/src/service/materialized_table_gc.ts +3 -3
  64. package/src/service/model.ts +4 -4
  65. package/src/service/package.spec.ts +2 -2
  66. package/src/service/package.ts +23 -21
  67. package/src/service/resolve_environment.ts +15 -0
  68. package/src/storage/DatabaseInterface.ts +34 -25
  69. package/src/storage/StorageManager.mock.ts +3 -3
  70. package/src/storage/StorageManager.ts +64 -28
  71. package/src/storage/duckdb/ConnectionRepository.ts +13 -11
  72. package/src/storage/duckdb/DuckDBConnection.ts +1 -1
  73. package/src/storage/duckdb/DuckDBManifestStore.ts +6 -6
  74. package/src/storage/duckdb/DuckDBRepository.ts +47 -47
  75. package/src/storage/duckdb/{ProjectRepository.ts → EnvironmentRepository.ts} +35 -35
  76. package/src/storage/duckdb/ManifestRepository.ts +21 -20
  77. package/src/storage/duckdb/MaterializationRepository.ts +31 -28
  78. package/src/storage/duckdb/PackageRepository.ts +11 -11
  79. package/src/storage/duckdb/manifest_store.spec.ts +2 -2
  80. package/src/storage/duckdb/schema.ts +20 -20
  81. package/src/storage/ducklake/DuckLakeManifestStore.ts +20 -11
  82. package/tests/fixtures/publisher.config.json +1 -1
  83. package/tests/harness/e2e.ts +1 -1
  84. package/tests/harness/mcp_test_setup.ts +12 -24
  85. package/tests/harness/mocks.ts +10 -8
  86. package/tests/integration/materialization/materialization_lifecycle.integration.spec.ts +4 -4
  87. package/tests/integration/mcp/mcp_execute_query_tool.integration.spec.ts +28 -49
  88. package/tests/integration/mcp/mcp_resource.integration.spec.ts +39 -47
  89. package/tests/integration/mcp/mcp_transport.integration.spec.ts +1 -1
  90. package/tests/unit/duckdb/attached_databases.test.ts +51 -33
  91. package/tests/unit/ducklake/ducklake.test.ts +24 -22
  92. package/tests/unit/mcp/prompt_happy.test.ts +8 -8
  93. package/dist/app/assets/HomePage-DbZS0N7G.js +0 -1
  94. package/dist/app/assets/MainPage-CBuWkbmr.js +0 -2
  95. package/dist/app/assets/ModelPage-Bt37smot.js +0 -1
  96. package/dist/app/assets/PackagePage-DLZe50WG.js +0 -1
  97. package/dist/app/assets/ProjectPage-FQTEPXP4.js +0 -1
  98. package/dist/app/assets/WorkbookPage-CkAo16ar.js +0 -1
  99. package/src/mcp/resources/project_resource.ts +0 -184
  100. package/src/service/resolve_project.ts +0 -13
@@ -1,7 +1,7 @@
1
1
  import type {
2
2
  BuildGraph,
3
- Connection as MalloyConnection,
4
3
  MalloyConfig,
4
+ Connection as MalloyConnection,
5
5
  PersistSource,
6
6
  } from "@malloydata/malloy";
7
7
  import { Manifest } from "@malloydata/malloy";
@@ -19,6 +19,7 @@ import {
19
19
  ResourceRepository,
20
20
  } from "../storage/DatabaseInterface";
21
21
  import { DuplicateActiveMaterializationError } from "../storage/duckdb/MaterializationRepository";
22
+ import { EnvironmentStore } from "./environment_store";
22
23
  import { ManifestService } from "./manifest_service";
23
24
  import {
24
25
  dropManifestEntries,
@@ -26,9 +27,8 @@ import {
26
27
  liveTableKey,
27
28
  } from "./materialized_table_gc";
28
29
  import { Model } from "./model";
29
- import { ProjectStore } from "./project_store";
30
30
  import { quoteTablePath, splitTablePath } from "./quoting";
31
- import { resolveProjectId } from "./resolve_project";
31
+ import { resolveEnvironmentId } from "./resolve_environment";
32
32
 
33
33
  /**
34
34
  * Length of the BuildID prefix used when synthesizing staging table names.
@@ -128,7 +128,7 @@ const VALID_TRANSITIONS: Record<
128
128
  * The manifest is optionally activated after a successful build so
129
129
  * subsequent queries resolve persist references to materialized tables.
130
130
  *
131
- * Enforces at-most-one concurrent build per (project, package) via a
131
+ * Enforces at-most-one concurrent build per (environment, package) via a
132
132
  * DB-level unique index on `materializations.active_key` (see
133
133
  * `MaterializationRepository`), and supports cooperative cancellation
134
134
  * through `AbortController`.
@@ -149,12 +149,12 @@ export class MaterializationService {
149
149
  private runningAbortControllers = new Map<string, AbortController>();
150
150
 
151
151
  constructor(
152
- private projectStore: ProjectStore,
152
+ private environmentStore: EnvironmentStore,
153
153
  private manifestService: ManifestService,
154
154
  ) {}
155
155
 
156
156
  private get repository(): ResourceRepository {
157
- return this.projectStore.storageManager.getRepository();
157
+ return this.environmentStore.storageManager.getRepository();
158
158
  }
159
159
 
160
160
  // ==================== STATE MACHINE ====================
@@ -198,28 +198,28 @@ export class MaterializationService {
198
198
  // ==================== BUILD QUERIES ====================
199
199
 
200
200
  async listMaterializations(
201
- projectName: string,
201
+ environmentName: string,
202
202
  packageName: string,
203
203
  options?: { limit?: number; offset?: number },
204
204
  ): Promise<Materialization[]> {
205
- const projectId = await this.resolveProjectId(projectName);
205
+ const environmentId = await this.resolveEnvironmentId(environmentName);
206
206
  return this.repository.listMaterializations(
207
- projectId,
207
+ environmentId,
208
208
  packageName,
209
209
  options,
210
210
  );
211
211
  }
212
212
 
213
213
  async getMaterialization(
214
- projectName: string,
214
+ environmentName: string,
215
215
  packageName: string,
216
216
  buildId: string,
217
217
  ): Promise<Materialization> {
218
- const projectId = await this.resolveProjectId(projectName);
218
+ const environmentId = await this.resolveEnvironmentId(environmentName);
219
219
  const execution = await this.repository.getMaterializationById(buildId);
220
220
  if (
221
221
  !execution ||
222
- execution.projectId !== projectId ||
222
+ execution.environmentId !== environmentId ||
223
223
  execution.packageName !== packageName
224
224
  ) {
225
225
  throw new MaterializationNotFoundError(
@@ -236,21 +236,24 @@ export class MaterializationService {
236
236
  * metadata so `startMaterialization` can read them back.
237
237
  */
238
238
  async createMaterialization(
239
- projectName: string,
239
+ environmentName: string,
240
240
  packageName: string,
241
241
  options: { forceRefresh?: boolean; autoLoadManifest?: boolean } = {},
242
242
  ): Promise<Materialization> {
243
- const projectId = await this.resolveProjectId(projectName);
243
+ const environmentId = await this.resolveEnvironmentId(environmentName);
244
244
 
245
245
  // Verify the package exists.
246
- const project = await this.projectStore.getProject(projectName, false);
247
- await project.getPackage(packageName, false);
246
+ const environment = await this.environmentStore.getEnvironment(
247
+ environmentName,
248
+ false,
249
+ );
250
+ await environment.getPackage(packageName, false);
248
251
 
249
252
  // A non-atomic probe for a helpful error message. The DB-level unique
250
253
  // index on active_key is the actual race-free guard — see the catch
251
254
  // block below.
252
255
  const active = await this.repository.getActiveMaterialization(
253
- projectId,
256
+ environmentId,
254
257
  packageName,
255
258
  );
256
259
  if (active) {
@@ -266,7 +269,7 @@ export class MaterializationService {
266
269
 
267
270
  try {
268
271
  return await this.repository.createMaterialization(
269
- projectId,
272
+ environmentId,
270
273
  packageName,
271
274
  "PENDING",
272
275
  metadata,
@@ -276,7 +279,7 @@ export class MaterializationService {
276
279
  // Lost the race with a concurrent create. Re-read to report the
277
280
  // winner's id for parity with the non-racy error above.
278
281
  const winner = await this.repository.getActiveMaterialization(
279
- projectId,
282
+ environmentId,
280
283
  packageName,
281
284
  );
282
285
  throw new MaterializationConflictError(
@@ -294,13 +297,13 @@ export class MaterializationService {
294
297
  * background. Returns the RUNNING execution immediately.
295
298
  */
296
299
  async startMaterialization(
297
- projectName: string,
300
+ environmentName: string,
298
301
  packageName: string,
299
302
  buildId: string,
300
303
  ): Promise<Materialization> {
301
- const projectId = await this.resolveProjectId(projectName);
304
+ const environmentId = await this.resolveEnvironmentId(environmentName);
302
305
  const execution = await this.getMaterialization(
303
- projectName,
306
+ environmentName,
304
307
  packageName,
305
308
  buildId,
306
309
  );
@@ -313,7 +316,7 @@ export class MaterializationService {
313
316
 
314
317
  // Check for a *different* active materialization on this package.
315
318
  const active = await this.repository.getActiveMaterialization(
316
- projectId,
319
+ environmentId,
317
320
  packageName,
318
321
  );
319
322
  if (active && active.id !== execution.id) {
@@ -331,8 +334,8 @@ export class MaterializationService {
331
334
  // Fire-and-forget: run the build in the background.
332
335
  this.runMaterialization(
333
336
  execution.id,
334
- projectName,
335
- projectId,
337
+ environmentName,
338
+ environmentId,
336
339
  packageName,
337
340
  metadata,
338
341
  ).catch((err) => {
@@ -347,8 +350,8 @@ export class MaterializationService {
347
350
 
348
351
  private async runMaterialization(
349
352
  executionId: string,
350
- projectName: string,
351
- projectId: string,
353
+ environmentName: string,
354
+ environmentId: string,
352
355
  packageName: string,
353
356
  metadata: Record<string, unknown>,
354
357
  ): Promise<void> {
@@ -357,8 +360,8 @@ export class MaterializationService {
357
360
 
358
361
  try {
359
362
  const buildMetadata = await this.executeBuild(
360
- projectName,
361
- projectId,
363
+ environmentName,
364
+ environmentId,
362
365
  packageName,
363
366
  !!metadata.forceRefresh,
364
367
  abortController.signal,
@@ -366,14 +369,14 @@ export class MaterializationService {
366
369
 
367
370
  if (metadata.autoLoadManifest) {
368
371
  const updatedManifest = await this.manifestService.getManifest(
369
- projectId,
372
+ environmentId,
370
373
  packageName,
371
374
  );
372
- const project = await this.projectStore.getProject(
373
- projectName,
375
+ const environment = await this.environmentStore.getEnvironment(
376
+ environmentName,
374
377
  false,
375
378
  );
376
- const pkg = await project.getPackage(packageName, false);
379
+ const pkg = await environment.getPackage(packageName, false);
377
380
  await pkg.reloadAllModels(updatedManifest.entries);
378
381
  }
379
382
 
@@ -415,12 +418,12 @@ export class MaterializationService {
415
418
  * Cancels a running build. Takes a specific buildId.
416
419
  */
417
420
  async stopMaterialization(
418
- projectName: string,
421
+ environmentName: string,
419
422
  packageName: string,
420
423
  buildId: string,
421
424
  ): Promise<Materialization> {
422
425
  const execution = await this.getMaterialization(
423
- projectName,
426
+ environmentName,
424
427
  packageName,
425
428
  buildId,
426
429
  );
@@ -455,12 +458,12 @@ export class MaterializationService {
455
458
  * (SUCCESS, FAILED, CANCELLED) can be deleted.
456
459
  */
457
460
  async deleteMaterialization(
458
- projectName: string,
461
+ environmentName: string,
459
462
  packageName: string,
460
463
  materializationId: string,
461
464
  ): Promise<void> {
462
465
  const execution = await this.getMaterialization(
463
- projectName,
466
+ environmentName,
464
467
  packageName,
465
468
  materializationId,
466
469
  );
@@ -481,7 +484,7 @@ export class MaterializationService {
481
484
  *
482
485
  * This is the only out-of-band teardown surface exposed by the
483
486
  * publisher and is intended for a single caller: the controlplane,
484
- * invoking it on the truly destructive path before the package/project
487
+ * invoking it on the truly destructive path before the package/environment
485
488
  * is torn down. The publisher's `DELETE` endpoints are *not* wired into
486
489
  * teardown because the controlplane invokes them for non-destructive
487
490
  * unload too (down-replicate, drain, archive) where the entity still
@@ -505,14 +508,14 @@ export class MaterializationService {
505
508
  * deleting manifest rows.
506
509
  */
507
510
  async teardownPackage(
508
- projectName: string,
511
+ environmentName: string,
509
512
  packageName: string,
510
513
  options: { dryRun?: boolean } = {},
511
514
  ): Promise<GcResult> {
512
- const projectId = await this.resolveProjectId(projectName);
515
+ const environmentId = await this.resolveEnvironmentId(environmentName);
513
516
 
514
517
  const active = await this.repository.getActiveMaterialization(
515
- projectId,
518
+ environmentId,
516
519
  packageName,
517
520
  );
518
521
  if (active) {
@@ -521,11 +524,14 @@ export class MaterializationService {
521
524
  );
522
525
  }
523
526
 
524
- const project = await this.projectStore.getProject(projectName, false);
525
- const pkg = await project.getPackage(packageName, false);
527
+ const environment = await this.environmentStore.getEnvironment(
528
+ environmentName,
529
+ false,
530
+ );
531
+ const pkg = await environment.getPackage(packageName, false);
526
532
 
527
533
  const entries = await this.manifestService.listEntries(
528
- projectId,
534
+ environmentId,
529
535
  packageName,
530
536
  );
531
537
 
@@ -541,7 +547,7 @@ export class MaterializationService {
541
547
  return dropManifestEntries(entries, {
542
548
  connections,
543
549
  manifestService: this.manifestService,
544
- projectId,
550
+ environmentId,
545
551
  dryRun: options.dryRun,
546
552
  forceDeleteRowOnMissingConnection: true,
547
553
  });
@@ -560,30 +566,33 @@ export class MaterializationService {
560
566
  * `gcErrors` metadata so the controller/UI can show them.
561
567
  */
562
568
  private async executeBuild(
563
- projectName: string,
564
- projectId: string,
569
+ environmentName: string,
570
+ environmentId: string,
565
571
  packageName: string,
566
572
  forceRefresh: boolean,
567
573
  signal: AbortSignal,
568
574
  ): Promise<Record<string, unknown>> {
569
575
  logger.info("Starting materialization build", {
570
- projectName,
576
+ environmentName,
571
577
  packageName,
572
578
  });
573
579
 
574
- const project = await this.projectStore.getProject(projectName, false);
575
- const pkg = await project.getPackage(packageName, false);
580
+ const environment = await this.environmentStore.getEnvironment(
581
+ environmentName,
582
+ false,
583
+ );
584
+ const pkg = await environment.getPackage(packageName, false);
576
585
 
577
586
  // ── STEP 1: LOAD ───────────────────────────────────────────────
578
587
  const manifest = new Manifest();
579
588
  const existingManifest = await this.manifestService.getManifest(
580
- projectId,
589
+ environmentId,
581
590
  packageName,
582
591
  );
583
592
  manifest.loadText(JSON.stringify(existingManifest));
584
593
 
585
594
  const existingEntries = await this.manifestService.listEntries(
586
- projectId,
595
+ environmentId,
587
596
  packageName,
588
597
  );
589
598
  const knownMaterializedTables = new Set(
@@ -594,7 +603,7 @@ export class MaterializationService {
594
603
 
595
604
  // ── STEP 2: COMPILE & PLAN ─────────────────────────────────────
596
605
  // `connections` is built lazily from the connection names the plan
597
- // actually targets — no upfront ATTACH on every project connection.
606
+ // actually targets — no upfront ATTACH on every environment connection.
598
607
  const { graphs, sources, connectionDigests, connections } =
599
608
  await this.compilePackageBuildPlan(pkg, signal);
600
609
 
@@ -634,7 +643,7 @@ export class MaterializationService {
634
643
  connection,
635
644
  connectionDigests,
636
645
  forceRefresh,
637
- projectId,
646
+ environmentId,
638
647
  packageName,
639
648
  knownMaterializedTables,
640
649
  );
@@ -649,7 +658,7 @@ export class MaterializationService {
649
658
  // ── STEP 4: GC ─────────────────────────────────────────────────
650
659
  const gcResult = await this.runPostBuildGc(
651
660
  manifest,
652
- projectId,
661
+ environmentId,
653
662
  packageName,
654
663
  connections,
655
664
  );
@@ -800,7 +809,7 @@ export class MaterializationService {
800
809
  connection: MalloyConnection,
801
810
  connectionDigests: Record<string, string>,
802
811
  forceRefresh: boolean,
803
- projectId: string,
812
+ environmentId: string,
804
813
  packageName: string,
805
814
  knownMaterializedTables: Set<string>,
806
815
  ): Promise<Record<string, unknown>> {
@@ -899,7 +908,7 @@ export class MaterializationService {
899
908
  manifest.update(buildId, { tableName });
900
909
 
901
910
  await this.manifestService.writeEntry(
902
- projectId,
911
+ environmentId,
903
912
  packageName,
904
913
  buildId,
905
914
  tableName,
@@ -930,13 +939,13 @@ export class MaterializationService {
930
939
  */
931
940
  private async runPostBuildGc(
932
941
  manifest: Manifest,
933
- projectId: string,
942
+ environmentId: string,
934
943
  packageName: string,
935
944
  connections: Map<string, MalloyConnection>,
936
945
  ): Promise<GcResult> {
937
946
  const activeManifest = manifest.activeEntries;
938
947
  const allDbEntries = await this.manifestService.listEntries(
939
- projectId,
948
+ environmentId,
940
949
  packageName,
941
950
  );
942
951
 
@@ -954,7 +963,7 @@ export class MaterializationService {
954
963
  const gcResult = await dropManifestEntries(staleEntries, {
955
964
  connections,
956
965
  manifestService: this.manifestService,
957
- projectId,
966
+ environmentId,
958
967
  liveTables,
959
968
  });
960
969
 
@@ -970,7 +979,7 @@ export class MaterializationService {
970
979
 
971
980
  // ==================== HELPERS ====================
972
981
 
973
- private resolveProjectId(projectName: string): Promise<string> {
974
- return resolveProjectId(this.repository, projectName);
982
+ private resolveEnvironmentId(environmentName: string): Promise<string> {
983
+ return resolveEnvironmentId(this.repository, environmentName);
975
984
  }
976
985
  }
@@ -9,7 +9,7 @@ import { dropManifestEntries, liveTableKey } from "./materialized_table_gc";
9
9
  function makeEntry(overrides: Partial<ManifestEntry> = {}): ManifestEntry {
10
10
  return {
11
11
  id: "entry-1",
12
- projectId: "proj-1",
12
+ environmentId: "proj-1",
13
13
  packageName: "pkg",
14
14
  buildId: "abcdef1234567890abcdef1234567890",
15
15
  tableName: "my_table",
@@ -67,7 +67,7 @@ describe("dropManifestEntries", () => {
67
67
  const result = await dropManifestEntries([entry], {
68
68
  connections: ctx.connections,
69
69
  manifestService: ctx.manifestService,
70
- projectId: "proj-1",
70
+ environmentId: "proj-1",
71
71
  });
72
72
 
73
73
  expect(result.dropped).toHaveLength(1);
@@ -102,7 +102,7 @@ describe("dropManifestEntries", () => {
102
102
  const result = await dropManifestEntries([entry], {
103
103
  connections: ctx.connections,
104
104
  manifestService: ctx.manifestService,
105
- projectId: "proj-1",
105
+ environmentId: "proj-1",
106
106
  });
107
107
 
108
108
  expect(result.dropped).toHaveLength(0);
@@ -122,7 +122,7 @@ describe("dropManifestEntries", () => {
122
122
  const result = await dropManifestEntries([entry], {
123
123
  connections: ctx.connections,
124
124
  manifestService: ctx.manifestService,
125
- projectId: "proj-1",
125
+ environmentId: "proj-1",
126
126
  });
127
127
 
128
128
  // Manifest row is gone → entry is authoritatively dropped. The
@@ -146,7 +146,7 @@ describe("dropManifestEntries", () => {
146
146
  const result = await dropManifestEntries([entry], {
147
147
  connections: ctx.connections,
148
148
  manifestService: ctx.manifestService,
149
- projectId: "proj-1",
149
+ environmentId: "proj-1",
150
150
  });
151
151
 
152
152
  expect(result.dropped).toHaveLength(1);
@@ -162,7 +162,7 @@ describe("dropManifestEntries", () => {
162
162
  const result = await dropManifestEntries([entry], {
163
163
  connections: ctx.connections,
164
164
  manifestService: ctx.manifestService,
165
- projectId: "proj-1",
165
+ environmentId: "proj-1",
166
166
  });
167
167
 
168
168
  expect(result.dropped).toHaveLength(0);
@@ -181,7 +181,7 @@ describe("dropManifestEntries", () => {
181
181
  const result = await dropManifestEntries([entry], {
182
182
  connections: ctx2.connections,
183
183
  manifestService: ctx2.manifestService,
184
- projectId: "proj-1",
184
+ environmentId: "proj-1",
185
185
  });
186
186
 
187
187
  expect(result.dropped).toHaveLength(0);
@@ -199,7 +199,7 @@ describe("dropManifestEntries", () => {
199
199
  const result = await dropManifestEntries(entries, {
200
200
  connections: ctx.connections,
201
201
  manifestService: ctx.manifestService,
202
- projectId: "proj-1",
202
+ environmentId: "proj-1",
203
203
  dryRun: true,
204
204
  });
205
205
 
@@ -222,7 +222,7 @@ describe("dropManifestEntries", () => {
222
222
  const result = await dropManifestEntries([bad, good], {
223
223
  connections: ctx.connections,
224
224
  manifestService: ctx.manifestService,
225
- projectId: "proj-1",
225
+ environmentId: "proj-1",
226
226
  });
227
227
 
228
228
  expect(result.dropped).toHaveLength(1);
@@ -250,7 +250,7 @@ describe("dropManifestEntries", () => {
250
250
  const result = await dropManifestEntries([staleEntry], {
251
251
  connections: ctx.connections,
252
252
  manifestService: ctx.manifestService,
253
- projectId: "proj-1",
253
+ environmentId: "proj-1",
254
254
  liveTables: live,
255
255
  });
256
256
 
@@ -280,7 +280,7 @@ describe("dropManifestEntries", () => {
280
280
  const result = await dropManifestEntries([staleEntry], {
281
281
  connections: ctx.connections,
282
282
  manifestService: ctx.manifestService,
283
- projectId: "proj-1",
283
+ environmentId: "proj-1",
284
284
  liveTables: live,
285
285
  });
286
286
 
@@ -296,7 +296,7 @@ describe("dropManifestEntries", () => {
296
296
  const result = await dropManifestEntries([staleEntry], {
297
297
  connections: ctx.connections,
298
298
  manifestService: ctx.manifestService,
299
- projectId: "proj-1",
299
+ environmentId: "proj-1",
300
300
  dryRun: true,
301
301
  liveTables: live,
302
302
  });
@@ -317,7 +317,7 @@ describe("dropManifestEntries", () => {
317
317
  const result = await dropManifestEntries([entry], {
318
318
  connections: ctx.connections,
319
319
  manifestService: ctx.manifestService,
320
- projectId: "proj-1",
320
+ environmentId: "proj-1",
321
321
  forceDeleteRowOnMissingConnection: true,
322
322
  });
323
323
 
@@ -339,7 +339,7 @@ describe("dropManifestEntries", () => {
339
339
  const result = await dropManifestEntries([entry], {
340
340
  connections: ctx.connections,
341
341
  manifestService: ctx.manifestService,
342
- projectId: "proj-1",
342
+ environmentId: "proj-1",
343
343
  forceDeleteRowOnMissingConnection: true,
344
344
  });
345
345
 
@@ -354,7 +354,7 @@ describe("dropManifestEntries", () => {
354
354
  const result = await dropManifestEntries([entry], {
355
355
  connections: ctx.connections,
356
356
  manifestService: ctx.manifestService,
357
- projectId: "proj-1",
357
+ environmentId: "proj-1",
358
358
  forceDeleteRowOnMissingConnection: true,
359
359
  dryRun: true,
360
360
  });
@@ -72,7 +72,7 @@ export interface GcResult {
72
72
  export interface GcContext {
73
73
  connections: Map<string, Connection>;
74
74
  manifestService: ManifestService;
75
- projectId: string;
75
+ environmentId: string;
76
76
  dryRun?: boolean;
77
77
  /**
78
78
  * Set of `liveTableKey(connectionName, tableName)` tuples that some
@@ -115,7 +115,7 @@ async function processOneEntry(
115
115
  if (!connection) {
116
116
  if (ctx.forceDeleteRowOnMissingConnection && !ctx.dryRun) {
117
117
  try {
118
- await ctx.manifestService.deleteEntry(ctx.projectId, entry.id);
118
+ await ctx.manifestService.deleteEntry(ctx.environmentId, entry.id);
119
119
  logger.warn(
120
120
  "GC: deleted manifest row whose connection is gone; physical table (if any) is orphaned",
121
121
  {
@@ -184,7 +184,7 @@ async function processOneEntry(
184
184
  const quoted = (p: string) => quoteTablePath(p, dialect);
185
185
 
186
186
  try {
187
- await ctx.manifestService.deleteEntry(ctx.projectId, entry.id);
187
+ await ctx.manifestService.deleteEntry(ctx.environmentId, entry.id);
188
188
  } catch (err) {
189
189
  const error = err instanceof Error ? err.message : String(err);
190
190
  logger.warn("GC: failed to delete manifest row; skipping physical drop", {
@@ -22,10 +22,10 @@ import {
22
22
  MalloySQLParser,
23
23
  MalloySQLStatementType,
24
24
  } from "@malloydata/malloy-sql";
25
- import { createRequire } from "module";
26
25
  import { DataStyles } from "@malloydata/render";
27
26
  import { metrics } from "@opentelemetry/api";
28
27
  import * as fs from "fs/promises";
28
+ import { createRequire } from "module";
29
29
  import * as path from "path";
30
30
  import { components } from "../api";
31
31
  import {
@@ -426,7 +426,7 @@ export class Model {
426
426
  logger.error("Query parsing error", {
427
427
  error,
428
428
  errorMessage,
429
- projectName: this.packageName,
429
+ environmentName: this.packageName,
430
430
  modelPath: this.modelPath,
431
431
  query,
432
432
  queryName,
@@ -466,7 +466,7 @@ export class Model {
466
466
  logger.error("Query execution error", {
467
467
  error,
468
468
  errorMessage,
469
- projectName: this.packageName,
469
+ environmentName: this.packageName,
470
470
  modelPath: this.modelPath,
471
471
  query,
472
472
  queryName,
@@ -703,7 +703,7 @@ export class Model {
703
703
 
704
704
  const modelURL = new URL(`file://${fullModelPath}`);
705
705
  const baseUrl = new URL(".", modelURL);
706
- const importBaseURL = new URL(baseUrl.pathname + "/", "file:");
706
+ const importBaseURL = baseUrl;
707
707
  const urlReader = new HackyDataStylesAccumulator(URL_READER);
708
708
 
709
709
  // Request runtimes borrow the cached package MalloyConfig. The package
@@ -316,7 +316,7 @@ describe("service/package", () => {
316
316
  expect(models).toEqual([
317
317
  {
318
318
  // @ts-expect-error TODO: Fix missing projectName type in API
319
- projectName: "testProject",
319
+ environmentName: "testProject",
320
320
  packageName: "testPackage",
321
321
  path: "model1.malloy",
322
322
  error: undefined,
@@ -327,7 +327,7 @@ describe("service/package", () => {
327
327
  expect(notebooks).toEqual([
328
328
  {
329
329
  // @ts-expect-error TODO: Fix missing projectName type in API
330
- projectName: "testProject",
330
+ environmentName: "testProject",
331
331
  packageName: "testPackage",
332
332
  path: "model2.malloynb",
333
333
  error: "This is the error",