@malloy-publisher/server 0.9.9 → 0.9.10

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/assets/{EnvironmentPage-DaNUmaHg.js → EnvironmentPage-DfL-2Fy5.js} +1 -1
  2. package/dist/app/assets/{HomePage-CRLoVDIs.js → HomePage-Cc5z85GD.js} +1 -1
  3. package/dist/app/assets/{MainPage-BsV5UnlK.js → MainPage-Cv63Ip_P.js} +1 -1
  4. package/dist/app/assets/{ModelPage-DOOiyJAE.js → ModelPage-DvyYSgri.js} +2 -2
  5. package/dist/app/assets/{PackagePage-QHG55rBw.js → PackagePage-BDzBa7qB.js} +1 -1
  6. package/dist/app/assets/{RenderedResult-BHuJpdSn.es-C37LMpwi.js → RenderedResult-Dp1Qdajz.es-woQDtiv_.js} +2 -2
  7. package/dist/app/assets/{RouteError-ziodz3bt.js → RouteError-Bc7-ukP7.js} +1 -1
  8. package/dist/app/assets/ThemeEditorPage-DShPXmlS.js +1 -0
  9. package/dist/app/assets/{ToggleButtonGroup-BrygJ1WP.js → ToggleButtonGroup-WO-9ZUmS.js} +1 -1
  10. package/dist/app/assets/{documentRoutes-1Qgo5Pvl.js → documentRoutes-CvCc_EZs.js} +1 -1
  11. package/dist/app/assets/{index-BK0mbcyQ.js → index-BvSbJtsT.js} +102 -102
  12. package/dist/app/assets/{index-sKcoT1e_.js → index-DFDVJFPm.js} +32 -32
  13. package/dist/app/assets/{index-CA5a5gJj.js → index-Ddy-NxB_.js} +1 -1
  14. package/dist/app/assets/{index-CXJpj7He.js → index-DnRXl1Nu.js} +1 -1
  15. package/dist/app/assets/{index-Bwc6-9Dc.js → index-DugQbYOk.js} +1 -1
  16. package/dist/app/assets/{index.es-CxcPJdYO.js → index.es-BhMC9nt1.js} +58 -58
  17. package/dist/app/index.html +1 -1
  18. package/dist/package_load_worker.mjs +13 -3
  19. package/dist/server.mjs +58 -29
  20. package/package.json +1 -1
  21. package/dist/app/assets/ThemeEditorPage-Cs3rIs4e.js +0 -1
  22. package/dist/sshcrypto-cqb52edz.node +0 -0
@@ -16,7 +16,7 @@ SPDX-License-Identifier: MIT
16
16
  href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap"
17
17
  />
18
18
  <title>Malloy Publisher</title>
19
- <script type="module" crossorigin src="/assets/index-BK0mbcyQ.js"></script>
19
+ <script type="module" crossorigin src="/assets/index-BvSbJtsT.js"></script>
20
20
  <link rel="stylesheet" crossorigin href="/assets/index-DUqldpo0.css">
21
21
  </head>
22
22
  <body>
