@malloy-publisher/server 0.0.234 → 0.0.236

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 (318) hide show
  1. package/dist/app/api-doc.yaml +47 -17
  2. package/dist/app/assets/{EnvironmentPage-DTZQ4Gxc.js → EnvironmentPage-BsAnavYN.js} +1 -1
  3. package/dist/app/assets/{HomePage-C5mlDPXK.js → HomePage-CADE138j.js} +1 -1
  4. package/dist/app/assets/{LightMode-DGNmhG0u.js → LightMode-Cfh7KzN8.js} +1 -1
  5. package/dist/app/assets/{MainPage-CVL_wmP4.js → MainPage-CO3pRlnV.js} +1 -1
  6. package/dist/app/assets/{MaterializationsPage-DmzMBCpy.js → MaterializationsPage-p9YjkRXZ.js} +1 -1
  7. package/dist/app/assets/{ModelPage-Dbvf4QbB.js → ModelPage-C1OSTv-x.js} +1 -1
  8. package/dist/app/assets/{PackagePage-DxdHc2Qs.js → PackagePage-e4kN75YR.js} +1 -1
  9. package/dist/app/assets/{RouteError-OJdT4tCd.js → RouteError-CzbfOkng.js} +1 -1
  10. package/dist/app/assets/{ThemeEditorPage-Bk7s0KXY.js → ThemeEditorPage-CciagFTq.js} +1 -1
  11. package/dist/app/assets/{WorkbookPage-j_vCWdN3.js → WorkbookPage-DNWmkCXa.js} +1 -1
  12. package/dist/app/assets/{core-Rj_4rRnA.es-DoIfLxDJ.js → core-Rj_4rRnA.es-BZyvITuO.js} +1 -1
  13. package/dist/app/assets/{index-B_jKMR35.js → index-CH2AcDzc.js} +4 -4
  14. package/dist/app/assets/{index-hw-xn0X7.js → index-DQa463gC.js} +2 -2
  15. package/dist/app/assets/{index-DWIe_hK0.js → index-DQpV7MyA.js} +1 -1
  16. package/dist/app/assets/{index-BabP-V-S.js → index-DzaYbhnD.js} +1 -1
  17. package/dist/app/assets/{index-D-rDyK11.js → index-VBbcc8s6.js} +1 -1
  18. package/dist/app/index.html +1 -1
  19. package/dist/package_load_worker.mjs +8 -1
  20. package/dist/server.mjs +471 -54
  21. package/package.json +16 -13
  22. package/.eslintrc.json +0 -44
  23. package/.prettierignore +0 -1
  24. package/.prettierrc +0 -4
  25. package/build.ts +0 -97
  26. package/eslint.config.mjs +0 -76
  27. package/k6-tests/README.md +0 -144
  28. package/k6-tests/bun.lock +0 -797
  29. package/k6-tests/load-test/load-test-crud-connections.ts +0 -263
  30. package/k6-tests/load-test/load-test-crud-packages.ts +0 -461
  31. package/k6-tests/load-test/load-test-crud-projects.ts +0 -160
  32. package/k6-tests/load-test/load-test-crud.ts +0 -142
  33. package/k6-tests/load-test/load-test.ts +0 -784
  34. package/k6-tests/package.json +0 -27
  35. package/k6-tests/scripts/run-with-otel.sh +0 -50
  36. package/k6-tests/smoke-test/smoke-test.ts +0 -158
  37. package/k6-tests/tsconfig.json +0 -29
  38. package/k6-tests/utils/client_factory.ts +0 -128
  39. package/k6-tests/utils/common.ts +0 -489
  40. package/k6-tests/utils/logger.ts +0 -62
  41. package/k6-tests/utils/types.d.ts +0 -35
  42. package/malloy_mcp.dxt +0 -0
  43. package/publisher.config.example.bigquery.json +0 -33
  44. package/publisher.config.example.duckdb.json +0 -23
  45. package/publisher.config.json +0 -23
  46. package/scripts/bake-duckdb-extensions.js +0 -110
  47. package/src/config.spec.ts +0 -1535
  48. package/src/config.theme.spec.ts +0 -178
  49. package/src/config.ts +0 -1142
  50. package/src/constants.ts +0 -105
  51. package/src/controller/compile.controller.ts +0 -40
  52. package/src/controller/connection.controller.spec.ts +0 -849
  53. package/src/controller/connection.controller.ts +0 -901
  54. package/src/controller/database.controller.ts +0 -24
  55. package/src/controller/materialization.controller.spec.ts +0 -293
  56. package/src/controller/materialization.controller.ts +0 -319
  57. package/src/controller/model.controller.ts +0 -164
  58. package/src/controller/package.controller.spec.ts +0 -273
  59. package/src/controller/package.controller.ts +0 -306
  60. package/src/controller/query.controller.ts +0 -152
  61. package/src/controller/theme.controller.ts +0 -83
  62. package/src/controller/watch-mode.controller.ts +0 -243
  63. package/src/data_styles.ts +0 -71
  64. package/src/default-publisher.config.json +0 -23
  65. package/src/ducklake_version.spec.ts +0 -163
  66. package/src/ducklake_version.ts +0 -153
  67. package/src/errors.spec.ts +0 -119
  68. package/src/errors.ts +0 -237
  69. package/src/filter_deprecation.spec.ts +0 -64
  70. package/src/filter_deprecation.ts +0 -42
  71. package/src/health.spec.ts +0 -123
  72. package/src/health.ts +0 -233
  73. package/src/heap_check.spec.ts +0 -144
  74. package/src/heap_check.ts +0 -144
  75. package/src/instrumentation.ts +0 -214
  76. package/src/json_utils.spec.ts +0 -51
  77. package/src/json_utils.ts +0 -33
  78. package/src/logger.spec.ts +0 -210
  79. package/src/logger.ts +0 -251
  80. package/src/malloy_pin_prereqs.spec.ts +0 -25
  81. package/src/materialization_metrics.spec.ts +0 -169
  82. package/src/materialization_metrics.ts +0 -346
  83. package/src/mcp/error_messages.spec.ts +0 -35
  84. package/src/mcp/error_messages.ts +0 -183
  85. package/src/mcp/handler_utils.spec.ts +0 -108
  86. package/src/mcp/handler_utils.ts +0 -251
  87. package/src/mcp/mcp_constants.ts +0 -6
  88. package/src/mcp/query_envelope.spec.ts +0 -229
  89. package/src/mcp/query_envelope.ts +0 -240
  90. package/src/mcp/server.protocol.spec.ts +0 -250
  91. package/src/mcp/server.ts +0 -87
  92. package/src/mcp/skills/build_skills_bundle.spec.ts +0 -51
  93. package/src/mcp/skills/build_skills_bundle.ts +0 -176
  94. package/src/mcp/skills/skills_bundle.json +0 -1
  95. package/src/mcp/skills/skills_bundle.spec.ts +0 -171
  96. package/src/mcp/tool_response.spec.ts +0 -108
  97. package/src/mcp/tool_response.ts +0 -138
  98. package/src/mcp/tools/compile_tool.spec.ts +0 -315
  99. package/src/mcp/tools/compile_tool.ts +0 -208
  100. package/src/mcp/tools/docs_search/build_docs_index.ts +0 -132
  101. package/src/mcp/tools/docs_search/malloy_docs_index.json +0 -1
  102. package/src/mcp/tools/docs_search_tool.spec.ts +0 -32
  103. package/src/mcp/tools/docs_search_tool.ts +0 -128
  104. package/src/mcp/tools/embedding_index.spec.ts +0 -1236
  105. package/src/mcp/tools/embedding_index.ts +0 -808
  106. package/src/mcp/tools/execute_query_tool.spec.ts +0 -294
  107. package/src/mcp/tools/execute_query_tool.ts +0 -316
  108. package/src/mcp/tools/get_context_eval.ts +0 -275
  109. package/src/mcp/tools/get_context_tool.spec.ts +0 -592
  110. package/src/mcp/tools/get_context_tool.ts +0 -585
  111. package/src/mcp/tools/reload_package_tool.spec.ts +0 -232
  112. package/src/mcp/tools/reload_package_tool.ts +0 -132
  113. package/src/mcp_config.spec.ts +0 -919
  114. package/src/mcp_config.ts +0 -425
  115. package/src/oom_guards.integration.spec.ts +0 -269
  116. package/src/package_load/package_load_pool.spec.ts +0 -252
  117. package/src/package_load/package_load_pool.ts +0 -931
  118. package/src/package_load/package_load_worker.ts +0 -1034
  119. package/src/package_load/protocol.ts +0 -364
  120. package/src/package_load/rpc_wait_accountant.spec.ts +0 -109
  121. package/src/package_load/rpc_wait_accountant.ts +0 -76
  122. package/src/package_load_metrics.spec.ts +0 -114
  123. package/src/package_load_metrics.ts +0 -127
  124. package/src/path_safety.spec.ts +0 -158
  125. package/src/path_safety.ts +0 -146
  126. package/src/pg_helpers.spec.ts +0 -223
  127. package/src/pg_helpers.ts +0 -52
  128. package/src/query_cap_metrics.spec.ts +0 -89
  129. package/src/query_cap_metrics.ts +0 -116
  130. package/src/query_concurrency.spec.ts +0 -247
  131. package/src/query_concurrency.ts +0 -237
  132. package/src/query_metadata_metrics.ts +0 -49
  133. package/src/query_param_utils.ts +0 -29
  134. package/src/query_timeout.spec.ts +0 -224
  135. package/src/query_timeout.ts +0 -179
  136. package/src/runtime/publisher.js +0 -328
  137. package/src/server-old.ts +0 -988
  138. package/src/server.ts +0 -2059
  139. package/src/service/annotations.spec.ts +0 -118
  140. package/src/service/annotations.ts +0 -91
  141. package/src/service/authorize.spec.ts +0 -154
  142. package/src/service/authorize.ts +0 -498
  143. package/src/service/authorize_integration.spec.ts +0 -2041
  144. package/src/service/build_plan.spec.ts +0 -685
  145. package/src/service/build_plan.ts +0 -797
  146. package/src/service/compile_authorize.spec.ts +0 -85
  147. package/src/service/compile_fragment_techniques.spec.ts +0 -156
  148. package/src/service/connection.spec.ts +0 -2360
  149. package/src/service/connection.ts +0 -2187
  150. package/src/service/connection_config.spec.ts +0 -734
  151. package/src/service/connection_config.ts +0 -899
  152. package/src/service/connection_federation.spec.ts +0 -184
  153. package/src/service/connection_fingerprint.spec.ts +0 -102
  154. package/src/service/connection_service.spec.ts +0 -711
  155. package/src/service/connection_service.ts +0 -291
  156. package/src/service/cron_evaluator.spec.ts +0 -79
  157. package/src/service/cron_evaluator.ts +0 -105
  158. package/src/service/db_utils.spec.ts +0 -1085
  159. package/src/service/db_utils.ts +0 -1502
  160. package/src/service/duckdb_instance_isolation.spec.ts +0 -137
  161. package/src/service/ducklake_lazy_attach.spec.ts +0 -110
  162. package/src/service/embedding_provider.spec.ts +0 -329
  163. package/src/service/embedding_provider.ts +0 -236
  164. package/src/service/environment.ts +0 -2191
  165. package/src/service/environment_admission.spec.ts +0 -344
  166. package/src/service/environment_compile.spec.ts +0 -197
  167. package/src/service/environment_store.spec.ts +0 -2274
  168. package/src/service/environment_store.ts +0 -2434
  169. package/src/service/environment_store_anchoring.spec.ts +0 -107
  170. package/src/service/environment_store_clone.spec.ts +0 -350
  171. package/src/service/explore_visibility.spec.ts +0 -434
  172. package/src/service/exports_probe.spec.ts +0 -107
  173. package/src/service/extension_fetch_policy.spec.ts +0 -256
  174. package/src/service/filter.spec.ts +0 -458
  175. package/src/service/filter.ts +0 -341
  176. package/src/service/filter_bypass.spec.ts +0 -418
  177. package/src/service/filter_integration.spec.ts +0 -1004
  178. package/src/service/freshness.spec.ts +0 -183
  179. package/src/service/freshness.ts +0 -112
  180. package/src/service/gcs_s3_utils.ts +0 -427
  181. package/src/service/given.ts +0 -105
  182. package/src/service/givens_integration.spec.ts +0 -219
  183. package/src/service/manifest_loader.spec.ts +0 -189
  184. package/src/service/manifest_loader.ts +0 -156
  185. package/src/service/materialization_build_session.spec.ts +0 -435
  186. package/src/service/materialization_build_session.ts +0 -681
  187. package/src/service/materialization_config_validation.spec.ts +0 -99
  188. package/src/service/materialization_config_validation.ts +0 -120
  189. package/src/service/materialization_eligibility.spec.ts +0 -158
  190. package/src/service/materialization_eligibility.ts +0 -305
  191. package/src/service/materialization_schedule_surface.spec.ts +0 -256
  192. package/src/service/materialization_scheduler.spec.ts +0 -289
  193. package/src/service/materialization_scheduler.ts +0 -304
  194. package/src/service/materialization_serve_transform.spec.ts +0 -1003
  195. package/src/service/materialization_serve_transform.ts +0 -779
  196. package/src/service/materialization_service.spec.ts +0 -2373
  197. package/src/service/materialization_service.ts +0 -2342
  198. package/src/service/materialization_test_fixtures.ts +0 -249
  199. package/src/service/model.spec.ts +0 -1157
  200. package/src/service/model.ts +0 -3370
  201. package/src/service/model_limits.spec.ts +0 -209
  202. package/src/service/model_limits.ts +0 -131
  203. package/src/service/model_storage_serve.spec.ts +0 -193
  204. package/src/service/model_storage_serve_joins.spec.ts +0 -193
  205. package/src/service/package.spec.ts +0 -612
  206. package/src/service/package.ts +0 -1799
  207. package/src/service/package_manifest.spec.ts +0 -230
  208. package/src/service/package_manifest.ts +0 -241
  209. package/src/service/package_memory_governor.spec.ts +0 -173
  210. package/src/service/package_memory_governor.ts +0 -233
  211. package/src/service/package_quote_bound_tables.spec.ts +0 -171
  212. package/src/service/package_race.spec.ts +0 -208
  213. package/src/service/package_reload_safety.spec.ts +0 -193
  214. package/src/service/package_rollback.spec.ts +0 -190
  215. package/src/service/package_worker_path.spec.ts +0 -645
  216. package/src/service/path_injection.spec.ts +0 -39
  217. package/src/service/persist_annotation_validation.spec.ts +0 -89
  218. package/src/service/persist_annotation_validation.ts +0 -59
  219. package/src/service/persistence_policy.spec.ts +0 -374
  220. package/src/service/proxy.spec.ts +0 -414
  221. package/src/service/proxy.ts +0 -248
  222. package/src/service/query_boundary.spec.ts +0 -470
  223. package/src/service/query_metadata.spec.ts +0 -408
  224. package/src/service/query_metadata.ts +0 -492
  225. package/src/service/query_metadata_identity.spec.ts +0 -149
  226. package/src/service/query_text.spec.ts +0 -79
  227. package/src/service/query_text.ts +0 -43
  228. package/src/service/quoting.spec.ts +0 -135
  229. package/src/service/quoting.ts +0 -78
  230. package/src/service/resolve_environment.ts +0 -15
  231. package/src/service/restricted_mode.spec.ts +0 -299
  232. package/src/service/source_extraction.ts +0 -225
  233. package/src/service/theme_store.ts +0 -199
  234. package/src/storage/DatabaseInterface.ts +0 -198
  235. package/src/storage/StorageManager.ts +0 -113
  236. package/src/storage/duckdb/ConnectionRepository.ts +0 -143
  237. package/src/storage/duckdb/DuckDBConnection.ts +0 -123
  238. package/src/storage/duckdb/DuckDBRepository.ts +0 -208
  239. package/src/storage/duckdb/EnvironmentRepository.ts +0 -148
  240. package/src/storage/duckdb/MaterializationRepository.spec.ts +0 -191
  241. package/src/storage/duckdb/MaterializationRepository.ts +0 -336
  242. package/src/storage/duckdb/PackageRepository.ts +0 -135
  243. package/src/storage/duckdb/schema.ts +0 -229
  244. package/src/stream_helpers.spec.ts +0 -280
  245. package/src/stream_helpers.ts +0 -162
  246. package/src/telemetry.ts +0 -20
  247. package/src/test_helpers/metrics_harness.ts +0 -166
  248. package/src/theme_key_parity.spec.ts +0 -57
  249. package/src/utils.ts +0 -29
  250. package/tests/fixtures/authorize-compile/model.malloy +0 -9
  251. package/tests/fixtures/authorize-compile/publisher.json +0 -4
  252. package/tests/fixtures/html-pages-nopublic/model.malloy +0 -1
  253. package/tests/fixtures/html-pages-nopublic/publisher.json +0 -5
  254. package/tests/fixtures/html-pages-test/data.csv +0 -3
  255. package/tests/fixtures/html-pages-test/public/assets/app.css +0 -3
  256. package/tests/fixtures/html-pages-test/public/barehtml.html +0 -4
  257. package/tests/fixtures/html-pages-test/public/bodymeta.html +0 -8
  258. package/tests/fixtures/html-pages-test/public/data.json +0 -1
  259. package/tests/fixtures/html-pages-test/public/fitcomment.html +0 -11
  260. package/tests/fixtures/html-pages-test/public/index.html +0 -9
  261. package/tests/fixtures/html-pages-test/public/nohead.html +0 -8
  262. package/tests/fixtures/html-pages-test/public/notfit.html +0 -13
  263. package/tests/fixtures/html-pages-test/public/slides.html +0 -12
  264. package/tests/fixtures/html-pages-test/public/sub/page2.html +0 -9
  265. package/tests/fixtures/html-pages-test/public/unterminated.html +0 -10
  266. package/tests/fixtures/html-pages-test/publisher.json +0 -5
  267. package/tests/fixtures/html-pages-test/report.malloy +0 -1
  268. package/tests/fixtures/persist-multi-level/data/orders.csv +0 -5
  269. package/tests/fixtures/persist-multi-level/multi_level.malloy +0 -18
  270. package/tests/fixtures/persist-multi-level/publisher.json +0 -5
  271. package/tests/fixtures/persist-schedule-test/data/orders.csv +0 -5
  272. package/tests/fixtures/persist-schedule-test/persist_schedule_test.malloy +0 -11
  273. package/tests/fixtures/persist-schedule-test/publisher.json +0 -7
  274. package/tests/fixtures/persist-schedule-warn-test/data/orders.csv +0 -5
  275. package/tests/fixtures/persist-schedule-warn-test/persist_warn_test.malloy +0 -11
  276. package/tests/fixtures/persist-schedule-warn-test/publisher.json +0 -6
  277. package/tests/fixtures/persist-test/data/orders.csv +0 -5
  278. package/tests/fixtures/persist-test/persist_test.malloy +0 -11
  279. package/tests/fixtures/persist-test/publisher.json +0 -5
  280. package/tests/fixtures/publisher.config.json +0 -15
  281. package/tests/fixtures/query-givens/data/orders.csv +0 -7
  282. package/tests/fixtures/query-givens/model.malloy +0 -34
  283. package/tests/fixtures/query-givens/publisher.json +0 -5
  284. package/tests/fixtures/xlsx/database.xlsx +0 -0
  285. package/tests/harness/mcp_test_setup.ts +0 -332
  286. package/tests/harness/rest_e2e.ts +0 -68
  287. package/tests/integration/authorize/compile_authorize_http.integration.spec.ts +0 -92
  288. package/tests/integration/concurrent_package/concurrent_package.integration.spec.ts +0 -280
  289. package/tests/integration/duckdb_storage/duckdb_storage.integration.spec.ts +0 -138
  290. package/tests/integration/first_boot/readiness_line.integration.spec.ts +0 -177
  291. package/tests/integration/html_pages/html_pages.integration.spec.ts +0 -440
  292. package/tests/integration/legacy_routes/legacy_routes.integration.spec.ts +0 -259
  293. package/tests/integration/materialization/environment_list.integration.spec.ts +0 -133
  294. package/tests/integration/materialization/freshness_gate.integration.spec.ts +0 -292
  295. package/tests/integration/materialization/manifest_binding.integration.spec.ts +0 -430
  296. package/tests/integration/materialization/materialization_lifecycle.integration.spec.ts +0 -441
  297. package/tests/integration/materialization/orchestrated_rebind.integration.spec.ts +0 -150
  298. package/tests/integration/materialization/reference_manifest.integration.spec.ts +0 -251
  299. package/tests/integration/materialization/schedule_edit.integration.spec.ts +0 -126
  300. package/tests/integration/materialization/scheduler.integration.spec.ts +0 -200
  301. package/tests/integration/materialization/scheduler_recovery.integration.spec.ts +0 -172
  302. package/tests/integration/materialization/scheduler_transitions.integration.spec.ts +0 -256
  303. package/tests/integration/materialization/scheduler_wiring.integration.spec.ts +0 -143
  304. package/tests/integration/mcp/mcp_execute_query_tool.integration.spec.ts +0 -438
  305. package/tests/integration/mcp/mcp_get_context_semantic.integration.spec.ts +0 -235
  306. package/tests/integration/mcp/mcp_transport.integration.spec.ts +0 -98
  307. package/tests/integration/query_givens/query_givens.integration.spec.ts +0 -146
  308. package/tests/integration/query_givens/query_givens_authorize.integration.spec.ts +0 -121
  309. package/tests/integration/sdk_givens/sdk_givens.integration.spec.ts +0 -110
  310. package/tests/integration/watch-mode/watch_mode.integration.spec.ts +0 -421
  311. package/tests/unit/controller/theme.controller.spec.ts +0 -141
  312. package/tests/unit/duckdb/attached_databases.test.ts +0 -1243
  313. package/tests/unit/duckdb/duckdb_connection.test.ts +0 -181
  314. package/tests/unit/duckdb/legacy_schema_migration.test.ts +0 -197
  315. package/tests/unit/duckdb/repositories.test.ts +0 -208
  316. package/tests/unit/ducklake/ducklake.test.ts +0 -952
  317. package/tests/unit/service/theme_store.spec.ts +0 -139
  318. package/tsconfig.json +0 -32
