@malloy-publisher/server 0.8.5 → 0.9.1

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 (25) hide show
  1. package/README.docker.md +86 -2
  2. package/dist/app/api-doc.yaml +17 -1
  3. package/dist/app/assets/{EnvironmentPage-D0689eMH.js → EnvironmentPage-UMS7Py4Q.js} +1 -1
  4. package/dist/app/assets/{HomePage-CQwxmRju.js → HomePage-D3MvQaZn.js} +1 -1
  5. package/dist/app/assets/{LightMode-DzUuDGQu.js → LightMode-e1lNBfpL.js} +1 -1
  6. package/dist/app/assets/{MainPage-CWebuoie.js → MainPage-B0ozqtQO.js} +1 -1
  7. package/dist/app/assets/{ModelPage-DddcQtR_.js → ModelPage-lQj4Axqu.js} +2 -2
  8. package/dist/app/assets/{PackagePage-B_6x-Kp1.js → PackagePage-BT0YKNKU.js} +1 -1
  9. package/dist/app/assets/{RenderedResult-BRgIgxWh.es-B6GsiQaB.js → RenderedResult-BRgIgxWh.es-DiE7kPNX.js} +2 -2
  10. package/dist/app/assets/{RouteError-D85c0IXR.js → RouteError-BQnzPJvb.js} +1 -1
  11. package/dist/app/assets/{ThemeEditorPage-DPFZnuXS.js → ThemeEditorPage-D6t7w9Js.js} +1 -1
  12. package/dist/app/assets/{ToggleButtonGroup-B2KkD7kC.js → ToggleButtonGroup-CJT2JKTC.js} +1 -1
  13. package/dist/app/assets/index-ByieDZlo.js +23 -0
  14. package/dist/app/assets/{index-BbrJd6fQ.js → index-CCNqF0-G.js} +1 -1
  15. package/dist/app/assets/{index-125-Lr5Z.js → index-CKmZ4HG7.js} +388 -388
  16. package/dist/app/assets/{index-mS-LEGFh.js → index-CdExa3Pk.js} +1 -1
  17. package/dist/app/assets/{index-BSBGZfIc.js → index-TiWjmdoW.js} +4 -4
  18. package/dist/app/assets/{index-DSoCUF-f.js → index-ireHUsv_.js} +419 -422
  19. package/dist/app/assets/{index-BK_RS5eN.js → index-ufFZR_K-.js} +1 -1
  20. package/dist/app/assets/{index.es-Dixkq2YH.js → index.es-iUV0gCYk.js} +4 -4
  21. package/dist/app/index.html +1 -1
  22. package/dist/package_load_worker.mjs +147 -118
  23. package/dist/server.mjs +742 -915
  24. package/package.json +14 -14
  25. package/dist/app/assets/index-w_0OQJgZ.js +0 -23
@@ -13058,9 +13058,54 @@ function logInternalFailure(summary, error, level = "error") {
13058
13058
  }
13059
13059
  });
13060
13060
  }
