@hyperframes/parsers 0.8.171 → 0.8.172
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/assetResolution.d.ts +3 -1
- package/dist/assetResolution.js +63 -16
- package/package.json +2 -2
|
@@ -53,6 +53,8 @@ declare function resolveExistingLocalAsset(projectDir: string, url: string): {
|
|
|
53
53
|
resolved: string;
|
|
54
54
|
rootRelativePath: string;
|
|
55
55
|
} | null;
|
|
56
|
+
/** The project file a `src` authored in `compositionFile` loads in preview and render; null when none exists. */
|
|
57
|
+
declare function resolveAuthoredAssetFile(projectDir: string, compositionFile: string, src: string): string | null;
|
|
56
58
|
/** Resolves a media `src` like a browser URL (`..` clamps at the project root); a miss returns the base-dir join. */
|
|
57
59
|
declare function resolveProjectRelativeSrc(src: string, baseDir: string, compiledDir?: string): string;
|
|
58
60
|
/** Blanks out comments, `<style>`, and `<script>` bodies so tag-scanning
|
|
@@ -69,4 +71,4 @@ type ProjectFileRead = {
|
|
|
69
71
|
/** Reads through one descriptor, so the file-type check and the read see the same file. */
|
|
70
72
|
declare function readProjectFile(path: string): ProjectFileRead;
|
|
71
73
|
|
|
72
|
-
export { type ProjectFileRead, cleanAssetUrl, collectSubCompositionSrcs, hasUnresolvedTemplatingToken, isRemoteOrInlineUrl, isUnresolvedAssetPlaceholder, isWithinProjectRoot, maskNonScannableRanges, readProjectFile, resolveExistingLocalAsset, resolveLocalAssetCandidates, resolveProjectRelativeSrc };
|
|
74
|
+
export { type ProjectFileRead, cleanAssetUrl, collectSubCompositionSrcs, hasUnresolvedTemplatingToken, isRemoteOrInlineUrl, isUnresolvedAssetPlaceholder, isWithinProjectRoot, maskNonScannableRanges, readProjectFile, resolveAuthoredAssetFile, resolveExistingLocalAsset, resolveLocalAssetCandidates, resolveProjectRelativeSrc };
|
package/dist/assetResolution.js
CHANGED
|
@@ -88,7 +88,7 @@ function decodeAuthoredAttribute(value) {
|
|
|
88
88
|
|
|
89
89
|
// src/assetResolution.ts
|
|
90
90
|
import { closeSync, constants, existsSync, fstatSync, openSync, readFileSync } from "fs";
|
|
91
|
-
import { isAbsolute, join, posix, relative, resolve, sep } from "path";
|
|
91
|
+
import { isAbsolute as isAbsolute2, join as join2, posix as posix2, relative as relative2, resolve as resolve3, sep } from "path";
|
|
92
92
|
|
|
93
93
|
// src/utils/urlPath.ts
|
|
94
94
|
function decodeUrlPathVariants(path) {
|
|
@@ -104,6 +104,46 @@ function decodeWellFormedEscapes(path) {
|
|
|
104
104
|
}
|
|
105
105
|
});
|
|
106
106
|
}
|
|
107
|
+
function splitUrlSuffix(urlValue) {
|
|
108
|
+
const queryIdx = urlValue.indexOf("?");
|
|
109
|
+
const hashIdx = urlValue.indexOf("#");
|
|
110
|
+
if (queryIdx < 0 && hashIdx < 0) return { basePath: urlValue, suffix: "" };
|
|
111
|
+
let cutIdx = urlValue.length;
|
|
112
|
+
if (queryIdx >= 0) cutIdx = Math.min(cutIdx, queryIdx);
|
|
113
|
+
if (hashIdx >= 0) cutIdx = Math.min(cutIdx, hashIdx);
|
|
114
|
+
return { basePath: urlValue.slice(0, cutIdx), suffix: urlValue.slice(cutIdx) };
|
|
115
|
+
}
|
|
116
|
+
function encodeUrlPath(path) {
|
|
117
|
+
return encodeURIComponent(path).replace(/%2F/g, "/").replace(/['()]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// src/rewriteSubCompPaths.ts
|
|
121
|
+
import { posix } from "path";
|
|
122
|
+
|
|
123
|
+
// src/assetPaths.ts
|
|
124
|
+
import { isAbsolute, relative, resolve } from "path";
|
|
125
|
+
function isNonRelativeUrl(val) {
|
|
126
|
+
return !val || val.startsWith("http://") || val.startsWith("https://") || val.startsWith("//") || val.startsWith("data:") || val.startsWith("#") || val.startsWith("/");
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// src/rewriteSubCompPaths.ts
|
|
130
|
+
var { join, resolve: resolve2, dirname } = posix;
|
|
131
|
+
var isAbsoluteOrSpecial = isNonRelativeUrl;
|
|
132
|
+
function needsRewrite(val) {
|
|
133
|
+
return val.startsWith("../") || val === "..";
|
|
134
|
+
}
|
|
135
|
+
function rewriteAssetPath(compSrcPath, relativePath, assetExists) {
|
|
136
|
+
if (isAbsoluteOrSpecial(relativePath)) return relativePath;
|
|
137
|
+
const compDir = dirname(compSrcPath);
|
|
138
|
+
if (!compDir || compDir === ".") return relativePath;
|
|
139
|
+
const { basePath, suffix } = splitUrlSuffix(relativePath);
|
|
140
|
+
const slashed = basePath.replace(/\\/g, "/");
|
|
141
|
+
if (!slashed || slashed.startsWith("/")) return relativePath;
|
|
142
|
+
const filePath = decodeWellFormedEscapes(slashed);
|
|
143
|
+
const sibling = resolve2("/", join(compDir, filePath)).slice(1);
|
|
144
|
+
if (!needsRewrite(filePath) && (!assetExists || !assetExists(sibling))) return relativePath;
|
|
145
|
+
return encodeUrlPath(sibling) + suffix;
|
|
146
|
+
}
|
|
107
147
|
|
|
108
148
|
// src/assetResolution.ts
|
|
109
149
|
function isRemoteOrInlineUrl(url) {
|
|
@@ -134,7 +174,7 @@ function collectSubCompositionSrcs(html) {
|
|
|
134
174
|
function cleanAssetUrl(url) {
|
|
135
175
|
return url.trim().split(/[?#]/, 1)[0] ?? "";
|
|
136
176
|
}
|
|
137
|
-
function isWithinProjectRoot(projectDir, candidate, pathModule = { resolve, relative, isAbsolute }) {
|
|
177
|
+
function isWithinProjectRoot(projectDir, candidate, pathModule = { resolve: resolve3, relative: relative2, isAbsolute: isAbsolute2 }) {
|
|
138
178
|
const projectRoot = pathModule.resolve(projectDir);
|
|
139
179
|
const relativePath = pathModule.relative(projectRoot, candidate);
|
|
140
180
|
return relativePath === "" || !relativePath.startsWith("..") && !pathModule.isAbsolute(relativePath);
|
|
@@ -144,49 +184,55 @@ function addCandidate(candidates, candidate) {
|
|
|
144
184
|
}
|
|
145
185
|
function resolveLocalAssetCandidates(projectDir, url) {
|
|
146
186
|
const cleanUrl = cleanAssetUrl(url);
|
|
147
|
-
const projectRoot =
|
|
187
|
+
const projectRoot = resolve3(projectDir);
|
|
148
188
|
const candidates = [];
|
|
149
189
|
for (const variant of decodeUrlPathVariants(cleanUrl)) {
|
|
150
190
|
const projectRelative = variant.startsWith("/") ? variant.slice(1) : variant;
|
|
151
|
-
const resolved =
|
|
191
|
+
const resolved = resolve3(projectRoot, projectRelative);
|
|
152
192
|
if (isWithinProjectRoot(projectRoot, resolved)) {
|
|
153
193
|
addCandidate(candidates, resolved);
|
|
154
194
|
continue;
|
|
155
195
|
}
|
|
156
|
-
const normalized =
|
|
196
|
+
const normalized = posix2.normalize(projectRelative.replace(/\\/g, "/"));
|
|
157
197
|
const clamped = normalized.replace(/^(\.\.\/)+/, "");
|
|
158
198
|
if (clamped && !clamped.startsWith("..")) {
|
|
159
|
-
addCandidate(candidates,
|
|
199
|
+
addCandidate(candidates, resolve3(projectRoot, clamped));
|
|
160
200
|
}
|
|
161
201
|
}
|
|
162
202
|
return candidates;
|
|
163
203
|
}
|
|
164
204
|
function resolveExistingLocalAsset(projectDir, url) {
|
|
165
|
-
const projectRoot =
|
|
205
|
+
const projectRoot = resolve3(projectDir);
|
|
166
206
|
const resolved = resolveLocalAssetCandidates(projectRoot, url).find(existsSync);
|
|
167
207
|
if (!resolved) return null;
|
|
168
|
-
return { resolved, rootRelativePath:
|
|
208
|
+
return { resolved, rootRelativePath: relative2(projectRoot, resolved) };
|
|
209
|
+
}
|
|
210
|
+
function resolveAuthoredAssetFile(projectDir, compositionFile, src) {
|
|
211
|
+
const cleanSrc = cleanAssetUrl(src.trim());
|
|
212
|
+
if (!cleanSrc) return null;
|
|
213
|
+
const rootRelative = cleanSrc.startsWith("/") ? cleanSrc : rewriteAssetPath(compositionFile, cleanSrc, (path) => existsSync(join2(projectDir, path)));
|
|
214
|
+
return resolveExistingLocalAsset(projectDir, rootRelative)?.resolved ?? null;
|
|
169
215
|
}
|
|
170
216
|
function reanchoredCandidates(variant, baseDir, compiledDir) {
|
|
171
|
-
const baseAbs =
|
|
172
|
-
const joinedAbs =
|
|
217
|
+
const baseAbs = resolve3(baseDir);
|
|
218
|
+
const joinedAbs = resolve3(join2(baseDir, variant));
|
|
173
219
|
if (joinedAbs === baseAbs || joinedAbs.startsWith(baseAbs + sep)) return [];
|
|
174
|
-
const stripped =
|
|
220
|
+
const stripped = posix2.normalize(variant.replace(/\\/g, "/")).replace(/^(\.\.\/)+/, "");
|
|
175
221
|
if (!stripped || stripped === variant || stripped.startsWith("..")) return [];
|
|
176
|
-
return compiledDir ? [
|
|
222
|
+
return compiledDir ? [join2(compiledDir, stripped), join2(baseDir, stripped)] : [join2(baseDir, stripped)];
|
|
177
223
|
}
|
|
178
224
|
function resolveProjectRelativeSrc(src, baseDir, compiledDir) {
|
|
179
225
|
const cleanSrc = cleanAssetUrl(src);
|
|
180
|
-
if (
|
|
226
|
+
if (isAbsolute2(cleanSrc) && existsSync(cleanSrc)) return cleanSrc;
|
|
181
227
|
const candidates = /* @__PURE__ */ new Set();
|
|
182
228
|
for (const variant of decodeUrlPathVariants(cleanSrc)) {
|
|
183
229
|
for (const candidate of reanchoredCandidates(variant, baseDir, compiledDir)) {
|
|
184
230
|
candidates.add(candidate);
|
|
185
231
|
}
|
|
186
|
-
if (compiledDir) candidates.add(
|
|
187
|
-
candidates.add(
|
|
232
|
+
if (compiledDir) candidates.add(join2(compiledDir, variant));
|
|
233
|
+
candidates.add(join2(baseDir, variant));
|
|
188
234
|
}
|
|
189
|
-
return [...candidates].find(existsSync) ??
|
|
235
|
+
return [...candidates].find(existsSync) ?? join2(baseDir, cleanSrc);
|
|
190
236
|
}
|
|
191
237
|
function maskRange(src, pattern) {
|
|
192
238
|
return src.replace(pattern, (m) => " ".repeat(m.length));
|
|
@@ -237,6 +283,7 @@ export {
|
|
|
237
283
|
isWithinProjectRoot,
|
|
238
284
|
maskNonScannableRanges,
|
|
239
285
|
readProjectFile,
|
|
286
|
+
resolveAuthoredAssetFile,
|
|
240
287
|
resolveExistingLocalAsset,
|
|
241
288
|
resolveLocalAssetCandidates,
|
|
242
289
|
resolveProjectRelativeSrc
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyperframes/parsers",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.172",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/heygen-com/hyperframes",
|
|
@@ -119,7 +119,7 @@
|
|
|
119
119
|
"tsx": "^4.21.0",
|
|
120
120
|
"typescript": "^5.0.0",
|
|
121
121
|
"vitest": "^4.1.11",
|
|
122
|
-
"@hyperframes/core": "0.8.
|
|
122
|
+
"@hyperframes/core": "0.8.172"
|
|
123
123
|
},
|
|
124
124
|
"scripts": {
|
|
125
125
|
"build": "tsup",
|