hyperframes 0.7.92 → 0.7.94
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 +1905 -381
- package/dist/hyperframes-player.global.js +1 -1
- package/dist/studio/assets/{hyperframes-player-9qOa08Tv.js → hyperframes-player-D4mryRja.js} +1 -1
- package/dist/studio/assets/{index-CDTN2ZVa.js → index-B0NWErIq.js} +1 -1
- package/dist/studio/assets/{index-Bw4lNdtO.js → index-BWh5m2-P.js} +1 -1
- package/dist/studio/assets/index-CH_dyqrx.js +428 -0
- package/dist/studio/assets/index-D78KEjgB.css +1 -0
- package/dist/studio/index.d.ts +20 -20
- package/dist/studio/index.html +2 -2
- package/dist/studio/index.js +7055 -5321
- package/dist/studio/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/studio/assets/index-BXkzp_OU.css +0 -1
- package/dist/studio/assets/index-DIntkrQl.js +0 -428
package/dist/cli.js
CHANGED
|
@@ -50,7 +50,7 @@ var VERSION;
|
|
|
50
50
|
var init_version = __esm({
|
|
51
51
|
"src/version.ts"() {
|
|
52
52
|
"use strict";
|
|
53
|
-
VERSION = true ? "0.7.
|
|
53
|
+
VERSION = true ? "0.7.94" : "0.0.0-dev";
|
|
54
54
|
}
|
|
55
55
|
});
|
|
56
56
|
|
|
@@ -52025,8 +52025,62 @@ function containsTimelineCall(node, timelineVar) {
|
|
|
52025
52025
|
function rangeOf(node) {
|
|
52026
52026
|
return typeof node.start === "number" && typeof node.end === "number" ? [node.start, node.end] : void 0;
|
|
52027
52027
|
}
|
|
52028
|
+
function isSafeDefaultExpression(node, earlierParams) {
|
|
52029
|
+
let safe = true;
|
|
52030
|
+
const visit = (current2, parent, key2) => {
|
|
52031
|
+
if (!isNode2(current2) || !safe) return;
|
|
52032
|
+
if (!SAFE_DEFAULT_NODES.has(current2.type)) {
|
|
52033
|
+
safe = false;
|
|
52034
|
+
return;
|
|
52035
|
+
}
|
|
52036
|
+
if (current2.type === "UnaryExpression" && current2.operator === "delete") {
|
|
52037
|
+
safe = false;
|
|
52038
|
+
return;
|
|
52039
|
+
}
|
|
52040
|
+
if (current2.type === "Identifier") {
|
|
52041
|
+
const nonValue = parent && key2 ? isNonValueIdentifierSlot(parent, key2) : false;
|
|
52042
|
+
if (!nonValue && current2.name !== "undefined" && !earlierParams.has(current2.name)) {
|
|
52043
|
+
safe = false;
|
|
52044
|
+
}
|
|
52045
|
+
return;
|
|
52046
|
+
}
|
|
52047
|
+
for (const childKey of Object.keys(current2)) {
|
|
52048
|
+
if (SKIP_KEYS.has(childKey)) continue;
|
|
52049
|
+
const child = current2[childKey];
|
|
52050
|
+
if (Array.isArray(child)) {
|
|
52051
|
+
for (const item of child) visit(item, current2, childKey);
|
|
52052
|
+
} else {
|
|
52053
|
+
visit(child, current2, childKey);
|
|
52054
|
+
}
|
|
52055
|
+
}
|
|
52056
|
+
};
|
|
52057
|
+
visit(node);
|
|
52058
|
+
return safe;
|
|
52059
|
+
}
|
|
52060
|
+
function supportedParam(param, earlier) {
|
|
52061
|
+
if (param.type === "Identifier") return { name: param.name };
|
|
52062
|
+
if (param.type !== "AssignmentPattern" || param.left?.type !== "Identifier") return null;
|
|
52063
|
+
if (!isSafeDefaultExpression(param.right, earlier)) return null;
|
|
52064
|
+
return { name: param.left.name, defaultExpression: param.right };
|
|
52065
|
+
}
|
|
52066
|
+
function supportedParams(fn) {
|
|
52067
|
+
if (SUPPORTED_PARAMS_CACHE.has(fn)) return SUPPORTED_PARAMS_CACHE.get(fn) ?? null;
|
|
52068
|
+
const params = [];
|
|
52069
|
+
const earlier = /* @__PURE__ */ new Set();
|
|
52070
|
+
for (const param of fn.params ?? []) {
|
|
52071
|
+
const parsed = supportedParam(param, earlier);
|
|
52072
|
+
if (!parsed) {
|
|
52073
|
+
SUPPORTED_PARAMS_CACHE.set(fn, null);
|
|
52074
|
+
return null;
|
|
52075
|
+
}
|
|
52076
|
+
params.push(parsed);
|
|
52077
|
+
earlier.add(parsed.name);
|
|
52078
|
+
}
|
|
52079
|
+
SUPPORTED_PARAMS_CACHE.set(fn, params);
|
|
52080
|
+
return params;
|
|
52081
|
+
}
|
|
52028
52082
|
function isShapeEligible(fn) {
|
|
52029
|
-
return isFunctionNode(fn) && fn.body?.type === "BlockStatement" &&
|
|
52083
|
+
return isFunctionNode(fn) && fn.body?.type === "BlockStatement" && supportedParams(fn) !== null;
|
|
52030
52084
|
}
|
|
52031
52085
|
function callsAny(node, names) {
|
|
52032
52086
|
let hit = false;
|
|
@@ -52076,20 +52130,55 @@ function timelineBuildingNames(candidates, timelineVar) {
|
|
|
52076
52130
|
function bump(counts, key2) {
|
|
52077
52131
|
counts.set(key2, (counts.get(key2) ?? 0) + 1);
|
|
52078
52132
|
}
|
|
52133
|
+
function undefinedIdentifier() {
|
|
52134
|
+
return { type: "Identifier", name: "undefined" };
|
|
52135
|
+
}
|
|
52136
|
+
function isExplicitUndefined(node) {
|
|
52137
|
+
return node?.type === "Identifier" && node.name === "undefined" || node?.type === "UnaryExpression" && node.operator === "void" && node.argument?.type === "Literal" && node.argument.value === 0;
|
|
52138
|
+
}
|
|
52139
|
+
function resolveHelperBindings(call, params) {
|
|
52140
|
+
if (call.arguments?.some((arg) => arg?.type === "SpreadElement")) return null;
|
|
52141
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
52142
|
+
for (let i2 = 0; i2 < params.length; i2++) {
|
|
52143
|
+
const param = params[i2];
|
|
52144
|
+
const arg = call.arguments?.[i2];
|
|
52145
|
+
if (arg && !isExplicitUndefined(arg)) {
|
|
52146
|
+
bindings.set(param.name, arg);
|
|
52147
|
+
} else if (param.defaultExpression) {
|
|
52148
|
+
bindings.set(param.name, substituteParams(cloneNode2(param.defaultExpression), bindings));
|
|
52149
|
+
} else {
|
|
52150
|
+
bindings.set(param.name, undefinedIdentifier());
|
|
52151
|
+
}
|
|
52152
|
+
}
|
|
52153
|
+
return bindings;
|
|
52154
|
+
}
|
|
52155
|
+
function statementHelperCall(node, names) {
|
|
52156
|
+
if (node.type !== "ExpressionStatement") return void 0;
|
|
52157
|
+
const expression = node.expression;
|
|
52158
|
+
if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier") {
|
|
52159
|
+
return void 0;
|
|
52160
|
+
}
|
|
52161
|
+
return names.has(expression.callee.name) ? expression : void 0;
|
|
52162
|
+
}
|
|
52079
52163
|
function safelyDroppable(program, candidates) {
|
|
52080
52164
|
const names = new Set(candidates.keys());
|
|
52081
52165
|
const totalIds = /* @__PURE__ */ new Map();
|
|
52082
52166
|
const stmtCalls = /* @__PURE__ */ new Map();
|
|
52167
|
+
const unbindable = /* @__PURE__ */ new Set();
|
|
52083
52168
|
walkNodes(program, (n2) => {
|
|
52084
52169
|
if (n2.type === "Identifier" && names.has(n2.name)) bump(totalIds, n2.name);
|
|
52085
|
-
const
|
|
52086
|
-
if (
|
|
52087
|
-
|
|
52088
|
-
|
|
52170
|
+
const call = statementHelperCall(n2, names);
|
|
52171
|
+
if (!call) return;
|
|
52172
|
+
bump(stmtCalls, call.callee.name);
|
|
52173
|
+
const fn = candidates.get(call.callee.name);
|
|
52174
|
+
const params = fn && supportedParams(fn);
|
|
52175
|
+
if (!params || !resolveHelperBindings(call, params)) unbindable.add(call.callee.name);
|
|
52089
52176
|
});
|
|
52090
52177
|
const safe = /* @__PURE__ */ new Map();
|
|
52091
52178
|
for (const [name, fn] of candidates) {
|
|
52092
|
-
if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0))
|
|
52179
|
+
if (!unbindable.has(name) && (totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) {
|
|
52180
|
+
safe.set(name, fn);
|
|
52181
|
+
}
|
|
52093
52182
|
}
|
|
52094
52183
|
return safe;
|
|
52095
52184
|
}
|
|
@@ -52132,11 +52221,11 @@ function expandBody(bodyStmts, bindings, prov, ctx) {
|
|
|
52132
52221
|
}
|
|
52133
52222
|
function inlineHelper(call, ctx) {
|
|
52134
52223
|
const fn = ctx.helpers.get(call.callee.name);
|
|
52135
|
-
|
|
52136
|
-
|
|
52137
|
-
|
|
52138
|
-
|
|
52139
|
-
|
|
52224
|
+
if (!fn) return null;
|
|
52225
|
+
const params = supportedParams(fn);
|
|
52226
|
+
if (!params) return null;
|
|
52227
|
+
const bindings = resolveHelperBindings(call, params);
|
|
52228
|
+
if (!bindings) return null;
|
|
52140
52229
|
const prov = {
|
|
52141
52230
|
kind: "helper",
|
|
52142
52231
|
fn: call.callee.name,
|
|
@@ -54683,7 +54772,7 @@ function decodeUrlPathVariants(path2) {
|
|
|
54683
54772
|
}
|
|
54684
54773
|
return variants;
|
|
54685
54774
|
}
|
|
54686
|
-
var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, COMPOSITION_VARIABLE_TYPES, TIMELINE_COLORS, DEFAULT_DURATIONS, PROPERTY_GROUPS, PROP_TO_GROUP, FORBIDDEN_GSAP_PATTERNS, roundPercentage, SKIP_KEYS, FUNCTION_TYPES, GSAP_METHODS, MAX_DEPTH, MAX_ITERS, GSAP_METHODS2, QUERY_METHODS, ITERATION_METHODS, SCOPE_NODE_TYPES, CONST_NODES, MATH_FNS, MATH_CONSTS, BUILTIN_VAR_KEYS, DROPPED_VAR_KEYS, EXTRAS_KEYS, PERCENTAGE_KEY_RE, GSAP_DEFAULT_DURATION, DEFAULT_TYPEOF, EXCLUDED_TAGS, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, ClipTimingWriteError, REFERENCE_ID_PATTERN, DERIVED_END_EQUALITY_EPSILON_SECONDS, MEDIA_TYPES, CompositionHtmlParseError, UHD_SQUARE_MIN, UHD_RECT_MIN, OK, FONT_ALIAS_MAP, FONT_ALIAS_KEYS;
|
|
54775
|
+
var recast, import_parser2, CANVAS_DIMENSIONS, VALID_CANVAS_RESOLUTIONS, RESOLUTION_ALIASES, ASPECT_AGNOSTIC_RESOLUTION_ALIASES, COMPOSITION_VARIABLE_TYPES, TIMELINE_COLORS, DEFAULT_DURATIONS, PROPERTY_GROUPS, PROP_TO_GROUP, FORBIDDEN_GSAP_PATTERNS, roundPercentage, SKIP_KEYS, FUNCTION_TYPES, GSAP_METHODS, MAX_DEPTH, MAX_ITERS, SAFE_DEFAULT_NODES, SUPPORTED_PARAMS_CACHE, GSAP_METHODS2, QUERY_METHODS, ITERATION_METHODS, SCOPE_NODE_TYPES, CONST_NODES, MATH_FNS, MATH_CONSTS, BUILTIN_VAR_KEYS, DROPPED_VAR_KEYS, EXTRAS_KEYS, PERCENTAGE_KEY_RE, GSAP_DEFAULT_DURATION, DEFAULT_TYPEOF, EXCLUDED_TAGS, COMPOSITION_ATTRIBUTES, CANONICAL_AUTHORED_TIMING_ATTRIBUTES, DERIVED_TIMING_ATTRIBUTES, LEGACY_TIMING_ATTRIBUTES, ClipTimingWriteError, REFERENCE_ID_PATTERN, DERIVED_END_EQUALITY_EPSILON_SECONDS, MEDIA_TYPES, CompositionHtmlParseError, UHD_SQUARE_MIN, UHD_RECT_MIN, OK, FONT_ALIAS_MAP, FONT_ALIAS_KEYS;
|
|
54687
54776
|
var init_dist2 = __esm({
|
|
54688
54777
|
"../parsers/dist/index.js"() {
|
|
54689
54778
|
"use strict";
|
|
@@ -54791,6 +54880,23 @@ var init_dist2 = __esm({
|
|
|
54791
54880
|
GSAP_METHODS = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
54792
54881
|
MAX_DEPTH = 8;
|
|
54793
54882
|
MAX_ITERS = 512;
|
|
54883
|
+
SAFE_DEFAULT_NODES = /* @__PURE__ */ new Set([
|
|
54884
|
+
"ArrayExpression",
|
|
54885
|
+
"BinaryExpression",
|
|
54886
|
+
"ChainExpression",
|
|
54887
|
+
"ConditionalExpression",
|
|
54888
|
+
"Identifier",
|
|
54889
|
+
"Literal",
|
|
54890
|
+
"LogicalExpression",
|
|
54891
|
+
"MemberExpression",
|
|
54892
|
+
"ObjectExpression",
|
|
54893
|
+
"Property",
|
|
54894
|
+
"SpreadElement",
|
|
54895
|
+
"TemplateElement",
|
|
54896
|
+
"TemplateLiteral",
|
|
54897
|
+
"UnaryExpression"
|
|
54898
|
+
]);
|
|
54899
|
+
SUPPORTED_PARAMS_CACHE = /* @__PURE__ */ new WeakMap();
|
|
54794
54900
|
GSAP_METHODS2 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
54795
54901
|
QUERY_METHODS = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
54796
54902
|
ITERATION_METHODS = /* @__PURE__ */ new Set(["forEach", "map"]);
|
|
@@ -58530,17 +58636,46 @@ function truncateTelemetryString(value, maxLength) {
|
|
|
58530
58636
|
function redactUrlQueryStrings(value) {
|
|
58531
58637
|
return value.replace(/\b(https?:\/\/[^\s?]+)\?[^\s]*/g, "$1?\u2026");
|
|
58532
58638
|
}
|
|
58639
|
+
function redactKnownPaths(value, paths) {
|
|
58640
|
+
if (typeof value !== "string")
|
|
58641
|
+
return "";
|
|
58642
|
+
let out = value;
|
|
58643
|
+
for (const path2 of paths) {
|
|
58644
|
+
if (typeof path2 !== "string" || path2.length === 0)
|
|
58645
|
+
continue;
|
|
58646
|
+
const basename31 = path2.split(/[\\/]/).pop() ?? "";
|
|
58647
|
+
for (const literal2 of [path2, basename31].filter((v2) => v2.length > 2)) {
|
|
58648
|
+
out = out.split(literal2).join("[path]");
|
|
58649
|
+
}
|
|
58650
|
+
}
|
|
58651
|
+
return out;
|
|
58652
|
+
}
|
|
58533
58653
|
function redactFilePaths(value) {
|
|
58534
|
-
return value.replace(/file:\/\/[^\s'")]+/g, "[file-url]").replace(
|
|
58654
|
+
return value.replace(/file:\/\/[^\s'")]+/g, "[file-url]").replace(RELATIVE_PATH, "[path]").replace(BARE_RELATIVE_PATH, "[path]").replace(ABSOLUTE_PATH, "[path]").replace(ASSET_BASENAME, "[file]");
|
|
58535
58655
|
}
|
|
58536
58656
|
function redactTelemetryString(value, maxLength = MAX_TELEMETRY_STRING_LENGTH) {
|
|
58537
58657
|
return truncateTelemetryString(redactFilePaths(redactUrlQueryStrings(value)), maxLength);
|
|
58538
58658
|
}
|
|
58539
|
-
var MAX_TELEMETRY_STRING_LENGTH;
|
|
58659
|
+
var MAX_TELEMETRY_STRING_LENGTH, SEGMENT, SEGMENT_NODOT, TOKEN_TAIL, ABSOLUTE_PATH, RELATIVE_PATH, ASSET_BASENAME, BARE_RELATIVE_PATH;
|
|
58540
58660
|
var init_telemetryRedaction = __esm({
|
|
58541
58661
|
"../core/dist/telemetryRedaction.js"() {
|
|
58542
58662
|
"use strict";
|
|
58543
58663
|
MAX_TELEMETRY_STRING_LENGTH = 240;
|
|
58664
|
+
SEGMENT = String.raw`[^\s/\\'"]+`;
|
|
58665
|
+
SEGMENT_NODOT = String.raw`[^\s/\\'".]+`;
|
|
58666
|
+
TOKEN_TAIL = String.raw`[^\s'")]*`;
|
|
58667
|
+
ABSOLUTE_PATH = new RegExp(String.raw`(?<![:\w/\\])(?:[A-Za-z]:)?(?:[\\/]${SEGMENT}){2,}${TOKEN_TAIL}`, "g");
|
|
58668
|
+
RELATIVE_PATH = new RegExp(String.raw`(?<![\w/\\.])\.{1,2}(?:[\\/]${SEGMENT})+${TOKEN_TAIL}`, "g");
|
|
58669
|
+
ASSET_BASENAME = /(?<![\w/\\])[^\s/\\'"]+\.(?:mp4|mov|mkv|webm|avi|m4v|mpe?g|ts|mp3|wav|aac|m4a|flac|ogg|opus|png|jpe?g|gif|webp|svg|html?|json|srt|vtt|ass)\b/gi;
|
|
58670
|
+
BARE_RELATIVE_PATH = new RegExp([
|
|
58671
|
+
// Two or more separators: `customer/acme/video.mp4`. No extension needed —
|
|
58672
|
+
// that much structure is already a path.
|
|
58673
|
+
String.raw`(?<![^\s'\"(=,\[])(?:${SEGMENT}[\\/]){2,}${SEGMENT}${TOKEN_TAIL}`,
|
|
58674
|
+
// One separator, but the last segment carries a file extension:
|
|
58675
|
+
// `assets/bgm.mp3`. That segment is dot-free on purpose — SEGMENT includes
|
|
58676
|
+
// `.`, so a greedy one swallows the extension this rule needs.
|
|
58677
|
+
String.raw`(?<![^\s'\"(=,\[])${SEGMENT}[\\/]${SEGMENT_NODOT}\.\w{1,8}\b${TOKEN_TAIL}`
|
|
58678
|
+
].join("|"), "g");
|
|
58544
58679
|
}
|
|
58545
58680
|
});
|
|
58546
58681
|
|
|
@@ -62432,6 +62567,7 @@ __export(dist_exports, {
|
|
|
62432
62567
|
quantizeTimeToFrame: () => quantizeTimeToFrame,
|
|
62433
62568
|
queryByAttr: () => queryByAttr2,
|
|
62434
62569
|
readClipTiming: () => readClipTiming2,
|
|
62570
|
+
redactKnownPaths: () => redactKnownPaths,
|
|
62435
62571
|
redactTelemetryString: () => redactTelemetryString,
|
|
62436
62572
|
removeElementFromHtml: () => removeElementFromHtml,
|
|
62437
62573
|
resolveHfColorGradingVariables: () => resolveHfColorGradingVariables,
|
|
@@ -64060,7 +64196,7 @@ async function probeAutoBrowserGpuMode(options) {
|
|
|
64060
64196
|
const ppt = await getPuppeteerOrNull();
|
|
64061
64197
|
if (ppt === null) {
|
|
64062
64198
|
logResolvedBrowserGpuMode("software", "puppeteer unavailable");
|
|
64063
|
-
return "software";
|
|
64199
|
+
return { mode: "software", cause: "probe-error" };
|
|
64064
64200
|
}
|
|
64065
64201
|
try {
|
|
64066
64202
|
const info = await probeHardwareWebGlInfo(ppt, {
|
|
@@ -64070,20 +64206,37 @@ async function probeAutoBrowserGpuMode(options) {
|
|
|
64070
64206
|
});
|
|
64071
64207
|
const resolved2 = resolveWebGlProbeMode(info);
|
|
64072
64208
|
logResolvedBrowserGpuMode(resolved2, describeWebGlProbe(info));
|
|
64073
|
-
return resolved2;
|
|
64209
|
+
return resolved2 === "hardware" ? { mode: "hardware" } : { mode: "software", cause: "no-gpu" };
|
|
64074
64210
|
} catch (err) {
|
|
64075
64211
|
logResolvedBrowserGpuMode("software", formatProbeFailure(err));
|
|
64076
|
-
return "software";
|
|
64212
|
+
return { mode: "software", cause: "probe-error" };
|
|
64077
64213
|
}
|
|
64078
64214
|
}
|
|
64079
64215
|
function resolveBrowserGpuMode(mode, options = {}) {
|
|
64080
|
-
if (mode
|
|
64081
|
-
|
|
64082
|
-
|
|
64083
|
-
return _autoBrowserGpuModeCache
|
|
64216
|
+
if (mode === "software") return Promise.resolve(mode);
|
|
64217
|
+
_autoBrowserGpuModeCache ??= probeAutoBrowserGpuMode(options);
|
|
64218
|
+
if (mode === "auto") return _autoBrowserGpuModeCache.then((probed) => probed.mode);
|
|
64219
|
+
return _autoBrowserGpuModeCache.then((probed) => {
|
|
64220
|
+
if (probed.mode === "software" && !_unverifiedHardwareGpuWarned) {
|
|
64221
|
+
_unverifiedHardwareGpuWarned = true;
|
|
64222
|
+
console.warn(
|
|
64223
|
+
buildUnverifiedHardwareGpuWarning(options.platform ?? process.platform, probed.cause)
|
|
64224
|
+
);
|
|
64225
|
+
}
|
|
64226
|
+
return "hardware";
|
|
64227
|
+
});
|
|
64228
|
+
}
|
|
64229
|
+
function buildUnverifiedHardwareGpuWarning(platform10, cause) {
|
|
64230
|
+
if (cause === "probe-error") {
|
|
64231
|
+
return "[hyperframes] browserGpuMode=hardware was requested, but the GPU probe could not run, so hardware acceleration is UNVERIFIED \u2014 if Chrome falls back to software WebGL the capture will run at CPU speed. Honouring the explicit request anyway.\n This is a probe failure, not evidence of a missing GPU: see the `browserGpuMode probe \u2192 software (probe failed ...)` line above for the underlying error, which usually means Chrome could not launch (bad HYPERFRAMES_BROWSER_PATH, missing shared libraries, or a denied sandbox) rather than a GPU problem.\n Run `hyperframes doctor` to check the Chrome install.";
|
|
64232
|
+
}
|
|
64233
|
+
const remediation = platform10 === "linux" ? "Inside Docker, the container needs GPU passthrough: `--gpus all` with the NVIDIA Container Toolkit installed, or `--device /dev/dri` for Mesa/AMD/Intel. The image also needs the matching userspace driver + libEGL. Verify with `hyperframes render --browser-gpu` and watch for this warning disappearing." : "Check that the host exposes a GPU to this process and that the graphics drivers are installed.";
|
|
64234
|
+
return `[hyperframes] browserGpuMode=hardware was requested, but the WebGL probe found no hardware GPU \u2014 Chrome will silently fall back to software WebGL and the capture will run at CPU speed. Honouring the explicit request anyway.
|
|
64235
|
+
${remediation}
|
|
64236
|
+
Pass --no-browser-gpu to select deterministic SwiftShader instead of waiting on a hardware path that is not there.`;
|
|
64084
64237
|
}
|
|
64085
64238
|
function logResolvedBrowserGpuMode(resolved2, reason) {
|
|
64086
|
-
console.error(`[hyperframes] browserGpuMode
|
|
64239
|
+
console.error(`[hyperframes] browserGpuMode probe \u2192 ${resolved2} (${reason})`);
|
|
64087
64240
|
}
|
|
64088
64241
|
function createBrowserLaunchFingerprint(chromeArgs, config) {
|
|
64089
64242
|
const launchConfig = {
|
|
@@ -64306,7 +64459,7 @@ function getBrowserGpuArgs(mode, platform10) {
|
|
|
64306
64459
|
return ["--enable-gpu-rasterization"];
|
|
64307
64460
|
}
|
|
64308
64461
|
}
|
|
64309
|
-
var _puppeteer, CACHED_HEADLESS_SHELL_EXECUTABLES, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS, BEGINFRAME_PROBE_TIMEOUT_MS, BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS, _autoBrowserGpuModeCache, browserLeasePool, _cachedVramMb, CANVAS_DRAW_ELEMENT_FEATURE_FLAG, WEBGPU_FLAG;
|
|
64462
|
+
var _puppeteer, CACHED_HEADLESS_SHELL_EXECUTABLES, ENABLE_BROWSER_POOL, BEGINFRAME_ONLY_FLAGS, BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS, BEGINFRAME_PROBE_TIMEOUT_MS, BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS, _autoBrowserGpuModeCache, _unverifiedHardwareGpuWarned, browserLeasePool, _cachedVramMb, CANVAS_DRAW_ELEMENT_FEATURE_FLAG, WEBGPU_FLAG;
|
|
64310
64463
|
var init_browserManager = __esm({
|
|
64311
64464
|
"../engine/src/services/browserManager.ts"() {
|
|
64312
64465
|
"use strict";
|
|
@@ -64336,6 +64489,7 @@ var init_browserManager = __esm({
|
|
|
64336
64489
|
BEGINFRAME_SCREENSHOT_PROBE_ATTEMPTS = 10;
|
|
64337
64490
|
BEGINFRAME_PROBE_TIMEOUT_MS = 2e3;
|
|
64338
64491
|
BEGINFRAME_PROBE_CLEANUP_TIMEOUT_MS = 250;
|
|
64492
|
+
_unverifiedHardwareGpuWarned = false;
|
|
64339
64493
|
browserLeasePool = new BrowserLeasePool({
|
|
64340
64494
|
launch: launchBrowser,
|
|
64341
64495
|
close: async (browser) => browser.close(),
|
|
@@ -66612,6 +66766,50 @@ function formatHttpErrorDiagnostic(input2) {
|
|
|
66612
66766
|
const statusText = input2.statusText ? ` ${input2.statusText}` : "";
|
|
66613
66767
|
return `[Browser:HTTP${input2.status}] ${input2.method} ${sanitizeDiagnosticUrl(input2.url)} resource=${input2.resourceType}${statusText}`;
|
|
66614
66768
|
}
|
|
66769
|
+
function warmupFrameTimeTicks(state, intervalMs) {
|
|
66770
|
+
return state.ticks * intervalMs;
|
|
66771
|
+
}
|
|
66772
|
+
function deriveBeginFrameTimeTicks(state, warmupIntervalMs, captureIntervalMs) {
|
|
66773
|
+
const legacyCaptureTimeTicks = (state.ticks + BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS) * captureIntervalMs;
|
|
66774
|
+
const legacyCommitTimeTicks = deriveBeginFrameCommitTimeTicks(
|
|
66775
|
+
legacyCaptureTimeTicks,
|
|
66776
|
+
captureIntervalMs
|
|
66777
|
+
);
|
|
66778
|
+
const lastWarmupTimeTicks = Math.max(0, state.ticks - 1) * warmupIntervalMs;
|
|
66779
|
+
if (legacyCommitTimeTicks > lastWarmupTimeTicks) return legacyCaptureTimeTicks;
|
|
66780
|
+
const monotonicCaptureTimeTicks = warmupFrameTimeTicks(state, warmupIntervalMs) + BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS * captureIntervalMs;
|
|
66781
|
+
return monotonicCaptureTimeTicks;
|
|
66782
|
+
}
|
|
66783
|
+
function deriveBeginFrameCommitTimeTicks(captureTimeTicks, captureIntervalMs) {
|
|
66784
|
+
return captureTimeTicks - BEGIN_FRAME_COMMIT_LEAD_INTERVALS * captureIntervalMs;
|
|
66785
|
+
}
|
|
66786
|
+
function deriveBeginFrameProbeTimeTicks(captureTimeTicks, captureIntervalMs) {
|
|
66787
|
+
return Math.max(0, captureTimeTicks - BEGIN_FRAME_PROBE_LEAD_INTERVALS * captureIntervalMs);
|
|
66788
|
+
}
|
|
66789
|
+
function deriveBeginFrameTimelineTicks(state, warmupIntervalMs, captureIntervalMs) {
|
|
66790
|
+
const capture2 = deriveBeginFrameTimeTicks(state, warmupIntervalMs, captureIntervalMs);
|
|
66791
|
+
return {
|
|
66792
|
+
capture: capture2,
|
|
66793
|
+
commit: deriveBeginFrameCommitTimeTicks(capture2, captureIntervalMs),
|
|
66794
|
+
probe: deriveBeginFrameProbeTimeTicks(capture2, captureIntervalMs)
|
|
66795
|
+
};
|
|
66796
|
+
}
|
|
66797
|
+
function prepareBeginFrameTimeline(session, state, warmupIntervalMs) {
|
|
66798
|
+
const timeline = deriveBeginFrameTimelineTicks(
|
|
66799
|
+
state,
|
|
66800
|
+
warmupIntervalMs,
|
|
66801
|
+
session.beginFrameIntervalMs
|
|
66802
|
+
);
|
|
66803
|
+
session.beginFrameTimeTicks = timeline.capture;
|
|
66804
|
+
return {
|
|
66805
|
+
timeline,
|
|
66806
|
+
commitParams: {
|
|
66807
|
+
frameTimeTicks: timeline.commit,
|
|
66808
|
+
interval: session.beginFrameIntervalMs,
|
|
66809
|
+
noDisplayUpdates: false
|
|
66810
|
+
}
|
|
66811
|
+
};
|
|
66812
|
+
}
|
|
66615
66813
|
async function driveWarmupTicks(options, state) {
|
|
66616
66814
|
const sleep5 = options.sleep ?? realSleep;
|
|
66617
66815
|
while (true) {
|
|
@@ -67557,17 +67755,16 @@ async function initializeSession(session) {
|
|
|
67557
67755
|
warmupState.running = false;
|
|
67558
67756
|
await warmupLoopPromise.catch(() => {
|
|
67559
67757
|
});
|
|
67560
|
-
const
|
|
67561
|
-
|
|
67758
|
+
const preparedBeginFrameTimeline = prepareBeginFrameTimeline(
|
|
67759
|
+
session,
|
|
67760
|
+
warmupState,
|
|
67761
|
+
warmupIntervalMs
|
|
67762
|
+
);
|
|
67562
67763
|
await initDrawElementOrTransparentBackground(session, page, logInitPhase);
|
|
67563
67764
|
await armStaticDedup(session, session.page, logInitPhase);
|
|
67564
67765
|
await ensureRenderFrameSiblings(page);
|
|
67565
67766
|
const commitCdp = await getCdpSession(page);
|
|
67566
|
-
await commitCdp.send("HeadlessExperimental.beginFrame",
|
|
67567
|
-
frameTimeTicks: session.beginFrameTimeTicks - 6 * session.beginFrameIntervalMs,
|
|
67568
|
-
interval: session.beginFrameIntervalMs,
|
|
67569
|
-
noDisplayUpdates: false
|
|
67570
|
-
});
|
|
67767
|
+
await commitCdp.send("HeadlessExperimental.beginFrame", preparedBeginFrameTimeline.commitParams);
|
|
67571
67768
|
session.isInitialized = true;
|
|
67572
67769
|
}
|
|
67573
67770
|
async function captureFrameErrorDiagnostics(session, frameIndex, time, error) {
|
|
@@ -68406,7 +68603,7 @@ function getCapturePerfSummary(session) {
|
|
|
68406
68603
|
deNcprFallbacks: session.deNcprFallbacks ?? 0
|
|
68407
68604
|
};
|
|
68408
68605
|
}
|
|
68409
|
-
var DrawElementVerificationError, BROWSER_CONSOLE_BUFFER_SIZE, CAPTURE_SESSION_CLOSE_TIMEOUT_MS, LOCKED_WARMUP_TICKS, realSleep, HF_READY_DIAGNOSTIC_EXPR, LIVE_MAP_MARKERS, MAX_STATIC_DEDUP_ANALYSIS_FRAMES, STATIC_VERIFY_REFERENCE_STRIDE, STATIC_VERIFY_MAX_MS;
|
|
68606
|
+
var DrawElementVerificationError, BROWSER_CONSOLE_BUFFER_SIZE, CAPTURE_SESSION_CLOSE_TIMEOUT_MS, LOCKED_WARMUP_TICKS, realSleep, BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS, BEGIN_FRAME_COMMIT_LEAD_INTERVALS, BEGIN_FRAME_PROBE_LEAD_INTERVALS, HF_READY_DIAGNOSTIC_EXPR, LIVE_MAP_MARKERS, MAX_STATIC_DEDUP_ANALYSIS_FRAMES, STATIC_VERIFY_REFERENCE_STRIDE, STATIC_VERIFY_MAX_MS;
|
|
68410
68607
|
var init_frameCapture = __esm({
|
|
68411
68608
|
"../engine/src/services/frameCapture.ts"() {
|
|
68412
68609
|
"use strict";
|
|
@@ -68437,6 +68634,9 @@ var init_frameCapture = __esm({
|
|
|
68437
68634
|
CAPTURE_SESSION_CLOSE_TIMEOUT_MS = 5e3;
|
|
68438
68635
|
LOCKED_WARMUP_TICKS = 60;
|
|
68439
68636
|
realSleep = (ms) => new Promise((resolve77) => setTimeout(resolve77, ms));
|
|
68637
|
+
BEGIN_FRAME_CAPTURE_HEADROOM_INTERVALS = 10;
|
|
68638
|
+
BEGIN_FRAME_COMMIT_LEAD_INTERVALS = 6;
|
|
68639
|
+
BEGIN_FRAME_PROBE_LEAD_INTERVALS = 5;
|
|
68440
68640
|
HF_READY_DIAGNOSTIC_EXPR = `(function() {
|
|
68441
68641
|
var hf = window.__hf;
|
|
68442
68642
|
var player = window.__player;
|
|
@@ -70621,21 +70821,25 @@ var init_referenceResolver = __esm({
|
|
|
70621
70821
|
// ../engine/src/utils/urlDownloader.ts
|
|
70622
70822
|
import {
|
|
70623
70823
|
closeSync,
|
|
70824
|
+
createReadStream as createReadStream2,
|
|
70624
70825
|
createWriteStream,
|
|
70625
70826
|
existsSync as existsSync9,
|
|
70626
70827
|
fsyncSync,
|
|
70828
|
+
linkSync,
|
|
70627
70829
|
mkdtempSync,
|
|
70628
70830
|
mkdirSync as mkdirSync5,
|
|
70629
70831
|
lstatSync,
|
|
70630
70832
|
openSync,
|
|
70631
|
-
|
|
70833
|
+
readdirSync as readdirSync3,
|
|
70834
|
+
rmdirSync,
|
|
70632
70835
|
rmSync as rmSync2,
|
|
70633
|
-
statSync as statSync4
|
|
70836
|
+
statSync as statSync4,
|
|
70837
|
+
unlinkSync
|
|
70634
70838
|
} from "fs";
|
|
70635
|
-
import { createHash } from "crypto";
|
|
70839
|
+
import { createHash, randomUUID as randomUUID2 } from "crypto";
|
|
70636
70840
|
import { BlockList, isIP } from "net";
|
|
70637
70841
|
import { dirname as dirname6, extname as extname2, join as join9 } from "path";
|
|
70638
|
-
import { Readable } from "stream";
|
|
70842
|
+
import { Readable, Transform } from "stream";
|
|
70639
70843
|
import { pipeline } from "stream/promises";
|
|
70640
70844
|
function signalScopeKey(signal) {
|
|
70641
70845
|
if (!signal) return "none";
|
|
@@ -70647,8 +70851,29 @@ function signalScopeKey(signal) {
|
|
|
70647
70851
|
}
|
|
70648
70852
|
return String(scope);
|
|
70649
70853
|
}
|
|
70650
|
-
function
|
|
70651
|
-
|
|
70854
|
+
function safeDownloadUrlIdentity(url) {
|
|
70855
|
+
let canonical = url;
|
|
70856
|
+
let host;
|
|
70857
|
+
try {
|
|
70858
|
+
const parsed = new URL(url);
|
|
70859
|
+
canonical = `${parsed.origin}${parsed.pathname}`;
|
|
70860
|
+
host = parsed.hostname.toLowerCase();
|
|
70861
|
+
} catch {
|
|
70862
|
+
}
|
|
70863
|
+
return {
|
|
70864
|
+
urlFingerprint: createHash("sha256").update(canonical).digest("hex"),
|
|
70865
|
+
host
|
|
70866
|
+
};
|
|
70867
|
+
}
|
|
70868
|
+
function writeUrlDownloadTelemetry(event) {
|
|
70869
|
+
try {
|
|
70870
|
+
process.stderr.write(`[hyperframes:download] ${JSON.stringify(event)}
|
|
70871
|
+
`);
|
|
70872
|
+
} catch {
|
|
70873
|
+
}
|
|
70874
|
+
}
|
|
70875
|
+
function classifyHttpFailure(status) {
|
|
70876
|
+
const message = `HTTP ${status}`;
|
|
70652
70877
|
if (status === 404 || status === 410) {
|
|
70653
70878
|
return new UrlDownloadError("http_not_found", false, message, status);
|
|
70654
70879
|
}
|
|
@@ -70659,15 +70884,22 @@ function classifyHttpFailure(status, statusText) {
|
|
|
70659
70884
|
}
|
|
70660
70885
|
function classifyDownloadFailure(error) {
|
|
70661
70886
|
if (error instanceof UrlDownloadError) return error;
|
|
70662
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
70663
70887
|
let current2 = error;
|
|
70664
70888
|
for (let depth = 0; current2 && depth < 4; depth += 1) {
|
|
70665
70889
|
if (isRetryableNetworkCause(current2)) {
|
|
70666
|
-
return new UrlDownloadError(
|
|
70890
|
+
return new UrlDownloadError(
|
|
70891
|
+
"network",
|
|
70892
|
+
true,
|
|
70893
|
+
"Download failed due to a transient network error"
|
|
70894
|
+
);
|
|
70667
70895
|
}
|
|
70668
70896
|
current2 = typeof current2 === "object" && current2 !== null && "cause" in current2 ? current2.cause : void 0;
|
|
70669
70897
|
}
|
|
70670
|
-
return new UrlDownloadError(
|
|
70898
|
+
return new UrlDownloadError(
|
|
70899
|
+
"filesystem",
|
|
70900
|
+
false,
|
|
70901
|
+
"Download failed while writing the local artifact"
|
|
70902
|
+
);
|
|
70671
70903
|
}
|
|
70672
70904
|
function isRetryableNetworkCause(error) {
|
|
70673
70905
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -70686,31 +70918,155 @@ function assertPublicHttpsUrl(url) {
|
|
|
70686
70918
|
try {
|
|
70687
70919
|
parsed = new URL(url);
|
|
70688
70920
|
} catch {
|
|
70689
|
-
throw new Error(
|
|
70921
|
+
throw new Error("[URLDownloader] Invalid URL");
|
|
70690
70922
|
}
|
|
70691
70923
|
if (parsed.protocol !== "https:") {
|
|
70692
|
-
throw new Error(
|
|
70693
|
-
`[URLDownloader] Only HTTPS URLs are permitted in compositions (got ${parsed.protocol}): ${url}`
|
|
70694
|
-
);
|
|
70924
|
+
throw new Error(`[URLDownloader] Only HTTPS URLs are permitted in compositions`);
|
|
70695
70925
|
}
|
|
70696
70926
|
if (isBlockedHost(parsed.hostname)) {
|
|
70697
|
-
throw new Error(
|
|
70698
|
-
`[URLDownloader] URL targets a private/reserved address and is not permitted: ${url}`
|
|
70699
|
-
);
|
|
70927
|
+
throw new Error("[URLDownloader] URL targets a private/reserved address and is not permitted");
|
|
70700
70928
|
}
|
|
70701
70929
|
}
|
|
70702
|
-
function getFilenameFromUrl(url) {
|
|
70703
|
-
const
|
|
70930
|
+
function getFilenameFromUrl(url, validationScope) {
|
|
70931
|
+
const physicalIdentity = validationScope === "" ? url : `${url}\0${validationScope}`;
|
|
70932
|
+
const hash2 = createHash("md5").update(physicalIdentity).digest("hex").slice(0, 12);
|
|
70704
70933
|
const urlObj = new URL(url);
|
|
70705
70934
|
const ext = extname2(urlObj.pathname) || ".mp4";
|
|
70706
70935
|
return `download_${hash2}${ext}`;
|
|
70707
70936
|
}
|
|
70708
|
-
function
|
|
70709
|
-
|
|
70710
|
-
|
|
70711
|
-
|
|
70712
|
-
|
|
70713
|
-
|
|
70937
|
+
function sameFileIdentity(left, right) {
|
|
70938
|
+
return left.dev === right.dev && left.ino === right.ino;
|
|
70939
|
+
}
|
|
70940
|
+
function sameCacheLockStatGeneration(left, right) {
|
|
70941
|
+
return sameFileIdentity(left, right) && left.mtimeMs === right.mtimeMs && left.ctimeMs === right.ctimeMs && left.birthtimeMs === right.birthtimeMs;
|
|
70942
|
+
}
|
|
70943
|
+
function observeCachePathLock(lockPath) {
|
|
70944
|
+
for (let pass = 0; pass < 3; pass += 1) {
|
|
70945
|
+
const before3 = lstatSync(lockPath);
|
|
70946
|
+
const owner = readdirSync3(lockPath).find((name) => name.startsWith(CACHE_LOCK_OWNER_PREFIX));
|
|
70947
|
+
const after2 = lstatSync(lockPath);
|
|
70948
|
+
if (sameCacheLockStatGeneration(before3, after2)) return { stats: after2, owner };
|
|
70949
|
+
}
|
|
70950
|
+
throw new UrlDownloadError("filesystem", true, "Cache lock changed repeatedly during inspection");
|
|
70951
|
+
}
|
|
70952
|
+
function sameCachePathLock(left, right) {
|
|
70953
|
+
if (left.owner !== void 0 || right.owner !== void 0) {
|
|
70954
|
+
return left.owner !== void 0 && left.owner === right.owner;
|
|
70955
|
+
}
|
|
70956
|
+
return sameFileIdentity(left.stats, right.stats);
|
|
70957
|
+
}
|
|
70958
|
+
function removeCacheLockDirectoryIfEmpty(lockPath) {
|
|
70959
|
+
try {
|
|
70960
|
+
rmdirSync(lockPath);
|
|
70961
|
+
} catch (error) {
|
|
70962
|
+
const code = error.code;
|
|
70963
|
+
if (code !== "ENOENT" && code !== "ENOTEMPTY" && code !== "EEXIST") throw error;
|
|
70964
|
+
}
|
|
70965
|
+
}
|
|
70966
|
+
function releaseOwnedCachePathLock(lockPath, owner) {
|
|
70967
|
+
try {
|
|
70968
|
+
rmdirSync(join9(lockPath, owner));
|
|
70969
|
+
} catch (error) {
|
|
70970
|
+
if (error.code === "ENOENT") return;
|
|
70971
|
+
throw error;
|
|
70972
|
+
}
|
|
70973
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
70974
|
+
}
|
|
70975
|
+
async function waitForCacheLock(signal) {
|
|
70976
|
+
if (signal?.aborted) {
|
|
70977
|
+
throw new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
70978
|
+
}
|
|
70979
|
+
await new Promise((resolve77, reject) => {
|
|
70980
|
+
const timeout = setTimeout(() => {
|
|
70981
|
+
signal?.removeEventListener("abort", onAbort);
|
|
70982
|
+
resolve77();
|
|
70983
|
+
}, CACHE_LOCK_POLL_MS);
|
|
70984
|
+
const onAbort = () => {
|
|
70985
|
+
clearTimeout(timeout);
|
|
70986
|
+
signal?.removeEventListener("abort", onAbort);
|
|
70987
|
+
reject(new UrlDownloadError("cancelled", false, "Download cancelled"));
|
|
70988
|
+
};
|
|
70989
|
+
signal?.addEventListener("abort", onAbort, { once: true });
|
|
70990
|
+
});
|
|
70991
|
+
}
|
|
70992
|
+
async function acquireCachePathLock(localPath, timeoutMs, signal) {
|
|
70993
|
+
const lockPath = `${localPath}.hf-lock`;
|
|
70994
|
+
const startedAt = Date.now();
|
|
70995
|
+
for (; ; ) {
|
|
70996
|
+
if (signal?.aborted) {
|
|
70997
|
+
throw new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
70998
|
+
}
|
|
70999
|
+
let createdLock = false;
|
|
71000
|
+
try {
|
|
71001
|
+
mkdirSync5(lockPath);
|
|
71002
|
+
createdLock = true;
|
|
71003
|
+
} catch (error) {
|
|
71004
|
+
if (error.code !== "EEXIST") throw error;
|
|
71005
|
+
}
|
|
71006
|
+
if (createdLock) {
|
|
71007
|
+
const owner = `${CACHE_LOCK_OWNER_PREFIX}${randomUUID2()}`;
|
|
71008
|
+
try {
|
|
71009
|
+
mkdirSync5(join9(lockPath, owner));
|
|
71010
|
+
const entries2 = readdirSync3(lockPath);
|
|
71011
|
+
if (entries2.length === 1 && entries2[0] === owner) {
|
|
71012
|
+
return () => releaseOwnedCachePathLock(lockPath, owner);
|
|
71013
|
+
}
|
|
71014
|
+
rmdirSync(join9(lockPath, owner));
|
|
71015
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
71016
|
+
continue;
|
|
71017
|
+
} catch (error) {
|
|
71018
|
+
if (error.code === "ENOENT") continue;
|
|
71019
|
+
throw error;
|
|
71020
|
+
}
|
|
71021
|
+
}
|
|
71022
|
+
let observedLock;
|
|
71023
|
+
try {
|
|
71024
|
+
observedLock = observeCachePathLock(lockPath);
|
|
71025
|
+
} catch (error) {
|
|
71026
|
+
if (error.code === "ENOENT") continue;
|
|
71027
|
+
throw error;
|
|
71028
|
+
}
|
|
71029
|
+
if (Date.now() - observedLock.stats.mtimeMs > CACHE_LOCK_STALE_MS) {
|
|
71030
|
+
if (observedLock.owner) {
|
|
71031
|
+
try {
|
|
71032
|
+
rmdirSync(join9(lockPath, observedLock.owner));
|
|
71033
|
+
} catch (error) {
|
|
71034
|
+
if (error.code === "ENOENT") continue;
|
|
71035
|
+
throw error;
|
|
71036
|
+
}
|
|
71037
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
71038
|
+
continue;
|
|
71039
|
+
}
|
|
71040
|
+
const reclaimPath = join9(lockPath, CACHE_LOCK_RECLAIM_NAME);
|
|
71041
|
+
try {
|
|
71042
|
+
mkdirSync5(reclaimPath);
|
|
71043
|
+
} catch (error) {
|
|
71044
|
+
const code = error.code;
|
|
71045
|
+
if (code === "EEXIST" || code === "ENOENT") continue;
|
|
71046
|
+
throw error;
|
|
71047
|
+
}
|
|
71048
|
+
try {
|
|
71049
|
+
const currentLock = observeCachePathLock(lockPath);
|
|
71050
|
+
if (sameCachePathLock(currentLock, observedLock)) {
|
|
71051
|
+
rmdirSync(reclaimPath);
|
|
71052
|
+
removeCacheLockDirectoryIfEmpty(lockPath);
|
|
71053
|
+
} else {
|
|
71054
|
+
rmdirSync(reclaimPath);
|
|
71055
|
+
}
|
|
71056
|
+
} catch (error) {
|
|
71057
|
+
if (error.code !== "ENOENT") throw error;
|
|
71058
|
+
}
|
|
71059
|
+
continue;
|
|
71060
|
+
}
|
|
71061
|
+
if (Date.now() - startedAt >= timeoutMs) {
|
|
71062
|
+
throw new UrlDownloadError(
|
|
71063
|
+
"timeout",
|
|
71064
|
+
true,
|
|
71065
|
+
`Download cache lock timeout after ${timeoutMs / 1e3}s`
|
|
71066
|
+
);
|
|
71067
|
+
}
|
|
71068
|
+
await waitForCacheLock(signal);
|
|
71069
|
+
}
|
|
70714
71070
|
}
|
|
70715
71071
|
function assertAllowedDownloadUrl(url, redirect) {
|
|
70716
71072
|
try {
|
|
@@ -70753,31 +71109,335 @@ async function fetchWithValidatedRedirects(initialUrl, controller) {
|
|
|
70753
71109
|
assertAllowedDownloadUrl(currentUrl, redirects > 0);
|
|
70754
71110
|
const response = await fetch(currentUrl, {
|
|
70755
71111
|
signal: controller.signal,
|
|
70756
|
-
redirect: "manual"
|
|
71112
|
+
redirect: "manual",
|
|
71113
|
+
headers: { "accept-encoding": "identity" }
|
|
70757
71114
|
});
|
|
70758
|
-
if (!REDIRECT_STATUSES.has(response.status)) return response;
|
|
71115
|
+
if (!REDIRECT_STATUSES.has(response.status)) return { response, finalUrl: currentUrl };
|
|
70759
71116
|
await cancelResponseBody(response);
|
|
70760
71117
|
currentUrl = resolveRedirectUrl(response, currentUrl, redirects);
|
|
70761
71118
|
}
|
|
70762
71119
|
}
|
|
70763
|
-
async function
|
|
70764
|
-
const
|
|
71120
|
+
async function fetchPublicHttpsText(url, options) {
|
|
71121
|
+
const timeoutMs = options.timeoutMs ?? 15e3;
|
|
71122
|
+
if (!Number.isSafeInteger(options.maxBytes) || options.maxBytes <= 0) {
|
|
71123
|
+
throw new RangeError("maxBytes must be a positive safe integer");
|
|
71124
|
+
}
|
|
71125
|
+
assertPublicHttpsUrl(url);
|
|
71126
|
+
const controller = new AbortController();
|
|
71127
|
+
let timedOut = false;
|
|
71128
|
+
let callerAborted = options.signal?.aborted ?? false;
|
|
71129
|
+
const onCallerAbort = () => {
|
|
71130
|
+
callerAborted = true;
|
|
71131
|
+
controller.abort();
|
|
71132
|
+
};
|
|
71133
|
+
options.signal?.addEventListener("abort", onCallerAbort, { once: true });
|
|
71134
|
+
const timeoutId = setTimeout(() => {
|
|
71135
|
+
timedOut = true;
|
|
71136
|
+
controller.abort();
|
|
71137
|
+
}, timeoutMs);
|
|
71138
|
+
try {
|
|
71139
|
+
if (callerAborted) {
|
|
71140
|
+
throw new UrlDownloadError("cancelled", false, "Text fetch cancelled");
|
|
71141
|
+
}
|
|
71142
|
+
const { response } = await fetchWithValidatedRedirects(url, controller);
|
|
71143
|
+
if (!response.ok) {
|
|
71144
|
+
await cancelResponseBody(response);
|
|
71145
|
+
throw classifyHttpFailure(response.status);
|
|
71146
|
+
}
|
|
71147
|
+
if (!response.body) return "";
|
|
71148
|
+
let declaredLength;
|
|
71149
|
+
try {
|
|
71150
|
+
declaredLength = parseDeclaredLength(response);
|
|
71151
|
+
} catch (error) {
|
|
71152
|
+
await cancelResponseBody(response);
|
|
71153
|
+
throw error;
|
|
71154
|
+
}
|
|
71155
|
+
const contentEncoding = response.headers.get("content-encoding")?.trim().toLowerCase();
|
|
71156
|
+
const expectedBytes = !contentEncoding || contentEncoding === "identity" ? declaredLength : void 0;
|
|
71157
|
+
if (declaredLength !== void 0 && declaredLength > options.maxBytes) {
|
|
71158
|
+
await cancelResponseBody(response);
|
|
71159
|
+
throw new UrlDownloadError(
|
|
71160
|
+
"length_mismatch",
|
|
71161
|
+
false,
|
|
71162
|
+
"Text response exceeded the configured byte limit",
|
|
71163
|
+
response.status
|
|
71164
|
+
);
|
|
71165
|
+
}
|
|
71166
|
+
const reader = response.body.getReader();
|
|
71167
|
+
const chunks = [];
|
|
71168
|
+
let receivedBytes = 0;
|
|
71169
|
+
for (; ; ) {
|
|
71170
|
+
const { done, value } = await reader.read();
|
|
71171
|
+
if (done) break;
|
|
71172
|
+
receivedBytes += value.byteLength;
|
|
71173
|
+
if (receivedBytes > options.maxBytes) {
|
|
71174
|
+
await reader.cancel();
|
|
71175
|
+
throw new UrlDownloadError(
|
|
71176
|
+
"length_mismatch",
|
|
71177
|
+
false,
|
|
71178
|
+
"Text response exceeded the configured byte limit",
|
|
71179
|
+
response.status,
|
|
71180
|
+
{ receivedBytes }
|
|
71181
|
+
);
|
|
71182
|
+
}
|
|
71183
|
+
chunks.push(value);
|
|
71184
|
+
}
|
|
71185
|
+
if (expectedBytes !== void 0 && receivedBytes !== expectedBytes) {
|
|
71186
|
+
throw new UrlDownloadError(
|
|
71187
|
+
"length_mismatch",
|
|
71188
|
+
true,
|
|
71189
|
+
"Text response byte count did not match its declared length",
|
|
71190
|
+
response.status,
|
|
71191
|
+
{ expectedBytes, receivedBytes }
|
|
71192
|
+
);
|
|
71193
|
+
}
|
|
71194
|
+
return new TextDecoder().decode(Buffer.concat(chunks.map((chunk) => Buffer.from(chunk))));
|
|
71195
|
+
} catch (error) {
|
|
71196
|
+
if (callerAborted) {
|
|
71197
|
+
throw new UrlDownloadError("cancelled", false, "Text fetch cancelled");
|
|
71198
|
+
}
|
|
71199
|
+
if (timedOut) {
|
|
71200
|
+
throw new UrlDownloadError("timeout", true, `Text fetch timeout after ${timeoutMs / 1e3}s`);
|
|
71201
|
+
}
|
|
71202
|
+
throw classifyDownloadFailure(error);
|
|
71203
|
+
} finally {
|
|
71204
|
+
clearTimeout(timeoutId);
|
|
71205
|
+
options.signal?.removeEventListener("abort", onCallerAbort);
|
|
71206
|
+
controller.abort();
|
|
71207
|
+
}
|
|
71208
|
+
}
|
|
71209
|
+
function parseDeclaredLength(response) {
|
|
71210
|
+
const raw = response.headers.get("content-length");
|
|
71211
|
+
if (raw === null) return void 0;
|
|
71212
|
+
if (!/^\d+$/.test(raw.trim())) {
|
|
71213
|
+
throw new UrlDownloadError(
|
|
71214
|
+
"length_mismatch",
|
|
71215
|
+
true,
|
|
71216
|
+
"Download response Content-Length is malformed",
|
|
71217
|
+
response.status,
|
|
71218
|
+
{ status: response.status }
|
|
71219
|
+
);
|
|
71220
|
+
}
|
|
71221
|
+
const value = Number(raw);
|
|
71222
|
+
if (!Number.isSafeInteger(value) || value < 0) {
|
|
71223
|
+
throw new UrlDownloadError(
|
|
71224
|
+
"length_mismatch",
|
|
71225
|
+
true,
|
|
71226
|
+
"Download response Content-Length is out of range",
|
|
71227
|
+
response.status,
|
|
71228
|
+
{ status: response.status }
|
|
71229
|
+
);
|
|
71230
|
+
}
|
|
71231
|
+
return value;
|
|
71232
|
+
}
|
|
71233
|
+
function classifyRangeDisposition(response) {
|
|
71234
|
+
const contentRange = response.headers.get("content-range");
|
|
71235
|
+
if (response.status === 206) {
|
|
71236
|
+
const match2 = contentRange?.match(/^bytes (\d+)-(\d+)\/(\d+|\*)$/i);
|
|
71237
|
+
if (!match2) return "malformed_206";
|
|
71238
|
+
const start2 = Number(match2[1]);
|
|
71239
|
+
const end2 = Number(match2[2]);
|
|
71240
|
+
const total2 = match2[3] === "*" ? void 0 : Number(match2[3]);
|
|
71241
|
+
if (!Number.isSafeInteger(start2) || !Number.isSafeInteger(end2) || start2 < 0 || end2 < start2 || total2 !== void 0 && (!Number.isSafeInteger(total2) || total2 <= end2)) {
|
|
71242
|
+
return "malformed_206";
|
|
71243
|
+
}
|
|
71244
|
+
return "unsolicited_206";
|
|
71245
|
+
}
|
|
71246
|
+
if (response.status !== 200 || contentRange === null) return "none";
|
|
71247
|
+
const match = contentRange.match(/^bytes (\d+)-(\d+)\/(\d+)$/i);
|
|
71248
|
+
const contentLength = response.headers.get("content-length")?.trim();
|
|
71249
|
+
const contentEncoding = response.headers.get("content-encoding")?.trim().toLowerCase();
|
|
71250
|
+
if (!match || !contentLength || !/^\d+$/.test(contentLength)) {
|
|
71251
|
+
return "content_range_on_200";
|
|
71252
|
+
}
|
|
71253
|
+
const start = Number(match[1]);
|
|
71254
|
+
const end = Number(match[2]);
|
|
71255
|
+
const total = Number(match[3]);
|
|
71256
|
+
const declaredLength = Number(contentLength);
|
|
71257
|
+
return Number.isSafeInteger(start) && Number.isSafeInteger(end) && Number.isSafeInteger(total) && Number.isSafeInteger(declaredLength) && start === 0 && total > 0 && end === total - 1 && declaredLength === total && (!contentEncoding || contentEncoding === "identity") ? "full_object_200" : "content_range_on_200";
|
|
71258
|
+
}
|
|
71259
|
+
function looksLikeRemoteErrorDocument(prefix) {
|
|
71260
|
+
const text2 = prefix.toString("utf8").replace(/^\uFEFF?\s*/, "").toLowerCase();
|
|
71261
|
+
return text2.startsWith("<!doctype html") || text2.startsWith("<html") || text2.startsWith("<head") || text2.startsWith("<body") || text2.startsWith("<error") || /^\{\s*"(?:error|message|detail|code|status)"\s*:/i.test(text2) || /^<\?xml\b/.test(text2) && /<(?:html|error)\b/.test(text2);
|
|
71262
|
+
}
|
|
71263
|
+
function normalizeCallerSha256(value) {
|
|
71264
|
+
if (value === void 0) return void 0;
|
|
71265
|
+
const normalized2 = value.trim().toLowerCase();
|
|
71266
|
+
if (!/^[a-f0-9]{64}$/.test(normalized2)) {
|
|
71267
|
+
throw new UrlDownloadError(
|
|
71268
|
+
"hash_mismatch",
|
|
71269
|
+
false,
|
|
71270
|
+
"Caller-provided SHA-256 checksum is malformed"
|
|
71271
|
+
);
|
|
71272
|
+
}
|
|
71273
|
+
return normalized2;
|
|
71274
|
+
}
|
|
71275
|
+
function expectedResponseSha256(response, callerSha256) {
|
|
71276
|
+
if (callerSha256) return { value: callerSha256, encoding: "hex", source: "caller" };
|
|
71277
|
+
const amazonChecksum = response.headers.get("x-amz-checksum-sha256")?.trim();
|
|
71278
|
+
const amazonChecksumType = response.headers.get("x-amz-checksum-type")?.trim().toUpperCase();
|
|
71279
|
+
if (amazonChecksum && amazonChecksumType !== "COMPOSITE") {
|
|
71280
|
+
return { value: amazonChecksum, encoding: "base64", source: "server" };
|
|
71281
|
+
}
|
|
71282
|
+
const digest = response.headers.get("digest");
|
|
71283
|
+
const sha256Digest = digest?.match(/(?:^|,)\s*sha-256=:?([^,:\s]+):?/i)?.[1];
|
|
71284
|
+
return sha256Digest ? { value: sha256Digest, encoding: "base64", source: "server" } : null;
|
|
71285
|
+
}
|
|
71286
|
+
function checksumMismatchError(source, status, telemetry) {
|
|
71287
|
+
return new UrlDownloadError(
|
|
71288
|
+
"hash_mismatch",
|
|
71289
|
+
source === "server",
|
|
71290
|
+
"Download payload checksum did not match",
|
|
71291
|
+
status,
|
|
71292
|
+
telemetry,
|
|
71293
|
+
true
|
|
71294
|
+
);
|
|
71295
|
+
}
|
|
71296
|
+
async function fetchToPartial(url, partialPath, controller, options) {
|
|
71297
|
+
const { response, finalUrl } = await fetchWithValidatedRedirects(url, controller);
|
|
71298
|
+
const finalIdentity = safeDownloadUrlIdentity(finalUrl);
|
|
71299
|
+
const rangeDisposition = classifyRangeDisposition(response);
|
|
71300
|
+
if (rangeDisposition !== "none" && rangeDisposition !== "full_object_200") {
|
|
71301
|
+
await cancelResponseBody(response);
|
|
71302
|
+
throw new UrlDownloadError(
|
|
71303
|
+
"range_protocol",
|
|
71304
|
+
true,
|
|
71305
|
+
rangeDisposition === "malformed_206" ? "Download received a malformed unsolicited partial response" : "Download received an unsolicited partial response",
|
|
71306
|
+
response.status,
|
|
71307
|
+
{
|
|
71308
|
+
finalHost: finalIdentity.host,
|
|
71309
|
+
status: response.status,
|
|
71310
|
+
rangeDisposition
|
|
71311
|
+
}
|
|
71312
|
+
);
|
|
71313
|
+
}
|
|
70765
71314
|
if (!response.ok) {
|
|
70766
71315
|
try {
|
|
70767
71316
|
await response.body?.cancel();
|
|
70768
71317
|
} catch {
|
|
70769
71318
|
}
|
|
70770
|
-
|
|
71319
|
+
const classified = classifyHttpFailure(response.status);
|
|
71320
|
+
throw new UrlDownloadError(
|
|
71321
|
+
classified.kind,
|
|
71322
|
+
classified.retryable,
|
|
71323
|
+
classified.message,
|
|
71324
|
+
classified.status,
|
|
71325
|
+
{ finalHost: finalIdentity.host, status: response.status, rangeDisposition }
|
|
71326
|
+
);
|
|
70771
71327
|
}
|
|
70772
71328
|
if (!response.body) {
|
|
70773
|
-
throw new UrlDownloadError(
|
|
71329
|
+
throw new UrlDownloadError(
|
|
71330
|
+
"empty_body",
|
|
71331
|
+
true,
|
|
71332
|
+
"Download response body is empty",
|
|
71333
|
+
response.status,
|
|
71334
|
+
{
|
|
71335
|
+
finalHost: finalIdentity.host,
|
|
71336
|
+
status: response.status
|
|
71337
|
+
}
|
|
71338
|
+
);
|
|
70774
71339
|
}
|
|
70775
|
-
|
|
71340
|
+
let declaredLength;
|
|
71341
|
+
try {
|
|
71342
|
+
declaredLength = parseDeclaredLength(response);
|
|
71343
|
+
} catch (error) {
|
|
71344
|
+
await cancelResponseBody(response);
|
|
71345
|
+
if (error instanceof UrlDownloadError) {
|
|
71346
|
+
throw new UrlDownloadError(error.kind, error.retryable, error.message, error.status, {
|
|
71347
|
+
...error.telemetry,
|
|
71348
|
+
finalHost: finalIdentity.host,
|
|
71349
|
+
rangeDisposition
|
|
71350
|
+
});
|
|
71351
|
+
}
|
|
71352
|
+
throw error;
|
|
71353
|
+
}
|
|
71354
|
+
const contentEncoding = response.headers.get("content-encoding")?.trim().toLowerCase();
|
|
71355
|
+
const expectedBytes = !contentEncoding || contentEncoding === "identity" ? declaredLength : void 0;
|
|
71356
|
+
let receivedBytes = 0;
|
|
71357
|
+
const sha256 = createHash("sha256");
|
|
71358
|
+
const md5 = createHash("md5");
|
|
71359
|
+
const prefixChunks = [];
|
|
71360
|
+
let prefixBytes = 0;
|
|
71361
|
+
const inspector = new Transform({
|
|
71362
|
+
transform(chunk, _encoding, callback) {
|
|
71363
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
71364
|
+
receivedBytes += bytes.length;
|
|
71365
|
+
sha256.update(bytes);
|
|
71366
|
+
md5.update(bytes);
|
|
71367
|
+
if (prefixBytes < 1024) {
|
|
71368
|
+
const remaining = 1024 - prefixBytes;
|
|
71369
|
+
const sample = bytes.subarray(0, remaining);
|
|
71370
|
+
prefixChunks.push(sample);
|
|
71371
|
+
prefixBytes += sample.length;
|
|
71372
|
+
}
|
|
71373
|
+
callback(null, bytes);
|
|
71374
|
+
}
|
|
71375
|
+
});
|
|
70776
71376
|
const readableStream = Readable.fromWeb(response.body);
|
|
70777
|
-
|
|
70778
|
-
|
|
70779
|
-
|
|
71377
|
+
const fileStream = createWriteStream(partialPath, { flags: "wx" });
|
|
71378
|
+
await pipeline(readableStream, inspector, fileStream);
|
|
71379
|
+
const localSize = statSync4(partialPath).size;
|
|
71380
|
+
const sha256Bytes = sha256.digest();
|
|
71381
|
+
const localSha256 = sha256Bytes.toString("hex");
|
|
71382
|
+
const md5Base64 = md5.digest("base64");
|
|
71383
|
+
const telemetry = {
|
|
71384
|
+
finalHost: finalIdentity.host,
|
|
71385
|
+
status: response.status,
|
|
71386
|
+
expectedBytes,
|
|
71387
|
+
receivedBytes,
|
|
71388
|
+
rangeDisposition,
|
|
71389
|
+
localSize,
|
|
71390
|
+
localSha256
|
|
71391
|
+
};
|
|
71392
|
+
if (receivedBytes === 0 || localSize === 0) {
|
|
71393
|
+
throw new UrlDownloadError(
|
|
71394
|
+
"empty_body",
|
|
71395
|
+
true,
|
|
71396
|
+
"Download response body contained zero bytes",
|
|
71397
|
+
response.status,
|
|
71398
|
+
telemetry
|
|
71399
|
+
);
|
|
71400
|
+
}
|
|
71401
|
+
if (localSize !== receivedBytes || expectedBytes !== void 0 && receivedBytes !== expectedBytes) {
|
|
71402
|
+
throw new UrlDownloadError(
|
|
71403
|
+
"length_mismatch",
|
|
71404
|
+
true,
|
|
71405
|
+
"Download response byte count did not match its declared length",
|
|
71406
|
+
response.status,
|
|
71407
|
+
telemetry
|
|
71408
|
+
);
|
|
70780
71409
|
}
|
|
71410
|
+
const prefix = Buffer.concat(prefixChunks);
|
|
71411
|
+
if (looksLikeRemoteErrorDocument(prefix)) {
|
|
71412
|
+
throw new UrlDownloadError(
|
|
71413
|
+
"invalid_payload",
|
|
71414
|
+
false,
|
|
71415
|
+
"Download returned an HTML or JSON error document",
|
|
71416
|
+
response.status,
|
|
71417
|
+
telemetry
|
|
71418
|
+
);
|
|
71419
|
+
}
|
|
71420
|
+
const expectedSha256 = expectedResponseSha256(response, options.expectedSha256);
|
|
71421
|
+
const checksumMatches = expectedSha256 === null || (expectedSha256.encoding === "base64" ? sha256Bytes.toString("base64") === expectedSha256.value : localSha256 === expectedSha256.value);
|
|
71422
|
+
const contentMd5 = response.headers.get("content-md5")?.trim();
|
|
71423
|
+
if (!checksumMatches) {
|
|
71424
|
+
throw checksumMismatchError(expectedSha256?.source ?? "server", response.status, telemetry);
|
|
71425
|
+
}
|
|
71426
|
+
if (expectedSha256 === null && contentMd5 && md5Base64 !== contentMd5) {
|
|
71427
|
+
throw checksumMismatchError("server", response.status, telemetry);
|
|
71428
|
+
}
|
|
71429
|
+
const etag = response.headers.get("etag")?.trim();
|
|
71430
|
+
return {
|
|
71431
|
+
finalHost: finalIdentity.host,
|
|
71432
|
+
status: response.status,
|
|
71433
|
+
expectedBytes,
|
|
71434
|
+
receivedBytes,
|
|
71435
|
+
rangeDisposition,
|
|
71436
|
+
etagFingerprint: etag ? createHash("sha256").update(etag).digest("hex") : void 0,
|
|
71437
|
+
etagWeak: etag ? /^W\//i.test(etag) : void 0,
|
|
71438
|
+
localSize,
|
|
71439
|
+
localSha256
|
|
71440
|
+
};
|
|
70781
71441
|
}
|
|
70782
71442
|
function syncAndPublishPartial(partialPath, localPath) {
|
|
70783
71443
|
const fd = openSync(partialPath, "r+");
|
|
@@ -70786,14 +71446,35 @@ function syncAndPublishPartial(partialPath, localPath) {
|
|
|
70786
71446
|
} finally {
|
|
70787
71447
|
closeSync(fd);
|
|
70788
71448
|
}
|
|
70789
|
-
if (hasCompleteFile(localPath)) return;
|
|
70790
71449
|
try {
|
|
70791
|
-
|
|
71450
|
+
linkSync(partialPath, localPath);
|
|
71451
|
+
unlinkSync(partialPath);
|
|
71452
|
+
return "published";
|
|
70792
71453
|
} catch (error) {
|
|
70793
|
-
|
|
71454
|
+
const code = error.code;
|
|
71455
|
+
if (code !== "EEXIST") throw error;
|
|
71456
|
+
let winner;
|
|
71457
|
+
try {
|
|
71458
|
+
winner = lstatSync(localPath);
|
|
71459
|
+
} catch (inspectionError) {
|
|
71460
|
+
if (inspectionError.code !== "ENOENT") throw inspectionError;
|
|
71461
|
+
throw new UrlDownloadError(
|
|
71462
|
+
"filesystem",
|
|
71463
|
+
true,
|
|
71464
|
+
"Concurrent cache artifact disappeared before validation"
|
|
71465
|
+
);
|
|
71466
|
+
}
|
|
71467
|
+
if (!winner.isFile() || winner.size === 0) throw error;
|
|
71468
|
+
return "race_reused";
|
|
70794
71469
|
}
|
|
70795
71470
|
}
|
|
70796
|
-
|
|
71471
|
+
function emitDownloadTelemetry(options, event) {
|
|
71472
|
+
try {
|
|
71473
|
+
options.onTelemetry?.(event);
|
|
71474
|
+
} catch {
|
|
71475
|
+
}
|
|
71476
|
+
}
|
|
71477
|
+
async function runDownloadAttempt(url, localPath, timeoutMs, attempt, options, signal) {
|
|
70797
71478
|
const attemptDir = mkdtempSync(join9(dirname6(localPath), ".hf-download-"));
|
|
70798
71479
|
const partialPath = join9(attemptDir, "payload");
|
|
70799
71480
|
const controller = new AbortController();
|
|
@@ -70808,21 +71489,91 @@ async function runDownloadAttempt(url, localPath, timeoutMs, signal) {
|
|
|
70808
71489
|
timedOut = true;
|
|
70809
71490
|
controller.abort();
|
|
70810
71491
|
}, timeoutMs);
|
|
71492
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
70811
71493
|
try {
|
|
70812
71494
|
if (callerAborted) {
|
|
70813
71495
|
throw new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
70814
71496
|
}
|
|
70815
|
-
await fetchToPartial(url, partialPath, controller);
|
|
70816
|
-
syncAndPublishPartial(partialPath, localPath);
|
|
71497
|
+
const integrity = await fetchToPartial(url, partialPath, controller, options);
|
|
71498
|
+
let outcome = syncAndPublishPartial(partialPath, localPath);
|
|
71499
|
+
let publishedIntegrity = integrity;
|
|
71500
|
+
if (outcome === "race_reused") {
|
|
71501
|
+
let inspection;
|
|
71502
|
+
try {
|
|
71503
|
+
inspection = await inspectExistingFile(localPath);
|
|
71504
|
+
} catch (error) {
|
|
71505
|
+
if (error.code !== "ENOENT") throw error;
|
|
71506
|
+
throw new UrlDownloadError(
|
|
71507
|
+
"filesystem",
|
|
71508
|
+
true,
|
|
71509
|
+
"Concurrent cache artifact disappeared before validation",
|
|
71510
|
+
integrity.status,
|
|
71511
|
+
integrity
|
|
71512
|
+
);
|
|
71513
|
+
}
|
|
71514
|
+
publishedIntegrity = {
|
|
71515
|
+
...integrity,
|
|
71516
|
+
localSize: inspection.localSize,
|
|
71517
|
+
localSha256: inspection.localSha256
|
|
71518
|
+
};
|
|
71519
|
+
if (!localInspectionMatchesOptions(inspection, options)) {
|
|
71520
|
+
if (looksLikeRemoteErrorDocument(inspection.prefix)) {
|
|
71521
|
+
throw new UrlDownloadError(
|
|
71522
|
+
"invalid_payload",
|
|
71523
|
+
false,
|
|
71524
|
+
"Concurrent download published an HTML or JSON error document",
|
|
71525
|
+
integrity.status,
|
|
71526
|
+
publishedIntegrity
|
|
71527
|
+
);
|
|
71528
|
+
}
|
|
71529
|
+
throw checksumMismatchError("caller", integrity.status, publishedIntegrity);
|
|
71530
|
+
}
|
|
71531
|
+
}
|
|
71532
|
+
emitDownloadTelemetry(options, {
|
|
71533
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71534
|
+
initialHost: identity.host,
|
|
71535
|
+
attempt,
|
|
71536
|
+
outcome,
|
|
71537
|
+
...publishedIntegrity
|
|
71538
|
+
});
|
|
70817
71539
|
return localPath;
|
|
70818
71540
|
} catch (error) {
|
|
70819
71541
|
if (callerAborted) {
|
|
70820
|
-
|
|
71542
|
+
const classified2 = new UrlDownloadError("cancelled", false, "Download cancelled");
|
|
71543
|
+
emitDownloadTelemetry(options, {
|
|
71544
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71545
|
+
initialHost: identity.host,
|
|
71546
|
+
attempt,
|
|
71547
|
+
outcome: "attempt_failed",
|
|
71548
|
+
failureKind: classified2.kind
|
|
71549
|
+
});
|
|
71550
|
+
throw classified2;
|
|
70821
71551
|
}
|
|
70822
71552
|
if (timedOut) {
|
|
70823
|
-
|
|
71553
|
+
const classified2 = new UrlDownloadError(
|
|
71554
|
+
"timeout",
|
|
71555
|
+
true,
|
|
71556
|
+
`Download timeout after ${timeoutMs / 1e3}s`
|
|
71557
|
+
);
|
|
71558
|
+
emitDownloadTelemetry(options, {
|
|
71559
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71560
|
+
initialHost: identity.host,
|
|
71561
|
+
attempt,
|
|
71562
|
+
outcome: "attempt_failed",
|
|
71563
|
+
failureKind: classified2.kind
|
|
71564
|
+
});
|
|
71565
|
+
throw classified2;
|
|
70824
71566
|
}
|
|
70825
|
-
|
|
71567
|
+
const classified = classifyDownloadFailure(error);
|
|
71568
|
+
emitDownloadTelemetry(options, {
|
|
71569
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71570
|
+
initialHost: identity.host,
|
|
71571
|
+
attempt,
|
|
71572
|
+
outcome: "attempt_failed",
|
|
71573
|
+
failureKind: classified.kind,
|
|
71574
|
+
...classified.telemetry
|
|
71575
|
+
});
|
|
71576
|
+
throw classified;
|
|
70826
71577
|
} finally {
|
|
70827
71578
|
clearTimeout(timeoutId);
|
|
70828
71579
|
signal?.removeEventListener("abort", onCallerAbort);
|
|
@@ -70830,22 +71581,114 @@ async function runDownloadAttempt(url, localPath, timeoutMs, signal) {
|
|
|
70830
71581
|
rmSync2(attemptDir, { recursive: true, force: true });
|
|
70831
71582
|
}
|
|
70832
71583
|
}
|
|
70833
|
-
async function downloadWithRetry(url, localPath, timeoutMs, signal, onTransientRetry) {
|
|
71584
|
+
async function downloadWithRetry(url, localPath, timeoutMs, signal, onTransientRetry, options = {}) {
|
|
70834
71585
|
const maxTransientRetries = 1;
|
|
70835
71586
|
for (let attempt = 0; ; attempt += 1) {
|
|
70836
71587
|
try {
|
|
70837
|
-
return await runDownloadAttempt(url, localPath, timeoutMs, signal);
|
|
71588
|
+
return await runDownloadAttempt(url, localPath, timeoutMs, attempt + 1, options, signal);
|
|
70838
71589
|
} catch (error) {
|
|
70839
71590
|
const classified = classifyDownloadFailure(error);
|
|
70840
|
-
if (!classified.
|
|
70841
|
-
onTransientRetry?.(classified);
|
|
71591
|
+
if (!classified.locallyRetryable || attempt >= maxTransientRetries) throw classified;
|
|
71592
|
+
if (classified.retryable) onTransientRetry?.(classified);
|
|
71593
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
71594
|
+
emitDownloadTelemetry(options, {
|
|
71595
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71596
|
+
initialHost: identity.host,
|
|
71597
|
+
attempt: attempt + 1,
|
|
71598
|
+
outcome: "retrying",
|
|
71599
|
+
failureKind: classified.kind,
|
|
71600
|
+
...classified.telemetry
|
|
71601
|
+
});
|
|
71602
|
+
}
|
|
71603
|
+
}
|
|
71604
|
+
}
|
|
71605
|
+
async function inspectExistingFile(path2) {
|
|
71606
|
+
const sha256 = createHash("sha256");
|
|
71607
|
+
const prefixChunks = [];
|
|
71608
|
+
let prefixBytes = 0;
|
|
71609
|
+
let localSize = 0;
|
|
71610
|
+
for await (const chunk of createReadStream2(path2)) {
|
|
71611
|
+
const bytes = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
71612
|
+
localSize += bytes.length;
|
|
71613
|
+
sha256.update(bytes);
|
|
71614
|
+
if (prefixBytes < 1024) {
|
|
71615
|
+
const sample = bytes.subarray(0, 1024 - prefixBytes);
|
|
71616
|
+
prefixChunks.push(sample);
|
|
71617
|
+
prefixBytes += sample.length;
|
|
70842
71618
|
}
|
|
70843
71619
|
}
|
|
71620
|
+
return {
|
|
71621
|
+
localSize,
|
|
71622
|
+
localSha256: sha256.digest("hex"),
|
|
71623
|
+
prefix: Buffer.concat(prefixChunks)
|
|
71624
|
+
};
|
|
71625
|
+
}
|
|
71626
|
+
function localInspectionMatchesOptions(inspection, options) {
|
|
71627
|
+
const expectedSha256 = options.expectedSha256?.trim().toLowerCase();
|
|
71628
|
+
return inspection.localSize > 0 && !looksLikeRemoteErrorDocument(inspection.prefix) && (!expectedSha256 || inspection.localSha256 === expectedSha256);
|
|
71629
|
+
}
|
|
71630
|
+
function sameCacheEntry(before3, after2) {
|
|
71631
|
+
return sameFileIdentity(before3, after2) && before3.size === after2.size && before3.mtimeMs === after2.mtimeMs;
|
|
71632
|
+
}
|
|
71633
|
+
async function reuseOrInvalidateCachedFile(url, localPath, timeoutMs, signal, options) {
|
|
71634
|
+
const releaseLock = await acquireCachePathLock(localPath, timeoutMs, signal);
|
|
71635
|
+
try {
|
|
71636
|
+
for (let pass = 0; pass < 3; pass += 1) {
|
|
71637
|
+
let before3;
|
|
71638
|
+
try {
|
|
71639
|
+
before3 = lstatSync(localPath);
|
|
71640
|
+
} catch (error) {
|
|
71641
|
+
if (error.code === "ENOENT") continue;
|
|
71642
|
+
throw error;
|
|
71643
|
+
}
|
|
71644
|
+
if (!before3.isFile() || before3.size === 0) {
|
|
71645
|
+
rmSync2(localPath, { recursive: before3.isDirectory(), force: true });
|
|
71646
|
+
return false;
|
|
71647
|
+
}
|
|
71648
|
+
let inspection;
|
|
71649
|
+
try {
|
|
71650
|
+
inspection = await inspectExistingFile(localPath);
|
|
71651
|
+
} catch (error) {
|
|
71652
|
+
if (error.code === "ENOENT") continue;
|
|
71653
|
+
throw error;
|
|
71654
|
+
}
|
|
71655
|
+
let after2;
|
|
71656
|
+
try {
|
|
71657
|
+
after2 = lstatSync(localPath);
|
|
71658
|
+
} catch (error) {
|
|
71659
|
+
if (error.code === "ENOENT") continue;
|
|
71660
|
+
throw error;
|
|
71661
|
+
}
|
|
71662
|
+
if (!sameCacheEntry(before3, after2)) continue;
|
|
71663
|
+
if (localInspectionMatchesOptions(inspection, options)) {
|
|
71664
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
71665
|
+
emitDownloadTelemetry(options, {
|
|
71666
|
+
urlFingerprint: identity.urlFingerprint,
|
|
71667
|
+
initialHost: identity.host,
|
|
71668
|
+
attempt: 0,
|
|
71669
|
+
outcome: "cache_hit",
|
|
71670
|
+
receivedBytes: inspection.localSize,
|
|
71671
|
+
localSize: inspection.localSize,
|
|
71672
|
+
localSha256: inspection.localSha256,
|
|
71673
|
+
rangeDisposition: "none"
|
|
71674
|
+
});
|
|
71675
|
+
return true;
|
|
71676
|
+
}
|
|
71677
|
+
rmSync2(localPath, { force: true });
|
|
71678
|
+
return false;
|
|
71679
|
+
}
|
|
71680
|
+
return false;
|
|
71681
|
+
} finally {
|
|
71682
|
+
releaseLock();
|
|
71683
|
+
}
|
|
70844
71684
|
}
|
|
70845
|
-
async function downloadToTemp(url, destDir, timeoutMs = 3e5, signal, onTransientRetry) {
|
|
71685
|
+
async function downloadToTemp(url, destDir, timeoutMs = 3e5, signal, onTransientRetry, options = {}) {
|
|
70846
71686
|
assertPublicHttpsUrl(url);
|
|
71687
|
+
const expectedSha256 = normalizeCallerSha256(options.expectedSha256);
|
|
71688
|
+
const normalizedOptions = { ...options, expectedSha256 };
|
|
70847
71689
|
const cacheKey = `${url}\0${destDir}`;
|
|
70848
|
-
const
|
|
71690
|
+
const validationScope = expectedSha256 ?? "";
|
|
71691
|
+
const inFlightKey = `${cacheKey}\0${timeoutMs}\0${signalScopeKey(signal)}\0${validationScope}`;
|
|
70849
71692
|
const inFlight2 = inFlightDownloads.get(inFlightKey);
|
|
70850
71693
|
if (inFlight2) {
|
|
70851
71694
|
return inFlight2;
|
|
@@ -70853,10 +71696,35 @@ async function downloadToTemp(url, destDir, timeoutMs = 3e5, signal, onTransient
|
|
|
70853
71696
|
if (!existsSync9(destDir)) {
|
|
70854
71697
|
mkdirSync5(destDir, { recursive: true });
|
|
70855
71698
|
}
|
|
70856
|
-
const filename = getFilenameFromUrl(url);
|
|
71699
|
+
const filename = getFilenameFromUrl(url, validationScope);
|
|
70857
71700
|
const localPath = join9(destDir, filename);
|
|
70858
|
-
|
|
70859
|
-
|
|
71701
|
+
const downloadPromise = (async () => {
|
|
71702
|
+
const cacheStartedAt = Date.now();
|
|
71703
|
+
const reused = await reuseOrInvalidateCachedFile(
|
|
71704
|
+
url,
|
|
71705
|
+
localPath,
|
|
71706
|
+
timeoutMs,
|
|
71707
|
+
signal,
|
|
71708
|
+
normalizedOptions
|
|
71709
|
+
);
|
|
71710
|
+
const remainingTimeoutMs = timeoutMs - (Date.now() - cacheStartedAt);
|
|
71711
|
+
if (remainingTimeoutMs <= 0) {
|
|
71712
|
+
throw new UrlDownloadError(
|
|
71713
|
+
"timeout",
|
|
71714
|
+
true,
|
|
71715
|
+
`Download cache inspection timeout after ${timeoutMs / 1e3}s`
|
|
71716
|
+
);
|
|
71717
|
+
}
|
|
71718
|
+
if (reused) return localPath;
|
|
71719
|
+
return downloadWithRetry(
|
|
71720
|
+
url,
|
|
71721
|
+
localPath,
|
|
71722
|
+
remainingTimeoutMs,
|
|
71723
|
+
signal,
|
|
71724
|
+
onTransientRetry,
|
|
71725
|
+
normalizedOptions
|
|
71726
|
+
);
|
|
71727
|
+
})();
|
|
70860
71728
|
const trackedDownload = downloadPromise.finally(() => {
|
|
70861
71729
|
inFlightDownloads.delete(inFlightKey);
|
|
70862
71730
|
});
|
|
@@ -70866,7 +71734,7 @@ async function downloadToTemp(url, destDir, timeoutMs = 3e5, signal, onTransient
|
|
|
70866
71734
|
function isHttpUrl(path2) {
|
|
70867
71735
|
return path2.startsWith("http://") || path2.startsWith("https://");
|
|
70868
71736
|
}
|
|
70869
|
-
var inFlightDownloads, signalScopes, nextSignalScope, UrlDownloadError, RETRYABLE_NETWORK_CODES, NON_PUBLIC_IPV4_ADDRESSES, NON_PUBLIC_IPV6_ADDRESSES, REDIRECT_STATUSES, MAX_REDIRECTS;
|
|
71737
|
+
var inFlightDownloads, signalScopes, nextSignalScope, UrlDownloadError, RETRYABLE_NETWORK_CODES, NON_PUBLIC_IPV4_ADDRESSES, NON_PUBLIC_IPV6_ADDRESSES, CACHE_LOCK_POLL_MS, CACHE_LOCK_STALE_MS, CACHE_LOCK_RECLAIM_NAME, CACHE_LOCK_OWNER_PREFIX, REDIRECT_STATUSES, MAX_REDIRECTS;
|
|
70870
71738
|
var init_urlDownloader = __esm({
|
|
70871
71739
|
"../engine/src/utils/urlDownloader.ts"() {
|
|
70872
71740
|
"use strict";
|
|
@@ -70874,16 +71742,20 @@ var init_urlDownloader = __esm({
|
|
|
70874
71742
|
signalScopes = /* @__PURE__ */ new WeakMap();
|
|
70875
71743
|
nextSignalScope = 1;
|
|
70876
71744
|
UrlDownloadError = class extends Error {
|
|
70877
|
-
constructor(kind, retryable, message, status) {
|
|
71745
|
+
constructor(kind, retryable, message, status, telemetry, locallyRetryable = retryable) {
|
|
70878
71746
|
super(message);
|
|
70879
71747
|
this.kind = kind;
|
|
70880
71748
|
this.retryable = retryable;
|
|
70881
71749
|
this.status = status;
|
|
71750
|
+
this.telemetry = telemetry;
|
|
71751
|
+
this.locallyRetryable = locallyRetryable;
|
|
70882
71752
|
this.name = "UrlDownloadError";
|
|
70883
71753
|
}
|
|
70884
71754
|
kind;
|
|
70885
71755
|
retryable;
|
|
70886
71756
|
status;
|
|
71757
|
+
telemetry;
|
|
71758
|
+
locallyRetryable;
|
|
70887
71759
|
};
|
|
70888
71760
|
RETRYABLE_NETWORK_CODES = /* @__PURE__ */ new Set(["ECONNRESET", "ECONNREFUSED", "ETIMEDOUT", "EAI_AGAIN"]);
|
|
70889
71761
|
NON_PUBLIC_IPV4_ADDRESSES = new BlockList();
|
|
@@ -70919,6 +71791,10 @@ var init_urlDownloader = __esm({
|
|
|
70919
71791
|
]) {
|
|
70920
71792
|
NON_PUBLIC_IPV6_ADDRESSES.addSubnet(network, prefix, "ipv6");
|
|
70921
71793
|
}
|
|
71794
|
+
CACHE_LOCK_POLL_MS = 10;
|
|
71795
|
+
CACHE_LOCK_STALE_MS = 5 * 6e4;
|
|
71796
|
+
CACHE_LOCK_RECLAIM_NAME = ".hf-reclaim";
|
|
71797
|
+
CACHE_LOCK_OWNER_PREFIX = ".hf-owner-";
|
|
70922
71798
|
REDIRECT_STATUSES = /* @__PURE__ */ new Set([301, 302, 303, 307, 308]);
|
|
70923
71799
|
MAX_REDIRECTS = 5;
|
|
70924
71800
|
}
|
|
@@ -75531,8 +76407,62 @@ function containsTimelineCall2(node, timelineVar) {
|
|
|
75531
76407
|
function rangeOf2(node) {
|
|
75532
76408
|
return typeof node.start === "number" && typeof node.end === "number" ? [node.start, node.end] : void 0;
|
|
75533
76409
|
}
|
|
76410
|
+
function isSafeDefaultExpression2(node, earlierParams) {
|
|
76411
|
+
let safe = true;
|
|
76412
|
+
const visit = (current2, parent, key2) => {
|
|
76413
|
+
if (!isNode3(current2) || !safe) return;
|
|
76414
|
+
if (!SAFE_DEFAULT_NODES2.has(current2.type)) {
|
|
76415
|
+
safe = false;
|
|
76416
|
+
return;
|
|
76417
|
+
}
|
|
76418
|
+
if (current2.type === "UnaryExpression" && current2.operator === "delete") {
|
|
76419
|
+
safe = false;
|
|
76420
|
+
return;
|
|
76421
|
+
}
|
|
76422
|
+
if (current2.type === "Identifier") {
|
|
76423
|
+
const nonValue = parent && key2 ? isNonValueIdentifierSlot2(parent, key2) : false;
|
|
76424
|
+
if (!nonValue && current2.name !== "undefined" && !earlierParams.has(current2.name)) {
|
|
76425
|
+
safe = false;
|
|
76426
|
+
}
|
|
76427
|
+
return;
|
|
76428
|
+
}
|
|
76429
|
+
for (const childKey of Object.keys(current2)) {
|
|
76430
|
+
if (SKIP_KEYS2.has(childKey)) continue;
|
|
76431
|
+
const child = current2[childKey];
|
|
76432
|
+
if (Array.isArray(child)) {
|
|
76433
|
+
for (const item of child) visit(item, current2, childKey);
|
|
76434
|
+
} else {
|
|
76435
|
+
visit(child, current2, childKey);
|
|
76436
|
+
}
|
|
76437
|
+
}
|
|
76438
|
+
};
|
|
76439
|
+
visit(node);
|
|
76440
|
+
return safe;
|
|
76441
|
+
}
|
|
76442
|
+
function supportedParam2(param, earlier) {
|
|
76443
|
+
if (param.type === "Identifier") return { name: param.name };
|
|
76444
|
+
if (param.type !== "AssignmentPattern" || param.left?.type !== "Identifier") return null;
|
|
76445
|
+
if (!isSafeDefaultExpression2(param.right, earlier)) return null;
|
|
76446
|
+
return { name: param.left.name, defaultExpression: param.right };
|
|
76447
|
+
}
|
|
76448
|
+
function supportedParams2(fn) {
|
|
76449
|
+
if (SUPPORTED_PARAMS_CACHE2.has(fn)) return SUPPORTED_PARAMS_CACHE2.get(fn) ?? null;
|
|
76450
|
+
const params = [];
|
|
76451
|
+
const earlier = /* @__PURE__ */ new Set();
|
|
76452
|
+
for (const param of fn.params ?? []) {
|
|
76453
|
+
const parsed = supportedParam2(param, earlier);
|
|
76454
|
+
if (!parsed) {
|
|
76455
|
+
SUPPORTED_PARAMS_CACHE2.set(fn, null);
|
|
76456
|
+
return null;
|
|
76457
|
+
}
|
|
76458
|
+
params.push(parsed);
|
|
76459
|
+
earlier.add(parsed.name);
|
|
76460
|
+
}
|
|
76461
|
+
SUPPORTED_PARAMS_CACHE2.set(fn, params);
|
|
76462
|
+
return params;
|
|
76463
|
+
}
|
|
75534
76464
|
function isShapeEligible2(fn) {
|
|
75535
|
-
return isFunctionNode3(fn) && fn.body?.type === "BlockStatement" &&
|
|
76465
|
+
return isFunctionNode3(fn) && fn.body?.type === "BlockStatement" && supportedParams2(fn) !== null;
|
|
75536
76466
|
}
|
|
75537
76467
|
function callsAny2(node, names) {
|
|
75538
76468
|
let hit = false;
|
|
@@ -75582,20 +76512,55 @@ function timelineBuildingNames2(candidates, timelineVar) {
|
|
|
75582
76512
|
function bump2(counts, key2) {
|
|
75583
76513
|
counts.set(key2, (counts.get(key2) ?? 0) + 1);
|
|
75584
76514
|
}
|
|
76515
|
+
function undefinedIdentifier2() {
|
|
76516
|
+
return { type: "Identifier", name: "undefined" };
|
|
76517
|
+
}
|
|
76518
|
+
function isExplicitUndefined2(node) {
|
|
76519
|
+
return node?.type === "Identifier" && node.name === "undefined" || node?.type === "UnaryExpression" && node.operator === "void" && node.argument?.type === "Literal" && node.argument.value === 0;
|
|
76520
|
+
}
|
|
76521
|
+
function resolveHelperBindings2(call, params) {
|
|
76522
|
+
if (call.arguments?.some((arg) => arg?.type === "SpreadElement")) return null;
|
|
76523
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
76524
|
+
for (let i2 = 0; i2 < params.length; i2++) {
|
|
76525
|
+
const param = params[i2];
|
|
76526
|
+
const arg = call.arguments?.[i2];
|
|
76527
|
+
if (arg && !isExplicitUndefined2(arg)) {
|
|
76528
|
+
bindings.set(param.name, arg);
|
|
76529
|
+
} else if (param.defaultExpression) {
|
|
76530
|
+
bindings.set(param.name, substituteParams2(cloneNode3(param.defaultExpression), bindings));
|
|
76531
|
+
} else {
|
|
76532
|
+
bindings.set(param.name, undefinedIdentifier2());
|
|
76533
|
+
}
|
|
76534
|
+
}
|
|
76535
|
+
return bindings;
|
|
76536
|
+
}
|
|
76537
|
+
function statementHelperCall2(node, names) {
|
|
76538
|
+
if (node.type !== "ExpressionStatement") return void 0;
|
|
76539
|
+
const expression = node.expression;
|
|
76540
|
+
if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier") {
|
|
76541
|
+
return void 0;
|
|
76542
|
+
}
|
|
76543
|
+
return names.has(expression.callee.name) ? expression : void 0;
|
|
76544
|
+
}
|
|
75585
76545
|
function safelyDroppable2(program, candidates) {
|
|
75586
76546
|
const names = new Set(candidates.keys());
|
|
75587
76547
|
const totalIds = /* @__PURE__ */ new Map();
|
|
75588
76548
|
const stmtCalls = /* @__PURE__ */ new Map();
|
|
76549
|
+
const unbindable = /* @__PURE__ */ new Set();
|
|
75589
76550
|
walkNodes2(program, (n2) => {
|
|
75590
76551
|
if (n2.type === "Identifier" && names.has(n2.name)) bump2(totalIds, n2.name);
|
|
75591
|
-
const
|
|
75592
|
-
if (
|
|
75593
|
-
|
|
75594
|
-
|
|
76552
|
+
const call = statementHelperCall2(n2, names);
|
|
76553
|
+
if (!call) return;
|
|
76554
|
+
bump2(stmtCalls, call.callee.name);
|
|
76555
|
+
const fn = candidates.get(call.callee.name);
|
|
76556
|
+
const params = fn && supportedParams2(fn);
|
|
76557
|
+
if (!params || !resolveHelperBindings2(call, params)) unbindable.add(call.callee.name);
|
|
75595
76558
|
});
|
|
75596
76559
|
const safe = /* @__PURE__ */ new Map();
|
|
75597
76560
|
for (const [name, fn] of candidates) {
|
|
75598
|
-
if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0))
|
|
76561
|
+
if (!unbindable.has(name) && (totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) {
|
|
76562
|
+
safe.set(name, fn);
|
|
76563
|
+
}
|
|
75599
76564
|
}
|
|
75600
76565
|
return safe;
|
|
75601
76566
|
}
|
|
@@ -75638,11 +76603,11 @@ function expandBody2(bodyStmts, bindings, prov, ctx) {
|
|
|
75638
76603
|
}
|
|
75639
76604
|
function inlineHelper2(call, ctx) {
|
|
75640
76605
|
const fn = ctx.helpers.get(call.callee.name);
|
|
75641
|
-
|
|
75642
|
-
|
|
75643
|
-
|
|
75644
|
-
|
|
75645
|
-
|
|
76606
|
+
if (!fn) return null;
|
|
76607
|
+
const params = supportedParams2(fn);
|
|
76608
|
+
if (!params) return null;
|
|
76609
|
+
const bindings = resolveHelperBindings2(call, params);
|
|
76610
|
+
if (!bindings) return null;
|
|
75646
76611
|
const prov = {
|
|
75647
76612
|
kind: "helper",
|
|
75648
76613
|
fn: call.callee.name,
|
|
@@ -77117,7 +78082,7 @@ function extractGsapLabels(script) {
|
|
|
77117
78082
|
return [];
|
|
77118
78083
|
}
|
|
77119
78084
|
}
|
|
77120
|
-
var PROPERTY_GROUPS2, PROP_TO_GROUP2, SKIP_KEYS2, FUNCTION_TYPES2, GSAP_METHODS3, MAX_DEPTH2, MAX_ITERS2, roundPercentage2, GSAP_METHODS22, QUERY_METHODS2, ITERATION_METHODS2, SCOPE_NODE_TYPES2, CONST_NODES2, MATH_FNS2, MATH_CONSTS2, BUILTIN_VAR_KEYS2, DROPPED_VAR_KEYS2, EXTRAS_KEYS2, PERCENTAGE_KEY_RE2, GSAP_DEFAULT_DURATION2;
|
|
78085
|
+
var PROPERTY_GROUPS2, PROP_TO_GROUP2, SKIP_KEYS2, FUNCTION_TYPES2, GSAP_METHODS3, MAX_DEPTH2, MAX_ITERS2, SAFE_DEFAULT_NODES2, SUPPORTED_PARAMS_CACHE2, roundPercentage2, GSAP_METHODS22, QUERY_METHODS2, ITERATION_METHODS2, SCOPE_NODE_TYPES2, CONST_NODES2, MATH_FNS2, MATH_CONSTS2, BUILTIN_VAR_KEYS2, DROPPED_VAR_KEYS2, EXTRAS_KEYS2, PERCENTAGE_KEY_RE2, GSAP_DEFAULT_DURATION2;
|
|
77121
78086
|
var init_gsapParserAcorn = __esm({
|
|
77122
78087
|
"../parsers/dist/gsapParserAcorn.js"() {
|
|
77123
78088
|
"use strict";
|
|
@@ -77144,6 +78109,23 @@ var init_gsapParserAcorn = __esm({
|
|
|
77144
78109
|
GSAP_METHODS3 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
77145
78110
|
MAX_DEPTH2 = 8;
|
|
77146
78111
|
MAX_ITERS2 = 512;
|
|
78112
|
+
SAFE_DEFAULT_NODES2 = /* @__PURE__ */ new Set([
|
|
78113
|
+
"ArrayExpression",
|
|
78114
|
+
"BinaryExpression",
|
|
78115
|
+
"ChainExpression",
|
|
78116
|
+
"ConditionalExpression",
|
|
78117
|
+
"Identifier",
|
|
78118
|
+
"Literal",
|
|
78119
|
+
"LogicalExpression",
|
|
78120
|
+
"MemberExpression",
|
|
78121
|
+
"ObjectExpression",
|
|
78122
|
+
"Property",
|
|
78123
|
+
"SpreadElement",
|
|
78124
|
+
"TemplateElement",
|
|
78125
|
+
"TemplateLiteral",
|
|
78126
|
+
"UnaryExpression"
|
|
78127
|
+
]);
|
|
78128
|
+
SUPPORTED_PARAMS_CACHE2 = /* @__PURE__ */ new WeakMap();
|
|
77147
78129
|
roundPercentage2 = (percentage) => Math.round(percentage * 10) / 10;
|
|
77148
78130
|
GSAP_METHODS22 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
77149
78131
|
QUERY_METHODS2 = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
@@ -77184,7 +78166,7 @@ __export(dist_exports2, {
|
|
|
77184
78166
|
});
|
|
77185
78167
|
import postcss2 from "postcss";
|
|
77186
78168
|
import postcss22 from "postcss";
|
|
77187
|
-
import { existsSync as existsSync22, readFileSync as readFileSync4, readdirSync as
|
|
78169
|
+
import { existsSync as existsSync22, readFileSync as readFileSync4, readdirSync as readdirSync4 } from "fs";
|
|
77188
78170
|
import { dirname as dirname7, extname as extname3, join as join22, relative as relative3, resolve as resolve8 } from "path";
|
|
77189
78171
|
import { execFile } from "child_process";
|
|
77190
78172
|
import { existsSync as existsSync11 } from "fs";
|
|
@@ -79013,6 +79995,7 @@ async function probeIsHevc(ffprobePath, filePath) {
|
|
|
79013
79995
|
"stream=codec_name",
|
|
79014
79996
|
"-of",
|
|
79015
79997
|
"json",
|
|
79998
|
+
"--",
|
|
79016
79999
|
filePath
|
|
79017
80000
|
]);
|
|
79018
80001
|
return hasHevcStream(JSON.parse(stdout2));
|
|
@@ -79169,7 +80152,7 @@ async function lintProject(projectDir, entryFile) {
|
|
|
79169
80152
|
if (!entryFile && existsSync22(compositionsDir)) {
|
|
79170
80153
|
const collectHtmlFiles = (dir, rel) => {
|
|
79171
80154
|
const out = [];
|
|
79172
|
-
for (const entry of
|
|
80155
|
+
for (const entry of readdirSync4(dir, { withFileTypes: true })) {
|
|
79173
80156
|
const relPath = rel ? `${rel}/${entry.name}` : entry.name;
|
|
79174
80157
|
if (entry.isDirectory()) {
|
|
79175
80158
|
if (!rel && entry.name === "components") continue;
|
|
@@ -79230,7 +80213,7 @@ function lintProjectAudioFiles(projectDir, htmlSources) {
|
|
|
79230
80213
|
const findings = [];
|
|
79231
80214
|
let audioFiles;
|
|
79232
80215
|
try {
|
|
79233
|
-
audioFiles =
|
|
80216
|
+
audioFiles = readdirSync4(projectDir).filter(
|
|
79234
80217
|
(f3) => AUDIO_EXTENSIONS.has(extname3(f3).toLowerCase())
|
|
79235
80218
|
);
|
|
79236
80219
|
} catch {
|
|
@@ -79349,7 +80332,7 @@ function lintTextureMaskAssetNotFound(projectDir, htmlSources) {
|
|
|
79349
80332
|
function lintMultipleRootCompositions(projectDir) {
|
|
79350
80333
|
const findings = [];
|
|
79351
80334
|
try {
|
|
79352
|
-
const rootHtmlFiles =
|
|
80335
|
+
const rootHtmlFiles = readdirSync4(projectDir).filter(
|
|
79353
80336
|
(file) => file.endsWith(".html") && !file.startsWith("._")
|
|
79354
80337
|
);
|
|
79355
80338
|
const rootCompositions = [];
|
|
@@ -83972,13 +84955,13 @@ var init_htmlTemplate = __esm({
|
|
|
83972
84955
|
});
|
|
83973
84956
|
|
|
83974
84957
|
// ../engine/src/services/extractionCache.ts
|
|
83975
|
-
import { createHash as createHash2, randomUUID as
|
|
84958
|
+
import { createHash as createHash2, randomUUID as randomUUID3 } from "crypto";
|
|
83976
84959
|
import {
|
|
83977
84960
|
existsSync as existsSync13,
|
|
83978
84961
|
lstatSync as lstatSync2,
|
|
83979
84962
|
mkdirSync as mkdirSync6,
|
|
83980
|
-
readdirSync as
|
|
83981
|
-
renameSync as
|
|
84963
|
+
readdirSync as readdirSync5,
|
|
84964
|
+
renameSync as renameSync2,
|
|
83982
84965
|
rmSync as rmSync3,
|
|
83983
84966
|
statSync as statSync5,
|
|
83984
84967
|
utimesSync,
|
|
@@ -84020,7 +85003,7 @@ function lookupCacheEntry(rootDir, input2) {
|
|
|
84020
85003
|
return { entry: { dir, keyHash }, hit: complete };
|
|
84021
85004
|
}
|
|
84022
85005
|
function partialCacheEntryDir(entry) {
|
|
84023
|
-
return `${entry.dir}.partial-${process.pid}-${
|
|
85006
|
+
return `${entry.dir}.partial-${process.pid}-${randomUUID3().slice(0, 8)}`;
|
|
84024
85007
|
}
|
|
84025
85008
|
function isTargetExistsRenameError(err) {
|
|
84026
85009
|
const code = err.code;
|
|
@@ -84038,7 +85021,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
84038
85021
|
return { dir: partialDir, published: false };
|
|
84039
85022
|
}
|
|
84040
85023
|
try {
|
|
84041
|
-
|
|
85024
|
+
renameSync2(partialDir, entry.dir);
|
|
84042
85025
|
return { dir: entry.dir, published: true };
|
|
84043
85026
|
} catch (err) {
|
|
84044
85027
|
if (!isTargetExistsRenameError(err)) return { dir: partialDir, published: false };
|
|
@@ -84051,7 +85034,7 @@ function publishCacheEntry(entry, partialDir) {
|
|
|
84051
85034
|
return { dir: partialDir, published: false };
|
|
84052
85035
|
}
|
|
84053
85036
|
try {
|
|
84054
|
-
|
|
85037
|
+
renameSync2(partialDir, entry.dir);
|
|
84055
85038
|
return { dir: entry.dir, published: true };
|
|
84056
85039
|
} catch {
|
|
84057
85040
|
return adoptPublishedWinner(entry, partialDir) ?? { dir: partialDir, published: false };
|
|
@@ -84080,7 +85063,7 @@ function directorySizeBytes(path2) {
|
|
|
84080
85063
|
let total = 0;
|
|
84081
85064
|
let children;
|
|
84082
85065
|
try {
|
|
84083
|
-
children =
|
|
85066
|
+
children = readdirSync5(path2);
|
|
84084
85067
|
} catch {
|
|
84085
85068
|
return 0;
|
|
84086
85069
|
}
|
|
@@ -84138,7 +85121,7 @@ function gcExtractionCache(rootDir, opts) {
|
|
|
84138
85121
|
try {
|
|
84139
85122
|
const now = Date.now();
|
|
84140
85123
|
const entries2 = [];
|
|
84141
|
-
for (const child of
|
|
85124
|
+
for (const child of readdirSync5(rootDir, { withFileTypes: true })) {
|
|
84142
85125
|
if (!child.isDirectory() || !isCacheLikeChild(child.name)) continue;
|
|
84143
85126
|
const entry = collectGcEntry(
|
|
84144
85127
|
join11(rootDir, child.name),
|
|
@@ -84168,7 +85151,7 @@ function rehydrateCacheEntry(entry, options) {
|
|
|
84168
85151
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${options.format}`;
|
|
84169
85152
|
const framePaths = /* @__PURE__ */ new Map();
|
|
84170
85153
|
const suffix = `.${options.format}`;
|
|
84171
|
-
const files =
|
|
85154
|
+
const files = readdirSync5(entry.dir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(suffix)).sort();
|
|
84172
85155
|
files.forEach((file, idx) => {
|
|
84173
85156
|
framePaths.set(idx, join11(entry.dir, file));
|
|
84174
85157
|
});
|
|
@@ -84197,7 +85180,7 @@ var init_extractionCache = __esm({
|
|
|
84197
85180
|
});
|
|
84198
85181
|
|
|
84199
85182
|
// ../engine/src/services/videoFrameExtractor.ts
|
|
84200
|
-
import { copyFileSync as copyFileSync2, existsSync as existsSync14, linkSync, mkdirSync as mkdirSync7, readdirSync as
|
|
85183
|
+
import { copyFileSync as copyFileSync2, existsSync as existsSync14, linkSync as linkSync2, mkdirSync as mkdirSync7, readdirSync as readdirSync6, rmSync as rmSync4 } from "fs";
|
|
84201
85184
|
import { isAbsolute as isAbsolute4, join as join12, posix as posix3, resolve as resolve10, sep as sep3 } from "path";
|
|
84202
85185
|
function isVideoFrameFormat(value) {
|
|
84203
85186
|
return typeof value === "string" && VIDEO_FRAME_FORMATS.includes(value);
|
|
@@ -84281,6 +85264,14 @@ function classifyVideoExtractionError(error) {
|
|
|
84281
85264
|
diagnostic
|
|
84282
85265
|
);
|
|
84283
85266
|
}
|
|
85267
|
+
if (error.kind === "invalid_payload") {
|
|
85268
|
+
return new VideoSourceExtractionError(
|
|
85269
|
+
"invalid_media",
|
|
85270
|
+
false,
|
|
85271
|
+
"Video source download returned a non-media payload",
|
|
85272
|
+
diagnostic
|
|
85273
|
+
);
|
|
85274
|
+
}
|
|
84284
85275
|
if (error.retryable) {
|
|
84285
85276
|
return new VideoSourceExtractionError(
|
|
84286
85277
|
"download_transient",
|
|
@@ -84578,7 +85569,7 @@ async function extractVideoFramesRange(videoPath, videoId, startTime, duration,
|
|
|
84578
85569
|
);
|
|
84579
85570
|
}
|
|
84580
85571
|
const framePaths = /* @__PURE__ */ new Map();
|
|
84581
|
-
const files =
|
|
85572
|
+
const files = readdirSync6(videoOutputDir).filter((f3) => f3.startsWith(FRAME_FILENAME_PREFIX) && f3.endsWith(`.${format}`)).sort();
|
|
84582
85573
|
files.forEach((file, index) => {
|
|
84583
85574
|
framePaths.set(index, join12(videoOutputDir, file));
|
|
84584
85575
|
});
|
|
@@ -84755,7 +85746,7 @@ function resolveFrameFormat(metadata, requested) {
|
|
|
84755
85746
|
}
|
|
84756
85747
|
function extractedFrameFileNames(outputDir, format) {
|
|
84757
85748
|
const suffix = `.${format}`;
|
|
84758
|
-
return
|
|
85749
|
+
return readdirSync6(outputDir).filter((file) => file.startsWith(FRAME_FILENAME_PREFIX) && file.endsWith(suffix)).sort();
|
|
84759
85750
|
}
|
|
84760
85751
|
function extractedFramesFromDirectory(work, outputDir, srcPath, fps) {
|
|
84761
85752
|
const framePattern = `${FRAME_FILENAME_PREFIX}%05d.${work.format}`;
|
|
@@ -84779,7 +85770,7 @@ function frameFileName(frameNumber, format) {
|
|
|
84779
85770
|
}
|
|
84780
85771
|
function linkOrCopyFrame(src, dest) {
|
|
84781
85772
|
try {
|
|
84782
|
-
|
|
85773
|
+
linkSync2(src, dest);
|
|
84783
85774
|
} catch {
|
|
84784
85775
|
copyFileSync2(src, dest);
|
|
84785
85776
|
}
|
|
@@ -84964,7 +85955,8 @@ async function extractAllVideoFrames(videos, baseDir, options, signal, config, c
|
|
|
84964
85955
|
downloadDir,
|
|
84965
85956
|
void 0,
|
|
84966
85957
|
signal,
|
|
84967
|
-
() => recordTransientRetries(1)
|
|
85958
|
+
() => recordTransientRetries(1),
|
|
85959
|
+
{ onTelemetry: writeUrlDownloadTelemetry }
|
|
84968
85960
|
);
|
|
84969
85961
|
}
|
|
84970
85962
|
if (!existsSync14(videoPath)) {
|
|
@@ -86021,7 +87013,7 @@ var init_videoFrameInjector = __esm({
|
|
|
86021
87013
|
});
|
|
86022
87014
|
|
|
86023
87015
|
// ../engine/src/services/audioVolumeEnvelope.ts
|
|
86024
|
-
import { readFileSync as readFileSync6, renameSync as
|
|
87016
|
+
import { readFileSync as readFileSync6, renameSync as renameSync3, writeFileSync as writeFileSync5 } from "fs";
|
|
86025
87017
|
import { randomBytes } from "crypto";
|
|
86026
87018
|
function parseWavLayout(buffer) {
|
|
86027
87019
|
if (buffer.length < 12 || buffer.toString("ascii", 0, 4) !== "RIFF") return null;
|
|
@@ -86083,7 +87075,7 @@ function applyVolumeEnvelopeToWav(wavPath, keyframes, trackStart, baseVolume) {
|
|
|
86083
87075
|
}
|
|
86084
87076
|
const tempPath = `${wavPath}.${randomBytes(6).toString("hex")}.tmp`;
|
|
86085
87077
|
writeFileSync5(tempPath, buffer);
|
|
86086
|
-
|
|
87078
|
+
renameSync3(tempPath, wavPath);
|
|
86087
87079
|
return true;
|
|
86088
87080
|
} catch {
|
|
86089
87081
|
return false;
|
|
@@ -86224,15 +87216,17 @@ function probeFailure(message, elementId) {
|
|
|
86224
87216
|
detail: boundedDetail(`Audio probe failed for element ${elementId}: ${message}`)
|
|
86225
87217
|
};
|
|
86226
87218
|
}
|
|
86227
|
-
function downloadFailure(
|
|
86228
|
-
const
|
|
87219
|
+
function downloadFailure(error, elementId) {
|
|
87220
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
87221
|
+
const invalidSource = error instanceof UrlDownloadError ? error.kind === "http_not_found" || error.kind === "http_rejected" || error.kind === "invalid_payload" || error.kind === "cancelled" : /(?:invalid URL|only HTTPS|private\/reserved|HTTP (?:400|401|403|404|405|410|422)\b)/i.test(
|
|
86229
87222
|
message
|
|
86230
87223
|
);
|
|
87224
|
+
const retryable = error instanceof UrlDownloadError ? error.retryable : !invalidSource;
|
|
86231
87225
|
return {
|
|
86232
87226
|
stage: "download",
|
|
86233
87227
|
reason: "download_failed",
|
|
86234
87228
|
owner: invalidSource ? "user" : "system",
|
|
86235
|
-
retryable
|
|
87229
|
+
retryable,
|
|
86236
87230
|
elementId,
|
|
86237
87231
|
detail: boundedDetail(`Download failed for audio element ${elementId}: ${message}`)
|
|
86238
87232
|
};
|
|
@@ -86579,11 +87573,11 @@ async function processCompositionAudio(elements, baseDir, workDir, outputPath, t
|
|
|
86579
87573
|
}
|
|
86580
87574
|
if (isHttpUrl(srcPath)) {
|
|
86581
87575
|
try {
|
|
86582
|
-
srcPath = await downloadToTemp(srcPath, workDir
|
|
87576
|
+
srcPath = await downloadToTemp(srcPath, workDir, void 0, signal, void 0, {
|
|
87577
|
+
onTelemetry: writeUrlDownloadTelemetry
|
|
87578
|
+
});
|
|
86583
87579
|
} catch (err) {
|
|
86584
|
-
failures.push(
|
|
86585
|
-
downloadFailure(err instanceof Error ? err.message : String(err), element.id)
|
|
86586
|
-
);
|
|
87580
|
+
failures.push(downloadFailure(err, element.id));
|
|
86587
87581
|
return;
|
|
86588
87582
|
}
|
|
86589
87583
|
}
|
|
@@ -86863,7 +87857,7 @@ var init_readWebGlVendorInfoFromCanvas = __esm({
|
|
|
86863
87857
|
|
|
86864
87858
|
// ../engine/src/services/parallelCoordinator.ts
|
|
86865
87859
|
import { cpus, freemem } from "os";
|
|
86866
|
-
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readdirSync as
|
|
87860
|
+
import { existsSync as existsSync16, mkdirSync as mkdirSync9, readdirSync as readdirSync7 } from "fs";
|
|
86867
87861
|
import { copyFile, readFile, rename } from "fs/promises";
|
|
86868
87862
|
import { join as join15 } from "path";
|
|
86869
87863
|
import { getHeapStatistics } from "v8";
|
|
@@ -87289,7 +88283,7 @@ async function mergeWorkerFrames(workDir, tasks, outputDir) {
|
|
|
87289
88283
|
if (!existsSync16(task.outputDir)) {
|
|
87290
88284
|
continue;
|
|
87291
88285
|
}
|
|
87292
|
-
const files =
|
|
88286
|
+
const files = readdirSync7(task.outputDir).filter((f3) => f3.startsWith("frame_") && (f3.endsWith(".jpg") || f3.endsWith(".png"))).sort();
|
|
87293
88287
|
const copyTasks = files.map(async (file) => {
|
|
87294
88288
|
const sourcePath = join15(task.outputDir, file);
|
|
87295
88289
|
const targetPath = join15(outputDir, file);
|
|
@@ -88804,7 +89798,7 @@ var init_shaderTransitions = __esm({
|
|
|
88804
89798
|
});
|
|
88805
89799
|
|
|
88806
89800
|
// ../engine/src/services/hdrCapture.ts
|
|
88807
|
-
import { existsSync as existsSync18, readdirSync as
|
|
89801
|
+
import { existsSync as existsSync18, readdirSync as readdirSync8 } from "fs";
|
|
88808
89802
|
import { join as join17 } from "path";
|
|
88809
89803
|
import { homedir as homedir3 } from "os";
|
|
88810
89804
|
function linearToPQ(L2) {
|
|
@@ -88923,7 +89917,7 @@ function float16ToPqRgb(rawBuffer, bytesPerRow, width, height) {
|
|
|
88923
89917
|
function resolveHeadedChromePath() {
|
|
88924
89918
|
const baseDir = join17(homedir3(), ".cache", "puppeteer", "chrome");
|
|
88925
89919
|
if (!existsSync18(baseDir)) return void 0;
|
|
88926
|
-
const versions =
|
|
89920
|
+
const versions = readdirSync8(baseDir).sort().reverse();
|
|
88927
89921
|
for (const version2 of versions) {
|
|
88928
89922
|
const candidates = [
|
|
88929
89923
|
join17(
|
|
@@ -89086,6 +90080,7 @@ __export(src_exports, {
|
|
|
89086
90080
|
decodePng: () => decodePng,
|
|
89087
90081
|
decodePngToRgb48le: () => decodePngToRgb48le,
|
|
89088
90082
|
defaultExtractCacheDir: () => defaultExtractCacheDir,
|
|
90083
|
+
deriveBeginFrameProbeTimeTicks: () => deriveBeginFrameProbeTimeTicks,
|
|
89089
90084
|
detectGpuEncoder: () => detectGpuEncoder,
|
|
89090
90085
|
detectTransfer: () => detectTransfer,
|
|
89091
90086
|
diffGpuParityFrames: () => diffGpuParityFrames,
|
|
@@ -89105,6 +90100,7 @@ __export(src_exports, {
|
|
|
89105
90100
|
extractVideoFramesRange: () => extractVideoFramesRange,
|
|
89106
90101
|
extractVideoMetadata: () => extractVideoMetadata,
|
|
89107
90102
|
extractionFrameCountForDuration: () => extractionFrameCountForDuration,
|
|
90103
|
+
fetchPublicHttpsText: () => fetchPublicHttpsText,
|
|
89108
90104
|
float16ToPqRgb: () => float16ToPqRgb,
|
|
89109
90105
|
formatFfmpegError: () => formatFfmpegError,
|
|
89110
90106
|
getCapturePerfSummary: () => getCapturePerfSummary,
|
|
@@ -89178,6 +90174,7 @@ __export(src_exports, {
|
|
|
89178
90174
|
roundedRectAlpha: () => roundedRectAlpha,
|
|
89179
90175
|
runFfmpeg: () => runFfmpeg,
|
|
89180
90176
|
runVideoExtractionWithRetry: () => runVideoExtractionWithRetry,
|
|
90177
|
+
safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
|
|
89181
90178
|
sampleRgb48le: () => sampleRgb48le,
|
|
89182
90179
|
scaleProtocolTimeoutForComposition: () => scaleProtocolTimeoutForComposition,
|
|
89183
90180
|
selectVerifySampleIndicesForTask: () => selectVerifySampleIndicesForTask,
|
|
@@ -89190,7 +90187,8 @@ __export(src_exports, {
|
|
|
89190
90187
|
validateEngineConfigSnapshot: () => validateEngineConfigSnapshot,
|
|
89191
90188
|
verifyDiskDrawElementSamples: () => verifyDiskDrawElementSamples,
|
|
89192
90189
|
verifyGpuParity: () => verifyGpuParity,
|
|
89193
|
-
writeCapturedFrame: () => writeCapturedFrame
|
|
90190
|
+
writeCapturedFrame: () => writeCapturedFrame,
|
|
90191
|
+
writeUrlDownloadTelemetry: () => writeUrlDownloadTelemetry
|
|
89194
90192
|
});
|
|
89195
90193
|
var init_src = __esm({
|
|
89196
90194
|
"../engine/src/index.ts"() {
|
|
@@ -89748,10 +90746,10 @@ var init_canary2 = __esm({
|
|
|
89748
90746
|
|
|
89749
90747
|
// src/telemetry/transport.ts
|
|
89750
90748
|
import { spawn as spawn5 } from "child_process";
|
|
89751
|
-
import { randomUUID as
|
|
90749
|
+
import { randomUUID as randomUUID4 } from "crypto";
|
|
89752
90750
|
function enqueue(event, properties, distinctId) {
|
|
89753
90751
|
eventQueue.push({
|
|
89754
|
-
uuid:
|
|
90752
|
+
uuid: randomUUID4(),
|
|
89755
90753
|
event,
|
|
89756
90754
|
distinctId,
|
|
89757
90755
|
properties,
|
|
@@ -93231,12 +94229,12 @@ var init_ffmpeg = __esm({
|
|
|
93231
94229
|
});
|
|
93232
94230
|
|
|
93233
94231
|
// src/utils/download.ts
|
|
93234
|
-
import { createWriteStream as createWriteStream2, renameSync as
|
|
94232
|
+
import { createWriteStream as createWriteStream2, renameSync as renameSync4, unlinkSync as unlinkSync2 } from "fs";
|
|
93235
94233
|
import { get as httpsGet } from "https";
|
|
93236
94234
|
import { pipeline as pipeline2 } from "stream/promises";
|
|
93237
94235
|
function removePartialFile(path2) {
|
|
93238
94236
|
try {
|
|
93239
|
-
|
|
94237
|
+
unlinkSync2(path2);
|
|
93240
94238
|
} catch {
|
|
93241
94239
|
}
|
|
93242
94240
|
}
|
|
@@ -93267,7 +94265,7 @@ function downloadFile(url, dest, options = {}) {
|
|
|
93267
94265
|
const file = createWriteStream2(tmp);
|
|
93268
94266
|
responsePipelineStarted = true;
|
|
93269
94267
|
pipeline2(res, file).then(() => {
|
|
93270
|
-
|
|
94268
|
+
renameSync4(tmp, dest);
|
|
93271
94269
|
resolve77();
|
|
93272
94270
|
}).catch((err) => {
|
|
93273
94271
|
removePartialFile(tmp);
|
|
@@ -93500,10 +94498,10 @@ __export(transcribe_exports, {
|
|
|
93500
94498
|
wrapWhisperTimeoutError: () => wrapWhisperTimeoutError
|
|
93501
94499
|
});
|
|
93502
94500
|
import { execFileSync as execFileSync5 } from "child_process";
|
|
93503
|
-
import { existsSync as existsSync25, readFileSync as readFileSync14, mkdirSync as mkdirSync12, unlinkSync as
|
|
94501
|
+
import { existsSync as existsSync25, readFileSync as readFileSync14, mkdirSync as mkdirSync12, unlinkSync as unlinkSync3 } from "fs";
|
|
93504
94502
|
import { join as join21, extname as extname5 } from "path";
|
|
93505
94503
|
import { tmpdir as tmpdir3 } from "os";
|
|
93506
|
-
import { randomUUID as
|
|
94504
|
+
import { randomUUID as randomUUID5 } from "crypto";
|
|
93507
94505
|
function detectLanguage(whisperPath, modelPath2, wavPath) {
|
|
93508
94506
|
try {
|
|
93509
94507
|
const output = execFileSync5(whisperPath, ["--model", modelPath2, "--detect-language", wavPath], {
|
|
@@ -93573,6 +94571,7 @@ function getMediaDurationSeconds(filePath) {
|
|
|
93573
94571
|
"format=duration",
|
|
93574
94572
|
"-of",
|
|
93575
94573
|
"default=noprint_wrappers=1:nokey=1",
|
|
94574
|
+
"--",
|
|
93576
94575
|
filePath
|
|
93577
94576
|
],
|
|
93578
94577
|
{ encoding: "utf-8", timeout: 1e4 }
|
|
@@ -93644,7 +94643,7 @@ function isVideoFile(filePath) {
|
|
|
93644
94643
|
return VIDEO_EXTENSIONS.has(extname5(filePath).toLowerCase());
|
|
93645
94644
|
}
|
|
93646
94645
|
function tempWavPath() {
|
|
93647
|
-
return join21(tmpdir3(), `hyperframes-audio-${process.pid}-${
|
|
94646
|
+
return join21(tmpdir3(), `hyperframes-audio-${process.pid}-${randomUUID5()}.wav`);
|
|
93648
94647
|
}
|
|
93649
94648
|
function extractAudio(videoPath) {
|
|
93650
94649
|
const ffmpegPath = findFFmpeg();
|
|
@@ -93670,7 +94669,7 @@ function isWav16kMono(filePath) {
|
|
|
93670
94669
|
if (!ffprobePath) return false;
|
|
93671
94670
|
const raw = execFileSync5(
|
|
93672
94671
|
ffprobePath,
|
|
93673
|
-
["-v", "quiet", "-print_format", "json", "-show_streams", filePath],
|
|
94672
|
+
["-v", "quiet", "-print_format", "json", "-show_streams", "--", filePath],
|
|
93674
94673
|
{ encoding: "utf-8", timeout: 1e4 }
|
|
93675
94674
|
);
|
|
93676
94675
|
const parsed = JSON.parse(raw);
|
|
@@ -93802,7 +94801,7 @@ async function transcribe(inputPath, outputDir, options) {
|
|
|
93802
94801
|
const speechOnsetSeconds = detectSpeechOnset(wavPath);
|
|
93803
94802
|
if (wavPath !== inputPath) {
|
|
93804
94803
|
try {
|
|
93805
|
-
|
|
94804
|
+
unlinkSync3(wavPath);
|
|
93806
94805
|
} catch {
|
|
93807
94806
|
}
|
|
93808
94807
|
}
|
|
@@ -93872,7 +94871,7 @@ __export(normalize_exports, {
|
|
|
93872
94871
|
stripBeforeOnset: () => stripBeforeOnset,
|
|
93873
94872
|
wordsToCues: () => wordsToCues
|
|
93874
94873
|
});
|
|
93875
|
-
import { readFileSync as readFileSync15, readdirSync as
|
|
94874
|
+
import { readFileSync as readFileSync15, readdirSync as readdirSync9, writeFileSync as writeFileSync9 } from "fs";
|
|
93876
94875
|
import { extname as extname6, join as join23 } from "path";
|
|
93877
94876
|
function detectFormat(filePath) {
|
|
93878
94877
|
const ext = extname6(filePath).toLowerCase();
|
|
@@ -94150,7 +95149,7 @@ function patchCaptionHtml(dir, words) {
|
|
|
94150
95149
|
const wordsJson = JSON.stringify(words, null, 2).replace(/\n/g, "\n ");
|
|
94151
95150
|
let htmlFiles;
|
|
94152
95151
|
try {
|
|
94153
|
-
htmlFiles =
|
|
95152
|
+
htmlFiles = readdirSync9(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join23(e3.parentPath, e3.name));
|
|
94154
95153
|
} catch {
|
|
94155
95154
|
return;
|
|
94156
95155
|
}
|
|
@@ -94640,9 +95639,9 @@ import { execFile as execFile3 } from "child_process";
|
|
|
94640
95639
|
import { createHash as createHash3 } from "crypto";
|
|
94641
95640
|
import {
|
|
94642
95641
|
existsSync as existsSync27,
|
|
94643
|
-
readdirSync as
|
|
95642
|
+
readdirSync as readdirSync10,
|
|
94644
95643
|
readFileSync as readFileSync18,
|
|
94645
|
-
renameSync as
|
|
95644
|
+
renameSync as renameSync5,
|
|
94646
95645
|
statSync as statSync8,
|
|
94647
95646
|
writeFileSync as writeFileSync11
|
|
94648
95647
|
} from "fs";
|
|
@@ -94655,7 +95654,7 @@ function isCoreSkill(name) {
|
|
|
94655
95654
|
function listFilesSorted(dir) {
|
|
94656
95655
|
const out = [];
|
|
94657
95656
|
const walk = (d2) => {
|
|
94658
|
-
for (const name of
|
|
95657
|
+
for (const name of readdirSync10(d2)) {
|
|
94659
95658
|
if (name === ".DS_Store") continue;
|
|
94660
95659
|
const p2 = join26(d2, name);
|
|
94661
95660
|
if (statSync8(p2).isDirectory()) walk(p2);
|
|
@@ -94681,7 +95680,7 @@ function hashSkillBundle(skillDir) {
|
|
|
94681
95680
|
return { hash: h3.digest("hex").slice(0, 16), files: files.length };
|
|
94682
95681
|
}
|
|
94683
95682
|
function buildManifest(skillsRoot, meta) {
|
|
94684
|
-
const names =
|
|
95683
|
+
const names = readdirSync10(skillsRoot).filter((n2) => existsSync27(join26(skillsRoot, n2, "SKILL.md"))).sort();
|
|
94685
95684
|
const skills = {};
|
|
94686
95685
|
for (const name of names) skills[name] = hashSkillBundle(join26(skillsRoot, name));
|
|
94687
95686
|
return { source: meta.source, skills };
|
|
@@ -94697,7 +95696,7 @@ function agentFromDir(dir) {
|
|
|
94697
95696
|
}
|
|
94698
95697
|
function listSubdirs(dir) {
|
|
94699
95698
|
try {
|
|
94700
|
-
return
|
|
95699
|
+
return readdirSync10(dir, { withFileTypes: true }).filter((e3) => e3.isDirectory() || e3.isSymbolicLink()).map((e3) => e3.name);
|
|
94701
95700
|
} catch {
|
|
94702
95701
|
return [];
|
|
94703
95702
|
}
|
|
@@ -94837,7 +95836,7 @@ function pruneOrphanedLockEntries(names, scope, opts = {}) {
|
|
|
94837
95836
|
const mode = statSync8(path2).mode & 511;
|
|
94838
95837
|
const tmp = `${path2}.tmp`;
|
|
94839
95838
|
writeFileSync11(tmp, JSON.stringify(lock, null, 2), { mode });
|
|
94840
|
-
|
|
95839
|
+
renameSync5(tmp, path2);
|
|
94841
95840
|
return pruned;
|
|
94842
95841
|
}
|
|
94843
95842
|
function findRepoManifest(cwd = process.cwd()) {
|
|
@@ -95053,7 +96052,7 @@ var init_agentDirs_generated = __esm({
|
|
|
95053
96052
|
});
|
|
95054
96053
|
|
|
95055
96054
|
// src/utils/skillsMirror.ts
|
|
95056
|
-
import { cpSync, existsSync as existsSync28, mkdirSync as mkdirSync13, readdirSync as
|
|
96055
|
+
import { cpSync, existsSync as existsSync28, mkdirSync as mkdirSync13, readdirSync as readdirSync11, rmSync as rmSync7, symlinkSync } from "fs";
|
|
95057
96056
|
import { homedir as homedir7 } from "os";
|
|
95058
96057
|
import { dirname as dirname11, isAbsolute as isAbsolute7, join as join27, relative as relative7 } from "path";
|
|
95059
96058
|
function resolveBases(home, env) {
|
|
@@ -95069,7 +96068,7 @@ function resolveBases(home, env) {
|
|
|
95069
96068
|
};
|
|
95070
96069
|
}
|
|
95071
96070
|
function listSkillDirs(store) {
|
|
95072
|
-
return
|
|
96071
|
+
return readdirSync11(store, { withFileTypes: true }).filter(
|
|
95073
96072
|
(e3) => (e3.isDirectory() || e3.isSymbolicLink()) && existsSync28(join27(store, e3.name, "SKILL.md"))
|
|
95074
96073
|
).map((e3) => e3.name);
|
|
95075
96074
|
}
|
|
@@ -97981,7 +98980,7 @@ var init_chunk_W2SBTCO2 = __esm({
|
|
|
97981
98980
|
}
|
|
97982
98981
|
});
|
|
97983
98982
|
|
|
97984
|
-
// ../studio-server/dist/chunk-
|
|
98983
|
+
// ../studio-server/dist/chunk-6H3V3WGJ.js
|
|
97985
98984
|
import { existsSync as existsSync33, statSync as statSync10 } from "fs";
|
|
97986
98985
|
import { relative as relative8, resolve as resolve19, sep as sep5 } from "path";
|
|
97987
98986
|
import { execFile as execFile5 } from "child_process";
|
|
@@ -98048,6 +99047,7 @@ async function probeMediaMetadata(filePath, runner = execFileRunner) {
|
|
|
98048
99047
|
"stream=codec_type,codec_name,profile,pix_fmt,color_space,color_transfer,color_primaries,bits_per_raw_sample:stream_disposition=attached_pic",
|
|
98049
99048
|
"-of",
|
|
98050
99049
|
"json",
|
|
99050
|
+
"--",
|
|
98051
99051
|
filePath
|
|
98052
99052
|
],
|
|
98053
99053
|
{ timeout: 15e3, maxBuffer: 1024 * 1024 }
|
|
@@ -98184,8 +99184,8 @@ async function scanProjectMediaCodecMap(projectDir, htmlSources, options = {}) {
|
|
|
98184
99184
|
return map;
|
|
98185
99185
|
}
|
|
98186
99186
|
var execFileRunner, VIDEO_EXT, IMAGE_EXT, AUDIO_EXT, ALPHA_PIX_FMT_RE, BROWSER_HOSTILE_CODECS, PROXY_VARIANT_CONFIG, defaultProbeCache, MAX_PROBE_CACHE_ENTRIES, VIDEO_SRC_RE, PROBE_CONCURRENCY2;
|
|
98187
|
-
var
|
|
98188
|
-
"../studio-server/dist/chunk-
|
|
99187
|
+
var init_chunk_6H3V3WGJ = __esm({
|
|
99188
|
+
"../studio-server/dist/chunk-6H3V3WGJ.js"() {
|
|
98189
99189
|
"use strict";
|
|
98190
99190
|
init_assets();
|
|
98191
99191
|
init_assetResolution();
|
|
@@ -98244,20 +99244,20 @@ var init_chunk_I2USK772 = __esm({
|
|
|
98244
99244
|
}
|
|
98245
99245
|
});
|
|
98246
99246
|
|
|
98247
|
-
// ../studio-server/dist/chunk-
|
|
99247
|
+
// ../studio-server/dist/chunk-ZPI6QXJH.js
|
|
98248
99248
|
import { spawn as spawn8 } from "child_process";
|
|
98249
|
-
import { createHash as createHash6, randomUUID as
|
|
99249
|
+
import { createHash as createHash6, randomUUID as randomUUID6 } from "crypto";
|
|
98250
99250
|
import {
|
|
98251
99251
|
existsSync as existsSync210,
|
|
98252
99252
|
mkdirSync as mkdirSync15,
|
|
98253
99253
|
realpathSync as realpathSync4,
|
|
98254
|
-
renameSync as
|
|
99254
|
+
renameSync as renameSync6,
|
|
98255
99255
|
statSync as statSync22,
|
|
98256
99256
|
unlinkSync as unlinkSync22,
|
|
98257
99257
|
utimesSync as utimesSync2
|
|
98258
99258
|
} from "fs";
|
|
98259
99259
|
import { basename as basename4, dirname as dirname14, isAbsolute as isAbsolute8, join as join29, relative as relative9, resolve as resolve20, sep as sep6 } from "path";
|
|
98260
|
-
import { existsSync as existsSync34, readdirSync as
|
|
99260
|
+
import { existsSync as existsSync34, readdirSync as readdirSync12, statSync as statSync11, unlinkSync as unlinkSync4 } from "fs";
|
|
98261
99261
|
import { extname as extname8, join as join30 } from "path";
|
|
98262
99262
|
function positiveEnvNumber(name, fallback) {
|
|
98263
99263
|
const parsed = Number(process.env[name]);
|
|
@@ -98283,7 +99283,7 @@ function shouldSkipSweep(cacheDir, now, minSweepIntervalMs) {
|
|
|
98283
99283
|
function readCacheInventory(cacheDir, protectedPaths, now, staleTempMs) {
|
|
98284
99284
|
const entries2 = [];
|
|
98285
99285
|
const staleTemps = [];
|
|
98286
|
-
for (const dirent of
|
|
99286
|
+
for (const dirent of readdirSync12(cacheDir, { withFileTypes: true })) {
|
|
98287
99287
|
if (!dirent.isFile()) continue;
|
|
98288
99288
|
const path2 = join30(cacheDir, dirent.name);
|
|
98289
99289
|
const stat3 = statSync11(path2);
|
|
@@ -98309,7 +99309,7 @@ function evictCacheEntries(entries2, staleTemps, now, maxIdleMs, maxBytes) {
|
|
|
98309
99309
|
let bytesAfter = bytesBefore;
|
|
98310
99310
|
const removed = [];
|
|
98311
99311
|
const remove2 = (entry, countsTowardBudget) => {
|
|
98312
|
-
|
|
99312
|
+
unlinkSync4(entry.path);
|
|
98313
99313
|
removed.push(entry.path);
|
|
98314
99314
|
if (countsTowardBudget) bytesAfter -= entry.size;
|
|
98315
99315
|
};
|
|
@@ -98570,10 +99570,10 @@ async function transcodeToCache(absoluteSourcePath, cachePath2, variant) {
|
|
|
98570
99570
|
if (existsSync210(cachePath2)) return cachePath2;
|
|
98571
99571
|
const cacheDir = dirname14(cachePath2);
|
|
98572
99572
|
mkdirSync15(cacheDir, { recursive: true });
|
|
98573
|
-
const tempPath = join29(cacheDir, `.tmp-${
|
|
99573
|
+
const tempPath = join29(cacheDir, `.tmp-${randomUUID6()}-${basename4(cachePath2)}`);
|
|
98574
99574
|
try {
|
|
98575
99575
|
await runFfmpeg2(absoluteSourcePath, tempPath, variant);
|
|
98576
|
-
|
|
99576
|
+
renameSync6(tempPath, cachePath2);
|
|
98577
99577
|
maintainProxyCache(cacheDir);
|
|
98578
99578
|
return cachePath2;
|
|
98579
99579
|
} finally {
|
|
@@ -98610,10 +99610,10 @@ async function resolveProxy(projectDir, absoluteSourcePath, variant = "h264") {
|
|
|
98610
99610
|
return promise;
|
|
98611
99611
|
}
|
|
98612
99612
|
var DEFAULT_MAX_BYTES, DEFAULT_STALE_TEMP_MS, DEFAULT_MIN_SWEEP_INTERVAL_MS, PROXY_EXTENSIONS, lastSweepAt, PROXY_PARAMS_VERSION, CACHE_DIR_NAME, MAX_CONCURRENT_TRANSCODES, MAX_QUEUED_TRANSCODES, STDERR_TAIL_MAX_CHARS, TRANSCODE_TIMEOUT_MS, FAILURE_CACHE_TTL_MS, MAX_FAILURE_CACHE_ENTRIES, DEFAULT_PROXY_WAIT_TIMEOUT_MS, ProxyTranscodeError, FfmpegUnavailableError, FfmpegMissingFilterError, ProxyCapacityError, ProxySourceOutsideProjectError, ProxyWaitTimeoutError, activeTranscodes, waitQueue, inFlight, failedTranscodes, hdrFilterCheck;
|
|
98613
|
-
var
|
|
98614
|
-
"../studio-server/dist/chunk-
|
|
99613
|
+
var init_chunk_ZPI6QXJH = __esm({
|
|
99614
|
+
"../studio-server/dist/chunk-ZPI6QXJH.js"() {
|
|
98615
99615
|
"use strict";
|
|
98616
|
-
|
|
99616
|
+
init_chunk_6H3V3WGJ();
|
|
98617
99617
|
init_ffBinaries();
|
|
98618
99618
|
DEFAULT_MAX_BYTES = 10 * 1024 * 1024 * 1024;
|
|
98619
99619
|
DEFAULT_STALE_TEMP_MS = 60 * 60 * 1e3;
|
|
@@ -98681,7 +99681,7 @@ var init_chunk_IQAVZUQP = __esm({
|
|
|
98681
99681
|
}
|
|
98682
99682
|
});
|
|
98683
99683
|
|
|
98684
|
-
// ../studio-server/dist/chunk-
|
|
99684
|
+
// ../studio-server/dist/chunk-LHYV3WLZ.js
|
|
98685
99685
|
import { resolve as resolve21 } from "path";
|
|
98686
99686
|
function isAutoProxyEnabled(adapter2) {
|
|
98687
99687
|
return adapter2.autoProxy !== false;
|
|
@@ -98728,11 +99728,11 @@ async function injectMediaCodecMap(html, adapter2, projectDir, compSrcPath, prob
|
|
|
98728
99728
|
if (!isAutoProxyEnabled(adapter2)) return html;
|
|
98729
99729
|
return injectMediaCodecMapIntoHtml(html, projectDir, [{ html, compSrcPath }], probeCache);
|
|
98730
99730
|
}
|
|
98731
|
-
var
|
|
98732
|
-
"../studio-server/dist/chunk-
|
|
99731
|
+
var init_chunk_LHYV3WLZ = __esm({
|
|
99732
|
+
"../studio-server/dist/chunk-LHYV3WLZ.js"() {
|
|
98733
99733
|
"use strict";
|
|
98734
|
-
|
|
98735
|
-
|
|
99734
|
+
init_chunk_ZPI6QXJH();
|
|
99735
|
+
init_chunk_6H3V3WGJ();
|
|
98736
99736
|
}
|
|
98737
99737
|
});
|
|
98738
99738
|
|
|
@@ -102421,7 +103421,7 @@ var init_gsapWriterAcorn = __esm({
|
|
|
102421
103421
|
|
|
102422
103422
|
// ../core/dist/fonts/systemFontLocator.js
|
|
102423
103423
|
import { execFileSync as execFileSync7 } from "child_process";
|
|
102424
|
-
import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as
|
|
103424
|
+
import { existsSync as existsSync35, lstatSync as lstatSync3, readdirSync as readdirSync13, realpathSync as realpathSync5 } from "fs";
|
|
102425
103425
|
import { homedir as homedir9, platform as platform5 } from "os";
|
|
102426
103426
|
import { join as join31, resolve as resolve22 } from "path";
|
|
102427
103427
|
function getAllowedFontDirs() {
|
|
@@ -102516,7 +103516,7 @@ function collectFontFileEntries(dir, depth = 0) {
|
|
|
102516
103516
|
return [];
|
|
102517
103517
|
const entries2 = [];
|
|
102518
103518
|
try {
|
|
102519
|
-
for (const entry of
|
|
103519
|
+
for (const entry of readdirSync13(dir, { withFileTypes: true })) {
|
|
102520
103520
|
const fullPath = join31(dir, entry.name);
|
|
102521
103521
|
if (entry.isDirectory()) {
|
|
102522
103522
|
entries2.push(...collectFontFileEntries(fullPath, depth + 1));
|
|
@@ -105455,7 +106455,7 @@ import { Hono as Hono2 } from "hono";
|
|
|
105455
106455
|
import { readFile as readFile2 } from "fs/promises";
|
|
105456
106456
|
import { join as join210 } from "path";
|
|
105457
106457
|
import { join as join32 } from "path";
|
|
105458
|
-
import { readdirSync as
|
|
106458
|
+
import { readdirSync as readdirSync14 } from "fs";
|
|
105459
106459
|
import { createHash as createHash7 } from "crypto";
|
|
105460
106460
|
import { lstatSync as lstatSync4, readFileSync as readFileSync21, readdirSync as readdirSync22 } from "fs";
|
|
105461
106461
|
import { extname as extname9, isAbsolute as isAbsolute9, relative as relative10, resolve as resolve23 } from "path";
|
|
@@ -105473,7 +106473,7 @@ import {
|
|
|
105473
106473
|
unlinkSync as unlinkSync23,
|
|
105474
106474
|
rmSync as rmSync22,
|
|
105475
106475
|
statSync as statSync12,
|
|
105476
|
-
renameSync as
|
|
106476
|
+
renameSync as renameSync7,
|
|
105477
106477
|
readdirSync as readdirSync42
|
|
105478
106478
|
} from "fs";
|
|
105479
106479
|
import { resolve as resolve32, dirname as dirname22, join as join62 } from "path";
|
|
@@ -105484,10 +106484,10 @@ import { spawnSync } from "child_process";
|
|
|
105484
106484
|
import { mkdtempSync as mkdtempSync3, rmSync as rmSync9, writeFileSync as writeFileSync22 } from "fs";
|
|
105485
106485
|
import { tmpdir as tmpdir4 } from "os";
|
|
105486
106486
|
import { basename as basename5, join as join42 } from "path";
|
|
105487
|
-
import { mkdirSync as mkdirSync22, readdirSync as readdirSync32, readFileSync as readFileSync32, unlinkSync as
|
|
106487
|
+
import { mkdirSync as mkdirSync22, readdirSync as readdirSync32, readFileSync as readFileSync32, unlinkSync as unlinkSync5, writeFileSync as writeFileSync32 } from "fs";
|
|
105488
106488
|
import { Buffer as Buffer2 } from "buffer";
|
|
105489
106489
|
import { join as join52, relative as relative22 } from "path";
|
|
105490
|
-
import { createHash as createHash22, randomUUID as
|
|
106490
|
+
import { createHash as createHash22, randomUUID as randomUUID7 } from "crypto";
|
|
105491
106491
|
import { existsSync as existsSync37, readFileSync as readFileSync42, realpathSync as realpathSync6 } from "fs";
|
|
105492
106492
|
import { randomUUID as randomUUID22 } from "crypto";
|
|
105493
106493
|
import { dirname as dirname15, relative as relative32, resolve as resolve24, sep as sep7 } from "path";
|
|
@@ -105532,7 +106532,7 @@ function isInHiddenOrVendorDir(relPath) {
|
|
|
105532
106532
|
}
|
|
105533
106533
|
function walkDir(dir, prefix = "") {
|
|
105534
106534
|
const files = [];
|
|
105535
|
-
for (const entry of
|
|
106535
|
+
for (const entry of readdirSync14(dir, { withFileTypes: true })) {
|
|
105536
106536
|
const rel = prefix ? `${prefix}/${entry.name}` : entry.name;
|
|
105537
106537
|
if (IGNORE_DIRS.has(entry.name) || shouldIgnoreDir(rel)) continue;
|
|
105538
106538
|
if (entry.isDirectory()) {
|
|
@@ -105838,6 +106838,7 @@ function validateUploadedMedia(filePath, runner = spawnSync) {
|
|
|
105838
106838
|
"stream=codec_type",
|
|
105839
106839
|
"-of",
|
|
105840
106840
|
"json",
|
|
106841
|
+
"--",
|
|
105841
106842
|
filePath
|
|
105842
106843
|
]);
|
|
105843
106844
|
if (result.error?.code === "ENOENT") {
|
|
@@ -105929,7 +106930,7 @@ function pruneBackups(backupDir, backupKey, keepPerFile) {
|
|
|
105929
106930
|
});
|
|
105930
106931
|
for (const file of matches2.slice(keep)) {
|
|
105931
106932
|
try {
|
|
105932
|
-
|
|
106933
|
+
unlinkSync5(file);
|
|
105933
106934
|
} catch {
|
|
105934
106935
|
}
|
|
105935
106936
|
}
|
|
@@ -105939,7 +106940,7 @@ function fileContentVersion(content) {
|
|
|
105939
106940
|
}
|
|
105940
106941
|
function createWriteToken(requestToken) {
|
|
105941
106942
|
const token = requestToken?.trim();
|
|
105942
|
-
return token && token.length <= 200 ? token :
|
|
106943
|
+
return token && token.length <= 200 ? token : randomUUID7();
|
|
105943
106944
|
}
|
|
105944
106945
|
function recordFileWriteReceipt(absPath, receipt) {
|
|
105945
106946
|
const now = Date.now();
|
|
@@ -108048,7 +109049,7 @@ function registerFileRoutes(api, adapter2) {
|
|
|
108048
109049
|
return c3.json({ error: "already exists" }, 409);
|
|
108049
109050
|
}
|
|
108050
109051
|
ensureDir(newAbs);
|
|
108051
|
-
|
|
109052
|
+
renameSync7(res.absPath, newAbs);
|
|
108052
109053
|
const updatedFiles = updateReferences(res.project.dir, res.filePath, body.newPath);
|
|
108053
109054
|
return c3.json({ ok: true, path: body.newPath, updatedReferences: updatedFiles });
|
|
108054
109055
|
});
|
|
@@ -109650,9 +110651,9 @@ var init_dist9 = __esm({
|
|
|
109650
110651
|
init_chunk_X62ASOGO();
|
|
109651
110652
|
init_chunk_VPA335OG();
|
|
109652
110653
|
init_chunk_W2SBTCO2();
|
|
109653
|
-
|
|
109654
|
-
|
|
109655
|
-
|
|
110654
|
+
init_chunk_LHYV3WLZ();
|
|
110655
|
+
init_chunk_ZPI6QXJH();
|
|
110656
|
+
init_chunk_6H3V3WGJ();
|
|
109656
110657
|
init_chunk_6XMC64FJ();
|
|
109657
110658
|
init_chunk_4ETS2LXI();
|
|
109658
110659
|
init_dist3();
|
|
@@ -110193,7 +111194,7 @@ __export(manager_exports2, {
|
|
|
110193
111194
|
withInstallLock: () => withInstallLock
|
|
110194
111195
|
});
|
|
110195
111196
|
import { execSync as execSync4, spawnSync as spawnSync2 } from "child_process";
|
|
110196
|
-
import { existsSync as existsSync38, mkdirSync as mkdirSync17, readdirSync as
|
|
111197
|
+
import { existsSync as existsSync38, mkdirSync as mkdirSync17, readdirSync as readdirSync15, rmSync as rmSync10, statSync as statSync13, utimesSync as utimesSync3 } from "fs";
|
|
110197
111198
|
import { basename as basename6 } from "path";
|
|
110198
111199
|
import { homedir as homedir11 } from "os";
|
|
110199
111200
|
import { join as join35 } from "path";
|
|
@@ -110392,7 +111393,7 @@ function findFromPuppeteerCache() {
|
|
|
110392
111393
|
if (!executable) return void 0;
|
|
110393
111394
|
let versions;
|
|
110394
111395
|
try {
|
|
110395
|
-
versions = [...
|
|
111396
|
+
versions = [...readdirSync15(PUPPETEER_CACHE_DIR)].sort(compareVersionDirsDescending);
|
|
110396
111397
|
} catch {
|
|
110397
111398
|
return void 0;
|
|
110398
111399
|
}
|
|
@@ -111093,7 +112094,7 @@ var init_logger = __esm({
|
|
|
111093
112094
|
// ../producer/src/services/fileServer.ts
|
|
111094
112095
|
import { Hono as Hono3 } from "hono";
|
|
111095
112096
|
import { serve as serve2 } from "@hono/node-server";
|
|
111096
|
-
import { existsSync as existsSync40, realpathSync as realpathSync7, statSync as statSync14, createReadStream as
|
|
112097
|
+
import { existsSync as existsSync40, realpathSync as realpathSync7, statSync as statSync14, createReadStream as createReadStream3 } from "fs";
|
|
111097
112098
|
import { readFile as readFile3 } from "fs/promises";
|
|
111098
112099
|
import { Readable as Readable2 } from "stream";
|
|
111099
112100
|
import { join as join36, extname as extname10, resolve as resolve27, sep as sep9 } from "path";
|
|
@@ -111490,7 +112491,7 @@ function createFileServer2(options) {
|
|
|
111490
112491
|
if (rangeRequest.kind === "satisfiable") {
|
|
111491
112492
|
const { start, end } = rangeRequest;
|
|
111492
112493
|
const length = end - start + 1;
|
|
111493
|
-
const stream2 =
|
|
112494
|
+
const stream2 = createReadStream3(filePath, { start, end });
|
|
111494
112495
|
const webStream2 = Readable2.toWeb(stream2);
|
|
111495
112496
|
return new Response(webStream2, {
|
|
111496
112497
|
status: 206,
|
|
@@ -111502,7 +112503,7 @@ function createFileServer2(options) {
|
|
|
111502
112503
|
}
|
|
111503
112504
|
});
|
|
111504
112505
|
}
|
|
111505
|
-
const stream =
|
|
112506
|
+
const stream = createReadStream3(filePath);
|
|
111506
112507
|
const webStream = Readable2.toWeb(stream);
|
|
111507
112508
|
return new Response(webStream, {
|
|
111508
112509
|
status: 200,
|
|
@@ -112144,8 +113145,8 @@ import {
|
|
|
112144
113145
|
mkdtempSync as mkdtempSync4,
|
|
112145
113146
|
openSync as openSync5,
|
|
112146
113147
|
readSync as readSync2,
|
|
112147
|
-
readdirSync as
|
|
112148
|
-
renameSync as
|
|
113148
|
+
readdirSync as readdirSync16,
|
|
113149
|
+
renameSync as renameSync8,
|
|
112149
113150
|
rmSync as rmSync12
|
|
112150
113151
|
} from "fs";
|
|
112151
113152
|
import { basename as basename9, dirname as dirname18, extname as extname11, join as join39, resolve as resolve29 } from "path";
|
|
@@ -112170,7 +113171,7 @@ function assertReadableNonEmptyFile(path2) {
|
|
|
112170
113171
|
function collectDirectoryFiles(root) {
|
|
112171
113172
|
const files = [];
|
|
112172
113173
|
const visit = (directory) => {
|
|
112173
|
-
for (const entry of
|
|
113174
|
+
for (const entry of readdirSync16(directory, { withFileTypes: true })) {
|
|
112174
113175
|
const path2 = join39(directory, entry.name);
|
|
112175
113176
|
if (entry.isDirectory()) visit(path2);
|
|
112176
113177
|
else if (entry.isFile()) files.push(path2);
|
|
@@ -112185,7 +113186,7 @@ var init_artifactTransaction = __esm({
|
|
|
112185
113186
|
"use strict";
|
|
112186
113187
|
defaultFileSystem = {
|
|
112187
113188
|
existsSync: existsSync43,
|
|
112188
|
-
renameSync:
|
|
113189
|
+
renameSync: renameSync8,
|
|
112189
113190
|
rmSync: rmSync12
|
|
112190
113191
|
};
|
|
112191
113192
|
ArtifactTransaction = class {
|
|
@@ -113444,9 +114445,11 @@ var init_ffprobe2 = __esm({
|
|
|
113444
114445
|
// ../producer/src/utils/urlDownloader.ts
|
|
113445
114446
|
var urlDownloader_exports = {};
|
|
113446
114447
|
__export(urlDownloader_exports, {
|
|
113447
|
-
assertPublicHttpsUrl: () => assertPublicHttpsUrl,
|
|
113448
114448
|
downloadToTemp: () => downloadToTemp,
|
|
113449
|
-
|
|
114449
|
+
fetchPublicHttpsText: () => fetchPublicHttpsText,
|
|
114450
|
+
isHttpUrl: () => isHttpUrl,
|
|
114451
|
+
safeDownloadUrlIdentity: () => safeDownloadUrlIdentity,
|
|
114452
|
+
writeUrlDownloadTelemetry: () => writeUrlDownloadTelemetry
|
|
113450
114453
|
});
|
|
113451
114454
|
var init_urlDownloader2 = __esm({
|
|
113452
114455
|
"../producer/src/utils/urlDownloader.ts"() {
|
|
@@ -116632,7 +117635,7 @@ __export(fontCompression_exports, {
|
|
|
116632
117635
|
fontToDataUri: () => fontToDataUri
|
|
116633
117636
|
});
|
|
116634
117637
|
import { createHash as createHash10 } from "crypto";
|
|
116635
|
-
import { existsSync as existsSync44, mkdirSync as mkdirSync19, readFileSync as readFileSync26, renameSync as
|
|
117638
|
+
import { existsSync as existsSync44, mkdirSync as mkdirSync19, readFileSync as readFileSync26, renameSync as renameSync9, rmSync as rmSync13, writeFileSync as writeFileSync15 } from "fs";
|
|
116636
117639
|
import { homedir as homedir12, tmpdir as tmpdir5 } from "os";
|
|
116637
117640
|
import { dirname as dirname19, join as join41 } from "path";
|
|
116638
117641
|
async function compressToWoff2(input2) {
|
|
@@ -116663,7 +117666,7 @@ function cacheCompression(path2, compressed) {
|
|
|
116663
117666
|
try {
|
|
116664
117667
|
mkdirSync19(dirname19(path2), { recursive: true });
|
|
116665
117668
|
writeFileSync15(tmpPath, compressed, { flag: "wx", mode: 420 });
|
|
116666
|
-
|
|
117669
|
+
renameSync9(tmpPath, path2);
|
|
116667
117670
|
} catch {
|
|
116668
117671
|
} finally {
|
|
116669
117672
|
try {
|
|
@@ -117488,7 +118491,7 @@ import {
|
|
|
117488
118491
|
existsSync as existsSync46,
|
|
117489
118492
|
mkdirSync as mkdirSync21,
|
|
117490
118493
|
readFileSync as readFileSync28,
|
|
117491
|
-
renameSync as
|
|
118494
|
+
renameSync as renameSync10,
|
|
117492
118495
|
rmSync as rmSync14,
|
|
117493
118496
|
statSync as statSync15
|
|
117494
118497
|
} from "fs";
|
|
@@ -117661,7 +118664,7 @@ async function ensurePreparedWebm(input2) {
|
|
|
117661
118664
|
throw new Error("Animated GIF transcode produced an empty output");
|
|
117662
118665
|
}
|
|
117663
118666
|
if (!isUsableFile(input2.cachePath)) {
|
|
117664
|
-
|
|
118667
|
+
renameSync10(tmpPath, input2.cachePath);
|
|
117665
118668
|
} else {
|
|
117666
118669
|
rmSync14(tmpPath, { force: true });
|
|
117667
118670
|
}
|
|
@@ -117980,8 +118983,11 @@ var init_assetMediaType = __esm({
|
|
|
117980
118983
|
});
|
|
117981
118984
|
|
|
117982
118985
|
// ../producer/src/services/htmlCompiler.ts
|
|
117983
|
-
import { createReadStream as
|
|
118986
|
+
import { createReadStream as createReadStream4, existsSync as existsSync48, mkdirSync as mkdirSync23, readFileSync as readFileSync29 } from "fs";
|
|
117984
118987
|
import { join as join45, dirname as dirname21, resolve as resolve31, basename as basename10 } from "path";
|
|
118988
|
+
function logRemoteDownloadTelemetry(event) {
|
|
118989
|
+
defaultLogger.info("[Compiler] Remote asset download integrity", { ...event });
|
|
118990
|
+
}
|
|
117985
118991
|
function parseSubCompHtmlForValidity(html) {
|
|
117986
118992
|
return parseHTML(html).document;
|
|
117987
118993
|
}
|
|
@@ -118141,7 +119147,9 @@ async function resolveMediaDuration(src, mediaStart, baseDir, downloadDir, tagNa
|
|
|
118141
119147
|
if (isHttpUrl(src)) {
|
|
118142
119148
|
if (!existsSync48(downloadDir)) mkdirSync23(downloadDir, { recursive: true });
|
|
118143
119149
|
try {
|
|
118144
|
-
filePath = await downloadToTemp(src, downloadDir
|
|
119150
|
+
filePath = await downloadToTemp(src, downloadDir, void 0, void 0, void 0, {
|
|
119151
|
+
onTelemetry: logRemoteDownloadTelemetry
|
|
119152
|
+
});
|
|
118145
119153
|
} catch {
|
|
118146
119154
|
return { duration: 0, resolvedPath: src };
|
|
118147
119155
|
}
|
|
@@ -118669,12 +119677,17 @@ async function downloadAndRewriteUrls(urlSet, html, remoteDir, warnLabel, logLab
|
|
|
118669
119677
|
await Promise.all(
|
|
118670
119678
|
[...urlSet].map(async (url) => {
|
|
118671
119679
|
try {
|
|
118672
|
-
const localPath = await downloadToTemp(url, remoteDir
|
|
119680
|
+
const localPath = await downloadToTemp(url, remoteDir, void 0, void 0, void 0, {
|
|
119681
|
+
onTelemetry: logRemoteDownloadTelemetry
|
|
119682
|
+
});
|
|
118673
119683
|
urlToLocal.set(url, localPath);
|
|
118674
119684
|
} catch (err) {
|
|
118675
|
-
|
|
118676
|
-
|
|
118677
|
-
|
|
119685
|
+
const identity = safeDownloadUrlIdentity(url);
|
|
119686
|
+
defaultLogger.warn(`[Compiler] ${warnLabel} \u2014 using original URL as fallback.`, {
|
|
119687
|
+
urlFingerprint: identity.urlFingerprint,
|
|
119688
|
+
host: identity.host,
|
|
119689
|
+
error: err instanceof Error ? err.message : String(err)
|
|
119690
|
+
});
|
|
118678
119691
|
}
|
|
118679
119692
|
})
|
|
118680
119693
|
);
|
|
@@ -118705,7 +119718,7 @@ async function localizeRemoteMediaSources(html, downloadDir) {
|
|
|
118705
119718
|
urlSet,
|
|
118706
119719
|
html,
|
|
118707
119720
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118708
|
-
"Remote media download failed
|
|
119721
|
+
"Remote media download failed",
|
|
118709
119722
|
"Localized remote media source(s)"
|
|
118710
119723
|
);
|
|
118711
119724
|
}
|
|
@@ -118720,7 +119733,7 @@ async function localizeRemoteImageSources(html, downloadDir) {
|
|
|
118720
119733
|
urlSet,
|
|
118721
119734
|
html,
|
|
118722
119735
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118723
|
-
"Remote image download failed
|
|
119736
|
+
"Remote image download failed",
|
|
118724
119737
|
"Localized remote image source(s)"
|
|
118725
119738
|
);
|
|
118726
119739
|
}
|
|
@@ -118735,7 +119748,7 @@ async function localizeRemoteBackgroundImages(html, downloadDir) {
|
|
|
118735
119748
|
urlSet,
|
|
118736
119749
|
html,
|
|
118737
119750
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118738
|
-
"Remote background-image download failed
|
|
119751
|
+
"Remote background-image download failed",
|
|
118739
119752
|
"Localized remote background-image(s)",
|
|
118740
119753
|
// Quoted url('..')/url("..") are rewritten by downloadAndRewriteUrls' default
|
|
118741
119754
|
// replaceAll; this handles the unquoted url(https://..) form.
|
|
@@ -118751,40 +119764,18 @@ function isGoogleFontsUrl(href) {
|
|
|
118751
119764
|
}
|
|
118752
119765
|
}
|
|
118753
119766
|
async function fetchExternalStylesheetCss(href) {
|
|
119767
|
+
const identity = safeDownloadUrlIdentity(href);
|
|
118754
119768
|
try {
|
|
118755
|
-
|
|
118756
|
-
|
|
118757
|
-
|
|
118758
|
-
}
|
|
118759
|
-
try {
|
|
118760
|
-
const response = await fetch(href, {
|
|
118761
|
-
signal: AbortSignal.timeout(15e3)
|
|
119769
|
+
return await fetchPublicHttpsText(href, {
|
|
119770
|
+
maxBytes: MAX_STYLESHEET_BYTES,
|
|
119771
|
+
timeoutMs: 15e3
|
|
118762
119772
|
});
|
|
118763
|
-
if (!response.ok) {
|
|
118764
|
-
defaultLogger.warn(
|
|
118765
|
-
`[Compiler] External stylesheet fetch failed for ${href} \u2014 HTTP ${response.status}`
|
|
118766
|
-
);
|
|
118767
|
-
return null;
|
|
118768
|
-
}
|
|
118769
|
-
const contentLength = response.headers.get("content-length");
|
|
118770
|
-
if (contentLength && parseInt(contentLength, 10) > MAX_STYLESHEET_BYTES) {
|
|
118771
|
-
defaultLogger.warn(
|
|
118772
|
-
`[Compiler] External stylesheet too large (${contentLength} bytes): ${href}`
|
|
118773
|
-
);
|
|
118774
|
-
return null;
|
|
118775
|
-
}
|
|
118776
|
-
const text2 = await response.text();
|
|
118777
|
-
if (text2.length > MAX_STYLESHEET_BYTES) {
|
|
118778
|
-
defaultLogger.warn(
|
|
118779
|
-
`[Compiler] External stylesheet too large (${text2.length} bytes): ${href}`
|
|
118780
|
-
);
|
|
118781
|
-
return null;
|
|
118782
|
-
}
|
|
118783
|
-
return text2;
|
|
118784
119773
|
} catch (err) {
|
|
118785
|
-
defaultLogger.warn(
|
|
118786
|
-
|
|
118787
|
-
|
|
119774
|
+
defaultLogger.warn("[Compiler] External stylesheet fetch failed \u2014 preserving link tag.", {
|
|
119775
|
+
urlFingerprint: identity.urlFingerprint,
|
|
119776
|
+
host: identity.host,
|
|
119777
|
+
error: err instanceof Error ? err.message : String(err)
|
|
119778
|
+
});
|
|
118788
119779
|
return null;
|
|
118789
119780
|
}
|
|
118790
119781
|
}
|
|
@@ -118840,13 +119831,16 @@ async function inlineExternalFontStylesheets(html) {
|
|
|
118840
119831
|
if (css === null) continue;
|
|
118841
119832
|
const fontFaceBlocks = extractFontFaceBlocks(css);
|
|
118842
119833
|
if (fontFaceBlocks.length === 0) continue;
|
|
118843
|
-
const
|
|
119834
|
+
const identity = safeDownloadUrlIdentity(href);
|
|
119835
|
+
const inlineStyle = `<style>/* Inlined external font stylesheet */
|
|
118844
119836
|
${fontFaceBlocks.join("\n")}
|
|
118845
119837
|
</style>`;
|
|
118846
119838
|
result = result.replace(fullMatch, inlineStyle);
|
|
118847
|
-
defaultLogger.info(
|
|
118848
|
-
|
|
118849
|
-
|
|
119839
|
+
defaultLogger.info("[Compiler] Inlined external @font-face rule(s)", {
|
|
119840
|
+
count: fontFaceBlocks.length,
|
|
119841
|
+
urlFingerprint: identity.urlFingerprint,
|
|
119842
|
+
host: identity.host
|
|
119843
|
+
});
|
|
118850
119844
|
}
|
|
118851
119845
|
return result;
|
|
118852
119846
|
}
|
|
@@ -118887,7 +119881,7 @@ async function localizeRemoteFontFaces(html, downloadDir) {
|
|
|
118887
119881
|
urlSet,
|
|
118888
119882
|
processed,
|
|
118889
119883
|
join45(downloadDir, REMOTE_MEDIA_SUBDIR),
|
|
118890
|
-
"Remote font download failed
|
|
119884
|
+
"Remote font download failed",
|
|
118891
119885
|
"Localized remote font face(s)",
|
|
118892
119886
|
(h3, url, relPath) => h3.replaceAll(`url(${url})`, `url("${relPath}")`)
|
|
118893
119887
|
);
|
|
@@ -118895,7 +119889,7 @@ async function localizeRemoteFontFaces(html, downloadDir) {
|
|
|
118895
119889
|
async function readLocalFont(absPath) {
|
|
118896
119890
|
const chunks = [];
|
|
118897
119891
|
let totalBytes = 0;
|
|
118898
|
-
for await (const chunk of
|
|
119892
|
+
for await (const chunk of createReadStream4(absPath)) {
|
|
118899
119893
|
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
118900
119894
|
totalBytes += buffer.length;
|
|
118901
119895
|
if (totalBytes > MAX_LOCAL_FONT_DATA_URI_BYTES) {
|
|
@@ -119799,9 +120793,9 @@ async function runProbeStage(input2) {
|
|
|
119799
120793
|
if (probeSession.launchCaptureMode === "beginframe") {
|
|
119800
120794
|
const probeTimeoutMs = Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) > 0 ? Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) : 3e4;
|
|
119801
120795
|
const livenessStart = Date.now();
|
|
119802
|
-
const probeTick =
|
|
119803
|
-
|
|
119804
|
-
probeSession.
|
|
120796
|
+
const probeTick = deriveBeginFrameProbeTimeTicks(
|
|
120797
|
+
probeSession.beginFrameTimeTicks,
|
|
120798
|
+
probeSession.beginFrameIntervalMs
|
|
119805
120799
|
);
|
|
119806
120800
|
const alive = await probeBeginFrameLiveness(
|
|
119807
120801
|
probeSession.page,
|
|
@@ -123319,7 +124313,7 @@ var init_gifEncodeArgs = __esm({
|
|
|
123319
124313
|
});
|
|
123320
124314
|
|
|
123321
124315
|
// ../producer/src/services/render/stages/encodeStage.ts
|
|
123322
|
-
import { copyFileSync as copyFileSync5, existsSync as existsSync53, mkdirSync as mkdirSync26, readdirSync as
|
|
124316
|
+
import { copyFileSync as copyFileSync5, existsSync as existsSync53, mkdirSync as mkdirSync26, readdirSync as readdirSync17, rmSync as rmSync16, statSync as statSync16 } from "fs";
|
|
123323
124317
|
import { dirname as dirname24, join as join59 } from "path";
|
|
123324
124318
|
function resolveGifLoop(loop) {
|
|
123325
124319
|
const resolved2 = loop ?? 0;
|
|
@@ -123330,7 +124324,7 @@ function resolveGifLoop(loop) {
|
|
|
123330
124324
|
}
|
|
123331
124325
|
async function encodeGifFromDir(framesDir, framePattern, outputPath, input2) {
|
|
123332
124326
|
const startTime = Date.now();
|
|
123333
|
-
const files =
|
|
124327
|
+
const files = readdirSync17(framesDir).filter((file) => file.match(/\.(jpg|jpeg|png)$/i));
|
|
123334
124328
|
const frameCount = files.length;
|
|
123335
124329
|
if (frameCount === 0) {
|
|
123336
124330
|
return {
|
|
@@ -123419,7 +124413,7 @@ async function runEncodeStage(input2) {
|
|
|
123419
124413
|
if (isPngSequence) {
|
|
123420
124414
|
updateJobStatus(job, "encoding", "Writing PNG sequence", 75, onProgress);
|
|
123421
124415
|
if (!existsSync53(outputPath)) mkdirSync26(outputPath, { recursive: true });
|
|
123422
|
-
const captured =
|
|
124416
|
+
const captured = readdirSync17(framesDir).filter((name) => name.endsWith(".png")).sort();
|
|
123423
124417
|
if (captured.length === 0) {
|
|
123424
124418
|
throw new Error(
|
|
123425
124419
|
`[Render] png-sequence output requested but no PNGs were captured to ${framesDir}`
|
|
@@ -123582,6 +124576,10 @@ function buildPadTrimAudioPlan(audioPath, outputPath, sourceDurationSeconds, tar
|
|
|
123582
124576
|
function formatSeconds(sec) {
|
|
123583
124577
|
return sec.toFixed(6);
|
|
123584
124578
|
}
|
|
124579
|
+
function sanitizeProbeFailure(reason, paths) {
|
|
124580
|
+
const message = reason instanceof Error ? reason.message : String(reason);
|
|
124581
|
+
return redactTelemetryString(redactKnownPaths(message, paths));
|
|
124582
|
+
}
|
|
123585
124583
|
async function padOrTrimAudioToVideoFrameCount(input2) {
|
|
123586
124584
|
const probeVideo2 = input2.probeVideoFrameInfo ?? ((videoPath) => defaultProbeVideoFrameInfo(videoPath, input2.signal));
|
|
123587
124585
|
const probeAudio = input2.probeAudioInfo ?? defaultProbeAudioInfo;
|
|
@@ -123590,12 +124588,16 @@ async function padOrTrimAudioToVideoFrameCount(input2) {
|
|
|
123590
124588
|
probeVideo2(input2.videoPath),
|
|
123591
124589
|
probeAudio(input2.audioPath, input2.signal)
|
|
123592
124590
|
]);
|
|
124591
|
+
const probePaths = [input2.videoPath, input2.audioPath, input2.outputPath];
|
|
123593
124592
|
if (videoResult.status === "rejected") {
|
|
123594
124593
|
return failResult(
|
|
123595
124594
|
input2.outputPath,
|
|
123596
124595
|
0,
|
|
123597
124596
|
audioResult.status === "fulfilled" ? audioResult.value.durationSeconds : 0,
|
|
123598
|
-
`audioPadTrim: failed to probe video: ${
|
|
124597
|
+
`audioPadTrim: failed to probe video: ${sanitizeProbeFailure(
|
|
124598
|
+
videoResult.reason,
|
|
124599
|
+
probePaths
|
|
124600
|
+
)}`
|
|
123599
124601
|
);
|
|
123600
124602
|
}
|
|
123601
124603
|
if (audioResult.status === "rejected") {
|
|
@@ -123603,7 +124605,10 @@ async function padOrTrimAudioToVideoFrameCount(input2) {
|
|
|
123603
124605
|
input2.outputPath,
|
|
123604
124606
|
0,
|
|
123605
124607
|
0,
|
|
123606
|
-
`audioPadTrim: failed to probe audio: ${
|
|
124608
|
+
`audioPadTrim: failed to probe audio: ${sanitizeProbeFailure(
|
|
124609
|
+
audioResult.reason,
|
|
124610
|
+
probePaths
|
|
124611
|
+
)}`
|
|
123607
124612
|
);
|
|
123608
124613
|
}
|
|
123609
124614
|
const videoInfo = videoResult.value;
|
|
@@ -123678,6 +124683,7 @@ async function defaultProbeVideoFrameInfo(videoPath, signal) {
|
|
|
123678
124683
|
"stream=nb_frames,r_frame_rate",
|
|
123679
124684
|
"-of",
|
|
123680
124685
|
"json",
|
|
124686
|
+
"--",
|
|
123681
124687
|
videoPath
|
|
123682
124688
|
],
|
|
123683
124689
|
signal
|
|
@@ -123698,6 +124704,7 @@ async function defaultProbeVideoFrameInfo(videoPath, signal) {
|
|
|
123698
124704
|
"stream=nb_read_packets,r_frame_rate",
|
|
123699
124705
|
"-of",
|
|
123700
124706
|
"json",
|
|
124707
|
+
"--",
|
|
123701
124708
|
videoPath
|
|
123702
124709
|
],
|
|
123703
124710
|
signal
|
|
@@ -123737,7 +124744,10 @@ async function defaultRunFfmpeg(args, signal) {
|
|
|
123737
124744
|
};
|
|
123738
124745
|
}
|
|
123739
124746
|
async function runFfprobeJson(args, signal) {
|
|
123740
|
-
|
|
124747
|
+
if (!args.includes("--")) {
|
|
124748
|
+
throw new Error('[audioPadTrim] ffprobe args must terminate options with "--".');
|
|
124749
|
+
}
|
|
124750
|
+
const proc = spawn11(getFfprobeBinary(), args, { stdio: ["ignore", "pipe", "pipe"] });
|
|
123741
124751
|
trackChildProcess(proc);
|
|
123742
124752
|
let stdout2 = "";
|
|
123743
124753
|
proc.stdout.on("data", (data2) => {
|
|
@@ -123755,7 +124765,9 @@ async function runFfprobeJson(args, signal) {
|
|
|
123755
124765
|
throw outcome.error ?? new Error(outcome.stderr);
|
|
123756
124766
|
}
|
|
123757
124767
|
if (outcome.reason !== "exit" || outcome.exitCode !== 0) {
|
|
123758
|
-
|
|
124768
|
+
const probed = args[args.length - 1];
|
|
124769
|
+
const scrubbed = redactKnownPaths(outcome.stderr, probed === void 0 ? [] : [probed]);
|
|
124770
|
+
throw new Error(`ffprobe ${outcome.reason}: ${redactTelemetryString(scrubbed, 2e3)}`);
|
|
123759
124771
|
}
|
|
123760
124772
|
try {
|
|
123761
124773
|
return JSON.parse(stdout2);
|
|
@@ -123768,6 +124780,7 @@ var init_audioPadTrim = __esm({
|
|
|
123768
124780
|
"../producer/src/services/render/audioPadTrim.ts"() {
|
|
123769
124781
|
"use strict";
|
|
123770
124782
|
init_src();
|
|
124783
|
+
init_dist3();
|
|
123771
124784
|
AUDIO_DURATION_TOLERANCE_SECONDS = 1e-3;
|
|
123772
124785
|
}
|
|
123773
124786
|
});
|
|
@@ -123845,7 +124858,7 @@ import {
|
|
|
123845
124858
|
mkdirSync as mkdirSync27,
|
|
123846
124859
|
mkdtempSync as mkdtempSync7,
|
|
123847
124860
|
readFileSync as readFileSync31,
|
|
123848
|
-
readdirSync as
|
|
124861
|
+
readdirSync as readdirSync18,
|
|
123849
124862
|
rmSync as rmSync18,
|
|
123850
124863
|
statSync as statSync17,
|
|
123851
124864
|
writeFileSync as writeFileSync17,
|
|
@@ -123855,7 +124868,7 @@ import {
|
|
|
123855
124868
|
import { tmpdir as tmpdir8 } from "os";
|
|
123856
124869
|
import { join as join60, dirname as dirname25, resolve as resolve33 } from "path";
|
|
123857
124870
|
import { totalmem as totalmem2 } from "os";
|
|
123858
|
-
import { randomUUID as
|
|
124871
|
+
import { randomUUID as randomUUID8 } from "crypto";
|
|
123859
124872
|
import { fileURLToPath as fileURLToPath5 } from "url";
|
|
123860
124873
|
function sampleDirectoryBytes(dir) {
|
|
123861
124874
|
let total = 0;
|
|
@@ -123865,7 +124878,7 @@ function sampleDirectoryBytes(dir) {
|
|
|
123865
124878
|
if (!current2) continue;
|
|
123866
124879
|
let entries2 = [];
|
|
123867
124880
|
try {
|
|
123868
|
-
entries2 =
|
|
124881
|
+
entries2 = readdirSync18(current2);
|
|
123869
124882
|
} catch {
|
|
123870
124883
|
continue;
|
|
123871
124884
|
}
|
|
@@ -124214,7 +125227,7 @@ async function executeDiskCaptureWithAdaptiveRetry(options) {
|
|
|
124214
125227
|
}
|
|
124215
125228
|
function createRenderJob(config) {
|
|
124216
125229
|
return {
|
|
124217
|
-
id:
|
|
125230
|
+
id: randomUUID8(),
|
|
124218
125231
|
config: {
|
|
124219
125232
|
...config,
|
|
124220
125233
|
fps: toFps(config.fps),
|
|
@@ -126607,7 +127620,7 @@ import {
|
|
|
126607
127620
|
mkdtempSync as mkdtempSync8,
|
|
126608
127621
|
writeFileSync as writeFileSync18,
|
|
126609
127622
|
rmSync as rmSync19,
|
|
126610
|
-
createReadStream as
|
|
127623
|
+
createReadStream as createReadStream5
|
|
126611
127624
|
} from "fs";
|
|
126612
127625
|
import { resolve as resolve35, dirname as dirname27, join as join64 } from "path";
|
|
126613
127626
|
import { tmpdir as tmpdir9 } from "os";
|
|
@@ -127166,7 +128179,7 @@ function createRenderHandlers(options = {}) {
|
|
|
127166
128179
|
return c3.json({ success: false, error: "Output artifact file missing" }, 404);
|
|
127167
128180
|
}
|
|
127168
128181
|
const stats = statSync19(artifact.path);
|
|
127169
|
-
return new Response(
|
|
128182
|
+
return new Response(createReadStream5(artifact.path), {
|
|
127170
128183
|
headers: {
|
|
127171
128184
|
"content-type": "video/mp4",
|
|
127172
128185
|
"content-length": String(stats.size),
|
|
@@ -127437,7 +128450,7 @@ var init_planHash = __esm({
|
|
|
127437
128450
|
});
|
|
127438
128451
|
|
|
127439
128452
|
// ../producer/src/services/render/stages/freezePlan.ts
|
|
127440
|
-
import { existsSync as existsSync58, mkdirSync as mkdirSync29, readFileSync as readFileSync34, readdirSync as
|
|
128453
|
+
import { existsSync as existsSync58, mkdirSync as mkdirSync29, readFileSync as readFileSync34, readdirSync as readdirSync19, writeFileSync as writeFileSync19 } from "fs";
|
|
127441
128454
|
import { join as join65, relative as relative12, resolve as resolve36 } from "path";
|
|
127442
128455
|
function stripUndefined(value) {
|
|
127443
128456
|
if (Array.isArray(value)) return value.map(stripUndefined);
|
|
@@ -127457,7 +128470,7 @@ function listPlanFiles(planDir) {
|
|
|
127457
128470
|
const results = [];
|
|
127458
128471
|
const rootResolved = resolve36(planDir);
|
|
127459
128472
|
function walk(dir) {
|
|
127460
|
-
const entries2 =
|
|
128473
|
+
const entries2 = readdirSync19(dir, { withFileTypes: true });
|
|
127461
128474
|
for (const entry of entries2) {
|
|
127462
128475
|
const full2 = join65(dir, entry.name);
|
|
127463
128476
|
if (entry.isDirectory()) {
|
|
@@ -127868,7 +128881,7 @@ var init_shared2 = __esm({
|
|
|
127868
128881
|
|
|
127869
128882
|
// ../producer/src/services/distributed/planSize.ts
|
|
127870
128883
|
import { createHash as createHash15 } from "crypto";
|
|
127871
|
-
import { lstatSync as lstatSync5, readdirSync as
|
|
128884
|
+
import { lstatSync as lstatSync5, readdirSync as readdirSync20 } from "fs";
|
|
127872
128885
|
import { extname as extname13, join as join67, relative as relative13 } from "path";
|
|
127873
128886
|
function hashComponent(value) {
|
|
127874
128887
|
return createHash15("sha256").update(value).digest("hex").slice(0, 12);
|
|
@@ -127950,7 +128963,7 @@ function recordFile(result, components, rootDir, rootKind, filePath) {
|
|
|
127950
128963
|
function walkRegularFiles(dir, visit) {
|
|
127951
128964
|
let entries2;
|
|
127952
128965
|
try {
|
|
127953
|
-
entries2 =
|
|
128966
|
+
entries2 = readdirSync20(dir, { withFileTypes: true });
|
|
127954
128967
|
} catch {
|
|
127955
128968
|
return;
|
|
127956
128969
|
}
|
|
@@ -128007,7 +129020,7 @@ var init_planSize = __esm({
|
|
|
128007
129020
|
});
|
|
128008
129021
|
|
|
128009
129022
|
// ../producer/src/services/distributed/plan.ts
|
|
128010
|
-
import { cpSync as cpSync3, existsSync as existsSync60, mkdirSync as mkdirSync30, renameSync as
|
|
129023
|
+
import { cpSync as cpSync3, existsSync as existsSync60, mkdirSync as mkdirSync30, renameSync as renameSync11, rmSync as rmSync20, writeFileSync as writeFileSync20 } from "fs";
|
|
128011
129024
|
import { join as join68, relative as relative14, sep as sep10 } from "path";
|
|
128012
129025
|
function applyDistributedAudioWarningPolicy(job, audioError, audioFailures = [], log2 = defaultLogger) {
|
|
128013
129026
|
const failureOwner = audioFailures.length === 0 ? void 0 : audioFailures.some((failure) => failure.owner === "system") ? "system" : "user";
|
|
@@ -128357,12 +129370,12 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
128357
129370
|
const videoFramesDst = join68(planDir, "video-frames");
|
|
128358
129371
|
if (existsSync60(videoFramesDst)) rmSync20(videoFramesDst, { recursive: true, force: true });
|
|
128359
129372
|
if (existsSync60(stagedVideoFrames)) {
|
|
128360
|
-
|
|
129373
|
+
renameSync11(stagedVideoFrames, videoFramesDst);
|
|
128361
129374
|
} else {
|
|
128362
129375
|
mkdirSync30(videoFramesDst, { recursive: true });
|
|
128363
129376
|
}
|
|
128364
129377
|
if (existsSync60(finalCompiledDir)) rmSync20(finalCompiledDir, { recursive: true, force: true });
|
|
128365
|
-
|
|
129378
|
+
renameSync11(compiledDir, finalCompiledDir);
|
|
128366
129379
|
const planVideosJson = buildPlanVideosJson({
|
|
128367
129380
|
videos: composition.videos,
|
|
128368
129381
|
compositionEnd: job.duration ?? Number.NaN,
|
|
@@ -128383,7 +129396,7 @@ async function buildLocalExecutionPlan(projectDir, config, executionPlanDir, opt
|
|
|
128383
129396
|
);
|
|
128384
129397
|
const planAudioPath = join68(planDir, PLAN_AUDIO_RELATIVE_PATH);
|
|
128385
129398
|
if (audioResult.hasAudio && existsSync60(audioResult.audioOutputPath)) {
|
|
128386
|
-
|
|
129399
|
+
renameSync11(audioResult.audioOutputPath, planAudioPath);
|
|
128387
129400
|
}
|
|
128388
129401
|
const maxParallel = config.maxParallelChunks ?? DEFAULT_MAX_PARALLEL_CHUNKS;
|
|
128389
129402
|
const { chunkCount, effectiveChunkSize } = resolveChunkPlan(
|
|
@@ -128609,10 +129622,10 @@ var init_planV2Layout = __esm({
|
|
|
128609
129622
|
import {
|
|
128610
129623
|
copyFileSync as copyFileSync7,
|
|
128611
129624
|
existsSync as existsSync61,
|
|
128612
|
-
linkSync as
|
|
129625
|
+
linkSync as linkSync3,
|
|
128613
129626
|
mkdirSync as mkdirSync31,
|
|
128614
129627
|
mkdtempSync as mkdtempSync9,
|
|
128615
|
-
renameSync as
|
|
129628
|
+
renameSync as renameSync12,
|
|
128616
129629
|
rmSync as rmSync21,
|
|
128617
129630
|
statSync as statSync20,
|
|
128618
129631
|
writeFileSync as writeFileSync21
|
|
@@ -128659,7 +129672,7 @@ var init_planV2Publisher = __esm({
|
|
|
128659
129672
|
throw new PlanV2IntegrityError(`output directory already exists: ${destinationDir}`);
|
|
128660
129673
|
}
|
|
128661
129674
|
this.destinationDir = destinationDir;
|
|
128662
|
-
this.#linkFile = options.linkFile ??
|
|
129675
|
+
this.#linkFile = options.linkFile ?? linkSync3;
|
|
128663
129676
|
mkdirSync31(dirname29(destinationDir), { recursive: true });
|
|
128664
129677
|
this.temporaryDir = mkdtempSync9(join70(dirname29(destinationDir), ".plan-v2-publish-"));
|
|
128665
129678
|
}
|
|
@@ -128683,7 +129696,7 @@ var init_planV2Publisher = __esm({
|
|
|
128683
129696
|
if (!canFallbackToCopy(error)) throw error;
|
|
128684
129697
|
copyFileSync7(blob.sourcePath, temporaryPath);
|
|
128685
129698
|
}
|
|
128686
|
-
|
|
129699
|
+
renameSync12(temporaryPath, destinationPath);
|
|
128687
129700
|
} finally {
|
|
128688
129701
|
rmSync21(stagingDir, { recursive: true, force: true });
|
|
128689
129702
|
}
|
|
@@ -128697,7 +129710,7 @@ var init_planV2Publisher = __esm({
|
|
|
128697
129710
|
}
|
|
128698
129711
|
}
|
|
128699
129712
|
writeFileSync21(join70(this.temporaryDir, "plan.json"), manifestBytes, "utf-8");
|
|
128700
|
-
|
|
129713
|
+
renameSync12(this.temporaryDir, this.destinationDir);
|
|
128701
129714
|
this.#committed = true;
|
|
128702
129715
|
}
|
|
128703
129716
|
async abort() {
|
|
@@ -128720,8 +129733,8 @@ import {
|
|
|
128720
129733
|
openSync as openSync7,
|
|
128721
129734
|
readFileSync as readFileSync36,
|
|
128722
129735
|
readSync as readSync4,
|
|
128723
|
-
readdirSync as
|
|
128724
|
-
renameSync as
|
|
129736
|
+
readdirSync as readdirSync21,
|
|
129737
|
+
renameSync as renameSync13,
|
|
128725
129738
|
rmSync as rmSync23,
|
|
128726
129739
|
statSync as statSync21,
|
|
128727
129740
|
writeFileSync as writeFileSync23
|
|
@@ -128758,7 +129771,7 @@ function listFiles(root) {
|
|
|
128758
129771
|
const files = [];
|
|
128759
129772
|
const rootResolved = resolve37(root);
|
|
128760
129773
|
function walk(dir) {
|
|
128761
|
-
for (const entry of
|
|
129774
|
+
for (const entry of readdirSync21(dir, { withFileTypes: true })) {
|
|
128762
129775
|
const absolutePath = join71(dir, entry.name);
|
|
128763
129776
|
if (entry.isDirectory()) {
|
|
128764
129777
|
walk(absolutePath);
|
|
@@ -128803,10 +129816,10 @@ function assertValidExtractionCacheCompleteSentinel(path2) {
|
|
|
128803
129816
|
function validateExtractionCacheCompleteSentinels(executionPlanDir) {
|
|
128804
129817
|
const videoRoot = join71(executionPlanDir, "video-frames");
|
|
128805
129818
|
if (!existsSync63(videoRoot)) return;
|
|
128806
|
-
for (const videoEntry of
|
|
129819
|
+
for (const videoEntry of readdirSync21(videoRoot, { withFileTypes: true })) {
|
|
128807
129820
|
if (!videoEntry.isDirectory()) continue;
|
|
128808
129821
|
const videoDir = join71(videoRoot, videoEntry.name);
|
|
128809
|
-
if (
|
|
129822
|
+
if (readdirSync21(videoDir).includes(EXTRACTION_CACHE_COMPLETE_SENTINEL)) {
|
|
128810
129823
|
const sentinelPath = join71(videoDir, EXTRACTION_CACHE_COMPLETE_SENTINEL);
|
|
128811
129824
|
assertValidExtractionCacheCompleteSentinel(sentinelPath);
|
|
128812
129825
|
}
|
|
@@ -128843,7 +129856,7 @@ function artifactTargets(path2, videoDependencies) {
|
|
|
128843
129856
|
function listVideoFramePaths(executionPlanDir, videos) {
|
|
128844
129857
|
return videos.extracted.map((video) => {
|
|
128845
129858
|
const outputDir = resolveExtractedVideoOutputDir(executionPlanDir, video.videoId);
|
|
128846
|
-
const frameNames =
|
|
129859
|
+
const frameNames = readdirSync21(outputDir).sort();
|
|
128847
129860
|
const framePaths = /* @__PURE__ */ new Map();
|
|
128848
129861
|
for (const frameName of frameNames) {
|
|
128849
129862
|
if (frameName === EXTRACTION_CACHE_COMPLETE_SENTINEL) {
|
|
@@ -128964,7 +129977,7 @@ function writeBlob(sourcePath, destinationPath) {
|
|
|
128964
129977
|
const temporaryPath = join71(temporaryDir, "blob");
|
|
128965
129978
|
try {
|
|
128966
129979
|
copyFileSync8(sourcePath, temporaryPath);
|
|
128967
|
-
|
|
129980
|
+
renameSync13(temporaryPath, destinationPath);
|
|
128968
129981
|
} finally {
|
|
128969
129982
|
rmSync23(temporaryDir, { recursive: true, force: true });
|
|
128970
129983
|
}
|
|
@@ -129056,7 +130069,7 @@ function createPlanV2FromExecutionPlan(executionPlanDir, planV2Dir) {
|
|
|
129056
130069
|
canonicalJsonStringify(publication.manifest),
|
|
129057
130070
|
"utf-8"
|
|
129058
130071
|
);
|
|
129059
|
-
|
|
130072
|
+
renameSync13(tempDir, planV2Dir);
|
|
129060
130073
|
return resultFromManifest(planV2Dir, publication.manifest);
|
|
129061
130074
|
} catch (error) {
|
|
129062
130075
|
rmSync23(tempDir, { recursive: true, force: true });
|
|
@@ -129310,7 +130323,7 @@ function materializePlanV2Target(planV2Dir, target, destinationDir) {
|
|
|
129310
130323
|
canonicalJsonStringify({ manifest, target }),
|
|
129311
130324
|
"utf-8"
|
|
129312
130325
|
);
|
|
129313
|
-
|
|
130326
|
+
renameSync13(tempDir, destinationDir);
|
|
129314
130327
|
} catch (error) {
|
|
129315
130328
|
rmSync23(tempDir, { recursive: true, force: true });
|
|
129316
130329
|
throw error;
|
|
@@ -129378,7 +130391,7 @@ import {
|
|
|
129378
130391
|
existsSync as existsSync64,
|
|
129379
130392
|
mkdirSync as mkdirSync34,
|
|
129380
130393
|
readFileSync as readFileSync37,
|
|
129381
|
-
readdirSync as
|
|
130394
|
+
readdirSync as readdirSync23,
|
|
129382
130395
|
rmSync as rmSync24,
|
|
129383
130396
|
statSync as statSync24,
|
|
129384
130397
|
writeFileSync as writeFileSync24
|
|
@@ -129589,7 +130602,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
129589
130602
|
`[assemble] png-sequence chunk must be a directory: ${chunkDir} (got a file)`
|
|
129590
130603
|
);
|
|
129591
130604
|
}
|
|
129592
|
-
const frames =
|
|
130605
|
+
const frames = readdirSync23(chunkDir).filter((name) => name.endsWith(".png")).sort();
|
|
129593
130606
|
if (frames.length === 0) {
|
|
129594
130607
|
throw new Error(`[assemble] png-sequence chunk has no frames: ${chunkDir}`);
|
|
129595
130608
|
}
|
|
@@ -129609,7 +130622,7 @@ function mergePngFrameDirs(chunkPaths, outputPath, totalFrames, audioPath, start
|
|
|
129609
130622
|
cpSync4(audioPath, sidecar);
|
|
129610
130623
|
}
|
|
129611
130624
|
let fileSize = 0;
|
|
129612
|
-
for (const name of
|
|
130625
|
+
for (const name of readdirSync23(outputPath)) {
|
|
129613
130626
|
try {
|
|
129614
130627
|
fileSize += statSync24(join73(outputPath, name)).size;
|
|
129615
130628
|
} catch {
|
|
@@ -129637,7 +130650,7 @@ var init_assemble = __esm({
|
|
|
129637
130650
|
|
|
129638
130651
|
// ../producer/src/services/distributed/renderChunk.ts
|
|
129639
130652
|
import { randomBytes as randomBytes2 } from "crypto";
|
|
129640
|
-
import { existsSync as existsSync65, mkdirSync as mkdirSync35, readFileSync as readFileSync38, readdirSync as
|
|
130653
|
+
import { existsSync as existsSync65, mkdirSync as mkdirSync35, readFileSync as readFileSync38, readdirSync as readdirSync24, rmSync as rmSync25, writeFileSync as writeFileSync25 } from "fs";
|
|
129641
130654
|
import { extname as extname14, join as join74 } from "path";
|
|
129642
130655
|
function validatePlanVideosForChunk(value) {
|
|
129643
130656
|
try {
|
|
@@ -129691,7 +130704,10 @@ async function runCaptureWithScreenshotFallback(input2) {
|
|
|
129691
130704
|
async function beginFrameSessionNeedsScreenshotFallback(session, probe = probeBeginFrameLiveness) {
|
|
129692
130705
|
if (session.launchCaptureMode !== "beginframe") return false;
|
|
129693
130706
|
const timeoutMs = Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) > 0 ? Number(process.env.PRODUCER_BEGINFRAME_PROBE_TIMEOUT_MS) : 3e4;
|
|
129694
|
-
const probeTick =
|
|
130707
|
+
const probeTick = deriveBeginFrameProbeTimeTicks(
|
|
130708
|
+
session.beginFrameTimeTicks,
|
|
130709
|
+
session.beginFrameIntervalMs
|
|
130710
|
+
);
|
|
129695
130711
|
return !await probe(session.page, timeoutMs, probeTick, session.beginFrameIntervalMs);
|
|
129696
130712
|
}
|
|
129697
130713
|
function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v1") {
|
|
@@ -129704,7 +130720,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
|
|
|
129704
130720
|
);
|
|
129705
130721
|
}
|
|
129706
130722
|
const ext = (extname14(v2.framePattern) || ".jpg").toLowerCase();
|
|
129707
|
-
const frames =
|
|
130723
|
+
const frames = readdirSync24(outputDir).filter((name) => name.toLowerCase().endsWith(ext)).sort();
|
|
129708
130724
|
const framePaths = /* @__PURE__ */ new Map();
|
|
129709
130725
|
for (let i2 = 0; i2 < frames.length; i2++) {
|
|
129710
130726
|
const frameName = frames[i2];
|
|
@@ -129734,7 +130750,7 @@ function rebuildExtractedFramesFromPlanDir(planDir, videos, indexMode = "dense-v
|
|
|
129734
130750
|
}
|
|
129735
130751
|
function hashChunkOutput(outputPath, kind) {
|
|
129736
130752
|
if (kind === "file") return sha256Hex(readFileSync38(outputPath));
|
|
129737
|
-
const entries2 =
|
|
130753
|
+
const entries2 = readdirSync24(outputPath).filter((name) => /\.(png|jpg|jpeg)$/i.test(name)).sort();
|
|
129738
130754
|
const lines = entries2.map(
|
|
129739
130755
|
(name) => `${name}\0${sha256Hex(readFileSync38(join74(outputPath, name)))}`
|
|
129740
130756
|
);
|
|
@@ -130259,7 +131275,7 @@ var init_planV2Execution = __esm({
|
|
|
130259
131275
|
});
|
|
130260
131276
|
|
|
130261
131277
|
// ../producer/src/services/distributed/projectHash.ts
|
|
130262
|
-
import { readdirSync as
|
|
131278
|
+
import { readdirSync as readdirSync25, readFileSync as readFileSync39 } from "fs";
|
|
130263
131279
|
import { createHash as createHash17 } from "crypto";
|
|
130264
131280
|
import { join as join76, relative as relative16 } from "path";
|
|
130265
131281
|
var init_projectHash = __esm({
|
|
@@ -130961,7 +131977,7 @@ __export(studioServer_exports, {
|
|
|
130961
131977
|
});
|
|
130962
131978
|
import { Hono as Hono5 } from "hono";
|
|
130963
131979
|
import { streamSSE as streamSSE4 } from "hono/streaming";
|
|
130964
|
-
import { existsSync as existsSync67, readFileSync as readFileSync40, writeFileSync as writeFileSync26, statSync as statSync25, unlinkSync as
|
|
131980
|
+
import { existsSync as existsSync67, readFileSync as readFileSync40, writeFileSync as writeFileSync26, statSync as statSync25, unlinkSync as unlinkSync6 } from "fs";
|
|
130965
131981
|
import { resolve as resolve38, join as join78, basename as basename11 } from "path";
|
|
130966
131982
|
async function loadStudioProducer() {
|
|
130967
131983
|
return isDevMode() ? await Promise.resolve().then(() => (init_src2(), src_exports2)) : await Promise.resolve().then(() => (init_src2(), src_exports2));
|
|
@@ -131200,7 +132216,7 @@ function createStudioServer(options) {
|
|
|
131200
132216
|
async transformPreviewHtml({ html, project: project2 }) {
|
|
131201
132217
|
const { injectDeterministicFontFaces: injectDeterministicFontFaces2 } = await Promise.resolve().then(() => (init_deterministicFonts(), deterministicFonts_exports));
|
|
131202
132218
|
const { prepareAnimatedGifInputs: prepareAnimatedGifInputs2 } = await Promise.resolve().then(() => (init_animatedGifPrep(), animatedGifPrep_exports));
|
|
131203
|
-
const { downloadToTemp: downloadToTemp2 } = await Promise.resolve().then(() => (init_urlDownloader2(), urlDownloader_exports));
|
|
132219
|
+
const { downloadToTemp: downloadToTemp2, writeUrlDownloadTelemetry: writeUrlDownloadTelemetry2 } = await Promise.resolve().then(() => (init_urlDownloader2(), urlDownloader_exports));
|
|
131204
132220
|
const gifOutputDir = join78(project2.dir, ".hyperframes", "prepared-assets", "gif");
|
|
131205
132221
|
const gifDownloadDir = join78(project2.dir, ".hyperframes", "prepared-assets", "downloads");
|
|
131206
132222
|
const prepared = await prepareAnimatedGifInputs2(html, {
|
|
@@ -131209,7 +132225,13 @@ function createStudioServer(options) {
|
|
|
131209
132225
|
outputDir: gifOutputDir,
|
|
131210
132226
|
outputSrcPrefix: ".hyperframes/prepared-assets/gif",
|
|
131211
132227
|
cacheDir: gifOutputDir,
|
|
131212
|
-
sourceAssets: await downloadRemoteGifImageSources(
|
|
132228
|
+
sourceAssets: await downloadRemoteGifImageSources(
|
|
132229
|
+
html,
|
|
132230
|
+
gifDownloadDir,
|
|
132231
|
+
(url, destDir) => downloadToTemp2(url, destDir, void 0, void 0, void 0, {
|
|
132232
|
+
onTelemetry: writeUrlDownloadTelemetry2
|
|
132233
|
+
})
|
|
132234
|
+
)
|
|
131213
132235
|
});
|
|
131214
132236
|
return injectDeterministicFontFaces2(prepared.html);
|
|
131215
132237
|
},
|
|
@@ -131242,7 +132264,7 @@ function createStudioServer(options) {
|
|
|
131242
132264
|
for (const suffix of ["", ".meta.json"]) {
|
|
131243
132265
|
const fp = suffix ? opts.outputPath.replace(/\.(mp4|webm|mov)$/, suffix) : opts.outputPath;
|
|
131244
132266
|
try {
|
|
131245
|
-
if (existsSync67(fp))
|
|
132267
|
+
if (existsSync67(fp)) unlinkSync6(fp);
|
|
131246
132268
|
} catch {
|
|
131247
132269
|
}
|
|
131248
132270
|
}
|
|
@@ -131621,7 +132643,7 @@ import {
|
|
|
131621
132643
|
readFileSync as readFileSync41,
|
|
131622
132644
|
readlinkSync,
|
|
131623
132645
|
symlinkSync as symlinkSync3,
|
|
131624
|
-
unlinkSync as
|
|
132646
|
+
unlinkSync as unlinkSync7
|
|
131625
132647
|
} from "fs";
|
|
131626
132648
|
import { resolve as resolve39, dirname as dirname33, basename as basename12, join as join79 } from "path";
|
|
131627
132649
|
import { fileURLToPath as fileURLToPath8 } from "url";
|
|
@@ -131955,7 +132977,7 @@ function linkProjectIntoStudioData(dir, projectsDir, projectName) {
|
|
|
131955
132977
|
try {
|
|
131956
132978
|
const stat3 = lstatSync7(symlinkPath);
|
|
131957
132979
|
if (stat3.isSymbolicLink() && resolve39(readlinkSync(symlinkPath)) !== resolve39(dir)) {
|
|
131958
|
-
|
|
132980
|
+
unlinkSync7(symlinkPath);
|
|
131959
132981
|
}
|
|
131960
132982
|
} catch {
|
|
131961
132983
|
}
|
|
@@ -131971,7 +132993,7 @@ function removeSymlinkOnExit(createdSymlink, symlinkPath) {
|
|
|
131971
132993
|
if (!createdSymlink) return;
|
|
131972
132994
|
process.on("exit", () => {
|
|
131973
132995
|
try {
|
|
131974
|
-
if (existsSync68(symlinkPath))
|
|
132996
|
+
if (existsSync68(symlinkPath)) unlinkSync7(symlinkPath);
|
|
131975
132997
|
} catch {
|
|
131976
132998
|
}
|
|
131977
132999
|
});
|
|
@@ -132541,7 +133563,7 @@ import {
|
|
|
132541
133563
|
cpSync as cpSync5,
|
|
132542
133564
|
writeFileSync as writeFileSync27,
|
|
132543
133565
|
readFileSync as readFileSync43,
|
|
132544
|
-
readdirSync as
|
|
133566
|
+
readdirSync as readdirSync26
|
|
132545
133567
|
} from "fs";
|
|
132546
133568
|
import { resolve as resolve40, basename as basename13, join as join80, dirname as dirname34 } from "path";
|
|
132547
133569
|
import { fileURLToPath as fileURLToPath9 } from "url";
|
|
@@ -132561,7 +133583,7 @@ function probeVideo(filePath) {
|
|
|
132561
133583
|
if (!ffprobePath) return void 0;
|
|
132562
133584
|
const raw = execFileSync8(
|
|
132563
133585
|
ffprobePath,
|
|
132564
|
-
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", filePath],
|
|
133586
|
+
["-v", "quiet", "-print_format", "json", "-show_format", "-show_streams", "--", filePath],
|
|
132565
133587
|
{ encoding: "utf-8", timeout: 15e3 }
|
|
132566
133588
|
);
|
|
132567
133589
|
const parsed = JSON.parse(raw);
|
|
@@ -132692,7 +133714,7 @@ function listHtmlFiles(dir) {
|
|
|
132692
133714
|
const files = [];
|
|
132693
133715
|
const ignoredDirs = /* @__PURE__ */ new Set([".git", "dist", "node_modules"]);
|
|
132694
133716
|
function walk(currentDir) {
|
|
132695
|
-
for (const entry of
|
|
133717
|
+
for (const entry of readdirSync26(currentDir, { withFileTypes: true })) {
|
|
132696
133718
|
const entryPath = join80(currentDir, entry.name);
|
|
132697
133719
|
if (entry.isDirectory()) {
|
|
132698
133720
|
if (!ignoredDirs.has(entry.name)) walk(entryPath);
|
|
@@ -132738,7 +133760,7 @@ function writeTailwindSupport(destDir) {
|
|
|
132738
133760
|
}
|
|
132739
133761
|
}
|
|
132740
133762
|
function patchVideoSrc(dir, videoFilename, durationSeconds) {
|
|
132741
|
-
const htmlFiles =
|
|
133763
|
+
const htmlFiles = readdirSync26(dir, { withFileTypes: true, recursive: true }).filter((e3) => e3.isFile() && e3.name.endsWith(".html")).map((e3) => join80(e3.parentPath, e3.name));
|
|
132742
133764
|
for (const file of htmlFiles) {
|
|
132743
133765
|
let content = readFileSync43(file, "utf-8");
|
|
132744
133766
|
if (videoFilename) {
|
|
@@ -132926,7 +133948,7 @@ async function scaffoldProject(destDir, name, templateId, localVideoName, durati
|
|
|
132926
133948
|
writeDefaultPackageJson(destDir, name);
|
|
132927
133949
|
const sharedDir = getSharedTemplateDir();
|
|
132928
133950
|
if (existsSync69(sharedDir)) {
|
|
132929
|
-
for (const entry of
|
|
133951
|
+
for (const entry of readdirSync26(sharedDir, { withFileTypes: true })) {
|
|
132930
133952
|
const src = join80(sharedDir, entry.name);
|
|
132931
133953
|
const dest = resolve40(destDir, entry.name);
|
|
132932
133954
|
if (entry.isFile() || entry.isSymbolicLink()) {
|
|
@@ -133145,7 +134167,7 @@ var init_init = __esm({
|
|
|
133145
134167
|
const templateId2 = exampleFlag ?? "blank";
|
|
133146
134168
|
const name2 = args.name ?? "my-video";
|
|
133147
134169
|
const destDir2 = resolve40(name2);
|
|
133148
|
-
if (existsSync69(destDir2) &&
|
|
134170
|
+
if (existsSync69(destDir2) && readdirSync26(destDir2).length > 0) {
|
|
133149
134171
|
console.error(c.error(`Directory already exists and is not empty: ${name2}`));
|
|
133150
134172
|
failCommand();
|
|
133151
134173
|
}
|
|
@@ -133226,7 +134248,7 @@ var init_init = __esm({
|
|
|
133226
134248
|
await patchTranscript(destDir2, transcriptFile2);
|
|
133227
134249
|
}
|
|
133228
134250
|
console.log(c.success(`Created ${c.accent(name2 + "/")}`));
|
|
133229
|
-
for (const f3 of
|
|
134251
|
+
for (const f3 of readdirSync26(destDir2).filter((f4) => !f4.startsWith("."))) {
|
|
133230
134252
|
console.log(` ${c.accent(f3)}`);
|
|
133231
134253
|
}
|
|
133232
134254
|
if (!skipSkills) {
|
|
@@ -133286,7 +134308,7 @@ var init_init = __esm({
|
|
|
133286
134308
|
name = nameResult;
|
|
133287
134309
|
}
|
|
133288
134310
|
const destDir = resolve40(name);
|
|
133289
|
-
if (existsSync69(destDir) &&
|
|
134311
|
+
if (existsSync69(destDir) && readdirSync26(destDir).length > 0) {
|
|
133290
134312
|
const overwrite = await ue({
|
|
133291
134313
|
message: `Directory ${c.accent(name)} already exists and is not empty. Overwrite?`,
|
|
133292
134314
|
initialValue: false
|
|
@@ -133418,7 +134440,7 @@ ${c.dim("Use --example blank for offline use.")}`
|
|
|
133418
134440
|
if (existsSync69(transcriptFile)) {
|
|
133419
134441
|
await patchTranscript(destDir, transcriptFile);
|
|
133420
134442
|
}
|
|
133421
|
-
const files =
|
|
134443
|
+
const files = readdirSync26(destDir);
|
|
133422
134444
|
Se(files.map((f3) => c.accent(f3)).join("\n"), c.success(`Created ${name}/`));
|
|
133423
134445
|
if (!skipSkills) {
|
|
133424
134446
|
await keepSkillsCurrent(destDir);
|
|
@@ -133882,14 +134904,14 @@ var init_catalog = __esm({
|
|
|
133882
134904
|
var init_mediaProxyPreview = __esm({
|
|
133883
134905
|
"../studio-server/dist/helpers/mediaProxyPreview.js"() {
|
|
133884
134906
|
"use strict";
|
|
133885
|
-
|
|
133886
|
-
|
|
133887
|
-
|
|
134907
|
+
init_chunk_LHYV3WLZ();
|
|
134908
|
+
init_chunk_ZPI6QXJH();
|
|
134909
|
+
init_chunk_6H3V3WGJ();
|
|
133888
134910
|
}
|
|
133889
134911
|
});
|
|
133890
134912
|
|
|
133891
134913
|
// src/utils/compositionServer.ts
|
|
133892
|
-
import { createReadStream as
|
|
134914
|
+
import { createReadStream as createReadStream6, existsSync as existsSync71, statSync as statSync26 } from "fs";
|
|
133893
134915
|
import { resolve as resolve44, dirname as dirname35 } from "path";
|
|
133894
134916
|
import { Readable as Readable3 } from "stream";
|
|
133895
134917
|
import { fileURLToPath as fileURLToPath10 } from "url";
|
|
@@ -133937,7 +134959,7 @@ function buildRangeResponse(filePath, contentType, rangeHeader) {
|
|
|
133937
134959
|
const size = statSync26(filePath).size;
|
|
133938
134960
|
const last = size - 1;
|
|
133939
134961
|
const match = rangeHeader ? /^bytes=(\d*)-(\d*)$/.exec(rangeHeader.trim()) : null;
|
|
133940
|
-
const body = (start2, end2) => size === 0 ? null : Readable3.toWeb(
|
|
134962
|
+
const body = (start2, end2) => size === 0 ? null : Readable3.toWeb(createReadStream6(filePath, { start: start2, end: end2 }));
|
|
133941
134963
|
if (!match) {
|
|
133942
134964
|
return new Response(body(0, last), {
|
|
133943
134965
|
status: 200,
|
|
@@ -134004,8 +135026,8 @@ var init_compositionServer = __esm({
|
|
|
134004
135026
|
var init_proxyTranscoder = __esm({
|
|
134005
135027
|
"../studio-server/dist/helpers/proxyTranscoder.js"() {
|
|
134006
135028
|
"use strict";
|
|
134007
|
-
|
|
134008
|
-
|
|
135029
|
+
init_chunk_ZPI6QXJH();
|
|
135030
|
+
init_chunk_6H3V3WGJ();
|
|
134009
135031
|
}
|
|
134010
135032
|
});
|
|
134011
135033
|
|
|
@@ -134013,7 +135035,7 @@ var init_proxyTranscoder = __esm({
|
|
|
134013
135035
|
var init_mediaCodecMap = __esm({
|
|
134014
135036
|
"../studio-server/dist/helpers/mediaCodecMap.js"() {
|
|
134015
135037
|
"use strict";
|
|
134016
|
-
|
|
135038
|
+
init_chunk_6H3V3WGJ();
|
|
134017
135039
|
}
|
|
134018
135040
|
});
|
|
134019
135041
|
|
|
@@ -134576,7 +135598,7 @@ var init_present = __esm({
|
|
|
134576
135598
|
function isAuthError(err) {
|
|
134577
135599
|
return err instanceof AuthError;
|
|
134578
135600
|
}
|
|
134579
|
-
var AuthError, ErrNotConfigured, ErrInvalidStore, ErrUnauthenticated, ErrApi, ErrOAuthNotConfigured, ErrRefreshFailed;
|
|
135601
|
+
var AuthError, ErrNotConfigured, ErrInvalidStore, ErrUnauthenticated, ErrApi, ErrOAuthNotConfigured, ErrRefreshFailed, ErrDeviceAuthFailed;
|
|
134580
135602
|
var init_errors = __esm({
|
|
134581
135603
|
"src/auth/errors.ts"() {
|
|
134582
135604
|
"use strict";
|
|
@@ -134616,6 +135638,11 @@ var init_errors = __esm({
|
|
|
134616
135638
|
detail ? `Failed to refresh OAuth tokens: ${detail}` : "Failed to refresh OAuth tokens",
|
|
134617
135639
|
"Run `hyperframes auth login` to re-authenticate."
|
|
134618
135640
|
);
|
|
135641
|
+
ErrDeviceAuthFailed = (detail) => new AuthError(
|
|
135642
|
+
"DEVICE_AUTH_FAILED",
|
|
135643
|
+
`Device authorization failed: ${detail}`,
|
|
135644
|
+
"Run `hyperframes auth login --device` to start a new code."
|
|
135645
|
+
);
|
|
134619
135646
|
}
|
|
134620
135647
|
});
|
|
134621
135648
|
|
|
@@ -135325,6 +136352,9 @@ function tokenEndpoint() {
|
|
|
135325
136352
|
function revokeEndpoint() {
|
|
135326
136353
|
return process.env["HYPERFRAMES_OAUTH_REVOKE_URL"] || DEFAULT_REVOKE_URL;
|
|
135327
136354
|
}
|
|
136355
|
+
function deviceAuthorizationEndpoint() {
|
|
136356
|
+
return process.env["HYPERFRAMES_OAUTH_DEVICE_URL"] || DEFAULT_DEVICE_AUTHORIZATION_URL;
|
|
136357
|
+
}
|
|
135328
136358
|
function resolveClientId() {
|
|
135329
136359
|
const override = process.env["HYPERFRAMES_OAUTH_CLIENT_ID"];
|
|
135330
136360
|
const id = override && override.length > 0 ? override : DEFAULT_CLIENT_ID;
|
|
@@ -135380,6 +136410,127 @@ async function startAuthorizationCodeFlow(opts = {}) {
|
|
|
135380
136410
|
await persistOAuth(tokens, { preserveMissing: false });
|
|
135381
136411
|
return { tokens };
|
|
135382
136412
|
}
|
|
136413
|
+
async function startDeviceAuthorizationFlow(opts = {}) {
|
|
136414
|
+
const runtime = {
|
|
136415
|
+
clientId: resolveClientId(),
|
|
136416
|
+
fetchImpl: opts.fetchImpl ?? fetch,
|
|
136417
|
+
sleepImpl: opts.sleepImpl ?? ((ms) => new Promise((resolve77) => setTimeout(resolve77, ms))),
|
|
136418
|
+
now: opts.now ?? Date.now,
|
|
136419
|
+
requestTimeoutMs: opts.requestTimeoutMs ?? DEVICE_REQUEST_TIMEOUT_MS
|
|
136420
|
+
};
|
|
136421
|
+
const issuance = await requestDeviceAuthorization(runtime, opts.scope ?? DEFAULT_SCOPES);
|
|
136422
|
+
await opts.onChallenge?.({
|
|
136423
|
+
userCode: issuance.userCode,
|
|
136424
|
+
verificationUri: issuance.verificationUri,
|
|
136425
|
+
...issuance.verificationUriComplete ? { verificationUriComplete: issuance.verificationUriComplete } : {}
|
|
136426
|
+
});
|
|
136427
|
+
return await pollDeviceToken(runtime, issuance);
|
|
136428
|
+
}
|
|
136429
|
+
async function requestDeviceAuthorization(runtime, scope) {
|
|
136430
|
+
return await withDeviceRequestTimeout(
|
|
136431
|
+
runtime,
|
|
136432
|
+
"could not reach the authorization server",
|
|
136433
|
+
async (signal) => {
|
|
136434
|
+
const response = await runtime.fetchImpl(deviceAuthorizationEndpoint(), {
|
|
136435
|
+
method: "POST",
|
|
136436
|
+
headers: {
|
|
136437
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
136438
|
+
accept: "application/json"
|
|
136439
|
+
},
|
|
136440
|
+
body: new URLSearchParams({ client_id: runtime.clientId, scope }).toString(),
|
|
136441
|
+
signal
|
|
136442
|
+
});
|
|
136443
|
+
if (!response.ok) {
|
|
136444
|
+
throw ErrDeviceAuthFailed(`authorization server returned HTTP ${response.status}`);
|
|
136445
|
+
}
|
|
136446
|
+
return parseDeviceAuthorizationResponse(await readJsonOrDeviceError(response));
|
|
136447
|
+
}
|
|
136448
|
+
);
|
|
136449
|
+
}
|
|
136450
|
+
async function pollDeviceToken(runtime, issuance) {
|
|
136451
|
+
const deadline = runtime.now() + Math.min(issuance.expiresIn, MAX_DEVICE_FLOW_SECONDS) * 1e3;
|
|
136452
|
+
let intervalSeconds = issuance.interval;
|
|
136453
|
+
while (runtime.now() < deadline) {
|
|
136454
|
+
const remainingMs = deadline - runtime.now();
|
|
136455
|
+
if (remainingMs <= 0) break;
|
|
136456
|
+
await runtime.sleepImpl(Math.min(intervalSeconds * 1e3, remainingMs));
|
|
136457
|
+
const result = await requestDeviceToken(runtime, issuance.deviceCode);
|
|
136458
|
+
if (result.tokens) return result.tokens;
|
|
136459
|
+
if (result.slowDown) {
|
|
136460
|
+
intervalSeconds = Math.min(
|
|
136461
|
+
Math.max(intervalSeconds + 5, result.retryAfterSeconds ?? 0),
|
|
136462
|
+
MAX_DEVICE_POLL_SECONDS
|
|
136463
|
+
);
|
|
136464
|
+
}
|
|
136465
|
+
}
|
|
136466
|
+
throw ErrDeviceAuthFailed("the code expired");
|
|
136467
|
+
}
|
|
136468
|
+
async function requestDeviceToken(runtime, deviceCode) {
|
|
136469
|
+
return await withDeviceRequestTimeout(
|
|
136470
|
+
runtime,
|
|
136471
|
+
"lost contact with the authorization server",
|
|
136472
|
+
async (signal) => {
|
|
136473
|
+
const response = await runtime.fetchImpl(tokenEndpoint(), {
|
|
136474
|
+
method: "POST",
|
|
136475
|
+
headers: {
|
|
136476
|
+
"content-type": "application/x-www-form-urlencoded",
|
|
136477
|
+
accept: "application/json"
|
|
136478
|
+
},
|
|
136479
|
+
body: new URLSearchParams({
|
|
136480
|
+
grant_type: DEVICE_CODE_GRANT_TYPE,
|
|
136481
|
+
device_code: deviceCode,
|
|
136482
|
+
client_id: runtime.clientId
|
|
136483
|
+
}).toString(),
|
|
136484
|
+
signal
|
|
136485
|
+
});
|
|
136486
|
+
return await evaluateDevicePollResponse(response, runtime.now());
|
|
136487
|
+
}
|
|
136488
|
+
);
|
|
136489
|
+
}
|
|
136490
|
+
async function evaluateDevicePollResponse(response, nowMs) {
|
|
136491
|
+
if (response.ok) {
|
|
136492
|
+
return { tokens: parseTokenResponse(await readJsonOrDeviceError(response)) };
|
|
136493
|
+
}
|
|
136494
|
+
const error = await readDeviceOAuthError(response);
|
|
136495
|
+
switch (error) {
|
|
136496
|
+
case "authorization_pending":
|
|
136497
|
+
return {};
|
|
136498
|
+
case "slow_down":
|
|
136499
|
+
return { slowDown: true, retryAfterSeconds: retryAfterSeconds(response, nowMs) };
|
|
136500
|
+
case "access_denied":
|
|
136501
|
+
throw ErrDeviceAuthFailed("access was denied");
|
|
136502
|
+
case "expired_token":
|
|
136503
|
+
throw ErrDeviceAuthFailed("the code expired");
|
|
136504
|
+
default:
|
|
136505
|
+
if (response.status === 429) {
|
|
136506
|
+
return { slowDown: true, retryAfterSeconds: retryAfterSeconds(response, nowMs) };
|
|
136507
|
+
}
|
|
136508
|
+
throw ErrDeviceAuthFailed(`authorization server returned HTTP ${response.status}`);
|
|
136509
|
+
}
|
|
136510
|
+
}
|
|
136511
|
+
async function withDeviceRequestTimeout(runtime, networkError, operation) {
|
|
136512
|
+
const controller = new AbortController();
|
|
136513
|
+
const timer = setTimeout(() => controller.abort(), runtime.requestTimeoutMs);
|
|
136514
|
+
try {
|
|
136515
|
+
return await operation(controller.signal);
|
|
136516
|
+
} catch (err) {
|
|
136517
|
+
if (controller.signal.aborted) {
|
|
136518
|
+
throw ErrDeviceAuthFailed("authorization server request timed out");
|
|
136519
|
+
}
|
|
136520
|
+
if (isAuthError(err)) throw err;
|
|
136521
|
+
throw ErrDeviceAuthFailed(networkError);
|
|
136522
|
+
} finally {
|
|
136523
|
+
clearTimeout(timer);
|
|
136524
|
+
}
|
|
136525
|
+
}
|
|
136526
|
+
function retryAfterSeconds(response, nowMs) {
|
|
136527
|
+
const value = response.headers.get("retry-after")?.trim();
|
|
136528
|
+
if (!value) return void 0;
|
|
136529
|
+
if (/^\d+$/.test(value)) return Math.min(Number(value), MAX_DEVICE_POLL_SECONDS);
|
|
136530
|
+
const retryAt = Date.parse(value);
|
|
136531
|
+
if (!Number.isFinite(retryAt)) return void 0;
|
|
136532
|
+
return Math.min(Math.max(Math.ceil((retryAt - nowMs) / 1e3), 0), MAX_DEVICE_POLL_SECONDS);
|
|
136533
|
+
}
|
|
135383
136534
|
async function refreshTokens(refresh_token, opts = {}) {
|
|
135384
136535
|
const clientId = resolveClientId();
|
|
135385
136536
|
const fetchImpl = opts.fetchImpl ?? fetch;
|
|
@@ -135540,6 +136691,146 @@ async function persistOAuth(tokens, opts) {
|
|
|
135540
136691
|
const oauth = opts.preserveMissing ? { ...existing.oauth, ...tokens } : { ...tokens };
|
|
135541
136692
|
await writeStore({ ...existing, oauth });
|
|
135542
136693
|
}
|
|
136694
|
+
async function persistVerifiedOAuthSession(tokens, user) {
|
|
136695
|
+
let credentials = {};
|
|
136696
|
+
try {
|
|
136697
|
+
({ credentials } = await readStore());
|
|
136698
|
+
} catch {
|
|
136699
|
+
credentials = {};
|
|
136700
|
+
}
|
|
136701
|
+
const next = {
|
|
136702
|
+
...credentials,
|
|
136703
|
+
oauth: { ...tokens }
|
|
136704
|
+
};
|
|
136705
|
+
if (user.email || user.first_name || user.last_name || user.username) {
|
|
136706
|
+
next.user = {
|
|
136707
|
+
...credentials.user,
|
|
136708
|
+
email: user.email,
|
|
136709
|
+
first_name: user.first_name,
|
|
136710
|
+
last_name: user.last_name,
|
|
136711
|
+
username: user.username
|
|
136712
|
+
};
|
|
136713
|
+
} else {
|
|
136714
|
+
delete next.user;
|
|
136715
|
+
}
|
|
136716
|
+
await writeStore(next);
|
|
136717
|
+
}
|
|
136718
|
+
function parseDeviceAuthorizationResponse(payload) {
|
|
136719
|
+
const data2 = requireDeviceAuthorizationRecord(payload);
|
|
136720
|
+
const deviceCode = stringField(data2, "device_code");
|
|
136721
|
+
const userCode = stringField(data2, "user_code");
|
|
136722
|
+
const verificationUri = requiredSafeVerificationUri(data2, "verification_uri");
|
|
136723
|
+
const verificationUriComplete = optionalSafeVerificationUri(data2, "verification_uri_complete");
|
|
136724
|
+
const expiresIn = strictNumericField(data2, "expires_in");
|
|
136725
|
+
const interval = strictNumericField(data2, "interval");
|
|
136726
|
+
requireSafeDeviceCode(deviceCode);
|
|
136727
|
+
requireSafeDeviceCode(userCode);
|
|
136728
|
+
const timing2 = normalizeDeviceAuthorizationTiming(data2, expiresIn, interval);
|
|
136729
|
+
return {
|
|
136730
|
+
deviceCode,
|
|
136731
|
+
userCode,
|
|
136732
|
+
verificationUri,
|
|
136733
|
+
...verificationUriComplete ? { verificationUriComplete } : {},
|
|
136734
|
+
...timing2
|
|
136735
|
+
};
|
|
136736
|
+
}
|
|
136737
|
+
function requireSafeDeviceCode(value) {
|
|
136738
|
+
if (!value || !isHeaderSafe(value)) {
|
|
136739
|
+
throw ErrDeviceAuthFailed("authorization server returned an invalid response");
|
|
136740
|
+
}
|
|
136741
|
+
}
|
|
136742
|
+
function normalizeDeviceAuthorizationTiming(data2, expiresIn, interval) {
|
|
136743
|
+
if (!isPositiveNumber(expiresIn) || data2["interval"] !== void 0 && !isPositiveNumber(interval)) {
|
|
136744
|
+
throw ErrDeviceAuthFailed("authorization server returned invalid timing values");
|
|
136745
|
+
}
|
|
136746
|
+
return {
|
|
136747
|
+
expiresIn,
|
|
136748
|
+
interval: Math.min(
|
|
136749
|
+
Math.max(Math.ceil(interval ?? MIN_DEVICE_POLL_SECONDS), MIN_DEVICE_POLL_SECONDS),
|
|
136750
|
+
MAX_DEVICE_POLL_SECONDS
|
|
136751
|
+
)
|
|
136752
|
+
};
|
|
136753
|
+
}
|
|
136754
|
+
function requiredSafeVerificationUri(data2, key2) {
|
|
136755
|
+
const value = normalizeSafeVerificationUri(stringField(data2, key2));
|
|
136756
|
+
if (!value) throw ErrDeviceAuthFailed("authorization server returned an unsafe verification URL");
|
|
136757
|
+
return value;
|
|
136758
|
+
}
|
|
136759
|
+
function optionalSafeVerificationUri(data2, key2) {
|
|
136760
|
+
if (data2[key2] === void 0) return void 0;
|
|
136761
|
+
return requiredSafeVerificationUri(data2, key2);
|
|
136762
|
+
}
|
|
136763
|
+
function requireDeviceAuthorizationRecord(payload) {
|
|
136764
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) {
|
|
136765
|
+
throw ErrDeviceAuthFailed("authorization server returned an invalid response");
|
|
136766
|
+
}
|
|
136767
|
+
return payload;
|
|
136768
|
+
}
|
|
136769
|
+
function isPositiveNumber(value) {
|
|
136770
|
+
return value !== void 0 && value > 0;
|
|
136771
|
+
}
|
|
136772
|
+
function normalizeSafeVerificationUri(value) {
|
|
136773
|
+
if (!value || !isHeaderSafe(value)) return void 0;
|
|
136774
|
+
try {
|
|
136775
|
+
const url = new URL(value);
|
|
136776
|
+
if (url.username || url.password) return void 0;
|
|
136777
|
+
const allowed = url.protocol === "https:" || url.protocol === "http:" && ["127.0.0.1", "localhost"].includes(url.hostname);
|
|
136778
|
+
return allowed ? url.href : void 0;
|
|
136779
|
+
} catch {
|
|
136780
|
+
return void 0;
|
|
136781
|
+
}
|
|
136782
|
+
}
|
|
136783
|
+
async function readJsonOrDeviceError(res) {
|
|
136784
|
+
return await readBoundedDeviceJson(res);
|
|
136785
|
+
}
|
|
136786
|
+
async function readDeviceOAuthError(res) {
|
|
136787
|
+
try {
|
|
136788
|
+
const payload = await readBoundedDeviceJson(res);
|
|
136789
|
+
if (!payload || typeof payload !== "object" || Array.isArray(payload)) return void 0;
|
|
136790
|
+
const error = payload["error"];
|
|
136791
|
+
return typeof error === "string" ? error : void 0;
|
|
136792
|
+
} catch {
|
|
136793
|
+
return void 0;
|
|
136794
|
+
}
|
|
136795
|
+
}
|
|
136796
|
+
function strictNumericField(obj, key2) {
|
|
136797
|
+
const value = obj[key2];
|
|
136798
|
+
if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
|
|
136799
|
+
if (typeof value !== "string" || value.trim() === "") return void 0;
|
|
136800
|
+
const parsed = Number(value);
|
|
136801
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
136802
|
+
}
|
|
136803
|
+
async function readBoundedDeviceJson(res) {
|
|
136804
|
+
if (!res.body) throw ErrDeviceAuthFailed("authorization server returned no data");
|
|
136805
|
+
const reader = res.body.getReader();
|
|
136806
|
+
const chunks = [];
|
|
136807
|
+
let total = 0;
|
|
136808
|
+
try {
|
|
136809
|
+
while (true) {
|
|
136810
|
+
const { done, value } = await reader.read();
|
|
136811
|
+
if (done) break;
|
|
136812
|
+
if (!value) continue;
|
|
136813
|
+
total += value.byteLength;
|
|
136814
|
+
if (total > MAX_DEVICE_RESPONSE_BYTES) {
|
|
136815
|
+
await reader.cancel();
|
|
136816
|
+
throw ErrDeviceAuthFailed("authorization server response was too large");
|
|
136817
|
+
}
|
|
136818
|
+
chunks.push(value);
|
|
136819
|
+
}
|
|
136820
|
+
const body = new Uint8Array(total);
|
|
136821
|
+
let offset2 = 0;
|
|
136822
|
+
for (const chunk of chunks) {
|
|
136823
|
+
body.set(chunk, offset2);
|
|
136824
|
+
offset2 += chunk.byteLength;
|
|
136825
|
+
}
|
|
136826
|
+
return JSON.parse(new TextDecoder().decode(body));
|
|
136827
|
+
} catch (err) {
|
|
136828
|
+
if (isAuthError(err)) throw err;
|
|
136829
|
+
throw ErrDeviceAuthFailed("authorization server returned non-JSON data");
|
|
136830
|
+
} finally {
|
|
136831
|
+
reader.releaseLock();
|
|
136832
|
+
}
|
|
136833
|
+
}
|
|
135543
136834
|
async function readJsonOrThrow(res) {
|
|
135544
136835
|
try {
|
|
135545
136836
|
return await res.json();
|
|
@@ -135554,7 +136845,7 @@ async function safeText2(res) {
|
|
|
135554
136845
|
return "";
|
|
135555
136846
|
}
|
|
135556
136847
|
}
|
|
135557
|
-
var REVOKE_TIMEOUT_MS, MIN_EXPIRES_IN_SECONDS, DEFAULT_CLIENT_ID, DEFAULT_SCOPES, DEFAULT_AUTHORIZE_URL, DEFAULT_TOKEN_URL, DEFAULT_REVOKE_URL;
|
|
136848
|
+
var REVOKE_TIMEOUT_MS, MIN_EXPIRES_IN_SECONDS, DEFAULT_CLIENT_ID, DEFAULT_SCOPES, DEFAULT_AUTHORIZE_URL, DEFAULT_TOKEN_URL, DEFAULT_REVOKE_URL, DEFAULT_DEVICE_AUTHORIZATION_URL, DEVICE_CODE_GRANT_TYPE, MAX_DEVICE_FLOW_SECONDS, MIN_DEVICE_POLL_SECONDS, MAX_DEVICE_POLL_SECONDS, MAX_DEVICE_RESPONSE_BYTES, DEVICE_REQUEST_TIMEOUT_MS;
|
|
135558
136849
|
var init_oauth = __esm({
|
|
135559
136850
|
"src/auth/oauth.ts"() {
|
|
135560
136851
|
"use strict";
|
|
@@ -135573,6 +136864,13 @@ var init_oauth = __esm({
|
|
|
135573
136864
|
DEFAULT_AUTHORIZE_URL = "https://app.heygen.com/oauth/authorize";
|
|
135574
136865
|
DEFAULT_TOKEN_URL = "https://api2.heygen.com/v1/oauth/token";
|
|
135575
136866
|
DEFAULT_REVOKE_URL = "https://api2.heygen.com/v1/oauth/revoke";
|
|
136867
|
+
DEFAULT_DEVICE_AUTHORIZATION_URL = "https://api2.heygen.com/v1/oauth/device_authorization";
|
|
136868
|
+
DEVICE_CODE_GRANT_TYPE = "urn:ietf:params:oauth:grant-type:device_code";
|
|
136869
|
+
MAX_DEVICE_FLOW_SECONDS = 30 * 60;
|
|
136870
|
+
MIN_DEVICE_POLL_SECONDS = 5;
|
|
136871
|
+
MAX_DEVICE_POLL_SECONDS = 60;
|
|
136872
|
+
MAX_DEVICE_RESPONSE_BYTES = 64 * 1024;
|
|
136873
|
+
DEVICE_REQUEST_TIMEOUT_MS = 15e3;
|
|
135576
136874
|
}
|
|
135577
136875
|
});
|
|
135578
136876
|
|
|
@@ -135591,7 +136889,7 @@ var init_auth = __esm({
|
|
|
135591
136889
|
});
|
|
135592
136890
|
|
|
135593
136891
|
// src/utils/projectLink.ts
|
|
135594
|
-
import { randomUUID as
|
|
136892
|
+
import { randomUUID as randomUUID9 } from "crypto";
|
|
135595
136893
|
import { existsSync as existsSync75, mkdirSync as mkdirSync39, readFileSync as readFileSync46, writeFileSync as writeFileSync28 } from "fs";
|
|
135596
136894
|
import { homedir as homedir16 } from "os";
|
|
135597
136895
|
import { join as join83, resolve as resolve47 } from "path";
|
|
@@ -135642,7 +136940,7 @@ function ensureProjectId(absDir) {
|
|
|
135642
136940
|
const path2 = resolve47(absDir);
|
|
135643
136941
|
const existing = links[path2];
|
|
135644
136942
|
if (existing) return existing.projectId;
|
|
135645
|
-
const projectId =
|
|
136943
|
+
const projectId = randomUUID9();
|
|
135646
136944
|
links[path2] = { projectId, url: "" };
|
|
135647
136945
|
writeProjectLinks(links);
|
|
135648
136946
|
return projectId;
|
|
@@ -135680,7 +136978,7 @@ var init_projectLink = __esm({
|
|
|
135680
136978
|
|
|
135681
136979
|
// src/utils/publishProject.ts
|
|
135682
136980
|
import { basename as basename14, dirname as dirname37, join as join84, posix as posix5, relative as relative18, resolve as resolve48 } from "path";
|
|
135683
|
-
import { existsSync as existsSync76, readdirSync as
|
|
136981
|
+
import { existsSync as existsSync76, readdirSync as readdirSync27, readFileSync as readFileSync47, statSync as statSync27 } from "fs";
|
|
135684
136982
|
import AdmZip from "adm-zip";
|
|
135685
136983
|
import ignore2 from "ignore";
|
|
135686
136984
|
function isRecord8(value) {
|
|
@@ -135792,7 +137090,7 @@ function createProjectIgnore(rootDir) {
|
|
|
135792
137090
|
return matcher;
|
|
135793
137091
|
}
|
|
135794
137092
|
function collectProjectFiles(rootDir, currentDir, paths, matcher) {
|
|
135795
|
-
for (const entry of
|
|
137093
|
+
for (const entry of readdirSync27(currentDir, { withFileTypes: true })) {
|
|
135796
137094
|
if (shouldIgnoreSegment(entry.name)) continue;
|
|
135797
137095
|
const absolutePath = join84(currentDir, entry.name);
|
|
135798
137096
|
const relativePath = relative18(rootDir, absolutePath).replaceAll("\\", "/");
|
|
@@ -137495,6 +138793,7 @@ function probeWebmAlpha(filePath) {
|
|
|
137495
138793
|
"stream=codec_name:stream_tags=alpha_mode",
|
|
137496
138794
|
"-of",
|
|
137497
138795
|
"json",
|
|
138796
|
+
"--",
|
|
137498
138797
|
filePath
|
|
137499
138798
|
],
|
|
137500
138799
|
{ encoding: "utf-8", timeout: 15e3 }
|
|
@@ -138042,7 +139341,7 @@ __export(render_exports, {
|
|
|
138042
139341
|
renderLocal: () => renderLocal,
|
|
138043
139342
|
resolveBrowserGpuForCli: () => resolveBrowserGpuForCli
|
|
138044
139343
|
});
|
|
138045
|
-
import { mkdtempSync as mkdtempSync12, readdirSync as
|
|
139344
|
+
import { mkdtempSync as mkdtempSync12, readdirSync as readdirSync28, readFileSync as readFileSync53, statSync as statSync29, writeFileSync as writeFileSync30, rmSync as rmSync27 } from "fs";
|
|
138046
139345
|
import { freemem as freemem5, tmpdir as tmpdir12 } from "os";
|
|
138047
139346
|
import { resolve as resolve54, dirname as dirname41, join as join88, basename as basename16 } from "path";
|
|
138048
139347
|
import { execFileSync as execFileSync11, spawn as spawn15 } from "child_process";
|
|
@@ -138725,7 +140024,7 @@ function printRenderComplete(outputPath, elapsedMs, quiet, outputDurationSeconds
|
|
|
138725
140024
|
isDirectory = stat3.isDirectory();
|
|
138726
140025
|
if (stat3.isDirectory()) {
|
|
138727
140026
|
let total = 0;
|
|
138728
|
-
for (const entry of
|
|
140027
|
+
for (const entry of readdirSync28(outputPath, { withFileTypes: true })) {
|
|
138729
140028
|
if (!entry.isFile()) continue;
|
|
138730
140029
|
try {
|
|
138731
140030
|
total += statSync29(join88(outputPath, entry.name)).size;
|
|
@@ -139141,7 +140440,7 @@ __export(staticProjectServer_exports, {
|
|
|
139141
140440
|
serveStaticProjectHtml: () => serveStaticProjectHtml
|
|
139142
140441
|
});
|
|
139143
140442
|
import { createServer as createServer2 } from "http";
|
|
139144
|
-
import { createReadStream as
|
|
140443
|
+
import { createReadStream as createReadStream7, existsSync as existsSync80, statSync as statSync30 } from "fs";
|
|
139145
140444
|
import { isAbsolute as isAbsolute14, relative as relative20, resolve as resolve55 } from "path";
|
|
139146
140445
|
function serveFileWithRange(filePath, rangeHeader, res, contentType = getMimeType(filePath)) {
|
|
139147
140446
|
const size = statSync30(filePath).size;
|
|
@@ -139167,7 +140466,7 @@ function serveFileWithRange(filePath, rangeHeader, res, contentType = getMimeTyp
|
|
|
139167
140466
|
headers["Content-Range"] = `bytes ${start}-${end}/${size}`;
|
|
139168
140467
|
}
|
|
139169
140468
|
headers["Content-Length"] = String(end - start + 1);
|
|
139170
|
-
const stream =
|
|
140469
|
+
const stream = createReadStream7(filePath, { start, end });
|
|
139171
140470
|
stream.on("open", () => {
|
|
139172
140471
|
res.writeHead(status, headers);
|
|
139173
140472
|
stream.pipe(res);
|
|
@@ -139709,7 +141008,7 @@ var init_motionAudit = __esm({
|
|
|
139709
141008
|
});
|
|
139710
141009
|
|
|
139711
141010
|
// src/utils/motionSpec.ts
|
|
139712
|
-
import { existsSync as existsSync81, readFileSync as readFileSync54, readdirSync as
|
|
141011
|
+
import { existsSync as existsSync81, readFileSync as readFileSync54, readdirSync as readdirSync29 } from "fs";
|
|
139713
141012
|
import { basename as basename17, join as join89 } from "path";
|
|
139714
141013
|
function isObject2(value) {
|
|
139715
141014
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -139753,7 +141052,7 @@ function parseMotionSpec(raw) {
|
|
|
139753
141052
|
}
|
|
139754
141053
|
function findMotionSpec(projectDir) {
|
|
139755
141054
|
if (!existsSync81(projectDir)) return null;
|
|
139756
|
-
const entries2 =
|
|
141055
|
+
const entries2 = readdirSync29(projectDir);
|
|
139757
141056
|
const sidecars = entries2.filter((name) => name.endsWith(".motion.json")).sort();
|
|
139758
141057
|
if (!sidecars[0]) return null;
|
|
139759
141058
|
if (sidecars.length === 1) return join89(projectDir, sidecars[0]);
|
|
@@ -143727,8 +145026,62 @@ function containsTimelineCall3(node, timelineVar) {
|
|
|
143727
145026
|
function rangeOf3(node) {
|
|
143728
145027
|
return typeof node.start === "number" && typeof node.end === "number" ? [node.start, node.end] : void 0;
|
|
143729
145028
|
}
|
|
145029
|
+
function isSafeDefaultExpression3(node, earlierParams) {
|
|
145030
|
+
let safe = true;
|
|
145031
|
+
const visit = (current2, parent, key2) => {
|
|
145032
|
+
if (!isNode4(current2) || !safe) return;
|
|
145033
|
+
if (!SAFE_DEFAULT_NODES3.has(current2.type)) {
|
|
145034
|
+
safe = false;
|
|
145035
|
+
return;
|
|
145036
|
+
}
|
|
145037
|
+
if (current2.type === "UnaryExpression" && current2.operator === "delete") {
|
|
145038
|
+
safe = false;
|
|
145039
|
+
return;
|
|
145040
|
+
}
|
|
145041
|
+
if (current2.type === "Identifier") {
|
|
145042
|
+
const nonValue = parent && key2 ? isNonValueIdentifierSlot3(parent, key2) : false;
|
|
145043
|
+
if (!nonValue && current2.name !== "undefined" && !earlierParams.has(current2.name)) {
|
|
145044
|
+
safe = false;
|
|
145045
|
+
}
|
|
145046
|
+
return;
|
|
145047
|
+
}
|
|
145048
|
+
for (const childKey of Object.keys(current2)) {
|
|
145049
|
+
if (SKIP_KEYS3.has(childKey)) continue;
|
|
145050
|
+
const child = current2[childKey];
|
|
145051
|
+
if (Array.isArray(child)) {
|
|
145052
|
+
for (const item of child) visit(item, current2, childKey);
|
|
145053
|
+
} else {
|
|
145054
|
+
visit(child, current2, childKey);
|
|
145055
|
+
}
|
|
145056
|
+
}
|
|
145057
|
+
};
|
|
145058
|
+
visit(node);
|
|
145059
|
+
return safe;
|
|
145060
|
+
}
|
|
145061
|
+
function supportedParam3(param, earlier) {
|
|
145062
|
+
if (param.type === "Identifier") return { name: param.name };
|
|
145063
|
+
if (param.type !== "AssignmentPattern" || param.left?.type !== "Identifier") return null;
|
|
145064
|
+
if (!isSafeDefaultExpression3(param.right, earlier)) return null;
|
|
145065
|
+
return { name: param.left.name, defaultExpression: param.right };
|
|
145066
|
+
}
|
|
145067
|
+
function supportedParams3(fn) {
|
|
145068
|
+
if (SUPPORTED_PARAMS_CACHE3.has(fn)) return SUPPORTED_PARAMS_CACHE3.get(fn) ?? null;
|
|
145069
|
+
const params = [];
|
|
145070
|
+
const earlier = /* @__PURE__ */ new Set();
|
|
145071
|
+
for (const param of fn.params ?? []) {
|
|
145072
|
+
const parsed = supportedParam3(param, earlier);
|
|
145073
|
+
if (!parsed) {
|
|
145074
|
+
SUPPORTED_PARAMS_CACHE3.set(fn, null);
|
|
145075
|
+
return null;
|
|
145076
|
+
}
|
|
145077
|
+
params.push(parsed);
|
|
145078
|
+
earlier.add(parsed.name);
|
|
145079
|
+
}
|
|
145080
|
+
SUPPORTED_PARAMS_CACHE3.set(fn, params);
|
|
145081
|
+
return params;
|
|
145082
|
+
}
|
|
143730
145083
|
function isShapeEligible3(fn) {
|
|
143731
|
-
return isFunctionNode6(fn) && fn.body?.type === "BlockStatement" &&
|
|
145084
|
+
return isFunctionNode6(fn) && fn.body?.type === "BlockStatement" && supportedParams3(fn) !== null;
|
|
143732
145085
|
}
|
|
143733
145086
|
function callsAny3(node, names) {
|
|
143734
145087
|
let hit = false;
|
|
@@ -143778,20 +145131,55 @@ function timelineBuildingNames3(candidates, timelineVar) {
|
|
|
143778
145131
|
function bump3(counts, key2) {
|
|
143779
145132
|
counts.set(key2, (counts.get(key2) ?? 0) + 1);
|
|
143780
145133
|
}
|
|
145134
|
+
function undefinedIdentifier3() {
|
|
145135
|
+
return { type: "Identifier", name: "undefined" };
|
|
145136
|
+
}
|
|
145137
|
+
function isExplicitUndefined3(node) {
|
|
145138
|
+
return node?.type === "Identifier" && node.name === "undefined" || node?.type === "UnaryExpression" && node.operator === "void" && node.argument?.type === "Literal" && node.argument.value === 0;
|
|
145139
|
+
}
|
|
145140
|
+
function resolveHelperBindings3(call, params) {
|
|
145141
|
+
if (call.arguments?.some((arg) => arg?.type === "SpreadElement")) return null;
|
|
145142
|
+
const bindings = /* @__PURE__ */ new Map();
|
|
145143
|
+
for (let i2 = 0; i2 < params.length; i2++) {
|
|
145144
|
+
const param = params[i2];
|
|
145145
|
+
const arg = call.arguments?.[i2];
|
|
145146
|
+
if (arg && !isExplicitUndefined3(arg)) {
|
|
145147
|
+
bindings.set(param.name, arg);
|
|
145148
|
+
} else if (param.defaultExpression) {
|
|
145149
|
+
bindings.set(param.name, substituteParams3(cloneNode4(param.defaultExpression), bindings));
|
|
145150
|
+
} else {
|
|
145151
|
+
bindings.set(param.name, undefinedIdentifier3());
|
|
145152
|
+
}
|
|
145153
|
+
}
|
|
145154
|
+
return bindings;
|
|
145155
|
+
}
|
|
145156
|
+
function statementHelperCall3(node, names) {
|
|
145157
|
+
if (node.type !== "ExpressionStatement") return void 0;
|
|
145158
|
+
const expression = node.expression;
|
|
145159
|
+
if (expression?.type !== "CallExpression" || expression.callee?.type !== "Identifier") {
|
|
145160
|
+
return void 0;
|
|
145161
|
+
}
|
|
145162
|
+
return names.has(expression.callee.name) ? expression : void 0;
|
|
145163
|
+
}
|
|
143781
145164
|
function safelyDroppable3(program, candidates) {
|
|
143782
145165
|
const names = new Set(candidates.keys());
|
|
143783
145166
|
const totalIds = /* @__PURE__ */ new Map();
|
|
143784
145167
|
const stmtCalls = /* @__PURE__ */ new Map();
|
|
145168
|
+
const unbindable = /* @__PURE__ */ new Set();
|
|
143785
145169
|
walkNodes3(program, (n2) => {
|
|
143786
145170
|
if (n2.type === "Identifier" && names.has(n2.name)) bump3(totalIds, n2.name);
|
|
143787
|
-
const
|
|
143788
|
-
if (
|
|
143789
|
-
|
|
143790
|
-
|
|
145171
|
+
const call = statementHelperCall3(n2, names);
|
|
145172
|
+
if (!call) return;
|
|
145173
|
+
bump3(stmtCalls, call.callee.name);
|
|
145174
|
+
const fn = candidates.get(call.callee.name);
|
|
145175
|
+
const params = fn && supportedParams3(fn);
|
|
145176
|
+
if (!params || !resolveHelperBindings3(call, params)) unbindable.add(call.callee.name);
|
|
143791
145177
|
});
|
|
143792
145178
|
const safe = /* @__PURE__ */ new Map();
|
|
143793
145179
|
for (const [name, fn] of candidates) {
|
|
143794
|
-
if ((totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0))
|
|
145180
|
+
if (!unbindable.has(name) && (totalIds.get(name) ?? 0) === 1 + (stmtCalls.get(name) ?? 0)) {
|
|
145181
|
+
safe.set(name, fn);
|
|
145182
|
+
}
|
|
143795
145183
|
}
|
|
143796
145184
|
return safe;
|
|
143797
145185
|
}
|
|
@@ -143834,11 +145222,11 @@ function expandBody3(bodyStmts, bindings, prov, ctx) {
|
|
|
143834
145222
|
}
|
|
143835
145223
|
function inlineHelper3(call, ctx) {
|
|
143836
145224
|
const fn = ctx.helpers.get(call.callee.name);
|
|
143837
|
-
|
|
143838
|
-
|
|
143839
|
-
|
|
143840
|
-
|
|
143841
|
-
|
|
145225
|
+
if (!fn) return null;
|
|
145226
|
+
const params = supportedParams3(fn);
|
|
145227
|
+
if (!params) return null;
|
|
145228
|
+
const bindings = resolveHelperBindings3(call, params);
|
|
145229
|
+
if (!bindings) return null;
|
|
143842
145230
|
const prov = {
|
|
143843
145231
|
kind: "helper",
|
|
143844
145232
|
fn: call.callee.name,
|
|
@@ -145157,7 +146545,7 @@ function parseGsapScriptAcorn3(script) {
|
|
|
145157
146545
|
return { animations: [], timelineVar: "tl", preamble: "", postamble: "" };
|
|
145158
146546
|
}
|
|
145159
146547
|
}
|
|
145160
|
-
var recast3, import_parser4, PROPERTY_GROUPS6, PROP_TO_GROUP6, roundPercentage5, SKIP_KEYS3, FUNCTION_TYPES3, GSAP_METHODS6, MAX_DEPTH3, MAX_ITERS3, GSAP_METHODS23, QUERY_METHODS5, ITERATION_METHODS5, SCOPE_NODE_TYPES5, CONST_NODES4, MATH_FNS4, MATH_CONSTS4, BUILTIN_VAR_KEYS5, DROPPED_VAR_KEYS5, EXTRAS_KEYS5, PERCENTAGE_KEY_RE5, GSAP_DEFAULT_DURATION5;
|
|
146548
|
+
var recast3, import_parser4, PROPERTY_GROUPS6, PROP_TO_GROUP6, roundPercentage5, SKIP_KEYS3, FUNCTION_TYPES3, GSAP_METHODS6, MAX_DEPTH3, MAX_ITERS3, SAFE_DEFAULT_NODES3, SUPPORTED_PARAMS_CACHE3, GSAP_METHODS23, QUERY_METHODS5, ITERATION_METHODS5, SCOPE_NODE_TYPES5, CONST_NODES4, MATH_FNS4, MATH_CONSTS4, BUILTIN_VAR_KEYS5, DROPPED_VAR_KEYS5, EXTRAS_KEYS5, PERCENTAGE_KEY_RE5, GSAP_DEFAULT_DURATION5;
|
|
145161
146549
|
var init_gsapParserExports = __esm({
|
|
145162
146550
|
"../parsers/dist/gsapParserExports.js"() {
|
|
145163
146551
|
"use strict";
|
|
@@ -145187,6 +146575,23 @@ var init_gsapParserExports = __esm({
|
|
|
145187
146575
|
GSAP_METHODS6 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
145188
146576
|
MAX_DEPTH3 = 8;
|
|
145189
146577
|
MAX_ITERS3 = 512;
|
|
146578
|
+
SAFE_DEFAULT_NODES3 = /* @__PURE__ */ new Set([
|
|
146579
|
+
"ArrayExpression",
|
|
146580
|
+
"BinaryExpression",
|
|
146581
|
+
"ChainExpression",
|
|
146582
|
+
"ConditionalExpression",
|
|
146583
|
+
"Identifier",
|
|
146584
|
+
"Literal",
|
|
146585
|
+
"LogicalExpression",
|
|
146586
|
+
"MemberExpression",
|
|
146587
|
+
"ObjectExpression",
|
|
146588
|
+
"Property",
|
|
146589
|
+
"SpreadElement",
|
|
146590
|
+
"TemplateElement",
|
|
146591
|
+
"TemplateLiteral",
|
|
146592
|
+
"UnaryExpression"
|
|
146593
|
+
]);
|
|
146594
|
+
SUPPORTED_PARAMS_CACHE3 = /* @__PURE__ */ new WeakMap();
|
|
145190
146595
|
GSAP_METHODS23 = /* @__PURE__ */ new Set(["set", "to", "from", "fromTo"]);
|
|
145191
146596
|
QUERY_METHODS5 = /* @__PURE__ */ new Set(["querySelector", "querySelectorAll"]);
|
|
145192
146597
|
ITERATION_METHODS5 = /* @__PURE__ */ new Set(["forEach", "map"]);
|
|
@@ -146555,7 +147960,7 @@ __export(info_exports, {
|
|
|
146555
147960
|
examples: () => examples16,
|
|
146556
147961
|
orientation: () => orientation
|
|
146557
147962
|
});
|
|
146558
|
-
import { readFileSync as readFileSync60, readdirSync as
|
|
147963
|
+
import { readFileSync as readFileSync60, readdirSync as readdirSync30, statSync as statSync33 } from "fs";
|
|
146559
147964
|
import { join as join98 } from "path";
|
|
146560
147965
|
function orientation(width, height) {
|
|
146561
147966
|
if (width > height) return "landscape";
|
|
@@ -146569,7 +147974,7 @@ function durationFromHtml(html, fallback) {
|
|
|
146569
147974
|
}
|
|
146570
147975
|
function totalSize(dir) {
|
|
146571
147976
|
let total = 0;
|
|
146572
|
-
for (const entry of
|
|
147977
|
+
for (const entry of readdirSync30(dir, { withFileTypes: true })) {
|
|
146573
147978
|
const path2 = join98(dir, entry.name);
|
|
146574
147979
|
if (entry.isDirectory()) {
|
|
146575
147980
|
total += totalSize(path2);
|
|
@@ -148018,7 +149423,7 @@ __export(synthesize_exports, {
|
|
|
148018
149423
|
synthesize: () => synthesize
|
|
148019
149424
|
});
|
|
148020
149425
|
import { execFileSync as execFileSync14 } from "child_process";
|
|
148021
|
-
import { existsSync as existsSync95, writeFileSync as writeFileSync38, mkdirSync as mkdirSync48, readdirSync as
|
|
149426
|
+
import { existsSync as existsSync95, writeFileSync as writeFileSync38, mkdirSync as mkdirSync48, readdirSync as readdirSync31, unlinkSync as unlinkSync8 } from "fs";
|
|
148022
149427
|
import { join as join104, dirname as dirname50, basename as basename20 } from "path";
|
|
148023
149428
|
import { homedir as homedir19 } from "os";
|
|
148024
149429
|
function ensureSynthScript() {
|
|
@@ -148027,10 +149432,10 @@ function ensureSynthScript() {
|
|
|
148027
149432
|
writeFileSync38(SCRIPT_PATH, SYNTH_SCRIPT);
|
|
148028
149433
|
const currentName = basename20(SCRIPT_PATH);
|
|
148029
149434
|
try {
|
|
148030
|
-
for (const entry of
|
|
149435
|
+
for (const entry of readdirSync31(SCRIPT_DIR)) {
|
|
148031
149436
|
if (entry !== currentName && /^synth(-v\d+)?\.py$/.test(entry)) {
|
|
148032
149437
|
try {
|
|
148033
|
-
|
|
149438
|
+
unlinkSync8(join104(SCRIPT_DIR, entry));
|
|
148034
149439
|
} catch {
|
|
148035
149440
|
}
|
|
148036
149441
|
}
|
|
@@ -148875,7 +150280,7 @@ __export(upgrade_exports, {
|
|
|
148875
150280
|
upgradeProjectPins: () => upgradeProjectPins
|
|
148876
150281
|
});
|
|
148877
150282
|
import { execFileSync as execFileSync16 } from "child_process";
|
|
148878
|
-
import { existsSync as existsSync99, readFileSync as readFileSync66, writeFileSync as writeFileSync39, renameSync as
|
|
150283
|
+
import { existsSync as existsSync99, readFileSync as readFileSync66, writeFileSync as writeFileSync39, renameSync as renameSync14 } from "fs";
|
|
148879
150284
|
import { resolve as resolve65 } from "path";
|
|
148880
150285
|
async function confirmUpgrade() {
|
|
148881
150286
|
const shouldUpgrade = await ue({ message: "Upgrade now?" });
|
|
@@ -148948,7 +150353,7 @@ async function upgradeProjectPins(dir, opts) {
|
|
|
148948
150353
|
const tmp = `${pkgPath}.tmp`;
|
|
148949
150354
|
writeFileSync39(tmp, `${JSON.stringify(raw, null, 2)}
|
|
148950
150355
|
`, "utf-8");
|
|
148951
|
-
|
|
150356
|
+
renameSync14(tmp, pkgPath);
|
|
148952
150357
|
}
|
|
148953
150358
|
return { changed: rewrite.changed, from: rewrite.fromVersions, to: latest, path: pkgPath };
|
|
148954
150359
|
}
|
|
@@ -149215,7 +150620,7 @@ __export(feedback_exports, {
|
|
|
149215
150620
|
default: () => feedback_default,
|
|
149216
150621
|
examples: () => examples26
|
|
149217
150622
|
});
|
|
149218
|
-
import { randomUUID as
|
|
150623
|
+
import { randomUUID as randomUUID10 } from "crypto";
|
|
149219
150624
|
import { resolve as resolve66 } from "path";
|
|
149220
150625
|
import open from "open";
|
|
149221
150626
|
function normalizeComment(raw) {
|
|
@@ -149368,7 +150773,7 @@ var init_feedback2 = __esm({
|
|
|
149368
150773
|
}
|
|
149369
150774
|
const comment = normalizeComment(args.comment);
|
|
149370
150775
|
const doctorSummary = await getDoctorSummary();
|
|
149371
|
-
const feedbackId =
|
|
150776
|
+
const feedbackId = randomUUID10();
|
|
149372
150777
|
const config = readConfig();
|
|
149373
150778
|
const joinKeys = buildTelemetryJoinKeys({
|
|
149374
150779
|
feedbackId,
|
|
@@ -149593,7 +150998,7 @@ __export(contactSheet_exports, {
|
|
|
149593
150998
|
createSvgContactSheet: () => createSvgContactSheet
|
|
149594
150999
|
});
|
|
149595
151000
|
import sharp from "sharp";
|
|
149596
|
-
import { readdirSync as
|
|
151001
|
+
import { readdirSync as readdirSync33, readFileSync as readFileSync67, writeFileSync as writeFileSync40, unlinkSync as unlinkSync9, existsSync as existsSync100 } from "fs";
|
|
149597
151002
|
import { join as join106, extname as extname19, basename as basename21, dirname as dirname53 } from "path";
|
|
149598
151003
|
async function createContactSheet(imagePaths, outputPath, opts = {}) {
|
|
149599
151004
|
const {
|
|
@@ -149681,7 +151086,7 @@ async function createContactSheetPages(imagePaths, outputBasePath, opts = {}, la
|
|
|
149681
151086
|
}
|
|
149682
151087
|
async function createScrollContactSheet(screenshotsDir, outputPath, budget = {}) {
|
|
149683
151088
|
if (!existsSync100(screenshotsDir)) return [];
|
|
149684
|
-
const scrollFiles =
|
|
151089
|
+
const scrollFiles = readdirSync33(screenshotsDir).filter((f3) => f3.startsWith("scroll-") && f3.endsWith(".png")).sort();
|
|
149685
151090
|
if (scrollFiles.length === 0) return [];
|
|
149686
151091
|
const paths = scrollFiles.map((f3) => join106(screenshotsDir, f3));
|
|
149687
151092
|
const labels = scrollFiles.map((f3) => {
|
|
@@ -149698,7 +151103,7 @@ async function createScrollContactSheet(screenshotsDir, outputPath, budget = {})
|
|
|
149698
151103
|
}
|
|
149699
151104
|
async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {}) {
|
|
149700
151105
|
if (!existsSync100(snapshotsDir)) return [];
|
|
149701
|
-
const snapshotFiles =
|
|
151106
|
+
const snapshotFiles = readdirSync33(snapshotsDir).filter((f3) => f3.startsWith("frame-") && f3.endsWith(".png")).sort();
|
|
149702
151107
|
if (snapshotFiles.length === 0) return [];
|
|
149703
151108
|
const paths = snapshotFiles.map((f3) => join106(snapshotsDir, f3));
|
|
149704
151109
|
const labels = snapshotFiles.map((f3) => {
|
|
@@ -149716,7 +151121,7 @@ async function createSnapshotContactSheet(snapshotsDir, outputPath, budget = {})
|
|
|
149716
151121
|
async function createAssetContactSheet(assetsDir, outputPath, budget = {}) {
|
|
149717
151122
|
if (!existsSync100(assetsDir)) return [];
|
|
149718
151123
|
const imageExts = /* @__PURE__ */ new Set([".png", ".jpg", ".jpeg", ".webp"]);
|
|
149719
|
-
const assetFiles =
|
|
151124
|
+
const assetFiles = readdirSync33(assetsDir).filter((f3) => imageExts.has(extname19(f3).toLowerCase()) && !f3.includes("contact-sheet")).sort();
|
|
149720
151125
|
if (assetFiles.length === 0) return [];
|
|
149721
151126
|
const paths = assetFiles.map((f3) => join106(assetsDir, f3));
|
|
149722
151127
|
return createContactSheetPages(paths, outputPath, {
|
|
@@ -149735,7 +151140,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
149735
151140
|
const seen = /* @__PURE__ */ new Set();
|
|
149736
151141
|
const svgPaths = [];
|
|
149737
151142
|
for (const dir of dirsToScan) {
|
|
149738
|
-
for (const f3 of
|
|
151143
|
+
for (const f3 of readdirSync33(dir).filter((f4) => f4.endsWith(".svg")).sort()) {
|
|
149739
151144
|
if (!seen.has(f3)) {
|
|
149740
151145
|
seen.add(f3);
|
|
149741
151146
|
svgPaths.push(join106(dir, f3));
|
|
@@ -149782,7 +151187,7 @@ async function createSvgContactSheet(svgsDir, outputPath, assetsRootDir, budget
|
|
|
149782
151187
|
} finally {
|
|
149783
151188
|
for (const tmp of tmpPaths) {
|
|
149784
151189
|
try {
|
|
149785
|
-
|
|
151190
|
+
unlinkSync9(tmp);
|
|
149786
151191
|
} catch {
|
|
149787
151192
|
}
|
|
149788
151193
|
}
|
|
@@ -155954,7 +157359,7 @@ var require_node_domexception = __commonJS({
|
|
|
155954
157359
|
});
|
|
155955
157360
|
|
|
155956
157361
|
// ../../node_modules/.bun/fetch-blob@3.2.0/node_modules/fetch-blob/from.js
|
|
155957
|
-
import { statSync as statSync35, createReadStream as
|
|
157362
|
+
import { statSync as statSync35, createReadStream as createReadStream8, promises as fs3 } from "fs";
|
|
155958
157363
|
import { basename as basename23 } from "path";
|
|
155959
157364
|
var import_node_domexception, stat, blobFromSync, blobFrom, fileFrom, fileFromSync, fromBlob, fromFile, BlobDataItem;
|
|
155960
157365
|
var init_from = __esm({
|
|
@@ -156006,7 +157411,7 @@ var init_from = __esm({
|
|
|
156006
157411
|
if (mtimeMs > this.lastModified) {
|
|
156007
157412
|
throw new import_node_domexception.default("The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.", "NotReadableError");
|
|
156008
157413
|
}
|
|
156009
|
-
yield*
|
|
157414
|
+
yield* createReadStream8(this.#path, {
|
|
156010
157415
|
start: this.#start,
|
|
156011
157416
|
end: this.#start + this.size - 1
|
|
156012
157417
|
});
|
|
@@ -157673,7 +159078,7 @@ var require_gaxios = __commonJS({
|
|
|
157673
159078
|
var retry_js_1 = require_retry3();
|
|
157674
159079
|
var stream_1 = __require("stream");
|
|
157675
159080
|
var interceptor_js_1 = require_interceptor();
|
|
157676
|
-
var
|
|
159081
|
+
var randomUUID11 = async () => globalThis.crypto?.randomUUID() || (await import("crypto")).randomUUID();
|
|
157677
159082
|
var HTTP_STATUS_NO_CONTENT = 204;
|
|
157678
159083
|
var Gaxios = class {
|
|
157679
159084
|
agentCache = /* @__PURE__ */ new Map();
|
|
@@ -157946,7 +159351,7 @@ var require_gaxios = __commonJS({
|
|
|
157946
159351
|
*/
|
|
157947
159352
|
["Blob", "File", "FormData"].includes(opts.data?.constructor?.name || "");
|
|
157948
159353
|
if (opts.multipart?.length) {
|
|
157949
|
-
const boundary = await
|
|
159354
|
+
const boundary = await randomUUID11();
|
|
157950
159355
|
preparedHeaders.set("content-type", `multipart/related; boundary=${boundary}`);
|
|
157951
159356
|
opts.body = stream_1.Readable.from(this.getMultipartRequest(opts.multipart, boundary));
|
|
157952
159357
|
} else if (shouldDirectlyPassData) {
|
|
@@ -189703,8 +191108,8 @@ async function captureSnapshots(projectDir, opts) {
|
|
|
189703
191108
|
const snapshotDir = opts.outputDir ?? join107(projectDir, "snapshots");
|
|
189704
191109
|
mkdirSync49(snapshotDir, { recursive: true });
|
|
189705
191110
|
try {
|
|
189706
|
-
const { readdirSync:
|
|
189707
|
-
for (const file of
|
|
191111
|
+
const { readdirSync: readdirSync39 } = await import("fs");
|
|
191112
|
+
for (const file of readdirSync39(snapshotDir)) {
|
|
189708
191113
|
if (/\.(png|jpg|jpeg)$/i.test(file)) {
|
|
189709
191114
|
rmSync30(join107(snapshotDir, file), { force: true });
|
|
189710
191115
|
}
|
|
@@ -190159,6 +191564,7 @@ function probeMedia2(mediaPath, ffprobePath) {
|
|
|
190159
191564
|
"stream=color_space,color_transfer,color_primaries,pix_fmt,duration:format=duration",
|
|
190160
191565
|
"-of",
|
|
190161
191566
|
"json",
|
|
191567
|
+
"--",
|
|
190162
191568
|
mediaPath
|
|
190163
191569
|
], { encoding: "utf8", timeout: 5e3, stdio: ["ignore", "pipe", "pipe"] });
|
|
190164
191570
|
const parsed = asRecord(JSON.parse(raw));
|
|
@@ -191614,7 +193020,7 @@ __export(compare_exports, {
|
|
|
191614
193020
|
parseCompareArgs: () => parseCompareArgs,
|
|
191615
193021
|
prepareCompareVariantProjects: () => prepareCompareVariantProjects
|
|
191616
193022
|
});
|
|
191617
|
-
import { cpSync as cpSync6, existsSync as existsSync105, mkdirSync as mkdirSync51, mkdtempSync as mkdtempSync17, renameSync as
|
|
193023
|
+
import { cpSync as cpSync6, existsSync as existsSync105, mkdirSync as mkdirSync51, mkdtempSync as mkdtempSync17, renameSync as renameSync15, rmSync as rmSync32, statSync as statSync36 } from "fs";
|
|
191618
193024
|
import { tmpdir as tmpdir17 } from "os";
|
|
191619
193025
|
import { basename as basename28, dirname as dirname55, extname as extname23, join as join110 } from "path";
|
|
191620
193026
|
function defaultLabelForPath(input2) {
|
|
@@ -191726,7 +193132,7 @@ function stageHtmlVariant(variant) {
|
|
|
191726
193132
|
});
|
|
191727
193133
|
const sourceName = basename28(variant.inputPath);
|
|
191728
193134
|
if (sourceName !== "index.html") {
|
|
191729
|
-
|
|
193135
|
+
renameSync15(join110(stagedDir, sourceName), join110(stagedDir, "index.html"));
|
|
191730
193136
|
}
|
|
191731
193137
|
return {
|
|
191732
193138
|
...variant,
|
|
@@ -192304,7 +193710,7 @@ __export(video_exports, {
|
|
|
192304
193710
|
runVideoMode: () => runVideoMode,
|
|
192305
193711
|
safeFilename: () => safeFilename
|
|
192306
193712
|
});
|
|
192307
|
-
import { createWriteStream as createWriteStream4, existsSync as existsSync106, mkdirSync as mkdirSync54, readFileSync as readFileSync71, unlinkSync as
|
|
193713
|
+
import { createWriteStream as createWriteStream4, existsSync as existsSync106, mkdirSync as mkdirSync54, readFileSync as readFileSync71, unlinkSync as unlinkSync10 } from "fs";
|
|
192308
193714
|
import { resolve as resolve71, join as join113, basename as basename29 } from "path";
|
|
192309
193715
|
async function streamToFile(url, destPath) {
|
|
192310
193716
|
const r2 = await safeFetch(url, {
|
|
@@ -192367,7 +193773,7 @@ async function streamToFile(url, destPath) {
|
|
|
192367
193773
|
file.destroy();
|
|
192368
193774
|
if (e3.code !== "EEXIST") {
|
|
192369
193775
|
try {
|
|
192370
|
-
|
|
193776
|
+
unlinkSync10(destPath);
|
|
192371
193777
|
} catch {
|
|
192372
193778
|
}
|
|
192373
193779
|
}
|
|
@@ -193726,7 +195132,7 @@ var init_designStyleExtractor = __esm({
|
|
|
193726
195132
|
});
|
|
193727
195133
|
|
|
193728
195134
|
// src/capture/fontMetadataExtractor.ts
|
|
193729
|
-
import { readdirSync as
|
|
195135
|
+
import { readdirSync as readdirSync34, readFileSync as readFileSync73, writeFileSync as writeFileSync46, existsSync as existsSync107 } from "fs";
|
|
193730
195136
|
import { join as join114 } from "path";
|
|
193731
195137
|
import * as fontkit from "fontkit";
|
|
193732
195138
|
function isFontCollection(value) {
|
|
@@ -193736,7 +195142,7 @@ function extractFontMetadata(fontsDir, outputPath) {
|
|
|
193736
195142
|
const files = [];
|
|
193737
195143
|
const unidentified = [];
|
|
193738
195144
|
if (existsSync107(fontsDir)) {
|
|
193739
|
-
const fontFiles =
|
|
195145
|
+
const fontFiles = readdirSync34(fontsDir).filter((f3) => /\.(woff2?|ttf|otf)$/i.test(f3));
|
|
193740
195146
|
for (const filename of fontFiles) {
|
|
193741
195147
|
const fullPath = join114(fontsDir, filename);
|
|
193742
195148
|
const meta = readSingleFont(fullPath, filename);
|
|
@@ -194049,7 +195455,7 @@ var init_animationCataloger = __esm({
|
|
|
194049
195455
|
});
|
|
194050
195456
|
|
|
194051
195457
|
// src/capture/mediaCapture.ts
|
|
194052
|
-
import { mkdirSync as mkdirSync55, writeFileSync as writeFileSync47, readdirSync as
|
|
195458
|
+
import { mkdirSync as mkdirSync55, writeFileSync as writeFileSync47, readdirSync as readdirSync35, readFileSync as readFileSync74, statSync as statSync37 } from "fs";
|
|
194053
195459
|
import { join as join115, extname as extname25 } from "path";
|
|
194054
195460
|
function liveRemainingMs(budget, fallbackMs) {
|
|
194055
195461
|
return budget.remainingMs?.() ?? fallbackMs;
|
|
@@ -194118,7 +195524,7 @@ async function renderLottiePreviews(chromeBrowser, lottieDir, outputDir, budget
|
|
|
194118
195524
|
const manifest = [];
|
|
194119
195525
|
const previewDir = join115(lottieDir, "previews");
|
|
194120
195526
|
mkdirSync55(previewDir, { recursive: true });
|
|
194121
|
-
for (const file of
|
|
195527
|
+
for (const file of readdirSync35(lottieDir)) {
|
|
194122
195528
|
if (!file.endsWith(".json")) continue;
|
|
194123
195529
|
if (liveRemainingMs(budget, 1) <= 0) break;
|
|
194124
195530
|
try {
|
|
@@ -194434,7 +195840,7 @@ var init_mediaCapture = __esm({
|
|
|
194434
195840
|
});
|
|
194435
195841
|
|
|
194436
195842
|
// src/capture/contentExtractor.ts
|
|
194437
|
-
import { existsSync as existsSync108, readdirSync as
|
|
195843
|
+
import { existsSync as existsSync108, readdirSync as readdirSync36, statSync as statSync38, readFileSync as readFileSync75 } from "fs";
|
|
194438
195844
|
import { basename as basename30, join as join116 } from "path";
|
|
194439
195845
|
function resolveVisionPhaseCompletion(outcome, remainingMs) {
|
|
194440
195846
|
if (outcome.budgetExhausted || remainingMs <= 0) {
|
|
@@ -194673,7 +196079,7 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
194673
196079
|
return response.text?.trim() || "";
|
|
194674
196080
|
};
|
|
194675
196081
|
}
|
|
194676
|
-
const imageFiles =
|
|
196082
|
+
const imageFiles = readdirSync36(join116(outputDir, "assets")).filter(
|
|
194677
196083
|
(f3) => /\.(png|jpg|jpeg|webp|gif)$/i.test(f3)
|
|
194678
196084
|
);
|
|
194679
196085
|
const BATCH_SIZE = 20;
|
|
@@ -194735,12 +196141,12 @@ async function captionImagesWithGemini(outputDir, progress, warnings, options =
|
|
|
194735
196141
|
);
|
|
194736
196142
|
const svgFiles = [];
|
|
194737
196143
|
const assetsDir = join116(outputDir, "assets");
|
|
194738
|
-
for (const f3 of
|
|
196144
|
+
for (const f3 of readdirSync36(assetsDir)) {
|
|
194739
196145
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: f3 });
|
|
194740
196146
|
}
|
|
194741
196147
|
const svgsSubdir = join116(assetsDir, "svgs");
|
|
194742
196148
|
if (existsSync108(svgsSubdir)) {
|
|
194743
|
-
for (const f3 of
|
|
196149
|
+
for (const f3 of readdirSync36(svgsSubdir)) {
|
|
194744
196150
|
if (/\.svg$/i.test(f3)) svgFiles.push({ file: f3, relPath: `svgs/${f3}` });
|
|
194745
196151
|
}
|
|
194746
196152
|
}
|
|
@@ -194840,7 +196246,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
194840
196246
|
const fontLines = [];
|
|
194841
196247
|
const assetsPath = join116(outputDir, "assets");
|
|
194842
196248
|
try {
|
|
194843
|
-
for (const file of
|
|
196249
|
+
for (const file of readdirSync36(assetsPath)) {
|
|
194844
196250
|
if (file === "svgs" || file === "fonts" || file === "lottie" || file === "videos") continue;
|
|
194845
196251
|
const filePath = join116(assetsPath, file);
|
|
194846
196252
|
const stat3 = statSync38(filePath);
|
|
@@ -194872,7 +196278,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
194872
196278
|
}
|
|
194873
196279
|
try {
|
|
194874
196280
|
const svgsPath = join116(assetsPath, "svgs");
|
|
194875
|
-
for (const file of
|
|
196281
|
+
for (const file of readdirSync36(svgsPath)) {
|
|
194876
196282
|
if (!file.endsWith(".svg")) continue;
|
|
194877
196283
|
const svgMatch = tokens.svgs.find(
|
|
194878
196284
|
(s2) => s2.label && file.includes(
|
|
@@ -194891,7 +196297,7 @@ function generateAssetDescriptions(outputDir, tokens, catalogedAssets, geminiCap
|
|
|
194891
196297
|
}
|
|
194892
196298
|
try {
|
|
194893
196299
|
const fontsPath = join116(assetsPath, "fonts");
|
|
194894
|
-
for (const file of
|
|
196300
|
+
for (const file of readdirSync36(fontsPath)) {
|
|
194895
196301
|
fontLines.push(`fonts/${file} \u2014 font file`);
|
|
194896
196302
|
}
|
|
194897
196303
|
} catch {
|
|
@@ -194934,7 +196340,7 @@ var agentPromptGenerator_exports = {};
|
|
|
194934
196340
|
__export(agentPromptGenerator_exports, {
|
|
194935
196341
|
generateAgentPrompt: () => generateAgentPrompt
|
|
194936
196342
|
});
|
|
194937
|
-
import { writeFileSync as writeFileSync48, readdirSync as
|
|
196343
|
+
import { writeFileSync as writeFileSync48, readdirSync as readdirSync37, existsSync as existsSync109 } from "fs";
|
|
194938
196344
|
import { join as join117 } from "path";
|
|
194939
196345
|
function inferColorRole(hex) {
|
|
194940
196346
|
const r2 = parseInt(hex.slice(1, 3), 16) / 255;
|
|
@@ -194970,7 +196376,7 @@ function buildPrompt(outputDir, url, tokens, hasScreenshot, hasLottie, hasShader
|
|
|
194970
196376
|
const baseName = baseFile.replace(/\.jpg$/, "");
|
|
194971
196377
|
const escapedBase = baseName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
194972
196378
|
const paginatedRe = new RegExp(`^${escapedBase}(?:-(\\d+))?\\.jpg$`);
|
|
194973
|
-
const all =
|
|
196379
|
+
const all = readdirSync37(fullDir).filter((f3) => paginatedRe.test(f3)).map((f3) => ({ name: f3, page: parseInt(f3.match(paginatedRe)?.[1] ?? "0", 10) })).sort((a, b2) => a.page - b2.page).map((entry) => entry.name);
|
|
194974
196380
|
if (all.length === 0) return [];
|
|
194975
196381
|
if (all.length === 1) {
|
|
194976
196382
|
return [`| \`${dir}/${all[0]}\` | ${label2} |`];
|
|
@@ -196560,7 +197966,7 @@ __export(state_exports, {
|
|
|
196560
197966
|
stateFilePath: () => stateFilePath,
|
|
196561
197967
|
writeStackOutputs: () => writeStackOutputs
|
|
196562
197968
|
});
|
|
196563
|
-
import { existsSync as existsSync113, mkdirSync as mkdirSync58, readdirSync as
|
|
197969
|
+
import { existsSync as existsSync113, mkdirSync as mkdirSync58, readdirSync as readdirSync38, readFileSync as readFileSync77, rmSync as rmSync33, writeFileSync as writeFileSync53 } from "fs";
|
|
196564
197970
|
import { dirname as dirname56, join as join121 } from "path";
|
|
196565
197971
|
function stateFilePath(stackName = DEFAULT_STACK_NAME, cwd = process.cwd()) {
|
|
196566
197972
|
return join121(cwd, STATE_DIR_NAME, `${STATE_FILE_PREFIX}${stackName}.json`);
|
|
@@ -196587,7 +197993,7 @@ function deleteStackOutputs(stackName = DEFAULT_STACK_NAME, cwd = process.cwd())
|
|
|
196587
197993
|
function listStackNames(cwd = process.cwd()) {
|
|
196588
197994
|
const dir = join121(cwd, STATE_DIR_NAME);
|
|
196589
197995
|
if (!existsSync113(dir)) return [];
|
|
196590
|
-
return
|
|
197996
|
+
return readdirSync38(dir).filter((f3) => f3.startsWith(STATE_FILE_PREFIX) && f3.endsWith(".json")).map((f3) => f3.slice(STATE_FILE_PREFIX.length, -".json".length));
|
|
196591
197997
|
}
|
|
196592
197998
|
function requireStack(stackName, cwd = process.cwd()) {
|
|
196593
197999
|
const stack = readStackOutputs(stackName, cwd);
|
|
@@ -199001,7 +200407,7 @@ var init_poll = __esm({
|
|
|
199001
200407
|
});
|
|
199002
200408
|
|
|
199003
200409
|
// src/cloud/download.ts
|
|
199004
|
-
import { createWriteStream as createWriteStream5, mkdirSync as mkdirSync60, unlinkSync as
|
|
200410
|
+
import { createWriteStream as createWriteStream5, mkdirSync as mkdirSync60, unlinkSync as unlinkSync11 } from "fs";
|
|
199005
200411
|
import { dirname as dirname58 } from "path";
|
|
199006
200412
|
async function downloadToFile(url, destPath, options = {}) {
|
|
199007
200413
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
@@ -199042,7 +200448,7 @@ async function downloadToFile(url, destPath, options = {}) {
|
|
|
199042
200448
|
await closeFile(file);
|
|
199043
200449
|
if (errored) {
|
|
199044
200450
|
try {
|
|
199045
|
-
|
|
200451
|
+
unlinkSync11(destPath);
|
|
199046
200452
|
} catch {
|
|
199047
200453
|
}
|
|
199048
200454
|
}
|
|
@@ -200622,6 +202028,98 @@ __export(login_exports, {
|
|
|
200622
202028
|
default: () => login_default
|
|
200623
202029
|
});
|
|
200624
202030
|
import { stdin as input } from "process";
|
|
202031
|
+
function isRemoteOrHeadless() {
|
|
202032
|
+
const remoteEnvironment = [
|
|
202033
|
+
"CODESPACES",
|
|
202034
|
+
"GITHUB_CODESPACES",
|
|
202035
|
+
"REMOTE_CONTAINERS",
|
|
202036
|
+
"GITPOD_WORKSPACE_ID",
|
|
202037
|
+
"container"
|
|
202038
|
+
].some(envFlagEnabled);
|
|
202039
|
+
return Boolean(
|
|
202040
|
+
process.env["SSH_CONNECTION"] || process.env["SSH_CLIENT"] || process.env["SSH_TTY"] || process.env["BROWSER"] === "none" || process.env["HF_NO_BROWSER"] === "1" || remoteEnvironment || process.stdout.isTTY !== true
|
|
202041
|
+
);
|
|
202042
|
+
}
|
|
202043
|
+
function envFlagEnabled(name) {
|
|
202044
|
+
const value = process.env[name]?.trim().toLowerCase();
|
|
202045
|
+
return Boolean(value && value !== "0" && value !== "false" && value !== "no");
|
|
202046
|
+
}
|
|
202047
|
+
function assertAttendedDeviceFlow() {
|
|
202048
|
+
if (envFlagEnabled("CI") || process.stdin.isTTY !== true || process.stdout.isTTY !== true) {
|
|
202049
|
+
console.error(
|
|
202050
|
+
c.error(
|
|
202051
|
+
"`--device` requires an attended terminal and is disabled in CI. Use an API key or workload credential for automation."
|
|
202052
|
+
)
|
|
202053
|
+
);
|
|
202054
|
+
failUsage();
|
|
202055
|
+
}
|
|
202056
|
+
}
|
|
202057
|
+
async function runDeviceLogin() {
|
|
202058
|
+
assertAttendedDeviceFlow();
|
|
202059
|
+
assertOAuthConfiguredOrExit();
|
|
202060
|
+
const { trackAuthLoginStarted: trackAuthLoginStarted2, trackAuthLoginCompleted: trackAuthLoginCompleted2, trackAuthLoginFailed: trackAuthLoginFailed2, identifyUser: identifyUser2 } = await Promise.resolve().then(() => (init_telemetry2(), telemetry_exports2));
|
|
202061
|
+
trackAuthLoginStarted2("device");
|
|
202062
|
+
let tokens;
|
|
202063
|
+
try {
|
|
202064
|
+
tokens = await startDeviceAuthorizationFlow({
|
|
202065
|
+
onChallenge: ({ verificationUri, verificationUriComplete, userCode }) => {
|
|
202066
|
+
console.log(`Open ${c.accent(verificationUriComplete ?? verificationUri)} in a browser.`);
|
|
202067
|
+
if (!verificationUriComplete) console.log(`Enter code ${c.bold(userCode)}.`);
|
|
202068
|
+
console.log(c.dim("Waiting for approval\u2026"));
|
|
202069
|
+
}
|
|
202070
|
+
});
|
|
202071
|
+
} catch (err) {
|
|
202072
|
+
const message = err.message || "Device authorization failed.";
|
|
202073
|
+
trackAuthLoginFailed2("device", /expired/i.test(message) ? "flow_timeout" : "flow_error");
|
|
202074
|
+
console.error(c.error(message));
|
|
202075
|
+
failCommand();
|
|
202076
|
+
}
|
|
202077
|
+
const credential = {
|
|
202078
|
+
type: "oauth",
|
|
202079
|
+
access_token: tokens.access_token,
|
|
202080
|
+
...tokens.refresh_token ? { refresh_token: tokens.refresh_token } : {},
|
|
202081
|
+
source: "file_json",
|
|
202082
|
+
refreshable: false
|
|
202083
|
+
};
|
|
202084
|
+
let user;
|
|
202085
|
+
try {
|
|
202086
|
+
user = await new AuthClient().getCurrentUser(credential);
|
|
202087
|
+
} catch (err) {
|
|
202088
|
+
await revokeDeviceTokens(tokens);
|
|
202089
|
+
trackAuthLoginFailed2("device", "rejected");
|
|
202090
|
+
console.error(
|
|
202091
|
+
c.error(
|
|
202092
|
+
`HeyGen could not verify the approved device session; no credential was saved. ${err.message}`
|
|
202093
|
+
)
|
|
202094
|
+
);
|
|
202095
|
+
failCommand();
|
|
202096
|
+
}
|
|
202097
|
+
try {
|
|
202098
|
+
await persistVerifiedOAuthSession(tokens, toStoredUserInfo(user));
|
|
202099
|
+
} catch (err) {
|
|
202100
|
+
await revokeDeviceTokens(tokens);
|
|
202101
|
+
trackAuthLoginFailed2("device", "flow_error");
|
|
202102
|
+
console.error(
|
|
202103
|
+
c.error(
|
|
202104
|
+
`Could not save the verified device session; it was revoked. ${err.message}`
|
|
202105
|
+
)
|
|
202106
|
+
);
|
|
202107
|
+
failCommand();
|
|
202108
|
+
}
|
|
202109
|
+
const id = identityKey(user);
|
|
202110
|
+
if (id) identifyUser2(id);
|
|
202111
|
+
trackAuthLoginCompleted2("device", id);
|
|
202112
|
+
const identity = userDisplayName(toStoredUserInfo(user)) ?? "(unknown user)";
|
|
202113
|
+
console.log(c.success(`\u2713 Signed in as ${identity}.`));
|
|
202114
|
+
}
|
|
202115
|
+
async function revokeDeviceTokens(tokens) {
|
|
202116
|
+
await revokeTokens(tokens.access_token, { token_type_hint: "access_token" });
|
|
202117
|
+
if (tokens.refresh_token) {
|
|
202118
|
+
await revokeTokens(tokens.refresh_token, {
|
|
202119
|
+
token_type_hint: "refresh_token"
|
|
202120
|
+
});
|
|
202121
|
+
}
|
|
202122
|
+
}
|
|
200625
202123
|
async function runOAuthLogin() {
|
|
200626
202124
|
assertOAuthConfiguredOrExit();
|
|
200627
202125
|
const { trackAuthLoginStarted: trackAuthLoginStarted2, trackAuthLoginFailed: trackAuthLoginFailed2 } = await Promise.resolve().then(() => (init_telemetry2(), telemetry_exports2));
|
|
@@ -200756,7 +202254,11 @@ async function rollback(previous) {
|
|
|
200756
202254
|
async function verifyAndReport(key2) {
|
|
200757
202255
|
const client = new AuthClient();
|
|
200758
202256
|
try {
|
|
200759
|
-
const user = await client.getCurrentUser({
|
|
202257
|
+
const user = await client.getCurrentUser({
|
|
202258
|
+
type: "api_key",
|
|
202259
|
+
key: key2,
|
|
202260
|
+
source: "file_json"
|
|
202261
|
+
});
|
|
200760
202262
|
await persistUserInfo(user);
|
|
200761
202263
|
const identity = userDisplayName(toStoredUserInfo(user)) ?? "(unknown user)";
|
|
200762
202264
|
console.log(c.success(`\u2713 API key saved. Authenticated as ${identity}.`));
|
|
@@ -200833,15 +202335,35 @@ var init_login = __esm({
|
|
|
200833
202335
|
"api-key": {
|
|
200834
202336
|
type: "string",
|
|
200835
202337
|
description: "API key value, or pass `--api-key` with no value to read from stdin / prompt."
|
|
202338
|
+
},
|
|
202339
|
+
device: {
|
|
202340
|
+
type: "boolean",
|
|
202341
|
+
description: "Use an attended device code (for SSH/headless terminals; never for CI)."
|
|
200836
202342
|
}
|
|
200837
202343
|
},
|
|
200838
202344
|
// fallow-ignore-next-line complexity
|
|
200839
202345
|
async run({ args }) {
|
|
200840
202346
|
const inlineKey = args["api-key"];
|
|
202347
|
+
if (inlineKey !== void 0 && args.device) {
|
|
202348
|
+
console.error(c.error("Choose either --device or --api-key, not both."));
|
|
202349
|
+
failUsage();
|
|
202350
|
+
}
|
|
200841
202351
|
if (inlineKey !== void 0) {
|
|
200842
202352
|
await runApiKeyLogin(inlineKey);
|
|
200843
202353
|
return;
|
|
200844
202354
|
}
|
|
202355
|
+
if (args.device) {
|
|
202356
|
+
await runDeviceLogin();
|
|
202357
|
+
return;
|
|
202358
|
+
}
|
|
202359
|
+
if (isRemoteOrHeadless()) {
|
|
202360
|
+
console.error(
|
|
202361
|
+
c.error(
|
|
202362
|
+
"Browser callback login is unavailable in this remote/headless terminal. Run `hyperframes auth login --device`."
|
|
202363
|
+
)
|
|
202364
|
+
);
|
|
202365
|
+
failUsage();
|
|
202366
|
+
}
|
|
200845
202367
|
await runOAuthLogin();
|
|
200846
202368
|
}
|
|
200847
202369
|
});
|
|
@@ -201264,6 +202786,7 @@ var init_auth3 = __esm({
|
|
|
201264
202786
|
init_colors();
|
|
201265
202787
|
examples37 = [
|
|
201266
202788
|
["Sign in via browser (OAuth)", "hyperframes auth login"],
|
|
202789
|
+
["Sign in from SSH/headless terminal", "hyperframes auth login --device"],
|
|
201267
202790
|
["Save an API key (interactive)", "hyperframes auth login --api-key"],
|
|
201268
202791
|
["Save an API key from stdin", "echo $HEYGEN_API_KEY | hyperframes auth login --api-key"],
|
|
201269
202792
|
["Check who you're signed in as", "hyperframes auth status"],
|
|
@@ -201277,7 +202800,7 @@ Manage HeyGen credentials. Credentials live in
|
|
|
201277
202800
|
${c.accent("~/.heygen/credentials")} and are shared with heygen-cli.
|
|
201278
202801
|
|
|
201279
202802
|
${c.bold("SUBCOMMANDS:")}
|
|
201280
|
-
${c.accent("login")} ${c.dim("Sign in via browser
|
|
202803
|
+
${c.accent("login")} ${c.dim("Sign in via browser, --device for SSH, or --api-key for a long-lived key.")}
|
|
201281
202804
|
${c.accent("status")} ${c.dim("Show the active credential's source, type, and identity.")}
|
|
201282
202805
|
${c.accent("refresh")} ${c.dim("Force-refresh the OAuth access token.")}
|
|
201283
202806
|
${c.accent("logout")} ${c.dim("Remove the stored credential (--keep-api-key for OAuth-only).")}
|
|
@@ -201288,6 +202811,7 @@ ${c.bold("ENV VARS:")}
|
|
|
201288
202811
|
${c.accent("HEYGEN_API_URL")} Override the API base URL (default https://api.heygen.com).
|
|
201289
202812
|
${c.accent("HEYGEN_CONFIG_DIR")} Override the credentials directory (default ~/.heygen).
|
|
201290
202813
|
${c.accent("HYPERFRAMES_OAUTH_CLIENT_ID")} Override the OAuth client_id (for dev/test).
|
|
202814
|
+
${c.accent("HYPERFRAMES_OAUTH_DEVICE_URL")} Override the RFC 8628 device endpoint (for dev/test).
|
|
201291
202815
|
`;
|
|
201292
202816
|
auth_default = defineCommand({
|
|
201293
202817
|
meta: { name: "auth", description: "Sign in to HeyGen and manage credentials" },
|