13061
- function internalErrorToHttpError(error) {
13061
+ function filesystemAccessFailure(error) {
13062
+ let current = error;
13063
+ for (let depth = 0;depth < 8 && current instanceof Error; depth++) {
13064
+ const errno = current;
13065
+ if (typeof errno.code === "string" && errno.code in FILESYSTEM_ACCESS_DESCRIPTIONS && typeof errno.syscall === "string") {
13066
+ return errno;
13067
+ }
13068
+ current = errno.cause;
13069
+ }
13070
+ return;
13071
+ }
13072
+ function describeFilesystemAccessFailure(errno) {
13073
+ const code = errno.code ?? "";
13074
+ const target = errno.path ? ` '${errno.path}'` : "";
13075
+ return `${code}: ${FILESYSTEM_ACCESS_DESCRIPTIONS[code] ?? code}, ${errno.syscall}${target}`;
13076
+ }
13077
+ function messageWithFilesystemCause(error) {
13078
+ const message = error instanceof Error ? error.message : String(error);
13079
+ const access = filesystemAccessFailure(error);
13080
+ if (!access || message.includes(access.code ?? ""))
13081
+ return message;
13082
+ return `${message}: ${describeFilesystemAccessFailure(access)}`;
13083
+ }
13084
+ function errnoWireFields(error) {
13085
+ const { code, syscall, path } = error;
13086
+ if (typeof code !== "string")
13087
+ return;
13088
+ return {
13089
+ code,
13090
+ ...typeof syscall === "string" ? { syscall } : {},
13091
+ ...typeof path === "string" ? { path } : {}
13092
+ };
13093
+ }
13094
+ function internalErrorToHttpError(error, { log = true } = {}) {
13095
+ const logInternal = (...args) => {
13096
+ if (log)
13097
+ logInternalFailure(...args);
13098
+ };
13099
+ const access = filesystemAccessFailure(error);
13100
+ if (access) {
13101
+ logInternal("Filesystem access refused", error, "warn");
13102
+ return httpError(500, `The server cannot access a path it needs (${describeFilesystemAccessFailure(access)}). ` + `Give the user the server runs as access to it.`);
13103
+ }
13062
13104
  if (error instanceof BadRequestError) {
13063
13105
  return httpError(400, error.message);
13106
+ } else if (error instanceof ServerConfigurationError) {
13107
+ logInternal("Server configuration error", error, "warn");
13108
+ return httpError(500, error.message);
13064
13109
  } else if (error instanceof FrozenConfigError) {
13065
13110
  return httpError(403, error.message);
13066
13111
  } else if (error instanceof AccessDeniedError) {
@@ -13106,7 +13151,7 @@ function internalErrorToHttpError(error) {
13106
13151
  if (error.callerSafe) {
13107
13152
  return httpError(502, error.message);
13108
13153
  }
13109
- logInternalFailure("Upstream connection error", error, "warn");
13154
+ logInternal("Upstream connection error", error, "warn");
13110
13155
  return httpError(502, GENERIC_UPSTREAM_MESSAGE);
13111
13156
  } else if (error instanceof MaterializationNotFoundError) {
13112
13157
  return httpError(404, error.message);
@@ -13117,7 +13162,7 @@ function internalErrorToHttpError(error) {
13117
13162
  } else if (error instanceof WriteConflictError) {
13118
13163
  return httpError(409, error.message);
13119
13164
  } else if (error instanceof WriteRolledBackError) {
13120
- logInternalFailure("Dashboard write rolled back", error, "warn");
13165
+ logInternal("Dashboard write rolled back", error, "warn");
13121
13166
  return httpError(500, error.message);
13122
13167
  } else if (error instanceof ServiceUnavailableError) {
13123
13168
  return httpError(503, error.message);
@@ -13128,7 +13173,7 @@ function internalErrorToHttpError(error) {
13128
13173
  } else if (error instanceof NotImplementedError) {
13129
13174
  return httpError(501, error.message);
13130
13175
  } else {
13131
- logInternalFailure("Unhandled internal error", error);
13176
+ logInternal("Unhandled internal error", error);
13132
13177
  return httpError(500, GENERIC_INTERNAL_MESSAGE);
13133
13178
  }
13134
13179
  }
@@ -13150,10 +13195,15 @@ function toQueryTextProblem(problem) {
13150
13195
  ...problem.at ? { at: { range: problem.at.range } } : {}
13151
13196
  };
13152
13197
  }
13153
- var GENERIC_INTERNAL_MESSAGE = "Internal server error.", GENERIC_UPSTREAM_MESSAGE = "Upstream connection error.", MAX_LOGGED_DETAIL_CHARS = 2000, NotImplementedError, BadRequestError, InvalidArgumentError, CompileRefusedError, EnvironmentNotFoundError, PackageNotFoundError, ModelNotFoundError, DashboardNotFoundError, ConnectionNotFoundError, TableNotFoundError, ConnectionError, DestinationNotFoundError, ConnectionAuthError, UnsupportedCatalogFormatError, ModelCompilationError, PackageManifestError, MaterializationEligibilityError, PublisherConfigError, FrozenConfigError, AccessDeniedError, QueryCompileError, NotQueryableError, OffSurfaceError, MaterializationNotFoundError, MaterializationConflictError, WriteConflictError, WriteRolledBackError, InvalidStateTransitionError, ServiceUnavailableError, PayloadTooLargeError, ResponseUnserializableError, QueryTimeoutError;
13198
+ var GENERIC_INTERNAL_MESSAGE = "Internal server error.", GENERIC_UPSTREAM_MESSAGE = "Upstream connection error.", MAX_LOGGED_DETAIL_CHARS = 2000, FILESYSTEM_ACCESS_DESCRIPTIONS, NotImplementedError, BadRequestError, InvalidArgumentError, CompileRefusedError, EnvironmentNotFoundError, PackageNotFoundError, ModelNotFoundError, DashboardNotFoundError, ConnectionNotFoundError, TableNotFoundError, ConnectionError, DestinationNotFoundError, ConnectionAuthError, UnsupportedCatalogFormatError, ModelCompilationError, PackageManifestError, MaterializationEligibilityError, PublisherConfigError, ServerConfigurationError, FrozenConfigError, AccessDeniedError, QueryCompileError, NotQueryableError, OffSurfaceError, MaterializationNotFoundError, MaterializationConflictError, WriteConflictError, WriteRolledBackError, InvalidStateTransitionError, ServiceUnavailableError, PayloadTooLargeError, ResponseUnserializableError, QueryTimeoutError;
13154
13199
  var init_errors = __esm(() => {
13155
13200
  init_constants();
13156
13201
  init_logger();
13202
+ FILESYSTEM_ACCESS_DESCRIPTIONS = {
13203
+ EACCES: "permission denied",
13204
+ EPERM: "operation not permitted",
13205
+ EROFS: "read-only file system"
13206
+ };
13157
13207
  NotImplementedError = class NotImplementedError extends Error {
13158
13208
  constructor(message) {
13159
13209
  super(message);
@@ -13174,8 +13224,8 @@ var init_errors = __esm(() => {
13174
13224
  }
13175
13225
  };
13176
13226
  PackageNotFoundError = class PackageNotFoundError extends Error {
13177
- constructor(message) {
13178
- super(message);
13227
+ constructor(message, options) {
13228
+ super(message, options);
13179
13229
  }
13180
13230
  };
13181
13231
  ModelNotFoundError = class ModelNotFoundError extends Error {
@@ -13246,6 +13296,12 @@ var init_errors = __esm(() => {
13246
13296
  this.cause = cause;
13247
13297
  }
13248
13298
  };
13299
+ ServerConfigurationError = class ServerConfigurationError extends Error {
13300
+ constructor(message) {
13301
+ super(message);
13302
+ this.name = "ServerConfigurationError";
13303
+ }
13304
+ };
13249
13305
  FrozenConfigError = class FrozenConfigError extends Error {
13250
13306
  constructor(message = `Publisher config can't be updated when ${PUBLISHER_CONFIG_NAME} has { "frozenConfig": true }`) {
13251
13307
  super(message);
@@ -13303,8 +13359,8 @@ var init_errors = __esm(() => {
13303
13359
  }
13304
13360
  };
13305
13361
  ServiceUnavailableError = class ServiceUnavailableError extends Error {
13306
- constructor(message) {
13307
- super(message);
13362
+ constructor(message, options) {
13363
+ super(message, options);
13308
13364
  }
13309
13365
  };
13310
13366
  PayloadTooLargeError = class PayloadTooLargeError extends Error {
@@ -13723,6 +13779,76 @@ var init_data_styles = __esm(() => {
13723
13779
  init_logger();
13724
13780
  });
13725
13781
 
13782
+ // src/package_load/error_wire.ts
13783
+ import { MalloyError as MalloyError2 } from "@malloydata/malloy";
13784
+ function serializeError(error) {
13785
+ const serialized = serializeErrorShape(error);
13786
+ const errno = error instanceof Error ? errnoWireFields(error) : undefined;
13787
+ return errno ? { ...serialized, errno } : serialized;
13788
+ }
13789
+ function serializeErrorShape(error) {
13790
+ if (error instanceof MalloyError2) {
13791
+ return {
13792
+ name: error.name,
13793
+ message: error.message,
13794
+ stack: error.stack,
13795
+ malloyProblems: error.problems,
13796
+ isCompilationError: true
13797
+ };
13798
+ }
13799
+ if (error instanceof ModelCompilationError) {
13800
+ return {
13801
+ name: error.name,
13802
+ message: error.message,
13803
+ stack: error.stack,
13804
+ isCompilationError: true
13805
+ };
13806
+ }
13807
+ if (error instanceof PackageManifestError) {
13808
+ return {
13809
+ name: error.name,
13810
+ message: error.message,
13811
+ stack: error.stack,
13812
+ isManifestError: true
13813
+ };
13814
+ }
13815
+ if (error instanceof Error) {
13816
+ return {
13817
+ name: error.name,
13818
+ message: error.message,
13819
+ stack: error.stack
13820
+ };
13821
+ }
13822
+ return { name: "Error", message: String(error) };
13823
+ }
13824
+ function deserializeError(serialized) {
13825
+ const err = new Error(serialized.message);
13826
+ err.name = serialized.name;
13827
+ if (serialized.stack)
13828
+ err.stack = serialized.stack;
13829
+ if (serialized.errno)
13830
+ Object.assign(err, serialized.errno);
13831
+ if (serialized.malloyProblems) {
13832
+ err.problems = serialized.malloyProblems;
13833
+ }
13834
+ if (serialized.isCompilationError) {
13835
+ const wrapped = new ModelCompilationError(err);
13836
+ if (serialized.stack)
13837
+ wrapped.stack = serialized.stack;
13838
+ return wrapped;
13839
+ }
13840
+ if (serialized.isManifestError) {
13841
+ const manifestError = new PackageManifestError(serialized.message);
13842
+ if (serialized.stack)
13843
+ manifestError.stack = serialized.stack;
13844
+ return manifestError;
13845
+ }
13846
+ return err;
13847
+ }
13848
+ var init_error_wire = __esm(() => {
13849
+ init_errors();
13850
+ });
13851
+
13726
13852
  // src/service/annotations.ts
13727
13853
  import { Annotations } from "@malloydata/malloy";
13728
13854
  function isReservedRoute(route) {
@@ -15384,72 +15510,21 @@ function onMotlyRoute(text) {
15384
15510
  function hasEnvReference(annotation) {
15385
15511
  return annotation.includes("@env.");
15386
15512
  }
15387
- function pollutionTargets() {
15388
- const targets = [Object.prototype];
15389
- for (const key of Object.getOwnPropertyNames(Object.prototype)) {
15390
- const descriptor = Object.getOwnPropertyDescriptor(Object.prototype, key);
15391
- if (!descriptor)
15392
- continue;
15393
- let value;
15394
- if ("value" in descriptor) {
15395
- value = descriptor.value;
15396
- } else {
15397
- if (BUILT_IN_PROTO_GETTER === undefined || descriptor.get !== BUILT_IN_PROTO_GETTER) {
15398
- return;
15399
- }
15400
- continue;
15401
- }
15402
- if ((typeof value === "object" || typeof value === "function") && value !== null && !targets.includes(value)) {
15403
- targets.push(value);
15404
- }
15405
- }
15406
- return targets;
15407
- }
15408
- function parseGuarded(texts) {
15409
- const targets = pollutionTargets();
15410
- if (targets === undefined) {
15411
- return { tag: undefined, messages: [UNSAFE_TO_PARSE] };
15412
- }
15413
- let unreadable = false;
15414
- const ownNames = (target) => {
15415
- try {
15416
- return Object.getOwnPropertyNames(target);
15417
- } catch {
15418
- unreadable = true;
15419
- return [];
15420
- }
15421
- };
15422
- const before = targets.map(ownNames);
15423
- if (unreadable)
15424
- return { tag: undefined, messages: [UNSAFE_TO_PARSE] };
15425
- const undoPollution = () => {
15426
- let polluted = false;
15427
- targets.forEach((target, index) => {
15428
- for (const key of ownNames(target)) {
15429
- if (before[index].includes(key))
15430
- continue;
15431
- polluted = true;
15432
- try {
15433
- delete target[key];
15434
- } catch {}
15435
- }
15436
- });
15437
- return polluted || unreadable;
15438
- };
15513
+ function parseBounded(texts) {
15439
15514
  if (texts.some((text) => text.length > MAX_ANNOTATION_CHARS)) {
15440
15515
  return { tag: undefined, messages: [ANNOTATION_TOO_LONG] };
15441
15516
  }
15442
15517
  try {
15443
15518
  const result = parseAnnotation([...texts]);
15444
- if (undoPollution())
15445
- return { tag: undefined, messages: [UNSAFE_TO_PARSE] };
15446
15519
  return {
15447
15520
  tag: result.tag,
15448
15521
  messages: result.log.map((error) => error.message)
15449
15522
  };
15450
- } catch {
15451
- undoPollution();
15452
- return { tag: undefined, messages: [UNSAFE_TO_PARSE] };
15523
+ } catch (error) {
15524
+ return {
15525
+ tag: undefined,
15526
+ messages: [error instanceof Error ? error.message : String(error)]
15527
+ };
15453
15528
  }
15454
15529
  }
15455
15530
  function docCommentText(texts) {
@@ -15581,16 +15656,16 @@ function parseMotly(texts) {
15581
15656
  const envErrors = envDropped > 0 ? [ENV_REFERENCE_DROPPED] : [];
15582
15657
  if (motly.length === 0)
15583
15658
  return { tag: undefined, errors: envErrors };
15584
- const direct = parseGuarded(motly);
15659
+ const direct = parseBounded(motly);
15585
15660
  if (direct.messages.length === 0)
15586
15661
  return { tag: direct.tag, errors: envErrors };
15587
15662
  const rescued = motly.map((text) => {
15588
- if (parseGuarded([text]).messages.length === 0)
15663
+ if (parseBounded([text]).messages.length === 0)
15589
15664
  return text;
15590
15665
  const rewritten = quoteFilterLiterals(text);
15591
- return parseGuarded([rewritten]).messages.length === 0 ? rewritten : text;
15666
+ return parseBounded([rewritten]).messages.length === 0 ? rewritten : text;
15592
15667
  });
15593
- const after = parseGuarded(rescued);
15668
+ const after = parseBounded(rescued);
15594
15669
  return { tag: after.tag, errors: [...envErrors, ...after.messages] };
15595
15670
  }
15596
15671
  function tagText(tag, ...path) {
@@ -15656,9 +15731,8 @@ function readStartingGivens(tag, declaredType) {
15656
15731
  }
15657
15732
  return Object.keys(collected).length > 0 ? collected : undefined;
15658
15733
  }
15659
- var BUILT_IN_PROTO_GETTER, MAX_ANNOTATION_CHARS = 8192, ANNOTATION_TOO_LONG, ENV_REFERENCE_DROPPED = "annotation dropped for carrying an @env. reference", UNSAFE_TO_PARSE = "annotation could not be parsed safely";
15734
+ var MAX_ANNOTATION_CHARS = 8192, ANNOTATION_TOO_LONG, ENV_REFERENCE_DROPPED = "annotation dropped for carrying an @env. reference";
15660
15735
  var init_motly = __esm(() => {
15661
- BUILT_IN_PROTO_GETTER = Object.getOwnPropertyDescriptor(Object.prototype, "__proto__")?.get;
15662
15736
  ANNOTATION_TOO_LONG = `annotation exceeds ${MAX_ANNOTATION_CHARS} characters and was not parsed`;
15663
15737
  });
15664
15738
 
@@ -23391,9 +23465,6 @@ function lintDashboard(facts, manifest) {
23391
23465
  return findings;
23392
23466
  }
23393
23467
  function describeParseFailure(message) {
23394
- if (message === UNSAFE_TO_PARSE) {
23395
- return `was refused rather than parsed (${message}), which can be caused by something outside this file`;
23396
- }
23397
23468
  if (message === ENV_REFERENCE_DROPPED) {
23398
23469
  return `was dropped rather than parsed (${message}), so nothing on that line took effect`;
23399
23470
  }
@@ -23990,6 +24061,7 @@ init_constants();
23990
24061
  init_authorize_metrics();
23991
24062
  init_data_styles();
23992
24063
  init_errors();
24064
+ init_error_wire();
23993
24065
  init_authorize();
23994
24066
  init_gate_classification();
23995
24067
  init_gate_dimension();
@@ -23998,7 +24070,6 @@ import {
23998
24070
  contextOverlay,
23999
24071
  isSourceDef as isSourceDef7,
24000
24072
  MalloyConfig,
24001
- MalloyError as MalloyError2,
24002
24073
  modelDefToModelInfo as modelDefToModelInfo2,
24003
24074
  Runtime
24004
24075
  } from "@malloydata/malloy";
@@ -24777,48 +24848,6 @@ async function loadPackage(job) {
24777
24848
  }
24778
24849
  };
24779
24850
  }
24780
- function serializeError(error) {
24781
- if (error instanceof MalloyError2) {
24782
- return {
24783
- name: error.name,
24784
- message: error.message,
24785
- stack: error.stack,
24786
- malloyProblems: error.problems,
24787
- isCompilationError: true
24788
- };
24789
- }
24790
- if (error instanceof ModelCompilationError) {
24791
- return {
24792
- name: error.name,
24793
- message: error.message,
24794
- stack: error.stack,
24795
- isCompilationError: true
24796
- };
24797
- }
24798
- if (error instanceof PackageManifestError) {
24799
- return {
24800
- name: error.name,
24801
- message: error.message,
24802
- stack: error.stack,
24803
- isManifestError: true
24804
- };
24805
- }
24806
- if (error instanceof Error) {
24807
- return {
24808
- name: error.name,
24809
- message: error.message,
24810
- stack: error.stack
24811
- };
24812
- }
24813
- return { name: "Error", message: String(error) };
24814
- }
24815
- function deserializeError(serialized) {
24816
- const err = new Error(serialized.message);
24817
- err.name = serialized.name;
24818
- if (serialized.stack)
24819
- err.stack = serialized.stack;
24820
- return err;
24821
- }
24822
24851
  var shuttingDown = false;
24823
24852
  var inFlightJobs = new Set;
24824
24853
  port.on("message", (message) => {