@malloy-publisher/server 0.2.5 → 0.2.7

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 (22) hide show
  1. package/dist/app/api-doc.yaml +30 -0
  2. package/dist/app/assets/{EnvironmentPage-BAegPFOF.js → EnvironmentPage-CKXJ6QGP.js} +1 -1
  3. package/dist/app/assets/{HomePage-DpDWLD0m.js → HomePage-DghEH50P.js} +1 -1
  4. package/dist/app/assets/{LightMode-CAFl4Cvr.js → LightMode-DzHSrjJH.js} +1 -1
  5. package/dist/app/assets/{MainPage-DBHZF__d.js → MainPage-Cj5zf5FO.js} +1 -1
  6. package/dist/app/assets/{MaterializationsPage-DS5Wrhkc.js → MaterializationsPage-BzNjmRO4.js} +1 -1
  7. package/dist/app/assets/{ModelPage-BE19OgP9.js → ModelPage-Dl4N2pr_.js} +1 -1
  8. package/dist/app/assets/{PackagePage-D5gz7Abx.js → PackagePage-C_e4oVtx.js} +1 -1
  9. package/dist/app/assets/{RouteError-BE1pcxrx.js → RouteError-DfNOfBXe.js} +1 -1
  10. package/dist/app/assets/{ThemeEditorPage-CiRxkL1D.js → ThemeEditorPage-CGkhNJr8.js} +1 -1
  11. package/dist/app/assets/{WorkbookPage-Czc9IG0b.js → WorkbookPage-WwPVhKNa.js} +1 -1
  12. package/dist/app/assets/{core-xdZbLgaF.es-BGrT15Sy.js → core-BY7vB5gN.es-BZH9lmb3.js} +1 -1
  13. package/dist/app/assets/{index-C22pKyUm.js → index-B07Dq5kA.js} +1 -1
  14. package/dist/app/assets/{index-DcYLvDJ2.js → index-BW-8erNY.js} +57 -57
  15. package/dist/app/assets/{index-73xxtSWr.js → index-Ca7nDqKT.js} +1 -1
  16. package/dist/app/assets/{index-BVkVGR63.js → index-Kff4bm9s.js} +1 -1
  17. package/dist/app/index.html +1 -1
  18. package/dist/package_load_worker.mjs +2905 -2876
  19. package/dist/runtime/publisher.js +60 -14
  20. package/dist/server.mjs +105 -37
  21. package/package.json +1 -1
  22. package/dist/sshcrypto-xqan60jb.node +0 -0
@@ -251,27 +251,73 @@
251
251
  var pad = parseFloat(bodyStyle.paddingBottom) || 0;
252
252
  return Math.ceil(maxBottom + scrollTop + pad);
253
253
  }
