@hyperframes/core 0.6.95 → 0.6.97

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 (46) hide show
  1. package/dist/compiler/htmlBundler.d.ts.map +1 -1
  2. package/dist/compiler/htmlBundler.js +11 -17
  3. package/dist/compiler/htmlBundler.js.map +1 -1
  4. package/dist/generated/runtime-inline.js +1 -1
  5. package/dist/generated/runtime-inline.js.map +1 -1
  6. package/dist/hyperframe.manifest.json +1 -1
  7. package/dist/hyperframe.runtime.iife.js +23 -23
  8. package/dist/hyperframe.runtime.mjs +23 -23
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -0
  12. package/dist/index.js.map +1 -1
  13. package/dist/media/gif.d.ts.map +1 -1
  14. package/dist/media/gif.js +9 -2
  15. package/dist/media/gif.js.map +1 -1
  16. package/dist/safePath.d.ts +34 -0
  17. package/dist/safePath.d.ts.map +1 -0
  18. package/dist/safePath.js +71 -0
  19. package/dist/safePath.js.map +1 -0
  20. package/dist/studio-api/helpers/backupJournal.d.ts +9 -0
  21. package/dist/studio-api/helpers/backupJournal.d.ts.map +1 -0
  22. package/dist/studio-api/helpers/backupJournal.js +81 -0
  23. package/dist/studio-api/helpers/backupJournal.js.map +1 -0
  24. package/dist/studio-api/helpers/finiteMutation.d.ts +11 -0
  25. package/dist/studio-api/helpers/finiteMutation.d.ts.map +1 -0
  26. package/dist/studio-api/helpers/finiteMutation.js +21 -0
  27. package/dist/studio-api/helpers/finiteMutation.js.map +1 -0
  28. package/dist/studio-api/helpers/safePath.d.ts +9 -2
  29. package/dist/studio-api/helpers/safePath.d.ts.map +1 -1
  30. package/dist/studio-api/helpers/safePath.js +21 -8
  31. package/dist/studio-api/helpers/safePath.js.map +1 -1
  32. package/dist/studio-api/routes/files.d.ts.map +1 -1
  33. package/dist/studio-api/routes/files.js +93 -21
  34. package/dist/studio-api/routes/files.js.map +1 -1
  35. package/dist/studio-api/routes/lint.d.ts.map +1 -1
  36. package/dist/studio-api/routes/lint.js +2 -2
  37. package/dist/studio-api/routes/lint.js.map +1 -1
  38. package/dist/studio-api/routes/preview.d.ts.map +1 -1
  39. package/dist/studio-api/routes/preview.js +9 -8
  40. package/dist/studio-api/routes/preview.js.map +1 -1
  41. package/dist/studio-api/routes/projects.js +2 -2
  42. package/dist/studio-api/routes/projects.js.map +1 -1
  43. package/dist/studio-api/routes/render.d.ts.map +1 -1
  44. package/dist/studio-api/routes/render.js +6 -3
  45. package/dist/studio-api/routes/render.js.map +1 -1
  46. package/package.json +5 -1
package/dist/index.d.ts CHANGED
@@ -22,6 +22,7 @@ export { getHyperframeRuntimeScript } from "./generated/runtime-inline";
22
22
  export { buildHyperframesRuntimeScript, type HyperframesRuntimeBuildOptions, } from "./inline-scripts/hyperframesRuntime.engine";
23
23
  export { MEDIA_VISUAL_STYLE_PROPERTIES, copyMediaVisualStyles, quantizeTimeToFrame, type MediaVisualStyleProperty, } from "./inline-scripts/parityContract";
24
24
  export { redactTelemetryString } from "./telemetryRedaction";
25
+ export { isSafePath, resolveWithinProject } from "./safePath";
25
26
  export type { HyperframePickerApi, HyperframePickerBoundingBox, HyperframePickerElementInfo, } from "./inline-scripts/pickerApi";
26
27
  export type { FrameAdapter, FrameAdapterContext } from "./adapters/types";