@@ -1,98 +0,0 @@
1
- import { Client } from "@modelcontextprotocol/sdk/client/index.js";
2
- import {
3
- ErrorCode,
4
- Notification,
5
- Request,
6
- Result,
7
- } from "@modelcontextprotocol/sdk/types.js";
8
- import { afterAll, beforeAll, describe, expect, it } from "bun:test";
9
- import { URL } from "url";
10
-
11
- // --- Import E2E Test Setup ---
12
- import {
13
- cleanupE2ETestEnvironment,
14
- McpE2ETestEnvironment,
15
- setupE2ETestEnvironment,
16
- } from "../../harness/mcp_test_setup";
17
-
18
- // --- Test Suite ---
19
- // Note: These tests assume interaction via a standard MCP client.
20
- // Tests for raw HTTP edge cases (non-JSON, non-RPC) are omitted based on this assumption.
21
- describe.serial("MCP Transport Tests (E2E Integration)", () => {
22
- let env: McpE2ETestEnvironment | null = null;
23
- let mcpClient: Client<Request, Notification, Result>; // Convenience variable
24
-
25
- beforeAll(async () => {
26
- env = await setupE2ETestEnvironment();
27
- mcpClient = env.mcpClient;
28
- });
29
-
30
- afterAll(async () => {
31
- await cleanupE2ETestEnvironment(env);
32
- env = null;
33
- });
34
-
35
- describe("Basic Protocol", () => {
36
- it(
37
- "should handle a simple listTools request",
38
- async () => {
39
- if (!env) throw new Error("Test environment not initialized");
40
- const result = await mcpClient.listTools();
41
- // Assert based on actual successful response structure
42
- expect(result).toHaveProperty("tools");
43
- expect(Array.isArray(result.tools)).toBe(true);
44
- expect(
45
- result.tools.some((t) => t.name === "malloy_executeQuery"),
46
- ).toBe(true);
47
- },
48
- { timeout: 30000 },
49
- );
50
-
51
- it("should receive MethodNotFound error for unknown methods", async () => {
52
- if (!env) throw new Error("Test environment not initialized");
53
- expect.assertions(2); // Expecting error instance and specific code
54
- try {
55
- // Attempt to call a method that doesn't exist
56
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
57
- await (mcpClient as any).request({
58
- method: "nonexistent/method",
59
- params: {},
60
- });
61
- // Should not reach here
62
- throw new Error("Request should have failed");
63
- } catch (error) {
64
- expect(error).toBeInstanceOf(Error);
65
- // Check for the specific MethodNotFound error code
66
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
67
- expect((error as { code?: number }).code).toBe(
68
- ErrorCode.MethodNotFound,
69
- );
70
- }
71
- });
72
- });
73
-
74
- describe("Connection Management & Bridge Logic", () => {
75
- it("should return 405 Method Not Allowed for GET requests", async () => {
76
- if (!env) throw new Error("Test environment not initialized");
77
- const getUrl = new URL(`${env.serverUrl}/mcp`); // No session ID needed
78
- const response = await fetch(getUrl.toString(), {
79
- method: "GET",
80
- headers: { Accept: "text/event-stream" },
81
- });
82
- expect(response.status).toBe(405); // Expect Method Not Allowed
83
- const errorBody = await response.json();
84
- expect(errorBody.error.message).toContain("Method Not Allowed");
85
- });
86
-
87
- it("should return 405 Method Not Allowed for DELETE requests", async () => {
88
- if (!env) throw new Error("Test environment not initialized");
89
- const deleteUrl = new URL(`${env.serverUrl}/mcp`); // No session ID needed
90
- const response = await fetch(deleteUrl.toString(), {
91
- method: "DELETE",
92
- });
93
- expect(response.status).toBe(405); // Expect Method Not Allowed
94
- const errorBody = await response.json();
95
- expect(errorBody.error.message).toContain("Method Not Allowed");
96
- });
97
- });
98
- });
@@ -1,146 +0,0 @@
1
- /// <reference types="bun-types" />
2
-
3
- /**
4
- * HTTP E2E coverage for `given:` runtime parameters on POST .../query:
5
- * givens retarget query results, unknown/mistyped givens surface as 400 (not
6
- * 500), givens compose with filterParams, a `null` given value is an
7
- * explicit SQL-NULL override, and a numeric-string value is accepted for a
8
- * `number`-typed given (Malloy's own coercion). Malloy is the single validator:
9
- * an unknown name or bad value throws a `runtime-given-*` error that
10
- * model.ts maps to a 400 (see getQueryResults).
11
- */
12
-
13
- import { afterAll, beforeAll, describe, expect, it } from "bun:test";
14
- import path from "path";
15
- import { fileURLToPath } from "url";
16
- import { type RestE2EEnv, startRestE2E } from "../../harness/rest_e2e";
17
-
18
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
19
- const ENV_NAME = "query-givens-env";
20
- const PKG = "query-givens";
21
- const MODEL = "model.malloy";
22
-
23
- type Row = Record<string, unknown>;
24
-
25
- describe("givens forwarding on /query (HTTP E2E)", () => {
26
- let env: (RestE2EEnv & { stop(): Promise<void> }) | null = null;
27
- let baseUrl: string;
28
-
29
- beforeAll(async () => {
30
- env = await startRestE2E();
31
- baseUrl = env.baseUrl;
32
- const fixtureDir = path.resolve(__dirname, "../../fixtures/query-givens");
33
- const createRes = await fetch(`${baseUrl}/api/v0/environments`, {
34
- method: "POST",
35
- headers: { "Content-Type": "application/json" },
36
- body: JSON.stringify({
37
- name: ENV_NAME,
38
- packages: [{ name: PKG, location: fixtureDir }],
39
- connections: [],
40
- }),
41
- });
42
- if (!createRes.ok) {
43
- throw new Error(
44
- `Failed to create test environment (${createRes.status}): ${await createRes.text()}`,
45
- );
46
- }
47
- const deadline = Date.now() + 30_000;
48
- while (Date.now() < deadline) {
49
- const res = await fetch(
50
- `${baseUrl}/api/v0/environments/${ENV_NAME}/packages/${PKG}`,
51
- );
52
- if (res.ok) break;
53
- await new Promise((r) => setTimeout(r, 250));
54
- }
55
- });
56
-
57
- afterAll(async () => {
58
- await fetch(`${baseUrl}/api/v0/environments/${ENV_NAME}`, {
59
- method: "DELETE",
60
- }).catch(() => {});
61
- await env?.stop();
62
- });
63
-
64
- const query = (body: Record<string, unknown>) =>
65
- fetch(
66
- `${baseUrl}/api/v0/environments/${ENV_NAME}/packages/${PKG}/models/${MODEL}/query`,
67
- {
68
- method: "POST",
69
- headers: { "Content-Type": "application/json" },
70
- body: JSON.stringify({
71
- sourceName: "orders",
72
- queryName: "by_given_region",
73
- compactJson: true,
74
- ...body,
75
- }),
76
- },
77
- );
78
-
79
- async function rows(res: Response): Promise<Row[]> {
80
- expect(res.status).toBe(200);
81
- const body = (await res.json()) as { result: string };
82
- return JSON.parse(body.result) as Row[];
83
- }
84
-
85
- it("retargets rows via a given override (EU vs default US)", async () => {
86
- const res = await query({ givens: { target_region: "EU" } });
87
- const r = await rows(res);
88
- expect(r.length).toBe(1);
89
- expect(Number(r[0].order_count)).toBe(3);
90
- });
91
-
92
- it("returns 400 for an unknown given name, naming it in the message", async () => {
93
- // Malloy rejects the unknown name (`runtime-given-unknown`, with a
94
- // did-you-mean hint) at prepare time; model.ts maps that to a 400 and
95
- // forwards Malloy's message, which names the given.
96
- const res = await query({ givens: { NOtaGiven: 1 } });
97
- expect(res.status).toBe(400);
98
- const body = (await res.json()) as { message: string };
99
- expect(body.message).toContain("NOtaGiven");
100
- });
101
-
102
- it("returns 400 for a value-type mismatch on a number-typed given", async () => {
103
- // "min_amount" is declared `:: number`; a non-numeric string can't be
104
- // coerced, so Malloy rejects it at prepare time (`runtime-given-*`),
105
- // surfaced as a 400 via the run try/catch in model.ts, not a 500.
106
- const res = await query({ givens: { min_amount: "not-a-number" } });
107
- expect(res.status).toBe(400);
108
- });
109
-
110
- it("composes givens with filterParams", async () => {
111
- // target_region=EU narrows to ids 4,5,6; filterParams status=active
112
- // narrows further to ids 4,6 -> order_count=2.
113
- const res = await query({
114
- givens: { target_region: "EU" },
115
- filterParams: { status: "active" },
116
- });
117
- const r = await rows(res);
118
- expect(r.length).toBe(1);
119
- expect(Number(r[0].order_count)).toBe(2);
120
- });
121
-
122
- it("omitting givens entirely uses the declared defaults (US baseline)", async () => {
123
- const res = await query({});
124
- const r = await rows(res);
125
- expect(r.length).toBe(1);
126
- expect(Number(r[0].order_count)).toBe(3);
127
- });
128
-
129
- it("a null given value is an explicit SQL-NULL override", async () => {
130
- // `region = NULL` is never true in SQL, so this should return zero
131
- // matching rows rather than falling back to the 'US' default.
132
- const res = await query({ givens: { target_region: null } });
133
- const r = await rows(res);
134
- expect(r.length).toBe(1);
135
- expect(Number(r[0].order_count)).toBe(0);
136
- });
137
-
138
- it("accepts a numeric string for a number-typed given", async () => {
139
- // Guards against Malloy's numeric-string coercion for `number` givens
140
- // regressing; "5" should be accepted just like the literal 5.
141
- const res = await query({ givens: { min_amount: "5" } });
142
- const r = await rows(res);
143
- expect(r.length).toBe(1);
144
- expect(Number(r[0].order_count)).toBe(3);
145
- });
146
- });
@@ -1,121 +0,0 @@
1
- /// <reference types="bun-types" />
2
-
3
- /**
4
- * HTTP E2E for the givens × `#(authorize)` interaction. Malloy is the single
5
- * given validator, so on a GATED source a bad given (unknown NAME or wrong-typed
6
- * VALUE) is caught inside the authorize probe, which fails closed — surfacing as
7
- * a 403, not the 400 the ungated path returns. This suite pins that documented
8
- * asymmetry so it stays intentional:
9
- *
10
- * - unknown given name -> 403 (probe can't bind it -> fails closed)
11
- * - authorized + valid givens -> 200 (retargets rows)
12
- * - authorize denies -> 403
13
- * - valid name, BAD value -> 403 (probe can't evaluate it -> fails closed)
14
- *
15
- * On an UNGATED source the same unknown name / bad value are a clean 400 (Malloy
16
- * `runtime-given-*` mapped by model.ts) — see query_givens.integration.spec.ts.
17
- *
18
- * See packages/server/src/service/authorize.ts (evaluateAuthorize, fail-closed).
19
- */
20
-
21
- import { afterAll, beforeAll, describe, expect, it } from "bun:test";
22
- import path from "path";
23
- import { fileURLToPath } from "url";
24
- import { type RestE2EEnv, startRestE2E } from "../../harness/rest_e2e";
25
-
26
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
27
- const ENV_NAME = "query-givens-authz-env";
28
- const PKG = "query-givens";
29
- const MODEL = "model.malloy";
30
-
31
- type Row = Record<string, unknown>;
32
-
33
- describe("givens × authorize on /query (HTTP E2E)", () => {
34
- let env: (RestE2EEnv & { stop(): Promise<void> }) | null = null;
35
- let baseUrl: string;
36
-
37
- beforeAll(async () => {
38
- env = await startRestE2E();
39
- baseUrl = env.baseUrl;
40
- const fixtureDir = path.resolve(__dirname, "../../fixtures/query-givens");
41
- const createRes = await fetch(`${baseUrl}/api/v0/environments`, {
42
- method: "POST",
43
- headers: { "Content-Type": "application/json" },
44
- body: JSON.stringify({
45
- name: ENV_NAME,
46
- packages: [{ name: PKG, location: fixtureDir }],
47
- connections: [],
48
- }),
49
- });
50
- if (!createRes.ok) {
51
- throw new Error(
52
- `Failed to create test environment (${createRes.status}): ${await createRes.text()}`,
53
- );
54
- }
55
- const deadline = Date.now() + 30_000;
56
- while (Date.now() < deadline) {
57
- const res = await fetch(
58
- `${baseUrl}/api/v0/environments/${ENV_NAME}/packages/${PKG}`,
59
- );
60
- if (res.ok) break;
61
- await new Promise((r) => setTimeout(r, 250));
62
- }
63
- });
64
-
65
- afterAll(async () => {
66
- await fetch(`${baseUrl}/api/v0/environments/${ENV_NAME}`, {
67
- method: "DELETE",
68
- }).catch(() => {});
69
- await env?.stop();
70
- });
71
-
72
- const queryGated = (body: Record<string, unknown>) =>
73
- fetch(
74
- `${baseUrl}/api/v0/environments/${ENV_NAME}/packages/${PKG}/models/${MODEL}/query`,
75
- {
76
- method: "POST",
77
- headers: { "Content-Type": "application/json" },
78
- body: JSON.stringify({
79
- sourceName: "gated_orders",
80
- queryName: "by_given_region",
81
- compactJson: true,
82
- ...body,
83
- }),
84
- },
85
- );
86
-
87
- it("unknown given name -> 403 on a gated source (authorize probe fails closed)", async () => {
88
- // Even with role=admin, the unknown given makes the authorize probe throw
89
- // (`runtime-given-unknown`), which the gate treats as not-granting. On an
90
- // ungated source the same name is a clean 400 (see query_givens suite).
91
- const res = await queryGated({
92
- givens: { role: "admin", NOtaGiven: 1 },
93
- });
94
- expect(res.status).toBe(403);
95
- });
96
-
97
- it("authorized caller with valid givens -> 200 and retargets rows", async () => {
98
- const res = await queryGated({
99
- givens: { role: "admin", target_region: "EU" },
100
- });
101
- expect(res.status).toBe(200);
102
- const body = (await res.json()) as { result: string };
103
- const r = JSON.parse(body.result) as Row[];
104
- expect(Number(r[0].order_count)).toBe(3);
105
- });
106
-
107
- it("authorize deny (non-admin role) -> 403", async () => {
108
- const res = await queryGated({ givens: { role: "guest" } });
109
- expect(res.status).toBe(403);
110
- });
111
-
112
- it("valid given name with a bad value -> 403 on a gated source (fail-closed authorize)", async () => {
113
- // The authorize probe binds the supplied givens; a value it can't evaluate
114
- // makes the probe throw and the gate denies. On the UNGATED path the same
115
- // bad value is a 400 (Malloy at prepare time) — this asymmetry is by design.
116
- const res = await queryGated({
117
- givens: { role: "admin", min_amount: "not-a-number" },
118
- });
119
- expect(res.status).toBe(403);
120
- });
121
- });
@@ -1,110 +0,0 @@
1
- /// <reference types="bun-types" />
2
-
3
- /**
4
- * Proves the browser SDK (`packages/server/src/runtime/publisher.js`, served
5
- * at GET /sdk/publisher.js) actually puts `givens` on the wire: fetch the
6
- * served source, evaluate it in a sandboxed vm context standing in for
7
- * `window` (self === top, so the in-iframe/live-reload branches are
8
- * inert no-ops), and call `window.Publisher.query(...)` with a `givens`
9
- * override against the real HTTP server. Approach used: sandbox-eval via
10
- * Node's `vm` module — evaluating the actual runtime rather than just
11
- * grepping its source proves the SDK's fetch body really carries `givens`
12
- * end-to-end.
13
- */
14
-
15
- import { afterAll, beforeAll, describe, expect, it } from "bun:test";
16
- import path from "path";
17
- import { fileURLToPath } from "url";
18
- import vm from "vm";
19
- import { type RestE2EEnv, startRestE2E } from "../../harness/rest_e2e";
20
-
21
- const __dirname = path.dirname(fileURLToPath(import.meta.url));
22
- const ENV_NAME = "sdk-givens-env";
23
- const PKG = "query-givens";
24
- const MODEL = "model.malloy";
25
-
26
- type Row = Record<string, unknown>;
27
-
28
- describe("Publisher SDK forwards givens (sandbox-eval HTTP E2E)", () => {
29
- let env: (RestE2EEnv & { stop(): Promise<void> }) | null = null;
30
- let baseUrl: string;
31
-
32
- beforeAll(async () => {
33
- env = await startRestE2E();
34
- baseUrl = env.baseUrl;
35
- const fixtureDir = path.resolve(__dirname, "../../fixtures/query-givens");
36
- const createRes = await fetch(`${baseUrl}/api/v0/environments`, {
37
- method: "POST",
38
- headers: { "Content-Type": "application/json" },
39
- body: JSON.stringify({
40
- name: ENV_NAME,
41
- packages: [{ name: PKG, location: fixtureDir }],
42
- connections: [],
43
- }),
44
- });
45
- if (!createRes.ok) {
46
- throw new Error(
47
- `Failed to create test environment (${createRes.status}): ${await createRes.text()}`,
48
- );
49
- }
50
- const deadline = Date.now() + 30_000;
51
- while (Date.now() < deadline) {
52
- const res = await fetch(
53
- `${baseUrl}/api/v0/environments/${ENV_NAME}/packages/${PKG}`,
54
- );
55
- if (res.ok) break;
56
- await new Promise((r) => setTimeout(r, 250));
57
- }
58
- });
59
-
60
- afterAll(async () => {
61
- await fetch(`${baseUrl}/api/v0/environments/${ENV_NAME}`, {
62
- method: "DELETE",
63
- }).catch(() => {});
64
- await env?.stop();
65
- });
66
-
67
- it("Publisher.query() with a givens override reaches the server and retargets rows", async () => {
68
- const sdkRes = await fetch(`${baseUrl}/sdk/publisher.js`);
69
- expect(sdkRes.status).toBe(200);
70
- const sdkSource = await sdkRes.text();
71
-
72
- // Sandbox stands in for `window`. self === top so the runtime's
73
- // in-iframe (postMessage resize) and live-reload (EventSource) branches
74
- // are no-ops; document/EventSource are omitted since that code path
75
- // never runs for a non-embedded page.
76
- const sandbox: Record<string, unknown> = {
77
- fetch,
78
- location: {
79
- pathname: `/environments/${ENV_NAME}/packages/${PKG}/`,
80
- origin: baseUrl,
81
- },
82
- console,
83
- };
84
- sandbox.self = sandbox;
85
- sandbox.top = sandbox;
86
- sandbox.window = sandbox;
87
-
88
- const context = vm.createContext(sandbox);
89
- vm.runInContext(sdkSource, context, { filename: "publisher.js" });
90
-
91
- const publisher = (sandbox.window as { Publisher: unknown })
92
- .Publisher as {
93
- query: (
94
- modelPath: string,
95
- malloyQuery: string | undefined,
96
- opts: Record<string, unknown>,
97
- ) => Promise<Row[]>;
98
- };
99
- expect(publisher).toBeDefined();
100
-
101
- const rows = await publisher.query(MODEL, undefined, {
102
- sourceName: "orders",
103
- queryName: "by_given_region",
104
- givens: { target_region: "EU" },
105
- });
106
-
107
- expect(rows.length).toBe(1);
108
- expect(Number(rows[0].order_count)).toBe(3);
109
- });
110
- });