@hyperframes/studio-server 0.8.41 → 0.8.43

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/dist/index.js CHANGED
@@ -3701,7 +3701,8 @@ ${runtimeTag}`;
3701
3701
  if (!compFile || !existsSync6(compFile) || !statSync3(compFile).isFile()) {
3702
3702
  return c.text("not found", 404);
3703
3703
  }
3704
- const etag = `"comp:v2:${compPath}:${signature}${variablesEtagSalt(vars.raw)}"`;
3704
+ const compPathHash = createHash3("sha1").update(compPath).digest("hex");
3705
+ const etag = `"comp:v2:${compPathHash}:${signature}${variablesEtagSalt(vars.raw)}"`;
3705
3706
  const ifNoneMatch = c.req.header("If-None-Match");
3706
3707
  if (ifNoneMatch === etag) {
3707
3708
  return new Response(null, {
@@ -3887,6 +3888,14 @@ import { join as join10 } from "path";
3887
3888
  import { VALID_CANVAS_RESOLUTIONS } from "@hyperframes/parsers";
3888
3889
  import { formatRenderOutputTimestamp, parseFps } from "@hyperframes/core";
3889
3890
  var VALID_RESOLUTIONS = new Set(VALID_CANVAS_RESOLUTIONS);
3891
+ function contentDispositionHeader(disposition, filename) {
3892
+ const fallback = filename.replace(/[^\x20-\x7e]|["\\]/g, "_");
3893
+ const encoded = encodeURIComponent(filename).replace(
3894
+ /[!'()*]/g,
3895
+ (character) => `%${character.charCodeAt(0).toString(16).toUpperCase()}`
3896
+ );
3897
+ return `${disposition}; filename="${fallback}"; filename*=UTF-8''${encoded}`;
3898
+ }
3890
3899
  function registerRenderRoutes(api, adapter) {
3891
3900
  const renderJobs = /* @__PURE__ */ new Map();
3892
3901
  const TTL_MS = 3e5;
@@ -4016,7 +4025,7 @@ function registerRenderRoutes(api, adapter) {
4016
4025
  return new Response(content, {
4017
4026
  headers: {
4018
4027
  "Content-Type": contentType,
4019
- "Content-Disposition": `inline; filename="${filename}"`,
4028
+ "Content-Disposition": contentDispositionHeader("inline", filename),
4020
4029
  "Accept-Ranges": "bytes",
4021
4030
  "Content-Length": String(content.length)
4022
4031
  }
@@ -4034,7 +4043,7 @@ function registerRenderRoutes(api, adapter) {
4034
4043
  return new Response(content, {
4035
4044
  headers: {
4036
4045
  "Content-Type": contentType,
4037
- "Content-Disposition": `attachment; filename="${filename}"`
4046
+ "Content-Disposition": contentDispositionHeader("attachment", filename)
4038
4047
  }
4039
4048
  });
4040
4049
  });
@@ -4067,7 +4076,7 @@ function registerRenderRoutes(api, adapter) {
4067
4076
  return new Response(content, {
4068
4077
  headers: {
4069
4078
  "Content-Type": contentType,
4070
- "Content-Disposition": `inline; filename="${filename}"`,
4079
+ "Content-Disposition": contentDispositionHeader("inline", filename),
4071
4080
  "Accept-Ranges": "bytes",
4072
4081
  "Content-Length": String(content.length)
4073
4082
  }