27
28
  export type { GSAPTimelineLike, CreateGSAPFrameAdapterOptions } from "./adapters/gsap";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,aAAa,EACb,WAAW,EACX,KAAK,EACL,eAAe,EACf,mBAAmB,EACnB,oBAAoB,EACpB,mBAAmB,EACnB,0BAA0B,EAC1B,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,GAAG,EACH,QAAQ,EACR,cAAc,EACd,SAAS,EACT,cAAc,EACd,SAAS,EACT,cAAc,EACd,gBAAgB,EAChB,gBAAgB,EAChB,QAAQ,EACR,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,iBAAiB,EACjB,uBAAuB,EACvB,uBAAuB,EACvB,cAAc,EACd,cAAc,EACd,aAAa,EACb,eAAe,EACf,YAAY,EACZ,mBAAmB,EACnB,eAAe,EACf,YAAY,GACb,MAAM,cAAc,CAAC;AAEtB,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,QAAQ,EACR,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,cAAc,GACf,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAM/B,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAErF,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,YAAY,EAAE,UAAU,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE5E,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAG9B,YAAY,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAGlC,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,GAClB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AAGnC,YAAY,EACV,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAGjF,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,EAC3B,KAAK,yBAAyB,GAC/B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,EAC1B,KAAK,uBAAuB,GAC7B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EACL,6BAA6B,EAC7B,KAAK,8BAA8B,GACpC,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,mBAAmB,EACnB,KAAK,wBAAwB,GAC9B,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,YAAY,EACV,mBAAmB,EACnB,2BAA2B,EAC3B,2BAA2B,GAC5B,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EAAE,YAAY,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,YAAY,EAAE,gBAAgB,EAAE,6BAA6B,EAAE,MAAM,iBAAiB,CAAC;AACvF,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAGzD,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAGrE,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAGzD,OAAO,EACL,iBAAiB,EACjB,6BAA6B,EAC7B,KAAK,uBAAuB,GAC7B,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EACV,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,sBAAsB,EACtB,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,SAAS,EACT,aAAa,EACb,qBAAqB,EACrB,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,UAAU,EACV,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -18,6 +18,7 @@ export { getHyperframeRuntimeScript } from "./generated/runtime-inline";
18
18
  export { buildHyperframesRuntimeScript, } from "./inline-scripts/hyperframesRuntime.engine";
19
19
  export { MEDIA_VISUAL_STYLE_PROPERTIES, copyMediaVisualStyles, quantizeTimeToFrame, } from "./inline-scripts/parityContract";
20
20
  export { redactTelemetryString } from "./telemetryRedaction";
21
+ export { isSafePath, resolveWithinProject } from "./safePath";
21
22
  export { createGSAPFrameAdapter } from "./adapters/gsap";
22
23
  // Text measurement
