@malloy-publisher/server 0.0.196-dev → 0.0.196

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 (103) 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 +1954 -1318
  16. package/package.json +1 -1
  17. package/publisher.config.json +2 -2
  18. package/src/config.spec.ts +181 -66
  19. package/src/config.ts +68 -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-old.ts +1119 -0
  48. package/src/server.ts +191 -159
  49. package/src/service/connection.spec.ts +158 -133
  50. package/src/service/connection.ts +42 -39
  51. package/src/service/connection_config.spec.ts +13 -11
  52. package/src/service/connection_config.ts +28 -19
  53. package/src/service/connection_service.spec.ts +63 -43
  54. package/src/service/connection_service.ts +106 -89
  55. package/src/service/{project.ts → environment.ts} +92 -77
  56. package/src/service/{project_compile.spec.ts → environment_compile.spec.ts} +1 -1
  57. package/src/service/{project_store.spec.ts → environment_store.spec.ts} +99 -85
  58. package/src/service/{project_store.ts → environment_store.ts} +368 -326
  59. package/src/service/manifest_service.spec.ts +15 -15
  60. package/src/service/manifest_service.ts +26 -21
  61. package/src/service/materialization_service.spec.ts +93 -59
  62. package/src/service/materialization_service.ts +71 -62
  63. package/src/service/materialized_table_gc.spec.ts +15 -15
  64. package/src/service/materialized_table_gc.ts +3 -3
  65. package/src/service/model.ts +2 -2
  66. package/src/service/package.spec.ts +2 -2
  67. package/src/service/package.ts +23 -21
  68. package/src/service/resolve_environment.ts +15 -0
  69. package/src/storage/DatabaseInterface.ts +34 -25
  70. package/src/storage/StorageManager.mock.ts +3 -3
  71. package/src/storage/StorageManager.ts +24 -23
  72. package/src/storage/duckdb/ConnectionRepository.ts +13 -11
  73. package/src/storage/duckdb/DuckDBConnection.ts +1 -1
  74. package/src/storage/duckdb/DuckDBManifestStore.ts +6 -6
  75. package/src/storage/duckdb/DuckDBRepository.ts +47 -47
  76. package/src/storage/duckdb/{ProjectRepository.ts → EnvironmentRepository.ts} +35 -35
  77. package/src/storage/duckdb/ManifestRepository.ts +21 -20
  78. package/src/storage/duckdb/MaterializationRepository.ts +31 -28
  79. package/src/storage/duckdb/PackageRepository.ts +11 -11
  80. package/src/storage/duckdb/manifest_store.spec.ts +2 -2
  81. package/src/storage/duckdb/schema.ts +61 -20
  82. package/src/storage/ducklake/DuckLakeManifestStore.ts +14 -14
  83. package/tests/fixtures/publisher.config.json +1 -1
  84. package/tests/harness/e2e.ts +1 -1
  85. package/tests/harness/mcp_test_setup.ts +1 -1
  86. package/tests/harness/mocks.ts +10 -8
  87. package/tests/harness/rest_e2e.ts +2 -2
  88. package/tests/integration/legacy_routes/legacy_routes.integration.spec.ts +259 -0
  89. package/tests/integration/materialization/materialization_lifecycle.integration.spec.ts +4 -4
  90. package/tests/integration/mcp/mcp_execute_query_tool.integration.spec.ts +27 -48
  91. package/tests/integration/mcp/mcp_resource.integration.spec.ts +26 -35
  92. package/tests/unit/duckdb/attached_databases.test.ts +51 -33
  93. package/tests/unit/duckdb/legacy_schema_migration.test.ts +194 -0
  94. package/tests/unit/ducklake/ducklake.test.ts +24 -22
  95. package/tests/unit/mcp/prompt_happy.test.ts +8 -8
  96. package/dist/app/assets/HomePage-DbZS0N7G.js +0 -1
  97. package/dist/app/assets/MainPage-CBuWkbmr.js +0 -2
  98. package/dist/app/assets/ModelPage-Bt37smot.js +0 -1
  99. package/dist/app/assets/PackagePage-DLZe50WG.js +0 -1
  100. package/dist/app/assets/ProjectPage-FQTEPXP4.js +0 -1
  101. package/dist/app/assets/WorkbookPage-CkAo16ar.js +0 -1
  102. package/src/mcp/resources/project_resource.ts +0 -184
  103. package/src/service/resolve_project.ts +0 -13