@@ -20619,6 +20619,12 @@ function ownLevelNoteTexts(annote) {
20619
20619
  function ownLevelNotes(annote) {
20620
20620
  return [...annote?.blockNotes ?? [], ...annote?.notes ?? []];
20621
20621
  }
20622
+ function sameNotePosition(a, b) {
20623
+ return a.url === b.url && a.range.start.line === b.range.start.line && a.range.start.character === b.range.start.character && a.range.end.line === b.range.end.line && a.range.end.character === b.range.end.character;
20624
+ }
20625
+ function notePositionKey(at) {
20626
+ return `${at.url}#${at.range.start.line}:${at.range.start.character}-${at.range.end.line}:${at.range.end.character}`;
20627
+ }
20622
20628
 
20623
20629
  // src/service/notebook.ts
20624
20630
  var ARTIFACT_NOTE = {
@@ -23480,6 +23486,9 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
23480
23486
  const authorizeMap = new Map;
23481
23487
  const misplacedAuthorize = [];
23482
23488
  const gatedSourceOwnAuthorizeNotes = new Set;
23489
+ const gatedSourceOwnAuthorizeNoteKeys = new Set;
23490
+ const noteKey = (note) => `${notePositionKey(note.at)}#${note.text}`;
23491
+ const isGatedSourceOwnNote = (note) => gatedSourceOwnAuthorizeNotes.has(note) || gatedSourceOwnAuthorizeNoteKeys.has(noteKey(note));
23483
23492
  const authorizeNoteDeclaredBy = new Map;
23484
23493
  const nearMissAuthorize = [];
23485
23494
  const sweptStructs = [];
@@ -23491,6 +23500,7 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
23491
23500
  for (const note of ownLevelNotes(struct.annotations)) {
23492
23501
  if (containsAuthorizeAnnotationTag([note.text])) {
23493
23502
  gatedSourceOwnAuthorizeNotes.add(note);
23503
+ gatedSourceOwnAuthorizeNoteKeys.add(noteKey(note));
23494
23504
  considerNoteOwner(authorizeNoteDeclaredBy, note, struct);
23495
23505
  }
23496
23506
  }
@@ -23509,6 +23519,7 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
23509
23519
  for (const note of ownLevelNotes(entry.annotations)) {
23510
23520
  if (containsAuthorizeAnnotationTag([note.text])) {
23511
23521
  gatedSourceOwnAuthorizeNotes.add(note);
23522
+ gatedSourceOwnAuthorizeNoteKeys.add(noteKey(note));
23512
23523
  considerNoteOwner(authorizeNoteDeclaredBy, note, entry);
23513
23524
  }
23514
23525
  }
@@ -23607,7 +23618,7 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
23607
23618
  const fieldAuthorizeNotes = ownLevelNotes(field.annotations).filter((note) => containsAuthorizeAnnotationTag([note.text]));
23608
23619
  if (fieldAuthorizeNotes.length === 0)
23609
23620
  continue;
23610
- if (fieldAuthorizeNotes.every((note) => gatedSourceOwnAuthorizeNotes.has(note))) {
23621
+ if (fieldAuthorizeNotes.every(isGatedSourceOwnNote)) {
23611
23622
  continue;
23612
23623
  }
23613
23624
  const fieldName = field.as || field.name;
@@ -26408,8 +26419,7 @@ async function prepareForMainThread(job, malloyConfig, load, model) {
26408
26419
  contents: model.model._modelDef.contents,
26409
26420
  getRuntime: companionRuntime
26410
26421
  }) ?? null : undefined;
26411
- if (wantsPlan && (load.planLeftToMainThread || pastDeadline())) {
26412
- load.planLeftToMainThread = true;
26422
+ if (wantsPlan && load.planLeftToMainThread) {
26413
26423
  wantsPlan = false;
26414
26424
  }
26415
26425
  if (wantsPlan && companion !== undefined && !load.failed) {
package/dist/server.mjs CHANGED
@@ -262101,11 +262101,6 @@ var require_utils93 = __commonJS((exports, module) => {
262101
262101
  };
262102
262102
  });
262103
262103
 
262104
- // ../../node_modules/ssh2/lib/protocol/crypto/build/Release/sshcrypto.node
262105
- var require_sshcrypto = __commonJS((exports, module) => {
262106
- module.exports = __require("./sshcrypto-cqb52edz.node");
262107
- });
262108
-
262109
262104
  // ../../node_modules/ssh2/lib/protocol/crypto/poly1305.js
262110
262105
  var require_poly1305 = __commonJS((exports, module) => {
262111
262106
  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";
@@ -262592,7 +262587,7 @@ var require_crypto = __commonJS((exports, module) => {
262592
262587
  var ChaChaPolyDecipher;
262593
262588
  var GenericDecipher;
262594
262589
  try {
262595
- binding = require_sshcrypto();
262590
+ binding = (()=>{throw new Error("Cannot require module "+"./crypto/build/Release/sshcrypto.node");})();
262596
262591
  ({
262597
262592
  AESGCMCipher,
262598
262593
  ChaChaPolyCipher,
@@ -336674,6 +336669,12 @@ function ownLevelNoteTexts(annote) {
336674
336669
  function ownLevelNotes(annote) {
336675
336670
  return [...annote?.blockNotes ?? [], ...annote?.notes ?? []];
336676
336671
  }
336672
+ function sameNotePosition(a, b) {
336673
+ return a.url === b.url && a.range.start.line === b.range.start.line && a.range.start.character === b.range.start.character && a.range.end.line === b.range.end.line && a.range.end.character === b.range.end.character;
336674
+ }
336675
+ function notePositionKey(at) {
336676
+ return `${at.url}#${at.range.start.line}:${at.range.start.character}-${at.range.end.line}:${at.range.end.character}`;
336677
+ }
336677
336678
 
336678
336679
  // src/service/notebook.ts
336679
336680
  var ARTIFACT_NOTE = {
@@ -357558,7 +357559,7 @@ source: orders_admin is orders_base extend {}
357558
357559
  - **Both only gate from the \`source:\` line.** The same annotation on a \`dimension:\`/\`measure:\`/\`join_*:\`/\`view:\` line, or on a top-level \`query:\`, is refused at load naming the position rather than silently protecting nothing.
357559
357560
  - **Every given the gate references must be declared on the entry model's own surface, and must carry no default.** In a package curated with \`index.malloy\`, "on the surface" means \`index.malloy\` imports it: import the declaring file whole, or name the given in a selective import (\`import { orders, GROUPS } from "orders.malloy"\`). A given the model cannot resolve is refused at load. So is a referenced given declared *with* a default: a caller who supplies nothing would get that default and be admitted or excluded by a value the gate's own line never shows, so it is refused rather than reasoned about case by case.
357560
357561
  - **A scalar/array mismatch between the operator and the given's declared type is a load-time refusal**, not a request-time warehouse error: \`org_id in $GROUPS\` requires \`GROUPS\` to be array-typed, \`region = $REGION\` requires \`REGION\` scalar. Negation is likewise refused outright, so there is no empty-given inversion surprise to warn about.
357561
- - **Entry point only: not joined, but inherited through \`extend\`.** The gate applies to the source a query enters through. A gate on a source reached only via \`join_*\` **never fires**, at any depth, so anything ungated that joins a locked base hands the base's rows to every caller. A source that \`extend\`s a locked base and declares no gate of its own **does** carry the base's gate; declaring its own annotation replaces it. A source derived from a locked base via a query (\`source: z is locked -> { … }\`) instead **always carries the base's gate in addition to its own**: the derivation recurses into the base unconditionally, so an own gate does not replace it, and the two combine as separate AND'd entries. Pair a locked base with curated extension sources, using access modifiers (\`include { public: …, private: * }\`), so an extension re-exposes only a curated column surface, and keep sensitive sources out of ungated joins.
357562
+ - **Entry point only: not joined, but inherited through \`extend\`.** The gate applies to the source a query enters through. A gate on a source reached only via \`join_*\` **never fires**, at any depth, so anything ungated that joins a locked base hands the base's rows to every caller. A source that \`extend\`s a locked base and declares no gate of its own **does** carry the base's gate; declaring its own annotation replaces it. A source derived from a locked base via a query (\`source: z is locked -> { … }\`) instead **always carries the base's gate in addition to its own**: the derivation recurses into the base unconditionally, so an own gate does not replace it, and the two combine as separate AND'd entries. Pair a locked base with curated extension sources, using access modifiers (\`include { public: …, private: * }\`), so an extension re-exposes only a curated column surface, and keep sensitive sources out of ungated joins. A join the *caller* writes in query text is the caller entering the joined source, so that source's gate does apply to it: a lock is decided, a row filter is grafted into the join. That holds for a query source the model declares over an inline \`table(...) extend { … }\` base as much as for a table source: the join anchors on the declared source, and the derivation carries the base's gate. The author-join side has a contract of its own: when a gated entry source author-joins a tenant-scoped source, carry the tenant key in the \`on\` (\`on list_id = values.list_id and org_id = values.org_id\`), because the joined source's gate does not fire through that join and the ON is what keeps the rows to the caller's tenant. Where a join cannot be keyed that way, the entry source's own gate may reference the joined column (\`#(access_filter) values.org_id = $ORG_ID\`): that is enforced, at the cost of turning that \`join_one\` into an inner join, so a row with no match drops rather than surviving with nulls.
357562
357563
  - **A derivation that drops a column the gate reads fails CLOSED.** \`extend { except: org_id }\`, or an \`accept:\` that omits it, leaves the grafted filter unable to compile, so the request is denied rather than served ungated. The one hole to know: dropping the gated column and then \`rename:\`-ing a *different* column onto that exact name grafts successfully and binds the gate to the wrong column. Narrow, but real, so don't recycle a gated column's name. If a derivation's own projection needs to drop the column a row-level term would read, use a source-level term (\`'literal' in/= $GIVEN\`) instead, since it never depends on any projected column.
357563
357564
  - **The quoted-string and file-level forms are refused at load and no longer exist.** A quoted expression on the \`source:\` line, in either quote, a file-level \`##(…) "<expr>"\` applying to every source in the file, and the earlier \`internal dimension: authorized is <expr>\` form are all retired; the load names the rewrite. Every \`.malloy\` file in a package compiles at load and any failure aborts the package, so a retired-form gate anywhere in the package is refused. Only a declaring file *outside* the package escapes that: it loads and denies every request instead, with no compile-time hint. See your deployment's reference documentation.
357564
357565
  - **A gated source can be persisted, but the gating column freezes.** \`storage=\` and \`#@ preaggregate\` refuse a gated source outright; a colocated \`#@ persist\` is admitted when the gate is provably the entry point's own row filter. The gate still runs live on every query, so rows come back filtered - but the column it filters ON is frozen at build time, so a row whose access decision changes keeps being served under the old decision until the next rebuild. Pair \`#@ persist\` on a gated source with a freshness window (\`fallback="live"\`), which is the only control that bounds that - and read \`skill:malloy-materialization\` for where that window binds, because on a standalone Publisher it does not.
@@ -360467,7 +360468,7 @@ run: source -> {
360467
360468
 
360468
360469
  ## Field Paths and Joins
360469
360470
 
360470
- **Use the joins the model declares.** When you answer a question over a published model, every query is rooted on one source, and you reach a joined source's fields by a dotted path within the query body (for example \`stores.region\`). Do not write \`join_one\` or \`join_many\` in an answer query, and never invent a join key. (A join written in a query does compile, and model files and notebooks use them; the rule is that an answer uses the joins the model declares.) If the field you need is on a source the model does not join, say so and ask the user to add the join to the model.
360471
+ **Use the joins the model declares.** When you answer a question over a published model, every query is rooted on one source, and you reach a joined source's fields by a dotted path within the query body (for example \`stores.region\`). Do not write \`join_one\` or \`join_many\` in an answer query, and never invent a join key. (A join written in a query does compile, and model files and notebooks use them; the rule is that an answer uses the joins the model declares.) If the field you need is on a source the model does not join, say so and ask the user to add the join to the model. If you do write a join in query text, it is gated as if you had entered that source yourself: a locked source refuses the query with a 403 that names your alias, and a row-filtered source filters the rows your join sees, so a denial on a join you wrote means the joined source refused you, not that the model is broken.
360471
360472
 
360472
360473
  The \`->\` operator separates a **source** from a **view** (query transformation). It does NOT navigate between joined sources.
360473
360474
 
@@ -380195,6 +380196,9 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
380195
380196
  const authorizeMap = new Map;
380196
380197
  const misplacedAuthorize = [];
380197
380198
  const gatedSourceOwnAuthorizeNotes = new Set;
380199
+ const gatedSourceOwnAuthorizeNoteKeys = new Set;
380200
+ const noteKey = (note) => `${notePositionKey(note.at)}#${note.text}`;
380201
+ const isGatedSourceOwnNote = (note) => gatedSourceOwnAuthorizeNotes.has(note) || gatedSourceOwnAuthorizeNoteKeys.has(noteKey(note));
380198
380202
  const authorizeNoteDeclaredBy = new Map;
380199
380203
  const nearMissAuthorize = [];
380200
380204
  const sweptStructs = [];
@@ -380206,6 +380210,7 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
380206
380210
  for (const note of ownLevelNotes(struct.annotations)) {
380207
380211
  if (containsAuthorizeAnnotationTag([note.text])) {
380208
380212
  gatedSourceOwnAuthorizeNotes.add(note);
380213
+ gatedSourceOwnAuthorizeNoteKeys.add(noteKey(note));
380209
380214
  considerNoteOwner(authorizeNoteDeclaredBy, note, struct);
380210
380215
  }
380211
380216
  }
@@ -380224,6 +380229,7 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
380224
380229
  for (const note of ownLevelNotes(entry.annotations)) {
380225
380230
  if (containsAuthorizeAnnotationTag([note.text])) {
380226
380231
  gatedSourceOwnAuthorizeNotes.add(note);
380232
+ gatedSourceOwnAuthorizeNoteKeys.add(noteKey(note));
380227
380233
  considerNoteOwner(authorizeNoteDeclaredBy, note, entry);
380228
380234
  }
380229
380235
  }
@@ -380322,7 +380328,7 @@ function extractSourcesFromModelDef(modelDef, givens, onParseError) {
380322
380328
  const fieldAuthorizeNotes = ownLevelNotes(field.annotations).filter((note) => containsAuthorizeAnnotationTag([note.text]));
380323
380329
  if (fieldAuthorizeNotes.length === 0)
380324
380330
  continue;
380325
- if (fieldAuthorizeNotes.every((note) => gatedSourceOwnAuthorizeNotes.has(note))) {
380331
+ if (fieldAuthorizeNotes.every(isGatedSourceOwnNote)) {
380326
380332
  continue;
380327
380333
  }
380328
380334
  const fieldName = field.as || field.name;
@@ -385538,12 +385544,12 @@ function resolveCallerJoin(callerJoin, compiledModelDef, region, context) {
385538
385544
  boundaryUnprovenAt ??= chain2.at;
385539
385545
  }
385540
385546
  }
385541
- return true;
385547
+ return "caller";
385542
385548
  }
385543
385549
  const name = entry ? aliasOf(entry) : key;
385544
385550
  if (context.isModelSource(name)) {
385545
385551
  add(name, forBoundary);
385546
- return true;
385552
+ return "model";
385547
385553
  }
385548
385554
  if (entry)
385549
385555
  return fail2(name);
@@ -385552,7 +385558,7 @@ function resolveCallerJoin(callerJoin, compiledModelDef, region, context) {
385552
385558
  return fail2(chain.at);
385553
385559
  for (const terminal of chain.terminals)
385554
385560
  add(terminal, forBoundary);
385555
- return true;
385561
+ return "chain";
385556
385562
  };
385557
385563
  const isUnmodifiedModelQuery = (q3) => {
385558
385564
  if (!q3.name || !context.isModelQuery(q3.name))
@@ -385564,16 +385570,40 @@ function resolveCallerJoin(callerJoin, compiledModelDef, region, context) {
385564
385570
  const keys = Object.entries(compiledModelDef.contents).filter(([, value]) => isSourceDef7(value) && value.sourceID === sourceID).map(([key]) => key);
385565
385571
  if (keys.length === 0)
385566
385572
  return fail2(sourceID);
385567
- return keys.every((key) => byContentsKey(key, forBoundary));
385573
+ let anchor = "model";
385574
+ for (const key of keys) {
385575
+ const got = byContentsKey(key, forBoundary);
385576
+ if (!got)
385577
+ return false;
385578
+ if (got !== "model")
385579
+ anchor = got;
385580
+ }
385581
+ return anchor;
385582
+ };
385583
+ const modelDeclaresSourceID = (sourceID) => {
385584
+ const entries = Object.entries(compiledModelDef.contents).filter(([, value]) => isSourceDef7(value) && value.sourceID === sourceID);
385585
+ return entries.length > 0 && entries.every(([key, value]) => !isCaller(value.location) && context.isModelSource(aliasOf(value) ?? key));
385568
385586
  };
385569
385587
  const resolveStruct = (struct, isJoinItself, forBoundary, depth) => {
385570
385588
  if (depth > RESOLVE_MAX_DEPTH)
385571
385589
  return fail2(callerJoin.alias);
385572
385590
  let anchored = false;
385591
+ let declaredByModel = false;
385573
385592
  if (struct.sourceID) {
385574
- if (!bySourceID(struct.sourceID, forBoundary))
385593
+ const anchor = bySourceID(struct.sourceID, forBoundary);
385594
+ if (!anchor)
385575
385595
  return false;
385576
385596
  anchored = true;
385597
+ declaredByModel = anchor === "model";
385598
+ } else {
385599
+ const extendsID = struct.extends;
385600
+ if (extendsID && modelDeclaresSourceID(extendsID)) {
385601
+ const anchor = bySourceID(extendsID, forBoundary);
385602
+ if (!anchor)
385603
+ return false;
385604
+ anchored = true;
385605
+ declaredByModel = anchor === "model";
385606
+ }
385577
385607
  }
385578
385608
  if (struct.type === "composite") {
385579
385609
  composite = true;
@@ -385594,15 +385624,17 @@ function resolveCallerJoin(callerJoin, compiledModelDef, region, context) {
385594
385624
  if (isJoinItself && q3 && isUnmodifiedModelQuery(q3)) {
385595
385625
  curatedQuery = q3.name;
385596
385626
  }
385597
- const ref = q3?.structRef;
385598
- if (typeof ref === "string") {
385599
- if (!byContentsKey(ref, forBoundary))
385600
- return false;
385601
- } else if (ref && typeof ref === "object") {
385602
- if (!resolveStruct(ref, false, forBoundary, depth + 1))
385603
- return false;
385604
- } else {
385605
- return fail2(callerJoin.alias);
385627
+ if (!declaredByModel) {
385628
+ const ref = q3?.structRef;
385629
+ if (typeof ref === "string") {
385630
+ if (!byContentsKey(ref, forBoundary))
385631
+ return false;
385632
+ } else if (ref && typeof ref === "object") {
385633
+ if (!resolveStruct(ref, false, forBoundary, depth + 1))
385634
+ return false;
385635
+ } else {
385636
+ return fail2(callerJoin.alias);
385637
+ }
385606
385638
  }
385607
385639
  anchored = true;
385608
385640
  }
@@ -386283,9 +386315,6 @@ function assertGraftedGateBindsToDeclaringSource(entryPointStruct, executedStruc
386283
386315
  }
386284
386316
  assertFilterConditionBindsToDeclaringSource(declaring, executedStruct, condition);
386285
386317
  }
386286
- function rangesEqual(a, b3) {
386287
- return a.start.line === b3.start.line && a.start.character === b3.start.character && a.end.line === b3.end.line && a.end.character === b3.end.character;
386288
- }
386289
386318
  function locationContains(outer, inner) {
386290
386319
  if (outer.url !== inner.url)
386291
386320
  return false;
@@ -386333,7 +386362,7 @@ function findSiblingAnnotationDeclaringSource(note, resolveSibling) {
386333
386362
  if (!isSourceDef8(value))
386334
386363
  continue;
386335
386364
  for (const candidate of ownLevelNotes2(value.annotations)) {
386336
- if (candidate.at && candidate.at.url === note.at.url && rangesEqual(candidate.at.range, note.at.range)) {
386365
+ if (candidate.at && sameNotePosition(candidate.at, note.at)) {
386337
386366
  return value;
386338
386367
  }
386339
386368
  }
@@ -386381,7 +386410,7 @@ function siblingCandidateOwnsCondition(candidate, condition) {
386381
386410
  if (c3.code !== condition.code)
386382
386411
  return false;
386383
386412
  const candidateAt = firstFieldUsageLocation(c3);
386384
- return !!candidateAt && candidateAt.url === at2.url && rangesEqual(candidateAt.range, at2.range);
386413
+ return !!candidateAt && sameNotePosition(candidateAt, at2);
386385
386414
  });
386386
386415
  }
386387
386416
  function conditionReadsNoField(condition) {
@@ -394137,7 +394166,7 @@ ${query}`);
394137
394166
  }
394138
394167
  }
394139
394168
  // package.json
394140
- var version2 = "0.9.9";
394169
+ var version2 = "0.9.10";
394141
394170
 
394142
394171
  // src/version.ts
394143
394172
  var SERVER_VERSION = version2;
package/package.json CHANGED
@@ -19,7 +19,7 @@
19
19
  "snowflake"
20
20
  ],
21
21
  "homepage": "https://docs.malloydata.dev/documentation/user_guides/publishing/mcp_agents",
22
- "version": "0.9.9",
22
+ "version": "0.9.10",
23
23
  "main": "dist/server.mjs",
24
24
  "bin": {
25
25
  "malloy-publisher": "dist/server.mjs"