23
24
  export { fitTextFontSize } from "./text/index.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuCA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,QAAQ,EACR,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAUlC,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AASnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAA4B,MAAM,aAAa,CAAC;AAEjF,iBAAiB;AACjB,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,GAE5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,GAE3B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EACL,6BAA6B,GAE9B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,mBAAmB,GAEpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAU7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,mBAAmB;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,qCAAqC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,2CAA2C;AAC3C,OAAO,EACL,iBAAiB,EACjB,6BAA6B,GAE9B,MAAM,gCAAgC,CAAC;AAiBxC,OAAO,EACL,UAAU,EACV,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAuCA,OAAO,EACL,iBAAiB,EACjB,wBAAwB,EACxB,uBAAuB,EACvB,QAAQ,EACR,mBAAmB,EACnB,KAAK,EACL,WAAW,EACX,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,0BAA0B,EAC1B,aAAa,EACb,cAAc,EACd,oBAAoB,EACpB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,iBAAiB,EACjB,cAAc,GACf,MAAM,cAAc,CAAC;AAEtB,YAAY;AACZ,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACpE,OAAO,EACL,QAAQ,EACR,WAAW,EACX,mBAAmB,EACnB,YAAY,EACZ,WAAW,EACX,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAQ/B,OAAO,EACL,uBAAuB,EACvB,yBAAyB,EACzB,uBAAuB,EACvB,yBAAyB,EACzB,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAIjC,OAAO,EACL,SAAS,EACT,mBAAmB,EACnB,gBAAgB,EAChB,qBAAqB,EACrB,uBAAuB,EACvB,0BAA0B,GAC3B,MAAM,sBAAsB,CAAC;AAK9B,OAAO,EACL,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAUlC,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,cAAc,EACd,wBAAwB,GACzB,MAAM,2BAA2B,CAAC;AASnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EACL,iBAAiB,EACjB,gBAAgB,EAChB,mBAAmB,GACpB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACnF,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,wBAAwB,EAA4B,MAAM,aAAa,CAAC;AAEjF,iBAAiB;AACjB,OAAO,EACL,4BAA4B,EAC5B,2BAA2B,EAC3B,2BAA2B,GAE5B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,0BAA0B,EAC1B,yBAAyB,EACzB,0BAA0B,GAE3B,MAAM,kCAAkC,CAAC;AAC1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,4BAA4B,CAAC;AACxE,OAAO,EACL,6BAA6B,GAE9B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACL,6BAA6B,EAC7B,qBAAqB,EACrB,mBAAmB,GAEpB,MAAM,iCAAiC,CAAC;AACzC,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAU9D,OAAO,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAEzD,mBAAmB;AACnB,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAGlD,qCAAqC;AACrC,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,2CAA2C;AAC3C,OAAO,EACL,iBAAiB,EACjB,6BAA6B,GAE9B,MAAM,gCAAgC,CAAC;AAiBxC,OAAO,EACL,UAAU,EACV,UAAU,EACV,cAAc,EACd,aAAa,EACb,WAAW,EACX,eAAe,GAChB,MAAM,qBAAqB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"gif.d.ts","sourceRoot":"","sources":["../../src/media/gif.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB;AA6DD,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,mBAAmB,GAAG,IAAI,CAwFtF"}