@@ -5,14 +5,14 @@ import * as sinon from "sinon";
5
5
  import { components } from "../api";
6
6
  import { isPublisherConfigFrozen } from "../config";
7
7
  import { TEMP_DIR_PATH } from "../constants";
8
- import { Project } from "./project";
9
- import { ProjectStore } from "./project_store";
8
+ import { Environment } from "./environment";
9
+ import { EnvironmentStore } from "./environment_store";
10
10
 
11
11
  type MockData = Record<string, unknown>;
12
12
 
13
13
  const initializeDuckLakeCalls: Array<{
14
- projectId: string;
15
- projectName: string;
14
+ environmentId: string;
15
+ environmentName: string;
16
16
  config: { catalogUrl: string; dataPath: string };
17
17
  }> = [];
18
18
 
@@ -23,20 +23,24 @@ mock.module("../storage/StorageManager", () => {
23
23
  return;
24
24
  }
25
25
 
26
- async initializeDuckLakeForProject(
27
- projectId: string,
28
- projectName: string,
26
+ async initializeDuckLakeForEnvironment(
27
+ environmentId: string,
28
+ environmentName: string,
29
29
  config: { catalogUrl: string; dataPath: string },
30
30
  ): Promise<void> {
31
- initializeDuckLakeCalls.push({ projectId, projectName, config });
31
+ initializeDuckLakeCalls.push({
32
+ environmentId,
33
+ environmentName,
34
+ config,
35
+ });
32
36
  }
33
37
 
34
38
  getRepository() {
35
39
  return {
36
40
  // ===== PROJECT METHODS =====
37
- listProjects: async (): Promise<unknown[]> => [],
41
+ listEnvironments: async (): Promise<unknown[]> => [],
38
42
 
39
- getProjectById: async (
43
+ getEnvironmentById: async (
40
44
  id: string,
41
45
  ): Promise<MockData | null> => ({
42
46
  id,
@@ -48,14 +52,16 @@ mock.module("../storage/StorageManager", () => {
48
52
  updatedAt: new Date(),
49
53
  }),
50
54
 
51
- getProjectByName: async (
55
+ getEnvironmentByName: async (
52
56
  _name: string,
53
57
  ): Promise<MockData | null> => {
54
58
  // Return null to simulate "project doesn't exist yet"
55
59
  return null;
56
60
  },
57
61
 
58
- createProject: async (data: MockData): Promise<MockData> => ({
62
+ createEnvironment: async (
63
+ data: MockData,
64
+ ): Promise<MockData> => ({
59
65
  id: "test-project-id",
60
66
  name: data.name,
61
67
  path: data.path,
@@ -65,7 +71,7 @@ mock.module("../storage/StorageManager", () => {
65
71
  updatedAt: new Date(),
66
72
  }),
67
73
 
68
- updateProject: async (
74
+ updateEnvironment: async (
69
75
  id: string,
70
76
  data: MockData,
71
77
  ): Promise<MockData> => ({
@@ -81,18 +87,18 @@ mock.module("../storage/StorageManager", () => {
81
87
  updatedAt: new Date(),
82
88
  }),
83
89
 
84
- deleteProject: async (_id: string): Promise<void> => {},
90
+ deleteEnvironment: async (_id: string): Promise<void> => {},
85
91
 
86
92
  // ===== PACKAGE METHODS =====
87
93
  listPackages: async (
88
- _projectId: string,
94
+ _environmentId: string,
89
95
  ): Promise<unknown[]> => [],
90
96
 
91
97
  getPackageById: async (
92
98
  id: string,
93
99
  ): Promise<MockData | null> => ({
94
100
  id,
95
- projectId: "test-project-id",
101
+ environmentId: "test-project-id",
96
102
  name: "test-package",
97
103
  description: "Test package",
98
104
  manifestPath: "/test/manifest.json",
@@ -102,13 +108,13 @@ mock.module("../storage/StorageManager", () => {
102
108
  }),
103
109
 
104
110
  getPackageByName: async (
105
- _projectId: string,
111
+ _environmentId: string,
106
112
  _name: string,
107
113
  ): Promise<MockData | null> => null,
108
114
 
109
115
  createPackage: async (data: MockData): Promise<MockData> => ({
110
116
  id: "test-package-id",
111
- projectId: data.projectId,
117
+ environmentId: data.environmentId,
112
118
  name: data.name,
113
119
  description: data.description,
114
120
  manifestPath: data.manifestPath,
@@ -122,7 +128,7 @@ mock.module("../storage/StorageManager", () => {
122
128
  data: MockData,
123
129
  ): Promise<MockData> => ({
124
130
  id,
125
- projectId: "test-project-id",
131
+ environmentId: "test-project-id",
126
132
  name: "test-package",
127
133
  description: data.description,
128
134
  manifestPath: "/test/manifest.json",
@@ -135,14 +141,14 @@ mock.module("../storage/StorageManager", () => {
135
141
 
136
142
  // ===== CONNECTION METHODS =====
137
143
  listConnections: async (
138
- _projectId: string,
144
+ _environmentId: string,
139
145
  ): Promise<unknown[]> => [],
140
146
 
141
147
  getConnectionById: async (
142
148
  id: string,
143
149
  ): Promise<MockData | null> => ({
144
150
  id,
145
- projectId: "test-project-id",
151
+ environmentId: "test-project-id",
146
152
  name: "test-connection",
147
153
  type: "postgres",
148
154
  config: {},
@@ -151,13 +157,13 @@ mock.module("../storage/StorageManager", () => {
151
157
  }),
152
158
 
153
159
  getConnectionByName: async (
154
- _projectId: string,
160
+ _environmentId: string,
155
161
  _name: string,
156
162
  ): Promise<MockData | null> => null,
157
163
 
158
164
  createConnection: async (data: MockData): Promise<MockData> => ({
159
165
  id: "test-connection-id",
160
- projectId: data.projectId,
166
+ environmentId: data.environmentId,
161
167
  name: data.name,
162
168
  type: data.type,
163
169
  config: data.config,
@@ -170,7 +176,7 @@ mock.module("../storage/StorageManager", () => {
170
176
  data: MockData,
171
177
  ): Promise<MockData> => ({
172
178
  id,
173
- projectId: "test-project-id",
179
+ environmentId: "test-project-id",
174
180
  name: "test-connection",
175
181
  type: "postgres",
176
182
  config: data.config || {},
@@ -196,8 +202,8 @@ const projectName = "organizationName-projectName";
196
202
 
197
203
  let sandbox: sinon.SinonSandbox;
198
204
 
199
- describe("ProjectStore Service", () => {
200
- let projectStore: ProjectStore;
205
+ describe("EnvironmentStore Service", () => {
206
+ let environmentStore: EnvironmentStore;
201
207
 
202
208
  beforeEach(async () => {
203
209
  // Clean up any existing test directory
@@ -214,7 +220,7 @@ describe("ProjectStore Service", () => {
214
220
  }));
215
221
 
216
222
  // Create project store after mocking
217
- projectStore = new ProjectStore(serverRootPath);
223
+ environmentStore = new EnvironmentStore(serverRootPath);
218
224
  });
219
225
 
220
226
  afterEach(async () => {
@@ -228,7 +234,7 @@ describe("ProjectStore Service", () => {
228
234
 
229
235
  it("should not load a package if the project does not exist", async () => {
230
236
  await expect(
231
- projectStore.getProject("non-existent-project"),
237
+ environmentStore.getEnvironment("non-existent-project"),
232
238
  ).rejects.toThrow();
233
239
  });
234
240
 
@@ -256,7 +262,7 @@ describe("ProjectStore Service", () => {
256
262
  publisherConfigPath,
257
263
  JSON.stringify({
258
264
  frozenConfig: false,
259
- projects: [
265
+ environments: [
260
266
  {
261
267
  name: projectName,
262
268
  packages: [
@@ -277,8 +283,8 @@ describe("ProjectStore Service", () => {
277
283
  );
278
284
 
279
285
  // Test that the project can be retrieved
280
- const project = await projectStore.getProject(projectName);
281
- expect(project).toBeInstanceOf(Project);
286
+ const project = await environmentStore.getEnvironment(projectName);
287
+ expect(project).toBeInstanceOf(Environment);
282
288
  expect(project.metadata.name).toBe(projectName);
283
289
  },
284
290
  { timeout: 30000 },
@@ -303,7 +309,7 @@ describe("ProjectStore Service", () => {
303
309
  publisherConfigPath,
304
310
  JSON.stringify({
305
311
  frozenConfig: false,
306
- projects: [
312
+ environments: [
307
313
  {
308
314
  name: projectName1,
309
315
  packages: [
@@ -340,11 +346,11 @@ describe("ProjectStore Service", () => {
340
346
  );
341
347
 
342
348
  // Create a new project store that will read the configuration
343
- const newProjectStore = new ProjectStore(serverRootPath);
344
- await newProjectStore.finishedInitialization;
349
+ const newEnvironmentStore = new EnvironmentStore(serverRootPath);
350
+ await newEnvironmentStore.finishedInitialization;
345
351
 
346
352
  // Test that both projects can be listed
347
- const projects = await newProjectStore.listProjects();
353
+ const projects = await newEnvironmentStore.listEnvironments();
348
354
  expect(projects).toBeInstanceOf(Array);
349
355
  expect(projects.length).toBe(2);
350
356
  expect(projects.map((p) => p.name)).toContain(projectName1);
@@ -382,7 +388,7 @@ describe("ProjectStore Service", () => {
382
388
  publisherConfigPath,
383
389
  JSON.stringify({
384
390
  frozenConfig: false,
385
- projects: [
391
+ environments: [
386
392
  {
387
393
  name: invalidProjectName,
388
394
  packages: [
@@ -413,13 +419,13 @@ describe("ProjectStore Service", () => {
413
419
  }),
414
420
  );
415
421
 
416
- const newProjectStore = new ProjectStore(serverRootPath);
417
- await newProjectStore.finishedInitialization;
422
+ const newEnvironmentStore = new EnvironmentStore(serverRootPath);
423
+ await newEnvironmentStore.finishedInitialization;
418
424
 
419
- const projects = await newProjectStore.listProjects();
425
+ const projects = await newEnvironmentStore.listEnvironments();
420
426
  expect(projects.map((p) => p.name)).toEqual([validProjectName]);
421
427
  await expect(
422
- newProjectStore.getProject(invalidProjectName),
428
+ newEnvironmentStore.getEnvironment(invalidProjectName),
423
429
  ).rejects.toThrow();
424
430
  });
425
431
 
@@ -444,7 +450,7 @@ describe("ProjectStore Service", () => {
444
450
  publisherConfigPath,
445
451
  JSON.stringify({
446
452
  frozenConfig: false,
447
- projects: [
453
+ environments: [
448
454
  {
449
455
  name: projectName,
450
456
  packages: [
@@ -458,10 +464,10 @@ describe("ProjectStore Service", () => {
458
464
  }),
459
465
  );
460
466
 
461
- await projectStore.finishedInitialization;
467
+ await environmentStore.finishedInitialization;
462
468
 
463
469
  // Get the project
464
- const project = await projectStore.getProject(projectName);
470
+ const project = await environmentStore.getEnvironment(projectName);
465
471
 
466
472
  // Update the project
467
473
  await project.update({
@@ -481,13 +487,13 @@ describe("ProjectStore Service", () => {
481
487
  expect(readmeContent).toBe("Updated README content");
482
488
  });
483
489
 
484
- it("should propagate materializationStorage on addProject for new project", async () => {
490
+ it("should propagate materializationStorage on addEnvironment for new environment", async () => {
485
491
  writeFileSync(
486
492
  path.join(serverRootPath, "publisher.config.json"),
487
- JSON.stringify({ frozenConfig: false, projects: [] }),
493
+ JSON.stringify({ frozenConfig: false, environments: [] }),
488
494
  );
489
495
 
490
- await projectStore.finishedInitialization;
496
+ await environmentStore.finishedInitialization;
491
497
 
492
498
  const materializationStorage = {
493
499
  catalogUrl:
@@ -496,7 +502,7 @@ describe("ProjectStore Service", () => {
496
502
  };
497
503
 
498
504
  initializeDuckLakeCalls.length = 0;
499
- const project = await projectStore.addProject({
505
+ const project = await environmentStore.addEnvironment({
500
506
  name: projectName,
501
507
  materializationStorage,
502
508
  });
@@ -519,7 +525,7 @@ describe("ProjectStore Service", () => {
519
525
  path.join(serverRootPath, "publisher.config.json"),
520
526
  JSON.stringify({
521
527
  frozenConfig: false,
522
- projects: [
528
+ environments: [
523
529
  {
524
530
  name: projectName,
525
531
  packages: [{ name: projectName, location: projectPath }],
@@ -528,8 +534,8 @@ describe("ProjectStore Service", () => {
528
534
  }),
529
535
  );
530
536
 
531
- await projectStore.finishedInitialization;
532
- const project = await projectStore.getProject(projectName);
537
+ await environmentStore.finishedInitialization;
538
+ const project = await environmentStore.getEnvironment(projectName);
533
539
 
534
540
  const materializationStorage = {
535
541
  catalogUrl:
@@ -567,7 +573,7 @@ describe("ProjectStore Service", () => {
567
573
  writeFileSync(
568
574
  publisherConfigPath,
569
575
  JSON.stringify({
570
- projects: [
576
+ environments: [
571
577
  {
572
578
  name: projectName,
573
579
  packages: [
@@ -582,13 +588,16 @@ describe("ProjectStore Service", () => {
582
588
  );
583
589
 
584
590
  // Get the project
585
- const project1 = await projectStore.getProject(projectName);
591
+ const project1 = await environmentStore.getEnvironment(projectName);
586
592
 
587
593
  // Get the project again with reload=true
588
- const project2 = await projectStore.getProject(projectName, true);
594
+ const project2 = await environmentStore.getEnvironment(
595
+ projectName,
596
+ true,
597
+ );
589
598
 
590
- expect(project1).toBeInstanceOf(Project);
591
- expect(project2).toBeInstanceOf(Project);
599
+ expect(project1).toBeInstanceOf(Environment);
600
+ expect(project2).toBeInstanceOf(Environment);
592
601
  expect(project1.metadata.name).toBe(project2.metadata.name as string);
593
602
  },
594
603
  { timeout: 30000 },
@@ -603,7 +612,7 @@ describe("ProjectStore Service", () => {
603
612
  writeFileSync(
604
613
  publisherConfigPath,
605
614
  JSON.stringify({
606
- projects: [
615
+ environments: [
607
616
  {
608
617
  name: projectName,
609
618
  packages: [
@@ -618,7 +627,9 @@ describe("ProjectStore Service", () => {
618
627
  );
619
628
 
620
629
  // Test that getting the project throws an error
621
- await expect(projectStore.getProject(projectName)).rejects.toThrow();
630
+ await expect(
631
+ environmentStore.getEnvironment(projectName),
632
+ ).rejects.toThrow();
622
633
  });
623
634
 
624
635
  it("should handle invalid publisher config", async () => {
@@ -630,11 +641,11 @@ describe("ProjectStore Service", () => {
630
641
  writeFileSync(publisherConfigPath, "invalid json");
631
642
 
632
643
  // Create a new project store that will read the invalid config
633
- const newProjectStore = new ProjectStore(serverRootPath);
644
+ const newEnvironmentStore = new EnvironmentStore(serverRootPath);
634
645
 
635
646
  // Test that the project store handles invalid JSON gracefully by falling back to empty config
636
- await newProjectStore.finishedInitialization;
637
- const projects = await newProjectStore.listProjects();
647
+ await newEnvironmentStore.finishedInitialization;
648
+ const projects = await newEnvironmentStore.listEnvironments();
638
649
  expect(projects).toEqual([]);
639
650
  });
640
651
 
@@ -648,7 +659,7 @@ describe("ProjectStore Service", () => {
648
659
  publisherConfigPath,
649
660
  JSON.stringify({
650
661
  frozenConfig: false,
651
- projects: [
662
+ environments: [
652
663
  {
653
664
  invalidKey1: "malloy-samples", // Invalid: should be "name"
654
665
  invalidKey2: [
@@ -671,11 +682,11 @@ describe("ProjectStore Service", () => {
671
682
  );
672
683
 
673
684
  // Create a new project store that will read the invalid config
674
- const newProjectStore = new ProjectStore(serverRootPath);
685
+ const newEnvironmentStore = new EnvironmentStore(serverRootPath);
675
686
 
676
687
  // Test that the project store handles invalid fields gracefully without crashing
677
- await newProjectStore.finishedInitialization;
678
- const projects = await newProjectStore.listProjects();
688
+ await newEnvironmentStore.finishedInitialization;
689
+ const projects = await newEnvironmentStore.listEnvironments();
679
690
 
680
691
  // Should not crash and should return empty array since invalid projects are filtered out
681
692
  expect(projects).toEqual([]);
@@ -701,7 +712,7 @@ describe("ProjectStore Service", () => {
701
712
  publisherConfigPath,
702
713
  JSON.stringify({
703
714
  frozenConfig: false,
704
- projects: [
715
+ environments: [
705
716
  {
706
717
  // Invalid project: missing "name" field
707
718
  packages: [
@@ -746,11 +757,11 @@ describe("ProjectStore Service", () => {
746
757
  );
747
758
 
748
759
  // Create a new project store that will read the config
749
- const newProjectStore = new ProjectStore(serverRootPath);
760
+ const newEnvironmentStore = new EnvironmentStore(serverRootPath);
750
761
 
751
762
  // Test that invalid projects are filtered out
752
- await newProjectStore.finishedInitialization;
753
- const projects = await newProjectStore.listProjects();
763
+ await newEnvironmentStore.finishedInitialization;
764
+ const projects = await newEnvironmentStore.listEnvironments();
754
765
 
755
766
  // Should only have the valid project
756
767
  expect(projects.length).toBe(1);
@@ -780,7 +791,7 @@ describe("ProjectStore Service", () => {
780
791
  publisherConfigPath,
781
792
  JSON.stringify({
782
793
  frozenConfig: false,
783
- projects: [
794
+ environments: [
784
795
  {
785
796
  name: projectName,
786
797
  packages: [
@@ -800,18 +811,18 @@ describe("ProjectStore Service", () => {
800
811
  }),
801
812
  );
802
813
 
803
- await projectStore.finishedInitialization;
814
+ await environmentStore.finishedInitialization;
804
815
 
805
816
  // Test concurrent access to the same project
806
817
  const promises = Array.from({ length: 5 }, () =>
807
- projectStore.getProject(projectName),
818
+ environmentStore.getEnvironment(projectName),
808
819
  );
809
820
 
810
821
  const projects = await Promise.all(promises);
811
822
 
812
823
  expect(projects).toHaveLength(5);
813
824
  projects.forEach((project) => {
814
- expect(project).toBeInstanceOf(Project);
825
+ expect(project).toBeInstanceOf(Environment);
815
826
  expect(project.metadata.name).toBe(projectName);
816
827
  });
817
828
  },
@@ -821,7 +832,7 @@ describe("ProjectStore Service", () => {
821
832
 
822
833
  describe("Project Service Error Recovery", () => {
823
834
  let sandbox: sinon.SinonSandbox;
824
- let projectStore: ProjectStore;
835
+ let environmentStore: EnvironmentStore;
825
836
  const serverRootPath = path.join(
826
837
  TEMP_DIR_PATH,
827
838
  "pathways-worker-publisher-error-recovery-test",
@@ -852,7 +863,7 @@ describe("Project Service Error Recovery", () => {
852
863
  }));
853
864
 
854
865
  // Create project store after mocking
855
- projectStore = new ProjectStore(serverRootPath);
866
+ environmentStore = new EnvironmentStore(serverRootPath);
856
867
  });
857
868
 
858
869
  afterEach(async () => {
@@ -872,7 +883,7 @@ describe("Project Service Error Recovery", () => {
872
883
  writeFileSync(
873
884
  publisherConfigPath,
874
885
  JSON.stringify({
875
- projects: [
886
+ environments: [
876
887
  {
877
888
  name: projectName,
878
889
  packages: [
@@ -890,7 +901,9 @@ describe("Project Service Error Recovery", () => {
890
901
  );
891
902
 
892
903
  // Test that the project store handles the missing directory
893
- await expect(projectStore.getProject(projectName)).rejects.toThrow();
904
+ await expect(
905
+ environmentStore.getEnvironment(projectName),
906
+ ).rejects.toThrow();
894
907
  });
895
908
 
896
909
  it(
@@ -923,7 +936,7 @@ describe("Project Service Error Recovery", () => {
923
936
  writeFileSync(
924
937
  publisherConfigPath,
925
938
  JSON.stringify({
926
- projects: [
939
+ environments: [
927
940
  {
928
941
  name: projectName,
929
942
  packages: [
@@ -939,8 +952,8 @@ describe("Project Service Error Recovery", () => {
939
952
 
940
953
  // Test that the project store handles corrupted connection files gracefully
941
954
  // (The current implementation loads the project even with corrupted connection files)
942
- const project = await projectStore.getProject(projectName);
943
- expect(project).toBeInstanceOf(Project);
955
+ const project = await environmentStore.getEnvironment(projectName);
956
+ expect(project).toBeInstanceOf(Environment);
944
957
  expect(project.metadata.name).toBe(projectName);
945
958
  },
946
959
  { timeout: 30000 },
@@ -974,7 +987,7 @@ describe("Project Service Error Recovery", () => {
974
987
  writeFileSync(
975
988
  publisherConfigPath,
976
989
  JSON.stringify({
977
- projects: [
990
+ environments: [
978
991
  {
979
992
  name: projectName,
980
993
  packages: [
@@ -989,17 +1002,18 @@ describe("Project Service Error Recovery", () => {
989
1002
  );
990
1003
 
991
1004
  // Get the project successfully
992
- const project = await projectStore.getProject(projectName);
993
- expect(project).toBeInstanceOf(Project);
1005
+ const project = await environmentStore.getEnvironment(projectName);
1006
+ expect(project).toBeInstanceOf(Environment);
994
1007
 
995
1008
  // Try to get a non-existent project
996
1009
  await expect(
997
- projectStore.getProject("non-existent"),
1010
+ environmentStore.getEnvironment("non-existent"),
998
1011
  ).rejects.toThrow();
999
1012
 
1000
1013
  // Verify the original project is still accessible
1001
- const projectAgain = await projectStore.getProject(projectName);
1002
- expect(projectAgain).toBeInstanceOf(Project);
1014
+ const projectAgain =
1015
+ await environmentStore.getEnvironment(projectName);
1016
+ expect(projectAgain).toBeInstanceOf(Environment);
1003
1017
  expect(projectAgain.metadata.name).toBe(projectName);
1004
1018
  },
1005
1019
  { timeout: 30000 },