@hyperframes/studio-server 0.8.135 → 0.8.137
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.d.ts +3 -1
- package/dist/index.js +41 -10
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -25,6 +25,8 @@ import './helpers/mediaCodecMap.js';
|
|
|
25
25
|
*/
|
|
26
26
|
declare function createStudioApi(adapter: StudioApiAdapter): Hono;
|
|
27
27
|
|
|
28
|
+
declare const MAX_UPLOAD_BYTES: number;
|
|
29
|
+
|
|
28
30
|
/**
|
|
29
31
|
* Whether a write at `changedPath` can change `createProjectSignature(projectDir)`.
|
|
30
32
|
*
|
|
@@ -226,4 +228,4 @@ type BackgroundRemovalRender = (options: {
|
|
|
226
228
|
}>;
|
|
227
229
|
declare function createBackgroundRemovalJob(opts: BackgroundRemovalJobOptions, render: BackgroundRemovalRender): MediaProcessingJobState;
|
|
228
230
|
|
|
229
|
-
export { type AppliedFileMutation, type BackgroundRemovalRender, DELETED_VERSION, type DuplicateElementResult, type FileMutationInput, type FileWriteReceipt, MIME_TYPES, MediaProcessingJobState, PREVIEW_BUNDLE_OPTIONS, SourceMutationTarget, StudioApiAdapter, type ThumbnailOutputDimensions, affectsPreview, affectsProjectSignature, applyFileMutations, buildSubCompositionHtml, cleanupProxyCache, compositionsAffectedBy, consumeFileWriteReceipt, createBackgroundRemovalJob, createPreviewDocumentStore, createProjectSignature, createStudioApi, duplicateElementInHtml, fileContentVersion, getMimeType, identifyFileWrite, requestSubPath, settledFileTag, thumbnailDeviceScaleFactor };
|
|
231
|
+
export { type AppliedFileMutation, type BackgroundRemovalRender, DELETED_VERSION, type DuplicateElementResult, type FileMutationInput, type FileWriteReceipt, MAX_UPLOAD_BYTES, MIME_TYPES, MediaProcessingJobState, PREVIEW_BUNDLE_OPTIONS, SourceMutationTarget, StudioApiAdapter, type ThumbnailOutputDimensions, affectsPreview, affectsProjectSignature, applyFileMutations, buildSubCompositionHtml, cleanupProxyCache, compositionsAffectedBy, consumeFileWriteReceipt, createBackgroundRemovalJob, createPreviewDocumentStore, createProjectSignature, createStudioApi, duplicateElementInHtml, fileContentVersion, getMimeType, identifyFileWrite, requestSubPath, settledFileTag, thumbnailDeviceScaleFactor };
|
package/dist/index.js
CHANGED
|
@@ -2681,8 +2681,8 @@ async function foldAtomicCutFile(c, file, absPath, before, writer) {
|
|
|
2681
2681
|
skippedSelectors: [...skippedSelectors]
|
|
2682
2682
|
};
|
|
2683
2683
|
}
|
|
2684
|
+
var MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
2684
2685
|
async function processUploadedFiles(formData, targetDir, projectDir) {
|
|
2685
|
-
const MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
2686
2686
|
const uploaded = [];
|
|
2687
2687
|
const skipped = [];
|
|
2688
2688
|
const invalid = [];
|
|
@@ -3495,7 +3495,6 @@ function registerFileRoutes(api, adapter) {
|
|
|
3495
3495
|
}
|
|
3496
3496
|
return c.json({ ok: true, path: copyPath }, 201);
|
|
3497
3497
|
});
|
|
3498
|
-
const MAX_UPLOAD_BYTES = 500 * 1024 * 1024;
|
|
3499
3498
|
api.post(
|
|
3500
3499
|
"/projects/:id/upload",
|
|
3501
3500
|
bodyLimit({
|
|
@@ -3597,7 +3596,7 @@ function registerFileRoutes(api, adapter) {
|
|
|
3597
3596
|
}
|
|
3598
3597
|
|
|
3599
3598
|
// src/routes/preview.ts
|
|
3600
|
-
import { parseHTML as
|
|
3599
|
+
import { parseHTML as parseHTML7 } from "linkedom";
|
|
3601
3600
|
import { createReadStream, existsSync as existsSync5, readFileSync as readFileSync6, statSync as statSync4 } from "fs";
|
|
3602
3601
|
import { Readable } from "stream";
|
|
3603
3602
|
import { join as join8, resolve as resolve4 } from "path";
|
|
@@ -3619,8 +3618,13 @@ import { ensureHfIds as ensureHfIds2 } from "@hyperframes/parsers/hf-ids";
|
|
|
3619
3618
|
// src/helpers/previewReads.ts
|
|
3620
3619
|
import { readlinkSync as readlinkSync2 } from "fs";
|
|
3621
3620
|
import { dirname as dirname4, join as join7, parse, relative as relative3, resolve as resolve3 } from "path";
|
|
3621
|
+
import { parseHTML as parseHTML5 } from "linkedom";
|
|
3622
3622
|
var ALWAYS_AFFECTS = ["hyperframes.json", ...STUDIO_SIGNATURE_MANIFEST_PATHS];
|
|
3623
|
+
var MAX_PREVIEW_PATH_LENGTH = 4096;
|
|
3624
|
+
var SHOW_ELEMENT = 1;
|
|
3623
3625
|
var REFERENCE = /\b(?:src|href|poster|data-composition-src)\s*=\s*(?:"([^"\n]*)"|'([^'\n]*)')|url\(\s*(?:"([^"\n]*)"|'([^'\n]*)'|([^"'\s)]+))/gi;
|
|
3626
|
+
var REFERENCE_ATTRIBUTE = /\b(?:src|href|poster|data-composition-src)$/i;
|
|
3627
|
+
var isElement = (node) => node.nodeType === 1;
|
|
3624
3628
|
var pathKey = process.platform === "darwin" || process.platform === "win32" ? (path) => resolve3(path).toLowerCase() : (path) => resolve3(path);
|
|
3625
3629
|
var readsByProject = /* @__PURE__ */ new Map();
|
|
3626
3630
|
var builtProjects = /* @__PURE__ */ new Set();
|
|
@@ -3645,6 +3649,7 @@ function linksOnTheWay(path) {
|
|
|
3645
3649
|
continue;
|
|
3646
3650
|
}
|
|
3647
3651
|
const next = join7(at, part);
|
|
3652
|
+
if (next.length > MAX_PREVIEW_PATH_LENGTH) return passed;
|
|
3648
3653
|
const target = hops < 40 ? readLink(next) : null;
|
|
3649
3654
|
if (target === null) {
|
|
3650
3655
|
at = next;
|
|
@@ -3660,26 +3665,51 @@ function linksOnTheWay(path) {
|
|
|
3660
3665
|
return passed;
|
|
3661
3666
|
}
|
|
3662
3667
|
function recordPreviewRead(projectDir, filePath) {
|
|
3668
|
+
if (filePath.length > MAX_PREVIEW_PATH_LENGTH) return;
|
|
3663
3669
|
const key = projectKey(projectDir);
|
|
3664
3670
|
let reads = readsByProject.get(key);
|
|
3665
3671
|
if (!reads) readsByProject.set(key, reads = /* @__PURE__ */ new Set());
|
|
3666
3672
|
const read = inRealProject(projectDir, filePath);
|
|
3673
|
+
if (read.length > MAX_PREVIEW_PATH_LENGTH) return;
|
|
3667
3674
|
for (const found of [read, ...linksOnTheWay(read)]) {
|
|
3668
3675
|
for (let path = pathKey(found); !reads.has(path); path = dirname4(path)) reads.add(path);
|
|
3669
3676
|
}
|
|
3670
3677
|
}
|
|
3671
3678
|
function recordPreviewReferences(projectDir, html) {
|
|
3672
3679
|
const named = /* @__PURE__ */ new Set();
|
|
3673
|
-
|
|
3674
|
-
const url =
|
|
3675
|
-
if (!url || /^(?:[a-z][a-z0-9+.-]*:|[/#])/i.test(url))
|
|
3680
|
+
const add = (reference) => {
|
|
3681
|
+
const url = reference.trim();
|
|
3682
|
+
if (!url || /^(?:[a-z][a-z0-9+.-]*:|[/#])/i.test(url)) return;
|
|
3676
3683
|
const path = url.split(/[?#]/)[0] ?? "";
|
|
3677
3684
|
let decoded = path;
|
|
3678
3685
|
try {
|
|
3679
3686
|
decoded = decodeURIComponent(path);
|
|
3680
3687
|
} catch {
|
|
3681
3688
|
}
|
|
3682
|
-
if (decoded) named.add(decoded);
|
|
3689
|
+
if (decoded && decoded.length <= MAX_PREVIEW_PATH_LENGTH) named.add(decoded);
|
|
3690
|
+
};
|
|
3691
|
+
const scan = (text2) => {
|
|
3692
|
+
for (const match of text2.matchAll(REFERENCE)) {
|
|
3693
|
+
add(match[1] ?? match[2] ?? match[3] ?? match[4] ?? match[5] ?? "");
|
|
3694
|
+
}
|
|
3695
|
+
};
|
|
3696
|
+
const scanElement = (element) => {
|
|
3697
|
+
for (const attribute of element.attributes) {
|
|
3698
|
+
if (REFERENCE_ATTRIBUTE.test(attribute.name)) add(attribute.value);
|
|
3699
|
+
}
|
|
3700
|
+
const style = element.getAttribute("style");
|
|
3701
|
+
if (style) scan(style);
|
|
3702
|
+
if (element.localName === "style" || element.localName === "script") {
|
|
3703
|
+
scan(element.textContent ?? "");
|
|
3704
|
+
}
|
|
3705
|
+
};
|
|
3706
|
+
const { document } = parseHTML5(html);
|
|
3707
|
+
for (const root of document.children) {
|
|
3708
|
+
scanElement(root);
|
|
3709
|
+
const elements = document.createTreeWalker(root, SHOW_ELEMENT);
|
|
3710
|
+
for (let node = elements.nextNode(); node; node = elements.nextNode()) {
|
|
3711
|
+
if (isElement(node)) scanElement(node);
|
|
3712
|
+
}
|
|
3683
3713
|
}
|
|
3684
3714
|
for (const path of named) recordPreviewRead(projectDir, path);
|
|
3685
3715
|
}
|
|
@@ -3717,7 +3747,7 @@ function injectPreviewVariables(html, values) {
|
|
|
3717
3747
|
|
|
3718
3748
|
// src/helpers/lazyPreviewImages.ts
|
|
3719
3749
|
import { findStartTags } from "@hyperframes/core/compiler/html-document";
|
|
3720
|
-
import { parseHTML as
|
|
3750
|
+
import { parseHTML as parseHTML6 } from "linkedom";
|
|
3721
3751
|
import { STUDIO_PREVIEW_LAZY_ATTR } from "@hyperframes/core/studio-preview-mark";
|
|
3722
3752
|
function startsAfterZero(el) {
|
|
3723
3753
|
for (let node = el; node; node = node.parentElement) {
|
|
@@ -3728,7 +3758,7 @@ function startsAfterZero(el) {
|
|
|
3728
3758
|
var hasLoading = (img) => Array.from(img.attributes).some((attr) => attr.name.toLowerCase() === "loading");
|
|
3729
3759
|
function lazyPreviewImages(html) {
|
|
3730
3760
|
if (!/<!doctype|<html[\s>]/i.test(html)) return html;
|
|
3731
|
-
const images = [...
|
|
3761
|
+
const images = [...parseHTML6(html).document.querySelectorAll("img")];
|
|
3732
3762
|
const tags = findStartTags(html, "img");
|
|
3733
3763
|
if (tags.length !== images.length) return html;
|
|
3734
3764
|
const parts = [];
|
|
@@ -3819,7 +3849,7 @@ function isGsapCoreUrl(src) {
|
|
|
3819
3849
|
return URL.canParse(src, base) && /\/gsap(\.min)?\.js$/i.test(new URL(src, base).pathname);
|
|
3820
3850
|
}
|
|
3821
3851
|
function findGsapCoreScript(html) {
|
|
3822
|
-
const scripts = [...
|
|
3852
|
+
const scripts = [...parseHTML7(html).document.querySelectorAll("script")];
|
|
3823
3853
|
const starts = findStartTags2(html, "script");
|
|
3824
3854
|
if (starts.length !== scripts.length) return null;
|
|
3825
3855
|
const at = scripts.findIndex(
|
|
@@ -6401,6 +6431,7 @@ export {
|
|
|
6401
6431
|
HistoryBusyError,
|
|
6402
6432
|
HistoryClosedError,
|
|
6403
6433
|
HistoryIdError,
|
|
6434
|
+
MAX_UPLOAD_BYTES,
|
|
6404
6435
|
MAX_WINDOW_IDLE_MS,
|
|
6405
6436
|
MIME_TYPES,
|
|
6406
6437
|
PREVIEW_BUNDLE_OPTIONS,
|