@malloy-publisher/server 0.0.169 → 0.0.171

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.
@@ -12,7 +12,7 @@
12
12
  href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap"
13
13
  />
14
14
  <title>Malloy Publisher</title>
15
- <script type="module" crossorigin src="/assets/index-C-0P3N7Y.js"></script>
15
+ <script type="module" crossorigin src="/assets/index-DUmIwFQ_.js"></script>
16
16
  <link rel="stylesheet" crossorigin href="/assets/index-CMlGQMcl.css">
17
17
  </head>
18
18
  <body>
package/dist/server.js CHANGED
@@ -196699,7 +196699,8 @@ var require_dist_cjs75 = __commonJS((exports2) => {
196699
196699
  // ../../node_modules/@malloydata/render-validator/dist/fake-dom.js
196700
196700
  var require_fake_dom = __commonJS((exports2) => {
196701
196701
  Object.defineProperty(exports2, "__esModule", { value: true });
196702
- exports2.ensureFakeDom = ensureFakeDom;
196702
+ exports2.installFakeDom = installFakeDom;
196703
+ exports2.removeFakeDom = removeFakeDom;
196703
196704
  var noop2 = () => {};
196704
196705
 
196705
196706
  class Node {
@@ -196770,17 +196771,24 @@ var require_fake_dom = __commonJS((exports2) => {
196770
196771
  return new Text(text);
196771
196772
  }
196772
196773
  }
196773
- function ensureFakeDom() {
196774
+ var installed = false;
196775
+ var hadDocument = false;
196776
+ var hadNavigator = false;
196777
+ var hadWindow = false;
196778
+ function installFakeDom() {
196774
196779
  const g = globalThis;
196775
- if (typeof g.document === "undefined") {
196780
+ hadDocument = typeof g.document !== "undefined";
196781
+ hadNavigator = typeof g.navigator !== "undefined";
196782
+ hadWindow = typeof g.window !== "undefined";
196783
+ if (!hadDocument) {
196776
196784
  g.document = new Document;
196777
196785
  }
196778
- if (typeof g.navigator === "undefined") {
196786
+ if (!hadNavigator) {
196779
196787
  g.navigator = { userAgent: "" };
196780
196788
  } else if (typeof g.navigator.userAgent === "undefined") {
196781
196789
  g.navigator.userAgent = "";
196782
196790
  }
196783
- if (typeof g.window === "undefined") {
196791
+ if (!hadWindow) {
196784
196792
  g.window = Object.assign(g, {
196785
196793
  addEventListener: noop2,
196786
196794
  removeEventListener: noop2,
@@ -196789,18 +196797,40 @@ var require_fake_dom = __commonJS((exports2) => {
196789
196797
  cancelAnimationFrame: noop2
196790
196798
  });
196791
196799
  }
196800
+ installed = true;
196801
+ }
196802
+ function removeFakeDom() {
196803
+ if (!installed)
196804
+ return;
196805
+ const g = globalThis;
196806
+ if (!hadWindow) {
196807
+ delete g.window;
196808
+ delete g.addEventListener;
196809
+ delete g.removeEventListener;
196810
+ delete g.getComputedStyle;
196811
+ delete g.requestAnimationFrame;
196812
+ delete g.cancelAnimationFrame;
196813
+ }
196814
+ if (!hadDocument) {
196815
+ delete g.document;
196816
+ }
196817
+ if (!hadNavigator) {
196818
+ delete g.navigator;
196819
+ }
196820
+ installed = false;
196792
196821
  }
196793
- ensureFakeDom();
196794
196822
  });
196795
196823
 
196796
196824
  // ../../node_modules/@malloydata/render-validator/dist/index.js
196797
196825
  var require_dist10 = __commonJS((exports2) => {
196798
196826
  Object.defineProperty(exports2, "__esModule", { value: true });
196799
196827
  exports2.validateRenderTags = validateRenderTags;
196800
- require_fake_dom();
196801
- var render_1 = require("@malloydata/render");
196828
+ var { installFakeDom, removeFakeDom } = require_fake_dom();
196829
+ installFakeDom();
196830
+ var { MalloyRenderer } = require("@malloydata/render");
196831
+ removeFakeDom();
196802
196832
  function validateRenderTags(result) {
196803
- const renderer = new render_1.MalloyRenderer;
196833
+ const renderer = new MalloyRenderer;
196804
196834
  const viz = renderer.createViz();
196805
196835
  viz.setResult(result);
196806
196836
  return viz.getLogs();
@@ -222397,7 +222427,7 @@ class PackageController {
222397
222427
  } else if (packageLocation.startsWith("gs://")) {
222398
222428
  await this.projectStore.downloadGcsDirectory(packageLocation, projectName, absoluteTargetPath, isCompressedFile);
222399
222429
  } else if (packageLocation.startsWith("s3://")) {
222400
- await this.projectStore.downloadS3Directory(packageLocation, projectName, absoluteTargetPath);
222430
+ await this.projectStore.downloadS3Directory(packageLocation, projectName, absoluteTargetPath, isCompressedFile);
222401
222431
  }
222402
222432
  if (packageLocation.startsWith("/")) {
222403
222433
  await this.projectStore.mountLocalDirectory(packageLocation, absoluteTargetPath, projectName, packageName);
@@ -222406,6 +222436,7 @@ class PackageController {
222406
222436
  }
222407
222437
 
222408
222438
  // src/controller/query.controller.ts
222439
+ var import_render_validator = __toESM(require_dist10());
222409
222440
  function bigIntReplacer(_key, value) {
222410
222441
  if (typeof value === "bigint") {
222411
222442
  return Number(value);
@@ -222426,8 +222457,7 @@ class QueryController {
222426
222457
  throw new ModelNotFoundError(`${modelPath} does not exist`);
222427
222458
  } else {
222428
222459
  const { result, compactResult } = await model.getQueryResults(sourceName, queryName, query);
222429
- const { validateRenderTags } = await Promise.resolve().then(() => __toESM(require_dist10()));
222430
- const renderLogs = validateRenderTags(result);
222460
+ const renderLogs = import_render_validator.validateRenderTags(result);
222431
222461
  return {
222432
222462
  result: compactJson ? JSON.stringify(compactResult, bigIntReplacer) : JSON.stringify(result),
222433
222463
  resource: `${API_PREFIX}/projects/${projectName}/packages/${packageName}/models/${modelPath}/query`,
@@ -230990,7 +231020,7 @@ class ProjectStore {
230990
231020
  if (this.isS3URL(location)) {
230991
231021
  try {
230992
231022
  logger.info(`Downloading S3 directory from "${location}" to "${targetPath}"`);
230993
- await this.downloadS3Directory(location, projectName, targetPath);
231023
+ await this.downloadS3Directory(location, projectName, targetPath, isCompressedFile);
230994
231024
  return;
230995
231025
  } catch (error) {
230996
231026
  const errorData = this.extractErrorDataFromError(error);
@@ -231067,10 +231097,33 @@ class ProjectStore {
231067
231097
  }
231068
231098
  logger.info(`Downloaded GCS directory ${gcsPath} to ${absoluteDirPath}`);
231069
231099
  }
231070
- async downloadS3Directory(s3Path, projectName, absoluteDirPath) {
231100
+ async downloadS3Directory(s3Path, projectName, absoluteDirPath, isCompressedFile = false) {
231071
231101
  const trimmedPath = s3Path.slice(5);
231072
231102
  const [bucketName, ...prefixParts] = trimmedPath.split("/");
231073
231103
  const prefix = prefixParts.join("/");
231104
+ if (isCompressedFile) {
231105
+ const zipFilePath = `${absoluteDirPath}.zip`;
231106
+ await fs7.promises.mkdir(path8.dirname(zipFilePath), {
231107
+ recursive: true
231108
+ });
231109
+ const command = new import_client_s32.GetObjectCommand({
231110
+ Bucket: bucketName,
231111
+ Key: prefix
231112
+ });
231113
+ const item = await this.s3Client.send(command);
231114
+ if (!item.Body) {
231115
+ throw new ProjectNotFoundError(`Project ${projectName} not found in ${s3Path}`);
231116
+ }
231117
+ const file = fs7.createWriteStream(zipFilePath);
231118
+ item.Body.transformToWebStream().pipeTo(import_stream5.Writable.toWeb(file));
231119
+ await new Promise((resolve3, reject) => {
231120
+ file.on("error", reject);
231121
+ file.on("finish", resolve3);
231122
+ });
231123
+ await this.unzipProject(zipFilePath);
231124
+ logger.info(`Downloaded S3 zip file ${s3Path} to ${absoluteDirPath}`);
231125
+ return;
231126
+ }
231074
231127
  const objects = await this.s3Client.listObjectsV2({
231075
231128
  Bucket: bucketName,
231076
231129
  Prefix: prefix
@@ -231108,6 +231161,7 @@ class ProjectStore {
231108
231161
  file.on("finish", resolve3);
231109
231162
  });
231110
231163
  }));
231164
+ logger.info(`Downloaded S3 directory ${s3Path} to ${absoluteDirPath}`);
231111
231165
  }
231112
231166
  parseGitHubUrl(githubUrl) {
231113
231167
  const httpsRegex = /github\.com\/(?<owner>[^/]+)\/(?<repoName>[^/]+)(?<packagePath>\/[^/]+)*/;
@@ -234997,8 +235051,8 @@ function registerExecuteQueryTool(mcpServer, projectStore) {
234997
235051
  try {
234998
235052
  if (query) {
234999
235053
  const { result } = await model.getQueryResults(undefined, undefined, query);
235000
- const { validateRenderTags } = await Promise.resolve().then(() => __toESM(require_dist10()));
235001
- const renderLogs = validateRenderTags(result);
235054
+ const { validateRenderTags: validateRenderTags2 } = await Promise.resolve().then(() => __toESM(require_dist10()));
235055
+ const renderLogs = validateRenderTags2(result);
235002
235056
  const baseUriComponents = {
235003
235057
  project: projectName,
235004
235058
  package: packageName,
@@ -235033,8 +235087,8 @@ ${JSON.stringify(renderLogs, null, 2)}`
235033
235087
  return { isError: false, content };
235034
235088
  } else if (queryName) {
235035
235089
  const { result } = await model.getQueryResults(sourceName, queryName, undefined);
235036
- const { validateRenderTags } = await Promise.resolve().then(() => __toESM(require_dist10()));
235037
- const renderLogs = validateRenderTags(result);
235090
+ const { validateRenderTags: validateRenderTags2 } = await Promise.resolve().then(() => __toESM(require_dist10()));
235091
+ const renderLogs = validateRenderTags2(result);
235038
235092
  const baseUriComponents = {
235039
235093
  project: projectName,
235040
235094
  package: packageName,
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.0.169",
4
+ "version": "0.0.171",
5
5
  "main": "dist/server.js",
6
6
  "bin": {
7
7
  "malloy-publisher": "dist/server.js"
@@ -30,15 +30,15 @@
30
30
  "dependencies": {
31
31
  "@aws-sdk/client-s3": "^3.958.0",
32
32
  "@google-cloud/storage": "^7.16.0",
33
- "@malloydata/db-bigquery": "^0.0.354",
34
- "@malloydata/db-duckdb": "^0.0.354",
35
- "@malloydata/db-mysql": "^0.0.354",
36
- "@malloydata/db-postgres": "^0.0.354",
37
- "@malloydata/db-snowflake": "^0.0.354",
38
- "@malloydata/db-trino": "^0.0.354",
39
- "@malloydata/malloy": "^0.0.354",
40
- "@malloydata/malloy-sql": "^0.0.354",
41
- "@malloydata/render-validator": "^0.0.354",
33
+ "@malloydata/db-bigquery": "^0.0.358",
34
+ "@malloydata/db-duckdb": "^0.0.358",
35
+ "@malloydata/db-mysql": "^0.0.358",
36
+ "@malloydata/db-postgres": "^0.0.358",
37
+ "@malloydata/db-snowflake": "^0.0.358",
38
+ "@malloydata/db-trino": "^0.0.358",
39
+ "@malloydata/malloy": "^0.0.358",
40
+ "@malloydata/malloy-sql": "^0.0.358",
41
+ "@malloydata/render-validator": "^0.0.358",
42
42
  "@modelcontextprotocol/sdk": "^1.13.2",
43
43
  "@opentelemetry/api": "^1.9.0",
44
44
  "@opentelemetry/auto-instrumentations-node": "^0.57.0",
@@ -113,6 +113,7 @@ export class PackageController {
113
113
  packageLocation,
114
114
  projectName,
115
115
  absoluteTargetPath,
116
+ isCompressedFile,
116
117
  );
117
118
  }
118
119
 
@@ -1,3 +1,4 @@
1
+ import { validateRenderTags } from "@malloydata/render-validator";
1
2
  import { components } from "../api";
2
3
  import { API_PREFIX } from "../constants";
3
4
  import { ModelNotFoundError } from "../errors";
@@ -41,11 +42,6 @@ export class QueryController {
41
42
  queryName,
42
43
  query,
43
44
  );
44
- // Lazy import since this creates a FakeDOM global which
45
- // can confuse other imports.
46
- const { validateRenderTags } = await import(
47
- "@malloydata/render-validator"
48
- );
49
45
  const renderLogs = validateRenderTags(result);
50
46
  return {
51
47
  result: compactJson
@@ -1112,7 +1112,12 @@ export class ProjectStore {
1112
1112
  logger.info(
1113
1113
  `Downloading S3 directory from "${location}" to "${targetPath}"`,
1114
1114
  );
1115
- await this.downloadS3Directory(location, projectName, targetPath);
1115
+ await this.downloadS3Directory(
1116
+ location,
1117
+ projectName,
1118
+ targetPath,
1119
+ isCompressedFile,
1120
+ );
1116
1121
  return;
1117
1122
  } catch (error) {
1118
1123
  const errorData = this.extractErrorDataFromError(error);
@@ -1242,10 +1247,43 @@ export class ProjectStore {
1242
1247
  s3Path: string,
1243
1248
  projectName: string,
1244
1249
  absoluteDirPath: string,
1250
+ isCompressedFile: boolean = false,
1245
1251
  ) {
1246
1252
  const trimmedPath = s3Path.slice(5);
1247
1253
  const [bucketName, ...prefixParts] = trimmedPath.split("/");
1248
1254
  const prefix = prefixParts.join("/");
1255
+
1256
+ if (isCompressedFile) {
1257
+ // Download the single zip file
1258
+ const zipFilePath = `${absoluteDirPath}.zip`;
1259
+ await fs.promises.mkdir(path.dirname(zipFilePath), {
1260
+ recursive: true,
1261
+ });
1262
+
1263
+ const command = new GetObjectCommand({
1264
+ Bucket: bucketName,
1265
+ Key: prefix,
1266
+ });
1267
+ const item = await this.s3Client.send(command);
1268
+ if (!item.Body) {
1269
+ throw new ProjectNotFoundError(
1270
+ `Project ${projectName} not found in ${s3Path}`,
1271
+ );
1272
+ }
1273
+ const file = fs.createWriteStream(zipFilePath);
1274
+ item.Body.transformToWebStream().pipeTo(Writable.toWeb(file));
1275
+ await new Promise<void>((resolve, reject) => {
1276
+ file.on("error", reject);
1277
+ file.on("finish", resolve);
1278
+ });
1279
+
1280
+ // Extract the zip file
1281
+ await this.unzipProject(zipFilePath);
1282
+ logger.info(`Downloaded S3 zip file ${s3Path} to ${absoluteDirPath}`);
1283
+ return;
1284
+ }
1285
+
1286
+ // Original behavior: download directory contents
1249
1287
  const objects = await this.s3Client.listObjectsV2({
1250
1288
  Bucket: bucketName,
1251
1289
  Prefix: prefix,
@@ -1291,6 +1329,7 @@ export class ProjectStore {
1291
1329
  });
1292
1330
  }),
1293
1331
  );
1332
+ logger.info(`Downloaded S3 directory ${s3Path} to ${absoluteDirPath}`);
1294
1333
  }
1295
1334
 
1296
1335
  private parseGitHubUrl(