@expofp/config 3.28.1 → 3.28.3
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.
|
@@ -8,7 +8,7 @@ import type { FpSvgLayerJs } from '@expofp/schema';
|
|
|
8
8
|
* (`window['__fpBooth'] = …` — the chain had every layer script clobber the
|
|
9
9
|
* shared `window.__fp`). The schemas and the floorplan know only the plain
|
|
10
10
|
* `__fp`/`__fpPaths` keys, so the loader folds the alias onto them on the
|
|
11
|
-
* payload's own copy, before the resource walk — the `svgAsset`
|
|
11
|
+
* payload's own copy, before the resource walk — the `svgAsset` URL rewrite
|
|
12
12
|
* then covers a folded drawing like a plain one. The folded values skip the
|
|
13
13
|
* (opt-in) schema validation, which ran before the fold — the same trust the
|
|
14
14
|
* untouched alias keys always had.
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (`window['__fpBooth'] = …` — the chain had every layer script clobber the
|
|
8
8
|
* shared `window.__fp`). The schemas and the floorplan know only the plain
|
|
9
9
|
* `__fp`/`__fpPaths` keys, so the loader folds the alias onto them on the
|
|
10
|
-
* payload's own copy, before the resource walk — the `svgAsset`
|
|
10
|
+
* payload's own copy, before the resource walk — the `svgAsset` URL rewrite
|
|
11
11
|
* then covers a folded drawing like a plain one. The folded values skip the
|
|
12
12
|
* (opt-in) schema validation, which ran before the fold — the same trust the
|
|
13
13
|
* untouched alias keys always had.
|
|
@@ -16,10 +16,10 @@ export declare function toAbsoluteUrl(path: string, baseUrl: string): string;
|
|
|
16
16
|
export declare function isAbsoluteUrl(path: string): boolean;
|
|
17
17
|
/** The ref's own directory — the base its document's relative paths resolve against. */
|
|
18
18
|
export declare function refDirectory(ref: string): string;
|
|
19
|
-
/** Every distinct `<image>` asset
|
|
20
|
-
export declare function
|
|
21
|
-
/** Rewrite every `<image>` asset
|
|
22
|
-
export declare function
|
|
19
|
+
/** Every distinct `<image>` asset URL in one SVG document string. */
|
|
20
|
+
export declare function collectSvgImageAssets(svg: string): string[];
|
|
21
|
+
/** Rewrite every `<image>` asset URL in one SVG document string. */
|
|
22
|
+
export declare function rewriteSvgImageAssets(svg: string, rewrite: (url: string) => string): string;
|
|
23
23
|
/** Every distinct non-`data:` `url(…)` in one CSS text. */
|
|
24
24
|
export declare function collectCssUrls(css: string): string[];
|
|
25
25
|
/** Rewrite every non-`data:` `url(…)` in one CSS text. */
|
|
@@ -42,37 +42,44 @@ function execAll(regex, text) {
|
|
|
42
42
|
}
|
|
43
43
|
return matches;
|
|
44
44
|
}
|
|
45
|
-
/* ── SVG documents (`svgAsset`) — `<image>`
|
|
45
|
+
/* ── SVG documents (`svgAsset`) — an `<image>`'s URLs are asset paths ─────── */
|
|
46
46
|
const IMAGE_TAG = /<image\b[^>]*>/g;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
47
|
+
/**
|
|
48
|
+
* The asset-bearing attributes of an `<image>`: the href it draws, and
|
|
49
|
+
* `data-model-3d` — the URL of the 3D model the floor plan renders *instead* of
|
|
50
|
+
* the image, whose href then never loads (floorplan's `layer-models.ts`). Both are
|
|
51
|
+
* authored relative to the drawing, so both need the same rebase; a model URL
|
|
52
|
+
* left behind resolves against the page and 404s.
|
|
53
|
+
*/
|
|
54
|
+
const ASSET_ATTR = /(\b(?:(?:xlink:)?href|data-model-3d)\s*=\s*)(?:"([^"]*)"|'([^']*)')/g;
|
|
55
|
+
/** In-document (`#id`) and empty references are not asset URLs. */
|
|
56
|
+
function isAssetUrl(url) {
|
|
57
|
+
return !!url && !url.startsWith('#');
|
|
51
58
|
}
|
|
52
|
-
/** Every distinct `<image>` asset
|
|
53
|
-
export function
|
|
54
|
-
const
|
|
59
|
+
/** Every distinct `<image>` asset URL in one SVG document string. */
|
|
60
|
+
export function collectSvgImageAssets(svg) {
|
|
61
|
+
const urls = new Set();
|
|
55
62
|
if (!svg.includes('<image'))
|
|
56
63
|
return [];
|
|
57
64
|
for (const tag of svg.match(IMAGE_TAG) ?? []) {
|
|
58
|
-
for (const match of execAll(
|
|
59
|
-
const
|
|
60
|
-
if (
|
|
61
|
-
|
|
65
|
+
for (const match of execAll(ASSET_ATTR, tag)) {
|
|
66
|
+
const url = match[2] ?? match[3];
|
|
67
|
+
if (isAssetUrl(url))
|
|
68
|
+
urls.add(url);
|
|
62
69
|
}
|
|
63
70
|
}
|
|
64
|
-
return [...
|
|
71
|
+
return [...urls];
|
|
65
72
|
}
|
|
66
|
-
/** Rewrite every `<image>` asset
|
|
67
|
-
export function
|
|
73
|
+
/** Rewrite every `<image>` asset URL in one SVG document string. */
|
|
74
|
+
export function rewriteSvgImageAssets(svg, rewrite) {
|
|
68
75
|
if (!svg.includes('<image'))
|
|
69
76
|
return svg;
|
|
70
|
-
return svg.replace(IMAGE_TAG, (tag) => tag.replace(
|
|
71
|
-
const
|
|
72
|
-
if (!
|
|
77
|
+
return svg.replace(IMAGE_TAG, (tag) => tag.replace(ASSET_ATTR, (match, attr, doubleQuoted, singleQuoted) => {
|
|
78
|
+
const url = doubleQuoted ?? singleQuoted ?? '';
|
|
79
|
+
if (!isAssetUrl(url))
|
|
73
80
|
return match;
|
|
74
81
|
const quote = doubleQuoted !== undefined ? '"' : "'";
|
|
75
|
-
return `${attr}${quote}${rewrite(
|
|
82
|
+
return `${attr}${quote}${rewrite(url)}${quote}`;
|
|
76
83
|
}));
|
|
77
84
|
}
|
|
78
85
|
/* ── CSS text (`cssAsset`) — `url(…)`s are asset paths ────────────────────── */
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
import { getResolved, isResolved, resolve } from '@expofp/resolve';
|
|
21
21
|
import { deepClone } from '@expofp/utils';
|
|
22
22
|
import { refSchemaOf, toJsonSchema, typeMatches } from './json-schema.js';
|
|
23
|
-
import { collectCssUrls,
|
|
23
|
+
import { collectCssUrls, collectSvgImageAssets, inlineCssImports, isAbsoluteUrl, refDirectory, rewriteCssUrls, rewriteSvgImageAssets, toAbsoluteUrl, } from './resource-urls.js';
|
|
24
24
|
import { timeValidation } from './validate-timing.js';
|
|
25
25
|
/**
|
|
26
26
|
* Gates every schema validation (`parse`) of the large expo documents —
|
|
@@ -138,10 +138,10 @@ async function walk(node, value, assign, handler, options) {
|
|
|
138
138
|
}
|
|
139
139
|
else if (node?.svgAsset) {
|
|
140
140
|
const rewrites = new Map();
|
|
141
|
-
for (const
|
|
142
|
-
rewrites.set(
|
|
141
|
+
for (const url of collectSvgImageAssets(value)) {
|
|
142
|
+
rewrites.set(url, await handler.asset(url));
|
|
143
143
|
}
|
|
144
|
-
assign(
|
|
144
|
+
assign(rewriteSvgImageAssets(value, (url) => rewrites.get(url) ?? url));
|
|
145
145
|
}
|
|
146
146
|
else if (node?.cssAsset) {
|
|
147
147
|
// a handler that can fetch stylesheets gets @imports spliced in first,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@expofp/config",
|
|
3
|
-
"version": "3.28.
|
|
3
|
+
"version": "3.28.3",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ExpoFP SDK internal: config layer and schemas",
|
|
6
6
|
"homepage": "https://developer.expofp.com/",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"debug": "^4.4.3",
|
|
30
30
|
"tslib": "^2.3.0",
|
|
31
31
|
"zod": "4.4.3",
|
|
32
|
-
"@expofp/resolve": "3.28.
|
|
33
|
-
"@expofp/schema": "3.28.
|
|
34
|
-
"@expofp/utils": "3.28.
|
|
32
|
+
"@expofp/resolve": "3.28.3",
|
|
33
|
+
"@expofp/schema": "3.28.3",
|
|
34
|
+
"@expofp/utils": "3.28.3"
|
|
35
35
|
}
|
|
36
36
|
}
|