hyperframes 0.4.4 → 0.4.5
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/cli.js +102 -75
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,7 @@ var VERSION;
|
|
|
54
54
|
var init_version = __esm({
|
|
55
55
|
"src/version.ts"() {
|
|
56
56
|
"use strict";
|
|
57
|
-
VERSION = true ? "0.4.
|
|
57
|
+
VERSION = true ? "0.4.5" : "0.0.0-dev";
|
|
58
58
|
}
|
|
59
59
|
});
|
|
60
60
|
|
|
@@ -6245,7 +6245,15 @@ function runSkillsAdd(repo) {
|
|
|
6245
6245
|
return new Promise((resolve35, reject) => {
|
|
6246
6246
|
const child = spawn("npx", ["skills", "add", repo, "--all"], {
|
|
6247
6247
|
stdio: "inherit",
|
|
6248
|
-
timeout: 12e4
|
|
6248
|
+
timeout: 12e4,
|
|
6249
|
+
// GH #316 — the upstream `skills` CLI shells out to `git clone`.
|
|
6250
|
+
// When Git's clone-hook protection is active (shipped on by
|
|
6251
|
+
// default in 2.45.1, reverted in 2.45.2, still present on many
|
|
6252
|
+
// corporate and CI setups), any globally-registered
|
|
6253
|
+
// `git lfs install` post-checkout hook aborts the clone. The
|
|
6254
|
+
// `repo` reaching this function is hardcoded in SOURCES below
|
|
6255
|
+
// — no user input reaches the spawn — so opting out here is safe.
|
|
6256
|
+
env: { ...process.env, GIT_CLONE_PROTECTION_ACTIVE: "0" }
|
|
6249
6257
|
});
|
|
6250
6258
|
child.on("close", (code, signal) => {
|
|
6251
6259
|
if (code === 0) resolve35();
|
|
@@ -10507,10 +10515,10 @@ function compareDocumentPosition(nodeA, nodeB) {
|
|
|
10507
10515
|
function uniqueSort(nodes) {
|
|
10508
10516
|
nodes = nodes.filter((node, i2, arr) => !arr.includes(node, i2 + 1));
|
|
10509
10517
|
nodes.sort((a, b) => {
|
|
10510
|
-
const
|
|
10511
|
-
if (
|
|
10518
|
+
const relative5 = compareDocumentPosition(a, b);
|
|
10519
|
+
if (relative5 & DocumentPosition.PRECEDING) {
|
|
10512
10520
|
return -1;
|
|
10513
|
-
} else if (
|
|
10521
|
+
} else if (relative5 & DocumentPosition.FOLLOWING) {
|
|
10514
10522
|
return 1;
|
|
10515
10523
|
}
|
|
10516
10524
|
return 0;
|
|
@@ -24302,6 +24310,40 @@ var init_ffprobe2 = __esm({
|
|
|
24302
24310
|
}
|
|
24303
24311
|
});
|
|
24304
24312
|
|
|
24313
|
+
// ../producer/src/utils/paths.ts
|
|
24314
|
+
import { resolve as resolve13, basename, join as join27, relative as relative2, isAbsolute as isAbsolute3 } from "path";
|
|
24315
|
+
function isPathInside(childPath, parentPath) {
|
|
24316
|
+
const absChild = resolve13(childPath);
|
|
24317
|
+
const absParent = resolve13(parentPath);
|
|
24318
|
+
if (absChild === absParent) return true;
|
|
24319
|
+
const rel = relative2(absParent, absChild);
|
|
24320
|
+
return rel !== "" && !rel.startsWith("..") && !isAbsolute3(rel);
|
|
24321
|
+
}
|
|
24322
|
+
function toExternalAssetKey(absPath) {
|
|
24323
|
+
if (absPath.startsWith("hf-ext/")) return absPath;
|
|
24324
|
+
let normalised = absPath.replace(/\\/g, "/");
|
|
24325
|
+
normalised = normalised.replace(/^\/\/\?\/UNC\//i, "//");
|
|
24326
|
+
normalised = normalised.replace(/^\/\/\?\//, "");
|
|
24327
|
+
normalised = normalised.replace(/^\/\/([^/]+)\//, "unc/$1/");
|
|
24328
|
+
normalised = normalised.replace(/^\/+/, "");
|
|
24329
|
+
normalised = normalised.replace(/^([A-Za-z]):\/?/, "$1/");
|
|
24330
|
+
return "hf-ext/" + normalised;
|
|
24331
|
+
}
|
|
24332
|
+
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
24333
|
+
const absoluteProjectDir = resolve13(projectDir);
|
|
24334
|
+
const projectName = basename(absoluteProjectDir);
|
|
24335
|
+
const resolvedOutputPath = outputPath ?? join27(rendersDir, `${projectName}.mp4`);
|
|
24336
|
+
const absoluteOutputPath = resolve13(resolvedOutputPath);
|
|
24337
|
+
return { absoluteProjectDir, absoluteOutputPath };
|
|
24338
|
+
}
|
|
24339
|
+
var DEFAULT_RENDERS_DIR;
|
|
24340
|
+
var init_paths = __esm({
|
|
24341
|
+
"../producer/src/utils/paths.ts"() {
|
|
24342
|
+
"use strict";
|
|
24343
|
+
DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve13(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
24344
|
+
}
|
|
24345
|
+
});
|
|
24346
|
+
|
|
24305
24347
|
// ../producer/src/utils/urlDownloader.ts
|
|
24306
24348
|
var init_urlDownloader2 = __esm({
|
|
24307
24349
|
"../producer/src/utils/urlDownloader.ts"() {
|
|
@@ -24365,7 +24407,7 @@ var init_fontData_generated = __esm({
|
|
|
24365
24407
|
// ../producer/src/services/deterministicFonts.ts
|
|
24366
24408
|
import { existsSync as existsSync25, mkdirSync as mkdirSync15, readFileSync as readFileSync18, writeFileSync as writeFileSync9 } from "fs";
|
|
24367
24409
|
import { homedir as homedir6 } from "os";
|
|
24368
|
-
import { join as
|
|
24410
|
+
import { join as join28 } from "path";
|
|
24369
24411
|
function normalizeFamilyName(family) {
|
|
24370
24412
|
return family.trim().replace(/^['"]|['"]$/g, "").trim().toLowerCase();
|
|
24371
24413
|
}
|
|
@@ -24476,14 +24518,14 @@ function fontSlug(familyName) {
|
|
|
24476
24518
|
return familyName.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
|
|
24477
24519
|
}
|
|
24478
24520
|
function fontCacheDir(slug) {
|
|
24479
|
-
const dir =
|
|
24521
|
+
const dir = join28(GOOGLE_FONTS_CACHE_DIR, slug);
|
|
24480
24522
|
if (!existsSync25(dir)) {
|
|
24481
24523
|
mkdirSync15(dir, { recursive: true });
|
|
24482
24524
|
}
|
|
24483
24525
|
return dir;
|
|
24484
24526
|
}
|
|
24485
24527
|
function cachedWoff2Path(slug, weight, style) {
|
|
24486
|
-
return
|
|
24528
|
+
return join28(fontCacheDir(slug), `${weight}-${style}.woff2`);
|
|
24487
24529
|
}
|
|
24488
24530
|
async function fetchGoogleFont(familyName) {
|
|
24489
24531
|
const slug = fontSlug(familyName);
|
|
@@ -24695,14 +24737,14 @@ var init_deterministicFonts = __esm({
|
|
|
24695
24737
|
poppins: "poppins",
|
|
24696
24738
|
"segoe ui": "roboto"
|
|
24697
24739
|
};
|
|
24698
|
-
GOOGLE_FONTS_CACHE_DIR =
|
|
24740
|
+
GOOGLE_FONTS_CACHE_DIR = join28(homedir6(), ".cache", "hyperframes", "fonts");
|
|
24699
24741
|
WOFF2_USER_AGENT = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36";
|
|
24700
24742
|
}
|
|
24701
24743
|
});
|
|
24702
24744
|
|
|
24703
24745
|
// ../producer/src/services/htmlCompiler.ts
|
|
24704
24746
|
import { readFileSync as readFileSync19, existsSync as existsSync26, mkdirSync as mkdirSync16 } from "fs";
|
|
24705
|
-
import { join as
|
|
24747
|
+
import { join as join29, dirname as dirname9, resolve as resolve14 } from "path";
|
|
24706
24748
|
import postcss from "postcss";
|
|
24707
24749
|
function dedupeElementsById(elements) {
|
|
24708
24750
|
const deduped = /* @__PURE__ */ new Map();
|
|
@@ -24721,7 +24763,7 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
24721
24763
|
return { duration: 0, resolvedPath: src };
|
|
24722
24764
|
}
|
|
24723
24765
|
} else if (!filePath.startsWith("/")) {
|
|
24724
|
-
filePath =
|
|
24766
|
+
filePath = join29(baseDir, filePath);
|
|
24725
24767
|
}
|
|
24726
24768
|
if (!existsSync26(filePath)) {
|
|
24727
24769
|
return { duration: 0, resolvedPath: filePath };
|
|
@@ -24787,7 +24829,7 @@ async function parseSubCompositions(html, projectDir, downloadDir, parentOffset
|
|
|
24787
24829
|
const elEnd = elEndRaw ? parseFloat(elEndRaw) : Infinity;
|
|
24788
24830
|
const absoluteStart = parentOffset + elStart;
|
|
24789
24831
|
const absoluteEnd = Math.min(parentEnd, isFinite(elEnd) ? parentOffset + elEnd : Infinity);
|
|
24790
|
-
const filePath =
|
|
24832
|
+
const filePath = resolve14(projectDir, srcPath);
|
|
24791
24833
|
if (visited.has(filePath)) {
|
|
24792
24834
|
continue;
|
|
24793
24835
|
}
|
|
@@ -24987,7 +25029,7 @@ function inlineSubCompositions(html, subCompositions, projectDir) {
|
|
|
24987
25029
|
if (!srcPath) continue;
|
|
24988
25030
|
let compHtml = subCompositions.get(srcPath) || null;
|
|
24989
25031
|
if (!compHtml) {
|
|
24990
|
-
const filePath =
|
|
25032
|
+
const filePath = resolve14(projectDir, srcPath);
|
|
24991
25033
|
if (existsSync26(filePath)) {
|
|
24992
25034
|
compHtml = readFileSync19(filePath, "utf-8");
|
|
24993
25035
|
}
|
|
@@ -25200,7 +25242,7 @@ ${safeText}
|
|
|
25200
25242
|
return result;
|
|
25201
25243
|
}
|
|
25202
25244
|
function collectExternalAssets(html, projectDir) {
|
|
25203
|
-
const absProjectDir =
|
|
25245
|
+
const absProjectDir = resolve14(projectDir);
|
|
25204
25246
|
const externalAssets = /* @__PURE__ */ new Map();
|
|
25205
25247
|
const CSS_URL_RE2 = /\burl\(\s*(["']?)([^)"']+)\1\s*\)/g;
|
|
25206
25248
|
function processPath(rawPath) {
|
|
@@ -25208,12 +25250,12 @@ function collectExternalAssets(html, projectDir) {
|
|
|
25208
25250
|
if (!trimmed || trimmed.startsWith("/") || trimmed.startsWith("http://") || trimmed.startsWith("https://") || trimmed.startsWith("//") || trimmed.startsWith("data:") || trimmed.startsWith("#")) {
|
|
25209
25251
|
return null;
|
|
25210
25252
|
}
|
|
25211
|
-
const absPath =
|
|
25212
|
-
if (
|
|
25253
|
+
const absPath = resolve14(absProjectDir, trimmed);
|
|
25254
|
+
if (isPathInside(absPath, absProjectDir)) {
|
|
25213
25255
|
return null;
|
|
25214
25256
|
}
|
|
25215
25257
|
if (!existsSync26(absPath)) return null;
|
|
25216
|
-
const safeKey =
|
|
25258
|
+
const safeKey = toExternalAssetKey(absPath);
|
|
25217
25259
|
externalAssets.set(safeKey, absPath);
|
|
25218
25260
|
return safeKey;
|
|
25219
25261
|
}
|
|
@@ -25285,7 +25327,7 @@ async function compileForRender(projectDir, htmlPath, downloadDir) {
|
|
|
25285
25327
|
const audios = dedupeElementsById([...mainAudios, ...subAudios]);
|
|
25286
25328
|
for (const video of videos) {
|
|
25287
25329
|
if (isHttpUrl(video.src)) continue;
|
|
25288
|
-
const videoPath =
|
|
25330
|
+
const videoPath = resolve14(projectDir, video.src);
|
|
25289
25331
|
const reencode = `ffmpeg -i "${video.src}" -c:v libx264 -r 30 -g 30 -keyint_min 30 -movflags +faststart -c:a copy output.mp4`;
|
|
25290
25332
|
Promise.all([analyzeKeyframeIntervals(videoPath), extractVideoMetadata(videoPath)]).then(([analysis, metadata]) => {
|
|
25291
25333
|
if (analysis.isProblematic) {
|
|
@@ -25420,6 +25462,7 @@ var init_htmlCompiler2 = __esm({
|
|
|
25420
25462
|
init_esm10();
|
|
25421
25463
|
init_src();
|
|
25422
25464
|
init_ffprobe2();
|
|
25465
|
+
init_paths();
|
|
25423
25466
|
init_src2();
|
|
25424
25467
|
init_urlDownloader2();
|
|
25425
25468
|
init_deterministicFonts();
|
|
@@ -25478,7 +25521,7 @@ import {
|
|
|
25478
25521
|
copyFileSync as copyFileSync2,
|
|
25479
25522
|
appendFileSync
|
|
25480
25523
|
} from "fs";
|
|
25481
|
-
import { join as
|
|
25524
|
+
import { join as join30, dirname as dirname10, resolve as resolve15 } from "path";
|
|
25482
25525
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
25483
25526
|
import { freemem as freemem2 } from "os";
|
|
25484
25527
|
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
@@ -25534,17 +25577,17 @@ function installDebugLogger(logPath, log = defaultLogger) {
|
|
|
25534
25577
|
};
|
|
25535
25578
|
}
|
|
25536
25579
|
function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
25537
|
-
const compileDir =
|
|
25580
|
+
const compileDir = join30(workDir, "compiled");
|
|
25538
25581
|
mkdirSync17(compileDir, { recursive: true });
|
|
25539
|
-
writeFileSync10(
|
|
25582
|
+
writeFileSync10(join30(compileDir, "index.html"), compiled.html, "utf-8");
|
|
25540
25583
|
for (const [srcPath, html] of compiled.subCompositions) {
|
|
25541
|
-
const outPath =
|
|
25584
|
+
const outPath = join30(compileDir, srcPath);
|
|
25542
25585
|
mkdirSync17(dirname10(outPath), { recursive: true });
|
|
25543
25586
|
writeFileSync10(outPath, html, "utf-8");
|
|
25544
25587
|
}
|
|
25545
25588
|
for (const [relativePath, absolutePath] of compiled.externalAssets) {
|
|
25546
|
-
const outPath =
|
|
25547
|
-
if (!outPath
|
|
25589
|
+
const outPath = resolve15(join30(compileDir, relativePath));
|
|
25590
|
+
if (!isPathInside(outPath, compileDir)) {
|
|
25548
25591
|
console.warn(`[Render] Skipping external asset with unsafe path: ${relativePath}`);
|
|
25549
25592
|
continue;
|
|
25550
25593
|
}
|
|
@@ -25572,7 +25615,7 @@ function writeCompiledArtifacts(compiled, workDir, includeSummary) {
|
|
|
25572
25615
|
})),
|
|
25573
25616
|
subCompositions: Array.from(compiled.subCompositions.keys())
|
|
25574
25617
|
};
|
|
25575
|
-
writeFileSync10(
|
|
25618
|
+
writeFileSync10(join30(compileDir, "summary.json"), JSON.stringify(summary, null, 2), "utf-8");
|
|
25576
25619
|
}
|
|
25577
25620
|
}
|
|
25578
25621
|
function createRenderJob(config) {
|
|
@@ -25616,9 +25659,9 @@ function extractStandaloneEntryFromIndex(indexHtml, entryFile) {
|
|
|
25616
25659
|
}
|
|
25617
25660
|
async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSignal) {
|
|
25618
25661
|
const moduleDir = dirname10(fileURLToPath3(import.meta.url));
|
|
25619
|
-
const producerRoot = process.env.PRODUCER_RENDERS_DIR ?
|
|
25620
|
-
const debugDir =
|
|
25621
|
-
const workDir = job.config.debug ?
|
|
25662
|
+
const producerRoot = process.env.PRODUCER_RENDERS_DIR ? resolve15(process.env.PRODUCER_RENDERS_DIR, "..") : resolve15(moduleDir, "../..");
|
|
25663
|
+
const debugDir = join30(producerRoot, ".debug");
|
|
25664
|
+
const workDir = job.config.debug ? join30(debugDir, job.id) : join30(dirname10(outputPath), `work-${job.id}`);
|
|
25622
25665
|
const pipelineStart = Date.now();
|
|
25623
25666
|
const log = job.config.logger ?? defaultLogger;
|
|
25624
25667
|
let fileServer = null;
|
|
@@ -25626,7 +25669,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25626
25669
|
let lastBrowserConsole = [];
|
|
25627
25670
|
let restoreLogger = null;
|
|
25628
25671
|
const perfStages = {};
|
|
25629
|
-
const perfOutputPath =
|
|
25672
|
+
const perfOutputPath = join30(workDir, "perf-summary.json");
|
|
25630
25673
|
const cfg = { ...job.config.producerConfig ?? resolveConfig() };
|
|
25631
25674
|
const outputFormat = job.config.format ?? "mp4";
|
|
25632
25675
|
const isWebm = outputFormat === "webm";
|
|
@@ -25648,19 +25691,19 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25648
25691
|
assertNotAborted();
|
|
25649
25692
|
if (!existsSync27(workDir)) mkdirSync17(workDir, { recursive: true });
|
|
25650
25693
|
if (job.config.debug) {
|
|
25651
|
-
const logPath =
|
|
25694
|
+
const logPath = join30(workDir, "render.log");
|
|
25652
25695
|
restoreLogger = installDebugLogger(logPath, log);
|
|
25653
25696
|
}
|
|
25654
25697
|
const entryFile = job.config.entryFile || "index.html";
|
|
25655
|
-
let htmlPath =
|
|
25698
|
+
let htmlPath = join30(projectDir, entryFile);
|
|
25656
25699
|
if (!existsSync27(htmlPath)) {
|
|
25657
25700
|
throw new Error(`Entry file not found: ${htmlPath}`);
|
|
25658
25701
|
}
|
|
25659
25702
|
assertNotAborted();
|
|
25660
25703
|
const rawEntry = readFileSync20(htmlPath, "utf-8");
|
|
25661
25704
|
if (entryFile !== "index.html" && rawEntry.trimStart().startsWith("<template")) {
|
|
25662
|
-
const wrapperPath =
|
|
25663
|
-
const projectIndexPath =
|
|
25705
|
+
const wrapperPath = join30(workDir, "standalone-entry.html");
|
|
25706
|
+
const projectIndexPath = join30(projectDir, "index.html");
|
|
25664
25707
|
if (!existsSync27(projectIndexPath)) {
|
|
25665
25708
|
throw new Error(
|
|
25666
25709
|
`Template entry file "${entryFile}" requires a project index.html to extract its render shell.`
|
|
@@ -25684,7 +25727,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25684
25727
|
const stage1Start = Date.now();
|
|
25685
25728
|
updateJobStatus(job, "preprocessing", "Compiling composition", 5, onProgress);
|
|
25686
25729
|
const compileStart = Date.now();
|
|
25687
|
-
let compiled = await compileForRender(projectDir, htmlPath,
|
|
25730
|
+
let compiled = await compileForRender(projectDir, htmlPath, join30(workDir, "downloads"));
|
|
25688
25731
|
assertNotAborted();
|
|
25689
25732
|
perfStages.compileOnlyMs = Date.now() - compileStart;
|
|
25690
25733
|
writeCompiledArtifacts(compiled, workDir, Boolean(job.config.debug));
|
|
@@ -25713,7 +25756,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25713
25756
|
reasons.push(`${compiled.unresolvedCompositions.length} unresolved composition(s)`);
|
|
25714
25757
|
fileServer = await createFileServer2({
|
|
25715
25758
|
projectDir,
|
|
25716
|
-
compiledDir:
|
|
25759
|
+
compiledDir: join30(workDir, "compiled"),
|
|
25717
25760
|
port: 0
|
|
25718
25761
|
});
|
|
25719
25762
|
assertNotAborted();
|
|
@@ -25726,7 +25769,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25726
25769
|
};
|
|
25727
25770
|
probeSession = await createCaptureSession(
|
|
25728
25771
|
fileServer.url,
|
|
25729
|
-
|
|
25772
|
+
join30(workDir, "probe"),
|
|
25730
25773
|
captureOpts,
|
|
25731
25774
|
null,
|
|
25732
25775
|
cfg
|
|
@@ -25758,7 +25801,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25758
25801
|
compiled,
|
|
25759
25802
|
resolutions,
|
|
25760
25803
|
projectDir,
|
|
25761
|
-
|
|
25804
|
+
join30(workDir, "downloads")
|
|
25762
25805
|
);
|
|
25763
25806
|
assertNotAborted();
|
|
25764
25807
|
composition.videos = compiled.videos;
|
|
@@ -25893,12 +25936,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25893
25936
|
const stage2Start = Date.now();
|
|
25894
25937
|
updateJobStatus(job, "preprocessing", "Extracting video frames", 10, onProgress);
|
|
25895
25938
|
let frameLookup = null;
|
|
25896
|
-
const compiledDir =
|
|
25939
|
+
const compiledDir = join30(workDir, "compiled");
|
|
25897
25940
|
if (composition.videos.length > 0) {
|
|
25898
25941
|
const extractionResult = await extractAllVideoFrames(
|
|
25899
25942
|
composition.videos,
|
|
25900
25943
|
projectDir,
|
|
25901
|
-
{ fps: job.config.fps, outputDir:
|
|
25944
|
+
{ fps: job.config.fps, outputDir: join30(workDir, "video-frames") },
|
|
25902
25945
|
abortSignal,
|
|
25903
25946
|
void 0,
|
|
25904
25947
|
compiledDir
|
|
@@ -25932,13 +25975,13 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25932
25975
|
}
|
|
25933
25976
|
const stage3Start = Date.now();
|
|
25934
25977
|
updateJobStatus(job, "preprocessing", "Processing audio tracks", 20, onProgress);
|
|
25935
|
-
const audioOutputPath =
|
|
25978
|
+
const audioOutputPath = join30(workDir, "audio.aac");
|
|
25936
25979
|
let hasAudio = false;
|
|
25937
25980
|
if (composition.audios.length > 0) {
|
|
25938
25981
|
const audioResult = await processCompositionAudio(
|
|
25939
25982
|
composition.audios,
|
|
25940
25983
|
projectDir,
|
|
25941
|
-
|
|
25984
|
+
join30(workDir, "audio-work"),
|
|
25942
25985
|
audioOutputPath,
|
|
25943
25986
|
job.duration,
|
|
25944
25987
|
abortSignal,
|
|
@@ -25956,12 +25999,12 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25956
25999
|
if (!fileServer) {
|
|
25957
26000
|
fileServer = await createFileServer2({
|
|
25958
26001
|
projectDir,
|
|
25959
|
-
compiledDir:
|
|
26002
|
+
compiledDir: join30(workDir, "compiled"),
|
|
25960
26003
|
port: 0
|
|
25961
26004
|
});
|
|
25962
26005
|
assertNotAborted();
|
|
25963
26006
|
}
|
|
25964
|
-
const framesDir =
|
|
26007
|
+
const framesDir = join30(workDir, "captured-frames");
|
|
25965
26008
|
if (!existsSync27(framesDir)) mkdirSync17(framesDir, { recursive: true });
|
|
25966
26009
|
const captureOptions = {
|
|
25967
26010
|
width,
|
|
@@ -25973,7 +26016,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
25973
26016
|
const workerCount = calculateOptimalWorkers(job.totalFrames, job.config.workers, cfg);
|
|
25974
26017
|
const FORMAT_EXT2 = { mp4: ".mp4", webm: ".webm", mov: ".mov" };
|
|
25975
26018
|
const videoExt = FORMAT_EXT2[outputFormat] ?? ".mp4";
|
|
25976
|
-
const videoOnlyPath =
|
|
26019
|
+
const videoOnlyPath = join30(workDir, `video-only${videoExt}`);
|
|
25977
26020
|
const preset = getEncoderPreset(job.config.quality, outputFormat);
|
|
25978
26021
|
const effectiveQuality = job.config.crf ?? preset.quality;
|
|
25979
26022
|
const effectiveBitrate = job.config.videoBitrate;
|
|
@@ -26249,7 +26292,7 @@ async function executeRenderJob(job, projectDir, outputPath, onProgress, abortSi
|
|
|
26249
26292
|
}
|
|
26250
26293
|
if (job.config.debug) {
|
|
26251
26294
|
if (existsSync27(outputPath)) {
|
|
26252
|
-
const debugOutput =
|
|
26295
|
+
const debugOutput = join30(workDir, `output${videoExt}`);
|
|
26253
26296
|
copyFileSync2(outputPath, debugOutput);
|
|
26254
26297
|
}
|
|
26255
26298
|
} else {
|
|
@@ -26350,6 +26393,7 @@ var init_renderOrchestrator = __esm({
|
|
|
26350
26393
|
init_fileServer2();
|
|
26351
26394
|
init_htmlCompiler2();
|
|
26352
26395
|
init_logger();
|
|
26396
|
+
init_paths();
|
|
26353
26397
|
RenderCancelledError = class extends Error {
|
|
26354
26398
|
reason;
|
|
26355
26399
|
constructor(message = "render_cancelled", reason = "aborted") {
|
|
@@ -26387,7 +26431,7 @@ var init_config3 = __esm({
|
|
|
26387
26431
|
|
|
26388
26432
|
// ../producer/src/services/hyperframeLint.ts
|
|
26389
26433
|
import { existsSync as existsSync28, readFileSync as readFileSync21, statSync as statSync8 } from "fs";
|
|
26390
|
-
import { resolve as
|
|
26434
|
+
import { resolve as resolve16, join as join31 } from "path";
|
|
26391
26435
|
function isStringRecord(value) {
|
|
26392
26436
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
26393
26437
|
return false;
|
|
@@ -26414,7 +26458,7 @@ function pickEntryFile(files, preferredEntryFile) {
|
|
|
26414
26458
|
return null;
|
|
26415
26459
|
}
|
|
26416
26460
|
function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
26417
|
-
const absProjectDir =
|
|
26461
|
+
const absProjectDir = resolve16(projectDir);
|
|
26418
26462
|
if (!existsSync28(absProjectDir) || !statSync8(absProjectDir).isDirectory()) {
|
|
26419
26463
|
return { error: `Project directory not found: ${absProjectDir}` };
|
|
26420
26464
|
}
|
|
@@ -26422,7 +26466,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
26422
26466
|
(value) => typeof value === "string" && value.trim().length > 0
|
|
26423
26467
|
);
|
|
26424
26468
|
for (const entryFile of entryCandidates) {
|
|
26425
|
-
const absoluteEntryPath =
|
|
26469
|
+
const absoluteEntryPath = resolve16(absProjectDir, entryFile);
|
|
26426
26470
|
if (!absoluteEntryPath.startsWith(absProjectDir)) {
|
|
26427
26471
|
return { error: `Entry file must stay inside project directory: ${entryFile}` };
|
|
26428
26472
|
}
|
|
@@ -26435,7 +26479,7 @@ function readProjectEntryFile(projectDir, preferredEntryFile) {
|
|
|
26435
26479
|
}
|
|
26436
26480
|
}
|
|
26437
26481
|
return {
|
|
26438
|
-
error: `No HTML entry file found in project directory: ${
|
|
26482
|
+
error: `No HTML entry file found in project directory: ${join31(absProjectDir, preferredEntryFile || "index.html")}`
|
|
26439
26483
|
};
|
|
26440
26484
|
}
|
|
26441
26485
|
function prepareHyperframeLintBody(body) {
|
|
@@ -26481,23 +26525,6 @@ var init_hyperframeLint = __esm({
|
|
|
26481
26525
|
}
|
|
26482
26526
|
});
|
|
26483
26527
|
|
|
26484
|
-
// ../producer/src/utils/paths.ts
|
|
26485
|
-
import { resolve as resolve16, basename, join as join31 } from "path";
|
|
26486
|
-
function resolveRenderPaths(projectDir, outputPath, rendersDir = DEFAULT_RENDERS_DIR) {
|
|
26487
|
-
const absoluteProjectDir = resolve16(projectDir);
|
|
26488
|
-
const projectName = basename(absoluteProjectDir);
|
|
26489
|
-
const resolvedOutputPath = outputPath ?? join31(rendersDir, `${projectName}.mp4`);
|
|
26490
|
-
const absoluteOutputPath = resolve16(resolvedOutputPath);
|
|
26491
|
-
return { absoluteProjectDir, absoluteOutputPath };
|
|
26492
|
-
}
|
|
26493
|
-
var DEFAULT_RENDERS_DIR;
|
|
26494
|
-
var init_paths = __esm({
|
|
26495
|
-
"../producer/src/utils/paths.ts"() {
|
|
26496
|
-
"use strict";
|
|
26497
|
-
DEFAULT_RENDERS_DIR = process.env.PRODUCER_RENDERS_DIR ?? resolve16(new URL(import.meta.url).pathname, "../../..", "renders");
|
|
26498
|
-
}
|
|
26499
|
-
});
|
|
26500
|
-
|
|
26501
26528
|
// ../producer/src/utils/semaphore.ts
|
|
26502
26529
|
var Semaphore;
|
|
26503
26530
|
var init_semaphore = __esm({
|
|
@@ -28300,7 +28327,7 @@ __export(add_exports, {
|
|
|
28300
28327
|
runAdd: () => runAdd
|
|
28301
28328
|
});
|
|
28302
28329
|
import { existsSync as existsSync33 } from "fs";
|
|
28303
|
-
import { resolve as resolve21, relative as
|
|
28330
|
+
import { resolve as resolve21, relative as relative3 } from "path";
|
|
28304
28331
|
function remapTarget(item, originalTarget, paths) {
|
|
28305
28332
|
if (item.type === "hyperframes:block") {
|
|
28306
28333
|
const blocksDir = paths.blocks.replace(/\/+$/, "");
|
|
@@ -28439,7 +28466,7 @@ var init_add = __esm({
|
|
|
28439
28466
|
console.log("");
|
|
28440
28467
|
console.log(`${c.success("\u2713")} Added ${c.accent(result.name)} (${result.type})`);
|
|
28441
28468
|
for (const file of result.written) {
|
|
28442
|
-
console.log(` ${c.dim(
|
|
28469
|
+
console.log(` ${c.dim(relative3(projectDir, file))}`);
|
|
28443
28470
|
}
|
|
28444
28471
|
if (result.snippet) {
|
|
28445
28472
|
console.log("");
|
|
@@ -30868,18 +30895,18 @@ function checkFFmpeg() {
|
|
|
30868
30895
|
return {
|
|
30869
30896
|
ok: false,
|
|
30870
30897
|
detail: "Not found",
|
|
30871
|
-
hint:
|
|
30898
|
+
hint: getFFmpegInstallHint()
|
|
30872
30899
|
};
|
|
30873
30900
|
}
|
|
30874
30901
|
function checkFFprobe() {
|
|
30875
30902
|
try {
|
|
30876
|
-
const
|
|
30877
|
-
return { ok: true, detail:
|
|
30903
|
+
const version = execSync3("ffprobe -version", { encoding: "utf-8", timeout: 5e3 }).split("\n")[0] ?? "";
|
|
30904
|
+
return { ok: true, detail: version.trim() };
|
|
30878
30905
|
} catch {
|
|
30879
30906
|
return {
|
|
30880
30907
|
ok: false,
|
|
30881
30908
|
detail: "Not found",
|
|
30882
|
-
hint:
|
|
30909
|
+
hint: `Installed with ffmpeg \u2014 ${getFFmpegInstallHint()}`
|
|
30883
30910
|
};
|
|
30884
30911
|
}
|
|
30885
30912
|
}
|
|
@@ -31531,7 +31558,7 @@ __export(snapshot_exports, {
|
|
|
31531
31558
|
examples: () => examples18
|
|
31532
31559
|
});
|
|
31533
31560
|
import { existsSync as existsSync44, readFileSync as readFileSync31, mkdirSync as mkdirSync24 } from "fs";
|
|
31534
|
-
import { resolve as resolve32, join as join44, dirname as dirname20, relative as
|
|
31561
|
+
import { resolve as resolve32, join as join44, dirname as dirname20, relative as relative4, isAbsolute as isAbsolute4 } from "path";
|
|
31535
31562
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
31536
31563
|
async function captureSnapshots(projectDir, opts) {
|
|
31537
31564
|
const { bundleToSingleHtml: bundleToSingleHtml2 } = await Promise.resolve().then(() => (init_compiler(), compiler_exports));
|
|
@@ -31564,8 +31591,8 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
31564
31591
|
return;
|
|
31565
31592
|
}
|
|
31566
31593
|
const filePath = resolve32(projectDir, decodeURIComponent(url).replace(/^\//, ""));
|
|
31567
|
-
const rel =
|
|
31568
|
-
if (rel.startsWith("..") ||
|
|
31594
|
+
const rel = relative4(projectDir, filePath);
|
|
31595
|
+
if (rel.startsWith("..") || isAbsolute4(rel)) {
|
|
31569
31596
|
res.writeHead(403);
|
|
31570
31597
|
res.end();
|
|
31571
31598
|
return;
|