1
+ {"version":3,"file":"gif.d.ts","sourceRoot":"","sources":["../../src/media/gif.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,EAAE,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,uFAAuF;IACvF,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAqED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,UAAU,GAAG,mBAAmB,GAAG,IAAI,CAuFtF"}
package/dist/media/gif.js CHANGED
@@ -1,3 +1,10 @@
1
+ const BROWSER_MIN_DELAY_CENTISECONDS = 10;
2
+ function normalizeDelayCentiseconds(delay) {
3
+ // Chrome clamps GIF frame delays <= 1cs to 10cs (100ms); mirror browser playback timing.
4
+ if (delay <= 1)
5
+ return BROWSER_MIN_DELAY_CENTISECONDS;
6
+ return Math.max(0, delay);
7
+ }
1
8
  function readAscii(bytes, start, length) {
2
9
  if (start + length > bytes.length)
3
10
  return "";
@@ -88,7 +95,7 @@ export function parseAnimatedGifMetadata(bytes) {
88
95
  const delay = readU16LE(bytes, pos + 2);
89
96
  if (delay == null)
90
97
  return null;
91
- delaysCentiseconds.push(delay);
98
+ delaysCentiseconds.push(normalizeDelayCentiseconds(delay));
92
99
  pos += 1 + blockSize;
93
100
  if (bytes[pos] !== 0)
94
101
  return null;
@@ -130,7 +137,7 @@ export function parseAnimatedGifMetadata(bytes) {
130
137
  }
131
138
  return null;
132
139
  }
133
- const durationSeconds = delaysCentiseconds.reduce((total, delay) => total + Math.max(0, delay), 0) / 100;
140
+ const durationSeconds = delaysCentiseconds.reduce((total, delay) => total + delay, 0) / 100;
134
141
  return {
135
142
  width,
136
143
  height,
@@ -1 +1 @@
1
- {"version":3,"file":"gif.js","sourceRoot":"","sources":["../../src/media/gif.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"gif.js","sourceRoot":"","sources":["../../src/media/gif.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Reject paths that escape the `base` directory — including via symlinks.
3
+ *
4
+ * `path.resolve()` collapses `.`/`..` but does NOT dereference symlinks, so a
5
+ * plain prefix check (`resolved.startsWith(base + sep)`) can be defeated by a
6
+ * symlink that lives *inside* `base` but points outside it (e.g.
7
+ * `base/link -> /etc`). A downstream `readFileSync`/`writeFileSync`/`statSync`
8
+ * then follows that link to a file outside `base`. To close this we canonicalize
9
+ * both sides with `realpathSync` before comparing.
10
+ *
11
+ * The target may not exist yet (e.g. creating a new file), so we canonicalize the
12
+ * deepest *existing* ancestor and re-attach the trailing not-yet-existing
13
+ * segments. Segments that don't exist cannot be symlinks at check time, so they
14
+ * can't redirect the path outside `base` right now. (A symlink swapped in between
15
+ * this check and the subsequent fs call is an inherent TOCTOU race this helper
16
+ * does not, and cannot by itself, defend against.)
17
+ *
18
+ * Lives at the package root rather than under `studio-api/` because callers span
19
+ * layers — `studio-api` routes, the `compiler`, the CLI, and the engine — and
20
+ * `compiler` sits below `studio-api` in the dependency graph, so it cannot import
21
+ * from there without a backwards edge.
22
+ */
23
+ export declare function isSafePath(base: string, resolved: string): boolean;
24
+ /**
25
+ * Resolve `relativePath` against `base` and return the absolute path only if it
26
+ * stays within `base` (after symlink resolution); otherwise return `null`.
27
+ *
28
+ * Prefer this over a bare `resolve()` followed by a separate `isSafePath()`
29
+ * check: collapsing the two into one call means a caller cannot resolve a
30
+ * project-relative path and then forget the containment guard — the gap that
31
+ * let the symlink-escape slip past several call sites historically.
32
+ */
33
+ export declare function resolveWithinProject(base: string, relativePath: string): string | null;
34
+ //# sourceMappingURL=safePath.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safePath.d.ts","sourceRoot":"","sources":["../src/safePath.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAgClE;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAGtF"}
@@ -0,0 +1,71 @@
1
+ import { resolve, sep, join, dirname, basename } from "node:path";
2
+ import { realpathSync } from "node:fs";
3
+ /**
4
+ * Reject paths that escape the `base` directory — including via symlinks.
5
+ *
6
+ * `path.resolve()` collapses `.`/`..` but does NOT dereference symlinks, so a
7
+ * plain prefix check (`resolved.startsWith(base + sep)`) can be defeated by a
8
+ * symlink that lives *inside* `base` but points outside it (e.g.
9
+ * `base/link -> /etc`). A downstream `readFileSync`/`writeFileSync`/`statSync`
10
+ * then follows that link to a file outside `base`. To close this we canonicalize
11
+ * both sides with `realpathSync` before comparing.
12
+ *
13
+ * The target may not exist yet (e.g. creating a new file), so we canonicalize the
14
+ * deepest *existing* ancestor and re-attach the trailing not-yet-existing
15
+ * segments. Segments that don't exist cannot be symlinks at check time, so they
16
+ * can't redirect the path outside `base` right now. (A symlink swapped in between
17
+ * this check and the subsequent fs call is an inherent TOCTOU race this helper
18
+ * does not, and cannot by itself, defend against.)
19
+ *
20
+ * Lives at the package root rather than under `studio-api/` because callers span
21
+ * layers — `studio-api` routes, the `compiler`, the CLI, and the engine — and
22
+ * `compiler` sits below `studio-api` in the dependency graph, so it cannot import
23
+ * from there without a backwards edge.
24
+ */
25
+ export function isSafePath(base, resolved) {
26
+ let baseReal;
27
+ try {
28
+ baseReal = realpathSync(resolve(base));
29
+ }
30
+ catch {
31
+ // Base must exist and be resolvable; fail closed if not.
32
+ return false;
33
+ }
34
+ const target = resolve(resolved);
35
+ const trailing = [];
36
+ let probe = target;
37
+ for (;;) {
38
+ let ancestorReal;
39
+ try {
40
+ ancestorReal = realpathSync(probe);
41
+ }
42
+ catch {
43
+ const parent = dirname(probe);
44
+ if (parent === probe)
45
+ return false; // walked past the filesystem root
46
+ trailing.push(basename(probe));
47
+ probe = parent;
48
+ continue;
49
+ }
50
+ // Copy before reverse(): the array is only consumed once today, but a future
51
+ // edit that loops would otherwise silently misorder the rebuilt segments.
52
+ const targetReal = trailing.length
53
+ ? join(ancestorReal, ...[...trailing].reverse())
54
+ : ancestorReal;
55
+ return targetReal === baseReal || targetReal.startsWith(baseReal + sep);
56
+ }
57
+ }
58
+ /**
59
+ * Resolve `relativePath` against `base` and return the absolute path only if it
60
+ * stays within `base` (after symlink resolution); otherwise return `null`.
61
+ *
62
+ * Prefer this over a bare `resolve()` followed by a separate `isSafePath()`
63
+ * check: collapsing the two into one call means a caller cannot resolve a
64
+ * project-relative path and then forget the containment guard — the gap that
65
+ * let the symlink-escape slip past several call sites historically.
66
+ */
67
+ export function resolveWithinProject(base, relativePath) {
68
+ const resolved = resolve(base, relativePath);
69
+ return isSafePath(base, resolved) ? resolved : null;
70
+ }
71
+ //# sourceMappingURL=safePath.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"safePath.js","sourceRoot":"","sources":["../src/safePath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAEvC;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,QAAgB;IACvD,IAAI,QAAgB,CAAC;IACrB,IAAI,CAAC;QACH,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;IACzC,CAAC;IAAC,MAAM,CAAC;QACP,yDAAyD;QACzD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,KAAK,GAAG,MAAM,CAAC;IAEnB,SAAS,CAAC;QACR,IAAI,YAAoB,CAAC;QACzB,IAAI,CAAC;YACH,YAAY,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;YAC9B,IAAI,MAAM,KAAK,KAAK;gBAAE,OAAO,KAAK,CAAC,CAAC,kCAAkC;YACtE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;YAC/B,KAAK,GAAG,MAAM,CAAC;YACf,SAAS;QACX,CAAC;QAED,6EAA6E;QAC7E,0EAA0E;QAC1E,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM;YAChC,CAAC,CAAC,IAAI,CAAC,YAAY,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,OAAO,EAAE,CAAC;YAChD,CAAC,CAAC,YAAY,CAAC;QACjB,OAAO,UAAU,KAAK,QAAQ,IAAI,UAAU,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAC;IAC1E,CAAC;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,oBAAoB,CAAC,IAAY,EAAE,YAAoB;IACrE,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IAC7C,OAAO,UAAU,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC;AACtD,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface BackupJournalResult {
2
+ backupPath: string | null;
3
+ error?: string;
4
+ }
5
+ export declare function backupPathForResponse(projectDir: string, backupPath: string | null): string | null;
6
+ export declare function snapshotBeforeWrite(projectDir: string, absPath: string, options?: {
7
+ keepPerFile?: number;
8
+ }): BackupJournalResult;
9
+ //# sourceMappingURL=backupJournal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backupJournal.d.ts","sourceRoot":"","sources":["../../../src/studio-api/helpers/backupJournal.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAUD,wBAAgB,qBAAqB,CACnC,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,MAAM,GAAG,IAAI,GACxB,MAAM,GAAG,IAAI,CAKf;AAED,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAO,GACrC,mBAAmB,CA0BrB"}
@@ -0,0 +1,81 @@
1
+ import { mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
2
+ import { Buffer } from "node:buffer";
3
+ import { join, relative } from "node:path";
4
+ import { isSafePath } from "./safePath.js";
5
+ const DEFAULT_KEEP_PER_FILE = 10;
6
+ function backupKeyForPath(path) {
7
+ return Buffer.from(path, "utf-8").toString("base64url");
8
+ }
9
+ function timestampPrefix() {
10
+ return new Date().toISOString().replace(/[:.]/g, "-");
11
+ }
12
+ export function backupPathForResponse(projectDir, backupPath) {
13
+ if (!backupPath)
14
+ return null;
15
+ const rel = relative(projectDir, backupPath);
16
+ if (!rel || rel.startsWith(".."))
17
+ return null;
18
+ return rel.split("\\").join("/");
19
+ }
20
+ export function snapshotBeforeWrite(projectDir, absPath, options = {}) {
21
+ if (!isSafePath(projectDir, absPath))
22
+ return { backupPath: null };
23
+ try {
24
+ const content = readFileSync(absPath);
25
+ const relativePath = relative(projectDir, absPath);
26
+ const backupDir = join(projectDir, ".hyperframes", "backup");
27
+ mkdirSync(backupDir, { recursive: true });
28
+ const backupKey = backupKeyForPath(relativePath);
29
+ const backupPath = nextBackupPath(backupDir, backupKey);
30
+ writeFileSync(backupPath, content);
31
+ pruneBackups(backupDir, backupKey, options.keepPerFile ?? DEFAULT_KEEP_PER_FILE);
32
+ return { backupPath };
33
+ }
34
+ catch (error) {
35
+ if (error &&
36
+ typeof error === "object" &&
37
+ "code" in error &&
38
+ (error.code === "ENOENT" || error.code === "EISDIR")) {
39
+ return { backupPath: null };
40
+ }
41
+ return { backupPath: null, error: error instanceof Error ? error.message : String(error) };
42
+ }
43
+ }
44
+ function nextBackupPath(backupDir, backupKey) {
45
+ const base = `${timestampPrefix()}-${backupKey}`;
46
+ let candidate = join(backupDir, base);
47
+ let counter = 2;
48
+ while (true) {
49
+ try {
50
+ readFileSync(candidate);
51
+ }
52
+ catch (error) {
53
+ if (error && typeof error === "object" && "code" in error && error.code === "ENOENT") {
54
+ return candidate;
55
+ }
56
+ throw error;
57
+ }
58
+ candidate = join(backupDir, `${base}-${counter}`);
59
+ counter += 1;
60
+ }
61
+ }
62
+ function pruneBackups(backupDir, backupKey, keepPerFile) {
63
+ const keep = Math.max(1, Math.floor(keepPerFile));
64
+ const suffix = `-${backupKey}`;
65
+ const numberedSuffix = new RegExp(`-${backupKey}-\\d+$`);
66
+ const matches = readdirSync(backupDir)
67
+ .filter((name) => name.endsWith(suffix) || numberedSuffix.test(name))
68
+ .map((name) => join(backupDir, name))
69
+ .sort((a, b) => {
70
+ return b.localeCompare(a);
71
+ });
72
+ for (const file of matches.slice(keep)) {
73
+ try {
74
+ unlinkSync(file);
75
+ }
76
+ catch {
77
+ // Backup pruning is best-effort and must not block the user's write.
78
+ }
79
+ }
80
+ }
81
+ //# sourceMappingURL=backupJournal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"backupJournal.js","sourceRoot":"","sources":["../../../src/studio-api/helpers/backupJournal.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ export interface UnsafeMutationValue {
2
+ path: string;
3
+ reason: "non-finite-number" | "null";
4
+ }
5
+ interface FindUnsafeMutationValuesOptions {
6
+ allowNullPath?: (path: string) => boolean;
7
+ }
8
+ export declare function findUnsafeMutationValues(value: unknown, path?: string, options?: FindUnsafeMutationValuesOptions): UnsafeMutationValue[];
9
+ export declare function findUnsafeDomPatchValues(value: unknown): UnsafeMutationValue[];
10
+ export {};
11
+ //# sourceMappingURL=finiteMutation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finiteMutation.d.ts","sourceRoot":"","sources":["../../../src/studio-api/helpers/finiteMutation.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,mBAAmB,GAAG,MAAM,CAAC;CACtC;AAED,UAAU,+BAA+B;IACvC,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CAC3C;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,OAAO,EACd,IAAI,SAAS,EACb,OAAO,GAAE,+BAAoC,GAC5C,mBAAmB,EAAE,CAgBvB;AAID,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,EAAE,CAI9E"}
@@ -0,0 +1,21 @@
1
+ export function findUnsafeMutationValues(value, path = "body", options = {}) {
2
+ if (value === null) {
3
+ return options.allowNullPath?.(path) ? [] : [{ path, reason: "null" }];
4
+ }
5
+ if (typeof value === "number") {
6
+ return Number.isFinite(value) ? [] : [{ path, reason: "non-finite-number" }];
7
+ }
8
+ if (!value || typeof value !== "object")
9
+ return [];
10
+ if (Array.isArray(value)) {
11
+ return value.flatMap((item, index) => findUnsafeMutationValues(item, `${path}[${index}]`, options));
12
+ }
13
+ return Object.entries(value).flatMap(([key, item]) => findUnsafeMutationValues(item, `${path}.${key}`, options));
14
+ }
15
+ const DOM_PATCH_NULL_VALUE_PATH = /^body\.operations\[\d+\]\.value$/;
16
+ export function findUnsafeDomPatchValues(value) {
17
+ return findUnsafeMutationValues(value, "body", {
18
+ allowNullPath: (path) => DOM_PATCH_NULL_VALUE_PATH.test(path),
19
+ });
20
+ }
21
+ //# sourceMappingURL=finiteMutation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finiteMutation.js","sourceRoot":"","sources":["../../../src/studio-api/helpers/finiteMutation.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,wBAAwB,CACtC,KAAc,EACd,IAAI,GAAG,MAAM,EACb,UAA2C,EAAE;IAE7C,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACnB,OAAO,OAAO,CAAC,aAAa,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzE,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC/E,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,EAAE,CAAC;IACnD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CACnC,wBAAwB,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,KAAK,GAAG,EAAE,OAAO,CAAC,CAC7D,CAAC;IACJ,CAAC;IACD,OAAO,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,CACnD,wBAAwB,CAAC,IAAI,EAAE,GAAG,IAAI,IAAI,GAAG,EAAE,EAAE,OAAO,CAAC,CAC1D,CAAC;AACJ,CAAC;AAED,MAAM,yBAAyB,GAAG,kCAAkC,CAAC;AAErE,MAAM,UAAU,wBAAwB,CAAC,KAAc;IACrD,OAAO,wBAAwB,CAAC,KAAK,EAAE,MAAM,EAAE;QAC7C,aAAa,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,IAAI,CAAC;KAC9D,CAAC,CAAC;AACL,CAAC"}
@@ -1,5 +1,12 @@
1
- /** Reject paths that escape the project directory. */
2
- export declare function isSafePath(base: string, resolved: string): boolean;
1
+ export { isSafePath, resolveWithinProject } from "../../safePath.js";
2
+ /**
3
+ * True when any directory segment of a relative path is a dot-directory or
4
+ * node_modules. Projects that vendor tooling assets under dot-directories
5
+ * (.hyperframes/, .cache/, …) ship example/preset HTML that must not surface
6
+ * as project compositions or studio lint targets (#1384). The file tree is
7
+ * deliberately not filtered — this only gates discovery.
8
+ */
9
+ export declare function isInHiddenOrVendorDir(relPath: string): boolean;
3
10
  /** Recursively walk a directory and return relative file paths. */
4
11
  export declare function walkDir(dir: string, prefix?: string): string[];
5
12
  //# sourceMappingURL=safePath.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"safePath.d.ts","sourceRoot":"","sources":["../../../src/studio-api/helpers/safePath.ts"],"names":[],"mappings":"AAGA,sDAAsD;AACtD,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGlE;AAID,mEAAmE;AACnE,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,EAAE,CAY1D"}
1
+ {"version":3,"file":"safePath.d.ts","sourceRoot":"","sources":["../../../src/studio-api/helpers/safePath.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAQrE;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAG9D;AAED,mEAAmE;AACnE,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,SAAK,GAAG,MAAM,EAAE,CAY1D"}
@@ -1,18 +1,31 @@
1
- import { resolve, sep, join } from "node:path";
1
+ import { join } from "node:path";
2
2
  import { readdirSync } from "node:fs";
3
- /** Reject paths that escape the project directory. */
4
- export function isSafePath(base, resolved) {
5
- const norm = resolve(base) + sep;
6
- return resolved.startsWith(norm) || resolved === resolve(base);
7
- }
3
+ // `isSafePath` lives at the package root so non-studio-api layers (compiler,
4
+ // CLI, engine) can share it without a backwards dependency on studio-api.
5
+ // Re-exported here for back-compat with existing `../helpers/safePath.js` imports.
6
+ export { isSafePath, resolveWithinProject } from "../../safePath.js";
8
7
  const IGNORE_DIRS = new Set([".thumbnails", "node_modules", ".git"]);
8
+ function shouldIgnoreDir(rel) {
9
+ return rel === ".hyperframes/backup";
10
+ }
11
+ /**
12
+ * True when any directory segment of a relative path is a dot-directory or
13
+ * node_modules. Projects that vendor tooling assets under dot-directories
14
+ * (.hyperframes/, .cache/, …) ship example/preset HTML that must not surface
15
+ * as project compositions or studio lint targets (#1384). The file tree is
16
+ * deliberately not filtered — this only gates discovery.
17
+ */
18
+ export function isInHiddenOrVendorDir(relPath) {
19
+ const segments = relPath.split("/");
20
+ return segments.slice(0, -1).some((seg) => seg.startsWith(".") || seg === "node_modules");
21
+ }
9
22
  /** Recursively walk a directory and return relative file paths. */
10
23
  export function walkDir(dir, prefix = "") {
11
24
  const files = [];
12
25
  for (const entry of readdirSync(dir, { withFileTypes: true })) {
13
- if (IGNORE_DIRS.has(entry.name))
14
- continue;
15
26
  const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
27
+ if (IGNORE_DIRS.has(entry.name) || shouldIgnoreDir(rel))
28
+ continue;
16
29
  if (entry.isDirectory()) {
17
30
  files.push(...walkDir(join(dir, entry.name), rel));
18
31
  }
@@ -1 +1 @@
1
- {"version":3,"file":"safePath.js","sourceRoot":"","sources":["../../../src/studio-api/helpers/safePath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,sDAAsD;AACtD,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,QAAgB;IACvD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;IACjC,OAAO,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,QAAQ,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAErE,mEAAmE;AACnE,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,MAAM,GAAG,EAAE;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC;YAAE,SAAS;QAC1C,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5D,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"safePath.js","sourceRoot":"","sources":["../../../src/studio-api/helpers/safePath.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAEtC,6EAA6E;AAC7E,0EAA0E;AAC1E,mFAAmF;AACnF,OAAO,EAAE,UAAU,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAErE,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,aAAa,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC,CAAC;AAErE,SAAS,eAAe,CAAC,GAAW;IAClC,OAAO,GAAG,KAAK,qBAAqB,CAAC;AACvC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAAe;IACnD,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,GAAG,KAAK,cAAc,CAAC,CAAC;AAC5F,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,OAAO,CAAC,GAAW,EAAE,MAAM,GAAG,EAAE;IAC9C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5D,IAAI,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,eAAe,CAAC,GAAG,CAAC;YAAE,SAAS;QAClE,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACN,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/studio-api/routes/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAcjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAywBpD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAuV7E"}
1
+ {"version":3,"file":"files.d.ts","sourceRoot":"","sources":["../../../src/studio-api/routes/files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAcjC,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAuyBpD,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,GAAG,IAAI,CA2Y7E"}