254
- function postSize() {
254
+ // Smallest SHRINK worth reporting. measureContentHeight already ceils,
255
+ // so nothing sub-pixel reaches here; what this absorbs is a 1-2px
256
+ // rounding flip-flop between two layout passes, which the host cannot
257
+ // act on without the resize itself becoming a layout change inside this
258
+ // frame — the feedback loop.
259
+ //
260
+ // Applied to shrinks ONLY, deliberately. A frame a few pixels too tall
261
+ // shows dead space; a few pixels too short CLIPS, and the frame has no
262
+ // internal scrollbar. The asymmetry also stops the two sides' bands
263
+ // compounding: the host runs its own epsilon against ITS height, which
264
+ // its MIN clamp guarantees can differ from lastHeight here, so two
265
+ // symmetric 8px bands leave a dead zone wider than either. Growing at
266
+ // 1px precision keeps the host's band the only one that applies.
267
+ var RESIZE_EPSILON = 8;
268
+ var resizePending = false;
269
+
270
+ function emitSize() {
255
271
  var h = measureContentHeight();
256
- if (h !== lastHeight) {
257
- lastHeight = h;
258
- try {
259
- window.parent.postMessage(
260
- { type: "publisher:resize", height: h },
261
- "*",
262
- );
263
- } catch (_e) {
264
- /* ignore */
265
- }
272
+ if (h < lastHeight && lastHeight - h < RESIZE_EPSILON) return;
273
+ if (h === lastHeight) return;
274
+ lastHeight = h;
275
+ try {
276
+ window.parent.postMessage(
277
+ { type: "publisher:resize", height: h },
278
+ "*",
279
+ );
280
+ } catch (_e) {
281
+ /* ignore */
266
282
  }
267
283
  }
284
+
285
+ // Coalesce a burst into one message per frame.
286
+ //
287
+ // ResizeObserver on documentElement fires on EVERY layout change, so a
288
+ // dashboard whose tiles resolve one by one used to post a height per
289
+ // tile. The host resized on each, which is what made an embedded app
290
+ // visibly jitter while it loaded. Same `pending`-flag idiom as the SSE
291
+ // reload debounce below; rAF rather than a timeout because the next
292
+ // paint is exactly when a coalesced layout is worth measuring.
293
+ //
294
+ // Trailing edge, not leading: the last measurement in a burst is the
295
+ // settled one, and reporting the first would send a stale height.
296
+ function postSize() {
297
+ if (resizePending) return;
298
+ resizePending = true;
299
+ var schedule =
300
+ typeof requestAnimationFrame === "function"
301
+ ? requestAnimationFrame
302
+ : function (fn) {
303
+ setTimeout(fn, 16);
304
+ };
305
+ schedule(function () {
306
+ resizePending = false;
307
+ emitSize();
308
+ });
309
+ }
268
310
  // Initial + observe content changes
311
+ // The first report goes out synchronously: the host shows a
312
+ // MIN_EMBED_HEIGHT placeholder until one arrives, so deferring it by a
313
+ // frame would leave a collapsed frame for no benefit. Only the bursts
314
+ // that follow need coalescing.
269
315
  if (document.readyState === "loading") {
270
- document.addEventListener("DOMContentLoaded", postSize);
316
+ document.addEventListener("DOMContentLoaded", emitSize);
271
317
  } else {
272
- postSize();
318
+ emitSize();
273
319
  }
274
- window.addEventListener("load", postSize);
320
+ window.addEventListener("load", emitSize);
275
321
  if (typeof ResizeObserver !== "undefined") {
276
322
  var ro = new ResizeObserver(postSize);
277
323
  // Observe documentElement so we catch any layout change
package/dist/server.mjs CHANGED
@@ -156437,7 +156437,7 @@ var BUNDLED_DEFAULT_CONFIG_PATH, PER_MODE_COLOR_KEYS, DEFAULT_HIGH_WATER_FRACTIO
156437
156437
  return false;
156438
156438
  }
156439
156439
  if (!conn.name || typeof conn.name !== "string") {
156440
- logger.warn(`Invalid connection: missing or invalid "name" field. Skipping.`, { connection: conn });
156440
+ logger.warn(`Invalid connection: missing or invalid "name" field. Skipping.`, { type: typeof conn.type === "string" ? conn.type : undefined });
156441
156441
  return false;
156442
156442
  }
156443
156443
  if (!conn.type || typeof conn.type !== "string") {
@@ -156461,13 +156461,13 @@ var BUNDLED_DEFAULT_CONFIG_PATH, PER_MODE_COLOR_KEYS, DEFAULT_HIGH_WATER_FRACTIO
156461
156461
  };
156462
156462
  }
156463
156463
  const validEnvironments = [];
156464
- for (const environment of rawConfig.environments) {
156464
+ for (const [index, environment] of rawConfig.environments.entries()) {
156465
156465
  if (!environment || typeof environment !== "object") {
156466
156466
  logger.warn(`Invalid environment in ${PUBLISHER_CONFIG_NAME}: entry must be an object. Skipping.`);
156467
156467
  continue;
156468
156468
  }
156469
156469
  if (!environment.name || typeof environment.name !== "string") {
156470
- logger.warn(`Invalid environment in ${PUBLISHER_CONFIG_NAME}: missing or invalid "name" field. Skipping entry.`, { environment });
156470
+ logger.warn(`Invalid environment in ${PUBLISHER_CONFIG_NAME}: missing or invalid "name" field. Skipping entry.`, { index });
156471
156471
  continue;
156472
156472
  }
156473
156473
  if (!Array.isArray(environment.packages)) {
@@ -156539,6 +156539,19 @@ var init_config = __esm(() => {
156539
156539
 
156540
156540
  // src/errors.ts
156541
156541
  import { MalloyError } from "@malloydata/malloy";
156542
+ function logInternalFailure(summary, error, level = "error") {
156543
+ const strip = (value) => value.replace(/[\u0000-\u001f\u007f-\u009f\u2028\u2029]/g, " ");
156544
+ const message = error.message ?? "";
156545
+ const stack = error.stack ?? "";
156546
+ const framesOnly = stack.startsWith(`${error.name}: ${message}`) ? stack.slice(`${error.name}: ${message}`.length).replace(/^\r?\n/, "") : stack;
156547
+ logger[level](summary, {
156548
+ error: {
156549
+ name: error.name,
156550
+ message: strip(message).slice(0, MAX_LOGGED_DETAIL_CHARS),
156551
+ stack: strip(framesOnly).slice(0, MAX_LOGGED_DETAIL_CHARS)
156552
+ }
156553
+ });
156554
+ }
156542
156555
  function internalErrorToHttpError(error) {
156543
156556
  if (error instanceof BadRequestError) {
156544
156557
  return httpError(400, error.message);
@@ -156558,6 +156571,8 @@ function internalErrorToHttpError(error) {
156558
156571
  return httpError(404, error.message);
156559
156572
  } else if (error instanceof MalloyError) {
156560
156573
  return httpError(400, error.message);
156574
+ } else if (error instanceof TableNotFoundError) {
156575
+ return httpError(404, error.message, "TABLE_NOT_FOUND");
156561
156576
  } else if (error instanceof ConnectionNotFoundError) {
156562
156577
  return httpError(404, error.message);
156563
156578
  } else if (error instanceof DestinationNotFoundError) {
@@ -156571,7 +156586,11 @@ function internalErrorToHttpError(error) {
156571
156586
  } else if (error instanceof ModelCompilationError) {
156572
156587
  return httpError(424, error.message);
156573
156588
  } else if (error instanceof ConnectionError) {
156574
- return httpError(502, error.message);
156589
+ if (error.callerSafe) {
156590
+ return httpError(502, error.message);
156591
+ }
156592
+ logInternalFailure("Upstream connection error", error, "warn");
156593
+ return httpError(502, GENERIC_UPSTREAM_MESSAGE);
156575
156594
  } else if (error instanceof MaterializationNotFoundError) {
156576
156595
  return httpError(404, error.message);
156577
156596
  } else if (error instanceof MaterializationConflictError) {
@@ -156587,21 +156606,24 @@ function internalErrorToHttpError(error) {
156587
156606
  } else if (error instanceof NotImplementedError) {
156588
156607
  return httpError(501, error.message);
156589
156608
  } else {
156590
- return httpError(500, error.message);
156609
+ logInternalFailure("Unhandled internal error", error);
156610
+ return httpError(500, GENERIC_INTERNAL_MESSAGE);
156591
156611
  }
156592
156612
  }
156593
- function httpError(code, message) {
156613
+ function httpError(code, message, reason) {
156594
156614
  return {
156595
156615
  status: code,
156596
156616
  json: {
156597
156617
  code,
156598
- message
156618
+ message,
156619
+ ...reason ? { reason } : {}
156599
156620
  }
156600
156621
  };
156601
156622
  }
156602
- var NotImplementedError, BadRequestError, InvalidArgumentError, EnvironmentNotFoundError, PackageNotFoundError, ModelNotFoundError, DashboardNotFoundError, ConnectionNotFoundError, ConnectionError, DestinationNotFoundError, ConnectionAuthError, UnsupportedCatalogFormatError, ModelCompilationError, MaterializationEligibilityError, PublisherConfigError, FrozenConfigError, AccessDeniedError, NotQueryableError, MaterializationNotFoundError, MaterializationConflictError, InvalidStateTransitionError, ServiceUnavailableError, PayloadTooLargeError, ResponseUnserializableError, QueryTimeoutError;
156623
+ var GENERIC_INTERNAL_MESSAGE = "Internal server error.", GENERIC_UPSTREAM_MESSAGE = "Upstream connection error.", MAX_LOGGED_DETAIL_CHARS = 2000, NotImplementedError, BadRequestError, InvalidArgumentError, EnvironmentNotFoundError, PackageNotFoundError, ModelNotFoundError, DashboardNotFoundError, ConnectionNotFoundError, TableNotFoundError, ConnectionError, DestinationNotFoundError, ConnectionAuthError, UnsupportedCatalogFormatError, ModelCompilationError, MaterializationEligibilityError, PublisherConfigError, FrozenConfigError, AccessDeniedError, NotQueryableError, MaterializationNotFoundError, MaterializationConflictError, InvalidStateTransitionError, ServiceUnavailableError, PayloadTooLargeError, ResponseUnserializableError, QueryTimeoutError;
156603
156624
  var init_errors = __esm(() => {
156604
156625
  init_constants();
156626
+ init_logger();
156605
156627
  NotImplementedError = class NotImplementedError extends Error {
156606
156628
  constructor(message) {
156607
156629
  super(message);
@@ -156639,11 +156661,18 @@ var init_errors = __esm(() => {
156639
156661
  super(message);
156640
156662
  }
156641
156663
  };
156642
- ConnectionError = class ConnectionError extends Error {
156664
+ TableNotFoundError = class TableNotFoundError extends Error {
156643
156665
  constructor(message) {
156644
156666
  super(message);
156645
156667
  }
156646
156668
  };
156669
+ ConnectionError = class ConnectionError extends Error {
156670
+ callerSafe;
156671
+ constructor(message, options) {
156672
+ super(message);
156673
+ this.callerSafe = options?.callerSafe ?? false;
156674
+ }
156675
+ };
156647
156676
  DestinationNotFoundError = class DestinationNotFoundError extends Error {
156648
156677
  constructor(message) {
156649
156678
  super(message);
@@ -213209,11 +213238,6 @@ var require_utils74 = __commonJS((exports, module) => {
213209
213238
  };
213210
213239
  });
213211
213240
 
213212
- // ../../node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
213213
- var require_sshcrypto = __commonJS((exports, module) => {
213214
- module.exports = __require("./sshcrypto-xqan60jb.node");
213215
- });
213216
-
213217
213241
  // ../../node_modules/ssh2/lib/protocol/crypto/poly1305.js
213218
213242
  var require_poly1305 = __commonJS((exports, module) => {
213219
213243
  var __dirname = "/home/runner/work/publisher/publisher/node_modules/ssh2/lib/protocol/crypto", __filename = "/home/runner/work/publisher/publisher/node_modules/ssh2/lib/protocol/crypto/poly1305.js";
@@ -213700,7 +213724,7 @@ var require_crypto = __commonJS((exports, module) => {
213700
213724
  var ChaChaPolyDecipher;
213701
213725
  var GenericDecipher;
213702
213726
  try {
213703
- binding = require_sshcrypto();
213727
+ binding = (()=>{throw new Error("Cannot require module "+"./crypto/build/Release/sshcrypto.node");})();
213704
213728
  ({
213705
213729
  AESGCMCipher,
213706
213730
  ChaChaPolyCipher,
@@ -234644,14 +234668,14 @@ var init_connection = __esm(() => {
234644
234668
  });
234645
234669
  const result2 = await super.fetchTableSchema(tableKey, azureUrl);
234646
234670
  if (!result2) {
234647
- throw new Error(`Azure file not found: ${azureUrl}`);
234671
+ throw new TableNotFoundError(`Azure file not found: ${azureUrl}`);
234648
234672
  }
234649
234673
  return result2;
234650
234674
  }
234651
234675
  }
234652
234676
  const result = await super.fetchTableSchema(tableKey, tablePath);
234653
234677
  if (!result) {
234654
- throw new Error(`Table ${tablePath} not found`);
234678
+ throw new TableNotFoundError(`Table ${tablePath} not found`);
234655
234679
  }
234656
234680
  return result;
234657
234681
  }
@@ -234703,13 +234727,13 @@ var init_connection = __esm(() => {
234703
234727
  });
234704
234728
  const result2 = await super.fetchTableSchema(tableKey, prefixedPath);
234705
234729
  if (!result2) {
234706
- throw new Error(`Table ${prefixedPath} not found in connection ${this.connectionName}`);
234730
+ throw new TableNotFoundError(`Table ${prefixedPath} not found in connection ${this.connectionName}`);
234707
234731
  }
234708
234732
  return result2;
234709
234733
  }
234710
234734
  const result = await super.fetchTableSchema(tableKey, tablePath);
234711
234735
  if (!result) {
234712
- throw new Error(`Table ${tablePath} not found in connection ${this.connectionName}`);
234736
+ throw new TableNotFoundError(`Table ${tablePath} not found in connection ${this.connectionName}`);
234713
234737
  }
234714
234738
  return result;
234715
234739
  }
@@ -254132,7 +254156,7 @@ function hydrateMarkdownOnlyCells(notebookCells) {
254132
254156
  return { type: "code", text: sc.text };
254133
254157
  });
254134
254158
  }
254135
- var MALLOY_VERSION, REQUEST_CHAIN_MAX_NAMES = 64, Model;
254159
+ var MALLOY_VERSION, REQUEST_CHAIN_MAX_NAMES = 64, NO_PREAGGREGATE_VIOLATIONS, Model;
254136
254160
  var init_model = __esm(() => {
254137
254161
  init_telemetry();
254138
254162
  init_materialization_metrics();
@@ -254168,6 +254192,7 @@ var init_model = __esm(() => {
254168
254192
  init_authorize_metrics();
254169
254193
  init_path_safety();
254170
254194
  MALLOY_VERSION = createRequire2(import.meta.url)("@malloydata/malloy/package.json").version;
254195
+ NO_PREAGGREGATE_VIOLATIONS = Object.freeze([]);
254171
254196
  Model = class Model {
254172
254197
  packageName;
254173
254198
  modelPath;
@@ -254191,6 +254216,7 @@ var init_model = __esm(() => {
254191
254216
  givens;
254192
254217
  declaredQueryMetadataMemo;
254193
254218
  declaredSourceQueryMetadataMemo;
254219
+ preaggregateViolationsMemo;
254194
254220
  authorizeReferencedGivenNames = new Set;
254195
254221
  discoveryCurationEnabled = false;
254196
254222
  queryBoundary = { mode: "all", exploresDeclared: false, isQueryEntryPoint: true };
@@ -255140,8 +255166,11 @@ var init_model = __esm(() => {
255140
255166
  }
255141
255167
  preaggregateViolations() {
255142
255168
  if (!this.modelDef)
255143
- return [];
255144
- return validateModelPreaggregation(this.modelDef.contents);
255169
+ return NO_PREAGGREGATE_VIOLATIONS;
255170
+ if (this.preaggregateViolationsMemo === undefined) {
255171
+ this.preaggregateViolationsMemo = validateModelPreaggregation(this.modelDef.contents);
255172
+ }
255173
+ return this.preaggregateViolationsMemo;
255145
255174
  }
255146
255175
  async buildPreaggregateServeModel(packagePath, malloyConfig, buildManifest) {
255147
255176
  this.preaggregateServeMaterializer = undefined;
@@ -277549,6 +277578,26 @@ function validateAdminAuthoredConnection(connectionName, connectionConfig) {
277549
277578
  }
277550
277579
  }
277551
277580
  }
277581
+ var BIGQUERY_NOT_FOUND = /^Not found: (Table|Dataset)\b/;
277582
+ var BIGQUERY_IMPROPER_PATH = /^Improper table path\b/;
277583
+ var DUCKDB_TABLE_NOT_FOUND = /^Catalog Error: Table with name .+ does not exist/;
277584
+ var DUCKDB_CATALOG_NOT_FOUND = /^Binder Error: Catalog .+ does not exist/;
277585
+ function driverErrorToPublisherError(message) {
277586
+ if (BIGQUERY_NOT_FOUND.test(message) || DUCKDB_TABLE_NOT_FOUND.test(message) || DUCKDB_CATALOG_NOT_FOUND.test(message)) {
277587
+ return new TableNotFoundError(message);
277588
+ }
277589
+ if (BIGQUERY_IMPROPER_PATH.test(message)) {
277590
+ return new InvalidArgumentError(message);
277591
+ }
277592
+ return new ConnectionError(message);
277593
+ }
277594
+ function classifyDriverFailure(error) {
277595
+ if (error instanceof TableNotFoundError || error instanceof InvalidArgumentError) {
277596
+ return error;
277597
+ }
277598
+ const message = error instanceof Error ? error.message : typeof error === "string" ? error : JSON.stringify(error);
277599
+ return driverErrorToPublisherError(message);
277600
+ }
277552
277601
 
277553
277602
  class ConnectionController {
277554
277603
  environmentStore;
@@ -277601,7 +277650,9 @@ class ConnectionController {
277601
277650
  if (packages.length === 1) {
277602
277651
  const onlyPackage = packages[0].name;
277603
277652
  if (!onlyPackage) {
277604
- throw new ConnectionError("Package name is undefined");
277653
+ throw new ConnectionError("Package name is undefined", {
277654
+ callerSafe: true
277655
+ });
277605
277656
  }
277606
277657
  const pkg = await environment.getPackage(onlyPackage);
277607
277658
  return await pkg.getMalloyConnection(connectionName);
@@ -277615,10 +277666,10 @@ class ConnectionController {
277615
277666
  try {
277616
277667
  const source = await malloyConnection.fetchTableSchema(tableKey, tablePath);
277617
277668
  if (!source) {
277618
- throw new ConnectionError(`Table ${tablePath} not found`);
277669
+ throw new TableNotFoundError(`Table ${tablePath} not found`);
277619
277670
  }
277620
277671
  if (typeof source === "string") {
277621
- throw new ConnectionError(source);
277672
+ throw driverErrorToPublisherError(source);
277622
277673
  }
277623
277674
  return {
277624
277675
  source: JSON.stringify(source),
@@ -277629,13 +277680,21 @@ class ConnectionController {
277629
277680
  }))
277630
277681
  };
277631
277682
  } catch (error) {
277632
- const errorMessage = error instanceof Error ? error.message : typeof error === "string" ? error : JSON.stringify(error);
277683
+ const classified = classifyDriverFailure(error);
277684
+ if (!(classified instanceof ConnectionError)) {
277685
+ logger.warn("table not resolvable", {
277686
+ tableKey,
277687
+ tablePath,
277688
+ reason: classified.constructor.name
277689
+ });
277690
+ throw classified;
277691
+ }
277633
277692
  logger.error("fetchTableSchema error", {
277634
277693
  error,
277635
277694
  tableKey,
277636
277695
  tablePath
277637
277696
  });
277638
- throw new ConnectionError(errorMessage);
277697
+ throw classified;
277639
277698
  }
277640
277699
  }
277641
277700
  async getConnection(environmentName, connectionName) {
@@ -277669,13 +277728,13 @@ class ConnectionController {
277669
277728
  selectStr: sqlStatement
277670
277729
  });
277671
277730
  if (typeof schema === "string") {
277672
- throw new ConnectionError(schema);
277731
+ throw driverErrorToPublisherError(schema);
277673
277732
  }
277674
277733
  return {
277675
277734
  source: JSON.stringify(schema)
277676
277735
  };
277677
277736
  } catch (error) {
277678
- throw new ConnectionError(error.message);
277737
+ throw classifyDriverFailure(error);
277679
277738
  }
277680
277739
  }
277681
277740
  async getTable(environmentName, connectionName, schemaName, tablePath, packageName) {
@@ -278152,6 +278211,7 @@ init_errors();
278152
278211
  import { MalloyError as MalloyError2 } from "@malloydata/malloy";
278153
278212
 
278154
278213
  // src/mcp/error_messages.ts
278214
+ init_errors();
278155
278215
  function getNotFoundError(resourceUriOrContext) {
278156
278216
  const baseMessage = `Resource not found: ${resourceUriOrContext}`;
278157
278217
  const suggestions = [
@@ -278165,13 +278225,21 @@ function getNotFoundError(resourceUriOrContext) {
278165
278225
  }
278166
278226
  function getInternalError(operation, error) {
278167
278227
  const baseMessage = `An unexpected internal error occurred during ${operation}.`;
278228
+ const suggestions = [
278229
+ "Try the request again later.",
278230
+ "If the problem persists, check server logs or contact support."
278231
+ ];
278232
+ if (error instanceof ConnectionError && !error.callerSafe) {
278233
+ logInternalFailure(`Upstream connection error during ${operation}`, error, "warn");
278234
+ return {
278235
+ message: `${baseMessage}: Upstream connection error.`,
278236
+ suggestions
278237
+ };
278238
+ }
278168
278239
  const errorMessage = error instanceof Error ? error.message : String(error);
278169
278240
  return {
278170
278241
  message: error ? `${baseMessage}: ${errorMessage}` : baseMessage,
278171
- suggestions: [
278172
- "Try the request again later.",
278173
- "If the problem persists, check server logs or contact support."
278174
- ]
278242
+ suggestions
278175
278243
  };
278176
278244
  }
278177
278245
  var RESTRICTED_CONSTRUCTS = "raw SQL (duckdb.sql(...) / connection.sql(...)), direct SQL function calls (name!type(...)), the sql_* function family (sql_number, sql_string, sql_date, sql_timestamp, sql_boolean), import statements, ##! flags, or new sources from connection.table(...)";
@@ -292431,8 +292499,8 @@ class WatchModeController {
292431
292499
  assertSafePackageName(watchName);
292432
292500
  } catch (error) {
292433
292501
  logger.error(error);
292434
- const { status } = internalErrorToHttpError(error);
292435
- res.status(status).json({ error: error.message });
292502
+ const { status, json } = internalErrorToHttpError(error);
292503
+ res.status(status).json({ error: json.message });
292436
292504
  return;
292437
292505
  }
292438
292506
  const environmentManifest = await EnvironmentStore.reloadEnvironmentManifest(this.environmentStore.serverRootPath);
@@ -292447,8 +292515,8 @@ class WatchModeController {
292447
292515
  await this.ensureWatching(watchName);
292448
292516
  } catch (error) {
292449
292517
  logger.error(error);
292450
- const { status } = internalErrorToHttpError(error);
292451
- res.status(status).json({ error: error.message });
292518
+ const { status, json } = internalErrorToHttpError(error);
292519
+ res.status(status).json({ error: json.message });
292452
292520
  return;
292453
292521
  }
292454
292522
  res.json();
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@malloy-publisher/server",
3
3
  "description": "Malloy Publisher Server",
4
- "version": "0.2.5",
4
+ "version": "0.2.7",
5
5
  "main": "dist/server.mjs",
6
6
  "bin": {
7
7
  "malloy-publisher": "dist/server.mjs"
Binary file