@mastra/daytona 0.2.1 → 0.3.0-alpha.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @mastra/daytona
2
2
 
3
+ ## 0.3.0-alpha.0
4
+
5
+ ### Minor Changes
6
+
7
+ - Added S3 prefix (subdirectory) mount support. You can now mount a specific folder within an S3 bucket instead of the entire bucket by setting the `prefix` option on your S3 filesystem. ([#15171](https://github.com/mastra-ai/mastra/pull/15171))
8
+
9
+ **Example:**
10
+
11
+ ```typescript
12
+ const fs = new S3Filesystem({
13
+ bucket: 'my-bucket',
14
+ region: 'us-east-1',
15
+ prefix: 'workspace/data',
16
+ accessKeyId: process.env.AWS_ACCESS_KEY_ID!,
17
+ secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY!,
18
+ });
19
+ ```
20
+
21
+ When mounted in a sandbox, only the contents under `workspace/data/` in the bucket will be visible at the mount path. This uses the s3fs `bucket:/path` syntax under the hood.
22
+
23
+ Closes #15147.
24
+
25
+ ### Patch Changes
26
+
27
+ - Updated dependencies [[`f112db1`](https://github.com/mastra-ai/mastra/commit/f112db179557ae9b5a0f1d25dc47f928d7d61cd9), [`21d9706`](https://github.com/mastra-ai/mastra/commit/21d970604d89eee970cbf8013d26d7551aff6ea5)]:
28
+ - @mastra/core@1.26.1-alpha.0
29
+
3
30
  ## 0.2.1
4
31
 
5
32
  ### Patch Changes
package/dist/index.cjs CHANGED
@@ -38,6 +38,21 @@ function validateEndpoint(endpoint) {
38
38
  throw new Error(`Invalid endpoint URL scheme: "${parsed.protocol}". Only http: and https: are allowed.`);
39
39
  }
40
40
  }
41
+ function validatePrefix(prefix) {
42
+ let normalized = prefix;
43
+ while (normalized.startsWith("/")) normalized = normalized.slice(1);
44
+ while (normalized.endsWith("/")) normalized = normalized.slice(0, -1);
45
+ if (!normalized) {
46
+ throw new Error("Mount prefix cannot be empty after normalization.");
47
+ }
48
+ if (normalized.includes("//") || normalized.split("/").some((s) => s === "." || s === "..")) {
49
+ throw new Error(`Invalid mount prefix: "${prefix}". Path traversal is not allowed.`);
50
+ }
51
+ if (/[\x00-\x1f\x7f]/.test(normalized)) {
52
+ throw new Error(`Invalid mount prefix: "${prefix}". Control characters are not allowed.`);
53
+ }
54
+ return normalized;
55
+ }
41
56
  async function runCommand(sandbox, command, options) {
42
57
  const result = await sandbox.process.executeCommand(
43
58
  command,
@@ -131,7 +146,12 @@ Sandbox network response: ${checkOutput}` : "")
131
146
  mountOptions.push("ro");
132
147
  logger.debug(`${LOG_PREFIX} Mounting as read-only`);
133
148
  }
134
- const mountCmd = `s3fs ${shellQuote(config.bucket)} ${quotedMountPath} -o ${mountOptions.join(" -o ")}`;
149
+ let bucketArg = config.bucket;
150
+ if (config.prefix) {
151
+ const normalizedPrefix = validatePrefix(config.prefix);
152
+ bucketArg = `${config.bucket}:/${normalizedPrefix}`;
153
+ }
154
+ const mountCmd = `s3fs ${shellQuote(bucketArg)} ${quotedMountPath} -o ${mountOptions.join(" -o ")}`;
135
155
  logger.debug(`${LOG_PREFIX} Mounting S3:`, hasCredentials ? mountCmd.replace(credentialsPath, "***") : mountCmd);
136
156
  const result = await run(mountCmd, 6e4);
137
157
  logger.debug(`${LOG_PREFIX} s3fs result:`, {